[pulseaudio] 01/19: Merge Ubuntu changes with updated Debian packaging.

Luke Yelavich themuso-guest at moszumanska.debian.org
Sun Nov 30 22:48:37 UTC 2014


This is an automated email from the git hooks/post-receive script.

themuso-guest pushed a commit to branch ubuntu
in repository pulseaudio.

commit ba509cf5a622a7e5c3c9322e42c8a4dab99078c8
Author: Luke Yelavich <themuso at ubuntu.com>
Date:   Tue Nov 18 12:22:30 2014 +1100

    Merge Ubuntu changes with updated Debian packaging.
---
 debian/changelog                                   | 3396 +++++++++++-
 debian/control                                     |   41 +-
 debian/gbp.conf                                    |    1 +
 .../0005-dont-load-cork-music-on-phone.patch       |   13 +
 debian/patches/0006-load-module-x11-bell.patch     |   24 +
 debian/patches/0016-nodisplay-autostart.patch      |   14 +
 ...urn-error-in-case-a-client-peeks-to-early.patch |   64 +
 ...rapper-Quit-daemon-if-pid-file-is-removed.patch |  257 +
 ...nd_mixer_poll_descriptors_count_when_zero.patch |   16 +
 ....c-changing-default-rlimit_rttime-value-t.patch |   26 +
 debian/patches/0202-dont-probe-ucm.patch           |   14 +
 ...0203-card-Add-hook-before-profile-changes.patch |   37 +
 ...tooth-discover-adding-module-option-profi.patch |   45 +
 debian/patches/0207-Enable-pulseaudio-droid.patch  | 5513 ++++++++++++++++++++
 ...tooth-device-Allow-leaving-transport-runn.patch |  220 +
 ...ch-on-connect-adding-parameter-to-allow-s.patch |   88 +
 ...le-device-restore-adding-property-to-skip.patch |   70 +
 ...pi-adding-missing-fields-for-sink_input-s.patch |   38 +
 debian/patches/series                              |   20 +
 debian/pulseaudio-module-droid.install             |    6 +
 debian/pulseaudio.install                          |    2 -
 debian/pulseaudio.upstart.example                  |   48 +
 debian/rules                                       |   14 +
 debian/tests/build                                 |   30 +
 debian/tests/control                               |    2 +
 25 files changed, 9970 insertions(+), 29 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 6e1e9dd..d5fec58 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,35 @@
+pulseaudio (1:5.0-13ubuntu1) UNRELEASED; urgency=medium
+
+  * Merge from Debian unstable, remaining changes:
+    - epoch (my stupid fault :S)
+    - Remove libwebrtc-audio-processing-dev build dep, its in universe
+    - Don't ship the consolekit module, and explicitly depend on the PAM
+      systemd module
+    - Add a module to allow pulseaudio to use the Android audio HAL
+    - Adjust gbp.conf file to point to the ubuntu branch for package builds
+    - Disable module-role-cork by default
+    - Load module-x11-bell in the start-pulseaudio-x11 script
+    - Hide pulseaudio from startup apps dialog
+    - Quit daemon if pid file is removed
+    - Avoid abort when poll descriptor is 0, such as when using it with the
+      audioflinger bridge, like done in ubuntu touch
+    - change default rlimit_rttime value to 200 ms
+    - Don't probe UCM profiles, trust that the profile writer knows what they
+      are doing
+    - Add card hook to allow modules to do something before a profile becomes
+      active
+    - Add an option to the bluez4 discovery module to set the profile
+    - Allow leaving bluetooth transport running while sink and source are
+      suspended.
+    - Add option to module-switch-on-connect to skip abstract devices
+    - Add property to module-device-restore to skip store/restore
+    - Add missing fields for sink_input/source_output info struct to the vala
+      bindings
+    - Add example upstart job to run pulseaudio in system mode
+    - Add a build/run autopkgtest for libpulse-dev
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 19 Nov 2014 11:21:32 +1100
+
 pulseaudio (5.0-13) unstable; urgency=medium
 
   * Replace raop channels patch with proper fix from upstream.
@@ -251,6 +283,228 @@ pulseaudio (4.0-1) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sun, 16 Jun 2013 17:20:36 +0200
 
+pulseaudio (1:4.0-0ubuntu22) utopic; urgency=medium
+
+  * 0211-module-stream-restore-use-entry_write-when-filling-u.patch =>
+    0108-module-stream-restore-use-entry_write-when-filling-u.patch:
+    - Renaming as it was accepted upstream
+  * 0212-libpulse.vapi-adding-missing-fields-for-sink_input-s.patch:
+    - Patch sent upstream, adding link to the thread
+  * 0207-Enable-pulseaudio-droid.patch:
+    - Fixing route when adding/removing devices (LP: #1363083)
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Wed, 08 Oct 2014 02:01:14 -0300
+
+pulseaudio (1:4.0-0ubuntu21) utopic; urgency=medium
+
+  * 0211-module-stream-restore-use-entry_write-when-filling-u.patch:
+    - Fixing use case for fallback_table, so we can provide default values
+      for stream restore
+  * 0212-libpulse.vapi-adding-missing-fields-for-sink_input-s.patch:
+    - Adding missing fields for sink_input/source_output structs
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Wed, 01 Oct 2014 12:37:54 -0300
+
+pulseaudio (1:4.0-0ubuntu20) utopic; urgency=medium
+
+  * debian/pulseaudio.install:
+    - Installing missing module-role-ducking
+  * 0107-sink-source-Fix-restore-of-volume-on-devices-without.patch:
+    - Updated version of 0211-fix-volume-max-boot.patch, that was merged
+      upstream
+  * 0207-Enable-pulseaudio-droid.patch:
+    - Adding option to create voice virtual stream when voicecall is active
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Thu, 04 Sep 2014 01:07:26 -0300
+
+pulseaudio (1:4.0-0ubuntu19) utopic; urgency=medium
+
+  * 0210-module-device-restore-adding-property-to-skip.patch:
+    - Adding property to skip device store/restore per sink/source
+  * 0211-fix-volume-max-boot.patch:
+    - Fix initial volume for sink (LP: #598308)
+  * 0207-Enable-pulseaudio-droid.patch:
+    - Adding support to track voice call volume when switching to the
+      voicecall mode
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Wed, 20 Aug 2014 15:15:16 -0300
+
+pulseaudio (1:4.0-0ubuntu18) utopic; urgency=medium
+
+  * 0207-Enable-pulseaudio-droid.patch:
+    - Fixing default priority for sink/source ports
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Fri, 01 Aug 2014 01:18:38 -0300
+
+pulseaudio (1:4.0-0ubuntu17) utopic; urgency=medium
+
+  * 0207-Enable-pulseaudio-droid.patch:
+    - droid-sink: enabling transport property on sco.fakesink
+    - droid-source: setting up default audio source
+  * 0208-module-bluetooth-device-Allow-leaving-transport-runn.patch:
+    - module-bluetooth-device: Allow leaving transport running while sink and
+      source source are suspended.
+  * 0209-module-switch-on-connect-adding-parameter-to-allow-s.patch:
+    - module-switch-on-connect: adding parameter to allow skipping abstract
+      devices
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Mon, 21 Jul 2014 19:00:21 -0300
+
+pulseaudio (1:4.0-0ubuntu16) utopic; urgency=medium
+
+  * 0207-Enable-pulseaudio-droid.patch:
+    - Skipping SPEAKER_DRC_ENABLED_TAG as it's not yet supported (available on
+      hammerhead)
+    - Adding missing flags (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD and
+      AUDIO_OUTPUT_FLAG_NON_BLOCKING)
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Sat, 28 Jun 2014 01:16:55 -0300
+
+pulseaudio (1:4.0-0ubuntu15) utopic; urgency=medium
+
+  * 0024-daemon-conf.c-changing-default-rlimit_rttime-value-t.patch:
+    - Changing default rlimit_rttime value as rtkit's limit is now 200ms
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Fri, 27 Jun 2014 16:57:48 -0300
+
+pulseaudio (1:4.0-0ubuntu14) utopic; urgency=medium
+
+  * Removing 0201-ALSA-Add-extcon-Android-switch-jack-detection.patch,
+    0204-Add-module-to-talk-to-the-Android-audio-hal-to-set-u.patch and
+    Disable-tsched-for-Nexus-10.patch code migrated to the pulse droid module
+  * Removing 0206-enable-module-switch-on-connect-ubuntu-touch.patch, as touch
+    as its own script file now
+  * 0206-module-bluetooth-discover-adding-module-option-profi.patch:
+    - Adding module option 'profile' in module-bluetooth-discover
+  * 0207-Enable-pulseaudio-droid.patch:
+    - Adding pulseaudio-droid element (used by Ubuntu Touch)
+  * debian/control: adding pulseaudio-module-droid
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Mon, 23 Jun 2014 03:23:51 -0300
+
+pulseaudio (1:4.0-0ubuntu13) utopic; urgency=medium
+
+  * 0206-enable-module-switch-on-connect-ubuntu-touch.patch:
+    - Enable module switch-on-connect by default on Ubuntu Touch
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Mon, 16 Jun 2014 21:45:19 -0300
+
+pulseaudio (1:4.0-0ubuntu12) utopic; urgency=high
+
+  * No change rebuild against new dh_installinit, to call update-rc.d at
+    postinst.
+
+ -- Dimitri John Ledkov <xnox at ubuntu.com>  Wed, 28 May 2014 10:41:54 +0100
+
+pulseaudio (1:4.0-0ubuntu11) trusty; urgency=medium
+
+  * 0105-sink-source-Initialize-port-before-fixate-hook-fixes.patch:
+    Fix volume/mute not restored in some cases (LP: #1285179, LP: #1289515)
+  * 0106-module-switch-on-port-available-Don-t-switch-profile.patch:
+    Fix profile incorrectly switched on startup (LP: #1256511) 
+
+ -- David Henningsson <david.henningsson at canonical.com>  Fri, 04 Apr 2014 09:39:55 +0200
+
+pulseaudio (1:4.0-0ubuntu10) trusty; urgency=medium
+
+  * 0204-Add-module-to-talk-to-the-Android-audio-hal-to-set-u.patch:
+    - Setting audio mode before shutting down output stream (LP: #1283818)
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Thu, 27 Feb 2014 22:37:56 -0300
+
+pulseaudio (1:4.0-0ubuntu9) trusty; urgency=medium
+
+  * 0205-suspend-on-idle-ensure-we-still-time-out-if-a-stream-remains-corked.patch:
+    - Properly suspending sink/source if the stream started corked and remains
+      corked (LP: #1284415)
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Tue, 25 Feb 2014 16:37:26 -0300
+
+pulseaudio (1:4.0-0ubuntu8) trusty; urgency=medium
+
+  * 0201-ALSA-Add-extcon-Android-switch-jack-detection.patch:
+    - Only getting udev events from the switch subsystem (LP: #1284410)
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Mon, 24 Feb 2014 23:43:50 -0300
+
+pulseaudio (1:4.0-0ubuntu7) trusty; urgency=low
+
+  * 0204-Add-module-to-talk-to-the-Android-audio-hal-to-set-u.patch:
+    - Refresh patch to use libhardware's pkg-config instead of looking for
+      audio.h
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Fri, 20 Dec 2013 04:08:09 -0200
+
+pulseaudio (1:4.0-0ubuntu6) saucy; urgency=low
+
+  * Three crash fixes from upstream:
+    0102-combine-Fix-crash-in-output-freeing.patch:
+    - Fix crash in module-combine-sink (LP: #1228759)
+    0103-resampler-Fix-peaks-resampler-s-channel-handling.patch:
+    - Fix crash in peak resampler (LP: #1212019)
+    0104-default-system.pa-Do-not-load-module-dbus-protocol.patch:
+    - module-dbus-protocol is still crashy, unfortunately (LP: #1213369)
+
+ -- David Henningsson <david.henningsson at canonical.com>  Mon, 30 Sep 2013 15:11:42 +0200
+
+pulseaudio (1:4.0-0ubuntu5) saucy; urgency=low
+
+  [ David Henningsson ]
+  * Ubuntu phone: Suspend sinks/sources before tearing down voice calls
+    (LP: #1226298)
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Wed, 25 Sep 2013 13:06:49 -0300
+
+pulseaudio (1:4.0-0ubuntu4) saucy; urgency=low
+
+  * debian/patches/Disable-tsched-for-Nexus-10.patch
+    Add a workaround patch for Nexus 10 and only apply it on armhf
+
+ -- David Henningsson <david.henningsson at canonical.com>  Thu, 12 Sep 2013 17:07:21 -0400
+
+pulseaudio (1:4.0-0ubuntu3) saucy; urgency=low
+
+  * Ubuntu Phone: Enable setting volume in voice calls
+    Fix speaker phone mode on Nexus 4
+
+ -- David Henningsson <david.henningsson at canonical.com>  Tue, 10 Sep 2013 12:32:10 -0400
+
+pulseaudio (1:4.0-0ubuntu2+build1) saucy; urgency=low
+
+  * No-change rebuild (updated android-platform-headers)
+
+ -- David Henningsson <david.henningsson at canonical.com>  Mon, 02 Sep 2013 17:12:10 +0200
+
+pulseaudio (1:4.0-0ubuntu2) saucy; urgency=low
+
+  * patches/020*, control, pulseaudio.install.armhf:
+    Add patches for Ubuntu Touch, make us detect Android jacks,
+    and talk to the Audio HAL for voice calls
+
+ -- David Henningsson <david.henningsson at canonical.com>  Tue, 27 Aug 2013 10:53:46 +0200
+
+pulseaudio (1:4.0-0ubuntu1) saucy; urgency=low
+
+  [ Luke Yelavich ]
+  * New upstream test release
+  * Drop all patches originally taken from upstream
+  * 0022-inotify-wrapper-Quit-daemon-if-pid-file-is-removed.patch: Refreshed
+  * Update symbols files
+  * Update shlibs
+  * Add/update lintian overrides from Debian package
+
+  [ David Henningsson ]
+  * 0019-disable-dbus-protocol.patch: Dropped, bug fixed upstream
+  * 0007-handle-Master-Front.patch: Dropped. "Master Front" does not exist as
+    of Linux 3.9 
+  * Drop references to pulseaudio-module-udev, pulseaudio-rygel-media-server and
+    pulseaudio-module-hal. We didn't have them in 12.04 and we don't support
+    upgrades bypassing 12.04.
+  * Ship new module-remap-source module and bash completion 
+  * Add an build/run autopkgtest for libpulse-dev
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 26 Jul 2013 11:02:06 +1000
+
 pulseaudio (3.0-1) experimental; urgency=low
 
   [ Sjoerd Simons ]
@@ -301,6 +555,141 @@ pulseaudio (3.0-1) experimental; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Mon, 11 Feb 2013 19:33:15 +0100
 
+pulseaudio (1:3.0-0ubuntu9) saucy; urgency=low
+
+  * debian/patches/0112-*, 0113-*: Add better support for machines with
+    "Headphone Mic" and "Headset Mic" jacks, used in some newer hardware
+    (LP: #1169143)
+
+ -- David Henningsson <david.henningsson at canonical.com>  Wed, 24 Jul 2013 09:43:55 +0200
+
+pulseaudio (1:3.0-0ubuntu8) saucy; urgency=low
+
+  * debian/patches/0023-fixing_snd_mixer_poll_descriptors_count_when_zero.patch:
+    - Avoid abort when poll descriptor is 0, such as when using it with the
+      audioflinger bridge, like done in ubuntu touch (LP: #1092377)
+
+ -- Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>  Mon, 10 Jun 2013 17:54:18 -0300
+
+pulseaudio (1:3.0-0ubuntu7) saucy; urgency=low
+
+  [ Martin Pitt ]
+  * Add 0111-logind-check.patch: Check for logind, not for systemd init. Patch
+    backported from upstream master.
+  * Switch to logind for session tracking:
+    - debian/control: Add systemd build dependencies for logind support. Move
+      dependency from consolekit to libpam-systemd.
+    - debian/pulseaudio.install: Install logind module instead of the
+      consolekit module.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 29 Apr 2013 15:13:12 +1000
+
+pulseaudio (1:3.0-0ubuntu6) raring; urgency=low
+
+  * 0022-inotify-wrapper-Quit-daemon-if-pid-file-is-removed.patch:
+    Fix patch not to cause 100% CPU (LP: #1170313)
+
+ -- David Henningsson <david.henningsson at canonical.com>  Thu, 18 Apr 2013 13:24:16 +0200
+
+pulseaudio (1:3.0-0ubuntu5) raring; urgency=low
+
+  * 0022-inotify-wrapper-Quit-daemon-if-pid-file-is-removed.patch: 
+    Fix stale pulseaudio processes after logout (LP: #1167192)
+
+ -- David Henningsson <david.henningsson at canonical.com>  Wed, 17 Apr 2013 16:13:04 +0200
+
+pulseaudio (1:3.0-0ubuntu4b2) raring; urgency=low
+
+  * Another no-change rebuild against libudev1 to pick up transitive
+    dependencies.
+
+ -- Martin Pitt <martin.pitt at ubuntu.com>  Thu, 14 Mar 2013 10:23:58 +0100
+
+pulseaudio (1:3.0-0ubuntu4b1) raring; urgency=low
+
+  * No-change rebuild against libudev1
+
+ -- Martin Pitt <martin.pitt at ubuntu.com>  Wed, 13 Mar 2013 07:02:09 +0000
+
+pulseaudio (1:3.0-0ubuntu4) raring; urgency=low
+
+  [ Kaj Ailomaa ]
+  * 0108-module-jackdbus-detect-channel-config.patch
+    0109-module-jackdbus-detect-channel-config-fix.patch
+    Adds channel configuration to module-jackdbus-detect
+  * 0110-module-jackdbus-detect-channel-config-default.patch
+    Sets default channel config for module-jackdbus-detect to 2,
+    as jack is not well adapted for anything beyond mono or stereo
+    connections.
+
+ -- David Henningsson <david.henningsson at canonical.com>  Fri, 01 Mar 2013 15:13:31 +0100
+
+pulseaudio (1:3.0-0ubuntu3) raring; urgency=low
+
+  * 0106-reserve-Move-get_name_owner-to-the-public-rd_device-.patch,
+    0107-reserve-Fix-leaking-NameLost-signals-after-release-a.patch:
+    Fix sound suddenly stops working, seems particularly frequent with VLC
+    (LP: #1129990, LP: #1127872)
+
+ -- David Henningsson <david.henningsson at canonical.com>  Thu, 21 Feb 2013 10:55:16 +0100
+
+pulseaudio (1:3.0-0ubuntu2) raring; urgency=low
+
+  * Update libpulse0 symbols
+  * Pulseaudio should have a hard dependency on the binary version of libpulse0
+    to guard against libpulsecommon ABI breakage.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 18 Feb 2013 09:43:39 +0000
+
+pulseaudio (1:3.0-0ubuntu1) raring; urgency=low
+
+  [ Luke Yelavich ]
+  * debian/control: Update Vcs-Bzr field for raring
+  * Bump upstream version and rules/shlib files to 3.0.
+
+  [ David Henningsson ]
+  * New upstream release (3.0)
+  * 0100-resampler-Fix-volume-on-downmix-to-mono.patch,
+    0101-alsa-mixer-Remove-analog-output-lfe-on-mono.patch,
+    0010-lp453966-handle-digmic-pt2.patch:
+    Dropped, applied upstream
+  * 0002-In-KDE-only-start-pulseaudio-from-the-KDE-specific-d.patch:
+    Dropped, Debian dropped it and we got it from there
+  * 0002-add-padsp-wrapper-check.patch:
+    Dropped, makes no sense now that OSS is disabled in the kernel
+  * 0008-delay-gnome-autostart.patch:
+    Dropped per Martin Pitt's recommendation (incompatible upstream change)
+  * 0101-alsa-mixer-Fix-the-analog-output-speaker-always-path.patch,
+    0102-Call-change_cb-only-when-there-s-an-actual-change.patch,
+    0103-Initialize-monitor-s-busy-status-to-false-if-we-own-.patch:
+    Added from upstream stable-3.x tree
+  * Other patches refreshed
+  * debian/control: PulseAudio binary package is no longer 
+    "Multi-Arch: foreign" (LP: #1078543)
+  * debian/control, pulseaudio-module-bluetooth.install:
+    Update for new bluetooth dependency (libsbc)
+  * debian/watch: Change to .xz by default (because Debian does)
+  * debian/pulseaudio.init: Don't claim to support reload (Debian BTS: #690736)
+  * debian/rules, debian/pulseaudio.manpages: Fix installation of default.pa
+    (Debian BTS: #690416)
+  * debian/rules: disable hal compat module
+  * debian/pulse-alsa.conf, debian/README.Debian,
+    debian/pulseaudio-esound-compat.links, debian/pulseaudio.init,
+    debian/pulseaudio.install: Sync with Debian.
+  * debian/manpages/esdcompat.1: Remove, already upstream.
+  * debian/control: Sync build-dependencies with debian, in particular,
+    - add fftw3 development library
+  * debian/control: Cosmetic changes (sync with Debian)
+  * debian/pulseaudio.postinst: Remove ancient upgrade stuff - we won't support
+    direct upgrades from 8.04 to 13.04+ anyway
+
+  [ Luke Yelavich ]
+  * 0104-alsa-ucm-Fallback-to-stereo-duplex.patch: Added from upstrea git
+    stable tree to fix ucm related issues.
+  * Disable use of UCM in PulseAudio for now.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 14 Feb 2013 12:05:20 +1100
+
 pulseaudio (2.1-2) experimental; urgency=low
 
   * debian/control: Use linux-any where applicable instead of specifying
@@ -322,6 +711,43 @@ pulseaudio (2.1-1) experimental; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sat, 21 Jul 2012 17:38:52 +0200
 
+pulseaudio (1:2.1-0ubuntu4) quantal-proposed; urgency=low
+
+  * 0101-alsa-mixer-Remove-analog-output-lfe-on-mono.patch:
+    Fix muted audio on startup in Virtualbox VM (LP: #1016969) 
+  * 0020-stream-Return-error-in-case-a-client-peeks-to-early.patch:
+    Fix clients crashing when asking for data, but there is no data
+    to hand out (LP: #1058200) 
+
+ -- David Henningsson <david.henningsson at canonical.com>  Thu, 04 Oct 2012 14:43:27 +0200
+
+pulseaudio (1:2.1-0ubuntu3) quantal; urgency=low
+
+  [ David Henningsson ]
+  * 0100-resampler-Fix-volume-on-downmix-to-mono.patch:
+    Fix clipped audio on downmix to mono (LP: #416190)
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 11 Sep 2012 09:24:29 +1000
+
+pulseaudio (1:2.1-0ubuntu2) quantal; urgency=low
+
+  * Merge changes that were accidentally squashed from 2.0-0ubuntu2.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 13 Aug 2012 15:14:32 +1000
+
+pulseaudio (1:2.1-0ubuntu1) quantal; urgency=low
+
+  [ David Henningsson ]
+  * Remove the old 01PulseAudio pm-utils script, since it
+    causes (LP: #665314) and is not recommended by upstream.
+
+  [ Luke Yelavich ]
+  * New upstream release.
+  * Dropped patches, applied upstream:
+    - 0621-Add-special-profiles-for-some-laptops-missing-speake.patch
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 13 Aug 2012 15:05:52 +1000
+
 pulseaudio (2.0-3) unstable; urgency=low
 
   [ Martin-Éric Racine ]
@@ -347,7 +773,7 @@ pulseaudio (2.0-2) unstable; urgency=low
     - LSB: NetworkManager to network-manager.
     - LSB: added missing Stop levels 0 and 6.
     - Added --disallow-exit option (Closes: #671470).
-  * pulseaudio-esound-compat.links: added man page link for esd.1.gz 
+  * pulseaudio-esound-compat.links: added man page link for esd.1.gz
   * watch: updated to point to FreeDesktop.org XZ tarball archive.
 
  -- Sjoerd Simons <sjoerd at debian.org>  Fri, 18 May 2012 20:54:08 +0200
@@ -364,6 +790,44 @@ pulseaudio (2.0-1) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sun, 13 May 2012 17:07:15 +0200
 
+pulseaudio (1:2.0-0ubuntu2) quantal; urgency=low
+
+  * deprecate pulseaudio.default.  Move it's helpful comments into the upstart
+    script.
+  * pulseaudio.upstart:
+    - replace mkdir/chmod/chown by install
+    - remove PULSEAUDIO_SYSTEM_START=0, and instead comment out the 'start on'
+      with a comment explaining how to re-enable
+    - remove started udev from start on - it's redundant with runlevel 2, and
+      would fail in the case of switching to runlevel 1 and back to 2.
+
+ -- Serge Hallyn <serge.hallyn at ubuntu.com>  Fri, 20 Jul 2012 12:30:47 -0500
+
+pulseaudio (1:2.0-0ubuntu1) quantal; urgency=low
+
+  [ Luke Yelavich ]
+  * New upstream release.
+  * Drop all patches which are now upstream, including jack detection.
+  * Refreshed patches:
+    - 0002-add-padsp-wrapper-check.patch
+    - 0005-dont-load-cork-music-on-phone.patch
+  * debian/pulseaudio.install: Point to module-role-cork.so
+  * debian/rules: pulse-1.1 -> pulse-2.0
+
+  [ Pali Rohár ]
+  * Convert System V pulseaudio init script to upstart
+
+  [ Luke Yelavich ]
+  * debian/libpulse0.install, debian/libpulsedsp.install:
+    - Point to new location of libpulsecommon.
+  * Ship new modules:
+    - switch-on-port-available.so
+    - virtual-surround-sink.so
+  * Ship new manpages.
+  * Switch to package version 3.0 quilt.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 08 Jun 2012 15:51:39 +1000
+
 pulseaudio (1.1-3.2) unstable; urgency=low
 
   * Non-maintainer upload.
@@ -397,6 +861,213 @@ pulseaudio (1.1-1) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sun, 23 Oct 2011 11:08:01 +0200
 
+pulseaudio (1:1.1-0ubuntu16) quantal; urgency=low
+
+  [ Luke Yelavich ]
+  * debian/control: Update Vcs-Bzr field for quantal.
+
+  [ David Henningsson ]
+  * 0621-Add-special-profiles-for-some-laptops-missing-speake.patch:
+    Add missing speaker/internal mic ports for some laptops (LP #946232)
+
+ -- David Henningsson <david.henningsson at canonical.com>  Mon, 28 May 2012 11:14:08 +0200
+
+pulseaudio (1:1.1-0ubuntu15) precise; urgency=low
+
+  * 0125-alsa-sink-source-Really-set-volumes-on-port-change.patch:
+    Fix volume not being correctly set on port change. With this fixed
+    we can also drop
+    0017-Hack-around-a-bug-in-the-core-causing-volumes-not-to.patch.
+  * 0022-allow-analog-input-path-for-no-volume.patch:
+    Allow inputs with no volume controls to still have ports. The lack of
+    ports caused a problem for the new sound settings UI (LP: #978109)
+  * 0126-alsa-sink-source-Make-sure-volumes-are-synchronised-.patch:
+    Fix volumes not synchronised in guest session (LP: #915035)
+
+ -- David Henningsson <david.henningsson at canonical.com>  Thu, 12 Apr 2012 00:24:20 +0200
+
+pulseaudio (1:1.1-0ubuntu14) precise; urgency=low
+
+  * 012*.patch: Cherry-pick bugfix patches from upstream git
+  * 0620-alsa-mixer-Show-HDMI-ports-for-older-Nvidia-cards.patch (LP: #961286)
+
+ -- David Henningsson <david.henningsson at canonical.com>  Fri, 30 Mar 2012 09:47:17 +0200
+
+pulseaudio (1:1.1-0ubuntu13) precise; urgency=low
+
+  * 0020-daemon-Initialize-dbus-to-use-thread-safe-mode-by-de.patch:
+    Make sure dbus is thread safe to avoid crashes in pa_make_realtime 
+    (LP: #937933)
+  * 0111-protocol-native-Protect-against-clients-trying-to-se.patch:
+    Don't crash if clients try to set a NULL port (LP: #951273)
+  * 0021-Fix-input-device-for-M-audio-fasttrack-pro.patch:
+    Probe two different input devices (LP: #569932)
+  * 0112-module-loopback-Never-call-adjust_rates-after-teardo.patch:
+    Don't crash on shutdown in module-loopback (LP: #946400)
+  * 0619-module-switch-on-port-available-Do-not-switch-profil.patch:
+    Prevent switching to HDMI profiles from analog profiles, as a result
+    of discussion on the pulseaudio-discuss and ubuntu-audio-dev mailinglist.
+
+ -- David Henningsson <david.henningsson at canonical.com>  Wed, 21 Mar 2012 10:47:33 +0100
+
+pulseaudio (1:1.1-0ubuntu12) precise; urgency=low
+
+  [ Luke Yelavich ]
+  * debian/control: Demote pulseaudio-esound-compat to suggests (LP: #930703)
+
+  [ David Henningsson ]
+  * 0110-flist-Avoid-the-ABA-problem.patch:
+    Fix occasional crashes in pa_memblock_free, pa_memblock_ref and drop_block
+    (LP: #924416)
+
+ -- David Henningsson <david.henningsson at canonical.com>  Fri, 09 Mar 2012 00:08:42 +0100
+
+pulseaudio (1:1.1-0ubuntu11) precise; urgency=low
+
+  * Cherry-pick a few crash-related patches from upstream git
+  * 0616-alsa-mixer-Make-speaker-get-available-no-when-headph.patch:
+    Don't remove paths if the state(un)plugged of the jack differs (LP: 933825)  
+
+ -- David Henningsson <david.henningsson at canonical.com>  Wed, 29 Feb 2012 11:03:32 +0100
+
+pulseaudio (1:1.1-0ubuntu10) precise; urgency=low
+
+  * debian/pulse-alsa.conf: Update syntax, as this file was throwing
+    errors when apps used the alsa pulse plugin.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 23 Feb 2012 14:58:36 +1100
+
+pulseaudio (1:1.1-0ubuntu9) precise; urgency=low
+
+  * debian/pulseaudio.init: Don't tell the user pulseaudio daemon isn't
+    starting when in per-user mode.  This is the most common case in Ubuntu
+    and causing needless distracting text on the screen. (LP: #656426)
+
+ -- Mario Limonciello <Mario_Limonciello at Dell.com>  Fri, 17 Feb 2012 16:32:52 -0600
+
+pulseaudio (1:1.1-0ubuntu8) precise; urgency=low
+
+  [ David Henningsson ]
+  * Make sure we switch away from unavailable ports at 
+    startup (LP: #928914)
+  * 0020-Fix-Darth-Vader-panning-bug.patch: 
+    Fix distorted sound when panned hard left (or right). (LP: #928757)
+  * 0618-alsa-mixer-Don-t-use-dangling-pointers-as-port-hashm.patch:
+    Fix inability to set port when options were used (LP: #932804)
+  * Minimize margins for deferred volumes, as a workaround for volume 
+    changes being dropped on port change.
+  * 0610-Jack-detection-kcontrol-implementation.patch:
+    Fix a bug in the headphone path
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 17 Feb 2012 07:28:23 +1100
+
+pulseaudio (1:1.1-0ubuntu7) precise; urgency=low
+
+  * Move the pulse.conf ALSA config file to the correct location, alsa.conf.d
+    not conf.d, thanks to Pete Graner for teh heads up.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 09 Feb 2012 08:22:04 +1100
+
+pulseaudio (1:1.1-0ubuntu6) precise; urgency=low
+
+  [ David Henningsson ]
+  * 0103-alsa-mixer-Allow-speaker-port-to-control-Front-Speak.patch:
+    - Control "Front Speaker" and a few more. From upstream git. (LP: #551441)
+  * 0105-loopback-Fix-crashes.patch:
+    - Fix some crashes on shutting down the loopback module, from upstream git.
+  * 0104-alsa-Improve-well-known-descriptions-for-ports.patch:
+    - Replace with upstream version.
+  * 0018-module-tunnel-source-fixup-create_record_stream.patch:
+    - Fix protocol error in module-tunnel-source (LP: #923661)
+  * Fixup HDMI patch to make sure it does not affect M-audio fasttrack Pro
+    (LP: #926911)
+  * Add two more jack detection patches to make it work better with the 
+    upcoming UI changes
+
+  [ Martin-Éric Racine ]
+  * Use --disallow-exit when running in system mode, as recommended
+    by PulseAudio log file (LP: #922848)  
+
+  [ Luke Yelavich ]
+  * Move the main pulse ALSA configuration file, pulse.conf to
+    /usr/share/alsa/conf.d, available in ALSA 1.0.25.
+  * Disable the dbus-protocol by default, as there have been recent reports
+    of crashes and race conditions, and upstream no longer finds the code
+    trustworthy.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 08 Feb 2012 15:58:41 +1100
+
+pulseaudio (1:1.1-0ubuntu5) precise; urgency=low
+ 
+  * Redo jack detection patches, so that they use the new jack detection
+    interface and the upstream code whenever possible.
+  * New patch better-well-known-descriptions.patch:
+    - Simplify port names. This patch is to be committed upstream shortly
+  * New patches from upstream git:
+    - 0101-alsa-Ignore-the-virtual-thinkpad-acpi-card.patch:
+      Ignore the dummy thinkpad-acpi soundcard (as it cannot playback or
+      record sound anyway)
+    - 0102-alsa-mixer-When-selecting-an-input-turn-off-boosts-o.patch:
+      alsa-mixer: When selecting an input, turn off boosts of
+      other inputs
+
+ -- David Henningsson <david.henningsson at canonical.com>  Fri, 27 Jan 2012 13:56:46 +0100
+
+pulseaudio (1:1.1-0ubuntu4) precise; urgency=low
+
+  [ Daniel T Chen ]
+  * Don't load module-raop-discover by default. (LP: #782860)
+
+  [ Gabor Kelemen ]
+  * Run dh_translations to generate translation template, add it as build-dep.
+    (LP: #876866)
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 14 Dec 2011 10:50:16 +1100
+
+pulseaudio (1:1.1-0ubuntu3) precise; urgency=low
+
+  * Allow pulseaudio-module-bluetooth to build on armhf.
+
+ -- Adam Conrad <adconrad at ubuntu.com>  Mon, 05 Dec 2011 12:57:06 -0700
+
+pulseaudio (1:1.1-0ubuntu2) precise; urgency=low
+
+  * No-change rebuild to drop spurious libsfgcc1 dependency on armhf.
+
+ -- Adam Conrad <adconrad at ubuntu.com>  Fri, 02 Dec 2011 17:31:22 -0700
+
+pulseaudio (1:1.1-0ubuntu1) precise; urgency=low
+
+  * New upstream release
+  * debian/watch: Update to new location
+  * Dropped patches, as these were from upstream:
+    - 0100-extended-Fix-doxygen-comment-style-typos.patch
+    - 0101-sink-source-Avoid-unnecessary-call-to-pa_rtclock_now.patch
+    - 0102-Always-return-a-three-part-version-number-in-API-cal.patch
+    - 0103-module-jackdbus-detect-Avoid-double-free-of-modargs.patch
+    - 0104-source-output-Do-not-use-unset-channel-map-in-pa_sou.patch
+    - 0105-Fix-deferred-volume-not-being-applied-if-sink-is-clo.patch
+    - 0106-sink-Move-updating-the-requested-latency-after-the-r.patch
+    - 0107-n ull-sink-Set-latency-range-at-the-time-of-initializ.patch
+    - 0108-Make-pulse-build-with-clang-again.patch
+    - 0109-alsa-Give-compressed-formats-preference-over-PCM.patch
+    - 0110-alsa-Better-error-handling-in-mixer-rtpoll-callback.patch
+    - 0111-echo-cancel-Fail-if-loaded-between-a-sink-and-its-mo.patch
+    - 0112-doc-Add-some-more-doxygen-tags-to-existing-comments.patch
+    - 0113-alsa-Make-mixer-error-handling-more-robust-still.patch
+    - 0114-echo-cancel-Don-t-crash-if-adjust_time-0.patch
+    - 0115-echo-cancel-Close-debug-files-on-module-unload.patch
+    - 0116-tests-Fix-calculation-of-memblock-size-in-resampler-.patch
+    - 0117-filter-apply-Move-sink-source-unlink-callbacks-befor.patch
+    - 0118-build-sys-Drop-libsamplerate-from-pulsecommon-deps.patch
+    - 0119-build-sys-Provide-a-simple-CMake-Config-setup-simila.patch
+  * Put libpulsedsp.so into its own package, so it can be built for
+    multi-arch
+  * debian/rules: Update for 1.1
+  * Update shlib files
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 27 Oct 2011 12:36:17 +1100
+
 pulseaudio (1.0-4) unstable; urgency=low
 
   * debian/control: Don't depend on libasound2-plugins on kfreebsd
@@ -426,6 +1097,157 @@ pulseaudio (1.0-1) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Wed, 28 Sep 2011 00:52:27 +0100
 
+pulseaudio (1:1.0-0ubuntu4) precise; urgency=low
+
+  [ David Henningsson ]
+  * Added patches:
+    0103-module-jackdbus-detect-Avoid-double-free-of-modargs.patch:
+      (LP: #867444)
+    0104-source-output-Do-not-use-unset-channel-map-in-pa_sou.patch: 
+      (LP: #864071)
+    0105-Fix-deferred-volume-not-being-applied-if-sink-is-clo.patch,
+    0017-Hack-around-a-bug-in-the-core-causing-volumes-not-to.patch:
+      These two patches affect users not having their volume correctly
+      set on port change (LP: #877954)
+
+  [ Luke Yelavich ]
+  * debian/control: Update Vcs-Bzr field
+  * 0102-Always-return-a-three-part-version-number-in-API-cal.patch: Refresh
+    the patch from upstrea git, to refer to the correct commit hash, and
+    update the description
+  * Pull some bug fixes from the stable-1.x upstream git branch:
+    - 411af6b (sink: Move updating the requested latency after the rewind
+               request when finishing a stream move.)
+    - 87f70c6 (null-sink: Set latency range at the time of initialization of
+               module.)
+    - d71a291 (Make pulse build with clang again)
+    - 4e5943b (alsa: Give compressed formats preference over PCM)
+    - 867170a (alsa: Better error handling in mixer rtpoll callback)
+    - c055c55 (echo-cancel: Fail if loaded between a sink and its monitor)
+    - 8754e0c (doc: Add some more doxygen tags to existing comments)
+    - 2c30c07 (alsa: Make mixer error handling more robust still)
+    - 8a5e6e8 (echo-cancel: Don't crash if adjust_time = 0)
+    - 7b13a79 (echo-cancel: Close debug files on module unload)
+    - 6bf0489 (tests: Fix calculation of memblock size in resampler-test)
+    - 93f55a4 (filter-apply: Move sink/source unlink callbacks before m-s-r)
+    - b1dabfb (build-sys: Drop libsamplerate from pulsecommon deps)
+    - 743a4d0 (build-sys: Provide a simple CMake Config setup (similar to
+               pkgconfig))
+  * Add liborc-0.4-dev as a build dependency to add orc support
+  * debian/libpulse-dev.install: Ship cmake files
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 20 Oct 2011 11:36:43 +1100
+
+pulseaudio (1:1.0-0ubuntu3) oneiric; urgency=low
+
+  * debian/patches/0102-Always-return-a-three-part-version-number-in-API
+    -cal.patch: Update to fix skype regression as well (LP: #865820)
+
+ -- David Henningsson <david.henningsson at canonical.com>  Thu, 06 Oct 2011 10:39:49 +0200
+
+pulseaudio (1:1.0-0ubuntu2) oneiric; urgency=low
+
+  [ Matthias Klose ]
+  * Drop build dependency on libatomic-ops-dev. Not needed on !ia64.
+
+  [ Scott Kitterman ]
+  * Add debian/patches/0102-Always-return-a-three-part-version-number-in-API
+    -cal.patch to fix regression in pulseaudio version detection by
+    applications depending on the three part version number previously used by
+    pulseaudio (including phonon)
+      - Cherrypicked from upstream
+
+ -- Scott Kitterman <scott at kitterman.com>  Tue, 04 Oct 2011 22:06:39 -0500
+
+pulseaudio (1:1.0-0ubuntu1) oneiric; urgency=low
+
+  [ David Henningsson ]
+  * Fix "Parse failure" error with remote sources/sinks,
+    thanks to Martin-Eric Racine for reporting/testing! (LP: #852902)
+  * Fix crash when dbus module does not load (LP: #855729)
+  * Add more bug fixes from upstream git
+
+  [ Daniel T Chen ]
+  * debian/copyright: Update all shipped sources
+  * Various xcb_*() bugs already fixed in Sep 2010 (LP: #642030,
+    LP: #646583, LP: #646616, LP: #648104)
+  * Passthrough is supported in 1.0 (LP: #448024)
+  * PulseAudio + alsa-plugins route through PulseAudio by default
+    (LP: #378382)
+
+  [ Luke Yelavich ]
+  * New upstream bugfix release
+    - vala: Add has_type_id=false to all enums, structs and classes
+    - module-switch-on-connect: Don't switch unlinked sink input and source
+      outputs
+    - alsa-mixer: Set "Front" control to 0 dB on headphone path
+    - module-equalizer-sink: Use %z for printf of size_t variables
+    - module-equalizer-sink: Use = in initialising variables
+    - bluetooth/sbc: Use __asm__ keyword
+    - module-equalizer-sink: Use correct limit in loop
+    - Squash the last gcc warnings
+    - Make gcc --std=c99 happy
+    - device-restore: Simplify the migration of data to per-port keys.
+    - stream-restore: Add in some variable sets that were missing from 9ffa93.
+    - stream-restore: Add proper data validity checks to the legacy database
+      entry read.
+    - formats: The format code should be in libpulse, not libpulsecommon
+    - formats: Export more functions needed for a clean build.
+    - device-restore: Fix use-after-free error.
+    - raop: Use the port supplied by avahi when connecting to RAOP devices.
+    - loopback: New modargs: sink_input_properties and
+      source_output_properties.
+    - bluetooth: Bump DBus version to 1.3.0 and drop conditional code.
+    - alsa: Tidy up argument descriptions
+    - module-suspend-on-idle: Move vacuum code to core
+    - alsa-mixer: Add support for the Microsoft Kinect Sensor device
+    - modargs: Ensure modargs can be accessed in their raw form.
+    - raop: Properly deal with the name coming from the device.
+    - build-sys: Oops forgot to add the Kinect profile to the build system.
+    - volume: Rename 'sync volume' to 'deferred volume'.
+    - raop: Don't crash if fd is not open when trying to close it
+    - doc: Update README with fresh links.
+    - doc: Add info about running pulseaudio from the build dir
+    - stream: Relax assert for extended API
+    - def: Hide server-side sink/source flags
+    - volume: Handle varying channel count for shared volumes
+    - virtual: Make volume sharing on by default
+    - equalizer: Use volume sharing by default
+    - echo-cancel: Use volume sharing by default
+    - sink,source: Avoid crash by not updating volume on shutdown
+    - conf: Make sure module-dbus-protocol is loaded after
+      module-default-device-restore
+    - build-sys: bump soname
+    - sink,source: Handle missing in the shared volume case
+    - dbus: Don't crash if the module does not load
+    - Fix crash in threaded message queues
+    - build-sys: Switch to the tar-ustar format (as per a lot of GNOME stuff
+      for 3.2) and distribute .xz files.
+    - build-sys: bump soname
+  * Dropped patches, all applied upstream:
+    - 0017-Avoid-crash-by-not-updating-volume-on-shutdown.patch
+    - 0018-RAOP-Don-t-crash-if-fd-is-not-open-when-trying-to-cl.patch
+    - 0019-Make-sure-module-dbus-protocol-is-loaded-after-modul.patch
+    - 0100-vala-Add-has_type_id-false-to-all-enums-structs-and-.patch
+    - 0101-module-switch-on-connect-Don-t-switch-unlinked-sink-.patch
+    - 0102-alsa-mixer-Set-Front-control-to-0-dB-on-headphone-pa.patch
+    - 0103-module-equalizer-sink-Use-z-for-printf-of-size_t-var.patch
+    - 0104-module-equalizer-sink-Use-in-initialising-variables.patch
+    - 0105-bluetooth-sbc-Use-__asm__-keyword.patch
+    - 0106-module-equalizer-sink-Use-correct-limit-in-loop.patch
+    - 0107-Squash-the-last-gcc-warnings.patch
+    - 0108-Make-gcc-std-c99-happy.patch
+    - 0109-device-restore-Simplify-the-migration-of-data-to-per.patch
+    - 0110-stream-restore-Add-in-some-variable-sets-that-were-m.patch
+    - 0111-stream-restore-Add-proper-data-validity-checks-to-th.patch
+  * Pull some post-1.0 fixes from upstream git master
+    - 6878140 (extended: Fix doxygen comment style typos)
+    - 6a9272f (sink,source: Avoid unnecessary call to pa_rtclock_now())
+  * debian/rules: Modules are now in a 1.0 directory
+  * Update symbols
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 29 Sep 2011 10:01:56 +1000
+
 pulseaudio (0.99.4-1) experimental; urgency=low
 
   * New upstream release
@@ -433,6 +1255,122 @@ pulseaudio (0.99.4-1) experimental; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Fri, 16 Sep 2011 21:23:47 +0100
 
+pulseaudio (1:0.99.3-0ubuntu5) oneiric; urgency=low
+
+  [ David Henningsson ]
+  * 0017-Avoid-crash-by-not-updating-volume-on-shutdown.patch:
+    Fix typo in patch
+
+  [ Luke Yelavich ]
+  * Patch from David Henningssen to make sure module-dbus-protocol is loaded
+    after module-device-restore (LP: #843780)
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 15 Sep 2011 09:59:20 +1000
+
+pulseaudio (1:0.99.3-0ubuntu4) oneiric; urgency=low
+
+  * Fix crash in jack detection patches (LP: #845468)
+  * Fix crash when reading volume when sink/source is unlinked (LP: #841968)
+  * Fix crash in RAOP (LP: #845286)
+
+ -- David Henningsson <david.henningsson at canonical.com>  Mon, 12 Sep 2011 10:29:00 +0200
+
+pulseaudio (1:0.99.3-0ubuntu3) oneiric; urgency=low
+
+  * Jack detection support, second version, now with HDMI support
+
+ -- David Henningsson <david.henningsson at canonical.com>  Mon, 05 Sep 2011 16:41:12 +0200
+
+pulseaudio (1:0.99.3-0ubuntu2) oneiric; urgency=low
+
+  * Dropped patches (applied upstream):
+    - 0004-mute-iec958-optical-raw-for-audigyX.patch
+    - 0011-lp451635-handle-dove-x0-line-hp-swap.patch
+    - 0012-JACK-Load-module-jackdbus-detect-in-default.pa.patch
+
+ -- David Henningsson <david.henningsson at canonical.com>  Mon, 05 Sep 2011 11:55:59 +0200
+
+pulseaudio (1:0.99.3-0ubuntu1) oneiric; urgency=low
+
+  [ David Henningsson ]
+  * 0018-alsa-mixer-Set-Front-control-to-0-dB-on-headphone-pa.patch:
+    Set Front to 0 dB for Headphones (LP: #836921)
+
+  [ Luke Yelavich ]
+  * New upstream bugfix release
+    - source: Remove the PA_SOURCE_PASSTHROUGH flag
+    - alsa: Don't always suspend/unsuspend on sink-input removal
+    - formats: Use correct API to check for passthrough streams
+    - alsa: Open iec958 device with NONAUDIO bit set in passthrough mode
+    - formats: Fix bad passsthrough check
+    - alsa: Fix bad function name
+    - daemon: Fix compiler warning about missing function prototype
+    - passthrough: We must not plug in a resampler on stream move
+    - sink-input: Ensure no volumes are applied for passthrough streams
+    - source-output: Ensure no volumes are applied for passthrough streams
+    - Revert "device-restore: Make bools not be bit fields"
+    - sample-util: Fix off-by-one in error check
+    - sink: Add PA_SINK_SET_FORMATS macro
+    - build-sys: Fix some LDFLAGS vs. LDADD usage
+    - echo-cancel: Add multiple include protection for header
+    - echo-cancel: Use pa_streq instead of strcmp
+    - echo-cancel: Move speex preprocessing out of the main module
+    - passthrough: Fix what volume we set sinks/sources to
+    - passthrough: Fix setting volume to unamplified again
+    - echo-cancel: Make save_aec modarg a bool instead of an int
+    - echo-cancel: Don't allow streams to attach while unloading
+    - echo-cancel: Get rid of annoying compiler warnings
+    - equalizer: Comment out unused function
+    - def: Add a new enum to allow differntiation between sinks and sources.
+    - dbus: Use pa_device_type_t rather than an internal equivalent
+    - device-restore: Change the API to include type information (sink
+      vs. source)
+    - device-restore: Split device restore database into two parts.
+    - device-restore: Restore volumes on port change.
+    - build-sys: bump soname
+    - alsa-mixer: Mute IEC958 optical raw for several Audigy models
+    - alsa-mixer: Add "Line HP Swap" element
+    - JACK: Load module-jackdbus-detect in default.pa
+    - Remove offensive part of error message
+    - switch-on-connect: Don't switch to a monitor source
+    - Fix spelling sucess -> success
+    - Set better priorities on input paths
+    - introspect: fix typo in default sink/source docs
+    - pacat: make pacat respond to cork/uncork events
+    - Spelling fixes in public headers
+    - More spelling fixes
+    - gitignore: Add Orc autogenerated files
+    - echo-cancel: Use stream index in debug message
+    - Remove extra ; s where they are not allowed in strict C99
+    - sndfile-util: Check return value of sf_command for errors
+  * Pull some further fixes from upstream git master:
+    - fb107fc (vala: Add has_type_id=false to all enums, structs and classes)
+    - c7bba24 (module-switch-on-connect: Don't switch unlinked sink input and
+               source outputs)
+    - 9636991 (alsa-mixer: Set "Front" control to 0 dB on headphone path)
+    - fc3ddfb (module-equalizer-sink: Use %z for printf of size_t variables)
+    - 918f168 (module-equalizer-sink: Use = in initialising variables)
+    - 3d04a05 (bluetooth/sbc: Use __asm__ keyword)
+    - 647048e (module-equalizer-sink: Use correct limit in loop)
+    - dfd706d (Squash the last gcc warnings)
+    - 9133c6c (Make gcc --std=c99 happy)
+    - 47c9d8c (device-restore: Simplify the migration of data to per-port keys.)
+    - e7b65d3 (stream-restore: Add in some variable sets that were missing
+               from 9ffa93.)
+    - 2b96fdf (stream-restore: Add proper data validity checks to the legacy
+               database entry read.)
+  * Dropped patches, applied upstream:
+    - 0017-Make-dbus-error-more-polite.patch
+    - 0018-alsa-mixer-Set-Front-control-to-0-dB-on-headphone-pa.patch
+    - 0400-introspect-fix-typo-in-default-sink-source-docs.patch
+    - 0401-source-Remove-the-PA_SOURCE_PASSTHROUGH-flag.patch
+    - 0402-alsa-Don-t-always-suspend-unsuspend-on-sink-input-re.patch
+    - 0403-formats-Use-correct-API-to-check-for-passthrough-str.patch
+  * 0604-ALSA-part-of-jack-detection-and-a-small-policy-modul.patch: Refreshed
+  * Update symbols files
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 05 Sep 2011 14:37:01 +1000
+
 pulseaudio (0.99.2-2) experimental; urgency=low
 
   * Fix build on kfreebsd architectures (Closes: 637785)
@@ -452,6 +1390,30 @@ pulseaudio (0.99.2-1) experimental; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Tue, 23 Aug 2011 20:51:25 +0200
 
+pulseaudio (1:0.99.2-0ubuntu2) oneiric; urgency=low
+
+  * Build-depend on libxcb1-dev (>= 1.6) rather than libxcb-atom1-dev, in
+    line with the packaging in Debian experimental.
+  * Build-depend on libtdb-dev rather than tdb-dev.
+
+ -- Colin Watson <cjwatson at ubuntu.com>  Thu, 18 Aug 2011 16:10:53 +0100
+
+pulseaudio (1:0.99.2-0ubuntu1) oneiric; urgency=low
+
+  * New upstream bugfix release
+  * 0005-dont-load-cork-music-on-phone.patch: Refreshed
+  * Dropped patches, applied upstream
+    - 0400-Fix-crash-in-path-subset-elimination.patch
+    - 0402-source-output-Fix-resampling.patch
+    - 0403-stream-restore-Save-restore-source-output-volume-mut.patch
+  * Pull some post 0.99.2 fixes from upstream git master:
+    - 7ed177d (introspect: fix typo in default sink/source docs)
+    - 2677911 (source: Remove the PA_SOURCE_PASSTHROUGH flag)
+    - dde09c7 (alsa: Don't always suspend/unsuspend on sink-input removal)
+    - adbdb62 (formats: Use correct API to check for passthrough streams)
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 18 Aug 2011 09:17:09 +1000
+
 pulseaudio (0.99.1-1) experimental; urgency=low
 
   * New upstream test release
@@ -490,6 +1452,68 @@ pulseaudio (0.99.1-1) experimental; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sat, 13 Aug 2011 14:21:02 +0200
 
+pulseaudio (1:0.99.1-0ubuntu3) oneiric; urgency=low
+
+  * debian/libpulse-glib-mainloop0.symbols: Fix a typo in the package name
+    which was made at the time of symbol generation
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 16 Aug 2011 15:20:47 +1000
+
+pulseaudio (1:0.99.1-0ubuntu2) oneiric; urgency=low
+
+  * Build for multiarch:
+    - libpulse{,-mainloop-glib}0{,-dbg} and libpulse-dev are Multi-Arch: same.
+    - pulseaudio itself should be Multi-Arch: foreign, since it's a daemon.
+    - drop dh-buildinfo build-dependency, incompatible with multiarch and not
+      relevant in Ubuntu where we have build logs for all builds.
+    - LP: #825342.
+
+ -- Steve Langasek <steve.langasek at ubuntu.com>  Sat, 13 Aug 2011 02:22:42 +0000
+
+pulseaudio (1:0.99.1-0ubuntu1) oneiric; urgency=low
+
+  [ Daniel T Chen ]
+  * 0017-Make-dbus-error-more-polite.patch: Remove language that doesn't
+    add anything to the error message (LP: #444400).
+
+  [ David Henningsson ]
+  * New upstream release, remaining patches:
+  * Add build dependency on libjson0-dev
+  * Dropped patches (implemented upstream):
+    0001-Work-around-some-platforms-not-having-O_CLOEXEC.patch
+    0009-lp533877-handle-digmic.patch
+    0015-alsa-mixer-Add-workaround-for-some-USB-headsets.patch
+    0200-gold.patch
+    0201-alsa-mixer-Add-a-few-well-known-descriptions.patch
+    0202-alsa-mixer-add-required-any-and-required-for-enum-op.patch
+    0203-alsa-mixer-always-round-towards-0-dB.patch
+    0204-alsa-mixer-Add-new-paths-for-Internal-Mic-Front-Mic-.patch
+    0205-alsa-mixer-Fixup-Mic-Line-analog-input-paths-to-work.patch
+    0206-alsa-mixer-Make-sure-capture-source-and-input-source.patch
+    0207-PulseAudio-added-IT-block-to-fix-thumb-conditional-i.patch
+    0208-alsa-sink-Fix-incorrect-work_done-value-to-prevent-expensive-update...
+    _smoother-calls.patch
+    0209-sndfile-pacat-Use-file-extension-and-fix-format-from-string.patch
+  * Refreshed patches:
+    0005-dont-load-cork-music-on-phone.patch
+    0012-JACK-Load-module-jackdbus-detect-in-default.pa.patch
+    0013-Load-RAOP-Zeroconf-by-default.patch
+    0014-alsa-mixer-Add-separate-profile-for-Nvidia.patch
+    0017-Make-dbus-error-more-polite.patch
+  * Upstream has removed libpulsebrowse, replace with dummy packages for the
+    time being.
+  * Updated shlibs files and debian/rules with new version number
+  * Add new modules to the pulseaudio package
+  * Initial pulseaudio support for jack detection
+
+  [ Luke Yelavich ]
+  * debian/control: Remove the libpulse-browse0 package, and add set
+    pulseaudio to replace that package until after the next LTS
+  * Add symbols files for libpulse0 and libpulse-mainloop-glib0 and adjust
+    other shlibs files as necessary
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 11 Aug 2011 14:30:44 +1000
+
 pulseaudio (0.9.23-1) unstable; urgency=low
 
   [ Daniel T Chen ]
@@ -533,33 +1557,744 @@ pulseaudio (0.9.23-1) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Mon, 25 Jul 2011 23:05:29 +0100
 
-pulseaudio (0.9.22-1) experimental; urgency=low
+pulseaudio (1:0.9.23-0ubuntu2) oneiric; urgency=low
 
-  * New upstream release
-  * debian/patches/0002-CVE-2009-1299.patch:
-    + Dropped, fixed upstream
-  * debian/patches/0003-Re-bootstrap.patch
-    + Dropped, not needed anymore
-  * debian/rules: Stop using -g0 on mips{,el} the toolchain has been fixed
-  * debian/rules, debian/control: Update build-depends and force building
-    with X11
-  * debian/control: Suggest rtkit
-  * debian/control: Prune unneeded depends of libpulse-dev
+  [ Daniel T Chen ]
+  * Add the following patches backported from upstream git:
+    - aa7bc32 (parecord: Automatically detect file format from extension)
+      [series patch 0208]
+    - 226ddb1 (alsa-sink: fix mmap_write() work_done) [series patch 0209]
+  * Update debian/copyright to cover echo-cancel files.
+
+  [ Michael Terry ]
+  * 0016-nodisplay-autostart.patch:
+    - Don't show in "Startup Applications" (LP: #803917)
+
+ -- Michael Terry <mterry at ubuntu.com>  Fri, 01 Jul 2011 12:56:15 +0100
+
+pulseaudio (1:0.9.23-0ubuntu1) oneiric; urgency=low
+
+  * New upstream release, the following commits from the stable-queue branch
+    are included in this release:
+    - d4c9ad1 (streams: Fix the actual resampler method shown in debug
+               messages.)
+    - cc91a8f (module-combine-sink: Initialize smoother with offset
+               pa_rtclock_now())
+    - 8a437ee (module-combine-sink: Initialize smoother in paused state)
+    - b54a43a (module-combine-sink: Check running flag before rendering in null
+               mode
+    - b3e4152 (pulsecore: Add a couple pa_asserts() on pa_tagstruct* calls.)
+    - 22c0dcb (device-manager: Free a hook slot to prevent segv on unload)
+    - c3bfcc9 (SSE/MMX: Fix problem with highpitched noise on i386)
+    - 9ee4229 (build-sys: Add echo-cancel dummy Makefile)
+    - f558189 (build-sys: bump soname)
+  * Bumped shlibs
+  * debian/rules: Exclude 0.9.23 modules from shlibs
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 24 Jun 2011 10:18:17 +1000
+
+pulseaudio (1:0.9.22+stable-queue-69-gf8e8-0ubuntu1) oneiric; urgency=low
+
+  * Merge from unreleased Debian git, remaining changes:
+    - epoch (my stupid fault :S)
+    - use speex-float-1 and change buffer and fragment size, depending on
+      architecture
+    - Add alsa configuration files to route alsa applications via pulseaudio
+    - Move libasound2-plugins from Recommends to Depends
+    - Add pm-utils sleep hook to suspend (and resume) users' pulseaudio
+      daemons
+    - Make initscript more informative in the default case of per-user
+      sessions
+    - add status check for system wide pulseaudio instance
+    - create /var/run/pulse, and make restart more robust
+    - indicate that the system pulseaudio instance is being started from the
+      init script
+    - check whether pulseaudio is running before preloading the padsp library
+    - Add DEB_OPT_FLAG = -O3 as per recommendation from
+      pulseaudio-discuss/2007-December/001017.html
+    - Generate a PO template on build
+    - the esd wrapper script should not load pulseaudio if pulseaudio is being
+      used as a system service
+    - add a pulseaudio apport hook
+    - drop padevchooser(Recommends) and pavucontrol (Suggests)
+    - add libudev-dev as a build-dependency
+    - Fix initialization of devices with modem subdevices
+    - Disable cork-music-on-phone
+    - disable flat volume
+    - Mute IEC958 Optical Raw by default
+    - use tdd instead of gdbm
+    - Add conflicts/replaces for pulseaudio-module-udev and
+      pulseaudio-module-rygel-media-server
+    - Add replaces for pulseaudio-module-hal to the pulseaudio package to handle
+      upgrades from hardy
+    - Load module-x11-bell in the start-pulseaudio-x11 script
+    - added IT block to fix thumb conditional instruction build error messages
+    - recommend instead of suggest rtkit
+    - Ship the jackdbus-detect module
+    - Ship extra quirks to mixer profiles for various x86 and ARM hardware, as
+      well as USB hardware
+  * New snapshot based on upstream git branch stable-queue:
+    - 4f67775 (http: support HTTP HEAD)
+    - 3bb6546 (vala: More vala fixes)
+    - 7fd0771 (x11: Fix build errors with newest xcb-util.)
+    - b72fc9b (x11: More XCB fixes.)
+    - f8e8a03 (rtkit: use private bus connection in order to avoid threading
+               issues when invoking pa_make_realtime())
+    - c524b4c (memblockq: implement new call pa_memblockq_peek_fixed_size())
+    - 1a8cf00 (make echo-cancel module that exposes a new sink and source)
+    - 9fa71e7 (echo-cancel: take into account snapshot delay)
+    - 7b972f5 (echo-cancel: use the phone media role)
+    - de6cdf9 (echo-cancel: tweak the resync code a little)
+    - 1c26694 (echo-cancel: improve debug)
+    - b30bf12 (echo-cancel: keep frame_size a power of 2)
+    - 6d8a907 (echo-cancel: Move the module into it's own directory)
+    - 57c5983 (echo-cancel: Split out speex code from the core module)
+    - 668f4e4 (echo-cancel: Pass arguments to the specific canceller module)
+    - c975dfa (echo-cancel: Let AEC module determine source/sink spec)
+    - 47e4dd1 (echo-cancel: Add alternative echo-cancellation implementation)
+    - 4a9fa8c (echo-cancel: Allow selection of AEC method using modargs)
+    - b6b8a7b (echo-cancel: Make blocksize a module-wide parameter)
+    - 2923c5e (echo-cancel: Mark immutable parameters as const in vfunc)
+    - 9f79c0e (echo-cancel: rework alignment code)
+    - 56a4684 (echo-cancel: improve accuracy)
+    - e936447 (echo-cancel: pause timer when echo canceling is off)
+    - d39043c (echo-cancel: Fix make distcheck)
+    - d8fab84 (echo-cancel: Fix out-of-tree build)
+    - 1212a6f (echo-cancel: Ensure correct handling of endianness)
+    - d866ade (echo-cancel: Use S16NE for adrian module)
+    - f93b5e1 (echo-cancel: Fix source may_move_to function)
+    - 6664650 (i18n: Update POTFILES.*)
+  * debian/libpulse-dev.install: Ship vala bindings
+  * Dropped patches, either they were previously backported, or are now
+    upstream:
+    - 0005-load-sample-dir-lazy.patch
+    - 0090-disable-flat-volumes.patch
+    - 0211-module-loopback-Add-adjust_time-to-valid-args.patch
+    - 0212-Limit-rate-adjustments-to-small-inaudible-jumps.patch
+    - 0213-module-rtp-recv-Use-new-algorithm-for-adjusting-samp.patch
+    - 0214-module-rtp-recv-Average-the-estimated-real-sample-ra.patch
+    - 0215-module-rtp-recv-Remove-smoother-from-write-index.patch
+    - 0216-conf-Make-system.pa-use-udev-detect-and-not-hal-dete.patch
+    - 0217-volume-Add-a-PA_VOLUME_UI_MAX-define-for-the-recomme.patch
+    - 0218-vala-Some-bugfixes-for-the-vala-bindings.patch
+    - 0219-vala-delegate-FreeCb-does-not-have-a-target.patch
+    - 0220-vala-move-GLibMainLoop-class-into-separate-file-to-f.patch
+    - 0221-vala-Fix-path-error-in-the-last-commit.patch
+    - 0222-build-sys-Link-binaries-linking-libpulse-to-libpulse.patch
+    - 0223-build-sys-Link-binaries-linking-libpulsecommon-to-li.patch
+    - 0224-build-sys-Link-lirc-libraries-in-right-order.patch
+    - 0225-module-jack-sink-source-protect-against-null-return-.patch
+    - 0226-vala-ChannelMap-has-no-destroy-function.patch
+  * debian/patches/series: Renamed and re-ordered some patches, and clearly
+    identified distro specific patches and upstream/upstreamable patches
+  * 0209-alsa-mixer-Fix-makefile-in.patch: Drop, as we use dh-autoreconf,
+    which takes care of this for us
+  * debian/pulseaudio.install: Add the echo-cancel module
+  * 0003-Mention-speex-and-libsamplerate-in-pulse-daemon.conf.patch: Drop,
+    upstream
 
- -- Sjoerd Simons <sjoerd at debian.org>  Sun, 05 Dec 2010 12:01:37 +0000
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 27 May 2011 14:05:01 +1000
 
-pulseaudio (0.9.21-3) unstable; urgency=low
+pulseaudio (1:0.9.22+stable-queue-24-g67d18-0ubuntu4) oneiric; urgency=low
 
-  * debian/rules: Compile with -g0 on mips{,el} to work around #519006 in
-    gcc-4.4
+  [ David Henningsson ]
+  * Fix missing Internal/Front/Rear mics on Nvidia chipsets (LP: #771739)
 
- -- Sjoerd Simons <sjoerd at debian.org>  Sat, 03 Jul 2010 15:12:54 +0100
+  [ Luke Yelavich ]
+  * debian/control: Update Vcs-Bzr field
 
-pulseaudio (0.9.21-2) unstable; urgency=low
+ -- David Henningsson <david.henningsson at canonical.com>  Thu, 28 Apr 2011 10:31:42 +0200
 
-  * Import NMU patches into pkg-pulse git, thanks to the security team for
-    their work!
-  * debian/patches/0003-Re-bootstrap.patch
+pulseaudio (1:0.9.22+stable-queue-24-g67d18-0ubuntu3) natty; urgency=low
+
+  [ David Henningsson ]
+  * Add separate profile for Nvidia to make it easier to select the right 
+    codec out of four (LP: #716371)
+  * Add workaround to make it possible to control the volume of some
+    USB headsets (LP: #749856, LP: #671560)
+
+  [ Luke Yelavich ]
+  * debian/control: Demote pulseaudio-module-raop to suggests, as it is
+    causing various issues, including crashers, (LP: #742281, #743073)
+    and re-opens (LP #688272)
+  * Pull some bugfixes from the stable-queue branch:
+    - 4fa7495 (vala: Some bugfixes for the vala bindings)
+    - ea0a2a6 (vala: delegate FreeCb does not have a target.)
+    - 64985aa (vala: move GLibMainLoop class into separate file to fix linker
+               errors)
+    - 9f52c10 (vala: Fix path error in the last commit.)
+    - 1ade8df (build-sys: Link binaries linking libpulse to libpulsecommon too)
+    - c25207f (build-sys: Link binaries linking libpulsecommon to libpulse too)
+    - 4be49ae (build-sys: Link lirc libraries in right order)
+    - fd5b282 (module-jack-sink/source: protect against null return in
+               jack_get_ports) (LP: #733424)
+    - 93e7a19 (vala: ChannelMap has no destroy function.)
+  * debian/patches/0097-explicitly-link-libraries.patch: Dropped, applied
+    upstream
+  * debian/control, debian/rules: Add dh-autoreconf
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 11 Apr 2011 16:58:14 +1000
+
+pulseaudio (1:0.9.22+stable-queue-24-g67d18-0ubuntu2) natty; urgency=low
+
+  * Update to latest stable queue patches:
+    - 09770e5 (module-loopback: Add adjust_time to valid args
+    - 90c5520 (Limit rate adjustments to small, inaudible jumps
+    - 4620039 (module-rtp-recv: Use new algorithm for adjusting sample rate
+    - 2bfc032 (module-rtp-recv: Average the estimated real sample rate
+    - 2ee4ec5 (module-rtp-recv: Remove smoother from write index (LP: #569378)
+    - a8cd9d2 (conf: Make system.pa use udev-detect and not hal-detect.
+    - b872254 (volume: Add a PA_VOLUME_UI_MAX define for the recommended max
+               volume to show in UIs)
+  * 0210-PulseAudio-added-IT-block-to-fix-thumb-conditional-i.patch:
+    - added IT block to fix thumb conditional instruction build error messages
+  * debian/rules: Remove CFLAGS that are specific to arm, the above patch
+    makes those redundant (LP: #721498)
+  * debian/control: Add a dependency on pulseaudio-module-raop
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 10 Mar 2011 07:15:02 +1100
+
+pulseaudio (1:0.9.22+stable-queue-24-g67d18-0ubuntu1) natty; urgency=low
+
+  [ David Henningsson ]
+  * debian/patches/020x patches - add PulseAudio input mixer rewrite.
+    This will cause several HDA chips to have better named and controlled
+    sliders on the input side. 
+
+  [ Luke Yelavich ]
+  * New upstream snapshot based on stable queue:
+    - 67d1888 (client: Don't update smoother while corked)
+    - 6b280e9 (Fighting rewinds: Reduce calls to handle_seek)
+    - 3aeb047 (Fighting rewinds: Seek and write data in the same message)
+    - 1e1b299 (Core: Fix incorrect check of return value)
+    - 4080725 (tunnel: Fix automatic names when source/sink_name argument is
+              missing.)
+    - ec5a785 (ratelimit: fix log levels of log suppression messages)
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 18 Feb 2011 13:50:30 +1100
+
+pulseaudio (1:0.9.22+stable-queue-18-geb966-0ubuntu2) natty; urgency=low
+
+  * Fix FTBFS with ld.gold.
+
+ -- Matthias Klose <doko at ubuntu.com>  Wed, 19 Jan 2011 06:57:29 +0100
+
+pulseaudio (1:0.9.22+stable-queue-18-geb966-0ubuntu1) natty; urgency=low
+
+  [ Daniel T Chen ]
+  * debian/control: pulseaudio-module-zeroconf Depends on avahi-daemon
+    (LP: #689093)
+  * debian/patches/0101-update-stable-queue.patch: Apply 84c8b23c to
+    resolve incorrect header being used for libsndfile seen with pacat
+    --file-format (LP: #660504)
+  * debian/patches/0104-Load-RAOP-Zeroconf-by-default.patch: Follow
+    recommendation by Martin-Éric Racine to conditionally load support
+    by default for streaming to an Apple Airport Express (LP: #688272)
+  * debian/pulseaudio-utils.links: Also add pamon(1) and parecord(1)
+    (Closes: #599696)
+
+  [ David Henningsson ]
+  * debian/pulse-alsa.conf: Add name hint for default pcm device,
+    indicating that PulseAudio is active.
+
+  [ Luke Yelavich ]
+  * New upstream snapshot based on the stable queue branch:
+    - eb966f7 (build-sys: Make --disable-dbus actually work.)
+    - 8f8d247 (build-sys: Mention dbus support in the summary)
+    - b3ff4f4 (build-sys: Put in specific warnings when there is no udev or
+              DBUS support)
+    - 862bbee (console-kit: Console Kit support is dependent on DBUS and is
+              thus optional.)
+    - 7cb1401 (padsp: wrap __open_2 and __open64_2)
+    - 6f870f5 (fix bug about get source-output status)
+    - 4269b05 (Fix typos)
+    - 1c83b03 (Further clarify src- and speex- references in pulse-daemon.conf)
+    - 84c8b23 (Fix return value of pa_sndfile_format_from_string)
+    - d963b86 (core: Fix variable "has_whined" value bug)
+    - 52e3268 (trivial: Mention speex as a resampler reference in
+              pulse-daemon.conf)
+    - 3e6af07 (module-loopback: Prevent an infinite loop when rate adjusting
+              is disabled
+  * 0101-update-stable-queue.patch and
+    #0102-autoreconf.patch:
+    - Disable for now, since latest stable queue are roled into the snapshot
+      tarball
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 14 Jan 2011 10:03:49 -0600
+
+pulseaudio (0.9.22-1) experimental; urgency=low
+
+  * New upstream release
+  * debian/patches/0002-CVE-2009-1299.patch:
+    + Dropped, fixed upstream
+  * debian/patches/0003-Re-bootstrap.patch
+    + Dropped, not needed anymore
+  * debian/rules: Stop using -g0 on mips{,el} the toolchain has been fixed
+  * debian/rules, debian/control: Update build-depends and force building
+    with X11
+  * debian/control: Suggest rtkit
+  * debian/control: Prune unneeded depends of libpulse-dev
+
+ -- Sjoerd Simons <sjoerd at debian.org>  Sun, 05 Dec 2010 12:01:37 +0000
+
+pulseaudio (1:0.9.22-0ubuntu3) natty; urgency=low
+
+  * debian/pulseaudio-module-jack.install: Ship the jackdbus-detect module
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 08 Dec 2010 17:57:18 +1100
+
+pulseaudio (1:0.9.22-0ubuntu2) natty; urgency=low
+
+  * 0101-update-stable-queue.patch, update to latest stable queue:
+    - 205cad6 (jack: Add module-jackdbus-detect
+    - e9deb97 (build-sys: Include the .version file in the distribution
+               tarball)
+    - a1f1255 (build-sys: Fix make distcheck failure due to udev rules
+               fixed install path)
+    - 675cc0a (build-sys: Replace dummy Makefiles with proper Makefile.am's)
+    - bd769fa (rescue-streams: Fix segfault in some conditions)
+    - f6574c8 (volume: Add explicit checks for ARMv6 instructions)
+  * 0102-autoreconf.patch: Re-generate autotools pieces for the above update
+  * 0103-JACK-Load-module-jackdbus-detect-in-default.pa.patch: Enable jackdbus
+    module by default for now, hopefully longer term there will be a better
+    way to turn this module on/off
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 08 Dec 2010 16:58:27 +1100
+
+pulseaudio (1:0.9.22-0ubuntu1) natty; urgency=low
+
+  * New upstream release, based on the stable-queue branch
+  * Drop following patches, as applied upstream:
+    - 0101-alsa-mixer-add-profile-for-Native-Instruments-Koreco.patch
+    - 0102-intended-roles-Mark-devices-with-a-form-factor-of-he.patch
+  * debian/rules:
+    - Disable --as-needed due to a circular dependency for libpulsecommon
+    - Adjust filenames/paths for 0.9.22
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 26 Nov 2010 13:44:10 +1100
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-98-ga8d7-0ubuntu3) natty; urgency=low
+
+  * 0101-alsa-mixer-add-profile-for-Native-Instruments-Koreco.patch: Also
+    adjust src/Makefile.in, so that the new profile actually gets shipped
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 05 Nov 2010 14:27:34 -0400
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-98-ga8d7-0ubuntu2) natty; urgency=low
+
+  * debian/control: Update Vcs-Bzr field
+  * Pull latest fixes from stable queue:
+    - 8a30d4c (alsa-mixer: add profile for Native Instruments Korecontroller)
+    - 848dd37 (intended-roles: Mark devices with a form factor of 'headset' as
+               being appropriate for 'phone' streams)
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 05 Nov 2010 10:40:47 -0400
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-98-ga8d7-0ubuntu1) natty; urgency=low
+
+  * New upstream snapshot, based on the stable-queue branch
+  * debian/patches: Drop the following patches as they are applied upstream,
+    or were created to regenerate autotools files/package version
+    - 0090-use-volume-ignore-for-analog-output.patch
+    - 0093-backport-fixes-stable-queue-head.patch
+    - 0094-add-missing-mixer-paths-and-rerun-automake.patch
+    - 0095-cve-2009-1299.patch
+    - 0097-regenerate-configure.patch
+    - 0098-tarball-version.patch
+    - 0192-stream-restore-Clear-the-save_sink-save_source-flags.patch
+    - 0193-augment-properties-Search-for-.desktop-files-in-subf.patch
+    - 0194-device-manager-Ensure-that-sinks-sources-populate-th.patch
+    - 0195-SSE-MMX-ARM-Fix-high-frequency-noise-with-unusual-nu.patch
+  * debian/control: Update Vcs-Bzr link
+  * 0097-explicitly-link-libraries.patch: Patch to explicitly link pulseaudio
+    tests binaries against pulseaudio libraries, due to gcc 4.5 and new
+    binutils in natty enforcing explicit linking
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 29 Oct 2010 12:39:27 -0400
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu21.1) maverick-proposed; urgency=low
+
+  * 0195-SSE-MMX-ARM-Fix-high-frequency-noise-with-unusual-nu.patch:
+    - Pull fix from the upstream stable-queue branch a8d76e9 to Fix a high
+      frequency noise with an nunusual number of channels, when either SSE,
+      MMX, or ARM optimized volume scaling code is used. (LP: #445849)
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 14 Oct 2010 16:38:46 +1100
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu21) maverick; urgency=low
+
+  * Add 0192-stream-restore-Clear-the-save_sink-save_source-flags.patch
+    Clear the save_sink/save_source flags on apply_entry.
+  * Add 0193-augment-properties-Search-for-.desktop-files-in-subf.patch
+    Search for .desktop files in subfolders too.
+  * Add 0194-device-manager-Ensure-that-sinks-sources-populate-th.patch
+    Ensure that sinks/sources populate the device manager lists in order
+    of their priority.
+
+ -- Jonathan Riddell <jriddell at ubuntu.com>  Sun, 03 Oct 2010 20:38:24 +0100
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu20) maverick; urgency=low
+
+  * 0093-backport-fixes-stable-queue-head.patch: Backport the following
+    changesets from the stable-queue branch:
+    + 2c564f2 (xcb: Ensure the XCB connection is valid before using it.)
+    + 5c0bc09 (xcb: xcb_get_setup() can return 0, so make sure we check it before using)
+    + 165cb87 (x11: Use the default screen for X11 properties.)
+    (LP: #640127)
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sat, 18 Sep 2010 08:46:31 -0400
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu19) maverick; urgency=low
+
+  * Removed packaging for a patch that was being tested locally, as the
+    patch is not going into maverick. Fixes FTBFS
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 15 Sep 2010 14:38:38 +1000
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu18) maverick; urgency=low
+
+  [ Emmet Hikory ]
+  * Drop 0001-change-resample-and-buffering.patch
+  * debian/rules: Add arch-specific build-time configuration patching system
+    - set resample-method to speex-fixed-1 and fragments to 2 for armel
+    - set resample-method to speex-float-1 and fragments to 8 for other arches
+    - Closes LP: #623242
+
+  [ Luke Yelavich ]
+  * debian/rules:
+    - Back up src/daemon/daemon.conf.in, restoring on package clean, allowing
+      the package to be built more than once, and keeping the diff sane
+    - Disable flat volumes via regular expression instead of a patch, to
+      prevent the mess that goes with touching a file multiple times, and
+      with multiple methods
+  * 0093-backport-fixes-stable-queue-head.patch: Backport the following
+    changesets from the stable-queue branch:
+    + 6c8660a (alsa: Fix assertion on mmap_write (triggered via a52 plugin))
+    + aaae99d (alsa: disable rewinds when using ALSA plugins)
+    + 4a1072e (udev: fix hex decoding)
+    + 2b88634 (x11: Partially convert to XCB.)
+    + 9375019 (alsa: resume smoother after unsuspend)
+    + 4fb02d8 (alsa: increase the smoother window)
+    + e2ef3a1 (alsa: don't make use of tsched related variables when tsched is
+               disabled)
+    + 514fd1e (add rewind-safeguard parameter)
+    + 8748ebd (alsa-sink: Get rid of a compiler warning regarding
+               rewind_safeguard type.)
+    + a65825f (alsa: Set the rewind safeguard proportionally to sample spec)
+    + 3d9b710 (smoother: avoid losing precision)
+    + 1503b8c (alsa-source: refactor smoother and device start)
+    + 74c117f (alsa-time-test: make test usable for capture too)
+    + 1c29f55 (alsa: work around slightly broken _delay implementations)
+    + 1ff360c (alsa: make defines for smoother configuration)
+    + 28f4aeb (alsa-mixer: add profile for Traktor Kontrol S4)
+    + eef247b (alsa: Only set the 'first' flag to false when we actually call
+               snd_pcm_start())
+  * debian/control: Add libxcb-atom1-dev and libx11-xcb-dev to build depends
+  * debian/patches/0090-disable-flat-volumes.patch: Drop, as per above
+  * debian/patches/0097-regenerate-configure.patch: Refreshed
+  * debian/patches/0098-tarball-version.patch: Ensure the version string for
+    pulseaudio internally stays the same, in case the build process wants
+    to regenerate autotools files
+  * debian/patches/0094-add-missing-mixer-paths-and-rerun-automake.patch:
+    - Remove the patch to Makefile.in, easier to do it all at once in a
+      single patch later in the series
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 15 Sep 2010 13:57:55 +1000
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu17) maverick; urgency=low
+
+  * No-change rebuild to pick up new j-a-c-k shlibs
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 21 Jul 2010 11:29:18 +0200
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu16) maverick; urgency=low
+
+  * Include /usr/bin/start-pulseaudio-kde and its autostart file now that KDE
+    will be using PulseAudio by default in Maverick (LP: #563250)
+  * Also update 0057-load-module-x11-bell.patch to give its improvements to
+    /usr/bin/start-pulseaudio-kde as well
+
+ -- Jonathan Thomas <echidnaman at kubuntu.org>  Mon, 07 Jun 2010 18:32:53 -0400
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu15) maverick; urgency=low
+
+  * 0093-backport-fixes-stable-queue-head.patch: Backport the following
+    changesets from the stable-queue branch:
+    + bc7314f (name all threads for /proc/$PID/task/$TID/comm)
+    + d519ca4 (prevent crash on jack server shutdown) (LP: #538815)
+    + 65f89dc (fix bracketing in pa_rtp_recv())
+  * debian/01PulseAudio: modify the ConsoleKit active seat checks in the
+    pm-utils hook so that:
+    - pre-suspend: all users' sink & source states are stored, then only
+      the active seat's sinks and sources are muted
+    - post-resume: all users' sink & source pre-suspend states are
+      restored
+    This resolves the issue where users' post-resume sink & source
+    states don't correspond with their pre-suspend ones.
+    (LP: #569395)
+  * debian/01PulseAudio: fix broken quoting and misuse of su -l. Merged
+    from lp:~hyperair/pulseaudio/fix-01Pulseaudio-quoting. Thanks,
+    Chow Loong Jin! (LP: #572391)
+  * debian/control: Update bzr branch for maverick.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sat, 08 May 2010 11:08:56 -0400
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu14) lucid; urgency=low
+
+  * 0096-lp451635-handle-dove-x0-line-hp-swap.patch: Make the connector
+    work as intended: if 'Analog Output' is selected in the dropdown,
+    then 'Line HP Swap' is muted; if 'Analog Headphones' is selected,
+    then 'Line HP Swap' is unmuted. This better fits existing speaker
+    semantics and actually works. Many thanks to Tobin Davis for
+    helping chase this one. Really closes (LP: #451635)
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Fri, 26 Mar 2010 15:18:35 -0700
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu13) lucid; urgency=low
+
+  [ Daniel T Chen ]
+  * 0093-backport-fixes-stable-queue-head.patch: Backport the following
+    changesets from the stable-queue branch:
+    + a7c1778 (don't pick monitor sources automatically for role-based
+               device selection).
+    + e8b83fa (handle asyncns failure when IPv6 is not supported in the
+               kernel).
+  * 0096-lp453966-handle-digmic-pt2.patch: Raise the priority of the
+    'Digital Mic 1' digital input source for newer Dell laptops.
+    (LP: #453966)
+  * 0096-lp451635-handle-dove-x0-line-hp-swap.patch: Add 'Line HP Swap'
+    to the Headphone profile. (LP: #451635)
+  * debian/control: Update Vcs-Bzr to point to new branch that uses pack
+    repo format 2a.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 25 Mar 2010 21:58:46 -0700
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu12) lucid; urgency=low
+
+  * debian/pulseaudio.init: Remove udev from Required-* LSB headers
+    (LP: #432301)
+  * debian/patches/:
+    + 0095-cve-2009-1299.patch: Fix insecure temporary file creation;
+      pulled from upstream stable-queue d3efa43; CVE-2009-1299.
+      (LP: #509008)
+    + 0096-lp533877-handle-digmic.patch: Prefer the built-in digital
+      mic on newer Dells, e.g., XPS 1330. (stable-queue 29845be)
+      (LP: #533877)
+    + 0097-regenerate-configure.patch: Apply changes from stable-queue
+      f9b31fe (gobject linking) and d3efa43 above.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Wed, 10 Mar 2010 18:53:51 -0500
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu11) lucid; urgency=low
+
+  * 0093-backport-fixes-stable-queue-head.patch: Backport the following
+    changesets from the stable-queue branch:
+    + 522c44 (strip spaces from ALSA card/pcm names)
+    + 195069 (use pa_strip())
+    + dd682d (reset max_rewind/max_request in sink while suspending)
+    + 30f28e (fix wrong counters by using pa_memblockq_pop_missing() for
+      all request handling)
+    + 0d1154 (rework how stream volumes affect sink volumes)
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Mon, 22 Feb 2010 00:22:50 -0500
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu10) lucid; urgency=low
+
+  * 0093-backport-fixes-stable-queue-head.patch: Backport the following
+    changesets from the stable-queue branch:
+    + dfe27f (don't complain about missing SHM segments)
+    + 5ce18c (fix definition of INVALID_INDEX for vala)
+    + 6bbdd2 (fix definition of the GLib mainloop adapter for vala)
+    + 3f44bf (Use "Subwoofer" in channelmap)
+    + 117c99 (fix wrapping of port setting calls for vala)
+    + ddabaa (explicitly mention 'test' role in proplist)
+    + 8adf53 (increase verboseness when not restoring sink)
+    + 180589 (use sample name for unmodified fallback)
+    + f9b957 (don't queue cached sample when sink is suspended)
+    + b2e9fb (pass buffer_attr to recording streams)
+    + a469d4 (make devices resume for corked state to fix latency
+      miscalculation) (LP: #511558)
+    + 4a3210 (improve buffer_attrs logging)
+  * 0094-add-missing-mixer-paths-and-rerun-automake.patch has been
+    merged upstream (047e16f in the stable-queue branch), but we'll continue to
+    carry it until the next stable tarball is rolled.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sun, 21 Feb 2010 22:37:37 -0500
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu9) lucid; urgency=low
+
+  * 0094-add-missing-mixer-paths-and-rerun-automake.patch: Fix missing paths
+    elements that broke volume control.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 18 Feb 2010 23:56:42 -0500
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu8) lucid; urgency=low
+
+  * Back out 307bd1 until we can roll a new tarball. Applying it to the
+    current source package requires all sorts of nasty hacks.
+    (LP: #523716)
+  * Drop 0094-autoconf.patch, as it's no longer needed
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 18 Feb 2010 07:32:58 -0500
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu7) lucid; urgency=low
+
+  * debian/control: Since JACK has been approved for promotion back into
+    main, add its packages
+  * 0093-backport-fixes-stable-queue-head.patch: Backport the following
+    changesets from the stable-queue branch:
+    + 19fa81 (always fulfill write requests from the server)
+    + 96ec29 (store away fd type for pacmd)
+    + 6e064d (don't enter busy loop when reading from stdin very early)
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Wed, 17 Feb 2010 22:33:34 -0500
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu6) lucid; urgency=low
+
+  [ Daniel T Chen ]
+  * pulseaudio.default: More clearly describe the conditions for
+    autospawn to function correctly given the recent login-speedup work.
+    (As a side effect, it now also lists what one needs to do to disable
+    PA.)
+  * 0093-backport-fixes-stable-queue-head.patch: Backport the following
+    changesets from the stable-queue branch:
+    + a631be (PA_SINK_INPUT_IS_LINKED typo fix)
+    + e8cb96 ('Desktop Speaker' handling)
+    + 7d6bab ('Shared Mic/Line in', 'Analog Source' handling)
+    + 0c836a ('Internal Mic' handling)
+    + 307bd1 (default output port names)
+    + f9b31f (gobject explicit linking)
+    + ff2474 (padsp handling of /dev/audio)
+    + 96592c (dbus timeout callback timer fix)
+    + 5e2af2 (logging of eventfd read failures)
+  * 0094-autoconf.patch: Rerun autoconf given explicit gobject link
+    addition; readd version string.
+
+  [ Martin Pitt ]
+  * 0092-delay-gnome-autostart.patch: Push it out a little further; the X11
+    bell is not crucial at desktop startup, and it keeps other programs from
+    doing more urgent initialization.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Mon, 08 Feb 2010 12:42:02 -0500
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu5) lucid; urgency=low
+
+  * Add bzr-builddeb configuration (merge mode).
+  * debian/control: Prefix the Debian git Vcs-* fields with XS-Debian-*, so
+    that debcheckout on Ubuntu will actually work.
+  * Add 0092-delay-gnome-autostart.patch: Delay applet startup by two seconds,
+    so that pulseaudio has started up enough to avoid starting it a second
+    time through autospawn.
+
+ -- Martin Pitt <martin.pitt at ubuntu.com>  Mon, 01 Feb 2010 18:12:13 -0800
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu4) lucid; urgency=low
+
+  * debian/01PulseAudio: Break from state (re)store in the correct
+    place!
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sun, 31 Jan 2010 13:44:57 -0500
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu3) lucid; urgency=low
+
+  * debian/01PulseAudio:
+    + Fix su(1) -c quoting (LP: #515038)
+    + Now that PA only stores mixer state for the active CK seat, and
+      because the active ConsoleKit seat is the only one we care about,
+      we don't need to save all PA users' mixer states.  Thus, we can
+      stop (re)storing state as soon as we've finished processing the
+      active ConsoleKit seat, thereby further optimizing the suspend/
+      resume speed.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sun, 31 Jan 2010 13:16:46 -0500
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu2) lucid; urgency=low
+
+  * debian/01PulseAudio: Use su(1) instead of sudo(8)
+    (LP: #489144, #498980).
+  * debian/patches/series: To trim the startup time, don't lazy-load
+    sounds by not applying 0005-load-sample-dir-lazy.patch.
+  * 0091-dont-load-cork-music-on-phone.patch: Refresh.
+  * 0057-load-module-x11-bell.patch: Don't explicitly load the daemon
+    since it will autospawn if necessary, and if the system or user
+    configuration has autospawn disabled it breaks that semantics
+    (LP: #513120).
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Fri, 29 Jan 2010 14:37:52 -0500
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu1) lucid; urgency=low
+
+  * New snapshot of stable-queue branch as requested by upstream
+  * debian/patches/0099-back-out-8d3566.patch: Drop. Seeking is fixed
+    in the latest snapshot.
+  * debian/pulseaudio.default: Update instructions for using system
+    mode.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sun, 17 Jan 2010 22:51:57 -0500
+
+pulseaudio (1:0.9.22~0.9.21+stable-queue-24-gfa64-0ubuntu1) lucid; urgency=low
+
+  * Reroll actual stable-queue tarball (arrrg!)
+  * debian/01PulseAudio: Rework pacmd bits (LP: #507941)
+  * debian/patches/:
+    + add:  0099-back-out-8d3566.patch (upstream says this commit causes
+            regressions)
+    - drop: 0099-change-configure-git-version-tag.patch (no longer
+            relevant)
+    + refresh: 0001-change-resample-and-buffering.patch
+               0054-mute-iec958-optical-raw-for-audigyX.patch
+               0090-disable-flat-volumes.patch
+               0091-dont-load-cork-music-on-phone.patch
+               0057-load-module-x11-bell.patch
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Fri, 15 Jan 2010 19:06:15 -0500
+
+pulseaudio (1:0.9.22~0.9.21+341-g62bf-0ubuntu1) lucid; urgency=low
+
+  * New snapshot based on stable-queue git branch (testing requested
+    specifically by upstream)
+    - LP: #164745, #173212, #201391, #204536, #207796, #210016, #221038,
+    - LP: #226342, #230408, #236423, #237443, #250059, #269585, #274304,
+    - LP: #274577, #275474, #277532, #277566, #277932, #278025, #280534,
+    - LP: #283049, #286816, #287036, #292732, #298011, #298301, #300290,
+    - LP: #302038, #311497, #311853, #324062, #339448, #344057, #348979,
+    - LP: #350829, #356206, #367379, #367544, #369822, #371897, #374846,
+    - LP: #375570, #381801, #399515, #402950, #403786, #408169, #409322,
+    - LP: #409723, #410326, #410446, #417695, #417976, #419271, #421072,
+    - LP: #422774, #423979, #424655, #425028, #427016, #431072, #432660,
+    - LP: #437640, #437996, #442191, #443306, #443389, #446719, #449762,
+    - LP: #455417, #461532, #464652, #483191, #497537, #503780
+  * debian/patches/:
+    + add: 0099-change-configure-git-version-tag.patch: Match released
+           upstream 0.9.21 for shlibs and LIBPULSE_VERSION_INFO
+    - drop: 0004-set-tsched0.patch (no longer relevant)
+            0050-revert-pacmd-poll-argv.patch (no longer relevant)
+            0056-dont-bail-on-sound-class-modem.patch (merged)
+            0056-ignore-sound-class-modem.patch (merged)
+            0058-Backport-4c793.patch (merged)
+            0059-Backport-978d3.patch (merged)
+            0060-fix-implicit-func-decl-cpu-arm.patch (merged)
+            0061-Backport-c5fdb.patch (merged)
+            0070-dont-bail-on-sound-class-modem-devs.patch (merged)
+    + refresh: 0001-change-resample-and-buffering.patch
+               0090-disable-flat-volumes.patch
+               0091-dont-load-cork-music-on-phone.patch
+               0057-load-module-x11-bell.patch
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 14 Jan 2010 20:33:05 -0500
+
+pulseaudio (0.9.21-3) unstable; urgency=low
+
+  * debian/rules: Compile with -g0 on mips{,el} to work around #519006 in
+    gcc-4.4
+
+ -- Sjoerd Simons <sjoerd at debian.org>  Sat, 03 Jul 2010 15:12:54 +0100
+
+pulseaudio (0.9.21-2) unstable; urgency=low
+
+  * Import NMU patches into pkg-pulse git, thanks to the security team for
+    their work!
+  * debian/patches/0003-Re-bootstrap.patch
     + Added. Update configure so we don't have to re-run autotools when
     building the package (Closes: #576457, #576546, #576769)
   * Install a KDE specific startup file and module-device-manager.
@@ -603,6 +2338,91 @@ pulseaudio (0.9.21-1) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Mon, 23 Nov 2009 23:51:16 +0000
 
+pulseaudio (1:0.9.21-0ubuntu6) lucid; urgency=low
+
+  * Backport fix from master HEAD:
+    + 0061-Backport-c5fdb.patch (LP: #502992)
+  * The following patches have been merged upstream, but we'll continue
+    to apply them here until the next upstream snapshot:
+    . 0056-ignore-sound-class-modem.patch
+    . 0060-fix-implicit-func-decl-cpu-arm.patch
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Tue, 05 Jan 2010 18:34:40 -0500
+
+pulseaudio (1:0.9.21-0ubuntu5) lucid; urgency=low
+
+  * Refresh 0060-fix-implicit-func-decl-cpu-arm.patch with more FTBFS-
+    on-armel fixes (all submitted upstream).
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 17 Dec 2009 00:01:49 -0500
+
+pulseaudio (1:0.9.21-0ubuntu4) lucid; urgency=low
+
+  * 0060-fix-implicit-func-decl-cpu-arm.patch: Fix FTBFS on armel.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Wed, 16 Dec 2009 22:45:25 -0500
+
+pulseaudio (1:0.9.21-0ubuntu3) lucid; urgency=low
+
+  * 0070-dont-bail-on-sound-class-modem-devs.patch: Fix parameter
+    in function call. Thanks to Whoopie for spotting.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Wed, 16 Dec 2009 20:13:43 -0500
+
+pulseaudio (1:0.9.21-0ubuntu2) lucid; urgency=low
+
+  * Fix LP: #394500, #450222:
+    + 0070-dont-bail-on-sound-class-modem-devs.patch:
+      + Add pa_udev_get_sysattr() helper function so that we can
+        retrieve pcm_class.
+      + Add short-circuit in is_card_busy(). Currently there is an
+        incorrect break out of the loop when an HDA modem is driven by
+        slmodemd/hsfmodem. An HDA modem resides in device 6 and will
+        not contain "closed\n" for
+        /proc/asound/card.../pcm.../sub.../status.
+  * 0058-Backport-4c793.patch: Use pa_stream pointers to hashmaps
+    instead of dynarrays.
+  * 0059-Backport-978d3.patch: Mark shared variables as volatile
+    to supress compiler optimizations.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sun, 06 Dec 2009 19:40:04 -0500
+
+pulseaudio (1:0.9.21-0ubuntu1) lucid; urgency=low
+
+  [ Daniel T Chen ]
+  * New upstream bugfix release
+  * debian/control: pulseaudio-module-raop must Depends
+    pulseaudio-module-zeroconf (LP: #484870). Thanks, Dominic Evans!
+  * Bump for 0.9.21:
+    + debian/libpulse0.shlibs
+    + debian/pulseaudio.shlibs
+    + debian/rules
+  * debian/pulseaudio.install:
+    debian/copyright: Amend for addition of:
+    + module-device-manager.so
+  * debian/README.Debian: Update for Ubuntu 9.04+.
+  * 0002-Fix-makefiles-to-include-all-alsa-path-files-on-inst.patch:
+    Drop, fixed upstream.
+  * 0051-fix-sigfpe-mcalign.patch: Drop, needs fixing in alsa-kernel
+    and alsa-lib.
+
+  [ Chow Loong Jin ]
+  * debian/01PulseAudio: Add/modify functions to (re)store sink/source
+    state for (resume/)suspend (LP: #404986, #483900)
+
+  [ Luke Yelavich ]
+  * Remove wrapper scripts and accessibility special case, to help with the
+    desktop startup time. The accessibility case should be solved in
+    speech-dispatcher by the time lucid ships.
+    - debian/patches/0006-a11y-special-case-disable.patch: Removed
+    - debian/70pulseaudio: Removed
+    - debian/pulse-session: Removed
+    - debian/pulseaudio.install: Re-add the xdg autostart desktop file
+    - debian/pulseaudio.preinst: Instead of removing the xdg autostart desktop
+      file on upgrade, remove the 70pulseaudio X Session script on upgrade
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Wed, 25 Nov 2009 16:34:54 -0500
+
 pulseaudio (0.9.20-1) unstable; urgency=low
 
   * New upstream release
@@ -611,6 +2431,123 @@ pulseaudio (0.9.20-1) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sat, 14 Nov 2009 22:50:52 +0000
 
+pulseaudio (1:0.9.20-0ubuntu3) lucid; urgency=low
+
+  * drop the enforced switch to ARMv6 in debian rules (we build for cortex-a8
+    by default now).
+  * Make sure the arm specific assembler code builds properly with thumb
+    support by adding -Wa,-mimplicit-it=thumb instead until it is added to
+    the default compiler flags (fixes FTBFS).
+
+ -- Oliver Grawert <ogra at ubuntu.com>  Wed, 25 Nov 2009 14:16:59 +0100
+
+pulseaudio (1:0.9.20-0ubuntu2) lucid; urgency=low
+
+  * Add 0002-Fix-makefiles-to-include-all-alsa-path-files-on-inst.patch
+    from Debian unstable (thanks, Sjoerd Simons!)
+  * Fix 0055-handle-Master-Front.patch to handle only front elements
+    based on comments from Lennart. The patch now does the right thing
+    despite linux still doing the wrong thing, but at least we handle
+    cases where linux will do the right thing.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sun, 15 Nov 2009 13:45:49 -0500
+
+pulseaudio (1:0.9.20-0ubuntu1) lucid; urgency=low
+
+  * New upstream bugfix release
+    + Fix BT validation (LP: #437293)
+  * debian/control:
+    + pulseaudio Provides pulseaudio-module-hal, pulseaudio-module-udev,
+      and pulseaudio-module-rygel-media-server for upgrades (really
+      fixes LP #477382)
+  * debian/patches/:
+    - 0002-work-around-suspend-on-idle-source-sink-race.patch:
+    - 0052-revert-sse2-optimize.patch:
+    - 0055-backport-alsa-bt-position-fixes-b3592a1.patch:
+      Remove; applied upstream
+    + 0054-mute-iec958-optical-raw-for-audigyX.patch: Refresh
+    + 0055-handle-Master-Front.patch: For new VIA-based HDA, handle
+      this mixer control until we've fixed it in linux (LP: #478868)
+  * Bump for 0.9.20:
+    + debian/libpulse0.shlibs
+    + debian/pulseaudio.shlibs
+    + debian/rules
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 12 Nov 2009 19:19:21 -0500
+
+pulseaudio (1:0.9.19-2ubuntu2) lucid; urgency=low
+
+  * debian/control:
+    + Promote pulseaudio-utils to Depends for pulseaudio so that the
+      pm-utils script is present (LP: #478182)
+    - Drop obsolete Depends on pulseaudio-module-udev for pulseaudio
+      (LP: #477382)
+  * debian/01PulseAudio: Don't fail suspend/resume when system-wide
+    daemon is running (LP: #476505)
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Fri, 06 Nov 2009 18:37:36 -0500
+
+pulseaudio (1:0.9.19-2ubuntu1) lucid; urgency=low
+
+  * Merge from Debian unstable, remaining changes:
+    - epoch (my stupid fault :S)
+    - Don't build against, and create jack package. Jack is not in main
+    - use speex-float-1 resampler to work better with lack of PREEMPT in
+      karmic's -generic kernel config, also change buffer size
+    - Add alsa configuration files to route alsa applications via pulseaudio
+    - Move libasound2-plugins from Recommends to Depends
+    - Add pm-utils sleep hook to suspend (and resume) users' pulseaudio
+      daemons
+    - Make initscript more informative in the default case of per-user
+      sessions
+    - add status check for system wide pulseaudio instance
+    - create /var/run/pulse, and make restart more robust
+    - LSB {Required-*,Should-*} should specify hal instead of dbus,
+      since hal is required (and already requires dbus)
+    - indicate that the system pulseaudio instance is being started from the init
+      script
+    - Install more upstream man pages
+    - Link to pacat for parec man page
+    - check whether pulseaudio is running before preloading the padsp library
+    - Add DEB_OPT_FLAG = -O3 as per recommendation from
+      pulseaudio-discuss/2007-December/001017.html
+    - cache /usr/share/sounds/ubuntu/stereo/ wav files on pulseaudio load
+    - Generate a PO template on build
+    - add special case to disable pulseaudio loading if accessibility/speech
+      is being used
+    - the esd wrapper script should not load pulseaudio if pulseaudio is being
+      used as a system service
+    - add a pulseaudio apport hook
+    - fix some typos in README.Debian
+    - drop padevchooser(Recommends) and pavucontrol (Suggests)
+    - drop libasyncns-dev build dependency, its in universe
+    - add libudev-dev as a build-dependency
+    - Fix initialization of devices with modem subdevices
+    - Backport ALSA BlueTOoth position fixes from git HEAD
+    - Disable cork-music-on-phone
+    - Revert sse2 optimizations
+    - disable flat volume
+    - Handle div by zero attempts
+    - Mute IEC958 Optical Raw by default
+    - use tdd instead of gdbm
+  * debian/control:
+    - Dro packages, due to debian including the files in these packages in the
+      main pulseaudio package: pulseaudio-module-udev,
+      pulseaudio-module-udev-dbg, pulseaudio-module-rygel-media-server,
+      pulseaudio-module-rygel-media-server-dbg
+    - Add conflicts/replaces for pulseaudio-module-udev and
+      pulseaudio-module-rygel-media-server
+    - Add replaces for pulseaudio-module-hal to the pulseaudio package to handle
+      upgrades from hardy
+    - Remove rtkit from conflicts, and add it to recommends, as 2.6.32 has the
+      needed patches
+
+  [ Daniel T Chen ]
+  * 0057-load-module-x11-bell.patch: Load module-x11-bell in the
+    start-pulseaudio-x11 script (LP: #301174)
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 06 Nov 2009 14:07:19 +1100
+
 pulseaudio (0.9.19-2) unstable; urgency=low
 
   * Built with normal old-style hal support on kfreebsd and the hurd
@@ -637,6 +2574,65 @@ pulseaudio (0.9.19-1) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sat, 03 Oct 2009 18:22:56 +0100
 
+pulseaudio (1:0.9.19-0ubuntu4) karmic; urgency=low
+
+  * Remove 0053-fix-sigsegv-module-bluetooth-device.patch, as it did
+    more harm than good (reopens LP #437293).
+  * debian/01PulseAudio: Fix bashisms, and make suspend/resume actually
+    work with sudo -H -u (LP: #432096, #450461).
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Tue, 20 Oct 2009 10:29:04 -0400
+
+pulseaudio (1:0.9.19-0ubuntu3) karmic; urgency=low
+
+  [ Tony Espy ]
+  * debian/control: Add a Conflicts for rtkit so we force removal, and
+    hence get more testing coverage between now and Karmic final (LP: #452458).
+
+  [ Daniel T Chen ]
+  * debian/patches/0056-ignore-sound-class-modem.patch:
+    + Apply patch from Whoopie to fix initialization of devices with
+      modem subdevices (LP: #394500, #450222)
+
+ -- Tony Espy <espy at ubuntu.com>  Thu, 15 Oct 2009 15:33:02 -0400
+
+pulseaudio (1:0.9.19-0ubuntu2) karmic; urgency=low
+
+  * debian/control: Drop rtkit from recommends, as the kernel patches have
+    not landed in karmic, so rtkit is currently useless.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 14 Oct 2009 12:02:50 +1100
+
+pulseaudio (1:0.9.19-0ubuntu1) karmic; urgency=low
+
+  * New upstream bugfix release
+  * debian/:
+    . {libpulse0,pulseaudio}.shlibs:
+    . shlibs{,_pulseaudio}.local:
+    . rules: Update for new release
+  * debian
+    + pulseaudio.dirs:
+    . patches/0006-a11y-special-case-disable.patch:
+    . pulse-session: Use a system-wide flag to assist in fixing
+      alsactl store race.
+  * debian/patches/:
+    - 0060-backport-c194d.patch: Drop, subsumed by new release
+    + 0053-fix-sigsegv-module-bluetooth-device.patch: Don't strcmp
+      uninitialized memory (LP: #437293)
+    + 0055-backport-alsa-bt-position-fixes-b3592a1.patch: Apply the
+      following changesets from origin/master HEAD for fixes:
+      40c1ca76c48147c7648e1f1a72cc2c747f3d0c9b,
+      7b682c969025845f75cbc74a9f830ad2dec8a415,
+      c96d2d1117a7e59b351358c8cdd79ef465ddbd49,
+      b3592a160f0d2a28605048a81c0261bf7c45acbb
+    + 0091-dont-load-cork-music-on-phone.patch: Disable for Karmic;
+      it's confusing users (LP: #437638)
+  * Previous uploads resolved Launchpad bug reports:
+    - LP: #434003 (crashed with SIGILL in pa_smoother_translate() )
+    - LP: #437638 (cpulimit.c: Received request to terminate)
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Tue, 06 Oct 2009 18:40:38 -0400
+
 pulseaudio (0.9.18-1) unstable; urgency=low
 
   * New upstream release
@@ -664,6 +2660,46 @@ pulseaudio (0.9.18-1) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sun, 27 Sep 2009 23:46:37 +0200
 
+pulseaudio (1:0.9.18-0ubuntu3) karmic; urgency=low
+
+  * debian/patches/:
+    + 0052-revert-sse2-optimize.patch: Revert 3d5a57 causing audio
+      anomalies (LP: #428619)
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Tue, 22 Sep 2009 22:19:42 -0400
+
+pulseaudio (1:0.9.18-0ubuntu2) karmic; urgency=low
+
+  * Remove epoch again, fixes FTBFs.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 21 Sep 2009 11:12:00 +1000
+
+pulseaudio (1:0.9.18-0ubuntu1) karmic; urgency=low
+
+  [ Daniel T Chen ]
+  * New upstream bugfix release
+  * debian/patches/:
+    - 0052-backport-56b6e18030.patch: Drop
+    - 0053-fix-output-element.patch: Drop, applied upstream
+    - 0090-use-volume-ignore-for-analog-output.patch: Stop applying
+      this patch. Too many people are confused as to why PCM isn't
+      being changed when they adjust PA's volume.
+    + 0060-backport-c194d.patch: Backport fixes from 0.9.18-stable
+      branch (to changeset c194db71b0ff853b4f46df26e135edf63b215451)
+    + 0090-disable-flat-volumes.patch: Many people seem uncomfortable
+      with PA's new default volume adjustment routine, so disable it
+      in favour of the existing behaviour known in previous Ubuntu
+      releases. The downside is that the user again has many knobs to
+      fiddle; the upside is that applications can no longer drop the
+      volume floor. This addresses LP: #403859, #433209.
+
+  [ Luke Yelavich ]
+  * debian/pulse-alsa.conf: Expose the pulse device to the ALSA name hint API.
+    Thanks to David Henningsson <launchpad.web at epost.diwic.se> for the patch.
+  * Add epoch to shlibs version definitions.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 21 Sep 2009 10:28:25 +1000
+
 pulseaudio (0.9.17-1) unstable; urgency=low
 
   * New upstream release
@@ -672,6 +2708,30 @@ pulseaudio (0.9.17-1) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sat, 12 Sep 2009 10:27:46 +0100
 
+pulseaudio (1:0.9.17-0ubuntu2) karmic; urgency=low
+
+  * debian/patches/:
+    + 0051-fix-sigfpe-mcalign.patch: Handle div by zero attempts
+      (LP: #412224)
+    + 0052-backport-56b6e18030.patch: Backport fixes from git HEAD
+      (56b6e18030b5a467946bd0a5803ec119efccdc8a)
+    + 0053-fix-output-element.patch: Fix misspelling of Surround
+    + 0054-mute-iec958-optical-raw-for-audigyX.patch: Mute
+      IEC958 Optical Raw by default (LP: #400629, #408370)
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 17 Sep 2009 19:57:15 -0400
+
+pulseaudio (1:0.9.17-0ubuntu1) karmic; urgency=low
+
+  [ Daniel T Chen ]
+  * New upstream release
+
+  [ Luke Yelavich ]
+  * debian/rules: refer to the 0.9.17 directory
+  * bump shlibs
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 14 Sep 2009 10:01:24 +1000
+
 pulseaudio (0.9.16-1) unstable; urgency=low
 
   * New upstream release
@@ -684,18 +2744,263 @@ pulseaudio (0.9.16-1) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Thu, 10 Sep 2009 21:53:15 +0100
 
+pulseaudio (1:0.9.16-0ubuntu1) karmic; urgency=low
+
+  [ Daniel T Chen ]
+  * debian/patches/0090-use-volume-ignore-for-analog-output.patch:
+    + Realign volume control behaviour with existing Ubuntu releases,
+      i.e., disable volume = merge and use volume = ignore for
+      analog output
+
+  [ Luke Yelavich ]
+  * New upstream release
+  * debian/patches/0057-introspect-version-fixes.patch (LP: #426210),
+    debian/patches/0056-alsa-rework.patch,
+    debian/patches/0055-llvm-clang-analyzer-fixes.patch,
+    0054-volume-libpulse-backported-fixes.patch,
+    0053-add-input-sources.patch,
+    debian/patches/0052-disable-cpu-limit.patch: Dropped, all applied upstream
+  * debian/patches/0051-reduce-lib-linking.patch: Drop, since we are not going
+    to be doing bi-arch pulseaudio packages for karmic
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 11 Sep 2009 09:24:39 +1000
+
+pulseaudio (1:0.9.16~test7-14-g7ca81-0ubuntu2) karmic; urgency=low
+
+  * debian/control: Fix missing pulseaudio-module-rygel-media-server
+    Depends thanks to lintian
+  * debian/patches/0054-use-sse2-volume.patch:
+    - Remove, resolved differently upstream (see below)
+  * debian/patches/0054-volume-libpulse-backported-fixes.patch:
+    + Add fixes from git HEAD:
+      e6a666d8d5fffbc9847b51b35349b88d74970079 (PA_BYTES_SNPRINT_MAX)
+      5cf0c1e544a5fce97d514c793256b2e301277136 (rearrange functions)
+      508c462841fd087528649ed1ca3646363387bb5d:
+         b5ac3839e18524524fa3e0da7ec68dbce16e8203 (remap/vol only SSE2)
+         723499439f575f744f07c85a42b47d95cdc98de6 (init SSE2)
+      3bbc5e6a4d0211d8cedd2fe6698c2e2c07d1c4b9 (add PA_VOLUME_INVALID)
+      cc6c4fe91f916451bbea9073619c11a6b122b684 (check pa_volume_t args)
+      9755bfa58af0c27b478d5d8cc56013527a6f660b (drop expensive checks)
+      d000dd6f4b976894558613f69bdad2974cce7d1e (NULL chan map consist.)
+      41a0dc1e9987ae00b605fd88bf887becbdf097d5 (log invalid fade/bal)
+      08a4d57ce2f20173ea8a90e597a3ebcd28398242 (ok NULL proplist inv.)
+  * debian/patches/0055-llvm-clang-analyzer-fixes.patch:
+    + Add fixes from git HEAD:
+      f5046759cdd72daf5ba3b31c9dfc7b8d5be6bc9b..
+      7cc100d9e1d7093da44c8c83cbf61bb8c6000d9a
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Tue, 08 Sep 2009 18:21:00 -0400
+
+pulseaudio (1:0.9.16~test7-14-g7ca81-0ubuntu1) karmic; urgency=low
+
+  * New git snapshot of origin/master (0.9.16~test7-14-g7ca81)
+    fixes LP: #419658, #422451, #424127
+  * debian/pulseaudio.install: add module-loopback
+  * debian/control: remove liboil*-dev build-dependency thanks to
+    included ASM optimisations
+  * debian/copyright: update; we've added module-loopback
+  * debian/patches/0052-disable-cpu-limit.patch: Disable cpu limit as
+    per 812be327836c93492ad389333bcc037566141eb8
+  * debian/patches/0053-add-input-sources.patch: Add internal mic and
+    docking station as per 8cd635bc614834c13d0f1c586d472b4a52b98664
+  * debian/patches/0054-use-sse2-volume.patch: Only use if SSE2 is
+    available. This is a workaround for LP: #418448, thanks "knarf"!
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sun, 06 Sep 2009 14:23:15 -0400
+
+pulseaudio (1:0.9.16~test6-3-g57e1-0ubuntu2) karmic; urgency=low
+
+  * add -march=armv6 to compiler flags on armel, recent upstream changes
+    make pulse fail building on anything below v6 (what a very bad idea !)
+
+ -- Oliver Grawert <ogra at ubuntu.com>  Thu, 27 Aug 2009 16:25:15 +0200
+
+pulseaudio (1:0.9.16~test6-3-g57e1-0ubuntu1) karmic; urgency=low
+
+  [ Daniel T Chen ]
+  * New git snapshot of origin/master (0.9.16~test6-3-g57e1)
+  * debian/patches/:
+    + 0050-revert-pacmd-poll-argv.patch: Retain, still seeing
+      excessive cpu usage with resume
+    - 0051-leave-hp-enabled.patch: Drop, applied upstream
+    + 0051-reduce-lib-linking.patch: Refresh and rename previous
+      0052-reduce.. so that minimal changes are made
+
+  [ Luke Yelavich ]
+  * debian/control: Promote rtkit from suggests to recommends
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 25 Aug 2009 09:44:32 +1000
+
 pulseaudio (0.9.16~test5-1) experimental; urgency=low
 
   * New Upstream Version
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sat, 22 Aug 2009 21:59:34 +0100
 
+pulseaudio (1:0.9.16~test5-0ubuntu2) karmic; urgency=low
+
+  [ Daniel T Chen ]
+  * debian/patches/0051-leave-hp-enabled.patch: Leave
+    headphones enabled in the default analog mixer profiles
+
+  [ Luke Yelavich ]
+  * debian/patches/0052-reduce-lib-linking.patch: Reduce the number of
+    libraries that the libpulse libraries are linked against as much as
+    possible, to lessen the work needed to make bi-arch libpulse packages
+    in the future
+  * Remove pulseaudio.desktop once again, as the a11y special case is
+    not being honoured, and we have the Xsession.d script to start pulse
+    for us, to avoid any races with other apps wanting to play sounds on
+    session startup
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 21 Aug 2009 15:48:31 +1000
+
+pulseaudio (1:0.9.16~test5-0ubuntu1) karmic; urgency=low
+
+  * New upstream release
+  * debian/patches/0050-backport-git-post-test4.patch: drop
+  * debian/patches/0050-revert-pacmd-poll-argv.patch: revert pacmd
+    changesets due to excessive cpu usage (poll()) with resume:
+    - aae7054b1c442e62cc1154d15a4b7a569d60d8f4
+    - 5fcb8a3c0838a4ecdb00a0af09b6e1a358b114d0
+  * debian/01PulseAudio: Escape hash when passed to sudo -u
+    (LP: #414385). Thanks, Christoph Kurrat and Dana Goyette!
+  * debian/pulseaudio.init: Add NetworkManager to
+    Should-St{art,op} to fix sink/source publishing with Avahi
+    (LP: #413443). Thanks, Martin-Éric Racine!
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Wed, 19 Aug 2009 17:43:48 -0400
+
 pulseaudio (0.9.16~test4-1) experimental; urgency=low
 
   * New Upstream Version
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sun, 09 Aug 2009 18:24:46 +0100
 
+pulseaudio (1:0.9.16~test4-0ubuntu6) karmic; urgency=low
+
+  * Correct changelog entry for 1:0.9.16~test4-0ubuntu5
+    (5fcb8a3c0838a4ecdb00a0af09b6e1a358b114d0 was _not_
+    applied)
+  * Resync proper 0050-backport-git-post-test4.patch
+    from the ~ubuntu-audio-dev PPA branch
+  * debian/control: Drop libgdbm-dev; use tdb-dev instead
+    since it's upstream's approach
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 13 Aug 2009 22:49:07 -0400
+
+pulseaudio (1:0.9.16~test4-0ubuntu5) karmic; urgency=low
+
+  [ Daniel T Chen ]
+  * 0050-backport-git-post-test4.patch: Add the following changesets
+    from git (can be dropped with -test5):
+    + 51b3899348bf29dd88b56691aeea9f57895dfd14
+    + 7d4916379bbf05384ad199004949cc220822aa5f
+    + 23a294c97e62e0bee9b17b1f8ad20a39e1ba15da
+    + d27e26dca0b492b1906b42b2d0f7decd38ed8ae3
+    + 462cdf44b7fe36768c836c90761f6b8153290517
+    + e8340345f6a102cd03b6676576bcd3879ead7aad
+    + 8998cba6839a46f11daec411c83a1b35723c5117
+    + facae1f27504983d7eff7c7c3ffa864f7e002272
+    + 9f53aa5546e7bf9246546c6dda5637d50679483c
+    + ef176ecb62a8f04bd14ca37e7c2a40469f0bb8ba
+    + 27b8cd783c2aedb23af8f88fc88632d5c4f387fd
+    + 5921324fd3c16e2b3d38d07b200febd90835f169
+    + 286ab2f19370c7a0041897435614b2c6aadc8e70
+    + 17d57415f5abad5b7c30301227054b4c899bc705
+
+  [ Luke Yelavich ]
+  * debian/pulseaudio.install: Also add previously dropped 70pulseaudio file
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 14 Aug 2009 10:29:16 +1000
+
+pulseaudio (1:0.9.16~test4-0ubuntu4) karmic; urgency=low
+
+  * debian/pulseaudio.install: ...and also re-add droped apport hook, and
+    alsa configuration files
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 07 Aug 2009 10:05:51 +0100
+
+pulseaudio (1:0.9.16~test4-0ubuntu3) karmic; urgency=low
+
+  * debian/pulseaudio.install: Also re-add pulse-session wrapper script
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 07 Aug 2009 09:41:15 +0100
+
+pulseaudio (1:0.9.16~test4-0ubuntu2) karmic; urgency=low
+
+  * debian/pulseaudio.install:
+    - Re-add the pm-utils script that was inadvertantly left out with the
+      previous Debian merge
+    - Add udev rules from upstream, needed for particular sound hardware
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 06 Aug 2009 18:49:12 +0100
+
+pulseaudio (1:0.9.16~test4-0ubuntu1) karmic; urgency=low
+
+  * New upstream release
+  * debian/patches/0008-clean-out-old-files.patch: Dropped, applied upstream
+  * debian/control: Fix pulseaudio-module-rygel-media-server debug package name
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 05 Aug 2009 12:02:18 +0100
+
+pulseaudio (1:0.9.16~test3-0ubuntu1) karmic; urgency=low
+
+  * New upstream release
+  * debian/pulseaudio.postinst:
+    - Do not create the pulse-rt group any more
+    - Do not make the pulseaudio binary suid root
+  * debian/pulseaudio.postrm: Do not try to remove the pulse-rt group
+  * debian/pulseaudio.preinst: Remove the pulse-rt group on upgrade
+  * debian/control:
+    - Suggest rtkit
+    - Renamed pulseaudio-module-hal and pulseaudio-module-hal-dbg to
+      pulseaudio-module-udev and pulseaudio-module-udev-dbg respectively
+    - pulseaudio-module-udev replaces pulseaudio-module-hal
+    - Bumped libudev-dev requirement to >= 143
+    - Added build dependencies libICE-dev, libxi-dev, x11proto-core-dev
+    - Add new package for the rygel-media-server module
+    - Tighten libasound2-dev and libsndfile1-dev dependencies
+  * debian/pulseaudio.init: Change all hal references to udev
+  * debian/patches/0008-clean-out-old-files.patch: Remove non-existant files
+    from POTFILES.in, patch sent upstream
+  * Merge from Debian unstable, remaining changes:
+    - epoch (my stupid fault :S)
+    - Don't build against, and create jack package. Jack is not in main
+    - use speex-float-1 resampler to work better with lack of PREEMPT in
+      karmic's -generic kernel config, also change buffer size
+    - Add alsa configuration files to route alsa applications via pulseaudio
+    - Move libasound2-plugins from Recommends to Depends
+    - Add pm-utils sleep hook to suspend (and resume) users' pulseaudio
+      daemons
+    - patch to fix source/sink and suspend-on-idle race
+    - Make initscript more informative in the default case of per-user
+      sessions
+    - add status check for system wide pulseaudio instance
+    - create /var/run/pulse, and make restart more robust
+    - LSB {Required-*,Should-*} should specify hal instead of dbus,
+      since hal is required (and already requires dbus)
+    - indicate that the system pulseaudio instance is being started from the init
+      script
+    - Install more upstream man pages
+    - Link to pacat for parec man page
+    - check whether pulseaudio is running before preloading the padsp library
+    - Add DEB_OPT_FLAG = -O3 as per recommendation from
+      pulseaudio-discuss/2007-December/001017.html
+    - cache /usr/share/sounds/ubuntu/stereo/ wav files on pulseaudio load
+    - Generate a PO template on build
+    - add special case to disable pulseaudio loading if accessibility/speech
+      is being used
+    - the esd wrapper script should not load pulseaudio if pulseaudio is being
+      used as a system service
+    - add a pulseaudio apport hook
+    - fix some typos in README.Debian
+    - drop padevchooser(Recommends) and pavucontrol (Suggests)
+    - drop libasyncns-dev build dependency, its in universe
+    - add libudev-dev as a build-dependency
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 04 Aug 2009 11:46:25 +0100
+
 pulseaudio (0.9.16~test2~20090726git59659e1db-1) experimental; urgency=low
 
   * New Upstream Version
@@ -723,6 +3028,72 @@ pulseaudio (0.9.15-4.1) unstable; urgency=high
 
  -- Nico Golde <nion at debian.org>  Fri, 24 Jul 2009 18:02:24 +0200
 
+pulseaudio (1:0.9.15-4ubuntu3) karmic; urgency=low
+
+  * debian/01PulseAudio: Mute sinks and sources prior to
+    suspend; unmute sinks and sources after resume (LP: #404986)
+  * debian/patches/series: Reenable glitch-free.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Mon, 27 Jul 2009 22:06:34 -0400
+
+pulseaudio (1:0.9.15-4ubuntu2) karmic; urgency=low
+
+  * SECURITY UPDATE: root escalation from BIND_NOW re-execution.
+    - 0040-do-not-exec-for-bindnow.patch: use -Wl,-z,now instead of
+      performing a racey re-exec.
+    - CVE-2009-1894
+
+ -- Kees Cook <kees at ubuntu.com>  Thu, 16 Jul 2009 10:03:46 -0700
+
+pulseaudio (1:0.9.15-4ubuntu1) karmic; urgency=low
+
+  [ Daniel T Chen ]
+  * debian/patches/0001_change_resample_and_buffering.patch: Bump
+    default resampler to speex-float-1 due to remaining audio
+    anomalies when playing DVDs (LP: #376374)
+
+  [ Luke Yelavich ]
+  * Merge from Debian unstable, remaining changes:
+    - epoch (my stupid fault :S)
+    - Don't build against, and create jack package. Jack is not in main
+    - use speex-float-1 resampler to work better with lack of PREEMPT in
+      karmic's -generic kernel config, also change buffer size
+    - Add alsa configuration files to route alsa applications via pulseaudio
+    - Move libasound2-plugins from Recommends to Depends
+    - Add pm-utils sleep hook to suspend (and resume) users' pulseaudio
+      daemons
+    - patch to fix source/sink and suspend-on-idle race
+    - Make initscript more informative in the default case of per-user
+      sessions
+    - add status check for system wide pulseaudio instance
+    - create /var/run/pulse, and make restart more robust
+    - LSB {Required-*,Should-*} should specify hal instead of dbus,
+      since hal is required (and already requires dbus)
+    - indicate that the system pulseaudio instance is being started from the init
+      script
+    - Install more upstream man pages
+    - Link to pacat for parec man page
+    - check whether pulseaudio is running before preloading the padsp library
+    - Add DEB_OPT_FLAG = -O3 as per recommendation from
+      pulseaudio-discuss/2007-December/001017.html
+    - cache /usr/share/sounds/ubuntu/stereo/ wav files on pulseaudio load
+    - disable glitch free (use tsched=0)
+    - Generate a PO template on build
+    - add special case to disable pulseaud  * debian/patches/0090-fix-sw-mute-desync.patch: Dropped, as this is included
+    in the recently added patches in Debian.io loading if accessibility/speech
+      is being used
+    - the esd wrapper script should not load pulseaudio if pulseaudio is being
+      used as a system service
+    - add a pulseaudio apport hook
+    - fix some typos in README.Debian
+    - drop padevchooser(Recommends) and pavucontrol (Suggests)
+    - drop libasyncns-dev build dependency, its in universe
+    - add libudev-dev as a build-dependency
+  * debian/patches/0090-fix-sw-mute-desync.patch: Dropped, as this is included
+    in the recently added patches in Debian.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 22 Jun 2009 11:17:06 +1000
+
 pulseaudio (0.9.15-4) unstable; urgency=low
 
   * Synchronize our patches with Mandriva and Fedora (thanks to Colin Guthrie
@@ -759,6 +3130,56 @@ pulseaudio (0.9.15-4) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sun, 21 Jun 2009 15:40:33 +0100
 
+pulseaudio (1:0.9.15-3ubuntu1) karmic; urgency=low
+
+  [ Daniel T Chen ]
+  * debian/patches/0001_change_resample_and_buffering.patch: Bump
+    default resampler to ffmpeg. We cannot peg the cpu, and we cannot
+    have audio anomalies, so this change _should_ be regression-free
+    but needs extensive testing (LP: #376374).
+  * debian/patches/0090_fix_sw_mute_desync.patch: Backport from
+    git HEAD to resolve sw vol becoming muted on logout
+    (LP: #315971, #352732)
+
+  [ Luke Yelavich ]
+  * Merge from Debian unstable, remaining changes:
+    - epoch (my stupid fault :S)
+    - Don't build against, and create jack package. Jack is not in main
+    - use ffmpeg resampler to work better with lack of PREEMPT in jaunty's
+      -generic kernel config, also change buffer size
+    - Add alsa configuration files to route alsa applications via pulseaudio
+    - Move libasound2-plugins from Recommends to Depends
+    - Add pm-utils sleep hook to suspend (and resume) users' pulseaudio
+      daemons
+    - patch to fix source/sink and suspend-on-idle race
+    - Make initscript more informative in the default case of per-user
+      sessions
+    - add status check for system wide pulseaudio instance
+    - create /var/run/pulse, and make restart more robust
+    - LSB {Required-*,Should-*} should specify hal instead of dbus,
+      since hal is required (and already requires dbus)
+    - indicate that the system pulseaudio instance is being started from the init
+      script
+    - Install more upstream man pages
+    - Link to pacat for parec man page
+    - check whether pulseaudio is running before preloading the padsp library
+    - Add DEB_OPT_FLAG = -O3 as per recommendation from
+      pulseaudio-discuss/2007-December/001017.html
+    - cache /usr/share/sounds/ubuntu/stereo/ wav files on pulseaudio load
+    - disable glitch free (use tsched=0)
+    - Generate a PO template on build
+    - add special case to disable pulseaudio loading if accessibility/speech
+      is being used
+    - the esd wrapper script should not load pulseaudio if pulseaudio is being
+      used as a system service
+    - add a pulseaudio apport hook
+    - fix some typos in README.Debian
+    - drop padevchooser(Recommends) and pavucontrol (Suggests)
+    - drop libasyncns-dev build dependency, its in universe
+    - add libudev-dev as a build-dependency
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 09 Jun 2009 10:47:05 +1000
+
 pulseaudio (0.9.15-3) unstable; urgency=low
 
   * Re-enable bluetooth support (Closes: #530514)
@@ -776,6 +3197,51 @@ pulseaudio (0.9.15-3) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sun, 07 Jun 2009 22:30:33 +0100
 
+pulseaudio (1:0.9.15-2ubuntu1) karmic; urgency=low
+
+  * Merge from Debian unstable, remaining changes:
+    - epoch (my stupid fault :S)
+    - Don't build against, and create jack package. Jack is not in main
+    - use linear resampler to work better with lack of PREEMPT in jaunty's
+      -generic kernel config, also change buffer size
+    - Add alsa configuration files to route alsa applications via pulseaudio
+    - Move libasound2-plugins from Recommends to Depends
+    - Add pm-utils sleep hook to suspend (and resume) users' pulseaudio
+      daemons
+    - patch to fix source/sink and suspend-on-idle race
+    - Make initscript more informative in the default case of per-user
+      sessions
+    - create /var/run/pulse, and make restart more robust
+    - add status check for system wide pulseaudio instance
+    - LSB {Required-*,Should-*} should specify hal instead of dbus,
+      since hal is required (and already requires dbus)
+    - indicate that the system pulseaudio instance is being started from the init
+      script
+    - Install more upstream man pages
+    - Link to pacat for parec man page
+    - check whether pulseaudio is running before preloading the padsp library
+    - Add DEB_OPT_FLAG = -O3 as per recommendation from
+      pulseaudio-discuss/2007-December/001017.html
+    - cache /usr/share/sounds/ubuntu/stereo/ wav files on pulseaudio load
+    - disable glitch free (use tsched=0)
+    - Generate a PO template on build
+    - add special case to disable pulseaudio loading if accessibility/speech
+      is being used
+    - the sd wrapper script should not load pulseaudio if pulseaudio is being
+      used as a system service
+    - add a pulseaudio apport hook
+    - fix some typos in README.Debian
+    - demote paprefs to suggests
+    - drop padevchooser(Recommends) and pavucontrol (Suggests)
+    - drop libasyncns-dev build dependency, its in universe
+    - add libudev-dev as a build-dependency
+    - Retain libbluetooth-dev build dependency
+  * debian/01Pulseaudio: Harvist users by UID, and not username, to ensure
+    that the script doesn't choak on characters not already considered as
+    used in a username (LP: #374694)
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 26 May 2009 23:33:42 +0200
+
 pulseaudio (0.9.15-2) unstable; urgency=low
 
   * debian/control: Add strict dependencies from libpulse-dev to the various
@@ -785,6 +3251,62 @@ pulseaudio (0.9.15-2) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Thu, 21 May 2009 00:54:38 +0100
 
+pulseaudio (1:0.9.15-1ubuntu3) karmic; urgency=low
+
+  * debian/control: libltdl7-dev -> libltdl-dev
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 11 May 2009 12:33:08 +1000
+
+pulseaudio (1:0.9.15-1ubuntu2) karmic; urgency=low
+
+  * debian/01PulseAudio: harvest users more robustly. Thanks,
+    Chow Loong Jin <hyperair at gmail.com>! (LP: #202089)
+  * debian/control: pulseaudio depends on pulseaudio-module-hal
+    to fix LP: #326532
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 09 Apr 2009 17:03:00 -0400
+
+pulseaudio (1:0.9.15-1ubuntu1) karmic; urgency=low
+
+  * Merge from unreleased Debian pulseaudio git, remaining changes:
+    - epoch (my stupid fault :S)
+    - Don't build against, and create jack package. Jack is not in main
+    - use linear resampler to work better with lack of PREEMPT in jaunty's
+      -generic kernel config, also change buffer size
+    - Add alsa configuration files to route alsa applications via pulseaudio
+    - Move libasound2-plugins from Recommends to Depends
+    - Add pm-utils sleep hook to suspend (and resume) users' pulseaudio
+      daemons
+    - patch to fix source/sink and suspend-on-idle race
+    - Make initscript more informative in the default case of per-user
+      sessions
+    - create /var/run/pulse, and make restart more robust
+    - add status check for system wide pulseaudio instance
+    - LSB {Required-*,Should-*} should specify hal instead of dbus,
+      since hal is required (and already requires dbus)
+    - indicate that the system pulseaudio instance is being started from the init
+      script
+    - Install more upstream man pages
+    - Link to pacat for parec man page
+    - check whether pulseaudio is running before preloading the padsp library
+    - Add DEB_OPT_FLAG = -O3 as per recommendation from
+      pulseaudio-discuss/2007-December/001017.html
+    - cache /usr/share/sounds/ubuntu/stereo/ wav files on pulseaudio load
+    - disable glitch free (use tsched=0)
+    - Generate a PO template on build
+    - add special case to disable pulseaudio loading if accessibility/speech
+      is being used
+    - the sd wrapper script should not load pulseaudio if pulseaudio is being
+      used as a system service
+    - add a pulseaudio apport hook
+    - fix some typos in README.Debian
+    - demote paprefs to suggests
+    - drop padevchooser(Recommends) and pavucontrol (Suggests)
+    - drop libasyncns-dev build dependency, its in universe
+  * add libudev-dev as a build-dependency
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 05 May 2009 14:18:20 +1000
+
 pulseaudio (0.9.15-1) unstable; urgency=low
 
   * debian/control: Build-Depend on libcap-dev instead of libcap2-dev
@@ -874,6 +3396,418 @@ pulseaudio (0.9.14-1) experimental; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sun, 01 Feb 2009 12:47:55 +0000
 
+pulseaudio (1:0.9.14-0ubuntu20) jaunty; urgency=low
+
+  * debian/01PulseAudio: use pactl instead of pacmd (LP: #202089)
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Wed, 08 Apr 2009 18:54:30 -0400
+
+pulseaudio (1:0.9.14-0ubuntu19) jaunty; urgency=low
+
+  [ Daniel T Chen ]
+  * debian/pulseaudio.init:
+    - Fix inane stop() syntax (LP: #357201)
+  * Update backported (from git HEAD) fixes:
+    - 0091_workaround_alsa_horkage.patch
+  * Add new fixes:
+    - 0049_fix_sampling_rate_not_beyond_pa-rate-max.patch
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Thu, 09 Apr 2009 07:29:24 +1000
+
+pulseaudio (1:0.9.14-0ubuntu18) jaunty; urgency=low
+
+  * debian/apport-hook.py: Add apport hook
+  * debian/rules, debian/pulseaudio.install: Install apport hook
+  * LP: #357913
+
+ -- Matt Zimmerman <mdz at ubuntu.com>  Wed, 08 Apr 2009 20:14:17 +0100
+
+pulseaudio (1:0.9.14-0ubuntu17) jaunty; urgency=low
+
+  [ Daniel T Chen ]
+  * debian/pulseaudio.init:
+    - Actually create /var/run/pulse, and make handling of /restart
+      more robust (LP #317921)
+    - Add /status check for system-wide daemon instance
+      (LP: #298299)
+  * Backport from upstream git HEAD:
+    - 0046_ignore_hal_no_such_cap.patch,
+    - 0047_pick_up_all_cards.patch (LP: #353807),
+    - 0048_fix_stuck_prebuf.patch (LP: #355825)
+
+  [ Luke Yelavich ]
+  * debian/control: Drop recommends from the pulseaudio-module-x11 package. if
+    they were dropped previously, they were re-added somehow, so lets get rid
+    of them once and for all.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 07 Apr 2009 16:51:59 +1000
+
+pulseaudio (1:0.9.14-0ubuntu16) jaunty; urgency=low
+
+  * Introduce epoch to fix my stupidity in uploading a test release of
+    pulseaudio.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 01 Apr 2009 14:04:33 +1100
+
+pulseaudio (0.9.14-0ubuntu15) jaunty; urgency=low
+
+  [ Daniel T Chen ]
+  * README.Debian:
+    pulse-session:
+    pulseaudio.default: Clarify function of system-wide check, and
+    make /usr/bin/pulse-session do the right thing if system-wide
+    is enabled (LP: #286966)
+
+  [ Luke Yelavich ]
+  * Make the a11y no start special case per user, not system wide.
+  * Also make the esd wrapper script honour system wide pulseaudio.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 30 Mar 2009 11:33:33 +1100
+
+pulseaudio (0.9.14-0ubuntu14) jaunty; urgency=low
+
+  * No-change rebuild to fix lpia shared library dependencies.
+
+ -- Colin Watson <cjwatson at ubuntu.com>  Thu, 19 Mar 2009 13:57:35 +0000
+
+pulseaudio (0.9.14-0ubuntu13) jaunty; urgency=low
+
+  * debian/rules: Generate a PO template on build. Thanks to Timo Jyrinki for
+    the patch! (LP: #342159)
+
+ -- Martin Pitt <martin.pitt at ubuntu.com>  Mon, 16 Mar 2009 10:14:19 +0100
+
+pulseaudio (0.9.14-0ubuntu12) jaunty; urgency=low
+
+  * 0091_workaround_alsa_horkage.patch:
+    - Lower severity of logging level to prevent DoS on syslog
+      LP: #320875, #343254
+      LP #330814
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sat, 14 Mar 2009 22:39:03 -0400
+
+pulseaudio (0.9.14-0ubuntu11) jaunty; urgency=low
+
+  [ Daniel T Chen ]
+  * Reenable 0030_set_tsched0.patch, which re-disables glitch-free;
+    too many users are reporting regressions and audio aberrations.
+  * Adjust 0003_change_resample_and_buffering.patch to use linear
+    resampler to work better with lack of PREEMPT in jaunty's
+    -generic kernel config (LP: #207135, #322250, #332761, #335955,
+    LP: #336965).
+  * Last upload, specifically 0091_workaround_alsa_horkage, fixes:
+    LP: #235990, #237443, #279847, #317997, #323185, #330814,
+    LP: #334874.
+  * sudo -H change in ubuntu6 fixed LP: #312505.
+  * Closing old bugs fixed in 0.9.11+: LP: #187963, #193520, #211052.
+  * Refresh 0006_regen-autotools.patch.
+  * Add 0043_load_sample_dir_lazy.patch to cache
+    /usr/share/sounds/ubuntu/stereo/* in default.pa.
+  * debian/:
+    - control: Build against libcap2-dev (LP: #339448);
+    - copyright: Update copyright from Debian's 0.9.14-2;
+    - rules: Add DEB_OPT_FLAG = -O3 as per recommendation from
+      pulseaudio-discuss/2007-December/001017.html.
+  * Refresh fixes from git HEAD:
+    - 0038_handle_errno_properly.patch,
+    - 0091_workaround_alsa_horkage.patch,
+    - 0092_fix_null_pointer_access.patch.
+
+  [ Luke Yelavich ]
+  * Add a special case to prevent Pulseaudio from being started when the
+    blindness accessibility profile has been enabled from the Ubuntu live CD,
+    and for an accessibility install. Unfortunately Pulseaudio and speech do
+    not currently work very well with each other, and its too late in
+    the cycle to solve this problem any other way.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 10 Mar 2009 09:00:40 +1100
+
+pulseaudio (0.9.14-0ubuntu10) jaunty; urgency=low
+
+  [ Daniel T Chen ]
+  * 0030_set_tsched0.patch: Disable this patch, which has the effect of
+    reenabling glitch-free. Depends on 0091_workaround_alsa_horkage.
+  * 0091_workaround_alsa_horkage.patch: Rework ALSA delay handling.
+
+  [ Luke Yelavich ]
+  * debian/control: re-add the vcs bzr URL for Ubuntu's pulseaudio packaging
+    as it got lost somewhere along the way
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 02 Mar 2009 10:40:11 +1100
+
+pulseaudio (0.9.14-0ubuntu9) jaunty; urgency=low
+
+  * PulseAudio does not need to be started before gdm, especially since we use
+    user sessions by default.
+
+ -- Scott James Remnant <scott at ubuntu.com>  Fri, 27 Feb 2009 01:27:20 +0000
+
+pulseaudio (0.9.14-0ubuntu8) jaunty; urgency=low
+
+  [ Daniel T Chen ]
+  * Backport fixes from git HEAD:
+    - 0041_clarify_cmdline_opts.patch,
+    - 0042_fix_selem_init.patch
+
+  [ Luke Yelavich ]
+  * 0001_more_translatable_strings.patch: Make the .desktop file and PolicyKit
+    files translatable, thanks to Gabor Kelemen <kelemeng at gnome.hu for this
+    work (LP: #331831)
+  * 0006_regen-autotools.patch: re-create to take into account changes needed
+    for the above mentioned translation additions
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 24 Feb 2009 13:46:25 +1100
+
+pulseaudio (0.9.14-0ubuntu7) jaunty; urgency=low
+
+  [ Luke Yelavich ]
+  * 0001-Fix-library-search-path-to-include-lib-and-usr-lib.patch: Dropped,
+    no longer applicable, as evident in Debian's pulseaudio git branch.
+
+  [ Daniel T Chen ]
+  * 0004_enable_autospawn.patch: Renamed from .."disable".. for clarity,
+    and actually apply it.
+  * 0012_clarify_driver_error_redirect_to_alsa_devs.patch: Clarify
+    logging message for 'linux' source package and ALSA developers
+    instead of PulseAudio developers in alsa-util.c, too.
+    - This patch can be tweaked, since upstream has now applied it to
+      git HEAD
+  * Backport fixes from git HEAD:
+    - 0035_fix_module-detect_access.patch,
+    - 0036_increase_memblock_imports.patch,
+    - 0037_fill_silence_fail_import_memblock.patch,
+    - 0038_handle_errno_properly.patch,
+    - 0039_add_validity_checks.patch,
+    - 0040_legacy_fixes.patch
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 19 Feb 2009 19:34:03 -0500
+
+pulseaudio (0.9.14-0ubuntu6) jaunty; urgency=low
+
+  * 0004_disable_autospawn.patch: Disable this patch. Doing so
+    allows the daemon to spawn if not already running, which
+    works around LP: #191027, #204272
+  * 0012_clarify_driver_error_redirect_to_alsa_devs.patch:
+    - Only log POLL* being set if tsched is used so that syslog
+      isn't filled with innocuous messages when we set tsched=0
+      (see 0030 below) (LP: #323712),
+    - Hint 'linux' source package instead of 'alsa-driver' for
+      Launchpad bug reports,
+    - The debug-specific portion is only applicable to 0.9.14;
+      0.9.15 enables a rate limiting module by default to work
+      around this (and other) issues
+  * 0029_fix_suspend_on_idle_null_race.patch: Handle sink case,
+    too
+  * 0030_set_tsched0.patch: Work around a shedload of (driver)
+    bugs by falling back to interrupt-based buffer semantics
+    (LP: #190754, #292880, #295519, #298494, #301755, #302964,
+     LP: #319118, #323976, #324103, #326205, #326864)
+  * Backport fixes from git HEAD:
+    - 0031_fix_6chan_map.patch,
+    - 0032_reinit_proplist.patch,
+    - 0033_fix_pa-gcc-packedmalloc.patch,
+    - 0034_bt_fixes.patch
+  * Make invoking the stop target in the initscript not fail an
+    upgrade (LP: #317921)
+  * Previous upload (0.9.14-0ubuntu3) fixed LP: #321357
+  * 01PulseAudio: use sudo -H to ensure that $HOME is, in fact,
+    the user's when invoking pacmd for suspend/resume
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sun, 15 Feb 2009 02:35:26 -0500
+
+pulseaudio (0.9.14-0ubuntu5) jaunty; urgency=low
+
+  * Add fixes from git HEAD:
+    - 0028_fix_uninit_rtp_resamp.patch,
+    - 0029_fix_suspend_on_idle_null_race.patch
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 12 Feb 2009 18:28:42 -0500
+
+pulseaudio (0.9.14-0ubuntu4) jaunty; urgency=low
+
+  * Add fixes from git HEAD:
+    - 0023_work_around_dlsym_retval_mistyping.patch,
+    - 0024_fix_sink_source_calls_in_suspended.patch,
+    - 0025_shortcut_pa-sink-process-rewind.patch,
+    - 0026_reset_rewind-requested_when_suspend.patch,
+    - 0027_fix_piped_pacmd.patch
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Wed, 04 Feb 2009 19:36:09 -0500
+
+pulseaudio (0.9.14-0ubuntu3) jaunty; urgency=low
+
+  [ Daniel T Chen ]
+  * Add fixes from git HEAD:
+    - 0014_fix_avail-min_calc.patch,
+    - 0015_no_pa-asyncq-push_fail.patch,
+    - 0016_dont_rely_pa-sink-running-idle_for_optim.patch,
+    - 0017_fix_hsp_rate_chan.patch,
+    - 0018_dont_restore_mute_vol_when_already_set.patch,
+    - 0019_fix_mem_leak_in_pa-alsa-open-by-device-string.patch,
+    - 0020_ask_for_same_frag_set_when_resuming_oss_dev.patch,
+    - 0021_add_missing_const.patch,
+    - 0022_dont_hit_assert_in_esound-sink_when_latency_queried.patch
+
+  [ Luke Yelavich ]
+  * Re-instate /etc/X11/Xsession.d/70pulseaudio, to again load pulseaudio
+    earlier in the X session, to aleviate a pulse/login-sound race condition
+    (LP: #322374)
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 02 Feb 2009 15:27:55 +0100
+
+pulseaudio (0.9.14-0ubuntu2) jaunty; urgency=low
+
+  * Add fixes from trunk:
+    - 0012_clarify_driver_error_redirect_to_alsa_devs.patch
+  * Add 0013_add_padsp_wrapper_check.patch (LP: #269939)
+  * debian/pulseaudio.manpages:
+    debian/pulseaudio-esound-compat.manpages:
+    debian/pulseaudio-utils.links:
+    - Install upstream man pages (LP: #219669, #318660),
+    - Link to pacat for parec man page (LP: #294628)
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 22 Jan 2009 02:57:54 -0500
+
+pulseaudio (0.9.14-0ubuntu1) jaunty; urgency=low
+
+  * New upstream release. (LP: #317502, #317613)
+  * Dropped patches, all in upstream release.
+    - 0003-make-sure-to-use-64bit-rounding-even-on-32bit-machin.patch
+    - 0004-properly-remove-dbus-matches-an-filters-when-unloadi.patch
+    - 0005-Fix-two-typos-that-broke-tunnels.patch
+    - 0008_regen_autotools.patch
+    - 0009_shm-arch-indep.patch
+    - 0010_check_before_using_environment.patch
+    - 0011_load_restore_before_other_modules.patch
+    - 0013_dont_hit_assert_issuing_two_rewinds_in_single_iter.patch
+    - 0014_retry_without_snd-pcm-no-auto-format.patch
+    - 0015_use_fionread.patch
+    - 0016_add_pa-source-message-get-latency.patch
+    - 0017_allow_dev_dsp_w-ok.patch
+    - 0019_fix_macro_pa-unlikely.patch
+    - 0020_catch_driver_errors.patch
+    - 0022_fix_return_val_dump-resample-methods.patch
+    - 0023_use_gdbm-nolock.patch
+    - 0024_dont_mix_front-center_into_rear.patch
+    - 0025_drop_cap-nice_properly.patch
+    - 0027_handle_multicast_sdp_with_same_ip_ttl_as_rtp.patch
+    - 0029_add_minor_fixes.patch
+    - 0030_dont_drop_client_data.patch
+    - 0031_use_fragsize_for_record_stream_latency.patch
+  * Bumped shlibs for libpulse0.
+  * Package libpulsecore8 -> libpulsecore9.
+  * Add libdbus-glib-1-dev to build-depends.
+  * Regression fix:
+    - pulse.conf: Always honour ~/.asoundrc and /etc/asound.conf with highest
+      priority, thanks to Daniel T Chen. (LP: #295832)
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 19 Jan 2009 14:45:36 +1100
+
+pulseaudio (0.9.13-2ubuntu7) UNRELEASED; urgency=low
+
+  * Add fixes from 0.9.14:
+    - 0030_dont_drop_client_data.patch,
+    - 0031_use_fragsize_for_record_stream_latency.patch,
+    - 0032_fix_suspend_sinks_sources.patch (LP: #317613)
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 15 Jan 2009 17:26:14 -0500
+
+pulseaudio (0.9.13-2ubuntu6) jaunty; urgency=low
+
+  * debian/control: Package pulseaudio-module-x11,
+    Recommends: gnome-audio | ubuntu-sounds.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 13 Jan 2009 16:15:48 +1100
+
+pulseaudio (0.9.13-2ubuntu5) jaunty; urgency=low
+
+  [ Daniel T Chen ]
+  * Add fixes from git:
+    - 0015_use_fionread.patch,
+    - 0016_add_pa-source-message-get-latency.patch,
+    - 0017_allow_dev_dsp_w-ok.patch,
+    - 0018_fix_return_val_pa-frame-aligned.patch,
+    - 0019_fix_macro_pa-unlikely.patch,
+    - 0020_catch_driver_errors.patch (LP: #312373),
+    - 0021_convert_to_pa-bool-t.patch,
+    - 0022_fix_return_val_dump-resample-methods.patch,
+    - 0023_use_gdbm-nolock.patch,
+    - 0024_dont_mix_front-center_into_rear.patch,
+    - 0025_drop_cap-nice_properly.patch,
+    - 0027_handle_multicast_sdp_with_same_ip_ttl_as_rtp.patch,
+    - 0028_prefer_mixer_controls_with_vols.patch (LP: #281605),
+    - 0029_add_minor_fixes.patch
+  * Forward-port workaround from hardy branch for source/sink and
+    suspend-on-idle race (LP: #203654):
+    - 0026_work_around_suspend-on-idle_source_sink_race.patch
+  * debian/control: Drop padevchooser(Recommends) and pavucontrol
+    (Suggests) completely - functionality has been subsumed by
+    jaunty's gnome-volume-control.
+  * debian/pulseaudio.init:
+    - Make initscript more informative in the default case of per-user
+      sessions (LP: #259522),
+    - Make initscript retry (until three-second timeout) if stopping
+      fails when restarting (LP: #244414),
+    - LSB {Required-*,Should-*} should specify hal instead of dbus,
+      since hal is required (and already requires dbus) (LP: #244679)
+  * Previous upload contains patches to close:
+    LP: #193491, #268891, #295164, #298301
+
+  [ Luke Yelavich ]
+  * 0008_regen_autotools.patch: Pull some libtool 2.2 updates from git,
+    and regenerate autotools glue.
+  * debian/rules: Add --enable-static to force creation of libpulse.a,
+    a side-effect of messing with the autotools files. This shouldn't
+    be needed for the 0.9.14 release.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 09 Jan 2009 17:05:38 +1100
+
+pulseaudio (0.9.13-2ubuntu4) jaunty; urgency=low
+
+  * Demote paprefs to suggests (LP: #309422)
+  * Add fixes from git:
+    - 0010_check_before_using_environment.patch,
+    - 0011_load_restore_before_other_modules.patch,
+    - 0012_dont_hit_assert_checking_for_idleness.patch,
+    - 0013_dont_hit_assert_issuing_two_rewinds_in_single_iter.patch,
+    - 0014_retry_without_snd-pcm-no-auto-format.patch.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sun, 28 Dec 2008 23:43:01 -0500
+
+pulseaudio (0.9.13-2ubuntu3) jaunty; urgency=low
+
+  * Add pm-utils sleep hook to suspend (and resume) users' pulseaudio
+    daemons (LP: #202089). Based on a patch by
+    Chow Loong Jin <hyperair at gmail.com>.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Mon, 08 Dec 2008 22:11:32 -0800
+
+pulseaudio (0.9.13-2ubuntu2) jaunty; urgency=low
+
+  * debian/patches/0009_shm-arch-indep.patch:
+    - Make shm marker architecture independant, taken from git.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 01 Dec 2008 12:06:00 +1100
+
+pulseaudio (0.9.13-2ubuntu1) jaunty; urgency=low
+
+  * Merge from Debian experimental, remaining changes:
+    - Don't build against, and create jack package. Jack is not in main.
+    - Remove --disable-per-user-esound-socket from configure flags, as we still
+      want per user esound sockets.
+    - Remove stop links from rc0 and rc6.
+    - Change default resample algorithm and bubffer size.
+    - Add alsa configuration files to route alsa applications via pulseaudio.
+    - Move libasound2-plugins from Recommends to Depends.
+    - debian/pulseaudio.preinst: When upgrading from intrepid, remove
+      /etc/X11/Xsession.d/70pulseaudio, as this was used to minimize a race
+      condition when starting GNOME in intrepid. This race should not exist in
+      jaunty once libcanberra is built to use pulseaudio as a backend.
+    - Do not spawn a pulseaudio server if clients fail to find a running server.
+    - Regenerate autotools files for ubuntu.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 19 Nov 2008 10:44:03 +1100
+
 pulseaudio (0.9.13-2) experimental; urgency=low
 
   * Rename libpulsecore5 to libpulsecore8 to correctly reflect the soname
@@ -887,6 +3821,42 @@ pulseaudio (0.9.13-2) experimental; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sun, 16 Nov 2008 18:13:05 +0000
 
+pulseaudio (0.9.13-1ubuntu3) jaunty; urgency=low
+
+  * Build-depend on libltdl7-dev to make the armel buildd happy.
+
+ -- Matthias Klose <doko at ubuntu.com>  Wed, 19 Nov 2008 16:26:45 +0000
+
+pulseaudio (0.9.13-1ubuntu2) jaunty; urgency=low
+
+  * Drop libasyncns-dev again. Its in universe, and we will worry about
+    whether we really need it again later.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 18 Nov 2008 15:47:20 +1100
+
+pulseaudio (0.9.13-1ubuntu1) jaunty; urgency=low
+
+  * Merge from Debian unstable, remaining changes:
+    - Don't build against, and create jack package. Jack is not in main.
+    - Remove --disable-per-user-esound-socket from configure flags, as we still
+      want per user esound sockets.
+    - Remove stop links from rc0 and rc6.
+    - Change default resample algorithm and bubffer size.
+    - Add alsa configuration files to route alsa applications via pulseaudio.
+    - Move libasound2-plugins from Recommends to Depends.
+  * debian/pulseaudio.preinst: When upgrading from intrepid, remove
+    /etc/X11/Xsession.d/70pulseaudio, as this was used to minimize a race
+    condition when starting GNOME in intrepid. This race should not exist in
+    jaunty once libcanberra is built to use pulseaudio as a backend.
+  * Do not spawn a pulseaudio server if clients fail to find a running server.
+  * Remove explicit version dependency for libspeex-dev to allow the package
+    to be built for now.
+  * Regenerate autotools files to work with Ubuntu's newer libtool/libltdl.
+  * debian/control: libpulsecore5 -> libpulsecore8 to match the library
+    soname.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 04 Nov 2008 15:46:00 +1100
+
 pulseaudio (0.9.13-1) experimental; urgency=low
 
   [ Bas Zoetekouw ]
@@ -935,6 +3905,109 @@ pulseaudio (0.9.10-3) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sat, 30 Aug 2008 14:24:51 +0100
 
+pulseaudio (0.9.10-2ubuntu9) intrepid; urgency=low
+
+  * debian/70pulseaudio && debian/pulse-session: Use a wrapper script
+    to start pulseaudio at the Xsession.d phase of the login process.
+    The wrapper script is necessary to execute processes that need to
+    be loaded after pulseaudio, such as the X session manager. This
+    works around a race condition involving pulseaudio and canberra-gtk-play
+    and the GNOME login sound. (LP: #274124)
+  * debian/pulseaudio.preinst: Remove /etc/xdg/autostart/pulseaudio.desktop
+    if it exists. We don't want pulseaudio started more than once.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Mon, 20 Oct 2008 13:26:28 +1100
+
+pulseaudio (0.9.10-2ubuntu8) intrepid; urgency=low
+
+  * debian/pulseaudio.desktop: Use a slightly modified version of the
+    pulseaudio desktop file from more recent versions, and place it in
+    /etc/xdg/autostart, to start pulseaudio earlier in the GNOME desktop
+    initialization. This should avoid a race condition between the login
+    sound being played, and pulseaudio being loaded. (LP: #274124)
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Fri, 10 Oct 2008 15:22:51 +1100
+
+pulseaudio (0.9.10-2ubuntu7) intrepid; urgency=low
+
+  * Fix some errors in the pid file handling patch, thanks to Mandriva.
+  * debian/pulse.conf: Do not use an absolute path when referring to the
+    pulse alsa plugin, as this breaks bi-arch configurations. libasound2
+    and lib32/64asound2 now include ldconfig files to include the alsa-plugins
+    path for the architecture in use.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Wed, 08 Oct 2008 11:20:17 +1100
+
+pulseaudio (0.9.10-2ubuntu6) intrepid; urgency=low
+
+  * debian/pulse-alsa.conf: extend configuration to include "pulse"
+    definitions for buggy ALSA applications (e.g., Skype). (LP: #258581)
+
+ -- Conn O Griofa <connogriofa at gmail.com>  Tue, 23 Sep 2008 16:12:19 +0100
+
+pulseaudio (0.9.10-2ubuntu5) intrepid; urgency=low
+
+  * debian/control: Bump libasound2-plugins from recommends to depends to be
+    sure that nobody's audio set up for alsa applications is broken.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 23 Sep 2008 23:07:23 +1000
+
+pulseaudio (0.9.10-2ubuntu4) intrepid; urgency=low
+
+  * debian/pulse.conf, debian/pulse-alsa.conf. Asoundrc configuration files
+    to allow the use of pulseaudio as the default output for applications
+    using alsa, when pulseaudio is running.
+  * debian/patches/0015-Change-resampler-and-buffering.patch: Change the
+    resample method used as well as the buffer size.
+  * Some patches taken from Mandriva's pulseaudio package. See comments in
+    patch headers for more details:
+    - 0007-Perfer-client.conf-over-X11-property-variables.patch
+    - 0008-Also-link-libpulsecore.la-to-some-libraries-needed.patch
+    - 0009-Rejig-r2495-slightly-and-directly-compile-the-necess.patch
+    - 0010-Do-not-invalidate-the-cookie-if-no-file-was-specifie.patch
+    - 0011-fix-error-path-spotted-by-Coling-Guthrie.patch
+    - 0012-Change-policykit-policy-to-allow-high-priority-and-d.patch
+    - 0013-More-robust-pid-file-handling.patch
+    - 0014-Disable-hotplug-sound-as-it-interferes-with-too-many.patch
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 23 Sep 2008 16:02:48 +1000
+
+pulseaudio (0.9.10-2ubuntu3) intrepid; urgency=low
+
+  * Remove stop links from rc0 and rc6 (LP: #254254):
+    - debian/rules: change DEB_UPDATE_RCD_PARAMS to
+      start 25 2 3 4 5 . stop 15 1 .
+
+ -- Cesare Tirabassi <norsetto at ubuntu.com>  Mon, 04 Aug 2008 19:22:43 +0200
+
+pulseaudio (0.9.10-2ubuntu2) intrepid; urgency=low
+
+  * debian/patches/0006-pcspkr-last.patch: Load the PC speaker as a sink
+    after all other sound card sinks have been loaded. (LP: #242966)
+  * debian/patches/0007-relibtoolize.patch: Regenerate relevant libtool
+    bits, because even though libltdl7 is supposed to be API-compatible
+    with libltdl3, the package FTBFs without regeneration.
+
+ -- Luke Yelavich <themuso at ubuntu.com>  Tue, 29 Jul 2008 16:07:18 +1000
+
+pulseaudio (0.9.10-2ubuntu1) intrepid; urgency=low
+
+  * Merge from Debian unstable.
+  * Patches
+    + 0001-Set-ESD-socket-to-tmp-.esd-socket-to-match-up-with.patch:
+      continue to disable this patch, as we want user sockets to be
+      the default in the conffile;
+    - 0050-Reduce-RT-highprio-log-to-info: absorbed into Debian unstable;
+    - 0051-Reduce-pa_pid_file_create-Daemon-already-running-log-spam:
+      removed as per discussion with Sjoerd, as it can confuse human
+      debugging;
+  * Packaging
+    + MaintainerField and Vcs munging;
+    + Don't generate or install the jackd module;
+    + Use multiuser semantics.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Wed, 14 May 2008 15:47:31 -0400
+
 pulseaudio (0.9.10-2) unstable; urgency=low
 
   * debian/patches/0003-Define-PULSE_INTERNAL.patch
@@ -950,6 +4023,32 @@ pulseaudio (0.9.10-2) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Sat, 10 May 2008 22:16:12 +0200
 
+pulseaudio (0.9.10-1ubuntu1) hardy; urgency=low
+
+  [ Daniel T Chen ]
+  * Merge from Debian unstable:
+  * Patches
+    + 0050-Reduce-RT-highprio-log-to-info:
+    + 0051-Reduce-pa_pid_file_create-Daemon-already-running-log-spam:
+      Retain to prevent innocuous messages from spamming user log;
+    - 0052-Add-extra-checks-to-padsp-debug-calls:
+    - 0053-Handle-channel-map-failure:
+    - 0054-Invoke-pa_ltdl_done-conditionally:
+    - 0055-fix_record_stream_moved:  Merged in new upstream version.
+  * Packaging
+    + control:  Adhere to DebianMaintainerField spec, and add a
+      Vcs-Bzr entry;
+    + control:
+    + pulseaudio-module-jack.install:  Don't generate or install the
+      jackd module;
+    + pulseaudio.init:
+    + rules:  Use multiuser semantics.
+
+  [ Luke Yelavich ]
+  * FFe granted. (LP: #211592)
+
+ -- Luke Yelavich <luke.yelavich at canonical.com>  Mon, 07 Apr 2008 10:40:01 +1000
+
 pulseaudio (0.9.10-1) unstable; urgency=low
 
   [ CJ van den Berg ]
@@ -975,6 +4074,52 @@ pulseaudio (0.9.10-1) unstable; urgency=low
 
  -- CJ van den Berg <cj at vdbonline.com>  Sun, 30 Mar 2008 20:11:02 +0200
 
+pulseaudio (0.9.9-1ubuntu4) hardy; urgency=low
+
+  * Patch from Thorvald Natvig to fix protocol error when moving source outputs.
+    (LP: #194756)
+
+ -- Luke Yelavich <luke.yelavich at canonical.com>  Fri, 28 Mar 2008 15:58:55 +1100
+
+pulseaudio (0.9.9-1ubuntu3) hardy; urgency=low
+
+  * Patches:
+    - Apply (new) patch to handle channel mapping failure.  From
+      upstream SVN changeset 2105.  (LP: #178442)
+    - Apply (new) patch to invoke pa_ltdl_done() conditionally.
+      From upstream SVN changeset 2111.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Mon, 18 Feb 2008 18:40:28 -0500
+
+pulseaudio (0.9.9-1ubuntu2) hardy; urgency=low
+
+  * Packaging:
+    - Add versioned dependency on sysv-rc to pulseaudio for LTS->LTS.
+      Thanks, Steve Langasek (LP: #187469)!
+  * Patches:
+    - Apply (new) patch from Mandriva adding checks to debug calls,
+      preventing crashes, with padsp.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Wed, 30 Jan 2008 20:43:29 -0500
+
+pulseaudio (0.9.9-1ubuntu1) hardy; urgency=low
+
+  * Merge from Debian unstable, remaining changes:
+    - Packaging:
+      + pulseaudio-module-x11 does not recommend an audio theme,
+      + no jack packages,
+      + pulseaudio-utils long description clarification,
+      + multiuser initscript semantics (Teardown spec),
+      + Vcs-Bzr entry and DebianMaintainerField mangling;
+    - Patches:
+      + omit 0001-Set-ESD-socket-to-tmp-..,
+      + omit socket parameter in 0007-Change-config-.. to apply
+        cleanly given above 0001-Set-ESD-socket omission,
+      + lower verboseness of some log messages,
+      + drop backported CVE-2008-008 fix (already in 0.9.9).
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Fri, 25 Jan 2008 16:04:34 -0500
+
 pulseaudio (0.9.9-1) unstable; urgency=high
 
   * New Upstream Version.
@@ -983,6 +4128,48 @@ pulseaudio (0.9.9-1) unstable; urgency=high
 
  -- Sjoerd Simons <sjoerd at debian.org>  Thu, 24 Jan 2008 12:44:55 +0100
 
+pulseaudio (0.9.8-2ubuntu3) hardy; urgency=low
+
+  * [SECURITY] Apply (new) patch fixing unchecked setuid() return
+    values.  Patch backported from upstream 0.9.9.
+  * References:
+    CVE-2008-0008
+    https://bugzilla.novell.com/show_bug.cgi?id=347822
+    https://bugzilla.redhat.com/show_bug.cgi?id=425481
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Wed, 23 Jan 2008 20:11:25 -0500
+
+pulseaudio (0.9.8-2ubuntu2) hardy; urgency=low
+
+  * Apply (new) 0051-Reduce-pa_pid_file_create.. patch that lowers the
+    "Daemon already running", "pa_pid_file_create() failed", and
+    "setrlimit(..Operation not permitted" levels to prevent spamming
+    /var/log/syslog.  Normal users not in the pulse-rt group don't need
+    this level of verbosity, and the "errors" are innocuous given per-
+    user session invocation.  (These changes really close LP #83137 and
+    duplicates.)
+  * Thanks to Sjoerd Simons for the insight.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Tue, 08 Jan 2008 06:36:42 -0500
+
+pulseaudio (0.9.8-2ubuntu1) hardy; urgency=low
+
+  * Merge from Debian unstable, remaining changes:
+    - Packaging:
+      + pulseaudio-module-x11 does not recommend an audio theme,
+      + no jack packages,
+      + pulseaudio-utils long description clarification,
+      + multiuser initscript semantics (Teardown spec),
+      + Vcs-Bzr entry and DebianMaintainerField mangling;
+    - Patches:
+      + omit 0001-Set-ESD-socket-to-tmp-..,
+      + omit socket parameter in 0007-Change-config-.. to apply
+        cleanly given above 0001-Set-ESD-socket omission,
+      + apply (new) 0050-Reduce-RT-highprio-log-to-info.patch
+        (LP: #83137 and duplicates).
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Fri, 04 Jan 2008 21:46:57 +0000
+
 pulseaudio (0.9.8-2) unstable; urgency=low
 
   * Bump shlibs of libpulse and libpulse-browse. Upstream has started
@@ -1006,6 +4193,44 @@ pulseaudio (0.9.8-2) unstable; urgency=low
 
  -- Sjoerd Simons <sjoerd at debian.org>  Fri, 04 Jan 2008 16:12:27 +0100
 
+pulseaudio (0.9.8-1ubuntu3) hardy; urgency=low
+
+  * debian/control: Drop Recommendation of ubuntu-sounds entirely; it's wrong
+    for derivatives, and theming should be done with seeds and derivative
+    specific meta packages.
+
+ -- Martin Pitt <martin.pitt at ubuntu.com>  Mon, 10 Dec 2007 14:37:37 +0100
+
+pulseaudio (0.9.8-1ubuntu2) hardy; urgency=low
+
+  * debian/control: Make pulseaudio-module-x11 recommend ubuntu-sounds,
+    not gnome-audio.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Thu, 06 Dec 2007 07:12:07 -0500
+
+pulseaudio (0.9.8-1ubuntu1) hardy; urgency=low
+
+  "Hail our new PulseAudio overlords (part two)."
+
+  * Merge from Debian unstable.
+  * Ubuntu-specific changes:
+    - debian/control:
+      + Don't build-depend on libjack0.100.0-dev or build jack module
+        packages,
+      + Update pulseaudio's Recommends and Suggests to accomodate
+        existing promoted main packages,
+      + Explicitly mention pasuspender in pulseaudio-utils's long
+        description,
+      + Add Vcs-Bzr URI,
+      + Adhere to DebianMaintainerField;
+    - debian/rules: Use multiuser for update-rc.d;
+    - debian/patches/series: Retain the exclusion of
+      0001-Set-ESD-socket-to-tmp-.esd-socket-to-match-up-with.patch.
+  * Dropped Ubuntu-specific change (absorbed into Debian source):
+    debian/patches/0002-Double-esound-maximum-sample-size.patch.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Tue, 04 Dec 2007 00:56:08 +0000
+
 pulseaudio (0.9.8-1) unstable; urgency=low
 
   [ CJ van den Berg ]
@@ -1047,6 +4272,40 @@ pulseaudio (0.9.8-1) unstable; urgency=low
 
  -- CJ van den Berg <cj at vdbonline.com>  Thu, 22 Nov 2007 02:33:51 +0100
 
+pulseaudio (0.9.7-3ubuntu2) hardy; urgency=low
+
+  * Disable 0001-Set-ESD-socket-to-tmp-.esd-socket-to-match-up-with.patch. We
+    do want per-user esd sockets in Ubuntu. This unbreaks multiuser support
+    and matches the patch that we did to esound for the very same reason:
+    every user needs its own esd socket path to have them not conflict to each
+    other.
+
+ -- Martin Pitt <martin.pitt at ubuntu.com>  Tue, 20 Nov 2007 22:30:35 +0100
+
+pulseaudio (0.9.7-3ubuntu1) hardy; urgency=low
+
+  "Hail our new PulseAudio overlords (part one)."
+
+  * Merge from Debian unstable.
+  * Apply Ubuntu-specific changes:
+    - debian/control:
+      + drop libasyncns-dev and libjack0.100.0-dev build-dependencies
+        since we don't build the jack plugin [yet];
+      + add versioned lsb-base dependency to pulseaudio;
+      + keep pulseaudio installable by demoting some recommended
+        packages to suggested [retain libasound2-plugins,
+        libgstreamer-plugins-pulse0.10-0, and
+        pulseaudio-esound-compat.  pulseaudio-module-hal,
+        pulseaudio-module-x11, libao-pulse, paprefs, and
+        padevchooser are currently in universe];
+      + adhere to DebianMaintainerField spec;
+    - debian/rules:
+      + use multiuser instead of defaults in DEB_UPDATE_RCD_PARAMS.
+  * Drop obsolete Ubuntu-specific change:
+    - src/pulsecore/protocol-esound.c: applied upstream.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sat, 17 Nov 2007 00:10:48 +0000
+
 pulseaudio (0.9.7-3) unstable; urgency=low
 
   [ CJ van den Berg ]
@@ -1124,6 +4383,25 @@ pulseaudio (0.9.6-2) unstable; urgency=low
 
  -- CJ van den Berg <cj at vdbonline.com>  Sun, 02 Sep 2007 20:22:19 +0200
 
+pulseaudio (0.9.6-1ubuntu2) gutsy; urgency=low
+
+  * fix esound max samplesize again to make sure teh login sound is playable
+    on networked connections. 
+
+ -- Oliver Grawert <ogra at ubuntu.com>  Thu, 28 Jun 2007 15:31:28 +0200
+
+pulseaudio (0.9.6-1ubuntu1) gutsy; urgency=low
+
+  * Merge from Debian unstable, remaining changes:
+    - debian/control:
+      + Add lsb-base (>= 3) to pulseaudio's dependencies,
+      + Adhere to DebianMaintainerField policy,
+      + Don't build-depend on libjack0.100.0-dev or libasyncns-dev,
+    - debian/patches/: Remove all Ubuntu-created patches (merged
+      upstream).
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Mon, 28 May 2007 22:30:44 +0100
+
 pulseaudio (0.9.6-1) unstable; urgency=low
 
   * New Upstream Version.
@@ -1145,6 +4423,22 @@ pulseaudio (0.9.6-1) unstable; urgency=low
 
  -- CJ van den Berg <cj at vdbonline.com>  Mon, 28 May 2007 00:53:28 +0200
 
+pulseaudio (0.9.5-7ubuntu1) gutsy; urgency=low
+
+  * Merge from Debian unstable, remaining changes:
+    - debian/control:
+      + Add lsb-base (>= 3) to pulseaudio's dependencies,
+      + Adhere to DebianMaintainerField policy,
+    - debian/patches/:
+      + Add 10_fix_DoS_vulns.dpatch (pA ticket 67) and
+        11_disallow_excessively_high_sampling_rates.dpatch,
+      + Drop 06_fix_suspend.dpatch in favour of
+        06_pulseaudio-0.9.5-suspend.dpatch,
+      + Retain 07_fix_esdcompat_bashism.dpatch and
+        09_fix_esd_max_samplesize.dpatch.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Fri, 25 May 2007 01:32:39 -0400
+
 pulseaudio (0.9.5-7) unstable; urgency=low
 
   * debian/control: Make pulseaudio-module-hal depend on hal, not just
@@ -1161,6 +4455,39 @@ pulseaudio (0.9.5-6) unstable; urgency=low
 
  -- CJ van den Berg <cj at vdbonline.com>  Mon, 12 Feb 2007 11:24:50 +0100
 
+pulseaudio (0.9.5-5ubuntu4) feisty; urgency=low
+
+  * add 09_fix_esd_max_samplesize.dpatch to make sure the login and logout
+    gnome sounds can be processed on remote connections. 
+
+ -- Oliver Grawert <ogra at ubuntu.com>  Tue,  6 Mar 2007 14:14:08 +0100
+
+pulseaudio (0.9.5-5ubuntu3) feisty; urgency=low
+
+  * debian/control:
+    - Add lsb-base (>= 3) to pulseaudio's dependencies,
+    - Adhere to DebianMaintainerField policy,
+    - Pull in fix from Debian's 0.9.5-7 adding hal to
+      pulseaudio-module-hal's dependencies,
+  * debian/pulseaudio.init: LSB-ify.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Sun, 25 Feb 2007 02:30:31 -0500
+
+pulseaudio (0.9.5-5ubuntu2) feisty; urgency=low
+
+  * added 06_fix_suspend.dpatch from http://pulseaudio.org/ticket/26
+  * added 07_fix_esdcompat_bashism.dpatch to avoid esdcompat trying to 
+    shift an empty $1 on POSIX shells
+
+ -- Oliver Grawert <ogra at ubuntu.com>  Tue, 30 Jan 2007 23:50:57 +0100
+
+pulseaudio (0.9.5-5ubuntu1) feisty; urgency=low
+
+  * Merge from Debian unstable, remaining change:
+    - debian/{control,rules}: Don't use jack or asyncns.
+
+ -- Daniel T Chen <crimsun at ubuntu.com>  Mon, 29 Jan 2007 10:36:35 -0500
+
 pulseaudio (0.9.5-5) unstable; urgency=low
 
   * debian/control: Make Build-deps more specific. (Closes: #401111)
@@ -1169,6 +4496,19 @@ pulseaudio (0.9.5-5) unstable; urgency=low
 
  -- CJ van den Berg <cj at vdbonline.com>  Mon,  8 Jan 2007 23:02:53 +0100
 
+pulseaudio (0.9.5-4ubuntu2) feisty; urgency=low
+
+  * disable libasyncns to fix ftbfs 
+
+ -- Oliver Grawert <ogra at ubuntu.com>  Sat, 20 Jan 2007 11:10:59 +0100
+
+pulseaudio (0.9.5-4ubuntu1) feisty; urgency=low
+
+  * merge from debian unstable
+    * keep jack removal
+
+ -- Oliver Grawert <ogra at ubuntu.com>  Tue, 28 Nov 2006 19:51:21 +0100
+
 pulseaudio (0.9.5-4) unstable; urgency=low
 
   * Add comment about resampling methods and CPU consumption to
@@ -1186,6 +4526,20 @@ pulseaudio (0.9.5-4) unstable; urgency=low
 
  -- CJ van den Berg <cj at vdbonline.com>  Wed, 18 Oct 2006 23:10:47 +0200
 
+pulseaudio (0.9.5-3ubuntu1) feisty; urgency=low
+
+  * indeed remove the jack plugin from debian/control as well 
+
+ -- Oliver Grawert <ogra at ubuntu.com>  Tue, 14 Nov 2006 21:05:29 +0100
+
+pulseaudio (0.9.5-3ubuntu0) feisty; urgency=low
+
+  * initial package
+  * disable jack
+  * disable asyncns
+
+ -- Oliver Grawert <ogra at ubuntu.com>  Sun, 12 Nov 2006 20:00:18 +0100
+
 pulseaudio (0.9.5-3) unstable; urgency=low
 
   * Add support for .ifexists configuration directive.
diff --git a/debian/control b/debian/control
index 5c8e3fb..ab3b2b1 100644
--- a/debian/control
+++ b/debian/control
@@ -1,7 +1,8 @@
 Source: pulseaudio
 Section: sound
 Priority: optional
-Maintainer: Pulseaudio maintenance team <pkg-pulseaudio-devel at lists.alioth.debian.org>
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss at lists.ubuntu.com>
+XSBC-Original-Maintainer: Pulseaudio maintenance team <pkg-pulseaudio-devel at lists.alioth.debian.org>
 Uploaders: Sjoerd Simons <sjoerd at debian.org>,
     Balint Reczey <balint at balintreczey.hu>,
     Felipe Sateler <fsateler at debian.org>
@@ -16,12 +17,13 @@ Build-Depends: debhelper (>= 9),
     libasyncns-dev,
     libatomic-ops-dev,
     libavahi-client-dev,
-    libbluetooth-dev (>= 4.99) [linux-any],
+    libbluetooth-dev (>= 4.40) [linux-any],
     libsbc-dev [linux-any],
     libcap-dev [linux-any],
     libfftw3-dev,
     libgconf2-dev,
     libglib2.0-dev,
+    libhardware-dev [armhf i386 amd64],
     libgtk-3-dev,
     libice-dev,
     libjack-dev,
@@ -38,21 +40,22 @@ Build-Depends: debhelper (>= 9),
     libsystemd-journal-dev [linux-any],
     libtdb-dev [!hurd-any],
     libudev-dev (>= 143) [linux-any],
-    libwebrtc-audio-processing-dev,
     libwrap0-dev,
     libx11-xcb-dev,
     libxcb1-dev (>= 1.6),
     libxtst-dev
 Standards-Version: 3.9.5
-Vcs-Git: git://anonscm.debian.org/git/pkg-pulseaudio/pulseaudio.git
-Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-pulseaudio/pulseaudio.git
+XS-Debian-Vcs-Git: git://anonscm.debian.org/git/pkg-pulseaudio/pulseaudio.git
+XS-Debian-Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-pulseaudio/pulseaudio.git
+XS-Testsuite: autopkgtest
+Vcs-Bzr: http://bazaar.launchpad.net/~ubuntu-audio-dev/pulseaudio/ubuntu
 Homepage: http://www.pulseaudio.org
 
 Package: pulseaudio
 Architecture: any
 Multi-Arch: foreign
 Depends: ${shlibs:Depends}, ${misc:Depends}, adduser,
-  lsb-base (>= 3.2-13),
+  lsb-base (>= 3.2-13), libpam-systemd,
   udev (>= 143) [linux-any],
   libasound2-plugins [linux-any],
   libpulse0 (= ${binary:Version}),
@@ -285,6 +288,32 @@ Description: RAOP module for PulseAudio sound server (debugging symbols)
  .
  This package contains debugging symbols for the PulseAudio RAOP module.
 
+Package: pulseaudio-module-droid
+Architecture: armhf i386 amd64
+Priority: extra
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Conflicts: pulseaudio (<< 0.9.14-2)
+Description: Android Audio HAL module for PulseAudio sound server
+ PulseAudio, previously known as Polypaudio, is a sound server for POSIX and
+ WIN32 systems. It is a drop in replacement for the ESD sound server with
+ much better latency, mixing/re-sampling quality and overall architecture.
+ .
+ This module enables PulseAudio to work on top of the Android Audio HAL.
+ .
+ The module is called module-droid.
+
+Package: pulseaudio-module-droid-dbg
+Architecture: armhf i386 amd64
+Priority: extra
+Section: debug
+Depends: ${misc:Depends}, pulseaudio-module-droid (= ${binary:Version})
+Description: Android Audio HAL module for PulseAudio sound server (debugging)
+ PulseAudio, previously known as Polypaudio, is a sound server for POSIX and
+ WIN32 systems. It is a drop in replacement for the ESD sound server with
+ much better latency, mixing/re-sampling quality and overall architecture.
+ .
+ This package contains debugging symbols for the PulseAudio droid module.
+
 Package: pulseaudio-module-bluetooth
 Architecture: linux-any
 Priority: extra
diff --git a/debian/gbp.conf b/debian/gbp.conf
index cec628c..d8d8b1e 100644
--- a/debian/gbp.conf
+++ b/debian/gbp.conf
@@ -1,2 +1,3 @@
 [DEFAULT]
 pristine-tar = True
+debian-branch = ubuntu
diff --git a/debian/patches/0005-dont-load-cork-music-on-phone.patch b/debian/patches/0005-dont-load-cork-music-on-phone.patch
new file mode 100644
index 0000000..803287b
--- /dev/null
+++ b/debian/patches/0005-dont-load-cork-music-on-phone.patch
@@ -0,0 +1,13 @@
+Index: pulseaudio-2.99.1/src/daemon/default.pa.in
+===================================================================
+--- pulseaudio-2.99.1.orig/src/daemon/default.pa.in	2012-11-16 11:19:57.904259183 +0100
++++ pulseaudio-2.99.1/src/daemon/default.pa.in	2012-11-16 11:20:18.408258877 +0100
+@@ -154,7 +154,7 @@
+ load-module module-position-event-sounds
+ 
+ ### Cork music/video streams when a phone stream is active
+-load-module module-role-cork
++#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
diff --git a/debian/patches/0006-load-module-x11-bell.patch b/debian/patches/0006-load-module-x11-bell.patch
new file mode 100644
index 0000000..6720ac4
--- /dev/null
+++ b/debian/patches/0006-load-module-x11-bell.patch
@@ -0,0 +1,24 @@
+Index: pulseaudio/src/daemon/start-pulseaudio-x11.in
+===================================================================
+--- pulseaudio.orig/src/daemon/start-pulseaudio-x11.in
++++ pulseaudio/src/daemon/start-pulseaudio-x11.in
+@@ -31,6 +31,7 @@ fi
+ if [ x"$DISPLAY" != x ] ; then
+ 
+     @PACTL_BINARY@ load-module module-x11-publish "display=$DISPLAY" > /dev/null
++    @PACTL_BINARY@ load-module module-x11-bell "display=$DISPLAY" "sample=bell.ogg" > /dev/null
+     @PACTL_BINARY@ load-module module-x11-cork-request "display=$DISPLAY" > /dev/null
+ 
+     if [ x"$SESSION_MANAGER" != x ] ; then
+Index: pulseaudio/src/daemon/start-pulseaudio-kde.in
+===================================================================
+--- pulseaudio.orig/src/daemon/start-pulseaudio-kde.in
++++ pulseaudio/src/daemon/start-pulseaudio-kde.in
+@@ -33,6 +33,7 @@ fi
+ if [ x"$DISPLAY" != x ] ; then
+ 
+     @PACTL_BINARY@ load-module module-device-manager "do_routing=1" > /dev/null
++    @PACTL_BINARY@ load-module module-x11-bell "display=$DISPLAY" "sample=bell.ogg" > /dev/null
+ 
+ fi
+ 
diff --git a/debian/patches/0016-nodisplay-autostart.patch b/debian/patches/0016-nodisplay-autostart.patch
new file mode 100644
index 0000000..e0a2c39
--- /dev/null
+++ b/debian/patches/0016-nodisplay-autostart.patch
@@ -0,0 +1,14 @@
+Description: Clean up Startup Applications dialog by hiding default apps
+Author: Michael Terry <michael.terry at canonical.com>
+Bug-Ubuntu: https://launchpad.net/bugs/803917
+Forwarded: not-needed
+
+Index: pulseaudio/src/daemon/pulseaudio.desktop.in
+===================================================================
+--- pulseaudio.orig/src/daemon/pulseaudio.desktop.in
++++ pulseaudio/src/daemon/pulseaudio.desktop.in
+@@ -9,3 +9,4 @@ Categories=
+ GenericName=
+ X-GNOME-Autostart-Phase=Initialization
+ NotShowIn=KDE;
++NoDisplay=true
diff --git a/debian/patches/0020-stream-Return-error-in-case-a-client-peeks-to-early.patch b/debian/patches/0020-stream-Return-error-in-case-a-client-peeks-to-early.patch
new file mode 100644
index 0000000..2f6d7e0
--- /dev/null
+++ b/debian/patches/0020-stream-Return-error-in-case-a-client-peeks-to-early.patch
@@ -0,0 +1,64 @@
+From david.henningsson at canonical.com  Mon Oct  1 15:06:56 2012
+Return-Path: <david.henningsson at canonical.com>
+X-Original-To: diwic at mail.canonical.com
+Delivered-To: diwic at mail.canonical.com
+Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145])
+	by grenadilla.canonical.com (Postfix) with ESMTP id A48961472160
+	for <diwic at mail.canonical.com>; Mon,  1 Oct 2012 15:06:56 +0000 (UTC)
+Received: from cluster-e.mailcontrol.com (cluster-e.mailcontrol.com [85.115.58.190])
+	by fiordland.canonical.com (Postfix) with ESMTP id 5DC1EA18423
+	for <david.henningsson at cleanmail.canonical.com>; Mon,  1 Oct 2012 15:06:56 +0000 (UTC)
+Received: from arctowski.canonical.com (arctowski.canonical.com [91.189.94.158])
+	by rly62e.srv.mailcontrol.com (MailControl) with ESMTP id q91F6t9E016745
+	for <david.henningsson at cleanmail.canonical.com>; Mon, 1 Oct 2012 16:06:55 +0100
+Received: from fiordland.canonical.com ([91.189.94.145])
+	by arctowski.canonical.com with esmtp (Exim 4.71)
+	(envelope-from <david.henningsson at canonical.com>)
+	id 1TIhaB-0002MW-HX
+	for david.henningsson at cleanmail.canonical.com; Mon, 01 Oct 2012 15:06:55 +0000
+Received: from youngberry.canonical.com (youngberry.canonical.com [91.189.89.112])
+	by fiordland.canonical.com (Postfix) with ESMTP id 8706DA18423
+	for <david.henningsson at canonical.com>; Mon,  1 Oct 2012 15:06:55 +0000 (UTC)
+Received: from hd9483857.selulk5.dyn.perspektivbredband.net ([217.72.56.87] helo=localhost.localdomain)
+	by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)
+	(Exim 4.71)
+	(envelope-from <david.henningsson at canonical.com>)
+	id 1TIhaB-0006f2-8F; Mon, 01 Oct 2012 15:06:55 +0000
+From: David Henningsson <david.henningsson at canonical.com>
+To: pulseaudio-discuss at lists.freedesktop.org
+Cc: 1058200 at bugs.launchpad.net,
+        David Henningsson <david.henningsson at canonical.com>
+Subject: [PATCH] stream: Return error in case a client peeks to early
+Date: Mon,  1 Oct 2012 17:06:55 +0200
+Message-Id: <1349104015-5924-1-git-send-email-david.henningsson at canonical.com>
+X-Mailer: git-send-email 1.7.9.5
+X-Mailcontrol-Inbound: uq3drnD2P+ps5SfEb0fvr78+NoP1DHBZwGqKpaXB2eTgNv8D6KLIxb8+NoP1DHBZ8VSaBg0k0xw=
+X-Spam-Score: -0.4
+X-Scanned-By: MailControl 9446.0 (www.mailcontrol.com) on 10.69.0.172
+
+If there is no silence memblock and no data, pa_memblockq_peek can
+return NULL. In this case, do not crash on an assertion in
+pa_memblock_acquire, but instead return a proper error to the client.
+
+BugLink: http://bugs.launchpad.net/bugs/1058200
+Signed-off-by: David Henningsson <david.henningsson at canonical.com>
+---
+ src/pulse/stream.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/pulse/stream.c b/src/pulse/stream.c
+index 2b6d306..9bb0995 100644
+--- a/src/pulse/stream.c
++++ b/src/pulse/stream.c
+@@ -1598,6 +1598,8 @@ int pa_stream_peek(pa_stream *s, const void **data, size_t *length) {
+             return 0;
+         }
+ 
++        PA_CHECK_VALIDITY(s->context, s->peek_memchunk.memblock != NULL, PA_ERR_NODATA);
++
+         s->peek_data = pa_memblock_acquire(s->peek_memchunk.memblock);
+     }
+ 
+-- 
+1.7.9.5
+
diff --git a/debian/patches/0022-inotify-wrapper-Quit-daemon-if-pid-file-is-removed.patch b/debian/patches/0022-inotify-wrapper-Quit-daemon-if-pid-file-is-removed.patch
new file mode 100644
index 0000000..4bbb704
--- /dev/null
+++ b/debian/patches/0022-inotify-wrapper-Quit-daemon-if-pid-file-is-removed.patch
@@ -0,0 +1,257 @@
+From afd823b21c544eb4764d9e38f2f15e5a4f50ab7a Mon Sep 17 00:00:00 2001
+From: David Henningsson <david.henningsson at canonical.com>
+Date: Wed, 17 Apr 2013 16:07:32 +0200
+Subject: [PATCH] inotify-wrapper: Quit daemon if pid file is removed
+
+XDG_RUNTIME_DIR is deleted on logout (according to xdg spec), and
+that's where we keep our pid file and native protocol socket.
+
+When these two files are deleted, it makes no sense to run anymore,
+so quit. Hanging around is not only sloppy, but can also be harmful:
+e g, if esd compat module is loaded, it will bind to the esd address.
+When a new pulseaudio process is created on next login of the same
+user, pulseaudio cannot start because the esd address is occupied.
+
+Buglink: https://bugs.launchpad.net/bugs/1167192
+Signed-off-by: David Henningsson <david.henningsson at canonical.com>
+---
+ src/Makefile.am                 |    1 +
+ src/daemon/main.c               |   20 +++++++-
+ src/pulsecore/inotify-wrapper.c |  103 +++++++++++++++++++++++++++++++++++++++
+ src/pulsecore/inotify-wrapper.h |   13 +++++
+ src/pulsecore/pid.c             |    5 ++
+ src/pulsecore/pid.h             |    1 +
+ 6 files changed, 141 insertions(+), 2 deletions(-)
+ create mode 100644 src/pulsecore/inotify-wrapper.c
+ create mode 100644 src/pulsecore/inotify-wrapper.h
+
+Index: pulseaudio/src/Makefile.am
+===================================================================
+--- pulseaudio.orig/src/Makefile.am
++++ pulseaudio/src/Makefile.am
+@@ -883,6 +883,7 @@ libpulsecore_ at PA_MAJORMINOR@_la_SOURCES
+ 		pulsecore/core.c pulsecore/core.h \
+ 		pulsecore/fdsem.c pulsecore/fdsem.h \
+ 		pulsecore/hook-list.c pulsecore/hook-list.h \
++		pulsecore/inotify-wrapper.c pulsecore/inotify-wrapper.h \
+ 		pulsecore/ltdl-helper.c pulsecore/ltdl-helper.h \
+ 		pulsecore/modargs.c pulsecore/modargs.h \
+ 		pulsecore/modinfo.c pulsecore/modinfo.h \
+Index: pulseaudio/src/daemon/main.c
+===================================================================
+--- pulseaudio.orig/src/daemon/main.c
++++ pulseaudio/src/daemon/main.c
+@@ -74,6 +74,7 @@
+ #include <pulsecore/core-rtclock.h>
+ #include <pulsecore/core-scache.h>
+ #include <pulsecore/core.h>
++#include <pulsecore/inotify-wrapper.h>
+ #include <pulsecore/module.h>
+ #include <pulsecore/cli-command.h>
+ #include <pulsecore/log.h>
+@@ -360,6 +361,15 @@ static char *check_configured_address(vo
+     return default_server;
+ }
+ 
++static bool valid_pid_file = false;
++static void pid_file_deleted(void *userdata)
++{
++    pa_core *c = userdata;
++    pa_log_info("Our pid file has been deleted (probably due to session logout), quitting...");
++    valid_pid_file = false;
++    pa_core_exit(c, true, 0);
++}
++
+ #ifdef HAVE_DBUS
+ static pa_dbus_connection *register_dbus_name(pa_core *c, DBusBusType bus, const char* name) {
+     DBusError error;
+@@ -402,7 +412,6 @@ int main(int argc, char *argv[]) {
+     char *s;
+     char *configured_address;
+     int r = 0, retval = 1, d = 0;
+-    bool valid_pid_file = false;
+     bool ltdl_init = false;
+     int passed_fd = -1;
+     const char *e;
+@@ -414,6 +423,7 @@ int main(int argc, char *argv[]) {
+     pa_time_event *win32_timer;
+     struct timeval win32_tv;
+ #endif
++    pa_inotify *pid_monitor = NULL;
+     int autospawn_fd = -1;
+     bool autospawn_locked = false;
+ #ifdef HAVE_DBUS
+@@ -1032,6 +1042,9 @@ int main(int argc, char *argv[]) {
+         goto finish;
+     }
+ 
++    if (valid_pid_file)
++        pid_monitor = pa_inotify_start(pa_pid_file_name(), c, pid_file_deleted, c);
++
+     c->default_sample_spec = conf->default_sample_spec;
+     c->alternate_sample_rate = conf->alternate_sample_rate;
+     c->default_channel_map = conf->default_channel_map;
+@@ -1179,6 +1192,9 @@ finish:
+         pa_mainloop_get_api(mainloop)->time_free(win32_timer);
+ #endif
+ 
++    if (pid_monitor)
++        pa_inotify_stop(pid_monitor);
++
+     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 */
+Index: pulseaudio/src/pulsecore/inotify-wrapper.c
+===================================================================
+--- /dev/null
++++ pulseaudio/src/pulsecore/inotify-wrapper.c
+@@ -0,0 +1,103 @@
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <fcntl.h>
++#include <sys/inotify.h>
++#include <errno.h>
++
++#include "inotify-wrapper.h"
++#include <pulse/mainloop.h>
++#include <pulsecore/core-util.h>
++#include <pulsecore/core-error.h>
++
++struct pa_inotify {
++    char *filename;
++    void *callback_data;
++    pa_inotify_cb callback;
++    int fd;
++    pa_io_event *io_event;
++    pa_core *core;
++};
++
++
++static void inotify_cb(
++        pa_mainloop_api *a,
++        pa_io_event *e,
++        int fd,
++        pa_io_event_flags_t events,
++        void *userdata) {
++
++    struct {
++        struct inotify_event event;
++        char name[NAME_MAX+1];
++    } buf;
++
++    pa_inotify *i = userdata;
++    int pid_fd;
++
++    pa_assert(i);
++
++    if (pa_read(fd, &buf, sizeof(buf), NULL) < (int) sizeof(buf.event))
++        pa_log_warn("inotify did not read a full event.");
++    else
++        pa_log_debug("inotify callback, event mask: 0x%x", (int) buf.event.mask);
++
++    pid_fd = pa_open_cloexec(i->filename, O_RDONLY
++#ifdef O_NOFOLLOW
++                       |O_NOFOLLOW
++#endif
++                       , S_IRUSR);
++
++    if (pid_fd < 0) {
++        if (i->callback)
++            i->callback(i->callback_data);
++    } else
++        pa_close(pid_fd);
++}
++
++
++pa_inotify *pa_inotify_start(const char *filename, void *userdata, pa_inotify_cb cb, pa_core *core) {
++
++    pa_inotify *i = pa_xnew0(pa_inotify, 1);
++    pa_assert(i);
++
++    i->core = core;
++    pa_core_ref(core);
++
++    i->filename = pa_xstrdup(filename);
++    i->callback_data = userdata;
++    i->callback = cb;
++    i->fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
++
++    if (i->fd < 0) {
++        pa_log("inotify_init1() failed: %s", pa_cstrerror(errno));
++        pa_inotify_stop(i);
++        return NULL;
++    }
++
++    if (inotify_add_watch(i->fd, filename, IN_DELETE_SELF|IN_MOVE_SELF) < 0) {
++        pa_log("inotify_add_watch() failed: %s", pa_cstrerror(errno));
++        pa_inotify_stop(i);
++        return NULL;
++    }
++
++    pa_assert_se(i->io_event = core->mainloop->io_new(core->mainloop, i->fd, PA_IO_EVENT_INPUT, inotify_cb, i));
++
++    return i;
++}
++
++
++void pa_inotify_stop(pa_inotify *i) {
++
++    pa_assert(i);
++
++    if (i->io_event)
++        i->core->mainloop->io_free(i->io_event);
++    if (i->fd)
++        pa_close(i->fd);
++    pa_xfree(i->filename);
++    if (i->core)
++        pa_core_unref(i->core);
++    pa_xfree(i);
++}
+Index: pulseaudio/src/pulsecore/inotify-wrapper.h
+===================================================================
+--- /dev/null
++++ pulseaudio/src/pulsecore/inotify-wrapper.h
+@@ -0,0 +1,13 @@
++#ifndef fooinotifywrapperhfoo
++#define fooinotifywrapperhfoo
++
++#include <pulsecore/core.h>
++
++typedef struct pa_inotify pa_inotify;
++
++typedef void (*pa_inotify_cb)(void *userdata);
++
++pa_inotify *pa_inotify_start(const char *filename, void *userdata, pa_inotify_cb cb, pa_core *c);
++void pa_inotify_stop(pa_inotify *i);
++
++#endif
+Index: pulseaudio/src/pulsecore/pid.c
+===================================================================
+--- pulseaudio.orig/src/pulsecore/pid.c
++++ pulseaudio/src/pulsecore/pid.c
+@@ -183,6 +183,11 @@ static int proc_name_ours(pid_t pid, con
+ 
+ }
+ 
++char *pa_pid_file_name()
++{
++    return pa_runtime_path("pid");
++}
++
+ /* Create a new PID file for the current process. */
+ int pa_pid_file_create(const char *procname) {
+     int fd = -1;
+Index: pulseaudio/src/pulsecore/pid.h
+===================================================================
+--- pulseaudio.orig/src/pulsecore/pid.h
++++ pulseaudio/src/pulsecore/pid.h
+@@ -22,6 +22,7 @@
+   USA.
+ ***/
+ 
++char *pa_pid_file_name(void);
+ int pa_pid_file_create(const char *procname);
+ int pa_pid_file_remove(void);
+ int pa_pid_file_check_running(pid_t *pid, const char *procname);
diff --git a/debian/patches/0023-fixing_snd_mixer_poll_descriptors_count_when_zero.patch b/debian/patches/0023-fixing_snd_mixer_poll_descriptors_count_when_zero.patch
new file mode 100644
index 0000000..c4439fa
--- /dev/null
+++ b/debian/patches/0023-fixing_snd_mixer_poll_descriptors_count_when_zero.patch
@@ -0,0 +1,16 @@
+Description: Avoid abort when poll descriptor is 0 (LP: #1092377)
+
+Index: pulseaudio/src/modules/alsa/alsa-mixer.c
+===================================================================
+--- pulseaudio.orig/src/modules/alsa/alsa-mixer.c	2012-12-20 00:37:53.862456000 -0200
++++ pulseaudio/src/modules/alsa/alsa-mixer.c	2012-12-20 00:39:58.631080479 -0200
+@@ -160,6 +160,9 @@
+     if (n < 0) {
+         pa_log("snd_mixer_poll_descriptors_count() failed: %s", pa_alsa_strerror(n));
+         return;
++    } else if (n == 0) {
++        pa_log("snd_mixer_poll_descriptors_count() equal 0");
++        return;
+     }
+     num_fds = (unsigned) n;
+ 
diff --git a/debian/patches/0024-daemon-conf.c-changing-default-rlimit_rttime-value-t.patch b/debian/patches/0024-daemon-conf.c-changing-default-rlimit_rttime-value-t.patch
new file mode 100644
index 0000000..f2cde66
--- /dev/null
+++ b/debian/patches/0024-daemon-conf.c-changing-default-rlimit_rttime-value-t.patch
@@ -0,0 +1,26 @@
+From 264e2d7c27d0f690b67e4cacf7b19dfeb7eeeca0 Mon Sep 17 00:00:00 2001
+From: Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>
+Date: Fri, 27 Jun 2014 16:36:48 -0300
+Subject: [PATCH] daemon-conf.c: changing default rlimit_rttime value to 200 ms
+
+Since rtkit v11, the top limit for rttime is 200 ms (previously it
+was wrongly limited to 2 seconds).
+
+Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>
+---
+ src/daemon/daemon-conf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: pulseaudio/src/daemon/daemon-conf.c
+===================================================================
+--- pulseaudio.orig/src/daemon/daemon-conf.c
++++ pulseaudio/src/daemon/daemon-conf.c
+@@ -139,7 +139,7 @@ static const pa_daemon_conf default_conf
+    ,.rlimit_rtprio = { .value = 9, .is_set = true }    /* One below JACK's default for the server */
+ #endif
+ #ifdef RLIMIT_RTTIME
+-   ,.rlimit_rttime = { .value = PA_USEC_PER_SEC, .is_set = true }
++   ,.rlimit_rttime = { .value = 200*PA_USEC_PER_MSEC, .is_set = true } /* rtkit's limit is 200 ms */
+ #endif
+ #endif
+ };
diff --git a/debian/patches/0202-dont-probe-ucm.patch b/debian/patches/0202-dont-probe-ucm.patch
new file mode 100644
index 0000000..f0e0ca8
--- /dev/null
+++ b/debian/patches/0202-dont-probe-ucm.patch
@@ -0,0 +1,14 @@
+Index: pulseaudio-5.0/src/modules/alsa/alsa-ucm.c
+===================================================================
+--- pulseaudio-5.0.orig/src/modules/alsa/alsa-ucm.c	2014-03-19 13:15:43.734768910 +1100
++++ pulseaudio-5.0/src/modules/alsa/alsa-ucm.c	2014-03-19 13:15:43.730768910 +1100
+@@ -1541,7 +1541,8 @@
+         ucm_create_profile(ucm, ps, verb, verb_name, verb_desc);
+     }
+ 
+-    ucm_probe_profile_set(ucm, ps);
++/*  Just trust that the person writing the UCM file knows what (s)he was doing, right? */
++/*    ucm_probe_profile_set(ucm, ps); */
+     ps->probed = true;
+ 
+     return ps;
diff --git a/debian/patches/0203-card-Add-hook-before-profile-changes.patch b/debian/patches/0203-card-Add-hook-before-profile-changes.patch
new file mode 100644
index 0000000..0d091af
--- /dev/null
+++ b/debian/patches/0203-card-Add-hook-before-profile-changes.patch
@@ -0,0 +1,37 @@
+From 3e04d944626ba4caee8a4d74a683c6c967e935ca Mon Sep 17 00:00:00 2001
+From: David Henningsson <david.henningsson at canonical.com>
+Date: Tue, 13 Aug 2013 12:43:29 +0200
+Subject: [PATCH 203/204] card: Add hook before profile changes
+
+This is useful to modules that want to do things just before a
+profile becomes inactive.
+---
+ src/pulsecore/card.c |    2 ++
+ src/pulsecore/core.h |    1 +
+ 2 files changed, 3 insertions(+)
+
+Index: pulseaudio/src/pulsecore/card.c
+===================================================================
+--- pulseaudio.orig/src/pulsecore/card.c
++++ pulseaudio/src/pulsecore/card.c
+@@ -278,6 +278,8 @@ int pa_card_set_profile(pa_card *c, pa_c
+         return 0;
+     }
+ 
++    pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CARD_PROFILE_CHANGING], profile);
++
+     if ((r = c->set_profile(c, profile)) < 0)
+         return r;
+ 
+Index: pulseaudio/src/pulsecore/core.h
+===================================================================
+--- pulseaudio.orig/src/pulsecore/core.h
++++ pulseaudio/src/pulsecore/core.h
+@@ -116,6 +116,7 @@ typedef enum pa_core_hook {
+     PA_CORE_HOOK_CARD_PUT,
+     PA_CORE_HOOK_CARD_UNLINK,
+     PA_CORE_HOOK_CARD_PROFILE_CHANGED,
++    PA_CORE_HOOK_CARD_PROFILE_CHANGING,
+     PA_CORE_HOOK_CARD_PROFILE_ADDED,
+     PA_CORE_HOOK_CARD_PROFILE_AVAILABLE_CHANGED,
+     PA_CORE_HOOK_PORT_AVAILABLE_CHANGED,
diff --git a/debian/patches/0206-module-bluetooth-discover-adding-module-option-profi.patch b/debian/patches/0206-module-bluetooth-discover-adding-module-option-profi.patch
new file mode 100644
index 0000000..afc17c6
--- /dev/null
+++ b/debian/patches/0206-module-bluetooth-discover-adding-module-option-profi.patch
@@ -0,0 +1,45 @@
+From 6b12d4743640059c4ad9ffe055ddeebb616f6a9a Mon Sep 17 00:00:00 2001
+From: Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>
+Date: Sun, 22 Jun 2014 23:00:59 -0300
+Subject: [PATCH] module-bluetooth-discover: adding module option profile
+
+Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>
+---
+ src/modules/bluetooth/module-bluez4-discover.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+Index: pulseaudio-5.0/src/modules/bluetooth/module-bluez4-discover.c
+===================================================================
+--- pulseaudio-5.0.orig/src/modules/bluetooth/module-bluez4-discover.c
++++ pulseaudio-5.0/src/modules/bluetooth/module-bluez4-discover.c
+@@ -40,11 +40,13 @@
+ 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> "
++PA_MODULE_USAGE("profile=<a2dp|hsp|hfgw> "
++                "sco_sink=<name of sink> "
+                 "sco_source=<name of source> ");
+ PA_MODULE_LOAD_ONCE(true);
+ 
+ static const char* const valid_modargs[] = {
++    "profile",
+     "sco_sink",
+     "sco_source",
+     "async", /* deprecated */
+@@ -83,6 +85,15 @@ static pa_hook_result_t load_module_for_
+ 
+             args = pa_sprintf_malloc("address=\"%s\" path=\"%s\"", d->address, d->path);
+ 
++            if (pa_modargs_get_value(u->modargs, "profile", NULL)) {
++                char *profile;
++
++                profile = pa_sprintf_malloc("%s profile=\"%s\"", args,
++                                        pa_modargs_get_value(u->modargs, "profile", NULL));
++                pa_xfree(args);
++                args = profile;
++            }
++
+             if (pa_modargs_get_value(u->modargs, "sco_sink", NULL) &&
+                 pa_modargs_get_value(u->modargs, "sco_source", NULL)) {
+                 char *tmp;
diff --git a/debian/patches/0207-Enable-pulseaudio-droid.patch b/debian/patches/0207-Enable-pulseaudio-droid.patch
new file mode 100644
index 0000000..3105b2d
--- /dev/null
+++ b/debian/patches/0207-Enable-pulseaudio-droid.patch
@@ -0,0 +1,5513 @@
+Index: pulseaudio/configure.ac
+===================================================================
+--- pulseaudio.orig/configure.ac
++++ pulseaudio/configure.ac
+@@ -796,6 +796,21 @@ AM_CONDITIONAL([HAVE_ALSA], [test "x$HAV
+ AS_IF([test "x$HAVE_ALSA" = "x1"], AC_DEFINE([HAVE_ALSA], 1, [Have ALSA?]))
+ AS_IF([test "x$HAVE_ALSA_UCM" = "x1"], AC_DEFINE([HAVE_ALSA_UCM], 1, [Have ALSA UCM?]))
+ 
++#### Android Audio HAL support (optional) ####
++
++AC_ARG_ENABLE([android-hal],
++    AS_HELP_STRING([--disable-android-hal],[Disable optional droid module (Android Audio HAL support)]))
++
++AS_IF([test "x$enable_android_hal" != "xno"],
++    [PKG_CHECK_MODULES(LIBHARDWARE, [ libhardware ], HAVE_ANDROID=1, HAVE_ANDROID=0)],
++    HAVE_ANDROID=0)
++
++AS_IF([test "x$enable_android_hal" = "xyes" && test "x$HAVE_ANDROID" = "x0"],
++    [AC_MSG_ERROR([*** libhardware not found])])
++
++AM_CONDITIONAL([HAVE_ANDROID], [test "x$HAVE_ANDROID" = "x1"])
++AS_IF([test "x$HAVE_ANDROID" = "x1"], AC_DEFINE([HAVE_ANDROID], 1, [Have Android Audio HAL?]))
++
+ #### EsounD support (optional) ####
+ 
+ AC_ARG_ENABLE([esound],
+@@ -1417,6 +1432,7 @@ AS_IF([test "x$HAVE_X11" = "x1"], ENABLE
+ 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_ANDROID" = "x1"], ENABLE_ANDROID=yes, ENABLE_ANDROID=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)
+@@ -1473,6 +1489,7 @@ echo "
+     Enable OSS Wrapper:            ${ENABLE_OSS_WRAPPER}
+     Enable EsounD:                 ${ENABLE_ESOUND}
+     Enable Alsa:                   ${ENABLE_ALSA}
++    Enable Android Audio HAL:      ${ENABLE_ANDROID}
+     Enable CoreAudio:              ${ENABLE_COREAUDIO}
+     Enable Solaris:                ${ENABLE_SOLARIS}
+     Enable WaveOut:                ${ENABLE_WAVEOUT}
+Index: pulseaudio/src/Makefile.am
+===================================================================
+--- pulseaudio.orig/src/Makefile.am
++++ pulseaudio/src/Makefile.am
+@@ -1196,6 +1196,16 @@ modlibexec_LTLIBRARIES += \
+ 		module-alsa-source.la \
+ 		module-alsa-card.la
+ 
++if HAVE_ANDROID
++modlibexec_LTLIBRARIES += \
++		libdroid-util.la \
++		libdroid-sink.la \
++		libdroid-source.la \
++		module-droid-sink.la \
++		module-droid-source.la \
++		module-droid-card.la
++endif
++
+ dist_alsaprofilesets_DATA = \
+ 		modules/alsa/mixer/profile-sets/default.conf \
+ 		modules/alsa/mixer/profile-sets/extra-hdmi.conf \
+@@ -1459,6 +1469,13 @@ SYMDEF_FILES = \
+ 		module-filter-apply-symdef.h \
+ 		module-filter-heuristics-symdef.h
+ 
++if HAVE_ANDROID
++SYMDEF_FILES += \
++		module-droid-sink-symdef.h \
++		module-droid-source-symdef.h \
++		module-droid-card-symdef.h
++endif
++
+ if HAVE_ESOUND
+ SYMDEF_FILES += \
+ 		module-esound-protocol-tcp-symdef.h \
+@@ -1768,6 +1785,44 @@ libalsa_util_la_LIBADD += $(DBUS_LIBS)
+ libalsa_util_la_CFLAGS += $(DBUS_CFLAGS)
+ endif
+ 
++if HAVE_ANDROID
++libdroid_util_la_SOURCES = modules/droid/droid-util.c modules/droid/droid-util.h
++libdroid_util_la_LDFLAGS = -avoid-version
++libdroid_util_la_LIBADD = $(MODULE_LIBADD) $(LIBHARDWARE_LIBS)
++libdroid_util_la_CFLAGS = $(AM_CFLAGS) $(LIBHARDWARE_CFLAGS)
++
++libdroid_sink_la_SOURCES = modules/droid/droid-sink.c modules/droid/droid-sink.h
++libdroid_sink_la_LDFLAGS = -avoid-version
++libdroid_sink_la_LIBADD = $(MODULE_LIBADD) $(LIBHARDWARE_LIBS) libdroid-util.la
++libdroid_sink_la_CFLAGS = $(AM_CFLAGS) $(LIBHARDWARE_CFLAGS)
++
++libdroid_source_la_SOURCES = modules/droid/droid-source.c modules/droid/droid-source.h
++libdroid_source_la_LDFLAGS = -avoid-version
++libdroid_source_la_LIBADD = $(MODULE_LIBADD) $(LIBHARDWARE_LIBS) libdroid-util.la
++libdroid_source_la_CFLAGS = $(AM_CFLAGS) $(LIBHARDWARE_CFLAGS)
++
++module_droid_sink_la_SOURCES = modules/droid/module-droid-sink.c
++module_droid_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
++module_droid_sink_la_LIBADD = $(MODULE_LIBADD) $(LIBHARDWARE_LIBS) libdroid-util.la libdroid-sink.la
++module_droid_sink_la_CFLAGS = $(AM_CFLAGS) $(LIBHARDWARE_CFLAGS)
++
++module_droid_source_la_SOURCES = modules/droid/module-droid-source.c
++module_droid_source_la_LDFLAGS = $(MODULE_LDFLAGS)
++module_droid_source_la_LIBADD = $(MODULE_LIBADD) $(LIBHARDWARE_LIBS) libdroid-util.la libdroid-source.la
++module_droid_source_la_CFLAGS = $(AM_CFLAGS) $(LIBHARDWARE_CFLAGS)
++
++module_droid_card_la_SOURCES = modules/droid/module-droid-card.c
++module_droid_card_la_LDFLAGS = $(MODULE_LDFLAGS)
++module_droid_card_la_LIBADD = $(MODULE_LIBADD) $(LIBHARDWARE_LIBS) libdroid-util.la libdroid-sink.la libdroid-source.la
++module_droid_card_la_CFLAGS = $(AM_CFLAGS) $(LIBHARDWARE_CFLAGS)
++
++if HAVE_UDEV
++module_droid_card_la_SOURCES += modules/droid/droid-extcon.c modules/droid/droid-extcon.h
++module_droid_card_la_LIBADD += $(UDEV_LIBS)
++module_droid_card_la_CFLAGS += $(UDEV_CFLAGS)
++endif
++endif
++
+ module_alsa_sink_la_SOURCES = modules/alsa/module-alsa-sink.c
+ module_alsa_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
+ module_alsa_sink_la_LIBADD = $(MODULE_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la
+Index: pulseaudio/src/modules/droid/droid-extcon.c
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/droid-extcon.c
+@@ -0,0 +1,269 @@
++/***
++  This file is part of PulseAudio.
++
++  Copyright (C) 2013 Canonical Ltd.
++  Contact: David Henningsson
++           Ricardo Salveti de Araujo <ricardo.salveti at canonical.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 <pulsecore/core-util.h>
++#include <pulsecore/device-port.h>
++#include <pulsecore/i18n.h>
++#include <libudev.h>
++
++#include "droid-extcon.h"
++
++/* For android */
++#define EXTCON_NAME "switch"
++
++/* TODO: Backport stuff to 4.0, remove before upstreaming */
++#ifndef PA_PORT_AVAILABLE_YES
++#define PA_PORT_AVAILABLE_YES PA_AVAILABLE_YES
++#define PA_PORT_AVAILABLE_NO PA_AVAILABLE_NO
++#define PA_PORT_AVAILABLE_UNKNOWN PA_AVAILABLE_UNKNOWN
++#define pa_port_available_t pa_available_t
++#endif
++
++static pa_port_available_t hponly_avail(int state)
++{
++    return (state & 2) ? PA_PORT_AVAILABLE_YES : PA_PORT_AVAILABLE_NO;
++}
++
++static pa_port_available_t hsmic_avail(int state)
++{
++    return (state & 1) ? PA_PORT_AVAILABLE_YES : PA_PORT_AVAILABLE_NO;
++}
++
++struct droid_switch {
++    char *name;
++    uint32_t current_value;
++};
++
++static void droid_switch_free(struct droid_switch *as) {
++    if (!as)
++        return;
++    pa_xfree(as->name);
++    pa_xfree(as);
++}
++
++static struct droid_switch *droid_switch_new(const char *name) {
++
++    struct droid_switch *as = NULL;
++    char *filename = pa_sprintf_malloc("/sys/class/%s/%s/state", EXTCON_NAME, name);
++    char *state = pa_read_line_from_file(filename);
++
++    if (state == NULL) {
++        pa_log_debug("Cannot open '%s'. Skipping.", filename);
++        pa_xfree(filename);
++        return NULL;
++    }
++    pa_xfree(filename);
++
++    as = pa_xnew0(struct droid_switch, 1);
++    as->name = pa_xstrdup(name);
++
++    if (pa_atou(state, &as->current_value) < 0) {
++        pa_log_warn("Switch '%s' has invalid value '%s'", name, state);
++        pa_xfree(state);
++        droid_switch_free(as);
++        return NULL;
++    }
++    pa_log_debug("Switch '%s' opened with value '%s'", name, state);
++
++    return as;
++}
++
++struct udev_data {
++    struct udev *udev;
++    struct udev_monitor *monitor;
++    pa_io_event *event;
++};
++
++struct pa_droid_extcon {
++    pa_card *card;
++    struct droid_switch *h2w;
++    struct udev_data udev;
++};
++
++static struct droid_switch *find_matching_switch(pa_droid_extcon *u,
++                                                   const char *devpath) {
++
++    if (pa_streq(devpath, "/devices/virtual/" EXTCON_NAME "/h2w"))
++        return u->h2w;  /* To be extended if we ever support more switches */
++    return NULL;
++}
++
++static void notify_ports(pa_droid_extcon *u, struct droid_switch *as) {
++
++    pa_device_port *p;
++    void *state;
++
++    pa_assert(as == u->h2w); /* To be extended if we ever support more switches */
++
++    pa_log_debug("Value of switch %s is now %d.", as->name, as->current_value);
++
++    PA_HASHMAP_FOREACH(p, u->card->ports, state) {
++        if (p->direction == PA_DIRECTION_OUTPUT) {
++            if (!strcmp(p->name, "output-wired_headset"))
++                pa_device_port_set_available(p, hsmic_avail(as->current_value));
++            if (!strcmp(p->name, "output-wired_headphone"))
++                pa_device_port_set_available(p, hponly_avail(as->current_value));
++        }
++        if (p->direction == PA_DIRECTION_INPUT) {
++            if (!strcmp(p->name, "input-wired_headset"))
++                pa_device_port_set_available(p, hsmic_avail(as->current_value));
++        }
++    }
++}
++
++static void udev_cb(pa_mainloop_api *a, pa_io_event *e, int fd,
++                    pa_io_event_flags_t events, void *userdata) {
++
++    pa_droid_extcon *u = userdata;
++    struct udev_device *d = udev_monitor_receive_device(u->udev.monitor);
++    struct udev_list_entry *entry;
++    struct droid_switch *as;
++    const char *devpath, *state;
++
++    if (!d) {
++        pa_log("udev_monitor_receive_device failed.");
++        pa_assert(a);
++        a->io_free(u->udev.event);
++        u->udev.event = NULL;
++        return;
++    }
++
++    devpath = udev_device_get_devpath(d);
++    if (!devpath) {
++        pa_log("udev_device_get_devpath failed.");
++        goto out;
++    }
++    pa_log_debug("Got uevent with devpath=%s", devpath);
++
++    as = find_matching_switch(u, devpath);
++    if (!as)
++        goto out;
++
++    entry = udev_list_entry_get_by_name(
++            udev_device_get_properties_list_entry(d), "SWITCH_STATE");
++    if (!entry) {
++        pa_log("udev_list_entry_get_by_name failed to find 'SWITCH_STATE' entry.");
++        goto out;
++    }
++
++    state = udev_list_entry_get_value(entry);
++    if (!state) {
++        pa_log("udev_list_entry_get_by_name failed.");
++        goto out;
++    }
++
++    if (pa_atou(state, &as->current_value) < 0) {
++        pa_log_warn("Switch '%s' has invalid value '%s'", as->name, state);
++        goto out;
++    }
++
++    notify_ports(u, as);
++
++out:
++    udev_device_unref(d);
++}
++
++static bool init_udev(pa_droid_extcon *u, pa_core *core) {
++
++    int fd;
++
++    u->udev.udev = udev_new();
++    if (!u->udev.udev) {
++        pa_log("udev_new failed.");
++        return false;
++    }
++
++    u->udev.monitor = udev_monitor_new_from_netlink(u->udev.udev, "udev");
++    if (!u->udev.monitor) {
++        pa_log("udev_monitor_new_from_netlink failed.");
++        return false;
++    }
++
++    if (udev_monitor_filter_add_match_subsystem_devtype(u->udev.monitor, EXTCON_NAME, NULL) < 0) {
++        pa_log("udev_monitor_filter_add_match_subsystem_devtype failed.");
++        return false;
++    }
++
++    if (udev_monitor_enable_receiving(u->udev.monitor) < 0) {
++        pa_log("udev_monitor_enable_receiving failed.");
++        return false;
++    }
++
++    fd = udev_monitor_get_fd(u->udev.monitor);
++    if (fd < 0) {
++        pa_log("udev_monitor_get_fd failed");
++        return false;
++    }
++
++    pa_assert_se(u->udev.event = core->mainloop->io_new(core->mainloop, fd,
++                 PA_IO_EVENT_INPUT, udev_cb, u));
++
++    return true;
++}
++
++pa_droid_extcon *pa_droid_extcon_new(pa_core *core, pa_card *card) {
++
++    pa_droid_extcon *u = pa_xnew0(pa_droid_extcon, 1);
++
++    pa_assert(core);
++    pa_assert(card);
++
++    u->card = card;
++    u->h2w = droid_switch_new("h2w");
++    if (!u->h2w)
++        goto fail;
++
++    if (!init_udev(u, core))
++        goto fail;
++
++    notify_ports(u, u->h2w);
++
++    return u;
++
++fail:
++    pa_droid_extcon_free(u);
++    return NULL;
++}
++
++void pa_droid_extcon_free(pa_droid_extcon *u) {
++
++    pa_assert(u);
++
++    if (u->udev.event)
++        u->card->core->mainloop->io_free(u->udev.event);
++
++    if (u->udev.monitor)
++        udev_monitor_unref(u->udev.monitor);
++
++    if (u->udev.udev)
++        udev_unref(u->udev.udev);
++
++    if (u->h2w)
++        droid_switch_free(u->h2w);
++
++    pa_xfree(u);
++}
+Index: pulseaudio/src/modules/droid/droid-extcon.h
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/droid-extcon.h
+@@ -0,0 +1,32 @@
++#ifndef foodroidextconhfoo
++#define foodroidextconhfoo
++
++/***
++  This file is part of PulseAudio.
++
++  Copyright (C) 2013 Canonical Ltd.
++  Contact: David Henningsson
++
++  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_droid_extcon pa_droid_extcon;
++
++pa_droid_extcon *pa_droid_extcon_new(pa_core *, pa_card *);
++
++void pa_droid_extcon_free(pa_droid_extcon *);
++
++#endif
+Index: pulseaudio/src/modules/droid/droid-sink.c
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/droid-sink.c
+@@ -0,0 +1,1394 @@
++/*
++ * Copyright (C) 2013 Jolla Ltd.
++ * Copyright (C) 2010 Nokia Corporation.
++ *
++ * Contact: Juho Hämäläinen <juho.hamalainen at tieto.com>
++ *
++ * These PulseAudio Modules are 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
++ * version 2.1 of the License.
++ *
++ * 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 Street, Fifth Floor, Boston, MA 02110-1301
++ * USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <signal.h>
++#include <stdio.h>
++#define __STDC_FORMAT_MACROS
++#include <inttypes.h>
++
++#ifdef HAVE_VALGRIND_MEMCHECK_H
++#include <valgrind/memcheck.h>
++#endif
++
++#include <pulse/rtclock.h>
++#include <pulse/timeval.h>
++#include <pulse/volume.h>
++#include <pulse/xmalloc.h>
++
++#include <pulsecore/core.h>
++#include <pulsecore/i18n.h>
++#include <pulsecore/module.h>
++#include <pulsecore/memchunk.h>
++#include <pulsecore/sink.h>
++#include <pulsecore/modargs.h>
++#include <pulsecore/core-rtclock.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/thread-mq.h>
++#include <pulsecore/rtpoll.h>
++#include <pulsecore/time-smoother.h>
++#include <pulsecore/hashmap.h>
++#include <pulsecore/core-subscribe.h>
++
++#include "droid-sink.h"
++#include "droid-util.h"
++
++struct userdata {
++    pa_core *core;
++    pa_module *module;
++    pa_card *card;
++    pa_sink *sink;
++
++    pa_thread *thread;
++    pa_thread_mq thread_mq;
++    pa_rtpoll *rtpoll;
++    int32_t routing_counter;
++    int32_t mute_routing_before;
++    int32_t mute_routing_after;
++
++    bool deferred_volume; /* TODO */
++
++    pa_memblockq *memblockq;
++    pa_memchunk silence;
++    size_t buffer_count;
++    size_t buffer_size;
++    pa_usec_t buffer_latency;
++    pa_usec_t timestamp;
++
++    audio_devices_t primary_devices;
++    audio_devices_t extra_devices;
++
++    bool use_hw_volume;
++    bool use_voice_volume;
++    bool voice_volume_call_mode;
++    bool voice_virtual_stream;
++    char *voice_property_key;
++    char *voice_property_value;
++    pa_sink_input *voice_virtual_sink_input;
++    pa_sink_input *voice_control_sink_input;
++    pa_subscription *sink_input_subscription;
++
++    pa_hook_slot *sink_input_put_hook_slot;
++    pa_hook_slot *sink_input_unlink_hook_slot;
++    pa_hook_slot *sink_proplist_changed_hook_slot;
++    pa_hashmap *parameters;
++
++    pa_droid_card_data *card_data;
++    pa_droid_hw_module *hw_module;
++    struct audio_stream_out *stream_out;
++
++    char *sco_fake_sink_name;
++    struct pa_sink *sco_fake_sink;
++};
++
++enum {
++    SINK_MESSAGE_DO_ROUTING = PA_SINK_MESSAGE_MAX,
++};
++
++#define DEFAULT_MODULE_ID "primary"
++
++/* sink properties */
++#define PROP_DROID_PARAMETER_PREFIX "droid.parameter."
++typedef struct droid_parameter_mapping {
++    char *key;
++    char *value;
++} droid_parameter_mapping;
++
++/* sink-input properties */
++#define PROP_DROID_ROUTE "droid.device.additional-route"
++
++/* Voice call volume control.
++ * With defaults defined below, whenever sink-input with proplist key "media.role" with
++ * value "phone" connects to the sink AND voice volume control is enabled, that connected
++ * sink-input's absolute volume is used for HAL voice volume. */
++#define DEFAULT_VOICE_CONTROL_PROPERTY_KEY      "media.role"
++#define DEFAULT_VOICE_CONTROL_PROPERTY_VALUE    "phone"
++
++/* While the HAL interface supports until 0, android just use up to ~0.05
++ * Lower values can crash the modem or cause mixer issues */
++#define VOICE_VOLUME_MIN_VALUE                  0.05
++
++/* Name of the fake sco sink used for HSP (used to set transport property) */
++#define DEFAULT_SCO_FAKE_SINK "sink.fake.sco"
++#define HSP_PREVENT_SUSPEND_STR "bluetooth.hsp.prevent.suspend.transport"
++
++static void userdata_free(struct userdata *u);
++static void set_voice_volume_from_input(struct userdata *u, pa_sink_input *i);
++static struct pa_sink *pa_sco_fake_sink_discover(pa_core *core, const char *sink_name);
++
++static void set_primary_devices(struct userdata *u, audio_devices_t devices) {
++    pa_assert(u);
++    pa_assert(devices);
++
++    u->primary_devices = devices;
++}
++
++static void add_extra_devices(struct userdata *u, audio_devices_t devices) {
++    pa_assert(u);
++    pa_assert(devices);
++
++    u->extra_devices |= devices;
++}
++
++static void remove_extra_devices(struct userdata *u, audio_devices_t devices) {
++    pa_assert(u);
++    pa_assert(devices);
++
++    u->extra_devices &= ~devices;
++}
++
++static void parameter_free(droid_parameter_mapping *m) {
++    pa_assert(m);
++
++    pa_xfree(m->key);
++    pa_xfree(m->value);
++    pa_xfree(m);
++}
++
++static void set_fake_sco_sink_transport_property(struct userdata *u, const char *value) {
++    pa_proplist *pl;
++
++    pa_assert(u);
++    pa_assert(value);
++    pa_assert(u->sco_fake_sink);
++
++    pl = pa_proplist_new();
++    pa_proplist_sets(pl, HSP_PREVENT_SUSPEND_STR, value);
++    pa_sink_update_proplist(u->sco_fake_sink, PA_UPDATE_REPLACE, pl);
++    pa_proplist_free(pl);
++}
++
++/* Called from main context during voice calls, and from IO context during media operation. */
++static bool do_routing(struct userdata *u) {
++    audio_devices_t routing;
++    char tmp[32];
++
++    pa_assert(u);
++    pa_assert(u->stream_out);
++
++    routing = u->primary_devices | u->extra_devices;
++
++    pa_snprintf(tmp, sizeof(tmp), "%s=%u;", AUDIO_PARAMETER_STREAM_ROUTING, routing);
++    pa_log_debug("Routing: set_parameters(): %s (%#010x)", tmp, routing);
++    pa_droid_hw_module_lock(u->hw_module);
++    u->stream_out->common.set_parameters(&u->stream_out->common, tmp);
++    pa_droid_hw_module_unlock(u->hw_module);
++
++    return true;
++}
++
++static bool parse_device_list(const char *str, audio_devices_t *dst) {
++    char *dev;
++    const char *state = NULL;
++
++    pa_assert(str);
++    pa_assert(dst);
++
++    *dst = 0;
++
++    while ((dev = pa_split(str, "|", &state))) {
++        audio_devices_t d;
++
++        if (!pa_string_convert_output_device_str_to_num(dev, &d)) {
++            pa_log_warn("Unknown device %s", dev);
++            pa_xfree(dev);
++            return false;
++        }
++
++        *dst |= d;
++
++        pa_xfree(dev);
++    }
++
++    return true;
++}
++
++static int thread_write_silence(struct userdata *u) {
++    const void *p;
++    ssize_t wrote;
++
++    /* Drop our rendered audio and write silence to HAL. */
++    pa_memblockq_drop(u->memblockq, u->buffer_size);
++
++    /* We should be able to write everything in one go as long as memblock size
++     * is multiples of buffer_size. Even if we don't write whole buffer size
++     * here it's okay, as long as mute time isn't configured too strictly. */
++
++    p = pa_memblock_acquire(u->silence.memblock);
++    wrote = u->stream_out->write(u->stream_out, (const uint8_t*) p + u->silence.index, u->silence.length);
++    pa_memblock_release(u->silence.memblock);
++
++    if (wrote < 0)
++        return -1;
++
++    return 0;
++}
++
++static int thread_write(struct userdata *u) {
++    pa_memchunk c;
++    const void *p;
++    ssize_t wrote;
++
++    pa_memblockq_peek_fixed_size(u->memblockq, u->buffer_size, &c);
++
++    /* We should be able to write everything in one go as long as memblock size
++     * is multiples of buffer_size. */
++
++    for (;;) {
++        p = pa_memblock_acquire(c.memblock);
++        wrote = u->stream_out->write(u->stream_out, (const uint8_t*) p + c.index, c.length);
++        pa_memblock_release(c.memblock);
++
++        if (wrote < 0) {
++            pa_memblockq_drop(u->memblockq, c.length);
++            pa_memblock_unref(c.memblock);
++            return -1;
++        }
++
++        if (wrote < (ssize_t) c.length) {
++            c.index += wrote;
++            c.length -= wrote;
++            continue;
++        }
++
++        pa_memblockq_drop(u->memblockq, c.length);
++        pa_memblock_unref(c.memblock);
++
++        break;
++    }
++
++    return 0;
++}
++static void thread_render(struct userdata *u) {
++    size_t length;
++    size_t missing;
++
++    length = pa_memblockq_get_length(u->memblockq);
++    missing = u->buffer_size * u->buffer_count - length;
++
++    if (missing > 0) {
++        pa_memchunk c;
++        pa_sink_render_full(u->sink, missing, &c);
++        pa_memblockq_push_align(u->memblockq, &c);
++        pa_memblock_unref(c.memblock);
++    }
++}
++
++static void process_rewind(struct userdata *u) {
++    size_t rewind_nbytes;
++    size_t max_rewind_nbytes;
++    size_t queue_length;
++
++    pa_assert(u);
++
++    if (u->sink->thread_info.rewind_nbytes == 0) {
++        pa_sink_process_rewind(u->sink, 0);
++        return;
++    }
++
++    rewind_nbytes = u->sink->thread_info.rewind_nbytes;
++    u->sink->thread_info.rewind_nbytes = 0;
++
++    pa_assert(rewind_nbytes > 0);
++    pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes);
++
++    queue_length = pa_memblockq_get_length(u->memblockq);
++    if (queue_length <= u->buffer_size)
++        goto do_nothing;
++    max_rewind_nbytes = queue_length - u->buffer_size;
++    if (max_rewind_nbytes == 0)
++        goto do_nothing;
++
++    if (rewind_nbytes > max_rewind_nbytes)
++        rewind_nbytes = max_rewind_nbytes;
++
++    pa_memblockq_drop(u->memblockq, rewind_nbytes);
++
++    pa_sink_process_rewind(u->sink, rewind_nbytes);
++
++    pa_log_debug("Rewound %lu bytes.", (unsigned long) rewind_nbytes);
++    return;
++
++do_nothing:
++    pa_log_debug("Rewound 0 bytes.");
++    pa_sink_process_rewind(u->sink, 0);
++}
++
++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);
++
++    pa_thread_mq_install(&u->thread_mq);
++
++    u->timestamp = 0;
++
++    for (;;) {
++        int ret;
++
++        if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
++
++            u->timestamp = pa_rtclock_now();
++
++            if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
++                process_rewind(u);
++            else
++                thread_render(u);
++
++            if (pa_rtpoll_timer_elapsed(u->rtpoll)) {
++                pa_usec_t now, sleept;
++
++                if (u->routing_counter == u->mute_routing_after) {
++                    do_routing(u);
++                    u->routing_counter--;
++                } else if (u->routing_counter > -1) {
++                    thread_write_silence(u);
++                    u->routing_counter--;
++                } else
++                    thread_write(u);
++
++                now = pa_rtclock_now();
++
++                if (now - u->timestamp > u->buffer_latency / 2)
++                    sleept = 0;
++                else
++                    sleept = u->buffer_latency / 2 - (now - u->timestamp) ;
++
++                pa_rtpoll_set_timer_relative(u->rtpoll, sleept);
++            }
++        } else
++            pa_rtpoll_set_timer_disabled(u->rtpoll);
++
++        /* 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.");
++}
++
++/* Called from IO context */
++static int suspend(struct userdata *u) {
++    int ret;
++    size_t length;
++
++    pa_assert(u);
++    pa_assert(u->sink);
++    pa_assert(u->stream_out);
++
++    ret = u->stream_out->common.standby(&u->stream_out->common);
++
++    if (ret == 0) {
++        pa_sink_set_max_request_within_thread(u->sink, 0);
++        pa_log_info("Device suspended.");
++    } else
++        pa_log("Couldn't set standby, err %d", ret);
++
++    /* Clear memblockq */
++    if ((length = pa_memblockq_get_length(u->memblockq)) > 0)
++        pa_memblockq_drop(u->memblockq, length);
++
++    return ret;
++}
++
++static int unsuspend(struct userdata *u) {
++    pa_assert(u);
++    pa_assert(u->sink);
++
++    /* HAL resumes automagically when writing to standby stream, but let's set max request */
++    pa_sink_set_max_request_within_thread(u->sink, u->buffer_size);
++
++    pa_log_info("Resuming...");
++
++    return 0;
++}
++
++/* Called from IO context */
++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 SINK_MESSAGE_DO_ROUTING: {
++            /* When mute_routing_before & mute_routing_after are 0, routing change is done
++             * immediately when next round in thread_func. Otherwise write silence until
++             * counter equals mute_routing_after, execute routing, and write silence until
++             * routing_counter is 0. */
++            u->routing_counter = u->mute_routing_before + u->mute_routing_after;
++            return 0;
++        }
++
++        case PA_SINK_MESSAGE_GET_LATENCY: {
++            pa_usec_t r = 0;
++
++            /* HAL reports milliseconds */
++            if (u->stream_out)
++                r = u->stream_out->get_latency(u->stream_out) * PA_USEC_PER_MSEC * u->buffer_count;
++
++            *((pa_usec_t*) data) = r;
++
++            return 0;
++        }
++
++        case PA_SINK_MESSAGE_SET_STATE: {
++            switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) {
++                case PA_SINK_SUSPENDED: {
++                    int r;
++
++                    pa_assert(PA_SINK_IS_OPENED(u->sink->thread_info.state));
++
++                    if ((r = suspend(u)) < 0)
++                        return r;
++
++                    break;
++                }
++
++                case PA_SINK_IDLE:
++                    /* Fall through */
++                case PA_SINK_RUNNING: {
++                    int r;
++                    u->timestamp = 0;
++
++                    if (u->sink->thread_info.state == PA_SINK_SUSPENDED) {
++                        if ((r = unsuspend(u)) < 0)
++                            return r;
++                    }
++
++                    pa_rtpoll_set_timer_absolute(u->rtpoll, pa_rtclock_now());
++                    break;
++                }
++
++                /* not needed */
++                case PA_SINK_UNLINKED:
++                case PA_SINK_INIT:
++                case PA_SINK_INVALID_STATE:
++                    ;
++            }
++            break;
++        }
++    }
++
++    return pa_sink_process_msg(o, code, data, offset, chunk);
++}
++
++static int sink_set_port_cb(pa_sink *s, pa_device_port *p) {
++    struct userdata *u = s->userdata;
++    pa_droid_port_data *data;
++    const char *sco_transport_enabled;
++
++    pa_assert(u);
++    pa_assert(p);
++
++    data = PA_DEVICE_PORT_DATA(p);
++
++    if (!data->device) {
++        /* If there is no device defined, just return 0 to say everything is ok.
++         * Then next port change can be whatever sink port, even the one enabled
++         * before parking. */
++        pa_log_debug("Sink set port to parking");
++        return 0;
++    }
++
++    pa_log_debug("Sink set port %u", data->device);
++
++    set_primary_devices(u, data->device);
++
++    /* See if the sco fake sink element is available (only when needed) */
++    if ((u->sco_fake_sink == NULL) && (data->device & AUDIO_DEVICE_OUT_ALL_SCO))
++        u->sco_fake_sink = pa_sco_fake_sink_discover(u->core, u->sco_fake_sink_name);
++
++    /* Update the bluetooth hsp transport property before we do the routing */
++    if (u->sco_fake_sink) {
++        sco_transport_enabled = pa_proplist_gets(u->sco_fake_sink->proplist, HSP_PREVENT_SUSPEND_STR);
++        if (sco_transport_enabled && pa_streq(sco_transport_enabled, "true")) {
++            if (data->device & ~AUDIO_DEVICE_OUT_ALL_SCO)
++                set_fake_sco_sink_transport_property(u, "false");
++        } else if (data->device & AUDIO_DEVICE_OUT_ALL_SCO)
++            set_fake_sco_sink_transport_property(u, "true");
++    }
++
++    /* If we are in voice call, sink is usually in suspended state and routing change can be applied immediately.
++     * When in media use cases, do the routing change in IO thread. */
++    if (u->use_voice_volume)
++        do_routing(u);
++    else {
++        pa_asyncmsgq_post(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_DO_ROUTING, NULL, 0, NULL, NULL);
++    }
++
++    return 0;
++}
++
++static void sink_set_volume_cb(pa_sink *s) {
++    struct userdata *u = s->userdata;
++    pa_cvolume r;
++
++    /* Shift up by the base volume */
++    pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
++
++    if (r.channels == 1) {
++        float val = pa_sw_volume_to_linear(r.values[0]);
++        pa_log_debug("Set hw volume %f", val);
++        pa_droid_hw_module_lock(u->hw_module);
++        if (u->stream_out->set_volume(u->stream_out, val, val) < 0)
++            pa_log_warn("Failed to set hw volume.");
++        pa_droid_hw_module_unlock(u->hw_module);
++    } else if (r.channels == 2) {
++        float val[2];
++        for (unsigned i = 0; i < 2; i++)
++            val[i] = pa_sw_volume_to_linear(r.values[i]);
++        pa_log_debug("Set hw volume %f : %f", val[0], val[1]);
++        pa_droid_hw_module_lock(u->hw_module);
++        if (u->stream_out->set_volume(u->stream_out, val[0], val[1]) < 0)
++            pa_log_warn("Failed to set hw volume.");
++        pa_droid_hw_module_unlock(u->hw_module);
++    }
++}
++
++/* Called from main context when set from input and from IO when set from sink volume. */
++static void set_voice_volume(struct userdata *u, pa_cvolume vol) {
++    float val;
++
++    pa_assert(u);
++
++    val = pa_sw_volume_to_linear(pa_cvolume_avg(&vol));
++
++    /* Make sure our lower value is still HAL compatible */
++    if (val < VOICE_VOLUME_MIN_VALUE) {
++        val = VOICE_VOLUME_MIN_VALUE;
++        pa_log_debug("Forcing minimal voice volume to %f", val);
++    }
++
++    pa_log_debug("Set voice volume %f", val);
++
++    pa_droid_hw_module_lock(u->hw_module);
++    if (u->hw_module->device->set_voice_volume(u->hw_module->device, val) < 0)
++        pa_log_warn("Failed to set voice volume.");
++    pa_droid_hw_module_unlock(u->hw_module);
++}
++
++static void sink_set_voice_volume_cb(pa_sink *s) {
++    struct userdata *u = s->userdata;
++    pa_cvolume r;
++
++    /* Shift up by the base volume */
++    pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
++
++    set_voice_volume(u, r);
++}
++
++/* Called from main thread */
++static void set_voice_volume_from_input(struct userdata *u, pa_sink_input *i) {
++    pa_cvolume vol;
++    float val;
++
++    pa_assert_ctl_context();
++    pa_assert(u);
++    pa_assert(i);
++
++    pa_sink_input_get_volume(i, &vol, true);
++
++    set_voice_volume(u, vol);
++}
++
++static void update_volumes(struct userdata *u) {
++    int ret = -1;
++
++    /* set_volume returns 0 if hw volume control is implemented, < 0 otherwise. */
++    pa_droid_hw_module_lock(u->hw_module);
++    if (u->stream_out->set_volume) {
++        pa_log_debug("Probe hw volume support for %s", u->sink->name);
++        pa_log_debug("Stream out volume set to 1.0f, 1.0f");
++        ret = u->stream_out->set_volume(u->stream_out, 1.0f, 1.0f);
++    }
++    pa_droid_hw_module_unlock(u->hw_module);
++
++    u->use_hw_volume = (ret == 0);
++
++    /* Apply callbacks */
++    pa_droid_sink_set_voice_control(u->sink, false);
++}
++
++static void set_sink_name(pa_modargs *ma, pa_sink_new_data *data, const char *module_id) {
++    const char *tmp;
++
++    pa_assert(ma);
++    pa_assert(data);
++
++    if ((tmp = pa_modargs_get_value(ma, "sink_name", NULL))) {
++        pa_sink_new_data_set_name(data, tmp);
++        data->namereg_fail = true;
++        pa_proplist_sets(data->proplist, PA_PROP_DEVICE_DESCRIPTION, "Droid sink");
++    } else {
++        char *tt;
++        pa_assert(module_id);
++        tt = pa_sprintf_malloc("sink.%s", module_id);
++        pa_sink_new_data_set_name(data, tt);
++        pa_xfree(tt);
++        data->namereg_fail = false;
++        pa_proplist_setf(data->proplist, PA_PROP_DEVICE_DESCRIPTION, "Droid sink %s", module_id);
++    }
++}
++
++/* Called from main thread */
++static pa_sink_input *find_volume_control_sink_input(struct userdata *u) {
++    const char *val;
++    uint32_t idx;
++    pa_sink_input *i;
++
++    pa_assert_ctl_context();
++    pa_assert(u);
++    pa_assert(u->sink);
++
++    PA_IDXSET_FOREACH(i, u->sink->inputs, idx) {
++        if ((val = pa_proplist_gets(i->proplist, u->voice_property_key))) {
++            if (pa_streq(val, u->voice_property_value)) {
++                return i;
++            }
++        }
++    }
++
++    return NULL;
++}
++
++/* Called from main thread */
++static void sink_input_subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, struct userdata *u) {
++    pa_sink_input *i;
++
++    pa_assert_ctl_context();
++
++    if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT | PA_SUBSCRIPTION_EVENT_NEW) &&
++        t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT | PA_SUBSCRIPTION_EVENT_CHANGE) &&
++        t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT | PA_SUBSCRIPTION_EVENT_REMOVE))
++        return;
++
++    if (!(i = pa_idxset_get_by_index(c->sink_inputs, idx)))
++        return;
++
++    if (t == (PA_SUBSCRIPTION_EVENT_SINK_INPUT | PA_SUBSCRIPTION_EVENT_NEW)) {
++        if (!u->voice_control_sink_input && (i = find_volume_control_sink_input(u))) {
++            u->voice_control_sink_input = i;
++            set_voice_volume_from_input(u, i);
++        }
++    }
++    else if (t == (PA_SUBSCRIPTION_EVENT_SINK_INPUT | PA_SUBSCRIPTION_EVENT_CHANGE)) {
++        if (u->voice_control_sink_input == i)
++            set_voice_volume_from_input(u, i);
++    }
++    else if (t == (PA_SUBSCRIPTION_EVENT_SINK_INPUT | PA_SUBSCRIPTION_EVENT_REMOVE)) {
++        if (u->voice_control_sink_input == i)
++            u->voice_control_sink_input = NULL;
++    }
++}
++
++/* For voice virtual stream, based on meego-mainvolume */
++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);
++
++    pa_sink_input_unlink(u->voice_virtual_sink_input);
++    pa_sink_input_unref(u->voice_virtual_sink_input);
++    u->voice_virtual_sink_input = NULL;
++}
++
++/* no-op */
++static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
++    return 0;
++}
++
++/* no-op */
++static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
++}
++
++static void create_voice_virtual_stream(struct userdata *u) {
++    pa_sink_input_new_data data;
++
++    pa_assert(u);
++
++    if (!u->voice_virtual_stream || u->voice_virtual_sink_input)
++        return;
++
++    pa_sink_input_new_data_init(&data);
++
++    data.driver = __FILE__;
++    data.module = u->module;
++    pa_proplist_sets(data.proplist, PA_PROP_MEDIA_NAME, "Virtual Stream for Voice Volume Control (Droid)");
++    pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "phone");
++    pa_sink_input_new_data_set_sample_spec(&data, &u->core->default_sample_spec);
++    pa_sink_input_new_data_set_channel_map(&data, &u->core->default_channel_map);
++    data.flags = PA_SINK_INPUT_START_CORKED | PA_SINK_INPUT_NO_REMAP | PA_SINK_INPUT_NO_REMIX;
++
++    pa_sink_input_new(&u->voice_virtual_sink_input, u->module->core, &data);
++    pa_sink_input_new_data_done(&data);
++
++    if (!u->voice_virtual_sink_input) {
++        pa_log_warn("Failed to create virtual sink input.");
++        return;
++    }
++
++    u->voice_virtual_sink_input->userdata = u;
++    u->voice_virtual_sink_input->kill = sink_input_kill_cb;
++    u->voice_virtual_sink_input->pop = sink_input_pop_cb;
++    u->voice_virtual_sink_input->process_rewind = sink_input_process_rewind_cb;
++
++    pa_sink_input_put(u->voice_virtual_sink_input);
++
++    pa_log_debug("Created virtual sink input for voice call volume control.");
++}
++
++static void destroy_voice_virtual_stream(struct userdata *u) {
++    pa_assert(u);
++
++    if (!u->voice_virtual_sink_input)
++        return;
++
++    sink_input_kill_cb(u->voice_virtual_sink_input);
++
++    pa_log_debug("Removed virtual stream.");
++}
++
++/* Called from main thread */
++void pa_droid_sink_set_voice_control(pa_sink* sink, bool enable) {
++    pa_sink_input *i;
++    struct userdata *u;
++
++    pa_assert_ctl_context();
++    pa_assert(sink);
++
++    u = sink->userdata;
++    pa_assert(u);
++    pa_assert(u->sink == sink);
++
++    pa_log_debug("Set voice control - use_voice_volume: %d, enable: %d", u->use_voice_volume, enable);
++    if (u->use_voice_volume == enable)
++        return;
++
++    u->use_voice_volume = enable;
++
++    if (u->use_voice_volume) {
++        pa_log_debug("Using voice volume control for %s", u->sink->name);
++
++        if (u->voice_virtual_stream)
++            create_voice_virtual_stream(u);
++
++        if (u->voice_volume_call_mode) {
++            /* In this case we want the sink volume to directly map into the voice volume */
++            pa_log_debug("Sink volume is now controlling the voice volume for %s", u->sink->name);
++
++            /* First disable module-device-restore, as we don't want to save the voice volume
++             * as the default sink volume when restoring to the default mode */
++            pa_proplist_sets(u->sink->proplist, MODULE_DEVICE_RESTORE_SKIP_PROPERTY, "true");
++
++            /* Then map normal sink volume changes to voice call volume changes */
++            pa_sink_set_set_volume_callback(u->sink, sink_set_voice_volume_cb);
++        } else {
++            pa_sink_set_set_volume_callback(u->sink, NULL);
++
++            /* Susbcription tracking voice call volume control sink-input is set up when
++             * voice volume control is enabled. In case volume control sink-input has already
++             * connected to the sink, check for the sink-input here as well. */
++
++            if (!u->sink_input_subscription)
++                u->sink_input_subscription = pa_subscription_new(u->core,
++                                                                 PA_SUBSCRIPTION_MASK_SINK_INPUT,
++                                                                 (pa_subscription_cb_t) sink_input_subscription_cb,
++                                                                 u);
++
++            if ((i = find_volume_control_sink_input(u))) {
++                u->voice_control_sink_input = i;
++                set_voice_volume_from_input(u, i);
++            }
++        }
++    } else {
++        if (u->voice_virtual_stream)
++            destroy_voice_virtual_stream(u);
++
++        if (u->voice_volume_call_mode) {
++            /* Enable module-device-restore again now that we're back to !voicecall mode */
++            pa_proplist_unset(u->sink->proplist, MODULE_DEVICE_RESTORE_SKIP_PROPERTY);
++        }
++
++        if (u->sink_input_subscription) {
++            pa_subscription_free(u->sink_input_subscription);
++            u->sink_input_subscription = NULL;
++            u->voice_control_sink_input = NULL;
++        }
++
++        if (u->use_hw_volume) {
++            pa_log_debug("Using hardware volume control for %s", u->sink->name);
++            pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
++        } else {
++            pa_log_debug("Using software volume control for %s", u->sink->name);
++            pa_sink_set_set_volume_callback(u->sink, NULL);
++        }
++    }
++}
++
++/* When sink-input with proper proplist variable appears, do extra routing configuration
++ * for the lifetime of that sink-input. */
++static pa_hook_result_t sink_input_put_hook_cb(pa_core *c, pa_sink_input *sink_input, struct userdata *u) {
++    const char *dev_str;
++    const char *media_str;
++    audio_devices_t devices;
++
++    /* Dynamic routing changes do not apply during active voice call. */
++    if (u->use_voice_volume)
++        return PA_HOOK_OK;
++
++    if ((dev_str = pa_proplist_gets(sink_input->proplist, PROP_DROID_ROUTE))) {
++
++        /* Do not change routing for gstreamer pulsesink probe. Workaround for unnecessary routing changes when gst-plugin
++         * pulsesink connects to our sink. Not the best fix or the best place for a fix, but let's have this here
++         * for now anyway. */
++        if ((media_str = pa_proplist_gets(sink_input->proplist, PA_PROP_MEDIA_NAME)) && pa_streq(media_str, "pulsesink probe"))
++            return PA_HOOK_OK;
++
++        if (parse_device_list(dev_str, &devices) && devices) {
++
++            pa_log_debug("Add extra route %s (%u).", dev_str, devices);
++
++            add_extra_devices(u, devices);
++            /* post routing change */
++            pa_asyncmsgq_post(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_DO_ROUTING, NULL, 0, NULL, NULL);
++        }
++    }
++
++    return PA_HOOK_OK;
++}
++
++/* Remove extra routing when sink-inputs disappear. */
++static pa_hook_result_t sink_input_unlink_hook_cb(pa_core *c, pa_sink_input *sink_input, struct userdata *u) {
++    const char *dev_str;
++    const char *media_str;
++    audio_devices_t devices;
++
++    /* Dynamic routing changes do not apply during active voice call. */
++    if (u->use_voice_volume)
++        return PA_HOOK_OK;
++
++    if ((dev_str = pa_proplist_gets(sink_input->proplist, PROP_DROID_ROUTE))) {
++
++        /* Do not change routing for gstreamer pulsesink probe. Workaround for unnecessary routing changes when gst-plugin
++         * pulsesink connects to our sink. Not the best fix or the best place for a fix, but let's have this here
++         * for now anyway. */
++        if ((media_str = pa_proplist_gets(sink_input->proplist, PA_PROP_MEDIA_NAME)) && pa_streq(media_str, "pulsesink probe"))
++            return PA_HOOK_OK;
++
++        if (parse_device_list(dev_str, &devices) && devices) {
++
++            pa_log_debug("Remove extra route %s (%u).", dev_str, devices);
++
++            remove_extra_devices(u, devices);
++            /* post routing change */
++            pa_asyncmsgq_post(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_DO_ROUTING, NULL, 0, NULL, NULL);
++        }
++    }
++
++    return PA_HOOK_OK;
++}
++
++/* Watch for properties starting with droid.parameter. and translate them directly to
++ * HAL set_parameters() calls. */
++static pa_hook_result_t sink_proplist_changed_hook_cb(pa_core *c, pa_sink *sink, struct userdata *u) {
++    bool changed = false;
++    const char *pkey;
++    const char *key;
++    const char *value;
++    char *tmp;
++    void *state = NULL;
++    droid_parameter_mapping *parameter = NULL;
++
++    pa_assert(sink);
++    pa_assert(u);
++
++    if (u->sink != sink)
++        return PA_HOOK_OK;
++
++    while ((key = pa_proplist_iterate(sink->proplist, &state))) {
++        if (!pa_startswith(key, PROP_DROID_PARAMETER_PREFIX))
++            continue;
++
++        pkey = key + strlen(PROP_DROID_PARAMETER_PREFIX);
++        if (pkey[0] == '\0')
++            continue;
++
++        changed = false;
++
++        if (!(parameter = pa_hashmap_get(u->parameters, pkey))) {
++            parameter = pa_xnew0(droid_parameter_mapping, 1);
++            parameter->key = pa_xstrdup(pkey);
++            parameter->value = pa_xstrdup(pa_proplist_gets(sink->proplist, key));
++            pa_hashmap_put(u->parameters, parameter->key, parameter);
++            changed = true;
++        } else {
++            value = pa_proplist_gets(sink->proplist, key);
++            if (!pa_streq(parameter->value, value)) {
++                pa_xfree(parameter->value);
++                parameter->value = pa_xstrdup(value);
++                changed = true;
++            }
++        }
++
++        if (changed) {
++            pa_assert(parameter);
++            tmp = pa_sprintf_malloc("%s=%s;", parameter->key, parameter->value);
++            pa_log_debug("sink proplist changed: set_parameters(): %s", tmp);
++            pa_droid_hw_module_lock(u->hw_module);
++            u->stream_out->common.set_parameters(&u->stream_out->common, tmp);
++            pa_droid_hw_module_unlock(u->hw_module);
++            pa_xfree(tmp);
++        }
++    }
++
++    return PA_HOOK_OK;
++}
++
++static struct pa_sink *pa_sco_fake_sink_discover(pa_core *core, const char *sink_name) {
++    struct pa_sink *sink;
++    pa_idxset *idxset;
++    void *state = NULL;
++
++    pa_assert(core);
++    pa_assert(sink_name);
++    pa_assert_se((idxset = core->sinks));
++
++    while ((sink = pa_idxset_iterate(idxset, &state, NULL)) != NULL) {
++        if (pa_streq(sink_name, sink->name)) {
++            pa_log_debug("Found fake SCO sink '%s'", sink_name);
++            return sink;
++        }
++    }
++
++    return NULL;
++}
++
++pa_sink *pa_droid_sink_new(pa_module *m,
++                             pa_modargs *ma,
++                             const char *driver,
++                             pa_droid_card_data *card_data,
++                             audio_output_flags_t flags,
++                             pa_droid_mapping *am,
++                             pa_card *card) {
++
++    struct userdata *u = NULL;
++    bool deferred_volume = false;
++    bool voice_volume_call_mode = false;
++    bool voice_virtual_stream = false;
++    char *thread_name = NULL;
++    pa_sink_new_data data;
++    const char *module_id = NULL;
++    const char *tmp;
++    /* char *list = NULL; */
++    uint32_t alternate_sample_rate;
++    uint32_t sample_rate;
++    audio_devices_t dev_out;
++    pa_sample_spec sample_spec;
++    pa_channel_map channel_map;
++    bool namereg_fail = false;
++    uint32_t total_latency;
++    pa_droid_config_audio *config = NULL; /* Only used when sink is created without card */
++    int32_t mute_routing_before = 0;
++    int32_t mute_routing_after = 0;
++    uint32_t sink_buffer = 0;
++    int ret;
++
++    audio_format_t hal_audio_format = 0;
++    audio_channel_mask_t hal_channel_mask = 0;
++
++    pa_assert(m);
++    pa_assert(ma);
++    pa_assert(driver);
++
++    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 (card && am)
++        module_id = am->output->module->name;
++    else
++        module_id = pa_modargs_get_value(ma, "module_id", DEFAULT_MODULE_ID);
++
++    sample_spec = m->core->default_sample_spec;
++    channel_map = m->core->default_channel_map;
++
++    if (pa_modargs_get_sample_spec_and_channel_map(ma, &sample_spec, &channel_map, PA_CHANNEL_MAP_AIFF) < 0) {
++        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;
++    }
++
++    if ((pa_modargs_get_value_s32(ma, "mute_routing_before", &mute_routing_before) < 0) || mute_routing_before < 0) {
++        pa_log("Failed to parse mute_routing_before. Needs to be integer >= 0.");
++        goto fail;
++    }
++
++    if ((pa_modargs_get_value_s32(ma, "mute_routing_after", &mute_routing_after) < 0) || mute_routing_after < 0) {
++        pa_log("Failed to parse mute_routing_after. Needs to be integer >= 0.");
++        goto fail;
++    }
++
++    if (pa_modargs_get_value_u32(ma, "sink_buffer", &sink_buffer) < 0) {
++        pa_log("Failed to parse sink_buffer. Needs to be integer >= 0.");
++        goto fail;
++    }
++
++    if (pa_modargs_get_value_boolean(ma, "voice_volume_call_mode", &voice_volume_call_mode) < 0) {
++        pa_log("Failed to parse voice_volume_call_mode. Needs to be a boolean argument.");
++        goto fail;
++    }
++
++    if (pa_modargs_get_value_boolean(ma, "voice_virtual_stream", &voice_virtual_stream) < 0) {
++        pa_log("Failed to parse voice_virtual_stream. Needs to be a boolean argument.");
++        goto fail;
++    }
++
++    u = pa_xnew0(struct userdata, 1);
++    u->core = m->core;
++    u->module = m;
++    u->card = card;
++    u->deferred_volume = deferred_volume;
++    u->rtpoll = pa_rtpoll_new();
++    pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
++    u->parameters = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) parameter_free);
++    u->voice_volume_call_mode = voice_volume_call_mode;
++    u->voice_virtual_stream = voice_virtual_stream;
++    u->voice_property_key   = pa_xstrdup(pa_modargs_get_value(ma, "voice_property_key", DEFAULT_VOICE_CONTROL_PROPERTY_KEY));
++    u->voice_property_value = pa_xstrdup(pa_modargs_get_value(ma, "voice_property_value", DEFAULT_VOICE_CONTROL_PROPERTY_VALUE));
++    u->sco_fake_sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sco_fake_sink", DEFAULT_SCO_FAKE_SINK));
++
++    if (card_data) {
++        u->card_data = card_data;
++        pa_assert(card);
++        pa_assert_se((u->hw_module = pa_droid_hw_module_get(u->core, NULL, card_data->module_id)));
++    } else {
++        /* Sink wasn't created from inside card module, so we'll need to open
++         * hw module ourselves.
++         * TODO some way to share hw module between other sinks/sources since
++         * opening same module from different places likely isn't a good thing. */
++
++        if (!(config = pa_droid_config_load(ma)))
++            goto fail;
++
++        /* Ownership of config transfers to hw_module if opening of hw module succeeds. */
++        if (!(u->hw_module = pa_droid_hw_module_get(u->core, config, module_id)))
++            goto fail;
++    }
++
++    if (!pa_convert_format(sample_spec.format, CONV_FROM_PA, &hal_audio_format)) {
++        pa_log("Sample spec format %u not supported.", sample_spec.format);
++        goto fail;
++    }
++
++    for (int i = 0; i < channel_map.channels; i++) {
++        audio_channel_mask_t c;
++        if (!pa_convert_output_channel(channel_map.map[i], CONV_FROM_PA, &c)) {
++            pa_log("Failed to convert channel map.");
++            goto fail;
++        }
++        hal_channel_mask |= c;
++    }
++
++    struct audio_config config_out = {
++        .sample_rate = sample_spec.rate,
++        .channel_mask = hal_channel_mask,
++        .format = hal_audio_format
++    };
++
++    /* Default routing */
++    dev_out = AUDIO_DEVICE_OUT_DEFAULT;
++
++    if ((tmp = pa_modargs_get_value(ma, "output_devices", NULL))) {
++        audio_devices_t tmp_dev;
++
++        if (parse_device_list(tmp, &tmp_dev) && tmp_dev)
++            dev_out = tmp_dev;
++
++        pa_log_debug("Set initial devices %s", tmp);
++    }
++
++    if (am)
++        flags = am->output->flags;
++
++    pa_droid_hw_module_lock(u->hw_module);
++    ret = u->hw_module->device->open_output_stream(u->hw_module->device,
++                                                   u->hw_module->stream_out_id++,
++                                                   dev_out,
++                                                   flags,
++                                                   &config_out,
++                                                   &u->stream_out);
++    pa_droid_hw_module_unlock(u->hw_module);
++
++    if (!u->stream_out) {
++        pa_log("Failed to open output stream. (errno %d)", ret);
++        goto fail;
++    }
++
++    if ((sample_rate = u->stream_out->common.get_sample_rate(&u->stream_out->common)) != sample_spec.rate) {
++        pa_log_warn("Requested sample rate %u but got %u instead.", sample_spec.rate, sample_rate);
++        sample_spec.rate = sample_rate;
++    }
++
++    u->buffer_size = u->stream_out->common.get_buffer_size(&u->stream_out->common);
++    if (sink_buffer) {
++        if (sink_buffer < u->buffer_size)
++            pa_log_warn("Requested buffer size %u less than HAL reported buffer size (%u).", sink_buffer, u->buffer_size);
++        else if (sink_buffer % u->buffer_size) {
++            uint32_t trunc = (sink_buffer / u->buffer_size) * u->buffer_size;
++            pa_log_warn("Requested buffer size %u not multiple of HAL buffer size (%u). Using buffer size %u", sink_buffer, u->buffer_size, trunc);
++            u->buffer_size = trunc;
++        } else {
++            pa_log_info("Using requested buffer size %u.", sink_buffer);
++            u->buffer_size = sink_buffer;
++        }
++    }
++
++    u->buffer_latency = pa_bytes_to_usec(u->buffer_size, &sample_spec);
++    /* Disable internal rewinding for now. */
++    u->buffer_count = 1;
++
++    pa_log_info("Created Android stream with device: %u flags: %u sample rate: %u channel mask: %u format: %u buffer size: %u",
++            dev_out,
++            flags,
++            sample_rate,
++            config_out.channel_mask,
++            config_out.format,
++            u->buffer_size);
++
++
++    u->mute_routing_before = mute_routing_before / u->buffer_size;
++    u->mute_routing_after = mute_routing_after / u->buffer_size;
++    if (u->mute_routing_before == 0 && mute_routing_before)
++        u->mute_routing_before = u->buffer_size;
++    if (u->mute_routing_after == 0 && mute_routing_after)
++        u->mute_routing_after = u->buffer_size;
++    if (u->mute_routing_before || u->mute_routing_after)
++        pa_log_debug("Mute playback when routing is changing, %u before and %u after.",
++                     u->mute_routing_before * u->buffer_size,
++                     u->mute_routing_after * u->buffer_size);
++    pa_silence_memchunk_get(&u->core->silence_cache, u->core->mempool, &u->silence, &sample_spec, u->buffer_size);
++    u->memblockq = pa_memblockq_new("droid-sink", 0, u->buffer_size * u->buffer_count, u->buffer_size * u->buffer_count, &sample_spec, 1, 0, 0, &u->silence);
++
++    pa_sink_new_data_init(&data);
++    data.driver = driver;
++    data.module = m;
++    data.card = card;
++
++    set_sink_name(ma, &data, module_id);
++    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
++    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, "internal");
++
++    /* 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, &sample_spec);
++    pa_sink_new_data_set_channel_map(&data, &channel_map);
++    pa_sink_new_data_set_alternate_sample_rate(&data, alternate_sample_rate);
++
++    /*
++    if (!(list = pa_list_string_output_device(dev_out))) {
++        pa_log("Couldn't format device list string.");
++        goto fail;
++    }
++    pa_proplist_sets(data.proplist, PROP_DROID_DEVICES, list);
++    pa_xfree(list);
++
++    if (flags) {
++        if (!(list = pa_list_string_flags(flags))) {
++            pa_log("Couldn't format flag list string.");
++            goto fail;
++        }
++    } else
++        list = NULL;
++
++    pa_proplist_sets(data.proplist, PROP_DROID_FLAGS, list ? list : "");
++    pa_xfree(list);
++    */
++
++    if (am)
++        pa_droid_add_ports(data.ports, am, card);
++
++    u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE | PA_SINK_LATENCY | PA_SINK_FLAT_VOLUME);
++    pa_sink_new_data_done(&data);
++
++    if (!u->sink) {
++        pa_log("Failed to create sink.");
++        goto fail;
++    }
++
++    u->sink->userdata = u;
++
++    u->sink->parent.process_msg = sink_process_msg;
++
++    u->sink->set_port = sink_set_port_cb;
++
++    pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
++    pa_sink_set_rtpoll(u->sink, u->rtpoll);
++
++    /* Rewind internal memblockq */
++    pa_sink_set_max_rewind(u->sink, u->buffer_size * (u->buffer_count - 1));
++
++    thread_name = pa_sprintf_malloc("droid-sink-%s", module_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;
++
++    /* Latency consists of HAL latency + our memblockq latency */
++    total_latency = u->stream_out->get_latency(u->stream_out) + (uint32_t) pa_bytes_to_usec(u->buffer_size * u->buffer_count, &sample_spec);
++    pa_sink_set_fixed_latency(u->sink, total_latency);
++    pa_log_debug("Set fixed latency %lu usec", (unsigned long) pa_bytes_to_usec(total_latency, &sample_spec));
++    pa_sink_set_max_request(u->sink, u->buffer_size * u->buffer_count);
++
++    if (u->sink->active_port)
++        sink_set_port_cb(u->sink, u->sink->active_port);
++
++    /* Hooks to track appearance and disappearance of sink-inputs. */
++    /* Hook a little bit earlier and later than module-role-ducking. */
++    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_cb, u);
++    u->sink_input_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_EARLY-10,
++            (pa_hook_cb_t) sink_input_unlink_hook_cb, u);
++    u->sink_proplist_changed_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], PA_HOOK_EARLY,
++            (pa_hook_cb_t) sink_proplist_changed_hook_cb, u);
++
++    update_volumes(u);
++
++    pa_sink_put(u->sink);
++
++    return u->sink;
++
++fail:
++    pa_xfree(thread_name);
++
++    if (config)
++        pa_xfree(config);
++
++    if (u)
++        userdata_free(u);
++
++    return NULL;
++}
++
++void pa_droid_sink_free(pa_sink *s) {
++    struct userdata *u;
++
++    pa_sink_assert_ref(s);
++    pa_assert_se(u = s->userdata);
++
++    userdata_free(u);
++}
++
++static void userdata_free(struct userdata *u) {
++
++    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_input_subscription)
++        pa_subscription_free(u->sink_input_subscription);
++
++    if (u->sink_input_put_hook_slot)
++        pa_hook_slot_free(u->sink_input_put_hook_slot);
++
++    if (u->sink_input_unlink_hook_slot)
++        pa_hook_slot_free(u->sink_input_unlink_hook_slot);
++
++    if (u->sink_proplist_changed_hook_slot)
++        pa_hook_slot_free(u->sink_proplist_changed_hook_slot);
++
++    if (u->sink)
++        pa_sink_unref(u->sink);
++
++    if (u->parameters)
++        pa_hashmap_free(u->parameters);
++
++    if (u->hw_module && u->stream_out) {
++        pa_droid_hw_module_lock(u->hw_module);
++        u->hw_module->device->close_output_stream(u->hw_module->device, u->stream_out);
++        pa_droid_hw_module_unlock(u->hw_module);
++    }
++
++    if (u->memblockq)
++        pa_memblockq_free(u->memblockq);
++
++    if (u->silence.memblock)
++        pa_memblock_unref(u->silence.memblock);
++
++    if (u->hw_module)
++        pa_droid_hw_module_unref(u->hw_module);
++
++    if (u->sco_fake_sink_name)
++        pa_xfree(u->sco_fake_sink_name);
++
++    if (u->voice_property_key)
++        pa_xfree(u->voice_property_key);
++    if (u->voice_property_value)
++        pa_xfree(u->voice_property_value);
++
++    pa_xfree(u);
++}
+Index: pulseaudio/src/modules/droid/droid-sink.h
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/droid-sink.h
+@@ -0,0 +1,57 @@
++#ifndef foodroidsinkfoo
++#define foodroidsinkfoo
++
++/*
++ * Copyright (C) 2013 Jolla Ltd.
++ *
++ * Contact: Juho Hämäläinen <juho.hamalainen at tieto.com>
++ *
++ * These PulseAudio Modules are 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
++ * version 2.1 of the License.
++ *
++ * 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 Street, Fifth Floor, Boston, MA 02110-1301
++ * USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#ifdef HAVE_VALGRIND_MEMCHECK_H
++#include <valgrind/memcheck.h>
++#endif
++
++#include <pulse/xmalloc.h>
++
++#include <pulsecore/core.h>
++#include <pulsecore/i18n.h>
++#include <pulsecore/module.h>
++#include <pulsecore/sink.h>
++#include <pulsecore/modargs.h>
++#include <pulsecore/log.h>
++#include <pulsecore/macro.h>
++#include <pulsecore/card.h>
++
++#include "droid-util.h"
++
++pa_sink *pa_droid_sink_new(pa_module *m,
++                             pa_modargs *ma,
++                             const char *driver,
++                             pa_droid_card_data *card_data,
++                             audio_output_flags_t flags,
++                             pa_droid_mapping *am,
++                             pa_card *card);
++void pa_droid_sink_free(pa_sink *s);
++
++void pa_droid_sink_set_voice_control(pa_sink* sink, bool enable);
++
++#endif
+Index: pulseaudio/src/modules/droid/droid-source.c
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/droid-source.c
+@@ -0,0 +1,667 @@
++/*
++ * Copyright (C) 2013 Jolla Ltd.
++ *
++ * Contact: Juho Hämäläinen <juho.hamalainen at tieto.com>
++ *
++ * These PulseAudio Modules are 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
++ * version 2.1 of the License.
++ *
++ * 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 Street, Fifth Floor, Boston, MA 02110-1301
++ * USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <signal.h>
++#include <stdio.h>
++
++#ifdef HAVE_VALGRIND_MEMCHECK_H
++#include <valgrind/memcheck.h>
++#endif
++
++#include <pulse/rtclock.h>
++#include <pulse/timeval.h>
++#include <pulse/volume.h>
++#include <pulse/xmalloc.h>
++
++#include <pulsecore/core.h>
++#include <pulsecore/i18n.h>
++#include <pulsecore/module.h>
++#include <pulsecore/memchunk.h>
++#include <pulsecore/source.h>
++#include <pulsecore/modargs.h>
++#include <pulsecore/core-rtclock.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/thread-mq.h>
++#include <pulsecore/rtpoll.h>
++#include <pulsecore/time-smoother.h>
++
++#include "droid-source.h"
++#include "droid-util.h"
++
++struct userdata {
++    pa_core *core;
++    pa_module *module;
++    pa_card *card;
++    pa_source *source;
++
++    pa_thread *thread;
++    pa_thread_mq thread_mq;
++    pa_rtpoll *rtpoll;
++
++    pa_memchunk memchunk;
++    audio_devices_t primary_devices;
++    audio_devices_t enabled_devices;
++    bool routing_changes_enabled;
++
++    size_t buffer_size;
++    pa_usec_t timestamp;
++
++    pa_droid_card_data *card_data;
++    pa_droid_hw_module *hw_module;
++    audio_stream_in_t *stream;
++};
++
++#define DEFAULT_MODULE_ID "primary"
++
++static void userdata_free(struct userdata *u);
++
++static bool do_routing(struct userdata *u, audio_devices_t devices) {
++    char tmp[32];
++    char *devlist;
++
++    pa_assert(u);
++    pa_assert(u->stream);
++
++    if (!u->routing_changes_enabled) {
++        pa_log_debug("Skipping routing change.");
++        return false;
++    }
++
++    if (u->primary_devices == devices)
++        pa_log_debug("Refresh active device routing.");
++
++    u->enabled_devices &= ~u->primary_devices;
++    u->primary_devices = devices;
++    u->enabled_devices |= u->primary_devices;
++
++    devlist = pa_list_string_input_device(devices);
++    pa_assert(devlist);
++#ifdef DROID_DEVICE_I9305
++    pa_snprintf(tmp, sizeof(tmp), "%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, devices & ~AUDIO_DEVICE_BIT_IN);
++#else
++    pa_snprintf(tmp, sizeof(tmp), "%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, devices);
++#endif
++    pa_log_debug("set_parameters(): %s (%s : %#010x)", tmp, devlist, devices);
++    pa_xfree(devlist);
++#ifdef DROID_DEVICE_MAKO
++#warning Using mako set_parameters hack.
++    u->card_data->set_parameters(u->card_data, tmp);
++#else
++    u->stream->common.set_parameters(&u->stream->common, tmp);
++#endif
++
++    return true;
++}
++
++static bool parse_device_list(const char *str, audio_devices_t *dst) {
++    char *dev;
++    const char *state = NULL;
++
++    pa_assert(str);
++    pa_assert(dst);
++
++    *dst = 0;
++
++    while ((dev = pa_split(str, "|", &state))) {
++        audio_devices_t d;
++
++        if (!pa_string_convert_input_device_str_to_num(dev, &d)) {
++            pa_log_warn("Unknown device %s", dev);
++            pa_xfree(dev);
++            return false;
++        }
++
++        *dst |= d;
++
++        pa_xfree(dev);
++    }
++
++    return true;
++}
++
++static int thread_read(struct userdata *u) {
++    void *p;
++    ssize_t readd;
++    pa_memchunk chunk;
++
++    chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) u->buffer_size);
++
++    p = pa_memblock_acquire(chunk.memblock);
++    readd = u->stream->read(u->stream, (uint8_t*) p, pa_memblock_get_length(chunk.memblock));
++    pa_memblock_release(chunk.memblock);
++
++    if (readd < 0) {
++        pa_log("Failed to read from stream. (err %i)", readd);
++        goto end;
++    }
++
++    u->timestamp += pa_bytes_to_usec(readd, &u->source->sample_spec);
++
++    chunk.index = 0;
++    chunk.length = readd;
++
++    if (chunk.length > 0)
++        pa_source_post(u->source, &chunk);
++
++end:
++    pa_memblock_unref(chunk.memblock);
++
++    return 0;
++}
++
++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);
++
++    pa_thread_mq_install(&u->thread_mq);
++
++    u->timestamp = pa_rtclock_now();
++
++    for (;;) {
++        int ret;
++
++        if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
++            thread_read(u);
++
++            pa_rtpoll_set_timer_absolute(u->rtpoll, u->timestamp);
++        } else
++            pa_rtpoll_set_timer_disabled(u->rtpoll);
++
++        /* 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.");
++}
++
++/* Called from IO context */
++static int suspend(struct userdata *u) {
++    int ret;
++
++    pa_assert(u);
++    pa_assert(u->stream);
++
++    ret = u->stream->common.standby(&u->stream->common);
++
++    if (ret == 0)
++        pa_log_info("Device suspended.");
++
++    return ret;
++}
++
++/* 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;
++
++    switch (code) {
++        case PA_SOURCE_MESSAGE_SET_STATE: {
++            switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
++                case PA_SOURCE_SUSPENDED: {
++                    int r;
++
++                    pa_assert(PA_SOURCE_IS_OPENED(u->source->thread_info.state));
++
++                    if ((r = suspend(u)) < 0)
++                        return r;
++
++                    break;
++                }
++
++                case PA_SOURCE_IDLE:
++                    break;
++                case PA_SOURCE_RUNNING: {
++                    pa_log_info("Resuming...");
++                    u->timestamp = pa_rtclock_now();
++                    break;
++                }
++
++                /* not needed */
++                case PA_SOURCE_UNLINKED:
++                case PA_SOURCE_INIT:
++                case PA_SOURCE_INVALID_STATE:
++                    ;
++            }
++            break;
++        }
++    }
++
++    return pa_source_process_msg(o, code, data, offset, chunk);
++}
++
++static int source_set_port_cb(pa_source *s, pa_device_port *p) {
++    struct userdata *u = s->userdata;
++    pa_droid_port_data *data;
++
++    pa_assert(u);
++    pa_assert(p);
++
++    data = PA_DEVICE_PORT_DATA(p);
++
++    if (!data->device) {
++        /* If there is no device defined, just return 0 to say everything is ok.
++         * Then next port change can be whatever source port, even the one enabled
++         * before parking. */
++        pa_log_debug("Source set port to parking");
++        return 0;
++    }
++
++    pa_log_debug("Source set port %u", data->device);
++
++    do_routing(u, data->device);
++
++    return 0;
++}
++
++
++static void source_set_name(pa_modargs *ma, pa_source_new_data *data, const char *module_id) {
++    const char *tmp;
++
++    pa_assert(ma);
++    pa_assert(data);
++
++    if ((tmp = pa_modargs_get_value(ma, "source_name", NULL))) {
++        pa_source_new_data_set_name(data, tmp);
++        data->namereg_fail = true;
++        pa_proplist_sets(data->proplist, PA_PROP_DEVICE_DESCRIPTION, "Droid source");
++    } else {
++        char *tt;
++        pa_assert(module_id);
++        tt = pa_sprintf_malloc("source.%s", module_id);
++        pa_source_new_data_set_name(data, tt);
++        pa_xfree(tt);
++        data->namereg_fail = false;
++        pa_proplist_setf(data->proplist, PA_PROP_DEVICE_DESCRIPTION, "Droid source %s", module_id);
++    }
++}
++
++static void source_get_mute_cb(pa_source *s) {
++    struct userdata *u = s->userdata;
++    bool b;
++
++    pa_assert(u);
++    pa_assert(u->hw_module && u->hw_module->device);
++
++    pa_droid_hw_module_lock(u->hw_module);
++    if (u->hw_module->device->get_mic_mute(u->hw_module->device, &b) < 0) {
++        pa_log("Failed to get mute state.");
++        pa_droid_hw_module_unlock(u->hw_module);
++        return;
++    }
++    pa_droid_hw_module_unlock(u->hw_module);
++
++    s->muted = b;
++}
++
++static void source_set_mute_cb(pa_source *s) {
++    struct userdata *u = s->userdata;
++
++    pa_assert(u);
++    pa_assert(u->hw_module && u->hw_module->device);
++
++    pa_droid_hw_module_lock(u->hw_module);
++    if (u->hw_module->device->set_mic_mute(u->hw_module->device, s->muted) < 0)
++        pa_log("Failed to set mute state to %smuted.", s->muted ? "" : "un");
++    pa_droid_hw_module_unlock(u->hw_module);
++}
++
++static void source_set_mute_control(struct userdata *u) {
++    pa_assert(u);
++    pa_assert(u->hw_module && u->hw_module->device);
++
++    if (u->hw_module->device->set_mic_mute) {
++        pa_log_info("Using hardware mute control for %s", u->source->name);
++        pa_source_set_get_mute_callback(u->source, source_get_mute_cb);
++        pa_source_set_set_mute_callback(u->source, source_set_mute_cb);
++    } else {
++        pa_log_info("Using software mute control for %s", u->source->name);
++        pa_source_set_get_mute_callback(u->source, NULL);
++        pa_source_set_set_mute_callback(u->source, NULL);
++    }
++}
++
++void pa_droid_source_set_routing(pa_source *s, bool enabled) {
++    struct userdata *u = s->userdata;
++
++    pa_assert(s);
++    pa_assert(s->userdata);
++
++    if (u->routing_changes_enabled != enabled)
++        pa_log_debug("%s source routing changes.", enabled ? "Enabling" : "Disabling");
++    u->routing_changes_enabled = enabled;
++}
++
++pa_source *pa_droid_source_new(pa_module *m,
++                                 pa_modargs *ma,
++                                 const char *driver,
++                                 pa_droid_card_data *card_data,
++                                 pa_droid_mapping *am,
++                                 pa_card *card) {
++
++    struct userdata *u = NULL;
++    char *thread_name = NULL;
++    pa_source_new_data data;
++    const char *module_id = NULL;
++    /* const char *tmp; */
++    uint32_t sample_rate;
++    uint32_t alternate_sample_rate;
++    audio_devices_t dev_in;
++    pa_sample_spec sample_spec;
++    pa_channel_map channel_map;
++    bool namereg_fail = false;
++    pa_droid_config_audio *config = NULL; /* Only used when source is created without card */
++    uint32_t source_buffer = 0;
++    char audio_source[32];
++    int ret;
++
++    audio_format_t hal_audio_format = 0;
++    audio_channel_mask_t hal_channel_mask = 0;
++
++    pa_assert(m);
++    pa_assert(ma);
++    pa_assert(driver);
++
++    /* When running under card use hw module name for source by default. */
++    if (card && ma)
++        module_id = am->input->module->name;
++    else
++        module_id = pa_modargs_get_value(ma, "module_id", DEFAULT_MODULE_ID);
++
++    sample_spec = m->core->default_sample_spec;
++    channel_map = m->core->default_channel_map;
++
++    if (pa_modargs_get_sample_spec_and_channel_map(ma, &sample_spec, &channel_map, PA_CHANNEL_MAP_AIFF) < 0) {
++        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;
++    }
++
++    if (pa_modargs_get_value_u32(ma, "source_buffer", &source_buffer) < 0) {
++        pa_log("Failed to parse source_buffer. Needs to be integer >= 0.");
++        goto fail;
++    }
++
++    u = pa_xnew0(struct userdata, 1);
++    u->core = m->core;
++    u->module = m;
++    u->card = card;
++    u->rtpoll = pa_rtpoll_new();
++    pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
++
++    /* Enabled routing changes by default. */
++    u->routing_changes_enabled = true;
++
++    if (card_data) {
++        pa_assert(card);
++        u->card_data = card_data;
++        pa_assert_se((u->hw_module = pa_droid_hw_module_get(u->core, NULL, card_data->module_id)));
++    } else {
++        /* Stand-alone source */
++
++        if (!(config = pa_droid_config_load(ma)))
++            goto fail;
++
++        /* Ownership of config transfers to hw_module if opening of hw module succeeds. */
++        if (!(u->hw_module = pa_droid_hw_module_get(u->core, config, module_id)))
++            goto fail;
++    }
++
++    if (!pa_convert_format(sample_spec.format, CONV_FROM_PA, &hal_audio_format)) {
++        pa_log("Sample spec format %u not supported.", sample_spec.format);
++        goto fail;
++    }
++
++    for (int i = 0; i < channel_map.channels; i++) {
++        audio_channel_mask_t c;
++        if (!pa_convert_input_channel(channel_map.map[i], CONV_FROM_PA, &c)) {
++            pa_log("Failed to convert channel map.");
++            goto fail;
++        }
++        hal_channel_mask |= c;
++    }
++
++    struct audio_config config_in = {
++        .sample_rate = sample_spec.rate,
++        .channel_mask = hal_channel_mask,
++        .format = hal_audio_format
++    };
++
++    /* Default routing */
++    /* FIXME So while setting routing through stream with HALv2 API fails, creation of stream
++     * requires HALv2 style device to work properly. So until that oddity is resolved we always
++     * set AUDIO_DEVICE_IN_BUILTIN_MIC as initial device here. */
++#if 0
++    pa_assert_se(pa_string_convert_input_device_str_to_num("AUDIO_DEVICE_IN_BUILTIN_MIC", &dev_in));
++
++    if ((tmp = pa_modargs_get_value(ma, "input_devices", NULL))) {
++        audio_devices_t tmp_dev;
++
++        if (parse_device_list(tmp, &tmp_dev) && tmp_dev)
++            dev_in = tmp_dev;
++
++        pa_log_debug("Set initial devices %s", tmp);
++    }
++#else
++    pa_log_info("FIXME: Setting AUDIO_DEVICE_IN_BUILTIN_MIC as initial device.");
++    dev_in = AUDIO_DEVICE_IN_BUILTIN_MIC;
++#endif
++    pa_droid_hw_module_lock(u->hw_module);
++    ret = u->hw_module->device->open_input_stream(u->hw_module->device,
++                                                  u->hw_module->stream_in_id,
++                                                  dev_in,
++                                                  &config_in,
++                                                  &u->stream);
++    /* On some devices the first call will fail if the config parameters are
++     * not supported, but it'll automatically set the right ones, expecting
++     * the caller to call it again, so let's try at least one more time */
++    if (!u->stream)
++        ret = u->hw_module->device->open_input_stream(u->hw_module->device,
++                                                      u->hw_module->stream_in_id,
++                                                      dev_in,
++                                                      &config_in,
++                                                      &u->stream);
++
++    u->hw_module->stream_in_id++;
++    pa_droid_hw_module_unlock(u->hw_module);
++
++    if (ret < 0) {
++        pa_log("Failed to open input stream.");
++        goto fail;
++    }
++
++    if ((sample_rate = u->stream->common.get_sample_rate(&u->stream->common)) != sample_spec.rate) {
++        pa_log_warn("Requested sample rate %u but got %u instead.", sample_spec.rate, sample_rate);
++        sample_spec.rate = sample_rate;
++    }
++
++    u->buffer_size = u->stream->common.get_buffer_size(&u->stream->common);
++    if (source_buffer) {
++        if (source_buffer < u->buffer_size)
++            pa_log_warn("Requested buffer size %u less than HAL reported buffer size (%u).", source_buffer, u->buffer_size);
++        else if (source_buffer % u->buffer_size) {
++            uint32_t trunc = (source_buffer / u->buffer_size) * u->buffer_size;
++            pa_log_warn("Requested buffer size %u not multiple of HAL buffer size (%u). Using buffer size %u", source_buffer, u->buffer_size, trunc);
++            u->buffer_size = trunc;
++        } else {
++            pa_log_info("Using requested buffer size %u.", source_buffer);
++            u->buffer_size = source_buffer;
++        }
++    }
++
++    pa_log_info("Created Android stream with device: %u sample rate: %u channel mask: %u format: %u buffer size: %u",
++            dev_in,
++            sample_rate,
++            config_in.channel_mask,
++            config_in.format,
++            u->buffer_size);
++
++    /* Setting audio source to MIC by default */
++    pa_snprintf(audio_source, sizeof(audio_source), "%s=%u", AUDIO_PARAMETER_STREAM_INPUT_SOURCE, AUDIO_SOURCE_MIC);
++    u->stream->common.set_parameters(&u->stream->common, audio_source);
++    pa_log_debug("Setting audio source to AUDIO_SOURCE_MIC by default");
++
++    pa_source_new_data_init(&data);
++    data.driver = driver;
++    data.module = m;
++    data.card = card;
++
++    source_set_name(ma, &data, module_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_source_new_data_done(&data);
++        goto fail;
++    }
++    data.namereg_fail = namereg_fail;
++
++    pa_source_new_data_set_sample_spec(&data, &sample_spec);
++    pa_source_new_data_set_channel_map(&data, &channel_map);
++    pa_source_new_data_set_alternate_sample_rate(&data, alternate_sample_rate);
++
++    if (am)
++        pa_droid_add_ports(data.ports, am, card);
++
++    u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE);
++    pa_source_new_data_done(&data);
++
++    if (!u->source) {
++        pa_log("Failed to create source.");
++        goto fail;
++    }
++
++    u->source->userdata = u;
++
++    u->source->parent.process_msg = source_process_msg;
++
++    source_set_mute_control(u);
++
++    u->source->set_port = source_set_port_cb;
++
++    pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
++    pa_source_set_rtpoll(u->source, u->rtpoll);
++
++    /* Disable rewind for droid source */
++    pa_source_set_max_rewind(u->source, 0);
++
++    thread_name = pa_sprintf_malloc("droid-source-%s", module_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;
++
++    pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->buffer_size, &sample_spec));
++    pa_log_debug("Set fixed latency %" PRIu64 " usec", pa_bytes_to_usec(u->buffer_size, &sample_spec));
++
++    if (u->source->active_port)
++        source_set_port_cb(u->source, u->source->active_port);
++
++    pa_source_put(u->source);
++
++    return u->source;
++
++fail:
++    pa_xfree(thread_name);
++
++    if (config)
++        pa_xfree(config);
++
++    if (u)
++        userdata_free(u);
++
++    return NULL;
++}
++
++void pa_droid_source_free(pa_source *s) {
++    struct userdata *u;
++
++    pa_source_assert_ref(s);
++    pa_assert_se(u = s->userdata);
++
++    userdata_free(u);
++}
++
++static void userdata_free(struct userdata *u) {
++
++    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->memchunk.memblock)
++        pa_memblock_unref(u->memchunk.memblock);
++
++    if (u->hw_module && u->stream) {
++        pa_droid_hw_module_lock(u->hw_module);
++        u->hw_module->device->close_input_stream(u->hw_module->device, u->stream);
++        pa_droid_hw_module_unlock(u->hw_module);
++    }
++
++    // Stand alone source
++    if (u->hw_module)
++        pa_droid_hw_module_unref(u->hw_module);
++
++    pa_xfree(u);
++}
+Index: pulseaudio/src/modules/droid/droid-source.h
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/droid-source.h
+@@ -0,0 +1,56 @@
++#ifndef foodroidsourcefoo
++#define foodroidsourcefoo
++
++/*
++ * Copyright (C) 2013 Jolla Ltd.
++ *
++ * Contact: Juho Hämäläinen <juho.hamalainen at tieto.com>
++ *
++ * These PulseAudio Modules are 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
++ * version 2.1 of the License.
++ *
++ * 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 Street, Fifth Floor, Boston, MA 02110-1301
++ * USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#ifdef HAVE_VALGRIND_MEMCHECK_H
++#include <valgrind/memcheck.h>
++#endif
++
++#include <pulse/xmalloc.h>
++
++#include <pulsecore/core.h>
++#include <pulsecore/i18n.h>
++#include <pulsecore/module.h>
++#include <pulsecore/source.h>
++#include <pulsecore/modargs.h>
++#include <pulsecore/log.h>
++#include <pulsecore/macro.h>
++#include <pulsecore/card.h>
++
++#include "droid-util.h"
++
++pa_source *pa_droid_source_new(pa_module *m,
++                                 pa_modargs *ma,
++                                 const char *driver,
++                                 pa_droid_card_data *card_data,
++                                 pa_droid_mapping *am,
++                                 pa_card *card);
++void pa_droid_source_free(pa_source *s);
++
++void pa_droid_source_set_routing(pa_source *s, bool enabled);
++
++#endif
+Index: pulseaudio/src/modules/droid/droid-util-41qc.h
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/droid-util-41qc.h
+@@ -0,0 +1,274 @@
++/*
++ * Copyright (C) 2013 Jolla Ltd.
++ *
++ * Contact: Juho Hämäläinen <juho.hamalainen at tieto.com>
++ *
++ * These PulseAudio Modules are 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
++ * version 2.1 of the License.
++ *
++ * 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 Street, Fifth Floor, Boston, MA 02110-1301
++ * USA.
++ */
++
++#ifndef _ANDROID_UTIL_V412_H_
++#define _ANDROID_UTIL_V412_H_
++
++// PulseAudio value    -    Android value
++
++static uint32_t conversion_table_output_channel[][2] = {
++    { PA_CHANNEL_POSITION_MONO,                     AUDIO_CHANNEL_OUT_MONO },
++    { PA_CHANNEL_POSITION_FRONT_LEFT,               AUDIO_CHANNEL_OUT_FRONT_LEFT },
++    { PA_CHANNEL_POSITION_FRONT_RIGHT,              AUDIO_CHANNEL_OUT_FRONT_RIGHT},
++    { PA_CHANNEL_POSITION_FRONT_CENTER,             AUDIO_CHANNEL_OUT_FRONT_CENTER },
++    { PA_CHANNEL_POSITION_SUBWOOFER,                AUDIO_CHANNEL_OUT_LOW_FREQUENCY },
++    { PA_CHANNEL_POSITION_REAR_LEFT,                AUDIO_CHANNEL_OUT_BACK_LEFT },
++    { PA_CHANNEL_POSITION_REAR_RIGHT,               AUDIO_CHANNEL_OUT_BACK_RIGHT },
++    { PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,     AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER },
++    { PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,    AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER },
++    { PA_CHANNEL_POSITION_REAR_CENTER,              AUDIO_CHANNEL_OUT_BACK_CENTER },
++    { PA_CHANNEL_POSITION_SIDE_LEFT,                AUDIO_CHANNEL_OUT_SIDE_LEFT },
++    { PA_CHANNEL_POSITION_SIDE_RIGHT,               AUDIO_CHANNEL_OUT_SIDE_RIGHT },
++    { PA_CHANNEL_POSITION_TOP_CENTER,               AUDIO_CHANNEL_OUT_TOP_CENTER },
++    { PA_CHANNEL_POSITION_TOP_FRONT_LEFT,           AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT },
++    { PA_CHANNEL_POSITION_TOP_FRONT_CENTER,         AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER },
++    { PA_CHANNEL_POSITION_TOP_FRONT_RIGHT,          AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT },
++    { PA_CHANNEL_POSITION_TOP_REAR_LEFT,            AUDIO_CHANNEL_OUT_TOP_BACK_LEFT },
++    { PA_CHANNEL_POSITION_TOP_REAR_CENTER,          AUDIO_CHANNEL_OUT_TOP_BACK_CENTER },
++    { PA_CHANNEL_POSITION_TOP_REAR_RIGHT,           AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT }
++};
++
++static uint32_t conversion_table_input_channel[][2] = {
++    { PA_CHANNEL_POSITION_MONO,                     AUDIO_CHANNEL_IN_MONO },
++    { PA_CHANNEL_POSITION_FRONT_LEFT,               AUDIO_CHANNEL_IN_LEFT },
++    { PA_CHANNEL_POSITION_FRONT_RIGHT,              AUDIO_CHANNEL_IN_RIGHT},
++    { PA_CHANNEL_POSITION_FRONT_CENTER,             AUDIO_CHANNEL_IN_FRONT },
++    { PA_CHANNEL_POSITION_REAR_CENTER,              AUDIO_CHANNEL_IN_BACK },
++    /* Following are missing suitable counterparts on PulseAudio side. */
++    { AUDIO_CHANNEL_IN_LEFT_PROCESSED,              AUDIO_CHANNEL_IN_LEFT_PROCESSED },
++    { AUDIO_CHANNEL_IN_RIGHT_PROCESSED,             AUDIO_CHANNEL_IN_RIGHT_PROCESSED },
++    { AUDIO_CHANNEL_IN_FRONT_PROCESSED,             AUDIO_CHANNEL_IN_FRONT_PROCESSED },
++    { AUDIO_CHANNEL_IN_BACK_PROCESSED,              AUDIO_CHANNEL_IN_BACK_PROCESSED },
++    { AUDIO_CHANNEL_IN_PRESSURE,                    AUDIO_CHANNEL_IN_PRESSURE },
++    { AUDIO_CHANNEL_IN_X_AXIS,                      AUDIO_CHANNEL_IN_X_AXIS },
++    { AUDIO_CHANNEL_IN_Y_AXIS,                      AUDIO_CHANNEL_IN_Y_AXIS },
++    { AUDIO_CHANNEL_IN_Z_AXIS,                      AUDIO_CHANNEL_IN_Z_AXIS },
++    { AUDIO_CHANNEL_IN_VOICE_UPLINK,                AUDIO_CHANNEL_IN_VOICE_UPLINK },
++    { AUDIO_CHANNEL_IN_VOICE_DNLINK,                AUDIO_CHANNEL_IN_VOICE_DNLINK }
++};
++
++static uint32_t conversion_table_format[][2] = {
++    { PA_SAMPLE_U8,             AUDIO_FORMAT_PCM_8_BIT },
++    { PA_SAMPLE_S16LE,          AUDIO_FORMAT_PCM_16_BIT },
++    { PA_SAMPLE_S32LE,          AUDIO_FORMAT_PCM_32_BIT },
++    { PA_SAMPLE_S24LE,          AUDIO_FORMAT_PCM_8_24_BIT }
++};
++
++struct string_conversion {
++    uint32_t value;
++    const char *str;
++};
++
++#if defined(STRING_ENTRY) || defined(STRING_ENTRY)
++#error STRING_ENTRY already defined somewhere, fix this lib.
++#endif
++#define STRING_ENTRY(str) { str, #str }
++/* Output devices */
++static struct string_conversion string_conversion_table_output_device[] = {
++    STRING_ENTRY(AUDIO_DEVICE_OUT_EARPIECE),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_SPEAKER),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_WIRED_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_SCO),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_AUX_DIGITAL),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_USB_ACCESSORY),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_USB_DEVICE),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_FM),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_FM_TX),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ANC_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ANC_HEADPHONE),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_PROXY),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ALL),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ALL_A2DP),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ALL_SCO),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ALL_USB),
++    { 0, NULL }
++};
++
++static struct string_conversion string_conversion_table_output_device_fancy[] = {
++    { AUDIO_DEVICE_OUT_EARPIECE,                    "output-earpiece" },
++    { AUDIO_DEVICE_OUT_SPEAKER,                     "output-speaker" },
++    { AUDIO_DEVICE_OUT_SPEAKER
++        | AUDIO_DEVICE_OUT_WIRED_HEADPHONE,         "output-speaker+wired_headphone" },
++    { AUDIO_DEVICE_OUT_WIRED_HEADSET,               "output-wired_headset" },
++    { AUDIO_DEVICE_OUT_WIRED_HEADPHONE,             "output-wired_headphone" },
++    { AUDIO_DEVICE_OUT_BLUETOOTH_SCO,               "output-bluetooth_sco" },
++    { AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,       "output-sco_headset" },
++    { AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,        "output-sco_carkit" },
++    { AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,              "output-a2dp" },
++    { AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,   "output-a2dp_headphones" },
++    { AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER,      "output-a2dp_speaker" },
++    { AUDIO_DEVICE_OUT_AUX_DIGITAL,                 "output-aux_digital" },
++    { AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET,           "output-analog_dock_headset" },
++    { AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET,           "output-digital_dock_headset" },
++    { AUDIO_DEVICE_OUT_USB_ACCESSORY,               "output-usb_accessory" },
++    { AUDIO_DEVICE_OUT_USB_DEVICE,                  "output-usb_device" },
++    { AUDIO_DEVICE_OUT_FM,                          "output-fm" },
++    { AUDIO_DEVICE_OUT_FM_TX,                       "output-fm_tx" },
++    { AUDIO_DEVICE_OUT_ANC_HEADSET,                 "output-anc_headset" },
++    { AUDIO_DEVICE_OUT_ANC_HEADPHONE,               "output-anc_headphone" },
++    { AUDIO_DEVICE_OUT_PROXY,                       "output-proxy" },
++    { 0, NULL }
++};
++
++/* Input devices */
++static struct string_conversion string_conversion_table_input_device[] = {
++    STRING_ENTRY(AUDIO_DEVICE_IN_COMMUNICATION),
++    STRING_ENTRY(AUDIO_DEVICE_IN_AMBIENT),
++    STRING_ENTRY(AUDIO_DEVICE_IN_BUILTIN_MIC),
++    STRING_ENTRY(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_IN_WIRED_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_IN_AUX_DIGITAL),
++    STRING_ENTRY(AUDIO_DEVICE_IN_VOICE_CALL),
++    STRING_ENTRY(AUDIO_DEVICE_IN_BACK_MIC),
++    STRING_ENTRY(AUDIO_DEVICE_IN_ANC_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_IN_FM_RX),
++    STRING_ENTRY(AUDIO_DEVICE_IN_FM_RX_A2DP),
++    STRING_ENTRY(AUDIO_DEVICE_IN_PROXY),
++    { 0, NULL }
++};
++
++static struct string_conversion string_conversion_table_input_device_fancy[] = {
++    { AUDIO_DEVICE_IN_COMMUNICATION,            "input-in_communication" },
++    { AUDIO_DEVICE_IN_AMBIENT,                  "input-ambient" },
++    { AUDIO_DEVICE_IN_BUILTIN_MIC,              "input-builtin_mic" },
++    { AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,    "input-bluetooth_sco_headset" },
++    { AUDIO_DEVICE_IN_WIRED_HEADSET,            "input-wired_headset" },
++    { AUDIO_DEVICE_IN_AUX_DIGITAL,              "input-aux_digital" },
++    { AUDIO_DEVICE_IN_VOICE_CALL,               "input-voice_call" },
++    { AUDIO_DEVICE_IN_BACK_MIC,                 "input-back_mic" },
++    { AUDIO_DEVICE_IN_ANC_HEADSET,              "input-anc_headset" },
++    { AUDIO_DEVICE_IN_FM_RX,                    "input-fm_rx" },
++    { AUDIO_DEVICE_IN_FM_RX_A2DP,               "input-fm_rx_a2dp" },
++    { AUDIO_DEVICE_IN_PROXY,                    "input-in_proxy" },
++    { 0, NULL }
++};
++
++/* Flags */
++static struct string_conversion string_conversion_table_flag[] = {
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_NONE),
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_DIRECT),
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_PRIMARY),
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_FAST),
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
++    /* Qualcomm flags */
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_LPA),
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_TUNNEL),
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_VOIP_RX),
++    { 0, NULL }
++};
++
++/* Channels */
++static struct string_conversion string_conversion_table_output_channels[] = {
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_LEFT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_RIGHT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_LOW_FREQUENCY),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_BACK_LEFT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_BACK_RIGHT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_BACK_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_SIDE_LEFT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_SIDE_RIGHT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_BACK_LEFT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_BACK_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_MONO),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_STEREO),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_QUAD),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_SURROUND),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_5POINT1),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_7POINT1),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_ALL),
++    { 0, NULL }
++};
++static struct string_conversion string_conversion_table_input_channels[] = {
++    STRING_ENTRY(AUDIO_CHANNEL_IN_LEFT),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_RIGHT),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_FRONT),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_BACK),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_LEFT_PROCESSED),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_RIGHT_PROCESSED),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_FRONT_PROCESSED),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_BACK_PROCESSED),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_PRESSURE),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_X_AXIS),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_Y_AXIS),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_Z_AXIS),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_UPLINK),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_DNLINK),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_MONO),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_STEREO),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_5POINT1),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_CALL_MONO),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_ALL),
++    { 0, NULL }
++};
++
++/* Formats */
++static struct string_conversion string_conversion_table_format[] = {
++    STRING_ENTRY(AUDIO_FORMAT_DEFAULT),
++    STRING_ENTRY(AUDIO_FORMAT_PCM),
++    STRING_ENTRY(AUDIO_FORMAT_MP3),
++    STRING_ENTRY(AUDIO_FORMAT_AMR_NB),
++    STRING_ENTRY(AUDIO_FORMAT_AMR_WB),
++    STRING_ENTRY(AUDIO_FORMAT_AAC),
++    STRING_ENTRY(AUDIO_FORMAT_HE_AAC_V1),
++    STRING_ENTRY(AUDIO_FORMAT_HE_AAC_V2),
++    STRING_ENTRY(AUDIO_FORMAT_VORBIS),
++    STRING_ENTRY(AUDIO_FORMAT_EVRC),
++    STRING_ENTRY(AUDIO_FORMAT_QCELP),
++    STRING_ENTRY(AUDIO_FORMAT_AC3),
++    STRING_ENTRY(AUDIO_FORMAT_AC3_PLUS),
++    STRING_ENTRY(AUDIO_FORMAT_DTS),
++    STRING_ENTRY(AUDIO_FORMAT_WMA),
++    STRING_ENTRY(AUDIO_FORMAT_WMA_PRO),
++    STRING_ENTRY(AUDIO_FORMAT_AAC_ADIF),
++    STRING_ENTRY(AUDIO_FORMAT_EVRCB),
++    STRING_ENTRY(AUDIO_FORMAT_EVRCWB),
++    STRING_ENTRY(AUDIO_FORMAT_EAC3),
++    STRING_ENTRY(AUDIO_FORMAT_DTS_LBR),
++    STRING_ENTRY(AUDIO_FORMAT_AMR_WB_PLUS),
++    /* Currently we support only PCM formats, but keep all formats
++     * here so audio_policy.conf can be parsed. */
++    STRING_ENTRY(AUDIO_FORMAT_PCM_16_BIT),
++    STRING_ENTRY(AUDIO_FORMAT_PCM_8_BIT),
++    STRING_ENTRY(AUDIO_FORMAT_PCM_32_BIT),
++    STRING_ENTRY(AUDIO_FORMAT_PCM_8_24_BIT),
++    { 0, NULL }
++};
++#undef STRING_ENTRY
++
++#endif
+Index: pulseaudio/src/modules/droid/droid-util-42.h
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/droid-util-42.h
+@@ -0,0 +1,286 @@
++/*
++ * Copyright (C) 2013 Jolla Ltd.
++ *
++ * Contact: Juho Hämäläinen <juho.hamalainen at tieto.com>
++ *
++ * These PulseAudio Modules are 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
++ * version 2.1 of the License.
++ *
++ * 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 Street, Fifth Floor, Boston, MA 02110-1301
++ * USA.
++ */
++
++#ifndef _ANDROID_UTIL_V42_H_
++#define _ANDROID_UTIL_V42_H_
++
++#define HAL_V2
++
++// PulseAudio value    -    Android value
++
++static uint32_t conversion_table_output_channel[][2] = {
++    { PA_CHANNEL_POSITION_MONO,                     AUDIO_CHANNEL_OUT_MONO },
++    { PA_CHANNEL_POSITION_FRONT_LEFT,               AUDIO_CHANNEL_OUT_FRONT_LEFT },
++    { PA_CHANNEL_POSITION_FRONT_RIGHT,              AUDIO_CHANNEL_OUT_FRONT_RIGHT},
++    { PA_CHANNEL_POSITION_FRONT_CENTER,             AUDIO_CHANNEL_OUT_FRONT_CENTER },
++    { PA_CHANNEL_POSITION_SUBWOOFER,                AUDIO_CHANNEL_OUT_LOW_FREQUENCY },
++    { PA_CHANNEL_POSITION_REAR_LEFT,                AUDIO_CHANNEL_OUT_BACK_LEFT },
++    { PA_CHANNEL_POSITION_REAR_RIGHT,               AUDIO_CHANNEL_OUT_BACK_RIGHT },
++    { PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,     AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER },
++    { PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,    AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER },
++    { PA_CHANNEL_POSITION_REAR_CENTER,              AUDIO_CHANNEL_OUT_BACK_CENTER },
++    { PA_CHANNEL_POSITION_SIDE_LEFT,                AUDIO_CHANNEL_OUT_SIDE_LEFT },
++    { PA_CHANNEL_POSITION_SIDE_RIGHT,               AUDIO_CHANNEL_OUT_SIDE_RIGHT },
++    { PA_CHANNEL_POSITION_TOP_CENTER,               AUDIO_CHANNEL_OUT_TOP_CENTER },
++    { PA_CHANNEL_POSITION_TOP_FRONT_LEFT,           AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT },
++    { PA_CHANNEL_POSITION_TOP_FRONT_CENTER,         AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER },
++    { PA_CHANNEL_POSITION_TOP_FRONT_RIGHT,          AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT },
++    { PA_CHANNEL_POSITION_TOP_REAR_LEFT,            AUDIO_CHANNEL_OUT_TOP_BACK_LEFT },
++    { PA_CHANNEL_POSITION_TOP_REAR_CENTER,          AUDIO_CHANNEL_OUT_TOP_BACK_CENTER },
++    { PA_CHANNEL_POSITION_TOP_REAR_RIGHT,           AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT }
++};
++
++static uint32_t conversion_table_input_channel[][2] = {
++    { PA_CHANNEL_POSITION_MONO,                     AUDIO_CHANNEL_IN_MONO },
++    { PA_CHANNEL_POSITION_FRONT_LEFT,               AUDIO_CHANNEL_IN_LEFT },
++    { PA_CHANNEL_POSITION_FRONT_RIGHT,              AUDIO_CHANNEL_IN_RIGHT},
++    { PA_CHANNEL_POSITION_FRONT_CENTER,             AUDIO_CHANNEL_IN_FRONT },
++    { PA_CHANNEL_POSITION_REAR_CENTER,              AUDIO_CHANNEL_IN_BACK },
++    /* Following are missing suitable counterparts on PulseAudio side. */
++    { AUDIO_CHANNEL_IN_LEFT_PROCESSED,              AUDIO_CHANNEL_IN_LEFT_PROCESSED },
++    { AUDIO_CHANNEL_IN_RIGHT_PROCESSED,             AUDIO_CHANNEL_IN_RIGHT_PROCESSED },
++    { AUDIO_CHANNEL_IN_FRONT_PROCESSED,             AUDIO_CHANNEL_IN_FRONT_PROCESSED },
++    { AUDIO_CHANNEL_IN_BACK_PROCESSED,              AUDIO_CHANNEL_IN_BACK_PROCESSED },
++    { AUDIO_CHANNEL_IN_PRESSURE,                    AUDIO_CHANNEL_IN_PRESSURE },
++    { AUDIO_CHANNEL_IN_X_AXIS,                      AUDIO_CHANNEL_IN_X_AXIS },
++    { AUDIO_CHANNEL_IN_Y_AXIS,                      AUDIO_CHANNEL_IN_Y_AXIS },
++    { AUDIO_CHANNEL_IN_Z_AXIS,                      AUDIO_CHANNEL_IN_Z_AXIS },
++    { AUDIO_CHANNEL_IN_VOICE_UPLINK,                AUDIO_CHANNEL_IN_VOICE_UPLINK },
++    { AUDIO_CHANNEL_IN_VOICE_DNLINK,                AUDIO_CHANNEL_IN_VOICE_DNLINK }
++};
++
++static uint32_t conversion_table_format[][2] = {
++    { PA_SAMPLE_U8,             AUDIO_FORMAT_PCM_8_BIT },
++    { PA_SAMPLE_S16LE,          AUDIO_FORMAT_PCM_16_BIT },
++    { PA_SAMPLE_S32LE,          AUDIO_FORMAT_PCM_32_BIT },
++    { PA_SAMPLE_S24LE,          AUDIO_FORMAT_PCM_8_24_BIT }
++};
++
++struct string_conversion {
++    uint32_t value;
++    const char *str;
++};
++
++#if defined(STRING_ENTRY)
++#error STRING_ENTRY already defined somewhere, fix this lib.
++#endif
++#define STRING_ENTRY(str) { str, #str }
++/* Output devices */
++static struct string_conversion string_conversion_table_output_device[] = {
++    STRING_ENTRY(AUDIO_DEVICE_OUT_EARPIECE),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_SPEAKER),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_WIRED_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_SCO),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_AUX_DIGITAL),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_USB_ACCESSORY),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_USB_DEVICE),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_REMOTE_SUBMIX),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ANC_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ANC_HEADPHONE),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_PROXY),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_FM),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_FM_TX),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_SPDIF),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_DEFAULT),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ALL),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ALL_A2DP),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ALL_SCO),
++    STRING_ENTRY(AUDIO_DEVICE_OUT_ALL_USB),
++    { 0, NULL }
++};
++
++static struct string_conversion string_conversion_table_output_device_fancy[] = {
++    { AUDIO_DEVICE_OUT_EARPIECE,                    "output-earpiece" },
++    { AUDIO_DEVICE_OUT_SPEAKER,                     "output-speaker" },
++    { AUDIO_DEVICE_OUT_SPEAKER
++        | AUDIO_DEVICE_OUT_WIRED_HEADPHONE,         "output-speaker+wired_headphone" },
++    { AUDIO_DEVICE_OUT_WIRED_HEADSET,               "output-wired_headset" },
++    { AUDIO_DEVICE_OUT_WIRED_HEADPHONE,             "output-wired_headphone" },
++    { AUDIO_DEVICE_OUT_BLUETOOTH_SCO,               "output-bluetooth_sco" },
++    { AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,       "output-sco_headset" },
++    { AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,        "output-sco_carkit" },
++    { AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,              "output-a2dp" },
++    { AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,   "output-a2dp_headphones" },
++    { AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER,      "output-a2dp_speaker" },
++    { AUDIO_DEVICE_OUT_AUX_DIGITAL,                 "output-aux_digital" },
++    { AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET,           "output-analog_dock_headset" },
++    { AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET,           "output-digital_dock_headset" },
++    { AUDIO_DEVICE_OUT_USB_ACCESSORY,               "output-usb_accessory" },
++    { AUDIO_DEVICE_OUT_USB_DEVICE,                  "output-usb_device" },
++    { AUDIO_DEVICE_OUT_REMOTE_SUBMIX,               "output-remote_submix" },
++    { AUDIO_DEVICE_OUT_ANC_HEADSET,                 "output-anc_headset" },
++    { AUDIO_DEVICE_OUT_ANC_HEADPHONE,               "output-anc_headphone" },
++    { AUDIO_DEVICE_OUT_PROXY,                       "output-proxy" },
++    { AUDIO_DEVICE_OUT_FM,                          "output-fm" },
++    { AUDIO_DEVICE_OUT_FM_TX,                       "output-fm_tx" },
++    { AUDIO_DEVICE_OUT_SPDIF,                       "output-spdif" },
++    { 0, NULL }
++};
++
++/* Input devices */
++static struct string_conversion string_conversion_table_input_device[] = {
++    STRING_ENTRY(AUDIO_DEVICE_IN_COMMUNICATION),
++    STRING_ENTRY(AUDIO_DEVICE_IN_AMBIENT),
++    STRING_ENTRY(AUDIO_DEVICE_IN_BUILTIN_MIC),
++    STRING_ENTRY(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_IN_WIRED_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_IN_AUX_DIGITAL),
++    STRING_ENTRY(AUDIO_DEVICE_IN_VOICE_CALL),
++    STRING_ENTRY(AUDIO_DEVICE_IN_BACK_MIC),
++    STRING_ENTRY(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
++    STRING_ENTRY(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_IN_USB_ACCESSORY),
++    STRING_ENTRY(AUDIO_DEVICE_IN_USB_DEVICE),
++    STRING_ENTRY(AUDIO_DEVICE_IN_ANC_HEADSET),
++    STRING_ENTRY(AUDIO_DEVICE_IN_PROXY),
++    STRING_ENTRY(AUDIO_DEVICE_IN_FM_RX),
++    STRING_ENTRY(AUDIO_DEVICE_IN_FM_RX_A2DP),
++    STRING_ENTRY(AUDIO_DEVICE_IN_FM),
++    STRING_ENTRY(AUDIO_DEVICE_IN_MATV),
++    STRING_ENTRY(AUDIO_DEVICE_IN_AUX_DIGITAL2),
++    STRING_ENTRY(AUDIO_DEVICE_IN_ALL_SCO),
++    STRING_ENTRY(AUDIO_DEVICE_IN_DEFAULT),
++    { 0, NULL }
++};
++
++static struct string_conversion string_conversion_table_input_device_fancy[] = {
++    { AUDIO_DEVICE_IN_COMMUNICATION,            "input-communication" },
++    { AUDIO_DEVICE_IN_AMBIENT,                  "input-ambient" },
++    { AUDIO_DEVICE_IN_BUILTIN_MIC,              "input-builtin_mic" },
++    { AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,    "input-bluetooth_sco_headset" },
++    { AUDIO_DEVICE_IN_WIRED_HEADSET,            "input-wired_headset" },
++    { AUDIO_DEVICE_IN_AUX_DIGITAL,              "input-aux_digital" },
++    { AUDIO_DEVICE_IN_VOICE_CALL,               "input-voice_call" },
++    { AUDIO_DEVICE_IN_BACK_MIC,                 "input-back_mic" },
++    { AUDIO_DEVICE_IN_REMOTE_SUBMIX,            "input-remote_submix" },
++    { AUDIO_DEVICE_IN_ANC_HEADSET,              "input-anc_headset" },
++    { AUDIO_DEVICE_IN_PROXY,                    "input-proxy" },
++    { AUDIO_DEVICE_IN_FM_RX,                    "input-fm_rx" },
++    { AUDIO_DEVICE_IN_FM_RX_A2DP,               "input-fm_rx_a2dp" },
++    { AUDIO_DEVICE_IN_FM,                       "input-fm" },
++    { AUDIO_DEVICE_IN_MATV,                     "input-matv" },
++    { AUDIO_DEVICE_IN_AUX_DIGITAL2,             "input-aux_digital2" },
++    { 0, NULL }
++};
++
++/* Flags */
++static struct string_conversion string_conversion_table_flag[] = {
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_NONE),
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_DIRECT),
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_PRIMARY),
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_FAST),
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
++    STRING_ENTRY(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
++    { 0, NULL }
++};
++
++/* Channels */
++static struct string_conversion string_conversion_table_output_channels[] = {
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_LEFT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_RIGHT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_LOW_FREQUENCY),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_BACK_LEFT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_BACK_RIGHT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_BACK_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_SIDE_LEFT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_SIDE_RIGHT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_BACK_LEFT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_BACK_CENTER),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_MONO),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_STEREO),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_QUAD),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_SURROUND),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_5POINT1),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_7POINT1),
++    STRING_ENTRY(AUDIO_CHANNEL_OUT_ALL),
++    { 0, NULL }
++};
++static struct string_conversion string_conversion_table_input_channels[] = {
++    STRING_ENTRY(AUDIO_CHANNEL_IN_LEFT),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_RIGHT),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_FRONT),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_BACK),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_LEFT_PROCESSED),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_RIGHT_PROCESSED),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_FRONT_PROCESSED),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_BACK_PROCESSED),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_PRESSURE),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_X_AXIS),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_Y_AXIS),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_Z_AXIS),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_UPLINK),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_VOICE_DNLINK),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_MONO),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_STEREO),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_FRONT_BACK),
++    STRING_ENTRY(AUDIO_CHANNEL_IN_ALL),
++    { 0, NULL }
++};
++
++/* Formats */
++static struct string_conversion string_conversion_table_format[] = {
++    STRING_ENTRY(AUDIO_FORMAT_DEFAULT),
++    STRING_ENTRY(AUDIO_FORMAT_PCM),
++    STRING_ENTRY(AUDIO_FORMAT_MP3),
++    STRING_ENTRY(AUDIO_FORMAT_AMR_NB),
++    STRING_ENTRY(AUDIO_FORMAT_AMR_WB),
++    STRING_ENTRY(AUDIO_FORMAT_AAC),
++    STRING_ENTRY(AUDIO_FORMAT_HE_AAC_V1),
++    STRING_ENTRY(AUDIO_FORMAT_HE_AAC_V2),
++    STRING_ENTRY(AUDIO_FORMAT_VORBIS),
++    STRING_ENTRY(AUDIO_FORMAT_MAIN_MASK),
++    STRING_ENTRY(AUDIO_FORMAT_SUB_MASK),
++    STRING_ENTRY(AUDIO_FORMAT_PCM_16_BIT),
++    STRING_ENTRY(AUDIO_FORMAT_PCM_8_BIT),
++    STRING_ENTRY(AUDIO_FORMAT_PCM_32_BIT),
++    STRING_ENTRY(AUDIO_FORMAT_PCM_8_24_BIT),
++    { 0, NULL }
++};
++#undef STRING_ENTRY
++
++/* Ports with availability option (for port/jack detection) */
++static const char* port_availability[] = {
++    "output-wired_headset",
++    "output-wired_headphone",
++    "input-wired_headset",
++    NULL
++};
++
++
++#endif
+Index: pulseaudio/src/modules/droid/droid-util.c
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/droid-util.c
+@@ -0,0 +1,1189 @@
++/*
++ * Copyright (C) 2013 Jolla Ltd.
++ *
++ * Contact: Juho Hämäläinen <juho.hamalainen at tieto.com>
++ *
++ * These PulseAudio Modules are 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
++ * version 2.1 of the License.
++ *
++ * 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 Street, Fifth Floor, Boston, MA 02110-1301
++ * USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <signal.h>
++#include <stdio.h>
++
++#ifdef HAVE_VALGRIND_MEMCHECK_H
++#include <valgrind/memcheck.h>
++#endif
++
++#include <pulse/rtclock.h>
++#include <pulse/timeval.h>
++#include <pulse/volume.h>
++#include <pulse/xmalloc.h>
++
++#include <pulsecore/core.h>
++#include <pulsecore/core-error.h>
++#include <pulsecore/i18n.h>
++#include <pulsecore/module.h>
++#include <pulsecore/memchunk.h>
++#include <pulsecore/sink.h>
++#include <pulsecore/modargs.h>
++#include <pulsecore/core-rtclock.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/thread-mq.h>
++#include <pulsecore/rtpoll.h>
++#include <pulsecore/time-smoother.h>
++#include <pulsecore/refcnt.h>
++#include <pulsecore/shared.h>
++#include <pulsecore/mutex.h>
++
++#include <hardware/audio.h>
++#include <hardware_legacy/audio_policy_conf.h>
++
++#include "droid-util.h"
++
++#include <android-version.h>
++
++#ifndef ANDROID_VERSION_MAJOR
++#error "ANDROID_VERSION_* not defined."
++#endif
++
++#if ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR == 1
++#include "droid-util-41qc.h"
++#elif ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR >= 2
++#include "droid-util-42.h"
++#else
++#error "No valid ANDROID_VERSION found."
++#endif
++
++#define CONVERT_FUNC(TABL) \
++bool pa_convert_ ## TABL (uint32_t value, pa_conversion_field_t field, uint32_t *to_value) {                    \
++    for (unsigned int i = 0; i < sizeof( conversion_table_ ## TABL )/(sizeof(uint32_t)*2); i++) {               \
++        if ( conversion_table_ ## TABL [i][field] == value) {                                                   \
++            *to_value = conversion_table_ ## TABL [i][!field];                                                  \
++            return true;                                                                                        \
++        }                                                                                                       \
++    }                                                                                                           \
++    return false;                                                                                               \
++} struct __funny_extra_to_allow_semicolon
++
++/* Creates convert_format convert_channel etc.
++ * bool pa_convert_func(uint32_t value, pa_conversion_field_t field, uint32_t *to_value);
++ * return true if conversion succesful */
++CONVERT_FUNC(format);
++CONVERT_FUNC(output_channel);
++CONVERT_FUNC(input_channel);
++
++#define DEFAULT_PRIORITY (100)
++
++static bool string_convert_num_to_str(const struct string_conversion *list, const uint32_t value, const char **to_str) {
++    pa_assert(list);
++    pa_assert(to_str);
++
++    pa_log_debug("Trying to convert %x to string.", value);
++
++    for (unsigned int i = 0; list[i].str; i++) {
++        if (list[i].value == value) {
++            *to_str = list[i].str;
++            return true;
++        }
++    }
++    return false;
++}
++
++static bool string_convert_str_to_num(const struct string_conversion *list, const char *str, uint32_t *to_value) {
++    pa_assert(list);
++    pa_assert(str);
++    pa_assert(to_value);
++
++    pa_log_debug("Trying to convert %s to num.", str);
++
++    for (unsigned int i = 0; list[i].str; i++) {
++        if (pa_streq(list[i].str, str)) {
++            *to_value = list[i].value;
++            return true;
++        }
++    }
++    return false;
++}
++
++static bool check_port_availability(const char *port) {
++    pa_assert(port);
++
++    pa_log_debug("Checking availability for port '%s'", port);
++
++    for (unsigned int i = 0; port_availability[i]; i++) {
++        if (pa_streq(port_availability[i], port)) {
++            return true;
++        }
++    }
++
++    return false;
++}
++
++static char *list_string(struct string_conversion *list, uint32_t flags) {
++    char *str = NULL;
++    char *tmp;
++
++#ifdef HAL_V2
++    if (flags & AUDIO_DEVICE_BIT_IN)
++        flags &= ~AUDIO_DEVICE_BIT_IN;
++#endif
++
++    for (unsigned int i = 0; list[i].str; i++) {
++#ifdef HAL_V2
++        if (list[i].value & AUDIO_DEVICE_BIT_IN) {
++            if (popcount(list[i].value & ~AUDIO_DEVICE_BIT_IN) != 1)
++                continue;
++        } else
++#endif
++        if (popcount(list[i].value) != 1)
++            continue;
++
++        if (flags & list[i].value) {
++            if (str) {
++                tmp = pa_sprintf_malloc("%s|%s", str, list[i].str);
++                pa_xfree(str);
++                str = tmp;
++            } else {
++                str = pa_sprintf_malloc("%s", list[i].str);
++            }
++        }
++    }
++
++    return str;
++}
++
++static void droid_port_free(pa_droid_port *p) {
++    pa_assert(p);
++
++    pa_xfree(p->name);
++    pa_xfree(p->description);
++    pa_xfree(p);
++}
++
++/* Output device */
++bool pa_string_convert_output_device_num_to_str(audio_devices_t value, const char **to_str) {
++    return string_convert_num_to_str(string_conversion_table_output_device, (uint32_t) value, to_str);
++}
++
++bool pa_string_convert_output_device_str_to_num(const char *str, audio_devices_t *to_value) {
++    return string_convert_str_to_num(string_conversion_table_output_device, str, (uint32_t*) to_value);
++}
++
++char *pa_list_string_output_device(audio_devices_t devices) {
++    return list_string(string_conversion_table_output_device, devices);
++}
++
++/* Input device */
++bool pa_string_convert_input_device_num_to_str(audio_devices_t value, const char **to_str) {
++    return string_convert_num_to_str(string_conversion_table_input_device, (uint32_t) value, to_str);
++}
++
++bool pa_string_convert_input_device_str_to_num(const char *str, audio_devices_t *to_value) {
++    return string_convert_str_to_num(string_conversion_table_input_device, str, (uint32_t*) to_value);
++}
++
++char *pa_list_string_input_device(audio_devices_t devices) {
++    return list_string(string_conversion_table_input_device, devices);
++}
++
++/* Flags */
++bool pa_string_convert_flag_num_to_str(audio_output_flags_t value, const char **to_str) {
++    return string_convert_num_to_str(string_conversion_table_flag, (uint32_t) value, to_str);
++}
++
++bool pa_string_convert_flag_str_to_num(const char *str, audio_output_flags_t *to_value) {
++    return string_convert_str_to_num(string_conversion_table_flag, str, (uint32_t*) to_value);
++}
++
++char *pa_list_string_flags(audio_output_flags_t flags) {
++    return list_string(string_conversion_table_flag, flags);
++}
++
++/* Config parser */
++
++#define WHITESPACE "\n\r \t"
++
++static int parse_list(const struct string_conversion *table, const char *str, uint32_t *dst) {
++    int count = 0;
++    char *entry;
++    const char *state = NULL;
++
++    pa_assert(table);
++    pa_assert(str);
++    pa_assert(dst);
++
++    *dst = 0;
++
++    while ((entry = pa_split(str, "|", &state))) {
++        uint32_t d = 0;
++
++        if (!string_convert_str_to_num(table, entry, &d)) {
++            pa_log("Unknown entry %s", entry);
++            pa_xfree(entry);
++            return -1;
++        }
++
++        *dst |= d;
++        count++;
++
++        pa_xfree(entry);
++    }
++
++    return count;
++}
++
++static bool parse_sampling_rates(const char *str, uint32_t sampling_rates[32]) {
++    char *entry;
++    const char *state = NULL;
++
++    pa_assert(str);
++
++    uint32_t pos = 0;
++    while ((entry = pa_split(str, "|", &state))) {
++        int32_t val;
++
++        if (pos == AUDIO_MAX_SAMPLING_RATES) {
++            pa_log("Too many sample rate entries (> %d)", AUDIO_MAX_SAMPLING_RATES);
++            pa_xfree(entry);
++            return false;
++        }
++
++        if (pa_atoi(entry, &val) < 0) {
++            pa_log("Bad sample rate value %s", entry);
++            pa_xfree(entry);
++            return false;
++        }
++
++        sampling_rates[pos++] = val;
++
++        pa_xfree(entry);
++
++    }
++
++    sampling_rates[pos] = 0;
++
++    return true;
++}
++
++static bool parse_formats(const char *str, audio_format_t *formats) {
++    pa_assert(str);
++    pa_assert(formats);
++
++    return parse_list(string_conversion_table_format, str, formats) > 0;
++}
++
++static int parse_channels(const char *str, bool in_output, audio_channel_mask_t *channels) {
++    pa_assert(str);
++    pa_assert(channels);
++
++    /* Needs to be probed later */
++    if (pa_streq(str, "dynamic")) {
++        *channels = 0;
++        return true;
++    }
++
++    if (in_output)
++        return parse_list(string_conversion_table_output_channels, str, channels);
++    else
++        return parse_list(string_conversion_table_input_channels, str, channels);
++}
++
++static bool parse_devices(const char *str, bool in_output, audio_devices_t *devices) {
++    pa_assert(str);
++    pa_assert(devices);
++
++    if (in_output)
++        return parse_list(string_conversion_table_output_device, str, devices) > 0;
++    else
++        return parse_list(string_conversion_table_input_device, str, devices) > 0;
++}
++
++static bool parse_flags(const char *str, audio_output_flags_t *flags) {
++    pa_assert(str);
++    pa_assert(flags);
++
++    return parse_list(string_conversion_table_flag, str, flags) > 0;
++}
++
++bool pa_parse_droid_audio_config(const char *filename, pa_droid_config_audio *config) {
++    FILE *f;
++    int n = 0;
++    bool ret = true;
++
++    enum config_loc {
++        IN_ROOT = 0,
++        IN_GLOBAL = 1,
++        IN_HW_MODULES = 1,
++        IN_MODULE = 2,
++        IN_OUTPUT_INPUT = 3,
++        IN_CONFIG = 4
++    } loc = IN_ROOT;
++
++
++    bool in_global = false;
++    bool in_output = true;
++
++    pa_droid_config_hw_module *module = NULL;
++    pa_droid_config_output *output = NULL;
++    pa_droid_config_input *input = NULL;
++
++    pa_assert(filename);
++    pa_assert(config);
++
++    memset(config, 0, sizeof(pa_droid_config_audio));
++
++    f = fopen(filename, "r");
++
++    if (!f) {
++        pa_log_info("Failed to open config file (%s): %s", filename, pa_cstrerror(errno));
++        ret = false;
++        goto finish;
++    }
++
++    pa_lock_fd(fileno(f), 1);
++
++    while (!feof(f)) {
++        char ln[512];
++        char *d, *v, *val;
++
++        if (!fgets(ln, sizeof(ln), f))
++            break;
++
++        n++;
++
++        pa_strip_nl(ln);
++
++        if (ln[0] == '#' || !*ln )
++            continue;
++
++        /* Enter section */
++        if (ln[strlen(ln)-1] == '{') {
++            d = ln+strspn(ln, WHITESPACE);
++            v = d;
++            d = v+strcspn(v, WHITESPACE);
++            d[0] = '\0';
++
++            if (!*v) {
++                pa_log(__FILE__ ": [%s:%u] failed to parse line - too few words", filename, n);
++                goto finish;
++            }
++
++            switch (loc) {
++                case IN_ROOT:
++                    if (pa_streq(v, GLOBAL_CONFIG_TAG)) {
++                        in_global = true;
++                        loc = IN_GLOBAL;
++                    }
++                    else if (pa_streq(v, AUDIO_HW_MODULE_TAG))
++                        loc = IN_HW_MODULES;
++                    else {
++                        pa_log(__FILE__ ": [%s:%u] failed to parse line - unknown field (%s)", filename, n, v);
++                        ret = false;
++                        goto finish;
++                    }
++                    break;
++
++                case IN_HW_MODULES:
++                    module = &config->hw_modules[config->hw_modules_size];
++                    config->hw_modules_size++;
++                    strncpy(module->name, v, AUDIO_HARDWARE_MODULE_ID_MAX_LEN);
++                    module->config = config;
++                    loc = IN_MODULE;
++                    pa_log_debug("config: New module: %s", module->name);
++                    break;
++
++                case IN_MODULE:
++                    if (pa_streq(v, OUTPUTS_TAG)) {
++                        loc = IN_OUTPUT_INPUT;
++                        in_output = true;
++                    } else if (pa_streq(v, INPUTS_TAG)) {
++                        loc = IN_OUTPUT_INPUT;
++                        in_output = false;
++                    } else {
++                        pa_log(__FILE__ ": [%s:%u] failed to parse line - unknown field (%s)", filename, n, v);
++                        ret = false;
++                        goto finish;
++                    }
++                    break;
++
++                case IN_OUTPUT_INPUT:
++                    pa_assert(module);
++
++                    if (in_output) {
++                        output = &module->outputs[module->outputs_size];
++                        module->outputs_size++;
++                        strncpy(output->name, v, AUDIO_HARDWARE_MODULE_ID_MAX_LEN);
++                        output->module = module;
++                        loc = IN_CONFIG;
++                        pa_log_debug("config: %s: New output: %s", module->name, output->name);
++                    } else {
++                        input = &module->inputs[module->inputs_size];
++                        module->inputs_size++;
++                        strncpy(input->name, v, AUDIO_HARDWARE_MODULE_ID_MAX_LEN);
++                        input->module = module;
++                        loc = IN_CONFIG;
++                        pa_log_debug("config: %s: New input: %s", module->name, input->name);
++                    }
++                    break;
++
++                case IN_CONFIG:
++                    pa_log(__FILE__ ": [%s:%u] failed to parse line - unknown field in config (%s)", filename, n, v);
++                    ret = false;
++                    goto finish;
++            }
++
++            continue;
++        }
++
++        /* Exit section */
++        if (ln[strlen(ln)-1] == '}') {
++            if (loc == IN_ROOT) {
++                pa_log(__FILE__ ": [%s:%u] failed to parse line - extra closing bracket", filename, n);
++                ret = false;
++                goto finish;
++            }
++
++            loc--;
++            if (loc == IN_MODULE) {
++                if (in_output)
++                    output = NULL;
++                else
++                    input = NULL;
++            }
++            if (loc == IN_ROOT)
++                module = NULL;
++
++            in_global = false;
++
++            continue;
++        }
++
++        /* Parse global configuration */
++        if (in_global) {
++            bool success = false;
++
++            d = ln+strspn(ln, WHITESPACE);
++            v = d;
++            d = v+strcspn(v, WHITESPACE);
++
++            val = d+strspn(d, WHITESPACE);
++            d[0] = '\0';
++            d = val+strcspn(val, WHITESPACE);
++            d[0] = '\0';
++
++            if (pa_streq(v, ATTACHED_OUTPUT_DEVICES_TAG))
++                success = parse_devices(val, true, &config->global_config.attached_output_devices);
++            else if (pa_streq(v, DEFAULT_OUTPUT_DEVICE_TAG))
++                success = parse_devices(val, true, &config->global_config.default_output_device);
++            else if (pa_streq(v, ATTACHED_INPUT_DEVICES_TAG))
++                success = parse_devices(val, false, &config->global_config.attached_input_devices);
++            else if (pa_streq(v, SPEAKER_DRC_ENABLED_TAG)) {
++                pa_log(__FILE__ ": speaker drc is not yet supported, skipping", filename);
++                success = true;
++            } else {
++                pa_log(__FILE__ ": [%s:%u] failed to parse line - unknown config entry %s", filename, n, v);
++                success = false;
++            }
++
++            if (!success) {
++                ret = false;
++                goto finish;
++            }
++        }
++
++        /* Parse per-output or per-input configuration */
++        if (loc == IN_CONFIG) {
++            bool success = false;
++
++            pa_assert(module);
++
++            d = ln+strspn(ln, WHITESPACE);
++            v = d;
++            d = v+strcspn(v, WHITESPACE);
++
++            val = d+strspn(d, WHITESPACE);
++            d[0] = '\0';
++            d = val+strcspn(val, WHITESPACE);
++            d[0] = '\0';
++
++
++            if ((in_output && !output) || (!in_output && !input)) {
++                pa_log(__FILE__ ": [%s:%u] failed to parse line", filename, n);
++                ret = false;
++                goto finish;
++            }
++
++            if (pa_streq(v, SAMPLING_RATES_TAG))
++                success = parse_sampling_rates(val, in_output ? output->sampling_rates : input->sampling_rates);
++            else if (pa_streq(v, FORMATS_TAG))
++                success = parse_formats(val, in_output ? &output->formats : &input->formats);
++            else if (pa_streq(v, CHANNELS_TAG)) {
++                if (in_output)
++                    success = (parse_channels(val, true, &output->channel_masks) > 0);
++                else
++                    success = (parse_channels(val, false, &input->channel_masks) > 0);
++            } else if (pa_streq(v, DEVICES_TAG)) {
++                if (in_output)
++                    success = parse_devices(val, true, &output->devices);
++                else
++                    success = parse_devices(val, false, &input->devices);
++            } else if (pa_streq(v, FLAGS_TAG)) {
++                if (in_output)
++                    success = parse_flags(val, &output->flags);
++                else {
++                    pa_log(__FILE__ ": [%s:%u] failed to parse line - output flags inside input definition", filename, n);
++                    success = false;
++                }
++            } else {
++                pa_log(__FILE__ ": [%s:%u] failed to parse line - unknown config entry %s", filename, n, v);
++                success = false;
++            }
++
++            if (!success) {
++                ret = false;
++                goto finish;
++            }
++        }
++    }
++
++    pa_log_info("Parsed config file (%s): %u modules.", filename, config->hw_modules_size);
++
++finish:
++    if (f) {
++        pa_lock_fd(fileno(f), 0);
++        fclose(f);
++    }
++
++    return ret;
++}
++
++
++const pa_droid_config_output *pa_droid_config_find_output(const pa_droid_config_hw_module *module, const char *name) {
++    pa_assert(module);
++    pa_assert(name);
++
++    for (unsigned i = 0; i < module->outputs_size; i++) {
++        if (pa_streq(name, module->outputs[i].name))
++            return &module->outputs[i];
++    }
++
++    return NULL;
++}
++
++const pa_droid_config_input *pa_droid_config_find_input(const pa_droid_config_hw_module *module, const char *name) {
++    pa_assert(module);
++    pa_assert(name);
++
++    for (unsigned i = 0; i < module->inputs_size; i++) {
++        if (pa_streq(name, module->inputs[i].name))
++            return &module->inputs[i];
++    }
++
++    return NULL;
++}
++
++const pa_droid_config_hw_module *pa_droid_config_find_module(const pa_droid_config_audio *config, const char* module_id) {
++    pa_assert(config);
++    pa_assert(module_id);
++
++    for (unsigned i = 0; i < config->hw_modules_size; i++) {
++        if (pa_streq(module_id, config->hw_modules[i].name))
++            return &config->hw_modules[i];
++    }
++
++    return NULL;
++}
++
++pa_droid_profile *pa_droid_profile_new(pa_droid_profile_set *ps, const pa_droid_config_output *output, const pa_droid_config_input *input) {
++    pa_droid_profile *p;
++
++    pa_assert(ps);
++    pa_assert(output);
++
++    p = pa_xnew0(pa_droid_profile, 1);
++    p->profile_set = ps;
++    p->module = output->module;
++    p->name = pa_sprintf_malloc("%s%s%s", output->name, input ? "-" : "", input ? input->name : "");
++    p->description = pa_sprintf_malloc("%s output%s%s%s", output->name,
++                                                          input ? " and " : "",
++                                                          input ? input->name : "",
++                                                          input ? " input." : "");
++    p->priority = DEFAULT_PRIORITY;
++    if (pa_streq(output->name, "primary")) {
++        p->priority += DEFAULT_PRIORITY;
++
++        if (input && pa_streq(input->name, "primary"))
++            p->priority += DEFAULT_PRIORITY;
++    }
++
++    if (output)
++        p->output = pa_droid_mapping_get(ps, PA_DIRECTION_OUTPUT, output);
++    if (input)
++        p->input = pa_droid_mapping_get(ps, PA_DIRECTION_INPUT, input);
++
++    pa_hashmap_put(ps->profiles, p->name, p);
++
++    return p;
++}
++
++static void add_profile(pa_droid_profile_set *ps, const pa_droid_config_output *output, const pa_droid_config_input *input) {
++    pa_droid_profile *ap;
++
++    pa_log_debug("New profile: %s-%s", output->name, input ? input->name : "no input");
++
++    ap = pa_droid_profile_new(ps, output, input);
++
++    pa_hashmap_put(ps->profiles, ap->name, ap);
++}
++
++pa_droid_profile_set *pa_droid_profile_set_new(const pa_droid_config_hw_module *module) {
++    pa_droid_profile_set *ps;
++
++    pa_assert(module);
++
++    ps = pa_xnew0(pa_droid_profile_set, 1);
++    ps->config = module->config;
++    ps->profiles = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_droid_profile_free);
++    ps->output_mappings = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_droid_mapping_free);
++    ps->input_mappings = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_droid_mapping_free);
++    ps->all_ports = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) droid_port_free);
++
++    /* Each distinct hw module output matches one profile. If there are multiple inputs
++     * combinations are made so that all possible outputs and inputs can be selected.
++     * So for outputs "primary" and "hdmi" and input "primary" profiles
++     * "primary-primary" and "hdmi-primary" are created. */
++
++    for (unsigned o = 0; o < module->outputs_size; o++) {
++
++        if (module->inputs_size > 0) {
++            for (unsigned i = 0; i < module->inputs_size; i++) {
++                add_profile(ps, &module->outputs[o], &module->inputs[i]);
++            }
++        } else
++            add_profile(ps, &module->outputs[o], NULL);
++    }
++
++    return ps;
++}
++
++void pa_droid_mapping_free(pa_droid_mapping *am) {
++    pa_assert(am);
++
++    pa_xfree(am->name);
++    pa_proplist_free(am->proplist);
++    pa_idxset_free(am->ports, NULL);
++    pa_xfree(am);
++}
++
++void pa_droid_profile_free(pa_droid_profile *ap) {
++    pa_assert(ap);
++
++    pa_xfree(ap->name);
++    pa_xfree(ap->description);
++    pa_xfree(ap);
++}
++
++void pa_droid_profile_set_free(pa_droid_profile_set *ps) {
++    pa_assert(ps);
++
++    if (ps->output_mappings)
++        pa_hashmap_free(ps->output_mappings);
++
++    if (ps->input_mappings)
++        pa_hashmap_free(ps->input_mappings);
++
++    if (ps->all_ports)
++        pa_hashmap_free(ps->all_ports);
++
++    if (ps->profiles)
++        pa_hashmap_free(ps->profiles);
++
++    pa_xfree(ps);
++}
++
++static pa_droid_port *create_o_port(pa_droid_mapping *am, uint32_t device, const char *name, const char *description) {
++    pa_droid_port *p;
++    char *desc;
++
++    pa_assert(am);
++    pa_assert(name);
++
++    pa_log_debug("  New output port %s", name);
++    p = pa_xnew0(pa_droid_port, 1);
++
++    p->mapping = am;
++    p->name = pa_xstrdup(name);
++    if (description) {
++        p->description = pa_xstrdup(description);
++    } else {
++        desc = pa_replace(name, "output-", "Output to ");
++        p->description = pa_replace(desc, "_", " ");
++        pa_xfree(desc);
++    }
++    p->priority = DEFAULT_PRIORITY;
++    p->device = device;
++
++    if (am->profile_set->config->global_config.attached_output_devices & device)
++        p->priority += DEFAULT_PRIORITY;
++
++    if (am->profile_set->config->global_config.default_output_device & device)
++        p->priority += DEFAULT_PRIORITY;
++
++    if (check_port_availability(p->name))
++        p->priority += (DEFAULT_PRIORITY * 3);
++
++    return p;
++}
++
++static void add_o_ports(pa_droid_mapping *am) {
++    pa_droid_port *p;
++    const char *name;
++    uint32_t devices;
++    uint32_t combo_devices;
++    uint32_t i = 0;
++
++    pa_assert(am);
++
++    devices = am->output->devices;
++
++    devices &= ~AUDIO_DEVICE_OUT_DEFAULT;
++
++    /* IHF combo devices, these devices are combined with IHF */
++    combo_devices = AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
++
++    while (devices) {
++        uint32_t cur_device = (1 << i++);
++
++        if (devices & cur_device) {
++
++            pa_assert_se(pa_droid_output_port_name(cur_device, &name));
++
++            if (!(p = pa_hashmap_get(am->profile_set->all_ports, name))) {
++
++                p = create_o_port(am, cur_device, name, NULL);
++                pa_hashmap_put(am->profile_set->all_ports, p->name, p);
++            } else
++                pa_log_debug("  Output port %s from cache", name);
++
++            pa_idxset_put(am->ports, p, NULL);
++
++            devices &= ~cur_device;
++        }
++    }
++
++    /* Combo devices, route to multiple routing targets simultaneously. */
++    if (am->output->devices & combo_devices) {
++        pa_assert_se(pa_droid_output_port_name(combo_devices, &name));
++        if (!(p = pa_hashmap_get(am->profile_set->all_ports, name))) {
++            p = create_o_port(am, combo_devices, name, NULL);
++            /* Reset priority to default. */
++            p->priority = DEFAULT_PRIORITY;
++
++            pa_hashmap_put(am->profile_set->all_ports, p->name, p);
++        } else
++            pa_log_debug("  Output port %s from cache", name);
++
++        pa_idxset_put(am->ports, p, NULL);
++    }
++
++    if (!(p = pa_hashmap_get(am->profile_set->all_ports, PA_DROID_OUTPUT_PARKING))) {
++        /* Create parking port for output mapping to be used when audio_mode_t changes. */
++        p = create_o_port(am, 0, PA_DROID_OUTPUT_PARKING, "Parking port");
++        /* Reset priority to half of default */
++        p->priority = DEFAULT_PRIORITY / 2;
++
++        pa_hashmap_put(am->profile_set->all_ports, p->name, p);
++    } else
++        pa_log_debug("  Output port %s from cache", PA_DROID_OUTPUT_PARKING);
++
++    pa_idxset_put(am->ports, p, NULL);
++}
++
++static void add_i_ports(pa_droid_mapping *am) {
++    pa_droid_port *p;
++    const char *name;
++    char *desc;
++    uint32_t devices;
++    uint32_t i = 0;
++
++    pa_assert(am);
++
++    devices = am->input->devices;
++#ifdef HAL_V2
++    devices &= ~AUDIO_DEVICE_IN_DEFAULT;
++#endif
++
++    while (devices) {
++        uint32_t cur_device = (1 << i++);
++
++        if (devices & cur_device) {
++
++#ifdef HAL_V2
++            cur_device |= AUDIO_DEVICE_BIT_IN;
++#endif
++
++            pa_assert_se(pa_droid_input_port_name(cur_device, &name));
++
++            if (!(p = pa_hashmap_get(am->profile_set->all_ports, name))) {
++                pa_log_debug("  New input port %s", name);
++                p = pa_xnew0(pa_droid_port, 1);
++
++                p->mapping = am;
++                p->name = pa_xstrdup(name);
++                desc = pa_replace(name, "input-", "Input from ");
++                p->description = pa_replace(desc, "_", " ");
++                pa_xfree(desc);
++                p->priority = DEFAULT_PRIORITY;
++                p->device = cur_device;
++
++                if (am->profile_set->config->global_config.attached_input_devices & cur_device & ~AUDIO_DEVICE_BIT_IN)
++                    p->priority += DEFAULT_PRIORITY;
++
++                /* Make builtin mic the default input device */
++                if (cur_device == AUDIO_DEVICE_IN_BUILTIN_MIC)
++                    p->priority += DEFAULT_PRIORITY;
++
++                if (check_port_availability(p->name))
++                    p->priority += (DEFAULT_PRIORITY * 3);
++
++                pa_hashmap_put(am->profile_set->all_ports, p->name, p);
++            } else
++                pa_log_debug("  Input port %s from cache", name);
++
++            pa_idxset_put(am->ports, p, NULL);
++
++            devices &= ~cur_device;
++        }
++    }
++
++    if (!(p = pa_hashmap_get(am->profile_set->all_ports, PA_DROID_INPUT_PARKING))) {
++        pa_log_debug("  New input port %s", PA_DROID_INPUT_PARKING);
++        /* Create parking port for input mapping to be used when audio_mode_t changes. */
++        p = pa_xnew0(pa_droid_port, 1);
++        p->mapping = am;
++        p->name = pa_sprintf_malloc(PA_DROID_INPUT_PARKING);
++        p->description = pa_sprintf_malloc("Parking port");
++        p->priority = 50;
++        p->device = 0; /* No routing */
++
++        pa_hashmap_put(am->profile_set->all_ports, p->name, p);
++    } else
++        pa_log_debug("  Input port %s from cache", PA_DROID_INPUT_PARKING);
++
++    pa_idxset_put(am->ports, p, NULL);
++}
++
++pa_droid_mapping *pa_droid_mapping_get(pa_droid_profile_set *ps, pa_direction_t direction, const void *data) {
++    pa_droid_mapping *am;
++    pa_hashmap *map;
++    const char *name;
++    const pa_droid_config_output *output = NULL;
++    const pa_droid_config_input *input = NULL;
++
++    if (direction == PA_DIRECTION_OUTPUT) {
++        output = (pa_droid_config_output *) data;
++        map = ps->output_mappings;
++        name = output->name;
++    } else {
++        input = (pa_droid_config_input *) data;
++        map = ps->input_mappings;
++        name = input->name;
++    }
++
++    if ((am = pa_hashmap_get(map, name))) {
++        pa_log_debug("  %s mapping %s from cache", input ? "Input" : "Output", name);
++        return am;
++    }
++    pa_log_debug("  New %s mapping %s", input ? "input" : "output", name);
++
++    am = pa_xnew0(pa_droid_mapping, 1);
++    am->profile_set = ps;
++    am->name = pa_xstrdup(name);
++    am->proplist = pa_proplist_new();
++    am->direction = direction;
++    am->output = output;
++    am->input = input;
++    am->ports = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);;
++
++    if (am->direction == PA_DIRECTION_OUTPUT)
++        add_o_ports(am);
++    else
++        add_i_ports(am);
++
++    pa_hashmap_put(map, am->name, am);
++
++    return am;
++}
++
++bool pa_droid_output_port_name(audio_devices_t value, const char **to_str) {
++    return string_convert_num_to_str(string_conversion_table_output_device_fancy, (uint32_t) value, to_str);
++}
++
++bool pa_droid_input_port_name(audio_devices_t value, const char **to_str) {
++    return string_convert_num_to_str(string_conversion_table_input_device_fancy, (uint32_t) value, to_str);
++}
++
++static int add_ports(pa_core *core, pa_card_profile *cp, pa_hashmap *ports, pa_droid_mapping *am, pa_hashmap *extra) {
++    pa_droid_port *p;
++    pa_device_port *dp;
++    pa_droid_port_data *data;
++    uint32_t idx;
++    int count = 0;
++
++    pa_log_debug("Ports for %s%s: %s", cp ? "card " : "", am->direction == PA_DIRECTION_OUTPUT ? "output" : "input", am->name);
++
++    PA_IDXSET_FOREACH(p, am->ports, idx) {
++        if (!(dp = pa_hashmap_get(ports, p->name))) {
++            pa_log_debug("  New port %s", p->name);
++
++            pa_device_port_new_data port_data;
++            pa_device_port_new_data_init(&port_data);
++            pa_device_port_new_data_set_name(&port_data, p->name);
++            pa_device_port_new_data_set_description(&port_data, p->description);
++            pa_device_port_new_data_set_direction(&port_data, p->mapping->direction);
++            dp = pa_device_port_new(core, &port_data, sizeof(pa_droid_port_data));
++            pa_device_port_new_data_done(&port_data);
++            dp->priority = p->priority;
++
++            pa_hashmap_put(ports, dp->name, dp);
++            dp->profiles = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_droid_profile_free);
++
++            data = PA_DEVICE_PORT_DATA(dp);
++            data->device = p->device;
++        } else
++            pa_log_debug("  Port %s from cache", p->name);
++
++        /* If port/jack detection is available, start as not available by default */
++        dp->available = check_port_availability(p->name) ? PA_AVAILABLE_NO : PA_AVAILABLE_UNKNOWN;
++
++        if (cp)
++            pa_hashmap_put(dp->profiles, cp->name, cp);
++
++        count++;
++
++        if (extra) {
++            pa_hashmap_put(extra, dp->name, dp);
++            pa_device_port_ref(dp);
++        }
++    }
++
++    return count;
++}
++
++
++void pa_droid_add_ports(pa_hashmap *p, pa_droid_mapping *am, pa_card *card) {
++    pa_assert(p);
++
++    add_ports(card->core, NULL, card->ports, am, p);
++}
++
++void pa_droid_add_card_ports(pa_card_profile *cp, pa_hashmap *ports, pa_droid_mapping *am, pa_core *core) {
++    pa_assert(cp);
++    pa_assert(am);
++    pa_assert(core);
++
++    add_ports(core, cp, ports, am, NULL);
++}
++
++static char *shared_name_get(const char *module_id) {
++    pa_assert(module_id);
++    return pa_sprintf_malloc("droid-hardware-module-%s", module_id);
++}
++
++static pa_droid_hw_module *droid_hw_module_open(pa_core *core, pa_droid_config_audio *config, const char *module_id) {
++    const pa_droid_config_hw_module *module;
++    pa_droid_hw_module *hw = NULL;
++    struct hw_module_t *hwmod = NULL;
++    audio_hw_device_t *device = NULL;
++    int ret;
++
++    pa_assert(core);
++    pa_assert(module_id);
++
++    if (!config) {
++        pa_log("No configuration provided for opening module with id %s", module_id);
++        goto fail;
++    }
++
++    if (!(module = pa_droid_config_find_module(config, module_id))) {
++        pa_log("Couldn't find module with id %s", module_id);
++        goto fail;
++    }
++
++    hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, module->name, (const hw_module_t**) &hwmod);
++    if (!hwmod) {
++        pa_log("Failed to get hw module id: %s name: %s, trying alternative.", AUDIO_HARDWARE_MODULE_ID, module->name);
++        hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID2, module->name, (const hw_module_t**) &hwmod);
++        if (!hwmod) {
++            pa_log("Failed to get hw module id: %s name: %s.", AUDIO_HARDWARE_MODULE_ID2, module->name);
++            goto fail;
++        }
++    }
++
++    pa_log_info("Loaded hw module %s", module->name);
++
++    ret = audio_hw_device_open(hwmod, &device);
++    if (!device) {
++        pa_log("Failed to open device (errno %d).", ret);
++        goto fail;
++    }
++
++    if ((ret = device->init_check(device)) != 0) {
++        pa_log("Failed init_check() (errno %d)", ret);
++        goto fail;
++    }
++
++    hw = pa_xnew0(pa_droid_hw_module, 1);
++    PA_REFCNT_INIT(hw);
++    hw->core = core;
++    hw->hwmod = hwmod;
++    hw->hw_mutex = pa_mutex_new(true, false);
++    hw->device = device;
++    hw->config = config; /* We take ownership of config struct. */
++    hw->enabled_module = pa_droid_config_find_module(hw->config, module_id);
++    hw->module_id = hw->enabled_module->name;
++    hw->shared_name = shared_name_get(hw->module_id);
++
++    pa_assert_se(pa_shared_set(core, hw->shared_name, hw) >= 0);
++
++    return hw;
++
++fail:
++    if (device)
++        audio_hw_device_close(device);
++
++    if (hw)
++        pa_xfree(hw);
++
++    return NULL;
++}
++
++pa_droid_hw_module *pa_droid_hw_module_get(pa_core *core, pa_droid_config_audio *config, const char *module_id) {
++    pa_droid_hw_module *hw;
++    char *shared_name;
++
++    pa_assert(core);
++    pa_assert(module_id);
++
++    shared_name = shared_name_get(module_id);
++    if ((hw = pa_shared_get(core, shared_name)))
++        hw = pa_droid_hw_module_ref(hw);
++    else
++        hw = droid_hw_module_open(core, config, module_id);
++
++    pa_xfree(shared_name);
++    return hw;
++}
++
++pa_droid_hw_module *pa_droid_hw_module_ref(pa_droid_hw_module *hw) {
++    pa_assert(hw);
++    pa_assert(PA_REFCNT_VALUE(hw) >= 1);
++
++    PA_REFCNT_INC(hw);
++    return hw;
++}
++
++static void droid_hw_module_close(pa_droid_hw_module *hw) {
++    pa_assert(hw);
++
++    pa_log_info("Closing hw module %s", hw->enabled_module->name);
++
++    if (hw->config)
++        pa_xfree(hw->config);
++
++    if (hw->device)
++        audio_hw_device_close(hw->device);
++
++    if (hw->hw_mutex)
++        pa_mutex_free(hw->hw_mutex);
++
++    if (hw->shared_name)
++        pa_xfree(hw->shared_name);
++
++    pa_xfree(hw);
++}
++
++void pa_droid_hw_module_unref(pa_droid_hw_module *hw) {
++
++    pa_assert(hw);
++    pa_assert(PA_REFCNT_VALUE(hw) >= 1);
++
++    if (PA_REFCNT_DEC(hw) > 0)
++        return;
++
++    pa_assert_se(pa_shared_remove(hw->core, hw->shared_name) >= 0);
++    droid_hw_module_close(hw);
++}
++
++pa_droid_config_audio *pa_droid_config_load(pa_modargs *ma) {
++    pa_droid_config_audio *config;
++    const char *config_location;
++
++    pa_assert(ma);
++
++    config = pa_xnew0(pa_droid_config_audio, 1);
++
++    if ((config_location = pa_modargs_get_value(ma, "config", NULL))) {
++        if (!pa_parse_droid_audio_config(config_location, config)) {
++            pa_log("Failed to parse configuration from %s", config_location);
++            goto fail;
++        }
++    } else {
++        config_location = AUDIO_POLICY_VENDOR_CONFIG_FILE;
++
++        if (!pa_parse_droid_audio_config(config_location, config)) {
++            pa_log_debug("Failed to parse configuration from vendor %s", config_location);
++
++            config_location = AUDIO_POLICY_CONFIG_FILE;
++
++            if (!pa_parse_droid_audio_config(config_location, config)) {
++                pa_log("Failed to parse configuration from %s", config_location);
++                goto fail;
++            }
++        }
++    }
++
++    return config;
++
++fail:
++    pa_xfree(config);
++    return NULL;
++}
++
++void pa_droid_hw_module_lock(pa_droid_hw_module *hw) {
++    pa_assert(hw);
++
++    pa_mutex_lock(hw->hw_mutex);
++}
++
++bool pa_droid_hw_module_try_lock(pa_droid_hw_module *hw) {
++    pa_assert(hw);
++
++    return pa_mutex_try_lock(hw->hw_mutex);
++}
++
++void pa_droid_hw_module_unlock(pa_droid_hw_module *hw) {
++    pa_assert(hw);
++
++    pa_mutex_unlock(hw->hw_mutex);
++}
+Index: pulseaudio/src/modules/droid/droid-util.h
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/droid-util.h
+@@ -0,0 +1,256 @@
++#ifndef foodroidutilfoo
++#define foodroidutilfoo
++
++/*
++ * Copyright (C) 2013 Jolla Ltd.
++ *
++ * Contact: Juho Hämäläinen <juho.hamalainen at tieto.com>
++ *
++ * These PulseAudio Modules are 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
++ * version 2.1 of the License.
++ *
++ * 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 Street, Fifth Floor, Boston, MA 02110-1301
++ * USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++#include <pulsecore/core-util.h>
++#include <pulsecore/macro.h>
++#include <pulsecore/mutex.h>
++#include <pulsecore/modargs.h>
++
++#include <hardware/audio.h>
++#include <hardware_legacy/audio_policy_conf.h>
++
++#define PROP_DROID_DEVICES    "droid.devices"
++#define PROP_DROID_FLAGS      "droid.flags"
++#define PROP_DROID_HW_MODULE  "droid.hw_module"
++
++/* Alternative module ID */
++#define AUDIO_HARDWARE_MODULE_ID2 "libaudio"
++
++/* From module-device-restore */
++#define MODULE_DEVICE_RESTORE_SKIP_PROPERTY "module-device-restore.skip"
++
++typedef struct pa_droid_hw_module pa_droid_hw_module;
++typedef struct pa_droid_card_data pa_droid_card_data;
++typedef void (*common_set_parameters_cb_t)(pa_droid_card_data *card_data, const char *str);
++
++typedef struct pa_droid_config_audio pa_droid_config_audio;
++typedef struct pa_droid_config_hw_module pa_droid_config_hw_module;
++
++struct pa_droid_hw_module {
++    PA_REFCNT_DECLARE;
++
++    pa_core *core;
++    char *shared_name;
++
++    pa_droid_config_audio *config;
++    const pa_droid_config_hw_module *enabled_module;
++    pa_mutex *hw_mutex;
++
++    struct hw_module_t *hwmod;
++    audio_hw_device_t *device;
++
++    const char *module_id;
++
++    uint32_t stream_out_id;
++    uint32_t stream_in_id;
++
++};
++
++struct pa_droid_card_data {
++    void *userdata;
++    /* General functions */
++    char *module_id;
++    common_set_parameters_cb_t set_parameters;
++};
++
++#define AUDIO_MAX_SAMPLING_RATES (32)
++#define AUDIO_MAX_HW_MODULES (8)
++#define AUDIO_MAX_INPUTS (8)
++#define AUDIO_MAX_OUTPUTS (8)
++
++typedef struct pa_droid_config_global {
++    audio_devices_t attached_output_devices;
++    audio_devices_t default_output_device;
++    audio_devices_t attached_input_devices;
++} pa_droid_config_global;
++
++typedef struct pa_droid_config_output {
++    const pa_droid_config_hw_module *module;
++
++    char name[AUDIO_HARDWARE_MODULE_ID_MAX_LEN];
++    uint32_t sampling_rates[AUDIO_MAX_SAMPLING_RATES];
++    audio_channel_mask_t channel_masks; /* 0 -> dynamic */
++    audio_format_t formats;
++    audio_devices_t devices;
++    audio_output_flags_t flags;
++} pa_droid_config_output;
++
++typedef struct pa_droid_config_input {
++    const pa_droid_config_hw_module *module;
++
++    char name[AUDIO_HARDWARE_MODULE_ID_MAX_LEN];
++    uint32_t sampling_rates[AUDIO_MAX_SAMPLING_RATES];
++    audio_channel_mask_t channel_masks; /* 0 -> dynamic */
++    audio_format_t formats;
++    audio_devices_t devices;
++} pa_droid_config_input;
++
++struct pa_droid_config_hw_module {
++    const pa_droid_config_audio *config;
++
++    char name[AUDIO_HARDWARE_MODULE_ID_MAX_LEN];
++    pa_droid_config_output outputs[AUDIO_MAX_OUTPUTS];
++    uint32_t outputs_size;
++    pa_droid_config_input inputs[AUDIO_MAX_INPUTS];
++    uint32_t inputs_size;
++};
++
++struct pa_droid_config_audio {
++    pa_droid_config_global global_config;
++    pa_droid_config_hw_module hw_modules[AUDIO_MAX_HW_MODULES];
++    uint32_t hw_modules_size;
++};
++
++
++/* Profiles */
++
++typedef struct pa_droid_profile_set pa_droid_profile_set;
++typedef struct pa_droid_mapping pa_droid_mapping;
++
++typedef struct pa_droid_port_data {
++    audio_devices_t device;
++} pa_droid_port_data;
++
++typedef struct pa_droid_port {
++    pa_droid_mapping *mapping;
++
++    audio_devices_t device;
++    char *name;
++    char *description;
++    unsigned priority;
++} pa_droid_port;
++
++struct pa_droid_mapping {
++    pa_droid_profile_set *profile_set;
++
++    const pa_droid_config_output *output;
++    const pa_droid_config_input *input;
++
++    char *name;
++    char *description;
++    unsigned priority;
++    pa_proplist *proplist;
++
++    /* Mapping doesn't own the ports */
++    pa_idxset *ports;
++
++    pa_direction_t direction;
++
++    pa_sink *sink;
++    pa_source *source;
++};
++
++typedef struct pa_droid_profile {
++    pa_droid_profile_set *profile_set;
++
++    const pa_droid_config_hw_module *module;
++
++    char *name;
++    char *description;
++    unsigned priority;
++
++    /* Profile doesn't own the mappings */
++    pa_droid_mapping *output;
++    pa_droid_mapping *input;
++
++} pa_droid_profile;
++
++struct pa_droid_profile_set {
++    const pa_droid_config_audio *config;
++
++    pa_hashmap *all_ports;
++    pa_hashmap *output_mappings;
++    pa_hashmap *input_mappings;
++    pa_hashmap *profiles;
++};
++
++#define PA_DROID_OUTPUT_PARKING "output-parking"
++#define PA_DROID_INPUT_PARKING "input-parking"
++
++/* Open hardware module */
++/* 'config' can be NULL if it is assumed that hw module with module_id already is open. */
++/* if opening of hw_module succeeds, config ownership is transferred to hw_module and config
++ * shouldn't be freed. */
++pa_droid_hw_module *pa_droid_hw_module_get(pa_core *core, pa_droid_config_audio *config, const char *module_id);
++pa_droid_hw_module *pa_droid_hw_module_ref(pa_droid_hw_module *hw);
++void pa_droid_hw_module_unref(pa_droid_hw_module *hw);
++
++void pa_droid_hw_module_lock(pa_droid_hw_module *hw);
++bool pa_droid_hw_module_try_lock(pa_droid_hw_module *hw);
++void pa_droid_hw_module_unlock(pa_droid_hw_module *hw);
++
++/* Conversion helpers */
++typedef enum {
++    CONV_FROM_PA,
++    CONV_FROM_HAL
++} pa_conversion_field_t;
++
++bool pa_convert_output_channel(uint32_t value, pa_conversion_field_t from, uint32_t *to_value);
++bool pa_convert_input_channel(uint32_t value, pa_conversion_field_t from, uint32_t *to_value);
++bool pa_convert_format(uint32_t value, pa_conversion_field_t from, uint32_t *to_value);
++
++bool pa_string_convert_output_device_num_to_str(audio_devices_t value, const char **to_str);
++bool pa_string_convert_output_device_str_to_num(const char *str, audio_devices_t *to_value);
++bool pa_string_convert_input_device_num_to_str(audio_devices_t value, const char **to_str);
++bool pa_string_convert_input_device_str_to_num(const char *str, audio_devices_t *to_value);
++
++bool pa_string_convert_flag_num_to_str(audio_output_flags_t value, const char **to_str);
++bool pa_string_convert_flag_str_to_num(const char *str, audio_output_flags_t *to_value);
++
++char *pa_list_string_output_device(audio_devices_t devices);
++char *pa_list_string_input_device(audio_devices_t devices);
++char *pa_list_string_flags(audio_output_flags_t flags);
++
++/* Config parser */
++bool pa_parse_droid_audio_config(const char *filename, pa_droid_config_audio *config);
++pa_droid_config_audio *pa_droid_config_load(pa_modargs *ma);
++
++const pa_droid_config_output *pa_droid_config_find_output(const pa_droid_config_hw_module *module, const char *name);
++const pa_droid_config_input *pa_droid_config_find_input(const pa_droid_config_hw_module *module, const char *name);
++const pa_droid_config_hw_module *pa_droid_config_find_module(const pa_droid_config_audio *config, const char* module_id);
++
++
++/* Profiles */
++pa_droid_profile_set *pa_droid_profile_set_new(const pa_droid_config_hw_module *module);
++void pa_droid_profile_set_free(pa_droid_profile_set *ps);
++
++pa_droid_profile *pa_droid_profile_new(pa_droid_profile_set *ps, const pa_droid_config_output *output, const pa_droid_config_input *input);
++void pa_droid_profile_free(pa_droid_profile *p);
++
++pa_droid_mapping *pa_droid_mapping_get(pa_droid_profile_set *ps, pa_direction_t direction, const void *data);
++void pa_droid_mapping_free(pa_droid_mapping *am);
++
++/* Add ports from sinks/sources */
++void pa_droid_add_ports(pa_hashmap *ports, pa_droid_mapping *am, pa_card *card);
++/* Add ports from card */
++void pa_droid_add_card_ports(pa_card_profile *cp, pa_hashmap *ports, pa_droid_mapping *am, pa_core *core);
++
++/* Pretty port names */
++bool pa_droid_output_port_name(audio_devices_t value, const char **to_str);
++bool pa_droid_input_port_name(audio_devices_t value, const char **to_str);
++
++#endif
+Index: pulseaudio/src/modules/droid/module-droid-card.c
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/module-droid-card.c
+@@ -0,0 +1,636 @@
++/*
++ * Copyright (C) 2013 Jolla Ltd.
++ *
++ * Contact: Juho Hämäläinen <juho.hamalainen at tieto.com>
++ *
++ * These PulseAudio Modules are 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
++ * version 2.1 of the License.
++ *
++ * 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 Street, Fifth Floor, Boston, MA 02110-1301
++ * USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <signal.h>
++#include <stdio.h>
++
++#ifdef HAVE_VALGRIND_MEMCHECK_H
++#include <valgrind/memcheck.h>
++#endif
++
++#include <pulse/rtclock.h>
++#include <pulse/timeval.h>
++#include <pulse/volume.h>
++#include <pulse/xmalloc.h>
++
++#include <pulsecore/core.h>
++#include <pulsecore/i18n.h>
++#include <pulsecore/module.h>
++#include <pulsecore/memchunk.h>
++#include <pulsecore/sink.h>
++#include <pulsecore/source.h>
++#include <pulsecore/modargs.h>
++#include <pulsecore/core-rtclock.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/thread-mq.h>
++#include <pulsecore/rtpoll.h>
++#include <pulsecore/time-smoother.h>
++#include <pulsecore/card.h>
++#include <pulsecore/device-port.h>
++#include <pulsecore/idxset.h>
++
++#include <hardware/audio.h>
++#include <system/audio.h>
++
++//#include <droid/hardware/audio_policy.h>
++//#include <droid/system/audio_policy.h>
++
++#include "droid-util.h"
++#include "droid-sink.h"
++#include "droid-source.h"
++#ifdef HAVE_UDEV
++#include "droid-extcon.h"
++#endif
++
++#include "module-droid-card-symdef.h"
++
++PA_MODULE_AUTHOR("Juho Hämäläinen");
++PA_MODULE_DESCRIPTION("Droid card");
++PA_MODULE_VERSION(PACKAGE_VERSION);
++PA_MODULE_USAGE(
++        "card_name=<name for the card> "
++        "sink_name=<name for the sink> "
++        "source_name=<name for the source> "
++        "namereg_fail=<when false attempt to synthesise new names if they are already taken> "
++        "rate=<sample rate> "
++        "output_flags=<flags for sink> "
++        "module_id=<which droid hw module to load, default primary> "
++        "voice_source_routing=<route source ports during voice call, default false> "
++        "deferred_volume=<synchronize software and hardware volume changes to avoid momentary jumps?> "
++        "config=<location for droid audio configuration> "
++        "voice_volume_call_mode=<sink volume controls voice volume during call mode, default false> "
++        "voice_property_key=<proplist key searched for sink-input that should control voice call volume> "
++        "voice_property_value=<proplist value for the key for voice control sink-input> "
++        "voice_virtual_stream=<true/false> create virtual stream for voice call volume control (default false)"
++);
++
++static const char* const valid_modargs[] = {
++    "card_name",
++    "sink_name",
++    "source_name",
++    "namereg_fail",
++    "format",
++    "rate",
++    "output_flags",
++    "module_id",
++    "voice_source_routing",
++    "sink_buffer",
++    "source_buffer",
++    "deferred_volume",
++    "mute_routing_before",
++    "mute_routing_after",
++    "config",
++    "voice_volume_call_mode",
++    "voice_property_key",
++    "voice_property_value",
++    "voice_virtual_stream",
++    NULL,
++};
++
++#define DEFAULT_MODULE_ID "primary"
++#define DEFAULT_AUDIO_POLICY_CONF "/system/etc/audio_policy.conf"
++#define VOICE_CALL_PROFILE_NAME     "voicecall"
++#define VOICE_CALL_PROFILE_DESC     "Call mode"
++#define RINGTONE_PROFILE_NAME       "ringtone"
++#define RINGTONE_PROFILE_DESC       "Ringtone mode"
++#define COMMUNICATION_PROFILE_NAME  "communication"
++#define COMMUNICATION_PROFILE_DESC  "Communication mode"
++
++struct virtual_profile {
++    pa_droid_profile *profile;
++    audio_mode_t mode;
++};
++
++struct userdata {
++    pa_core *core;
++    pa_module *module;
++
++    pa_thread *thread;
++    pa_thread_mq thread_mq;
++    pa_rtpoll *rtpoll;
++
++    pa_droid_profile_set *profile_set;
++
++    pa_droid_hw_module *hw_module;
++    pa_droid_card_data card_data;
++
++    struct virtual_profile call_profile;
++    struct virtual_profile comm_profile;
++    struct virtual_profile ring_profile;
++    pa_droid_profile *old_profile;
++
++#ifdef HAVE_UDEV
++    pa_droid_extcon *extcon;
++#endif
++
++    bool voice_source_routing;
++
++    pa_modargs *modargs;
++    pa_card *card;
++};
++
++struct profile_data {
++    pa_droid_profile *profile;
++};
++
++static void add_disabled_profile(pa_hashmap *profiles) {
++    pa_card_profile *cp;
++    struct profile_data *d;
++
++    cp = pa_card_profile_new("off", _("Off"), sizeof(struct profile_data));
++
++    d = PA_CARD_PROFILE_DATA(cp);
++    d->profile = NULL;
++
++    pa_hashmap_put(profiles, cp->name, cp);
++}
++
++/* Special profile for calls */
++static pa_droid_profile* add_virtual_profile(struct userdata *u, const char *name, const char *description, pa_hashmap *profiles) {
++    pa_droid_profile *ap;
++    pa_card_profile *cp;
++    struct profile_data *d;
++
++    pa_assert(u);
++    pa_assert(u->profile_set);
++
++    pa_log_debug("New virtual profile: %s", name);
++
++    ap = pa_xnew0(pa_droid_profile, 1);
++    ap->profile_set = u->profile_set;
++    ap->name = pa_xstrdup(name);
++    ap->description = pa_xstrdup(description);
++    ap->priority = 50;
++
++    pa_hashmap_put(u->profile_set->profiles, ap->name, ap);
++
++    cp = pa_card_profile_new(ap->name, ap->description, sizeof(struct profile_data));
++    d = PA_CARD_PROFILE_DATA(cp);
++    d->profile = ap;
++
++    pa_hashmap_put(profiles, cp->name, cp);
++
++    return ap;
++}
++
++static void set_parameters_cb(pa_droid_card_data *card_data, const char *str) {
++    struct userdata *u;
++
++    pa_assert(card_data);
++    pa_assert(str);
++
++    u = card_data->userdata;
++
++    if (u) {
++        pa_log_debug("Setting parameters: %s", str);
++        pa_droid_hw_module_lock(u->hw_module);
++        u->hw_module->device->set_parameters(u->hw_module->device, str);
++        pa_droid_hw_module_unlock(u->hw_module);
++    }
++}
++
++static void set_card_name(pa_modargs *ma, pa_card_new_data *data, const char *module_id) {
++    const char *tmp;
++    char *name;
++
++    pa_assert(ma);
++    pa_assert(data);
++    pa_assert(module_id);
++
++    if ((tmp = pa_modargs_get_value(ma, "card_name", NULL))) {
++        pa_card_new_data_set_name(data, tmp);
++        data->namereg_fail = true;
++        return;
++    }
++
++    name = pa_sprintf_malloc("droid_card.%s", module_id);
++    pa_card_new_data_set_name(data, name);
++    pa_xfree(name);
++    data->namereg_fail = false;
++}
++
++static void add_profile(struct userdata *u, pa_hashmap *h, pa_hashmap *ports, pa_droid_profile *ap) {
++    pa_card_profile *cp;
++    struct profile_data *d;
++
++    pa_assert(u);
++    pa_assert(h);
++    pa_assert(ports);
++    pa_assert(ap);
++
++    pa_log_debug("Card profile %s", ap->name);
++
++    cp = pa_card_profile_new(ap->name, ap->description, sizeof(struct profile_data));
++    cp->priority = ap->priority;
++
++    cp->n_sinks = 1;
++    pa_droid_add_card_ports(cp, ports, ap->output, u->core);
++    cp->max_sink_channels = popcount(ap->output->output->channel_masks);
++    if (ap->input) {
++        pa_droid_add_card_ports(cp, ports, ap->input, u->core);
++        cp->n_sources = 1;
++        cp->max_source_channels = popcount(ap->input->input->channel_masks);
++    }
++
++    d = PA_CARD_PROFILE_DATA(cp);
++    d->profile = ap;
++
++    pa_hashmap_put(h, cp->name, cp);
++}
++
++static void add_profiles(struct userdata *u, pa_hashmap *h, pa_hashmap *ports) {
++    void *state;
++    pa_droid_profile *ap;
++
++    pa_assert(u);
++    pa_assert(h);
++    pa_assert(ports);
++
++    PA_HASHMAP_FOREACH(ap, u->profile_set->profiles, state) {
++        add_profile(u, h, ports, ap);
++    }
++}
++
++static void init_profile(struct userdata *u) {
++    pa_droid_mapping *am;
++    struct profile_data *d;
++
++    pa_assert(u);
++
++    pa_log_debug("Init profile.");
++
++    d = PA_CARD_PROFILE_DATA(u->card->active_profile);
++
++    if (d->profile && d->profile->output) {
++        am = d->profile->output;
++        am->sink = pa_droid_sink_new(u->module, u->modargs, __FILE__, &u->card_data, 0, am, u->card);
++    }
++
++    if (d->profile && d->profile->input) {
++        am = d->profile->input;
++        am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, &u->card_data, am, u->card);
++    }
++}
++
++static int set_mode(struct userdata *u, audio_mode_t mode) {
++    int ret;
++    const char *mode_str;
++
++    pa_assert(u);
++    pa_assert(u->hw_module);
++    pa_assert(u->hw_module->device);
++
++    switch (mode) {
++        case AUDIO_MODE_RINGTONE:
++            mode_str = "AUDIO_MODE_RINGTONE";
++            break;
++        case AUDIO_MODE_IN_CALL:
++            mode_str = "AUDIO_MODE_IN_CALL";
++            break;
++        case AUDIO_MODE_IN_COMMUNICATION:
++            mode_str = "AUDIO_MODE_IN_COMMUNICATION";
++            break;
++        default:
++            mode_str = "AUDIO_MODE_NORMAL";
++            break;
++    }
++
++    pa_log_debug("Set mode to %s.", mode_str);
++
++    pa_droid_hw_module_lock(u->hw_module);
++    if ((ret = u->hw_module->device->set_mode(u->hw_module->device, mode)) < 0)
++        pa_log("Failed to set mode.");
++    pa_droid_hw_module_unlock(u->hw_module);
++
++    return ret;
++}
++
++static void park_profile(pa_droid_profile *dp) {
++    pa_assert(dp);
++
++    if (dp->output && dp->output->sink)
++        pa_sink_set_port(dp->output->sink, PA_DROID_OUTPUT_PARKING, false);
++    if (dp->input && dp->input->source)
++        pa_source_set_port(dp->input->source, PA_DROID_INPUT_PARKING, false);
++}
++
++static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
++    struct userdata *u;
++    pa_droid_mapping *am;
++    struct virtual_profile *new_vp = NULL;
++    struct virtual_profile *old_vp = NULL;
++    struct profile_data *nd, *od;
++    pa_queue *sink_inputs = NULL, *source_outputs = NULL;
++
++    pa_assert(c);
++    pa_assert(new_profile);
++    pa_assert_se(u = c->userdata);
++
++    nd = PA_CARD_PROFILE_DATA(new_profile);
++    od = PA_CARD_PROFILE_DATA(c->active_profile);
++
++    if (nd->profile == u->call_profile.profile)
++        new_vp = &u->call_profile;
++    if (nd->profile == u->ring_profile.profile)
++        new_vp = &u->ring_profile;
++    if (nd->profile == u->comm_profile.profile)
++        new_vp = &u->comm_profile;
++
++    if (new_vp) {
++        pa_log_debug("Setting new virtual profile.");
++        if (u->old_profile == NULL)
++            u->old_profile = od->profile;
++
++        park_profile(od->profile);
++
++        set_mode(u, new_vp->mode);
++
++        /* call mode specialities */
++        if (new_vp->profile == u->call_profile.profile) {
++            pa_droid_sink_set_voice_control(u->old_profile->output->sink, true);
++            if (!u->voice_source_routing)
++                pa_droid_source_set_routing(u->old_profile->input->source, false);
++        }
++        return 0;
++    }
++
++    if (od->profile == u->call_profile.profile)
++        old_vp = &u->call_profile;
++    if (od->profile == u->ring_profile.profile)
++        old_vp = &u->ring_profile;
++    if (od->profile == u->comm_profile.profile)
++        old_vp = &u->comm_profile;
++
++    if (old_vp) {
++        pa_assert(u->old_profile);
++
++        park_profile(nd->profile);
++
++        set_mode(u, AUDIO_MODE_NORMAL);
++
++        /* call mode specialities */
++        if (old_vp->profile == u->call_profile.profile) {
++            pa_droid_sink_set_voice_control(u->old_profile->output->sink, false);
++            if (!u->voice_source_routing)
++                pa_droid_source_set_routing(u->old_profile->input->source, true);
++        }
++
++        /* If new profile is the same as from which we switched to
++         * call profile, transfer ownership back to that profile.
++         * Otherwise destroy sinks & sources and switch to new profile. */
++        if (nd->profile == u->old_profile) {
++            u->old_profile = NULL;
++            return 0;
++        } else {
++            od->profile = u->old_profile;
++            u->old_profile = NULL;
++
++            /* Continue to sink-input transfer below */
++        }
++    }
++
++    /* If there are connected sink inputs/source outputs in old profile's sinks/sources move
++     * them all to new sinks/sources. */
++
++    if (od->profile && od->profile->output) {
++        do {
++            am = od->profile->output;
++
++            if (!am->sink)
++                continue;
++
++            if (nd->profile && nd->profile->output && am == nd->profile->output)
++                continue;
++
++            sink_inputs = pa_sink_move_all_start(am->sink, sink_inputs);
++            pa_droid_sink_free(am->sink);
++            am->sink = NULL;
++        } while(0);
++    }
++
++    if (od->profile && od->profile->input) {
++        do {
++            am = od->profile->input;
++
++            if (!am->source)
++                continue;
++
++            if (nd->profile && nd->profile->input && am == nd->profile->input)
++                continue;
++
++            source_outputs = pa_source_move_all_start(am->source, source_outputs);
++            pa_droid_source_free(am->source);
++            am->source = NULL;
++        } while(0);
++    }
++
++    if (nd->profile && nd->profile->output) {
++        am = nd->profile->output;
++
++        if (!am->sink)
++            am->sink = pa_droid_sink_new(u->module, u->modargs, __FILE__, &u->card_data, 0, am, u->card);
++
++        if (sink_inputs && am->sink) {
++            pa_sink_move_all_finish(am->sink, sink_inputs, false);
++            sink_inputs = NULL;
++        }
++    }
++
++    if (nd->profile && nd->profile->input) {
++        am = nd->profile->input;
++
++        if (!am->source)
++            am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, &u->card_data, am, u->card);
++
++        if (source_outputs && am->source) {
++            pa_source_move_all_finish(am->source, source_outputs, false);
++            source_outputs = NULL;
++        }
++    }
++
++    if (sink_inputs)
++        pa_sink_move_all_fail(sink_inputs);
++
++    if (source_outputs)
++        pa_source_move_all_fail(source_outputs);
++
++    return 0;
++}
++
++
++int pa__init(pa_module *m) {
++    pa_modargs *ma = NULL;
++    pa_card_new_data data;
++    pa_droid_config_audio *config = NULL;
++    const char *module_id;
++    bool namereg_fail = false;
++    bool voice_source_routing = false;
++
++    pa_assert(m);
++
++    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
++        pa_log("Failed to parse module argumets.");
++        goto fail;
++    }
++
++    struct userdata *u = pa_xnew0(struct userdata, 1);
++    u->core = m->core;
++
++    if (!(config = pa_droid_config_load(ma)))
++        goto fail;
++
++    if (pa_modargs_get_value_boolean(ma, "voice_source_routing", &voice_source_routing) < 0) {
++        pa_log("Failed to parse voice_source_routing argument.");
++        goto fail;
++    }
++    u->voice_source_routing = voice_source_routing;
++
++    module_id = pa_modargs_get_value(ma, "module_id", DEFAULT_MODULE_ID);
++
++    /* Ownership of config transfers to hw_module if opening of hw module succeeds. */
++    if (!(u->hw_module = pa_droid_hw_module_get(u->core, config, module_id)))
++        goto fail;
++
++    u->card_data.set_parameters = set_parameters_cb;
++    u->card_data.module_id = pa_xstrdup(module_id);
++    u->card_data.userdata = u;
++
++    u->profile_set = pa_droid_profile_set_new(u->hw_module->enabled_module);
++
++    pa_card_new_data_init(&data);
++    data.driver = __FILE__;
++    data.module = m;
++
++    set_card_name(ma, &data, u->hw_module->module_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;
++
++    add_profiles(u, data.profiles, data.ports);
++
++    if (pa_hashmap_isempty(data.profiles)) {
++        pa_log("Failed to find a working profile.");
++        pa_card_new_data_done(&data);
++        goto fail;
++    }
++
++    u->call_profile.profile = add_virtual_profile(u, VOICE_CALL_PROFILE_NAME,
++                                                  VOICE_CALL_PROFILE_DESC, data.profiles);
++    u->call_profile.mode = AUDIO_MODE_IN_CALL;
++    u->comm_profile.profile = add_virtual_profile(u, COMMUNICATION_PROFILE_NAME,
++                                                  COMMUNICATION_PROFILE_DESC, data.profiles);
++    u->comm_profile.mode = AUDIO_MODE_IN_COMMUNICATION;
++    u->ring_profile.profile = add_virtual_profile(u, RINGTONE_PROFILE_NAME,
++                                                  RINGTONE_PROFILE_DESC, data.profiles);
++    u->ring_profile.mode = AUDIO_MODE_RINGTONE;
++
++    add_disabled_profile(data.profiles);
++
++    pa_proplist_sets(data.proplist, PROP_DROID_HW_MODULE, u->hw_module->module_id);
++
++    u->card = pa_card_new(m->core, &data);
++    pa_card_new_data_done(&data);
++
++    if (!u->card) {
++        pa_log("Couldn't create card.");
++        goto fail;
++    }
++
++    u->card->userdata = u;
++    u->card->set_profile = card_set_profile;
++
++    u->modargs = ma;
++    u->module = m;
++
++    m->userdata = u;
++
++    init_profile(u);
++
++#ifdef HAVE_UDEV
++    u->extcon = pa_droid_extcon_new(m->core, u->card);
++#endif
++
++    return 0;
++
++fail:
++    if (ma)
++        pa_modargs_free(ma);
++
++    pa_xfree(config);
++
++    pa__done(m);
++
++    return -1;
++}
++
++void pa__done(pa_module *m) {
++    struct userdata *u;
++
++    pa_assert(m);
++
++    if ((u = m->userdata)) {
++
++        if (u->card && u->card->sinks)
++            pa_idxset_remove_all(u->card->sinks, (pa_free_cb_t) pa_droid_sink_free);
++
++        if (u->card && u->card->sources)
++            pa_idxset_remove_all(u->card->sources, (pa_free_cb_t) pa_droid_source_free);
++
++#ifdef HAVE_UDEV
++        if (u->extcon)
++            pa_droid_extcon_free(u->extcon);
++#endif
++
++        if (u->card)
++            pa_card_free(u->card);
++
++        if (u->modargs)
++            pa_modargs_free(u->modargs);
++
++        if (u->profile_set)
++            pa_droid_profile_set_free(u->profile_set);
++
++        if (u->card_data.module_id)
++            pa_xfree(u->card_data.module_id);
++
++        if (u->hw_module)
++            pa_droid_hw_module_unref(u->hw_module);
++
++        pa_xfree(u);
++    }
++}
+Index: pulseaudio/src/modules/droid/module-droid-sink.c
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/module-droid-sink.c
+@@ -0,0 +1,103 @@
++/*
++ * Copyright (C) 2013 Jolla Ltd.
++ *
++ * Contact: Juho Hämäläinen <juho.hamalainen at tieto.com>
++ *
++ * These PulseAudio Modules are 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
++ * version 2.1 of the License.
++ *
++ * 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 Street, Fifth Floor, Boston, MA 02110-1301
++ * USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#ifdef HAVE_VALGRIND_MEMCHECK_H
++#include <valgrind/memcheck.h>
++#endif
++
++#include <pulse/xmalloc.h>
++
++#include <pulsecore/core.h>
++#include <pulsecore/i18n.h>
++#include <pulsecore/module.h>
++#include <pulsecore/sink.h>
++#include <pulsecore/modargs.h>
++#include <pulsecore/log.h>
++#include <pulsecore/macro.h>
++
++#include "droid-util.h"
++#include "droid-sink.h"
++
++#include "module-droid-sink-symdef.h"
++
++PA_MODULE_AUTHOR("Juho Hämäläinen");
++PA_MODULE_DESCRIPTION("Droid sink");
++PA_MODULE_USAGE("master_sink=<sink to connect to> "
++                "sink_name=<name of created sink> "
++                "sco_fake_sink=<name of the fake sco sink used for hsp>");
++PA_MODULE_VERSION(PACKAGE_VERSION);
++
++static const char* const valid_modargs[] = {
++    "rate",
++    "flags",
++    "devices",
++    "sink_name",
++    "module_id",
++    "mute_routing_before",
++    "mute_routing_after",
++    "sink_buffer",
++    "deferred_volume",
++    "voice_volume_call_mode",
++    "voice_property_key",
++    "voice_property_value",
++    "voice_virtual_stream",
++    "sco_fake_sink",
++    NULL,
++};
++
++void pa__done(pa_module *m) {
++    pa_sink *sink;
++
++    pa_assert(m);
++
++    if ((sink = m->userdata))
++        pa_droid_sink_free(sink);
++}
++
++int pa__init(pa_module *m) {
++    pa_modargs *ma = NULL;
++
++    pa_assert(m);
++
++    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
++        pa_log("Failed to parse module argumets.");
++        goto fail;
++    }
++
++    if (!(m->userdata = pa_droid_sink_new(m, ma, __FILE__, NULL, 0, NULL, NULL)))
++        goto fail;
++
++    pa_modargs_free(ma);
++
++    return 0;
++
++fail:
++    if (ma)
++        pa_modargs_free(ma);
++
++    pa__done(m);
++
++    return -1;
++}
+Index: pulseaudio/src/modules/droid/module-droid-source.c
+===================================================================
+--- /dev/null
++++ pulseaudio/src/modules/droid/module-droid-source.c
+@@ -0,0 +1,95 @@
++/*
++ * Copyright (C) 2013 Jolla Ltd.
++ *
++ * Contact: Juho Hämäläinen <juho.hamalainen at tieto.com>
++ *
++ * These PulseAudio Modules are 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
++ * version 2.1 of the License.
++ *
++ * 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 Street, Fifth Floor, Boston, MA 02110-1301
++ * USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#ifdef HAVE_VALGRIND_MEMCHECK_H
++#include <valgrind/memcheck.h>
++#endif
++
++#include <pulse/xmalloc.h>
++
++#include <pulsecore/core.h>
++#include <pulsecore/i18n.h>
++#include <pulsecore/module.h>
++#include <pulsecore/source.h>
++#include <pulsecore/modargs.h>
++#include <pulsecore/log.h>
++#include <pulsecore/macro.h>
++
++#include "droid-util.h"
++#include "droid-source.h"
++
++#include "module-droid-source-symdef.h"
++
++PA_MODULE_AUTHOR("Juho Hämäläinen");
++PA_MODULE_DESCRIPTION("Droid source");
++PA_MODULE_USAGE("master_source=<source to connect to> "
++                "source_name=<name of created source>");
++PA_MODULE_VERSION(PACKAGE_VERSION);
++
++static const char* const valid_modargs[] = {
++    "rate",
++    "flags",
++    "devices",
++    "source_name",
++    "module_id",
++    "source_buffer",
++    "deferred_volume",
++    NULL,
++};
++
++void pa__done(pa_module *m) {
++    pa_source *source;
++
++    pa_assert(m);
++
++    if ((source = m->userdata))
++        pa_droid_source_free(source);
++}
++
++int pa__init(pa_module *m) {
++    pa_modargs *ma = NULL;
++
++    pa_assert(m);
++
++    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
++        pa_log("Failed to parse module argumets.");
++        goto fail;
++    }
++
++    if (!(m->userdata = pa_droid_source_new(m, ma, __FILE__, NULL, NULL, NULL)))
++        goto fail;
++
++    pa_modargs_free(ma);
++
++    return 0;
++
++fail:
++    if (ma)
++        pa_modargs_free(ma);
++
++    pa__done(m);
++
++    return -1;
++}
+Index: pulseaudio/po/POTFILES.in
+===================================================================
+--- pulseaudio.orig/po/POTFILES.in
++++ pulseaudio/po/POTFILES.in
+@@ -16,6 +16,7 @@ src/modules/alsa/module-alsa-sink.c
+ src/modules/alsa/module-alsa-source.c
+ src/modules/bluetooth/module-bluez4-device.c
+ src/modules/bluetooth/module-bluez5-device.c
++src/modules/droid/module-droid-card.c
+ src/modules/echo-cancel/module-echo-cancel.c
+ src/modules/gconf/gconf-helper.c
+ src/modules/gconf/module-gconf.c
diff --git a/debian/patches/0208-module-bluetooth-device-Allow-leaving-transport-runn.patch b/debian/patches/0208-module-bluetooth-device-Allow-leaving-transport-runn.patch
new file mode 100644
index 0000000..7d21968
--- /dev/null
+++ b/debian/patches/0208-module-bluetooth-device-Allow-leaving-transport-runn.patch
@@ -0,0 +1,220 @@
+From: Ricardo Salveti de Araujo <rsalveti at rsalveti.net>
+Date: Thu, 17 Jul 2014 19:34:44 -0300
+Subject: [PATCH] module-bluez4-device: Allow leaving transport running
+ while sink and source are suspended.
+
+There are some cases where keeping the SCO transport running even when
+SCO sink and source are suspended is needed. This patch allows keeping
+the transport running when SCO sink has property
+bluetooth.hsp.prevent.suspend.transport set as true.
+
+Patch done by Juho Hamalainen <juho.hamalainen at tieto.com>
+
+Corner-case specific patch (pulse droid), not upstreamable.
+
+Signed-off-by: Ricardo Salveti de Araujo <rsalveti at rsalveti.net>
+---
+ src/modules/bluetooth/bluez4-util.c          | 23 +++++++
+ src/modules/bluetooth/module-bluez4-device.c | 85 ++++++++++++++++++++++++-
+ 2 files changed, 106 insertions(+), 2 deletions(-)
+
+Index: pulseaudio/src/modules/bluetooth/bluez4-util.c
+===================================================================
+--- pulseaudio.orig/src/modules/bluetooth/bluez4-util.c
++++ pulseaudio/src/modules/bluetooth/bluez4-util.c
+@@ -28,6 +28,7 @@
+ #include <pulsecore/core-util.h>
+ #include <pulsecore/shared.h>
+ #include <pulsecore/dbus-shared.h>
++#include <pulse/rtclock.h>
+ 
+ #include "bluez4-util.h"
+ #include "a2dp-codecs.h"
+@@ -61,6 +62,8 @@
+     " </interface>"                                                     \
+     "</node>"
+ 
++#define RACE_CONDITION_TIME 1000000  // 1 second
++
+ struct pa_bluez4_discovery {
+     PA_REFCNT_DECLARE;
+ 
+@@ -506,6 +509,9 @@ static int parse_audio_property(pa_bluez
+     DBusMessageIter variant_i;
+     bool is_audio_interface;
+     pa_bluez4_profile_t p = PA_BLUEZ4_PROFILE_OFF;
++    pa_usec_t tstamp_now;
++    static pa_usec_t tstamp_prev = 0;
++    DBusMessage *m;
+ 
+     pa_assert(d);
+     pa_assert(interface);
+@@ -537,6 +543,23 @@ static int parse_audio_property(pa_bluez
+                 pa_bluez4_transport_state_t old_state;
+ 
+                 pa_log_debug("Device %s interface %s property 'State' changed to value '%s'", d->path, interface, value);
++                /* Device may change state again (e.g. suspend itself) before previous state change
++                 * message has been parsed here. When this take place sink state in here and bluez
++                 * will be out-of-sync. This may generate endless transport acquire/release loop
++                 * which will be sustained by this module. When we notice this to be ongoing
++                 * message is ignored and current state is queried with GetProperties. */
++                if (pa_streq(interface, "org.bluez.AudioSink") && state == PA_BLUEZ4_AUDIO_STATE_CONNECTED) {
++                   tstamp_now = pa_rtclock_now();
++                   if (tstamp_prev != 0 && tstamp_now - tstamp_prev < RACE_CONDITION_TIME) {
++                       pa_log_debug("Race condition. Message ignored.");
++                       tstamp_prev = 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);
++
++                       return 0;
++                   }
++                   tstamp_prev = tstamp_now;
++                }
+ 
+                 if (state == PA_BLUEZ4_AUDIO_STATE_INVALID)
+                     return -1;
+Index: pulseaudio/src/modules/bluetooth/module-bluez4-device.c
+===================================================================
+--- pulseaudio.orig/src/modules/bluetooth/module-bluez4-device.c
++++ pulseaudio/src/modules/bluetooth/module-bluez4-device.c
+@@ -189,6 +189,9 @@ struct userdata {
+     pa_modargs *modargs;
+ 
+     int stream_write_type;
++
++    pa_hook_slot *sco_sink_proplist_changed_slot;
++    bool prevent_suspend_transport;
+ };
+ 
+ enum {
+@@ -382,6 +385,67 @@ static int bt_transport_acquire(struct u
+     return 0;
+ }
+ 
++#define HSP_PREVENT_SUSPEND_STR "bluetooth.hsp.prevent.suspend.transport"
++
++/* Check and update prevent_suspend_transport value from sco sink proplist.
++ *
++ * Return < 0 if sink proplist doesn't contain HSP_PREVENT_SUSPEND_STR value,
++ * 1 if value is 'true'
++ * 0 if value is something else. */
++static int check_proplist(struct userdata *u) {
++    int ret;
++    const char *str;
++
++    pa_assert(u);
++    pa_assert(u->hsp.sco_sink);
++
++    if ((str = pa_proplist_gets(u->hsp.sco_sink->proplist, HSP_PREVENT_SUSPEND_STR))) {
++        if (pa_streq(str, "true"))
++            ret = 1;
++        else
++            ret = 0;
++    } else
++        ret = -1;
++
++    u->prevent_suspend_transport = ret == 1;
++
++    pa_log_debug("Set %s %s", HSP_PREVENT_SUSPEND_STR, u->prevent_suspend_transport ? "true" : "false");
++
++    return ret;
++}
++
++/* There are cases where keeping the transport running even when sco sink and source are suspended
++ * is needed.
++ * To work with these cases, check sco.sink for bluetooth.hsp.prevent.suspend.transport value, and
++ * when set to true prevent closing the transport when sink suspends.
++ * Also, if the sink&source are suspended when sco-sink suspend.transport value changes to true,
++ * bring sco transport up. When suspend.transport value changes to false while sink&source are suspended,
++ * tear down the transport. */
++static pa_hook_result_t update_allow_release_cb(pa_core *c, pa_sink *s, struct userdata *u) {
++    pa_assert(u);
++    pa_assert(s);
++
++    if (!u->hsp.sco_sink || u->hsp.sco_sink != s)
++        return PA_HOOK_OK;
++
++    if (check_proplist(u) < 0)
++        return PA_HOOK_OK;
++
++    if (!USE_SCO_OVER_PCM(u)) {
++        pa_log_debug("SCO sink not available.");
++        return PA_HOOK_OK;
++    }
++
++    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))) {
++
++        /* Clear all suspend bits, effectively resuming SCO sink for a while. */
++        pa_sink_suspend(s, false, PA_SUSPEND_ALL);
++    }
++
++    return PA_HOOK_OK;
++}
++
+ /* 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;
+@@ -1423,6 +1487,10 @@ static int sco_over_pcm_state_update(str
+         if (u->stream_fd < 0)
+             return 0;
+ 
++        if (check_proplist(u) == 1) {
++            pa_log_debug("Suspend prevention active, not closing SCO over PCM");
++            return 0;
++        }
+         pa_log_debug("Closing SCO over PCM");
+ 
+         bt_transport_release(u);
+@@ -1466,6 +1534,11 @@ static pa_hook_result_t transport_nrec_c
+     if (t != u->transport)
+         return PA_HOOK_OK;
+ 
++    if (!u->source) {
++        pa_log_warn("trying to change bluetooth source property, but source doesn't exist.");
++        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);
+@@ -1828,7 +1901,7 @@ static int setup_transport(struct userda
+     pa_bluez4_transport *t;
+ 
+     pa_assert(u);
+-    pa_assert(!u->transport);
++    pa_assert(!u->transport_acquired);
+     pa_assert(u->profile != PA_BLUEZ4_PROFILE_OFF);
+ 
+     /* check if profile has a transport */
+@@ -1908,7 +1981,8 @@ static void stop_thread(struct userdata
+ 
+     if (u->transport) {
+         bt_transport_release(u);
+-        u->transport = NULL;
++        /* Do not set transport pointer to NULL. When failing to switch
++         * profile NULL u->transport would assert. */
+     }
+ 
+     if (u->sink) {
+@@ -2513,6 +2587,10 @@ int pa__init(pa_module *m) {
+         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);
+ 
++    u->sco_sink_proplist_changed_slot =
++        pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED],
++                        PA_HOOK_NORMAL, (pa_hook_cb_t) update_allow_release_cb, u);
++
+     /* Add the card structure. This will also initialize the default profile */
+     if (add_card(u) < 0)
+         goto fail;
+@@ -2592,6 +2670,9 @@ void pa__done(pa_module *m) {
+     if (u->transport_speaker_changed_slot)
+         pa_hook_slot_free(u->transport_speaker_changed_slot);
+ 
++    if (u->sco_sink_proplist_changed_slot)
++        pa_hook_slot_free(u->sco_sink_proplist_changed_slot);
++
+     if (USE_SCO_OVER_PCM(u))
+         restore_sco_volume_callbacks(u);
+ 
diff --git a/debian/patches/0209-module-switch-on-connect-adding-parameter-to-allow-s.patch b/debian/patches/0209-module-switch-on-connect-adding-parameter-to-allow-s.patch
new file mode 100644
index 0000000..c2c3776
--- /dev/null
+++ b/debian/patches/0209-module-switch-on-connect-adding-parameter-to-allow-s.patch
@@ -0,0 +1,88 @@
+From: Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>
+Date: Sun, 20 Jul 2014 01:27:09 -0300
+Subject: [PATCH] module-switch-on-connect: adding parameter to allow
+ skipping abstract devices
+
+Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti at canonical.com>
+---
+ src/modules/module-switch-on-connect.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+Index: pulseaudio/src/modules/module-switch-on-connect.c
+===================================================================
+--- pulseaudio.orig/src/modules/module-switch-on-connect.c
++++ pulseaudio/src/modules/module-switch-on-connect.c
+@@ -41,6 +41,8 @@ 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);
++PA_MODULE_USAGE(
++        "skip_abstract=<yes or no>");
+ 
+ static const char* const valid_modargs[] = {
+     NULL,
+@@ -50,13 +52,15 @@ struct userdata {
+     pa_hook_slot
+         *sink_put_slot,
+         *source_put_slot;
++    bool skip_abstract;
+ };
+ 
+ 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;
++    const char *s, *class;
++    struct userdata *u = userdata;
+ 
+     pa_assert(c);
+     pa_assert(sink);
+@@ -73,6 +77,12 @@ static pa_hook_result_t sink_put_hook_ca
+             return PA_HOOK_OK;
+     }
+ 
++    /* Check if we want or to skip abstract devices (e.g. null) */
++    if ((class = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_CLASS))) {
++        if (pa_streq(class, "abstract") && (u->skip_abstract))
++            return PA_HOOK_OK;
++    }
++
+     def = pa_namereg_get_default_sink(c);
+     if (def == sink)
+         return PA_HOOK_OK;
+@@ -105,7 +115,8 @@ static pa_hook_result_t source_put_hook_
+     pa_source_output *o;
+     uint32_t idx;
+     pa_source *def;
+-    const char *s;
++    const char *s, *class;
++    struct userdata *u = userdata;
+ 
+     pa_assert(c);
+     pa_assert(source);
+@@ -126,6 +137,12 @@ static pa_hook_result_t source_put_hook_
+             return PA_HOOK_OK;
+     }
+ 
++    /* Check if we want or to skip abstract devices (e.g. null) */
++    if ((class = pa_proplist_gets(source->proplist, PA_PROP_DEVICE_CLASS))) {
++        if (pa_streq(class, "abstract") && (u->skip_abstract))
++            return PA_HOOK_OK;
++    }
++
+     def = pa_namereg_get_default_source(c);
+     if (def == source)
+         return PA_HOOK_OK;
+@@ -167,6 +184,11 @@ int pa__init(pa_module*m) {
+ 
+     m->userdata = u = pa_xnew(struct userdata, 1);
+ 
++    if (pa_modargs_get_value_boolean(ma, "skip_abstract", &u->skip_abstract) < 0) {
++        pa_log_error("skip_abstract= expects a boolean argument, assuming false by default");
++        u->skip_abstract = false;
++    }
++
+     /* 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);
diff --git a/debian/patches/0210-module-device-restore-adding-property-to-skip.patch b/debian/patches/0210-module-device-restore-adding-property-to-skip.patch
new file mode 100644
index 0000000..04830ed
--- /dev/null
+++ b/debian/patches/0210-module-device-restore-adding-property-to-skip.patch
@@ -0,0 +1,70 @@
+From: Ricardo Salveti de Araujo <rsalveti at rsalveti.net>
+Date: Fri, 15 Aug 2014 02:15:16 -0300
+Subject: [PATCH] module-device-restore: adding property to skip store/restore
+
+Useful when the user wants to control the volume/port/mute without
+storing/restoring the values, at least temporarily (until the property
+gets unset).
+
+Signed-off-by: Ricardo Salveti de Araujo <rsalveti at rsalveti.net>
+
+Index: pulseaudio/src/modules/module-device-restore.c
+===================================================================
+--- pulseaudio.orig/src/modules/module-device-restore.c
++++ pulseaudio/src/modules/module-device-restore.c
+@@ -53,6 +53,7 @@
+ #include <pulsecore/pstream-util.h>
+ #include <pulsecore/database.h>
+ #include <pulsecore/tagstruct.h>
++#include <pulsecore/proplist-util.h>
+ 
+ #include "module-device-restore-symdef.h"
+ 
+@@ -67,6 +68,7 @@ PA_MODULE_USAGE(
+         "restore_formats=<Save/restore saved formats?>");
+ 
+ #define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
++#define MODULE_DEVICE_RESTORE_SKIP_PROPERTY "module-device-restore.skip"
+ 
+ static const char* const valid_modargs[] = {
+     "restore_volume",
+@@ -611,6 +613,9 @@ static void subscribe_callback(pa_core *
+         if (!(sink = pa_idxset_get_by_index(c->sinks, idx)))
+             return;
+ 
++        if (pa_proplist_gets(sink->proplist, MODULE_DEVICE_RESTORE_SKIP_PROPERTY))
++            return;
++
+         type = PA_DEVICE_TYPE_SINK;
+         name = pa_sprintf_malloc("sink:%s", sink->name);
+         if (sink->active_port)
+@@ -650,6 +655,9 @@ static void subscribe_callback(pa_core *
+         if (!(source = pa_idxset_get_by_index(c->sources, idx)))
+             return;
+ 
++        if (pa_proplist_gets(source->proplist, MODULE_DEVICE_RESTORE_SKIP_PROPERTY))
++            return;
++
+         type = PA_DEVICE_TYPE_SOURCE;
+         name = pa_sprintf_malloc("source:%s", source->name);
+         if (source->active_port)
+@@ -815,6 +823,9 @@ static pa_hook_result_t sink_port_hook_c
+     pa_assert(u);
+     pa_assert(u->restore_volume || u->restore_muted);
+ 
++    if (pa_proplist_gets(sink->proplist, MODULE_DEVICE_RESTORE_SKIP_PROPERTY))
++        return PA_HOOK_OK;
++
+     name = pa_sprintf_malloc("sink:%s", sink->name);
+ 
+     if ((e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL)))) {
+@@ -956,6 +967,9 @@ static pa_hook_result_t source_port_hook
+     pa_assert(u);
+     pa_assert(u->restore_volume || u->restore_muted);
+ 
++    if (pa_proplist_gets(source->proplist, MODULE_DEVICE_RESTORE_SKIP_PROPERTY))
++        return PA_HOOK_OK;
++
+     name = pa_sprintf_malloc("source:%s", source->name);
+ 
+     if ((e = perportentry_read(u, name, (source->active_port ? source->active_port->name : NULL)))) {
diff --git a/debian/patches/0212-libpulse.vapi-adding-missing-fields-for-sink_input-s.patch b/debian/patches/0212-libpulse.vapi-adding-missing-fields-for-sink_input-s.patch
new file mode 100644
index 0000000..82a45e9
--- /dev/null
+++ b/debian/patches/0212-libpulse.vapi-adding-missing-fields-for-sink_input-s.patch
@@ -0,0 +1,38 @@
+From 5c0bea7f5a0a649d86262d9dc8d81b69ad614cb4 Mon Sep 17 00:00:00 2001
+From: Ricardo Salveti de Araujo <rsalveti at rsalveti.net>
+Date: Wed, 17 Sep 2014 01:07:58 -0300
+Subject: [PATCH] libpulse.vapi: adding missing fields for
+ sink_input/source_output info struct
+
+Upstream: http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-October/021885.html
+Signed-off-by: Ricardo Salveti de Araujo <rsalveti at rsalveti.net>
+---
+ vala/libpulse.vapi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+Index: pulseaudio/vala/libpulse.vapi
+===================================================================
+--- pulseaudio.orig/vala/libpulse.vapi
++++ pulseaudio/vala/libpulse.vapi
+@@ -1376,6 +1376,9 @@ namespace PulseAudio {
+                 public string driver;
+                 public int mute;
+                 public Proplist proplist;
++                public int corked;
++                public int has_volume;
++                public int volume_writable;
+         }
+ 
+         [CCode (cname="pa_source_output_info", has_type_id=false)]
+@@ -1392,6 +1395,11 @@ namespace PulseAudio {
+                 public string resample_method;
+                 public string driver;
+                 public Proplist proplist;
++                public int corked;
++                public CVolume volume;
++                public int mute;
++                public int has_volume;
++                public int volume_writable;
+         }
+ 
+         [CCode (cname="pa_stat_info", has_type_id=false)]
diff --git a/debian/patches/series b/debian/patches/series
index 97b3013..2ce2eba 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,4 @@
+# Debian patches
 0001-raop-Don-t-use-incompatible-default-sample-spec-para.patch
 0002-Use-the-fixed-point-speex-resampler-on-ARM.patch
 0003-exit-with-X-session.patch
@@ -15,3 +16,22 @@ util-Fix-pa_get_binary_name-on-Debian-kFreeBSD.patch
 misc-cleanups-and-bug-fixes.patch
 util-Try-finding-out-application-name-using-dladdr.patch
 broken-PA_FLOAT32_SWAP.patch
+
+# Ubuntu/Debian specific config/fixes
+0005-dont-load-cork-music-on-phone.patch
+0006-load-module-x11-bell.patch
+0016-nodisplay-autostart.patch
+#0020-stream-Return-error-in-case-a-client-peeks-to-early.patch
+0022-inotify-wrapper-Quit-daemon-if-pid-file-is-removed.patch
+0023-fixing_snd_mixer_poll_descriptors_count_when_zero.patch
+0024-daemon-conf.c-changing-default-rlimit_rttime-value-t.patch
+
+# Ubuntu touch stuff
+0202-dont-probe-ucm.patch
+0203-card-Add-hook-before-profile-changes.patch
+0206-module-bluetooth-discover-adding-module-option-profi.patch
+0207-Enable-pulseaudio-droid.patch
+0208-module-bluetooth-device-Allow-leaving-transport-runn.patch
+0209-module-switch-on-connect-adding-parameter-to-allow-s.patch
+0210-module-device-restore-adding-property-to-skip.patch
+0212-libpulse.vapi-adding-missing-fields-for-sink_input-s.patch
diff --git a/debian/pulseaudio-module-droid.install b/debian/pulseaudio-module-droid.install
new file mode 100644
index 0000000..1ccb2d6
--- /dev/null
+++ b/debian/pulseaudio-module-droid.install
@@ -0,0 +1,6 @@
+usr/lib/pulse-*/modules/libdroid-util.so
+usr/lib/pulse-*/modules/libdroid-sink.so
+usr/lib/pulse-*/modules/libdroid-source.so
+usr/lib/pulse-*/modules/module-droid-sink.so
+usr/lib/pulse-*/modules/module-droid-source.so
+usr/lib/pulse-*/modules/module-droid-card.so
diff --git a/debian/pulseaudio.install b/debian/pulseaudio.install
index 67a86b0..fe50bb2 100644
--- a/debian/pulseaudio.install
+++ b/debian/pulseaudio.install
@@ -14,11 +14,9 @@ usr/lib/pulse-*/modules/libprotocol-http.so
 usr/lib/pulse-*/modules/libprotocol-native.so
 usr/lib/pulse-*/modules/libprotocol-simple.so
 usr/lib/pulse-*/modules/librtp.so
-usr/lib/pulse-*/modules/libwebrtc-util.so
 usr/lib/pulse-*/modules/module-alsa-sink.so
 usr/lib/pulse-*/modules/module-alsa-source.so
 usr/lib/pulse-*/modules/module-always-sink.so
-usr/lib/pulse-*/modules/module-console-kit.so
 usr/lib/pulse-*/modules/module-device-restore.so
 usr/lib/pulse-*/modules/module-echo-cancel.so
 usr/lib/pulse-*/modules/module-stream-restore.so
diff --git a/debian/pulseaudio.upstart.example b/debian/pulseaudio.upstart.example
new file mode 100644
index 0000000..27ecac4
--- /dev/null
+++ b/debian/pulseaudio.upstart.example
@@ -0,0 +1,48 @@
+# System PulseAudio service
+
+description	"System PulseAudio sound server"
+author		"Pali Rohár <pali.rohar at gmail.com>"
+
+# uncomment the 'start on' to start pulseaudio in system mode
+# (enables the pulseaudio init script - requires that users be in the
+# pulse-access group)
+# System mode is not the recommended way to run PulseAudio as it has some
+# limitations (such as no shared memory access) and could potentially allow
+# users to disconnect or redirect each others' audio streams. The
+# recommended way to run PulseAudio is as a per-session daemon. For GNOME/KDE/
+# Xfce sessions in Ubuntu Lucid/10.04, /etc/xdg/autostart/pulseaudio.desktop
+# handles this function of automatically starting PulseAudio on login, and for
+# it to work correctly your user must *not* have "autospawn = no" set in
+# ~/.pulse/client.conf (or in /etc/pulse/client.conf). By default, autospawn
+# is enabled. For other sessions, you can simply start PulseAudio with
+# "pulseaudio --daemonize".
+
+#start on runlevel [2345]
+stop on runlevel [016]
+
+expect daemon
+respawn
+
+# Prevent users from dynamically loading modules into the PulseAudio sound
+# server. Dynamic module loading enhances the flexibility of the PulseAudio
+# system, but may pose a security risk.
+# 0 = no, 1 = yes
+env DISALLOW_MODULE_LOADING=1
+
+# extra arguments to pass to the daemon
+env PULSEAUDIO_ARGS=
+
+pre-start exec install -d -m755 -o pulse -g pulse /run/pulse
+
+exec /usr/bin/pulseaudio --system --daemonize --high-priority --log-target=syslog --disallow-exit --disallow-module-loading=$DISALLOW_MODULE_LOADING $PULSEAUDIO_ARGS
+
+post-start script
+	if [ -e /var/run/pulse/.esd_auth ]; then
+		chown pulse:pulse-access /var/run/pulse/.esd_auth
+		chmod 640 /var/run/pulse/.esd_auth
+	fi
+	if [ -e /var/run/pulse/.pulse-cookie ]; then
+		chown pulse:pulse-access /var/run/pulse/.pulse-cookie
+		chmod 640 /var/run/pulse/.pulse-cookie
+	fi
+end script
diff --git a/debian/rules b/debian/rules
index 9e72ac7..93b85bf 100755
--- a/debian/rules
+++ b/debian/rules
@@ -25,6 +25,7 @@ common-build-arch::
 	  debian/pulseaudio.install >  debian/pulseaudio.install.kfreebsd-amd64
 	grep -v -e alsa -e evdev -e udev -e share/pulseaudio -e systemd \
 	  debian/pulseaudio.install > debian/pulseaudio.install.hurd-i386
+	dh_translations
 
 common-install-arch::
 	find $(DEB_DESTDIR) -name "*.la" -delete
@@ -47,6 +48,19 @@ clean::
 	rm -f debian/pulseaudio.install.kfreebsd-i386
 	rm -f debian/pulseaudio.install.kfreebsd-amd64
 	rm -f debian/pulseaudio.install.hurd-i386
+	rm -f debian/stamp-post-patches
+	if test -f $(CURDIR)/debian/daemon.conf.in; then \
+	   mv $(CURDIR)/debian/daemon.conf.in $(CURDIR)/src/daemon/daemon.conf.in; \
+	fi
+
+-post-patches:: debian/stamp-post-patches
+
+debian/stamp-post-patches:
+	cp $(CURDIR)/src/daemon/daemon.conf.in $(CURDIR)/debian/daemon.conf.in
+	sed -e 's/; deferred-volume-safety-margin-usec = 8000/deferred-volume-safety-margin-usec = 1/' \
+	    -e 's/; flat-volumes = yes/flat-volumes = no/' \
+	    $(CURDIR)/src/daemon/daemon.conf.in
+	touch debian/stamp-post-patches
 
 # Libs should be in the multi-arch path, but the modules should be in the
 # normal directory as pulseaudio is foreign
diff --git a/debian/tests/build b/debian/tests/build
new file mode 100755
index 0000000..342ad34
--- /dev/null
+++ b/debian/tests/build
@@ -0,0 +1,30 @@
+#!/bin/sh
+# autopkgtest check: Build and run a program against pulseaudio, to verify that the
+# headers and pkg-config file are installed correctly
+# (C) 2013 Canonical Ltd.
+# Author: Martin Pitt <martin.pitt at ubuntu.com>
+# Author: David Henningsson <david.henningsson at canonical.com>
+
+set -e
+
+WORKDIR=$(mktemp -d)
+trap "rm -rf $WORKDIR" 0 INT QUIT ABRT PIPE TERM
+cd $WORKDIR
+cat <<EOF > buildtest.c
+#include <pulse/pulseaudio.h>
+#include <assert.h>
+
+int main()
+{
+    pa_mainloop * ml = pa_mainloop_new();
+    assert(ml);
+    pa_mainloop_free(ml);
+    return 0;
+}
+EOF
+
+gcc -o buildtest buildtest.c $(pkg-config --cflags --libs libpulse)
+echo "build: OK"
+[ -x buildtest ]
+./buildtest
+echo "run: OK"
diff --git a/debian/tests/control b/debian/tests/control
new file mode 100644
index 0000000..8e3e6ce
--- /dev/null
+++ b/debian/tests/control
@@ -0,0 +1,2 @@
+Tests: build
+Depends: libpulse-dev, build-essential

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-pulseaudio/pulseaudio.git



More information about the pkg-pulseaudio-devel mailing list