A Bevy plugin to use Kira for game audio

Overview

Bevy Kira audio

Crates.io license Crates.io

This bevy plugin is intended to try integrating Kira into Bevy. The end goal would be to replace or update bevy_audio, if Kira turns out to be a good approach. Currently, this plugin can play .ogg, .mp3, .flac, and .wav formats and supports web builds for everything except for mp3.

I am using Oicana as "guinea pig project" and will keep it's game audio plugin up to date with this crate. You can also check out the examples directory in this repository for a display of this plugin's functionality.

Usage

To initialize the corresponding AssetLoaders, use at least one of the features ogg, mp3, wav, or flac. The following example assumes that bevy_kira_audio/ogg is used.

use bevy_kira_audio::{Audio, AudioPlugin};

// in your game's AppBuilder:
// app.add_plugin(AudioPlugin)

fn my_audio_system(
    asset_server: Res<AssetServer>,
    audio: Res<Audio>,
) {
    let music_handle = asset_server.get_handle("sounds/music.ogg");
    audio.play(music_handle);
}

Current state

  • play common audio formats
    • ogg
    • mp3
    • wav
    • flac
  • web support
    • The features ogg, flac and wav can be build for WASM. There are some differences between browsers:
      • Firefox: The audio might sound distorted (trying to figure out why)
      • Chrome: an interaction with the website is required before the AudioContext is started (e.g. a button click). Currently, the plugin cannot restart the AudioContext after an interaction.
  • pause/resume and stop tracks
  • play a track on repeat
  • control volume
  • control pitch
  • control panning
  • get the current status of a track (time elapsed/left)?

License

This crate is distributed under the terms of the MIT license.

Substantial parts of the asset loaders were taken from Kira (MIT license Copyright 2020 Andrew Minnich).

Assets in the examples might be distributed under different terms. See the readme in the examples directory.

