PulseAudio 9.0 release notes

Changes at a glance

  • Automatic routing improvements
  • Beamforming and various other new features in the WebRTC echo canceller
  • Various improvements in module-role-cork and module-role-ducking
  • LFE remixing disabled by default
  • memfd-backed shared memory transport
  • Support for sample rates up to 384 kHz
  • webrtc-audio-processing dependency minimum version bumped to 0.2
  • Changed the C standard from C99 to C11.

Notes for end users

Automatic routing improvements

In 8.0, PulseAudio started to automatically switch to another profile when the device associated with the current profile is unplugged. That seemingly smart thing had some serious unintended consequences. One typical issue was that when unplugging headphones, PulseAudio might switch to S/PDIF output and not switch back to headphones when they are plugged in again. Another issue was that HDMI in many cases appears to get temporarily unplugged when the monitor goes to sleep mode, or even when switching the refresh rate of the monitor - PulseAudio 8.0 would move audio away from the HDMI monitor in these cases and not move the audio back to HDMI when the monitor becomes available again. These issues are now fixed.

Beamforming and various other new features in the WebRTC echo canceller

The WebRTC echo canceller now supports beamforming. To enable the feature, pass "beamforming=true" in aec_args when loading module-echo-cancel. The filter also needs to know the microphone array geometry and the target direction, configured with the "mic_geometry" and "target_direction" options. For more details about how to configure beamforming, refer to the Modules wiki page.

There's a new "extended filter" mode in the WebRTC echo canceller. The extended filter is more complex and less sensitive to incorrect delay reporting from the hardware than the regular filter. The extended filter mode is disabled by default, because it seemed produce worse results during double-talk (based on some very quick testing). Pass "extended_filter=true" in aec_args when loading module-echo-cancel to enable this feature.

It's now possible to disable the voice activity detection feature. To do that, pass "voice_detection=false" in aec_args when loading module-echo-cancel.

It's now possible to configure the initial volume when using AGC (automatic gain control). To do that, pass "agc_start_volume=VOL" in aec_args when loading module-echo-cancel (replace VOL with a number between 0 and 255). Note that too low initial volume may prevent the AGC algorithm from ever raising the volume high enough (there seems to be some regression in the WebRTC code in this regard).

Various improvements in module-role-cork and module-role-ducking

module-role-cork and module-role-ducking previously ignored streams that don't have the "media.role" property set. Now it's possible to refer to such streams in the configuration by using the special "no_role" string in place of a real stream role.

Another new special role string is "any_role", which allows corking or ducking all streams other than the trigger stream.

module-role-ducking now supports configuring different ducking volume levels for different trigger streams, and different trigger streams can also be configured to duck different sets of streams. For example, "trigger_roles=trig_role1/trig_role2,trig_role3 ducking_roles=ducking_role1,ducking_role2/ducking_role2,ducking_role3 volume=40%/20%" configures two groups. In the first group, streams with role "trig_role1" cause streams with roles "ducking_role1" and "ducking_role2" to be set to 40% volume. In the second group, streams with role "trig_role2" or "trig_role3" cause streams with roles "ducking_role2" or "ducking_role3" to be set to 20% volume.

If the trigger streams themselves get muted or corked, their effects on other streams now get cancelled.

LFE remixing disabled by default

When playing e.g. a stereo stream to a surround system with a subwoofer, the question arises what to do with the subwoofer (i.e. LFE, "low frequency emitter") channel. Up until 6.0 we left the LFE channel silent by default. In 7.0 we introduced support for filtering out low frequencies from other channels and playing the low frequencies to the LFE channel, and we enabled that feature by default. Now we have reverted the default configuration back to what it was in 6.0, i.e. we leave the LFE channel silent. The reason is that the low frequency filtering feature turned out to not work properly; the LFE channel is too quiet. It's not clear how to fix the issue, because increasing the volume may cause clipping in the LFE channel (another possibility would be to lower the volume of the other channels, but that has its problems too), so we decided to just disable the problematic feature by default for now.

Memfd-backed shared memory transport

We have so far used POSIX shared memory to implement efficient, zero-copy, communication between clients and the server. Now we also have initial support for memfd-backed shared memory.

Memfd is a simple memory sharing mechanism, added by the systemd/kdbus developers, to share pages between processes in an anonymous, no global registry needed, no mount-point required, relatively secure, manner. Memfd support in PulseAudio has the potential of improving security in sandboxing use cases by preventing applications from accessing each other's audio streams.

Moreover, due to the nature of POSIX shared memory, where a global /dev/shm registry is needed, shared memory communication is always disabled for system-mode setups. In the future, pending further development to materialize, memfd will also enable system-wide setups to use shared memory.

