Breaking changes:
- Updated the feature flags for file formats to be 1-to-1 with Symphonia's feature flags.
- If you were using the
oggfeature previously, you'll want to addvorbisas well. - If you were using the
wavfeature previously, you'll want to addpcmas well. - If you were using the default features, you don't need to change anything.
- If you were using the
Other changes:
- Update
cpalto 0.17 - Update
glamto 0.32 - Update
pasteyto 0.2 - Fix a slight inaccuracy in the docs
Breaking changes:
- Replaced the
buffer_sizeoption inCpalBackendSettingswithconfig, which gives many more configuration options (thanks @DaforLynx!) - Switch to 2024 edition, update dependencies, and update GitHub actions to use newer rustc versions (thanks @Roms1383!)
- Remove the
android_shared_stdcxxfeature, ascpalnow usesndk::audio, andcpal'soboe-shared-stdcxxfeature is deprecated
Other changes:
- Switch from
pastetopastey, re-exportpastey, and update macros to not require manually importingpasteyat the call site (thanks @Keinsleif!) - Fix typo in readme (thanks @benjamin-lieser!)
- Decode default audio track when multiple tracks are present (thanks @siavashserver!)
- Make
StreamingSoundHandleSync
- Fix cpal (desktop) errors on startup causing a panic on another thread instead of being returned to the caller
- Allow getting unhandled errors from
CpalBackendand querying the number of errors discarded due to the error buffer being full (desktop only) (thanks @voidentente!) - Update glam to 0.30 (thanks @a1phyr!)
- Clamp all audio internally to the -1.0 to 1.0 range
From my testing, not all audio drivers clamp audio signals to the -1.0 to 1.0 range before applying the operating system volume, so in cases where Kira would have previously played sounds outside of that range, your application would play audio that's unexpectedly loud for the operating system's volume setting. This change prevents Kira from playing anything louder than it's "supposed" to.
- Clamp some parameters to valid values
- Add
Static/StreamingSoundData::unsliced_duration(thanks @Roms1383!)
- Fix spatial audio tracks immediately outputting non-spatialized audio if the corresponding listener is dropped. This could result in unexpectedly loud audio playback. Now if the listener is dropped, the spatial track will output silence.
Kira now processes audio in chunks instead of one sample at a time. This means that
Sound::process no longer returns a Frame; instead it receives a slice of Frames
to overwrite. Effect::process takes an input slice instead of a single frame,
and it overwrites that slice instead of returning a new Frame.
The benefit of this change is significantly improved performance. The criterion benchmarks aren't comparable to the ones in v0.9.x and earlier, but in my unscientific test, I can play about twice as many sounds on my PC without crackling.
There are some tradeoffs, but I think they're reasonable:
- Modulators are no longer sample accurate. Instead, they update once per internal
processing chunk. Sounds and effects can interpolate between the previous and
current modulator value using
Parameter::interpolated_valueto avoid discontinuities. - Clocks are no longer sample accurate. For my use case which involves dynamically generating music, the default internal buffer size of 128 frames sounds almost exactly the same as sample-accurate clocks. You can adjust the internal buffer size to get the right tradeoff of performance vs. accuracy for your game. I have some ideas for how sample-accurate clocks could be implemented within the buffered architecture, so if you find yourself needing sample-accurate clocks, let me know!
- The delay effect can no longer have its delay time changed after the fact. If you know how to implement a delay that can smoothly change its delay time with the buffered architecture, please make a PR!
Sounds now live inside mixer tracks. Previously, to play a sound on a mixer track, you
would use StaticSoundData/StreamingSoundData::output_destination. Now, you pass the
sound to TrackHandle::play. Additionally, tracks can contain other tracks. Tracks
can also route their outputs to send tracks, which are a separate concept now. This change
enables the following feature:
Mixer tracks can now be paused and resumed. Pausing a mixer track pauses all sounds playing on the track, as well as all child tracks.
The concepts of spatial scenes and emitters have been removed, and listeners no longer output to a mixer track. Instead, mixer tracks can optionally have spatial properties, like position and spatialization strength. Sounds and child tracks on the track will have spatialization applied relative to a specified listener.
This release also adds Value::FromListenerDistance, which can be used to map sound and
effect parameters to the distance between a spatial track and its corresponding listener.
Previously, Volume was an enum with Amplitude and Decibels variants, and PlaybackRate
was an enum with Factor and Semitones variants. There's a couple problems with this:
- It's unclear what scale a tween uses when tweening from one variant to another. For instance,
if you tween a
Volume::Amplitudeto aVolume::Decibelswith linear easing, is it linear in the amplitude domain or decibels? - Amplitude isn't a good default representation for volume because it's not perceptually linear.
Now, everything that previously used Volume uses the simpler Decibels type, and
PlaybackRate always contains a factor. (Semitones still exists as a separate type that
implements Into<PlaybackRate>).
There's also a new Panning type that's used instead of bare f64s. Panning has been changed
so -1.0 is left instead of 0.0, since this makes more sense mathematically.
- Reorganized some types and modules to reduce unnecessary nesting
- Added
WaitingToResumeandResumingvariants toPlaybackState - Changes to
Mapping:- Added an
easingfield - Inputs are now always clamped to the input range
- Removed the
Defaultimplementation - Added methods for performing math operations on the output range
- Added an
- Implemented some math operations to
Value - Changed the fields of
Capacitiesback tou64s ClockInfoProviderandModulatorValueProviderand now combined into oneInfostruct, which also provides info about spatial audio state- Added
CpalBackend::pop_cpu_usage(desktop only for now)
- Improve performance when adding or subtracting large
f64s from aClockTime(thanks @crabm4n!) - Fix UB detected by miri in the stacked borrows model (thanks @Imberflur!)
- Update
glamto 0.29.0
- Fix bug where static sounds played backwards would never be marked as finished, and thus never unloaded
- Update
triple_bufferto 8.0.0
- Update
glamto 0.28.0
- Fix
StaticSoundHandle/StreamingSoundHandle::pause/resume/stopnot taking effect immediately if the sound has a start time. This was an unintended change from the behavior in v0.8.x and earlier versions. - Fix sounds erroneously reporting their state as
Playingbefore playback has resumed after callingStaticSoundHandle/StreamingSoundHandle::resume_atwith a non-immediateStartTime - Fix sounds entering a limbo state where they output no sound and can never be unloaded when their output destination (track or emitter) is removed
- Fix a bug where static sounds could enter a limbo state where they're stopped, but never unloaded if the clock they're waiting on is removed
- Fix sounds stopping after having already started if the clock they were originally waiting on stops
- Implement
DefaultforRegion,EndPosition,PlaybackPosition, andValue - Implement
Debugfor handles, command types, andResourceController
ClockTime now has a fraction field, which represents a fraction of a tick. This
means sounds and tweens can be scheduled for times in-between ticks.
In addition, ClockHandle::fractional_position has been removed because
ClockHandle::time provides that info anyway, and the shape of ClockInfo has
changed to hold a ClockTime (this is only relevant if you're creating implementations
of one of Kira's traits).
(Implemented by @zeozeozeo)
The device and buffer size used by the CpalBackend are now configurable via
CpalBackendSettings.
Anything that could previously fail because of a command buffer filling up or
getting poisoned can no longer fail that way, so you can call functions
like Emitter::set_position as frequently as you want.
v0.8 introduced a playback_region setting for static and streaming sounds
which replaced the previous start_position setting. It was meant to serve two
purposes:
- Allow you to play only a portion of a sound
- Allow setting the start position of the sound
However, these two purposes had an unintuitive interaction. Say you want to play a sound starting 3 seconds in. In v0.8, you would do something like this:
manager.play(
StaticSoundData::from_file(
"test.ogg",
StaticSoundSettings::new().playback_region(3..),
)?,
)?;Then let's say you wanted to seek the sound to 2 seconds. The sound would stop because you've set the playback region not to include that part of the sound, when all you really wanted to do was set the start position.
In v0.9, these two purposes are separated. The playback_region setting has been
reverted to the start_position setting from versions before v0.8, and to serve
the purpose of playing portions of sounds, slice methods have been added to
StaticSoundData and StreamingSoundData.
Note that the loop_region option added in v0.8 remains and works the same way
in v0.9.
Previously, you could delay the playback of a static sound by setting its
start position to a negative number. This only worked with static sounds, however,
not streaming sounds or tweens. This is now disallowed, which allows for some
minor internal code cleanup. In its place is the more explicit and intuitive
StartTime::delayed, which works with anything that has a StartTime.
Previously, if you paused a sound and set the fade-in tween to have a start time
in the future, the sound wouldn't become audible until the start time, but it would
still be advancing in the background as soon as you called resume. The resume_at
method delays playback until the specified StartTime.
Chainable methods have been added to StaticSoundData and StreamingSoundData to
change settings on the sound data. So instead of doing this:
let sound = StaticSoundData::from_file("sound.ogg", StaticSoundSettings::new()
.volume(0.5)
.playback_rate(2.0)
)?;You can use this less verbose code:
let sound = StaticSoundData::from_file("sound.ogg")?
.volume(0.5)
.playback_rate(2.0);StaticSoundSettings and StreamingSoundSettings still exist and are still fields
of the corresponding SoundDatas, so you can still store settings independently
of a sound data.
This allows for some performance improvements, but it does mean you are limited to 65,536 of each kind of resource (sounds, clocks, etc.). I apologize to anyone who was trying to play more than 65k sounds.
This feature was thrown into a previous version of Kira as a quick and dirty way to pause/resume all sounds. However, it's the wrong tool for the job, since it pauses and resumes the entire audio system, which is almost never what you want.
The benchmarks run about 26-29% faster (on my machine) compared to v0.8.7.
- Added
android_shared_stdcxxfeature - Update
glamto 0.27 - Added
TrackBuilder::add_built_effectandTrackBuilder::with_built_effect - Improve performance when using
start_positionwith streaming sounds - Remove
RangeInclusiveconversions forRegions, as all current uses ofRegions treat the end bound as exclusive - Stop streaming sounds immediately if there's a decoding error
- Remove all uses of
#[non_exhaustive] - Add
#[must_use]where appropriate - Moved some types and modules to reduce excessive nesting
AudioManager::main_tracknow returns&mut TrackHandleinstead ofTrackHandle
- Fix ClockInfoProvider having poor timing resolution
- Fix a typo in the readme
- Add
StreamingSoundData::duration - Make
AudioManagersSyncif the backend isSync - Make the
CpalBackendSyncon wasm targets - Make the
MockBackendSync - Update
glamto v0.25.0
- Fix
kira::spatial::scene::AddEmitterErrornot being publicly available - Fix some typos in the documentation
- Add the
assert_no_allocfeature - Fix garbage audio getting sent to surround sound channels
- Add
serdefeature - Implement
PartialOrdforClockTime - Implement
DefaultforVolumeandPlaybackRate
This release removes reverse playback support for streaming sounds. There's pretty serious issues with garbled audio when streaming an mp3 or ogg file backwards, and based the initial investigation, these issues won't be trivial to fix. This feature may return in the future, but for now, you should not rely on it.
- Fix errors when streaming some ogg files
Known issues:
- Seeking can cause errors with short ogg files
- Reverse playback of ogg files results in garbled sound
- Added
StaticSoundData::from_media_source - Added
StreamingSoundData::from_media_source
The main highlight of this release: Kira now supports 3D positional audio! This is a simple implementation of 3D audio that only support volume attenuation based on distance and panning based on direction. Doppler effect and distance-based filtering and reverb are not supported yet.
This is meant to be an MVP of positional audio. Please give it a try and let me know what improvements you'd like to see so I can gauge what expansions to this API should look like.
Modulators are globally available streams of values that parameters like volume and playback rate can be linked to. These are useful for controlling multiple parameters with one value and using more complex modulations, like LFOs.
For anyone who's made implementations of traits in previous versions of Kira,
keep in mind that Tweener was renamed to Parameter, and now Tweener is the
name of a modulator implementation that comes with Kira.
Two new effects were added: compressor and EQ filter. The compressor adjusts the volume of audio to make louder parts quieter. An EQ filter a single band of a parametric EQ useful for adjusting the volume of frequencies of sound.
The start_position setting for static and streaming sounds has been replaced
with a playback_region setting which lets you specify an end position for the
sound as well as a start position. The loop_behavior setting has been replaced
with loop_region, which lets you specify an end point for the loop. You can
now change the loop_region after the sound is created using the
set_loop_region function on the sound's handle.
StaticSoundData::framesis now anArc<[Frame]>instead ofArc<Vec<Frame>>- Exposed the
Decodertrait for streaming sounds - Moved
PlaybackStateto the sound module - Streaming sounds now support reverse playback
- Added
TrackBuilder::with_effect - Moved
ClockSpeedto theclockmodule - Moved
PlaybackRateto thesoundmodule
- Fix compile error on WASM targets
- Fix crackling on Mac OS when multiple applications are playing audio
- Update
cpalto 0.15.1
- Update
cpalto 0.14.1 - Update
ringbufto 0.3.1 - Implement
PartialEqforStaticSoundData,DistortionKind,DistortionBuilder,FilterMode,FilterBuilder,PanningControlBuilder,ReverbBuilder,VolumeControlBuilder, andTrackRoutes - Implement
DebugforStaticSoundDataandTrackRoutes - Implement
CloneforTrackRoutes
This is a bugfix release, but unfortunately one of the bugfixes did require a
breaking change. Fortunately, this breaking change only affects people who have
created their own Sound or Effect implementations, which is not the most
common use case.
Fixes:
- Fix a panic when starting a
StaticSoundwith a start position later than the end of the sound - Fix negative start positions getting rounded up to
0.0. Now sounds played with negative start positions will output silence until the position reaches0.0, at which point normal playback will resume. This is the behavior from versions 0.5.x and prior, and it was not meant to change in 0.6.x. - Streaming sounds will no longer stop after they encounter an error, allowing them to recover from non-fatal errors and continue playback
- Fix a bug where if a sound was played with the start time set to a clock time, and the clock time had already passed by the time the sound was played, it would not start until the next tick of that clock
Breaking changes (only for Sound and Effect implementations):
- Removed the
on_clock_tickcallback fromSound,Effect, andTweener - Instead,
Sound::process,Effect::process, andTweener::updatereceive a&ClockInfoProviderargument.ClockInfoProvidercan report the current state of any active clock.
- Added
ClockHandle::fractional_position - Added
StaticSoundData::with_settingsandStaticSoundData::with_modified_settings - Changed the following functions to take
&selfarguments instead of&mut self(thanks @nobbele!):ClockHandle::set_speedClockHandle::startClockHandle::pauseClockHandle::stopAudioManager::pauseAudioManager::resumeTrackHandle::set_volumeTrackHandle::set_route
Kira v0.6 is a complete rewrite of Kira with the following goals:
- Make the API more elegant
- Make the library leaner by removing features that weren't pulling their weight
- Provide a solid technical foundation for future feature development
Of course, the overall goals of Kira are the same: provide a library that fills missing niches in most audio libraries and enables people to be creative with their game audio.
Kira now supports streaming sounds! Unlike static sounds, which keep all audio data in memory, streaming sounds decode audio from the filesystem in realtime. This has a much leaner memory footprint at the cost of higher CPU usage.
Static and streaming sounds are both implementors of the new Sound trait.
Sounds produce arbitrary streams of audio, so they can be used for both finite
sounds or infinite sounds, like voice chat audio. In this sense, they're similar
to AudioStreams from previous versions of Kira, but they can be automatically
unloaded when they're finished, and they can receive clock events (see below).
They're better integrated with the rest of Kira, making them first class
citizens instead of escape hatches.
Kira no longer has any concept of "instances". If you want to play a static
sound multiple times, you can clone it each time you want to pass it to
AudioManager::play. (Static sounds share their samples via an Arc, so
cloning is cheap.) Streaming sounds cannot be cloned since each one opens up a
new file handle.
Metronomes and sequences from previous versions of Kira were useful for complex audio scripting, but most games don't need such a complex system. In Kira v0.6, they're both replaced by clocks, which are simple timing sources.
Static and streaming sounds can be set to start playing at a certain clock time. Additionally, tweens can be set to start at a clock time. This means anything involving a tween, such as fading out a sound or changing its playback rate, can be synced to a clock.
If you need a more complex system, you should be able to build it in gameplay code using clocks as a building block.
The mixer no longer makes a distinction between sub-tracks and send tracks. Any sub-track can be routed to any number of other sub-tracks.
Previous versions of Kira were hardcoded to use cpal to talk to the operation
system's audio drivers. Kira v0.6.0 has a Backend trait, so you can implement
your own backends.
Kira is now available under the MIT or Apache-2.0 license. (Previous versions were only available under MIT.)
Previous versions of Kira had global "parameters" that you could link settings to, like metronome tempos and instance playback rates. The only way to smoothly tween a setting was to link it to a parameter and tween that parameter. It is useful to be able to link multiple settings to one parameter, but the more common use case was to create a parameter just to tween one setting, which isn't very ergonomic.
In Kira v0.6, parameters have been removed, and all settings can be tweened directly. In future versions, I'd like to bring back global parameters and allow users to either tween settings directly or link them to parameters, I just haven't figured out a good way to architect that.
The main purpose of arrangements was to make it easier to create looping music with intro sections. It served that purpose well, but it was overkill for that purpose, and it wouldn't work with streaming sounds.
Groups were meant to help with pausing, resuming, stopping, and unloading large categories of resources. It tried to cover different types of resources with different notions of pausing, resuming, and stopping. It mapped decently to instances and sequences, but I think it would have been likely that future versions of Kira would have a resource type that groups didn't make sense for, and the abstraction would become shakier over time. Furthermore, resource management can be done from gameplay code, so it's not even necessary for Kira to provide this feature.
- Added volume control and panning control effects
- Removed the built-in panning control from mixer tracks
- Moved the functionality from
kira-cpalandkira-loadersinto the mainkiracrate.kira-cpalandkira-loadersare now unneeded and deprecated.CpalBackendfromkira-cpalis now available askira::manager::backend::cpal::CpalBackendkira_loaders::loadandkira_loaders::load_from_cursorare nowStaticSoundData::from_fileandStaticSoundData::from_cursorkira_loaders::streamandkira_loaders::stream_from_cursorare nowStreamingSoundData::from_fileandStreamingSoundData::from_cursor
- Added
Renderer::on_change_sample_rate, which theBackendshould call if the audio sample rate changes - Added
Effect::on_change_sample_rate, which is called when the audio sample rate changes - Changes to the
Backendtrait:- Added the associated type
Backend::settingsand the methodBackend::setup, which is used for creatingBackends (basically anewfunction, but required by theBackendtrait) - Renamed
Backend::inittoBackend::start - Removed
Backend::sample_rate - Removed
UnusedResourceCollectorfrom the public API.Backends are no longer responsible for dropping unused resources.
- Added the associated type
- Updated
MockBackendto the new API - Removed the
backendargument toAudioManager::new - Restructured
AudioManagerSettings - The cpal backend will now do its best to gracefully handle device disconnection and sample rate changes
- The cpal backend now works in wasm environments
- Fix static sounds not pausing/resuming/stopping immediately when playback is waiting for a clock tick
- Remove
From<f64>implementation forClockSpeed - Change
AudioManager::add_clockto take aClockSpeedargument instead of animpl Into<ClockSpeed>argument
- Fix clocks not resetting their fractional position when stopped
- Fix clock tick 0 occurring one tick after the clock is started instead of immediately when the clock is started
- Fix static sound pause/resume/stop fades never starting when the start time is set to a clock time
- Remove
ClockandClocksfrom the public API - Sounds and effects now have an
on_clock_tickcallback instead of having a&Clocksargument passed intoprocess - Remove parameters
- Settings that were previously
Values can now be tweened directly without needing to link them to a parameter - All functions that send commands to the renderer now use
CommandErroras their error type - Effects now have a similar structure to sounds
EffectBuilder- trait for types that can be converted to anEffectand a handleEffect- runs on the renderer
TrackSettingsis nowTrackBuilder. Effects can be added by passing anEffectBuildertoTrackBuilder::add_effect.- Changes to the built-in effects:
- Removed
Distortionfrom the public API,DistortionSettingsis nowDistortionBuilder, addedDistortionHandle - Removed
Delayfrom the public API,DelaySettingsis nowDelayBuilder, addedDelayHandle - Removed
Reverbfrom the public API,ReverbSettingsis nowReverbBuilder, addedReverbHandle - Removed
Filterfrom the public API,FilterSettingsis nowFilterBuilder, addedFilterHandle
- Removed
- Renamed
TweenabletoTweener - Added a
Tweenabletrait for things that aTweenercan control.Tweeneris now generic over the type of theTweenablevalue - Volume settings now use the
Volumetype instead off64 - Playback rate settings now use the
PlaybackRatetype instead off64 - Clock speed settings now use the
ClockSpeedtype instead off64 - Fix audio artifacts when a static sound loops
- Slight performance improvement when sounds are center-panned
- Allow configuring the main mixer track using a
TrackBuilderinAudioManagerSettings
- Fix looping static sounds with a loop start position greater than 0.0 starting playback at that position. (The intended behavior is that the sound will still start at the beginning, but jump back to the loop start position after reaching the end.)
Complete rewrite, most things have changed
- Fix an issue where the
AudioManagercleanup would fail if there are existing track handles
- Added
Sound::from_mp3_reader,Sound::from_ogg_reader,Sound::from_flac_reader, andSound::from_wav_reader(thanks @Zicklag!) - (Hopefully) fixed an issue where capacities (the maximum number of instances, sequences, etc.) could decrease over time
- Added a
Defaultimplementation forTrackSends - Fixed a compile error when building Kira with the
serde_supportfeature enabled
- Added send tracks, which you can route sub-tracks to in addition to their parent track. This is useful for sharing effects between multiple sub-tracks.
- Made the
volumesetting forTracks aValue<f64>, which means you can link it to a parameter - Added
Main/Sub/SendTrackHandle::set_volume - Added an
initcallback to theEffecttrait - Added new effects:
Distortion,Delay, andReverb - Added a
mixsetting for effects, which lets you blend dry and wet signal - Added
InstanceHandle::position, which gets the current playback position of the instance - Added
CachedValue::with_valid_rangefor clamping values
- The default filter cutoff is no longer outside of the range of human hearing
- Changed settings structs with an
idfield to useOption<Id>. This eliminates a confusing situation where cloning the same settings struct and passing it to multiple objects results in each object overwriting the previous one since it has the same ID. - Changes to errors related to sending commands to the audio thread:
- Command-sending related errors are now listed in the
CommandErrorenum BackendDisconnectedis no longer included in error enums- Handle structs whose only error variant was
BackendDisconnectednow return aCommandError TrackHandleErrorwas split intoAddEffectErrorandRemoveEffectError
- Command-sending related errors are now listed in the
MetronomeHandle.event_iterhas been replaced withMetronomeHandle.pop_event, which works the same way asSequenceInstanceHandle.pop_event- Changed all occurrences of the term "pitch" to "playback rate"
Added serde support for Arrangements and SoundClips
Kira now runs on any platform supporting wasm32 and having a cpal backend.
This means one can now run an instance of Kira in a web browser.
The API has gone through a major revision. Previously, to do just about
anything, you would have to use the AudioManager:
audio_manager.stop_instance(instance_id)?;
audio_manager.set_metronome_tempo(Tempo(128.0))?;
// etc...This meant that you had to pass a reference to the audio manager to every part
of the code that needs it. It also meant that the AudioManager struct had an
overwhelming number of methods.
The API has been changed so that whenever you create a new thing (like a sound, an instance, or a mixer track), you receive a handle to that thing that you can use to control it.
let mut sound = audio_manager.load_sound("sound.ogg", SoundSettings::default())?;
let mut instance = sound.play(InstanceSettings::default())?;
instance.set_pitch(2.0)?;You can now create multiple metronomes. Each sequence instance can be assigned
to a different metronome, and interval events can be received from a
MetronomeHandle:
let mut metronome = audio_manager.add_metronome(
MetronomeSettings::new().interval_events_to_emit([0.25, 0.5, 1.0]))?;
audio_manager.start_sequence({
let mut sequence = Sequence::<()>::new(SequenceSettings::default());
// sequence code
sequence
}, SequenceInstanceSettings::new().metronome(&metronome))?;
metronome.start()?;
for interval in metronome.event_iter() {
println!("{}", interval);
}Most people will only need one metronome at a time - the main point of this is
to move more functionality out of the AudioManager struct.
Sequences and most config structs now have serialization/deserialization support
via the serde_support feature.
The capacity limits specified in AudioManagerSettings are now enforced, and
the audio manager will also check that when you remove something with an ID,
something with that ID actually exists. Because this creates a lot of new error
variants, the large AudioError enum has been split up into smaller,
situational error enums.
Previously, custom events emitted by sequences were retrieved by calling
AudioManager::pop_event, which meant that the audio manager had a generic type
parameter for custom events, and every sequence had to emit custom events of the
same type.
Now, each sequence has its own custom event type, and you receive those events
from an EventReceiver that the audio manager returns when you call
AudioManager::add_sequence. This gives you more flexibility in how you
organize your custom events as well as moving some functionality out of the
AudioManager struct, which already has a lot of methods.
Audio streams provide a way of sending arbitrary audio data to the mixer. Sometimes, you need to play audio that you generate in real time, like voice chats. This feature lets you do that.
Sounds, arrangements, and sequences can now be grouped so that they can all be paused, resumed, or stopped at once. This is useful for controlling broad categories of sounds, like gameplay sounds or music.
- Added
Sequence::play_random - Added
Value::Random - Renamed
Sound::newtoSound::from_frames - Audio file format decoding is now gated behind feature flags
- Changed functions for pausing, resuming, and stopping instances to take
settings structs (
PauseInstanceSettings,ResumeInstanceSettings, andStopInstanceSettings) - When resuming an instance, you can now choose to have it seek backward to the time when it was paused. This is useful if you need to keep audio synced up with something in-game, but you still want a smooth fade out when pausing the game.
- Renamed
Sequence::emit_custom_eventtoSequence::emit - Added
AudioManager::seek_instanceandAudioManager::seek_instance_tofor changing the playback positions of running instances - Refined the behavior of looping backwards instances
- Added
Tween::linear - Make
Arrangement::settingsprivate and add settings parameters toArrangement::new_loopandArrangement::new_loop_with_intro
This release adds Arrangements, which allow you to stitch together multiple
sounds into a larger sound that you can play instances of.
The main use case for this is setting up seamless loops, including looping songs with intros. The previous release could create seamless loops, but only if the sound didn't have an intro.
Functions that dealt with instances of sounds now deal with instances of sounds
or arrangements. InstanceSettings has become PlayableSettings to
correspond to the new Playable enum.
Arrangements also help reduce some complexity from the code for instances and make some more unusual behaviors, like playing instances backwards or rewinding instances (not implemented yet, but planned), easier to reason about.
I'm sure there's other good uses for arrangements, too! But I think the most common use case will be songs with intros.
- Remove
SoundMetadataand movesemantic_durationintoPlayableSettings - Rename
StereoSampletoFrame - Added support for panning instances:
- Added
Frame::panned - Added a
panningfield and method toInstanceSettings - Added
AudioManager::set_instance_panning - Added
Sequence::set_instance_panning
- Added
- Added parameter mappings, which allow
Values to map to parameters with custom scaling and offsets.Value::Parameternow contains aMappingas its second piece of data.ParameterIds can be converted intoValue::Parameters with the default 1:1 mapping. - Changed
Tweento a C-style struct with named fields:duration- the duration of the tweeneasing- the easing function to use (linear, power, etc.)ease_direction- the easing direction (in, out, in-out)
- Added chainable methods to more settings structs
- Replaced
AudioManager::eventswithAudioManager::pop_event - Add
Sequence:pause/stop/resume_sequence - Replace
AudioError::SupportedStreamConfigsErrorwithAudioError::DefaultStreamConfigError
Changes:
- Update cpal to 0.13.1
- Fix a crash when using a mono output config
- Use the system's default output config instead of the config with the highest sample rate in the first valid range
Changes:
- Fix readme path in Cargo.toml
First public release