Comments
  • Can not use `AudioSource` with bevy_asset_loader on the latest main branch

    Can not use `AudioSource` with bevy_asset_loader on the latest main branch

    The following code fails to compile on the latest commit of bevy_kira_audio (b721820). This issue is very similar to #31, however I can't find a commit that works for me. I absolutely need the feature introduced on this commit, but no commit after this one compiles successfully.

    I also do not understand why this error is thrown in the first place. this code clearly shows that TypeUuid is defined for AudioSource so I'm not sure where the error is coming from.

    Failing code:

    #[derive(AssetCollection)]
    pub struct AudioAssets {
        #[asset(path = "audio/flying.ogg")]
        pub flying: Handle<AudioSource>,
    }
    

    Error:

    error[E0277]: the trait bound `AudioSource: TypeUuid` is not satisfied
       --> src/loading.rs:34:17
        |
    34  |     pub flying: Handle<AudioSource>,
        |                 ^^^^^^^^^^^^^^^^^^^ the trait `TypeUuid` is not implemented for `AudioSource`
        |
    

    Cargo.toml

    ...
    
    [features]
    default = [
        "bevy_kira_audio/ogg",
        "bevy/bevy_winit",
        "bevy/render",
        "bevy/png",
        "bevy/x11",
    ]
    
    dev = ["bevy/dynamic"]
    
    [dependencies]
    bevy = { git = "https://github.com/bevyengine/bevy", rev = "7d554146524987b050923841de06c7d18adf66e9", default-features = false }
    bevy_kira_audio = { git = "https://github.com/NiklasEi/bevy_kira_audio", rev = "b721820d0f7b479a136cc2a9d51c23bbedd2934e" }
    bevy_asset_loader = "0.11.0"
    rand = "0.8.5"
    
    [target.'cfg(target_os = "linux")'.dependencies]
    winit = { version = "0.26.1", features = ["x11"] }
    
    [build-dependencies]
    embed-resource = "1.7.2"
    
    ...
    
    opened by developomp 13
  • Playback time available from new playback InstanceHandle

    Playback time available from new playback InstanceHandle

    As discussed in #23

    TODO

    • [x] Get play state from Res<Audio>.state(handle), including: an enum with Playing, Paused, Stopped; a position as Option<f64>.
    • [x] Merge InstanceHandlePriv into InstanceHandle
    • [x] Rename InstanceState.priv_ => .handle
    • [x] Write an example
    opened by fluffysquirrels 13
  • audio_output.instances not cleaned up properly

    audio_output.instances not cleaned up properly

    I stress tested an application Im making (for fun really) and it plays audio. Due to the high volume of play commands added I started to get log messages that I think originates from the CommandQueueFull error (perhaps kira printed it?).

    I did a profiling and ran the stress test and basically even long after all audio stops playing this method: https://github.com/NiklasEi/bevy_kira_audio/blob/a08ee2a4e3719cfbffbbca5f3feb61690e2233c6/src/audio_output.rs#L454 continues to take up in the profiling I did 34-35ms of frame-time (steadily growing from almost no time at start of app then really going haywire after a while). My guess is that the cleanup_stopped_instances don't detect them as faulty or even started but they still exist in the vector or something.

    opened by Elogain 11
  • Strange issue with latest bevy main

    Strange issue with latest bevy main

    error[E0277]: the trait bound `AudioSource: TypeUuid` is not satisfied
      --> src/states/mod.rs:8:22
       |
    8  |     pub loop_handle: Handle<AudioSource>,
       |                      ^^^^^^^^^^^^^^^^^^^ the trait `TypeUuid` is not implemented for `AudioSource`
       |
       = note: required because of the requirements on the impl of `Asset` for `AudioSource`
    note: required by a bound in `bevy::prelude::Handle`
      --> /Users/visual/.cargo/git/checkouts/bevy-f7ffde730c324c74/91c3b21/crates/bevy_asset/src/handle.rs:65:8
       |
    65 |     T: Asset,
       |        ^^^^^ required by this bound in `bevy::prelude::Handle`
    
    For more information about this error, try `rustc --explain E0277`.
    
    opened by ChefKissInc 10
  • Firefox Sound Observations πŸ”₯ 🦊 πŸ”‰ πŸ”

    Firefox Sound Observations πŸ”₯ 🦊 πŸ”‰ πŸ”

    I saw the note in the readme about sound playback issues in Firefox and I just wanted to share my experiencewith my own Bevy Kira plugin on web ( I'm not using this plugin, but I am using Kira ).

    I also had audio issues on Firefox, but I noticed that Firefox is also using almost 100% of one of my CPU cores. If I resize the browser window so that it is much smaller, though, the CPU usage goes down and the sound playback works nicely. That seems to indicate that the issue isn't actually with the sound playback itself, but how much CPU usage the Bevy game is using on Firefox. It seems that Bevy takes much more CPU on firefox than it does on Chrome.

    I'm not sure exactly what causes the CPU usage difference, but at least I think that gives us somewhere to look. If resizing the screen changes the CPU usage, then it is probably rendering. Maybe firefox's rendering is just slower than chrome's.

    I'm using a custom renderer, too, so my experience may not be the best benchmark, but that's what I know for what it's worth.

    opened by zicklag 9
  • SoundLimitReached causes Panic

    SoundLimitReached causes Panic

    Hello again! Upgraded to latest version. Ended up being in a scenario where the amount of sounds played (not super-crazy) caused a panic here: https://github.com/NiklasEi/bevy_kira_audio/blob/main/src/audio_output.rs#L167

    This is the full error message: thread 'main' panicked at 'Failed to play sound: SoundLimitReached'

    I'm wondering if there is a way to get the limit by code? If so I guess I can implement a rate-limiter on sounds on my side. However I think it would be nice to propagate this error up to the user of bevy_kira_audio :)

    opened by Elogain 6
  • wasm performance compared to bevy_audio

    wasm performance compared to bevy_audio

    Hello! πŸ‘‹ Thanks for all your work! I really love this crate ❀️ ❀️

    I'm creating this issue because I'd like to document some surprising (to me) behavior of bevy_kira_audio / kira in comparison to bevy_audio πŸ˜„

    Because of some crackling audio in the browser (see #27) I recently ported a project of mine to bevy_audio in a branch to experiment.

    After porting I noticed a significant speedup to load times as well as the crackling audio going away.

    Anecdotally, when using bevy_kira_audio it takes a couple seconds for my "Play" button to display and then a couple more after clicking "Play" for the scene to render. When I switched to bevy_audio, everything much quicker, i.e. no delay between startup and "Play" button or after clicking "Play".

    project code: https://github.com/shnewto/limbo_pass

    wasm branches

    • wasm-rodio
    • wasm-kira

    Some of this is definitely a candidate for being system specific, I'm on macOS Monterey 12.3.1. I'd be curious to know if this is or isn't the case for someone with a different setup.

    opened by shnewto 6
  • Relicense under dual MIT/Apache-2.0

    Relicense under dual MIT/Apache-2.0

    Following bevyengine/bevy#2373 I would like to adapt licensing of this plugin to keep maximal compatibility with Bevy. For other reasons to switch to MIT/Apache 2.0 please take a look at the Bevy issue.

    With only two other contributors this should be much easier than for Bevy itself :wink:

    @rparrett and @CleanCut, I think you know the drill: please comment on this issue with

    I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to choose either at their option.
    

    Thanks again for your help!

    opened by NiklasEi 6
  • Add Tween Options

    Add Tween Options

    Hey there!

    Would you be open to a pull request that adds versions of the play, stop, etc. functions that additionally take the Tween parameter present in kira?

    I was using my own wrapper around kira for Bevy, but would like to switch to this one and that looks like it's the only feature I'm missing.

    I think we could re-export Tween from kira, but maybe rename it to AudioTween, just to avoid confusion with any other Bevy tweening plugins or something like that.

    opened by zicklag 5
  • Unexpected `PlaybackState` behavior

    Unexpected `PlaybackState` behavior

    There are 3 slightly different cases. The common part is that we're playing a short sound on a separate AudioChannel with play() method.

    • Waiting for the sound to end. Checking PlaybackState: it is permanently PlaybackState::Playing
    • Waiting for the sound to end, running stop() method. Checking PlaybackState: it is permanently PlaybackState::Playing
    • Not waiting for the sound to end, running stop() method while the sound is still playing. Checking PlaybackState: it is permanently PlaybackState::Stopping

    In all cases my expectation for PlaybackState would be PlaybackState::Stopped.

    opened by 5tr1k3r 5
  • Build error with latest bevy

    Build error with latest bevy

    Hi-

    I'm trying to consume bevy directly from git, due to the fact the latest release 0.5.0 is 6 months old and is missing a few fixes I need (see bevyengine/bevy#2940). However I'm facing many build errors:

    error[E0432]: unresolved import `bevy::prelude::AppBuilder`
    error[E0432]: unresolved imports `bevy::core::AsBytes`, `bevy::render::pass::RenderPassDepthStencilAttachmentDescriptor`
    error[E0261]: use of undeclared lifetime name `'w`
    error[E0261]: use of undeclared lifetime name `'s`
    error[E0107]: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied
    

    So I have a few questions:

    • Is bevy_kira_audio only supposed to work with bevy on released version?
    • Would it be possible to add some CI to catch those build issues along the way?

    Thanks!

    opened by djeedai 5
  • Support reading 'chunks' from a single audio file

    Support reading 'chunks' from a single audio file

    Hi,

    Does kira_audio support having a single audio asset, but then having Audio handles that will read only parts of the audio file? (e.g. from 0.8sec to 1.5sec)

    This would be helpful for the web as I would like to limit the number of files that clients have to download, so I'd like to 'merge' all audio files into one.

    opened by cBournhonesque 0
  • Implement systems for common channel actions

    Implement systems for common channel actions

    It is common to want to do something simple like stop the playback of a channel on entering or exiting a certain state. This PR removes boilerplate from this functionality. E.g. (using iyes_loopless):

    Context
    use bevy::prelude::*;
    use bevy_kira_audio::prelude::*;
    use iyes_loopless::prelude::*;
    
    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
    enum GameState {
        MainMenu
    }
    
    #[derive(Resource)]
    struct BgmChannel;
    
    struct FooPlugin;
    
    fn main() {
        App::new()
            .add_loopless_state(GameState::MainMenu)
            .add_plugin(AudioPlugin)
            .add_audio_channel::<BgmChannel>()
            .add_plugin(FooPlugin)
            .run();
    }
    

    Current method:

    impl Plugin for FooPlugin {
        fn build(&self, app: &mut App) {
            app.add_exit_system(GameState::MainMenu, stop_title_music);
        }
    }
    
    fn stop_title_music(audio: Res<AudioChannel<BgmChannel>>) {
        audio.stop();
    }
    

    With PR changes:

    impl Plugin for FooPlugin {
        fn build(&self, app: &mut App) {
            app.add_exit_system(GameState::MainMenu, stop_playback::<BgmChannel>);
        }
    }
    
    opened by Piturnah 2
  • Support additional types audio tweens?

    Support additional types audio tweens?

    Maybe I'm mistaken, but as far as I understand, it looks like kira supports lots of different tweens (allowing frequency slides etc.), but that the only exposed tween is through the fade_in command.

    Or maybe exposing such features is out of scope?

    opened by johanhelsing 1
  • Reexport `kira`

    Reexport `kira`

    Currently, to create a StaticSoundData for AudioSource, you have to import kira with the correct version. I'd like... to not do that lol.

    Also, in the case that #63 would be implemented, it is likely that users would have to reimport kira just to implement their own SoundData.

    A solution to this is to reexport kira itself.

    opened by harudagondi 2
  • Allow iterating through `DynamicChannels`

    Allow iterating through `DynamicChannels`

    Not sure to what extent this is a good idea, but I'm trying to manage various characteristics of dynamic channels. One missing feature I've noticed is the ability to iterate through all channels.

    Might be useful to impl Iterator/IntoIter on DynamicChannels. Also, generally making it more hashmap-like would help as well (I.e. being able to retrieve keys/values.)

    Thanks.

    opened by ndarilek 0
Owner
Niklas Eicker
Niklas Eicker
A Client/Server game networking plugin using QUIC, for the Bevy game engine.

Bevy Quinnet A Client/Server game networking plugin using QUIC, for the Bevy game engine. Bevy Quinnet QUIC as a game networking protocol Features Roa

Gilles Henaux 65 Feb 20, 2023
Bevy plugin for an AssetServer that can load embedded resources, or use other AssetServers based on the path.

Bevy-Embasset Embed your asset folder inside your binary. bevy-embasset adds support for loading assets embedded into the binary. Furthermore, it can

Johnny Tidemand Vestergaard 9 Aug 4, 2022
A plugin to use the kajiya renderer with bevy

??️ ?? bevy-kajiya A plugin that enables use of the kajiya renderer in bevy WARNING: This plugin is barebones and supports a limited set of features.

Sebastian Hamel 79 Jan 5, 2023
Inspector plugin for the bevy game engine

bevy-inspector-egui This crate provides the ability to annotate structs with a #[derive(Inspectable)], which opens a debug interface using egui where

Jakob Hellermann 517 Dec 31, 2022
Crossterm plugin for the bevy game engine

What is bevy_crossterm? bevy_crossterm is a Bevy plugin that uses crossterm as a renderer. It provides custom components and events which allow users

null 79 Nov 2, 2022
Hanabi β€” a particle system plugin for the Bevy game engine.

Hanabi β€” a particle system plugin for the Bevy game engine

Jerome Humbert 256 Dec 30, 2022
Tweening animation plugin for the Bevy game engine.

?? Bevy Tweening Tweening animation plugin for the Bevy game engine. Features Animate any field of any component or asset, including custom ones. Run

Jerome Humbert 135 Dec 23, 2022
A plugin to enable random number generation for the Bevy game engine.

bevy_turborand A plugin to enable random number generation for the Bevy game engine, built upon turborand. Implements ideas from Bevy's Deterministic

Gonçalo Rica Pais da Silva 15 Dec 23, 2022
A spectator camera plugin for the Bevy game engine

bevy_spectator A spectator camera plugin for the Bevy game engine. Controls Action Key Forward W Left A Backward S Right D Up Space Down LControl Alt.

Jonah Henriksson 5 Jan 2, 2023
Minecraft-esque voxel engine prototype made with the bevy game engine. Pending bevy 0.6 release to undergo a full rewrite.

vx_bevy A voxel engine prototype made using the Bevy game engine. Goals and features Very basic worldgen Animated chunk loading (ala cube world) Optim

Lucas Arriesse 125 Dec 31, 2022
A simple-to-use input manager for the Bevy game engine that empowers players and makes accessibility easy.

Bevy Ineffable A simple-to-use input manager for the Bevy game engine that empowers players and makes accessibility easy. Core tenets Make accessibili

Jazarro 10 Mar 2, 2024
2d Endless Runner Game made with Bevy Game Engine

Cute-runner A 2d Endless Runner Game made with Bevy Game Engine. Table of contents Project Infos Usage Screenshots Disclaimer Project Infos Date: Sept

JoaoMarinho 2 Jul 15, 2022
A game of snake written in Rust using the Bevy game engine, targeting WebGL2

Snake using the Bevy Game Engine Prerequisites cargo install cargo-make Build and serve WASM version Set your local ip address in Makefile.toml (loca

Michael Dorst 0 Dec 26, 2021
A game made in one week for the Bevy engine's first game jam

ΒΏQuien es el MechaBurro? An entry for the first Bevy game jam following the theme of "Unfair Advantage." It was made in one week using the wonderful B

mike 20 Dec 23, 2022
Solana Game Server is a decentralized game server running on Solana, designed for game developers

Solana Game Server* is the first decentralized Game Server (aka web3 game server) designed for game devs. (Think web3 SDK for game developers as a ser

Tardigrade Life Sciences, Inc 16 Dec 1, 2022
A Bevy plugin for loading the LDtk 2D tile map format.

bevy_ldtk ( Tileset from "Cavernas" by Adam Saltsman ) A Bevy plugin for loading LDtk tile maps. Usage use bevy::prelude::*; use bevy_ldtk::*; fn mai

Katharos Technology 23 Jul 4, 2022
A plugin for Egui integration into Bevy

bevy_egui This crate provides a Egui integration for the Bevy game engine. Features: Desktop and web (bevy_webgl2) platforms support Clipboard (web su

Vladyslav Batyrenko 453 Jan 3, 2023
A prototype plugin providing a simple line drawing api for bevy.

bevy_debug_lines A prototype plugin providing a simple line drawing api for bevy. See docs.rs for documentation. Expect breakage on master. Click on t

Michael Palmos 92 Dec 31, 2022
Bevy plugin helping with asset loading and organisation

Bevy asset loader This Bevy plugin reduces boilerplate when loading game assets. The crate offers the AssetCollection trait and can automatically load

Niklas Eicker 205 Jan 2, 2023