Skip to content

Audio Sink Creation Delayed and Multiple Sinks Spawned #13881

@ivanstepanovftw

Description

@ivanstepanovftw

Bevy version

main aaccbe8

Relevant system information

  • Fedora Linux 40 (Workstation Edition)
    $ uname -a
    Linux fedora 6.8.11-300.fc40.x86_64 #1 SMP PREEMPT_DYNAMIC Mon May 27 14:53:33 UTC 2024 x86_64 GNU/Linux
    

What you did

Tried to play audio if it is not yet playing in Update system loop.

use bevy::audio::Volume;
use bevy::ecs::query::QuerySingleError;
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Update, _update_spawn_audio)
        .run();
}

#[derive(Component)]
pub struct Beatmap;

fn _update_spawn_audio(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    query: Query<&AudioSink, With<Beatmap>>
) {
    println!("Query: {}", query.iter().count());

    match query.get_single() {
        Ok(sink) => {
            println!("Ok(sink)");
        }
        Err(QuerySingleError::NoEntities(_)) => {
            println!("Err(QuerySingleError::NoEntities(_))");

            commands.spawn((
                Beatmap,
                AudioBundle {
                    source: asset_server.load("sounds/loop.ogg"),
                    settings: PlaybackSettings::LOOP.with_volume(Volume::new(0.1))
                },
            ));
        }
        Err(QuerySingleError::MultipleEntities(_)) => {
            println!("QuerySingleError::MultipleEntities(_)");
        }
    }
}

Output:

Query: 0
Err(QuerySingleError::NoEntities(_))
Query: 0
Err(QuerySingleError::NoEntities(_))
Query: 2
QuerySingleError::MultipleEntities(_)

After suggestion to use Resources, tried to manually loop audio:

use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Update, (
            update,
        ))
        .run();
}

#[derive(Resource)]
pub struct Beatmap {
    entity: Entity,
}

#[derive(Component)]
pub struct BeatmapAudio;

fn update(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    beatmap: Option<ResMut<Beatmap>>,
    query_sink: Query<&AudioSink, With<BeatmapAudio>>,
) {
    match beatmap {
        Some(beatmap) => {
            if query_sink.iter().count() >= 2 {
                println!("bug: sink count: {:?}", query_sink.iter().count());
            }
            if query_sink.iter().count() == 0 {
                commands.remove_resource::<Beatmap>();
            }
        }
        None => {
            let entity = commands.spawn((
                BeatmapAudio,
                AudioBundle {
                    source: asset_server.load("sounds/tss.wav"),
                    settings: PlaybackSettings::DESPAWN
                },
            )).id();
            commands.insert_resource(Beatmap {
                entity,
            });
        }
    }
}

Output:

bug: sink count: 2
...

What went wrong

  • Expected that audio sink is created immediately.
  • Instead, sink is created 2 frames later.
  • Expected that it is possible to manually loop the audio.
  • Instead, 2 sinks created.

Additional information

Related discussions:

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-AudioSounds playback and modificationC-BugAn unexpected or incorrect behaviorD-ModestA "normal" level of difficulty; suitable for simple features or challenging fixesS-Needs-InvestigationThis issue requires detective work to figure out what's going wrong

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions