Skip to content

Updating GlobalVolume now updates the volume of any playing (Spatial)AudioSinks #19168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Cyberboss
Copy link
Contributor

Objective

Fixes #18952

Solution

Adds a system that iterates playing audio sinks and reconfigures the volume if GlobalVolume changes. Volume change is based on the initial PlaybackSettings.

Testing

Adjusted game_menu example to play music in the volume screen and actually made that volume slider modify GlobalVolume.


Showcase

output.webm

@Cyberboss Cyberboss force-pushed the 18952-GlobalVolumeLiveUpdate branch from 1b2aee6 to 358b26e Compare May 10, 2025 20:48
@Cyberboss Cyberboss force-pushed the 18952-GlobalVolumeLiveUpdate branch from 358b26e to 405fa13 Compare May 10, 2025 21:14
@Cyberboss Cyberboss marked this pull request as draft May 11, 2025 02:56
@rparrett rparrett self-requested a review May 11, 2025 14:44
@Cyberboss
Copy link
Contributor Author

Cyberboss commented May 12, 2025

Might've bitten off a bit more than I can chew here. Looking into the validation failure, it seems like other systems that operation on AudioSinks take &self and rely on mutexes to remain exclusive. Not sure I'm comfortable making that kind of change.

@janhohenheim janhohenheim added A-Audio Sounds playback and modification S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 12, 2025
@janhohenheim janhohenheim added D-Straightforward Simple bug fixes and API improvements, docs, test and examples D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Design This issue requires design work to think about how it would best be accomplished and removed D-Straightforward Simple bug fixes and API improvements, docs, test and examples labels May 12, 2025
@mgi388
Copy link
Contributor

mgi388 commented May 13, 2025

I'm curious if there's value in Bevy having a GlobalVolume at all. In my own codebase, I don't use GlobalVolume at all.

Part of the reason is that different types of sounds have their own volume anyway, so the global/master volume setting is only half the equation. For example, I have a music volume setting, sound effect volume setting, conversation volume setting and voice over volume setting. And then each of my sounds can have their own per-sound volume.

I have systems like this:

app.add_systems(
    Update,
    update_volume.run_if(resource_exists_and_changed::<SoundConfig>),
);

fn update_volume(sound_config: Res<SoundConfig>, query: Query<(&AudioSink, &SoundEffectSettings)>) {
    for (sink, settings) in query.iter() {
        sink.set_volume(
            sound_config
                .sound_effect_volume(Volume::Amplitude(settings.linear_volume() as f64))
                .as_amplitude() as f32,
        );
    }
}

Its purpose is to modify currently playing sounds to make their volume update based on the player changing volume settings in the options screen.

(Ignore the verbosity of volume linear/amplitude calculation in this system, it's not relevant)

But notice that I call sound_config.sound_effect_volume(). The internals of that function aren't important to share here, but it needs to incorporate all these volumes:

  1. Global/master volume setting. Players change this in their settings.
  2. Sound effect volume setting. Players change this in their settings.
  3. The volume of the actual sound effect sound we're looping over and changing. This comes from SoundEffectSettings which is a per-sound effect component.

And return the combined volume for that sound.

All that is to say, does it make sense for Bevy to have GlobalVolume? I'm not fussed either way as long as I can ignore it (which I currently do). But I'm also happy making my code use it if it ends up making sense.

Copy link
Contributor

@rparrett rparrett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing a quick little draft-mode review to hopefully get you unstuck.

The big scary ambiguity warning isn't quite as scary as it seems.

Bevy's scheduler will handle keeping the mutable accesses exclusive. CI just wants to make sure that we're either defining an order for systems to run in when we're modifying/accessing something in multiple systems and the order in which it happens is ambiguous.

This can be resolved by either telling Bevy that it's okay for the systems to run in any order (by adding .ambiguous_with(system) or .ambiguous_with_all()), or defining an order (by adding .after(system), .before(system).

After fixing the add_systems call I mentioned in another comment, you should be left with four ambiguities:

update_playing_audio_volume <-> update_emitter_positions
update_playing_audio_volume <-> update_listener_positions
update_playing_audio_volume <-> cleanup_finished_audio<Pitch>
update_playing_audio_volume <-> cleanup_finished_audio<AudioSource>

At a glance, the particular ordering of these systems doesn't seem super important, so I'd start the conversation by just adding .ambiguous_with_all() when adding the update_playing_audio_volume system.

@Cyberboss Cyberboss marked this pull request as ready for review May 13, 2025 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Audio Sounds playback and modification D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Design This issue requires design work to think about how it would best be accomplished S-Needs-Review Needs reviewer attention (from anyone!) to move forward
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

Make GlobalVolume change running audio
4 participants