bevy/crates
mgi388 7749c9945b
Add ability to mute audio sinks (#16813)
# Objective

- Allow users to mute audio.

```rust
fn mute(
    keyboard_input: Res<ButtonInput<KeyCode>>,
    mut sink: Single<&mut AudioSink, With<MyMusic>>,
) {
    if keyboard_input.just_pressed(KeyCode::KeyM) {
        sink.toggle_mute();
    }
}
```

- I want to be able to press, say, `M` and mute all my audio. I want
this for dev, but I'm sure it's a useful player setting as well.
- Muting is different to pausing—I don't want to pause my sounds, I want
them to keep playing but with no volume. For example if I have
background music playing which is made up of 5 tracks, I want to be able
to temporarily mute my background music, and if I unmute at, say, track
4, I want to play track 4 rather than have had everything paused and
still be on the first track.
- I want to be able to continue to control the volume of my audio even
when muted. Like in the example, if I have muted my audio but I use the
volume up/down controls, I want Bevy to remember those volume changes so
that when I unmute, the volume corresponds to that.

## Solution

- Add methods to audio to allow muting, unmuting and toggling muting.
- To preserve the user's intended volume, each sink needs to keep track
of a "managed volume".
- I checked `rodio` and I don't see any built in support for doing this,
so I added it to `bevy_audio`.
- I'm interested to hear if this is a good idea or a bad idea. To me,
this API looks nice and looks usable, but I'm aware it involves some
changes to the existing API and now also requires mutable access in some
places compared to before.
- I'm also aware of work on *Better Audio*, but I'm hoping that if this
change isn't too wild it might be a useful addition considering we don't
really know when we'll eventually get better audio.

## Testing

- Update and run the example:  `cargo run --example audio_control`
- Run the example:  `cargo run --example soundtrack`
- Update and run the example:  `cargo run --example spatial_audio_3d`
- Add unit tests.

---

## Showcase

See 2 changed examples that show how you can mute an audio sink and a
spatial audio sink.

## Migration Guide

- The `AudioSinkPlayback` trait now has 4 new methods to allow you to
mute audio sinks: `is_muted`, `mute`, `unmute` and `toggle_mute`. You
can use these methods on `bevy_audio`'s `AudioSink` and
`SpatialAudioSink` components to manage the sink's mute state.
- `AudioSinkPlayback`'s `set_volume` method now takes a mutable
reference instead of an immutable one. Update your code which calls
`set_volume` on `AudioSink` and `SpatialAudioSink` components to take a
mutable reference. E.g.:

Before:

```rust
fn increase_volume(sink: Single<&AudioSink>) {
    sink.set_volume(sink.volume() + 0.1);
}
```

After:

```rust
fn increase_volume(mut sink: Single<&mut AudioSink>) {
    let current_volume = sink.volume();
    sink.set_volume(current_volume + 0.1);
}
```

- The `PlaybackSettings` component now has a `muted` field which you can
use to spawn your audio in a muted state. `PlaybackSettings` also now
has a helper method `muted` which you can use when building the
component. E.g.:

```rust
commands.spawn((
    // ...
    AudioPlayer::new(asset_server.load("sounds/Windless Slopes.ogg")),
    PlaybackSettings::LOOP.with_spatial(true).muted(),
));
```

---------

Co-authored-by: Nathan Graule <solarliner@gmail.com>
2024-12-15 19:19:16 +00:00
..
bevy_a11y Remove accesskit re-export from bevy_a11y (#16257) 2024-11-08 21:01:16 +00:00
bevy_animation Support tuple structs in AnimatedField (#16747) 2024-12-11 17:06:08 +00:00
bevy_app Update hashbrown to 0.15 (#15801) 2024-12-10 19:45:50 +00:00
bevy_asset Fix stale comment on LoadContext::finish. (#16821) 2024-12-15 19:18:03 +00:00
bevy_audio Add ability to mute audio sinks (#16813) 2024-12-15 19:19:16 +00:00
bevy_color Deny derive_more error feature and replace it with thiserror (#16684) 2024-12-06 17:03:55 +00:00
bevy_core Update hashbrown to 0.15 (#15801) 2024-12-10 19:45:50 +00:00
bevy_core_pipeline Make indirect drawing opt-out instead of opt-in, enabling multidraw by default. (#16757) 2024-12-13 06:16:57 +00:00
bevy_derive Use one BevyManifest instance in proc macros (#16766) 2024-12-15 15:00:05 +00:00
bevy_dev_tools Draw the UI debug overlay using the UI renderer (#16693) 2024-12-11 00:49:47 +00:00
bevy_diagnostic Update hashbrown to 0.15 (#15801) 2024-12-10 19:45:50 +00:00
bevy_dylib Generate links to definition in source code pages on docs.rs and dev-docs.bevyengine.org (#12965) 2024-07-29 23:10:16 +00:00
bevy_ecs Use one BevyManifest instance in proc macros (#16766) 2024-12-15 15:00:05 +00:00
bevy_encase_derive Use one BevyManifest instance in proc macros (#16766) 2024-12-15 15:00:05 +00:00
bevy_gilrs Deny derive_more error feature and replace it with thiserror (#16684) 2024-12-06 17:03:55 +00:00
bevy_gizmos Use one BevyManifest instance in proc macros (#16766) 2024-12-15 15:00:05 +00:00
bevy_gltf Remove the meta field from LoadedAsset and ErasedLoadedAsset. (#15487) 2024-12-13 20:40:02 +00:00
bevy_hierarchy rename enqueue_command to queue_command for consistency (#16753) 2024-12-11 00:53:54 +00:00
bevy_image ✏️ Fix typos across bevy (#16702) 2024-12-08 01:18:39 +00:00
bevy_input Deny derive_more error feature and replace it with thiserror (#16684) 2024-12-06 17:03:55 +00:00
bevy_input_focus Improve bevy_input_focus (#16749) 2024-12-12 19:15:08 +00:00
bevy_internal Draw the UI debug overlay using the UI renderer (#16693) 2024-12-11 00:49:47 +00:00
bevy_log Use en-us locale for typos (#16037) 2024-10-20 18:55:17 +00:00
bevy_macro_utils Use one BevyManifest instance in proc macros (#16766) 2024-12-15 15:00:05 +00:00
bevy_math Derivative access patterns for curves (#16503) 2024-12-10 20:27:37 +00:00
bevy_mesh Update hashbrown to 0.15 (#15801) 2024-12-10 19:45:50 +00:00
bevy_mikktspace Use en-us locale for typos (#16037) 2024-10-20 18:55:17 +00:00
bevy_pbr Make #[bindless] in ExtendedMaterial actually enable bindless mode. (#16818) 2024-12-15 19:18:58 +00:00
bevy_picking Reorder PickSet::Focus systems (#16791) 2024-12-13 18:55:22 +00:00
bevy_ptr Fix MSRVs for standalone crates (#16333) 2024-11-17 09:38:13 +00:00
bevy_reflect Use one BevyManifest instance in proc macros (#16766) 2024-12-15 15:00:05 +00:00
bevy_remote BRP strict field in query (#16725) 2024-12-14 05:22:19 +00:00
bevy_render Make #[bindless] in ExtendedMaterial actually enable bindless mode. (#16818) 2024-12-15 19:18:58 +00:00
bevy_scene Add missing #[reflect(Component, Default)] to SceneRoot and DynamicSceneRoot. (#16816) 2024-12-15 19:18:22 +00:00
bevy_sprite BorderRect maintenance (#16727) 2024-12-12 04:33:44 +00:00
bevy_state Use one BevyManifest instance in proc macros (#16766) 2024-12-15 15:00:05 +00:00
bevy_tasks Add no_std support to bevy_tasks (#15464) 2024-12-06 02:14:54 +00:00
bevy_text fix tiny copy-paste mistake in bevy_text::font_atlas_set (#16667) 2024-12-10 03:17:09 +00:00
bevy_time Use en-us locale for typos (#16037) 2024-10-20 18:55:17 +00:00
bevy_transform Deny derive_more error feature and replace it with thiserror (#16684) 2024-12-06 17:03:55 +00:00
bevy_ui Made UIRect initialisation functions const (#16823) 2024-12-15 19:17:43 +00:00
bevy_utils Update hashbrown to 0.15 (#15801) 2024-12-10 19:45:50 +00:00
bevy_window add missing type registration for Monitor (#16685) 2024-12-06 15:20:10 +00:00
bevy_winit Rename trigger.entity() to trigger.target() (#16716) 2024-12-08 21:55:09 +00:00