To allow more testing before this is rolled out, the memfd support is for now disabled by default. Everyone is encouraged to test this feature, and if there are problems please report them! To enable this feature, add "enable-memfd = true" to /etc/pulse/daemon.conf or ~/.config/pulse/daemon.conf.

Even if the server supports memfd and has it enabled, clients can opt out by setting "enable-memfd = false" in /etc/pulse/client.conf or ~/.config/pulse/client.conf.

Support for sample rates up to 384 kHz

PulseAudio has traditionally limited the maximum sample rate to 192 kHz, but it seems that there is some use for rates as high as 384 kHz, so the hard limit has been increased. While such rates may seem nonsensical, there are reasons for supporting them:

  • Some online stores sell music with such sample rates.
  • ALSA uses such sample rates for playing back some compressed formats in passthrough mode. In that case the actual audio doesn't have that high sample rate. The high rate is just an ALSA quirk originating from the choice of pretending that the compressed data is PCM audio with only two channels, while the compressed data actually carries more channels. Note that these compressed formats don't work yet with PulseAudio, the increase in the maximum sample rate is just a precondition for adding the support later.
  • There are indications that some hardware supports such rates. PulseAudio should now be able to take advantage of that hardware feature, but it hasn't been tested.

Notes for application developers

Support for sample rates up to 384 kHz

If you have always wanted to create streams in your application with sample rates higher than 192 kHz, now it is possible, up to 384 kHz.

Notes for packagers

webrtc-audio-processing dependency minimum version bumped to 0.2

When enabling the WebRTC features, the webrtc-audio-processing package version has to be at least 0.2. Note that webrtc-audio-processing 0.2 is not compatible with applications that use version 0.1 (for example, older PulseAudio versions), so PulseAudio and webrtc-audio-processing have to be upgraded in lockstep.

Changed the C standard from C99 to C11.

We now pass -std=gnu11 to the C compiler. Earlier we didn't explicitly set the C standard version, but we tried to be C99 compliant (with GNU extensions). Now we have decided to start using C11 features.

git shortlog

Ahmed S. Darwish (18):
      log: journal: Prevent duplicate values for CODE_* fields
      pulsecore: Cache daemon shm size inside pa_core
      pulsecore: Reference count mempools
      srbchannel: Introduce per-client SHM files
      pulsecore: Transform pa_mempool_new() into a factory method
      SHM: Refactor private allocations
      pulsecore: Introduce memfd support
      memimport: Support memfd blocks
      pulsecore: Specially mark global mempools
      pstream: Support memfd blocks transport
      build-sys: Set C language standard to gnu11
      protocol-native: Disable srbchannel for setups without SCM_CREDENTIALS
      stream: Document pa_stream_write() size and offset requirements
      detect: Don't deprecate module-detect on non-Linux systems
      client audio: Support memfd transport
      core: Support memfd transport; bump protocol version
      shm: Fix use of uninitialized value: segment's shared-memory type
      pstream: Fix use of uninitialized value: ancillary fd cleanup flag

Alexander E. Patrakov (1):
      Disable LFE remixing by default

Arun Raghavan (39):
      format: Make pa_format_info_valid() stricter for PCM
      pulse: Bump PA_RATE_MAX to 384 kHz
      glib: Trivial whitespace fix
      build-sys: Only use sysroot in OS X CFLAGS if specified
      coreaudio: Dynamically allocate C string when converting from CFString
      coreaudio: Catch devices with more channels than we support
      echo-cancel: Update webrtc-audio-processing usage to new API
      echo-cancel: Allow enabling the extended filter in webrtc AEC
      echo-cancel: Canceller may use different spec for playback and capture
      echo-cancel: Express restrictions correctly on webrtc AEC stream config
      echo-cancel: Add a modarg to use sink/source master format and spec
      echo-cancel: Mark private function as static
      echo-cancel: Allow enabling tracing output from the webrtc canceller
      echo-cancel: Deal with volume limit breakage in webrtc AGC
      echo-cancel: Start capture at a sane volume if we're doing webrtc AGC
      echo-cancel: Allow enabling of the webrtc experimental AGC mechanism
      echo-cancel: Add a modarg toggle for VAD in the webrtc canceller
      build-sys: Move to compiling with C11 support
      echo-cancel: Use anonymous unions for echo canceller params
      echo-cancel: Make webrtc AGC start volume a modarg
      echo-cancel: Fix webrtc canceller when rec channels != play channels
      echo-cancel: Improve webrtc canceller error handling a bit
      echo-cancel: webrtc canceller supports different in/out channel counts
      echo-cancel: Use webrtc's deinterleaved API
      echo-cancel: Update a copyright notice
      echo-cancel: Remove pa_ prefix on private functions
      echo-cancel: Add beamforming support in the webrtc canceller
      echo-cancel: Convert AGC API to deal with pa_volume_t
      rtp: Do all receive side rate calculations in sink-input domain
      Revert "format: Make pa_format_info_valid() stricter for PCM"
      module-filter-apply: Remove some dead code
      module-filter-apply: Don't implement policy in module-device-manager
      module-device-manager: Refine logic to ignore filtered streams
      alsa: Reread and upate jack status when a card is unsuspended
      module-filter-apply: Fix stale m-d-m property name in comment
      build-sys: Bump sonames for release
      dbus: Deal with double-counting module-dbus-protocol
      sink-input,source-output: Fix crasher while setting property
      Update NEWS for 9.0

Barun Kumar Singh (1):
      resampler: Fix leaking lfe filter on init failure

David Henningsson (3):
      switch-on-port-available: Switch from HDMI to analog; but not the other way around
      alsa-mixer: refactor element_probe and fix >2 channel bug
      memblock/pstream: Fix two compiler warnings

Deepak Srivastava (1):
      pulsecore: Fixed possible memory leak

Gabor Kelemen (1):
      Updated Hungarian translation

Georg Chini (11):
      role-cork: Don't ignore streams without media.role
      role-cork: React to mute/cork of trigger streams and to proplist changes
      role-cork: allow cork of all non-trigger streams using cork_roles=any_role
      role-cork: remove corking on module exit
      role-cork: prepare merge with role-ducking: move most code to stream-interaction.c
      role-cork: prepare merge with role-ducking: replace "cork" with "interact" where appropriate
      role-cork: more cosmetic changes, changed debug output
      stream-interaction: Bugfix for improper uncorking behavior with global=1
      stream-interaction: add ducking functionality
      role-ducking: use the common code in stream-interaction.c
      stream-interaction: interact if a stream starts corked

Jeremy Huddleston Sequoia (1):
      build-sys: Fix check for CoreServices.h

Jonathan Perkin (1):
      solaris: Catch up with newer API

Juho Hämäläinen (1):
      stream-restore: With dbus-proto fix segfault if e->device is NULL.

Jungsup Lee (1):
      rescue-streams : Fix a typo

Kamil Rytarowski (1):
      solaris: Illumos does not ship with SOUND_PCM* functionality

Marcin Lewandowski (1):
      vala: Added cnames to callback delegates in Vala VAPI

Milo Casagrande (1):
      i18n: Update Italian translation

Muhammet Kara (1):
      i18n: Updated Turkish translation

Nazar Mokrynskyi (1):
      alsa-mixer: Support for Creative SoundBlaster Omni Surround 5.1 USB sound card with latest firmware

Peter Meerwald (2):
      modules: Fix compiler warning comparing 0 with bool
      core: Fix GCC 6 compiler warning regarding left shift of negative value

Piotr Drąg (1):
      i18n: Update Polish translation

Sachin Kumar Chauhan (2):
      module-filter-apply: Fix a memory leak
      resampler: Fix a memory leak in pa_resampler_ffmpeg_init()

Sangchul Lee (3):
      role-ducking: Fix improper unducking behavior in case of operating globally
      role-ducking: Add support for ducking group
      stream-interaction: Fix crash in case of invalid argument for volume

Tanu Kaskinen (24):
      source-output: do volume_factor_source application before resampling
      source-output: remap volume_factor_source when starting move
      device-manager: improve logging about non-existing data
      default.pa: remove X11 module examples
      echo-cancel: Add some bits for webrtc intelligibility enhancer
      card-restore: save the database when shutting down
      resampler-test: remove translations
      filter-apply: fix typo "what" -> "want"
      build-sys: build gtk-test only when glib is enabled
      echo-cancel: rework move handling
      don't move streams to devices that are going away
      device-manager, filter-apply: don't reroute streams that have a filter
      sink-input, source-output: rework property setting
      sink-input, source-output: remove set_name()
      loopback: refactor proplist updating
      filter-apply: simplify proplist updating
      switch-on-port-available: unify input/output switching policy
      switch-on-port-available: fix inverted if condition
      switch-on-port-available: avoid repetitive pointer deferencing
      card: add preferred_{input, output}_port
      card-restore: restore preferred ports
      switch-on-port-available: prefer ports that have been selected by the user
      alsa: ignore jack events when the user is inactive
      dbus: fix crash on LoadModule()

YunQiang Su (1):
      i18n: update Simplified Chinese translation