NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #4304 most downloaded on crates.io
A Rust language binding for the PulseAudio libpulse library.
Last release 1 years ago
19 Apr 2025
Release timing varies
gaps range from 2 weeks to 1.4 years
Nearly every release is documented
notes for 38 of 38 stable releases
22 versions withdrawn
withdrawn after publishing
9 years old
60 releases · first in 2018
Added a length check to the stream new_extended() method (missed in previous version).
new_extended() method (missed in previous version).write() method (missed in previous version).Dropped additional long-deprecated constants, missed in the previous version.
to_owned() methods to a bunch of introspection objects (as requested back in 2021 in
issue 44). Thanks to @t4ccer on github for prompting this and providing an initial partial
implementation.set_corked_state() method to Stream providing an alternative to using cork() and
uncork().set_prop_int_array() and set_prop_string_array() methods of
format::Info. Now should you happen to pass in an array with a length larger than can fit
within the len parameter of the C function, it will panic.check_version() function.CardProfileInfo2 introspection alias.One column per quarter.
Dropped various constants that were deprecated back in versions 2.20 and 2.21 (December 2020).
clone() that have become unnecessary.num-derive dependency.bitflags dependency to version 2.x (required adding Debug to a few flagsets).libpulse-sys from 1.21 to 1.22.num-derive from 0.3 to 0.4.bitflags from 1.2 to 2.x.Clarify in documenation that mainloop and context objects must both live for the entire duration.
Fixed crash when audio device has null device but non-null name, thanks to @AdriaanPrinsloo on github.
i forgot to do this as part of the previous release. i already published the new sys crates so will have to yank them (except pulse-sys which has no d
i forgot to do this as part of the previous release. i already published
the new sys crates so will have to yank them (except pulse-sys which has
no dependency on the other crates of course).
Fixed broken build status badge in readme.
Added rust-version (MSRV) attribute to cargo.toml file.
rust-version (MSRV) attribute to cargo.toml file.Duration::try_from_secs_f32/64
made in rust stdlib version 1.60 and further tweaked in 1.63. See [this issue][issue48].libpulse-sys from 1.19 to 1.20.Changed the type of the timestamp member of def::TimingInfo from Timeval to UnixTs since it is actually a system time not a generic duration.
timestamp member of def::TimingInfo from Timeval to UnixTs since
it is actually a system time not a generic duration.#[repr(transparent)] marker to MicroSeconds.#[track_caller] such that panics from overflows and such in math operation
implementations will point to the caller as the source of the problem.Made the attributes of MainloopInner private. Methods new() and get_api_ptr() were added to support this, while get_ptr() was marked unsafe.
MainloopInner private. Methods new() and get_api_ptr() were added to
support this, while get_ptr() was marked unsafe.channelmap::Position::to_mask() to const fn.Added PA v15 support (API additions):
Introspector::send_message_to_object().proplist::properties::{CONTEXT_FORCE_DISABLE_SHM, BLUETOOTH_CODEC}.libpulse-sys from 1.18 to 1.19.* Minor documentation tweaks.
Implemented std::Error for error::{Code, PAErr}.
std::error::Error for error::{Code, PAErr}.Debug for ListResult.libpulse-sys from 1.17 to 1.18.Deprecated version::check_version().
Context creation functions new() and new_with_proplist() will now fail if the version
of the PulseAudio client system library is older then the minimum compatibility level set via use
of the version feature flags. This is done to block use of the library in such a circumstance as
a means of helping to prevent the undefined behaviour that could result from the possible
“forward” compatibility problems discussed in the project COMPATIBILITY.md documentation.version::get_library_version_numbers(), version::compare_with_library_version() and
version::library_version_is_too_old().version::check_version().libpulse-sys from 1.16 to 1.17.Converted context::FlagSet to a [bitflags] type, moving the context::* constants to associated constants of it, deprecating the old constant set. This…
context::FlagSet to a [bitflags] type, moving the context::flags::* constants
to associated constants of it, deprecating the old constant set. This was overlooked in 2.20.Fixed mistake made trying to conditionally enable #[cfg(doc)] for docs.rs.
#[cfg(doc)] for docs.rs.Deprecated sample::{CHANNELS_MAX, RATE_MAX}.
dox cargo feature.pa_latest and pa_latest_common cargo features.pa_v8.COMPATIBILITY.md guide (available in the code repo), including adding important
discussion of the hazard of “forward compatibility” concerns.Add, Sub, Mul, Div and Rem
for time types, such that those that were not previously making use of “checked” calculations
now do so, and thus overflow causes a panic rather than being wrapped. If panicing is not wanted,
the “checked” methods should be used directly which return a None on failure.Option wrapper to the volume param of Context::play_sample() and
Context::play_sample_with_proplist() “scache” methods to simplify usage. Supplying None is
a nicer alternative to passing Volume::INVALID.sample mod to methods of sample::Spec:
format_is_valid(), rate_is_valid() and channels_are_valid(), having noticed that they
clearly relate to the attributes of that type and so should have been there all along.channels param of channelmap::Map methods init_auto() and
init_extend() from u32 to u8.sample::CHANNELS_MAX type from usize to u8.sample::{CHANNELS_MAX, RATE_MAX}.sample::Spec::{CHANNELS_MAX, RATE_MAX} replacements.volume::ChannelVolumes::CHANNELS_MAX replacement.volume::{VOLUME_NORM, VOLUME_MUTED, VOLUME_MAX, VOLUME_INVALID}.volume::Volume::{NORMAL, MUTED, MAX, INVALID} replacements.volume::DECIBEL_MINUS_INFINITY.volume::VolumeDB::MINUS_INFINITY replacement.time::{USEC_INVALID, USEC_MAX}.time::MicroSeconds::{INVALID, MAX} replacements.context::subscribe::{FACILITY_MASK, OPERATION_MASK}.context::subscribe::{Facility::MASK, Operation::MASK} replacements.MicroSeconds:
MicroSeconds::{MIN, ZERO, SECOND, MILLISECOND} associated constants.MicroSeconds::is_zero(), MicroSeconds::from_secs(), MicroSeconds::from_millis(),
MicroSeconds::inner(), MicroSeconds::as_secs(), MicroSeconds::as_millis(),
and MicroSeconds::diff().MicroSeconds::from_secs_f64(), MicroSeconds::from_secs_f32(),
MicroSeconds::as_secs_f64() and MicroSeconds::as_secs_f32() for converting to/from
floating point form, and MicroSeconds::mul_f32(), MicroSeconds::mul_f64(),
MicroSeconds::div_f32() and MicroSeconds::div_f64() for multiplication and division by
floats.Mul operations between an integer primitive and a
MicroSeconds that required the Rhs to be the integer, by extending the implementation. Thus
you can now do 2 * MicroSeconds(20) not just MicroSeconds(20) * 2.MicroSeconds to be added or subtracted from a Duration, not just the other way
around.bitflags] (long overdue). The following
types which have been simple integer primitive type aliases have now been changed to [bitflags]
wrappers. The set of flags associated with them have been thus assigned as associated constants
to them, and the separate set marked as deprecated.
stream::FlagSet, with its stream::flags::* flags.def::{SinkFlagSet, SourceFlagSet} and their def::sink_flags::* and def::source_flags::*
flag sets.direction::FlagSet and its direction::flags::* flags.mainloop::events::io::IoEventFlagSet and its mainloop::events::io::flags::* flags.context::subscribe::InterestMaskSet and its context::subscribe::subscription_masks flags.mainloop::events::io::IoEventFlagSet type to simply FlagSet.MASK_CARD constant from context::subscribe to simply CARD, since the inclusion
of MASK_ in the name was a mistake (part of a prefix removed from others but mistakenly left
in place for this one).direction::is_valid() and direction::to_string() to methods of direction::FlagSet.MonotonicTs::checked_add_duration() and MonotonicTs::checked_sub_duration() along with
corresponding Add[Assign] and Sub[Assign] impls for adding a Duration to MonotonicTs.
This complements the existing functionality for adding a MicroSeconds, without requiring
conversion of a Duration to a MicroSeconds.#[cfg(doc)] to always include stuff behind PA version feature guards in generated
documentation. (Required bump of minimum supported Rust version from 1.40 to 1.41).version::Compatibility as #[non_exhaustive].libpulse-sys from 1.15 to 1.16.bitflags 1.2 now required.Fixed broken conversions between Duration and other time duration types (MicroSeconds and Timeval), which were mistakenly converting based upon millis
Duration and other time duration types (MicroSeconds and
Timeval), which were mistakenly converting based upon milliseconds rather than microseconds and
thus were off by a scale of 1000. Lack of tests failed to catch this, which have now been added.Default implementation for channelmap::MapDef.version::check_version(). If you use it, please double check that it
actually does what you think it does. It does not involve talking to the client library.Fixed deprecated license attribute syntax.
Unfortunately it was not possible to leave the From version in place with a deprecation notice due to conflicts that result. The solution was also re-…
format::Encoding as #[non_exhaustive].From<PAErr> for Code impl with TryFrom<PAErr> for Code, since the conversion is
fallible and now that TryFrom has been stable for a while (since 1.40). Unfortunately it was
not possible to leave the From version in place with a deprecation notice due to conflicts that
result. The solution was also re-implemented based upon FromPrimitive.std::fmt::Display for error::Code.FromPrimitive and ToPrimitive from the num-derive crate on basic enums.libpulse-sys from 1.14 to 1.15.num-traits 0.2 now required.num-derive 0.3 now required.Added PA v14 support (API additions).
prepare() method to take an Option<MicroSeconds> instead of
Option<i32>.Code::Io enum variant to Code::IO.libpulse-sys from 1.13 to 1.14.Trivial internal tidy-up in volume module.
Bumped pa_latest_common feature to target PA v13.
pa_latest_common feature to target PA v13.Fixed some dangling pointer issues with handling of string arrays, thanks to @yatinmaan on github.
Made the attributes of channelmap::{ChannelVolumes, Map} types private. (Direct access had been deprecated previously).
channelmap::{ChannelVolumes, Map} types private.
(Direct access had been deprecated previously).libpulse-sys from 1.12 to 1.13.Fixed issues with a threaded mainloop example in the documentation.
libpulse-sys from 1.11 to 1.12.
libpulse-sys from 1.11 to 1.12.Fixed issues compiling on Windows:
pollfd definitiontimeval attribute type definitions
Thanks to @allquixotic on github for reporting.Reverted "Changed the mainloop param of Context::rttime_new() from trait object to generic (dyn toimpl)" from v2.7. Failed to test sufficiently. This
mainloop param of Context::rttime_new() from trait object to generic
(dyn toimpl)" from v2.7. Failed to test sufficiently. This introduces an E0632 error in a
test app and I was unsuccessful in finding a compilable workaround.Changed the license model from LGPL to dual MIT and Apache-2.0. See [here][issue26] for details.
libpulse-sys from 1.10 to 1.11.Implemented PA v13 enhancements, including:
get_sample_format(), get_rate(), get_channel_count() and get_channel_map()
methods to format::Info.util::make_thread_realtime().Encoding::TRUEHD_IEC61937 and Encoding::DTSHD_IEC61937.pa_threaded_mainloop_once_unlocked has not been added at this time.ss param of Context::get_tile_size() to add an Option wrapper.
The C API function allows a null pointer to be used for this param, which was not a use case
allowed in the binding, for no particular reason. This enables it.libpulse-sys from 1.9 to 1.10.Fixed broken doc.rs documentation generation.
Extended support to even older versions of PA, specifically up to and including v4.
version::Compatibility variants to make more sense.dox feature flag, for use with cargo doc.
It enables the very latest PA version compatibility, while bypassing the pkg-config check, thus
is useful for generating documentation that includes information on features from versions of PA
that may be newer than the version you have installed.libpulse-sys from 1.8 to 1.9.Added missing version info to deprecation notices.
Version: purged deprecated items.
channelmap::{ChannelVolumes, Map} types to be more Rust-like.
Both of these types hold an array of size sample::CHANNELS_MAX, along with a channels
attribute which controls how much of the initial portion of that array is “active” (equivalent to
the len() of a Vec). Previously the array and len were simply public attributes, with changes
to be applied directly. While for the time being they remain publicly accessible for backwards
compatibility, this will become private in a future release. These types should now be used in a
way more similar to a Vec:
len() and set_len() get read/write access to the channels attribute that
records how much of the array is considered “active”.Borrow<[_]> and BorrowMut<[_]> have been implemented, along with the addition of
new methods get() and get_mut() (for convenience - you can avoid type ambiguity), for
accessing the array as a slice (of just the “active” portion).use conventions to that of Rust 1.30/1.31.const:
version::get_compatibility().Volume::is_valid().Timeval::new() and Timeval::new_zero().subscribe::Facility::to_interest_mask().libpulse-sys from 1.6 to 1.8.Note: versions 2.8 and 2.9 skipped, used only for libpulse-glib-binding crate changes.
Fixed overlooked use of new method names in docs.
Deprecated ChannelMap::is_equal_to(), ChannelVolumes::equal_to(), ChannelVolumes::channels_equal_to(), Spec::equal_to(), and Proplist::equal_to() in f…
Proplist for clarity:
Proplist::sets() to Proplist::set_str().Proplist::gets() to Proplist::get_str().Proplist::setp() to Proplist::set_pl().Stream::write_copy() which is just a simplified interface for asking PA to make an
internal copy of the to-be-written data (same as providing None in the free_cb param of
Stream::write().mainloop param of Context::rttime_new() from trait object to generic (dyn to
impl).PartialEq implementations:
ChannelMap::is_equal_to(), ChannelVolumes::equal_to(),
ChannelVolumes::channels_equal_to(), Spec::equal_to(), and Proplist::equal_to() in
favour of PartialEq implementations.Proplist and PartialEq<Volume> impl for ChannelVolumes.PartialEq implementations for channelmap::{Map, Spec, ChannelVolumes} to delegate the
logic to the C API.repr(C) attribute from SinkPortInfo introspection type.latest_pa_common_compatibility feature flag, used by default now instead of
latest_pa_compatibility.sys crate counterparts.libpulse-sys from 1.5 to 1.6.Implemented use of std::catch_unwind() in callbacks.
std::panic::catch_unwind() in callbacks.Note: This includes a security fix!
Note: This includes a security fix!
proplist::Iterator (not to be confused with the
std::iter::Iterator trait). An instance of this object type is created from a Proplist object
and holds a copy of the same raw pointer to the underlying C object; the Proplist object had
sole responsibility for destroying it via its Drop implementation. There was no actual lifetime
association however linking the lifetime of the Iterator object to the Proplist object, and
thus it was possible for the Proplist object to be destroyed first, leaving the Iterator
object working on a freed C object. This is unlikely to have been done in actual user code, but
would have been trivial to achieve, including simply by using the into_iter() function. This
affects versions all the way back to 1.0.5.Send+Sync for various types.
This was previously not done due to uncertainty as to whether or not it was safe to do so, but I
have now reconsidered it and arrived at the conclusion that it should be okay: With the threaded
mainloop, a lock must be held when using objects; this is taken by the mainloop dispatcher when
executing callbacks, and otherwise must be taken by the user before using objects within any
thread. With that locking mechanism, it should be safe I presume for these objects to be marked
Send+Sync. It is not ideal that the user can so easily just forget to grab the lock, as opposed
to the Rust design of Arc<Mutex<_>> forcing unlocking to get at things, but it’s not certain
that we can easily really do anything to address this. So long as users stick to the principle of
grabbing the mainloop lock though, they should be fine.Duration to MicroSeconds or Timeval using
Duration::subsec_millis().proplist::Iterator::new() private, since it’s very unlikely anyone needs it.latest_pa_compatibility and pa_v12_compatibility feature flags, and deprecated
pa_encoding_from_string in favour of pa_v12_compatibility.From conversion implementation to/from C type for format::Info.libpulse-sys from 1.4 to 1.5.Changed the channelmap::Map::new_from_string() method return value to use a Result wrapper. Previously failure was just ignored, expecting strings pro
channelmap::Map::new_from_string() method return value to use a Result wrapper.
Previously failure was just ignored, expecting strings provided to always be valid, as obtained
from the Map::print() and Map::to_name() methods, but let's be more cautious.Option wrapper back
in v2.0. Thanks to @0xpr03 on github for noticing a discrepancy.Option wrapper to the Context::drain() return value. It was incorrectly removed
from this function at the same time as legitimately being removed from many others.Drop implementation on Stream to no longer unwrap the Result returned by the
disconnect() attempt it makes. This should fix [this problem][issue11] encountered by @futpib
on github.Introduced TARGET_VERSION and deprecated MAJOR, MINOR and MICRO.
version mod:
Compatibility enum and get_compatibility() function.BINDING_TARGET_VERSION to TARGET_VERSION_STRING.TARGET_VERSION and deprecated MAJOR, MINOR and MICRO.get_headers_version().version mod.pa_encoding_from_string feature purpose.libpulse-sys from 1.3 to 1.4.Minor tweaks, improving code clarity and such.
Fixed broken attempt to include license file in bundled package.
Added dedicated changelog, split off from the old single project overview one.
.gitignore and README.md
files.* Fixed feature control.
Added homepage and repo links, thanks to @berkus on github for the patch.
Fixed reported compilation errors in the time mode on macOS and raspberry pi platforms. Thanks to @noahbkim on github for reporting and @ssendev for t
time mode on macOS and raspberry pi platforms. Thanks
to @noahbkim on github for reporting and @ssendev for the suggested solution.Nothing published for this version
Nothing published for this version
Updated declared PA version compatibility (11.0 → 12.0).
Operation: Documented possible memory leak.Proplist: Fixed debug output to use comma separator rather than newline (for consistency in
dumping introspection data), and output in list style instead of mixed struct/list style.README usage example.Nothing published for this version
Restored access to format::Info’s ptr attribute.
format::Info’s ptr attribute.Note: This includes a security fix!
Note: This includes a security fix!
Stream::get_format_info() and Stream::get_context(). These should
have used Stream::from_raw_weak() instead of Stream::from_raw() to avoid incorrectly freeing
the underlying C object, leaving a dangling pointer.Nothing published for this version
Nothing published for this version
Fixed and simplified Proplist iteration:
Proplist iteration:
Some. I don’t know what I was thinking.iterate() method was renamed iter() and now
returns an actual Rust Iterator object, which makes iterating much more simple and tidy.self immutable for CVolume::is_muted() and CVolume::is_norm().Stream write methods.Stream::write_ext_free()’s free_cb_data param with free_cb as tuple, as done
elsewhere.Note, version number 1.0.4 skipped (it was used for non-crate project changes).
Added From methods for transmuting between certain introspection structs and their sys counterparts. (They are identical, and only duplicated in the b
From methods for transmuting between certain introspection structs and their sys
counterparts. (They are identical, and only duplicated in the binding to add documentation).* Added travis badge.
Fixed toml file license string LGPL-2.1 → LGPL-2.1+.
LGPL-2.1 → LGPL-2.1+.Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →