bevy_kira_audio

repository·main·Indexed 19 days ago

https://github.com/niklasei/bevy_kira_audio

A Bevy plugin that integrates the Kira audio engine to provide a robust alternative to Bevy's default audio system. It supports multiple formats (ogg, mp3, wav, flac), channel-based control, smooth audio transitions via AudioTween, and limited spatial audio support. Version 0.26.0.

Tokens
9K
Snippets
35
Records
39
Agent score
66%

What's inside bevy_kira_audio

  1. How audio channels and instances work

    main

    The plugin provides two primary ways to manage audio:

    1. Audio Channels: You can control an entire channel. Changes to a channel (like volume, panning, or playback speed) affect all sounds playing within that channel. Channels can be customized and accessed via Bevy's ECS.
    2. Audio Instances: You can control a single, specific instance of a playing sound independently of its channel.

    Both methods support audio transitions using Tweens and various easing functions.

  2. Run bevy_kira_audio examples

    main

    You can explore the capabilities of bevy_kira_audio by running the provided examples. Use the following command to run a specific example:

    cargo run --example <example_name>

    Available examples include:

    • basic: Basic functionality display.
    • channel_control: Controlling an audio channel.
    • custom_channel: Adding and using a custom audio channel.
    • dynamic_channels: Using dynamic audio channels.
    • instance_control: Controlling a single audio instance.
    • multiple_channels: GUI application with control over three different audio channels.
    • settings: Supported settings when playing a sound.
    • settings_loader: Loading a sound with applied settings.
    • spatial: Limited support for spatial audio.
    • status: Continuously getting the playback state of a sound.
    • stress_test: Playing a high number of sounds every frame.
    cargo run --example basic
  3. Setup bevy_kira_audio in a Bevy project

    main

    To use bevy_kira_audio, you must disable Bevy's default audio feature, as it is incompatible. When configuring your Bevy dependencies, ensure you use the default features minus audio (e.g., "2d", "3d", "ui").

    To play audio files, you must enable the corresponding format features in bevy_kira_audio: ogg (enabled by default), mp3, wav, or flac.

    use bevy_kira_audio::prelude::*;
    use bevy::prelude::*;
    
    fn main() {
       App::new()
            .add_plugins((DefaultPlugins, AudioPlugin))
            .add_systems(Startup, start_background_audio)
            .run();
    }
    
    fn start_background_audio(asset_server: Res<AssetServer>, audio: Res<Audio>) {
        audio.play(asset_server.load("background_audio.ogg")).looped();
    }
  4. How Audio channels and the MainTrack work

    main

    The audio engine is organized into channels. By default, the plugin provides a MainTrack which is exposed via the Audio type alias (type Audio = AudioChannel<MainTrack>;).

    • MainTrack: The default channel used for general audio playback.
    • AudioChannel<T>: A resource used to play and control sounds on a specific track. You can define your own custom channels using AudioApp::add_audio_channel.
  5. Identify audio channels using Channel enum

    main

    Audio can be organized into channels to allow for grouped control. The Channel enum supports two types of identification:

    1. Typed(TypeId): Uses a Rust TypeId for type-safe channel identification.
    2. Dynamic(String): Uses a string identifier for flexible, name-based channel management.
    #[derive(Clone, PartialEq, Eq, Hash)]
    pub enum Channel {
        Typed(TypeId),
        Dynamic(String),
    }
  6. Load audio with pre-configured settings via RON

    main

    If the settings_loader feature is enabled, you can define audio settings in .ron files. This allows you to load an AudioSource that already has specific behaviors (like looping or intros) applied by default.

    Example .ron configuration for a looping sound with a 3-second intro:

    (
        // The actual sound asset in your assets directory
        asset: "sounds/loop.ogg",
    
        loop_behavior: Some(3.0),
    )
  7. How spatial audio emitters and receivers work together

    main

    Spatial audio is implemented using a producer-consumer model with two primary components:

    1. SpatialAudioReceiver: Represents the listener (e.g., the Camera or the Player). Important: There can only be exactly one entity with this component in the world at any given time.
    2. SpatialAudioEmitter: Represents the source of the sound. You add this to entities that should emit sound. It holds a list of Handle<AudioInstance>s that will be automatically panned and attenuated based on the distance and angle to the receiver.

    The plugin calculates volume based on distance (attenuation) and panning based on the angle relative to the receiver's orientation.

    // Example setup
    // 1. The Receiver (usually on the camera)
    commands.spawn((Camera3dBundle::default(), SpatialAudioReceiver));
    
    // 2. The Emitter (on a sound-producing entity)
    commands.spawn((SpatialAudioEmitter { instances: vec![my_audio_handle] }, Transform::from_xyz(10.0, 0.0, 0.0)));
  8. Install and setup the AudioPlugin

    main

    To use bevy_kira_audio, add the AudioPlugin to your Bevy App. This initializes the Audio resource (the default MainTrack), asset loaders for supported formats (MP3, OGG, WAV, FLAC, etc.), and the internal audio management systems.

    Note that you must also include Bevy's AssetPlugin for the audio assets to load correctly.

    use bevy_kira_audio::prelude easily;
    use bevy::prelude easily;
    use bevy::asset::AssetPlugin;
    
    fn main() {
        App::new()
            .add_plugins(MinimalPlugins)
            .add_plugins(AssetPlugin::default())
            .add_plugins(AudioPlugin)
            .add_systems(Startup, start_background_audio)
            .run();
    }
    
    fn start_background_audio(asset_server: Res<AssetServer>, audio: Res<Audio>) {
        // Play a looped background track
        audio.play(asset_server.load("background_audio.mp3")).looped();
    }
  9. Set up the SpatialAudioPlugin

    main

    To enable spatial audio in your Bevy application, add the SpatialAudioPlugin to your App. This plugin manages the relationship between audio emitters and a receiver, calculating volume attenuation and panning based on their relative positions in 3D space.

    use bevy::prelude::*;
    use bevy_kira_audio::SpatialAudioPlugin;
    
    fn main() {
        App::new()
            .add_plugins(DefaultPlugins)
            .add_plugins(SpatialAudioPlugin)
            .run();
    }
  10. Add audio channels to your Bevy App

    main

    To use typed audio channels, use the add_audio_channel::<T>() extension method on your Bevy App. This registers the necessary systems and inserts the AudioChannel<T> resource.

    1. Define a marker struct for your channel.
    2. Call .add_audio_channel::<YourMarker>() during app setup.
    3. Access the channel via Res<AudioChannel<YourMarker>> in your systems.
    use bevy::prelude::*;
    use bevy_kira_audio::prelude::*;
    
    #[derive(Resource)]
    struct Background;
    
    fn main() {
        App::new()
            .add_plugins(DefaultPlugins)
            .add_plugins(AudioPlugin)
            .add_audio_channel::<Background>() // Register the channel
            .add_systems(Startup, setup_audio)
            .run();
    }
    
    fn setup_audio(mut background: ResMut<AudioChannel<Background>>, asset_server: Res<AssetServer>) {
        // Use the channel to play a sound
        background.play(asset_server.load("sounds/loop.ogg"));
    }
  11. Configure sound settings and playback behavior

    main

    You can configure audio properties like volume, panning, playback rate, and looping at the moment of playback. Most changes can be applied as smooth transitions using AudioTween and AudioEasing.

    Key methods for configuring playback:

    • .loop_from(duration): Sets a specific point in the track to loop from (useful for 'intro' sections).
    • .fade_in(AudioTween): Smoothly increases volume.
    • .with_panning(value): Sets stereo panning (e.g., 1.0 for right ear).
    • .with_playback_rate(value): Changes speed and pitch.
    • .with_volume(decibels): Sets volume in decibels.
    • .reverse(): Plays the track in reverse.
    use bevy_kira_audio::prelude::*;
    use bevy::prelude::*;
    use std::time::Duration;
    
    fn play_audio(asset_server: Res<AssetServer>, audio: Res<Audio>) {
        audio.play(asset_server.load("background_audio.ogg"))
            // The first 0.5 seconds will not be looped and are the "intro"
            .loop_from(0.5)
            // Fade-in with a dynamic easing
            .fade_in(AudioTween::new(Duration::from_secs(2), AudioEasing::OutPowi(2)))
            // Only play on our right ear
            .with_panning(1.0)
            // Increase playback rate by 50% (this also increases the pitch)
            .with_playback_rate(1.5)
            // Play at lower volume (-10dB)
            .with_volume(-10.)
            // play the track reversed
            .reverse();
    }