Crate bevy_seedling

Crate bevy_seedling 

Source
Expand description

crates.io docs.rs

A sprouting integration of the Firewheel audio engine for Bevy.

bevy_seedling is powerful, flexible, and fast. You can play sounds, apply effects, and route audio anywhere. Creating and integrating custom audio processors is simple.

§Getting started

First, you’ll need to add the dependency to your Cargo.toml. Note that you’ll need to disable Bevy’s bevy_audio feature, meaning you’ll need to specify quite a few features manually!

[dependencies]
bevy_seedling = "0.5"
bevy = { version = "0.16", default-features = false, features = [
  "animation",
  "bevy_asset",
  "bevy_color",
  "bevy_core_pipeline",
  "bevy_gilrs",
  "bevy_gizmos",
  "bevy_gltf",
  "bevy_mesh_picking_backend",
  "bevy_pbr",
  "bevy_picking",
  "bevy_render",
  "bevy_scene",
  "bevy_sprite",
  "bevy_sprite_picking_backend",
  "bevy_state",
  "bevy_text",
  "bevy_ui",
  "bevy_ui_picking_backend",
  "bevy_window",
  "bevy_winit",
  "custom_cursor",
  "default_font",
  "hdr",
  "multi_threaded",
  "png",
  "smaa_luts",
  "sysinfo_plugin",
  "tonemapping_luts",
  "webgl2",
  "x11",
] }

Then, you’ll need to add the SeedlingPlugin to your app.

use bevy::prelude::*;
use bevy_seedling::prelude::*;

fn main() {
    App::default()
        .add_plugins((DefaultPlugins, SeedlingPlugin::default()))
        .run();
}

Once you’ve set it all up, playing sounds is easy!

fn play_sound(mut commands: Commands, server: Res<AssetServer>) {
    // Play a sound!
    commands.spawn(SamplePlayer::new(server.load("my_sample.wav")));

    // Play a sound... with effects :O
    commands.spawn((
        SamplePlayer::new(server.load("my_ambience.wav")).looping(),
        sample_effects![LowPassNode { frequency: 500.0 }],
    ));
}

The repository’s examples should help you get up to speed on common usage patterns.

§Table of contents

Below is a structured overview of this crate’s documentation, arranged to ease you into bevy_seedling’s features.

§Playing samples

§Sampler pools

§The audio graph

§Event scheduling

§Custom nodes

§Feature flags

FlagDescriptionDefault
reflectEnable bevy_reflect derive macros.Yes
randEnable the RandomPitch component.Yes
wavEnable WAV format and PCM encoding.Yes
oggEnable Ogg format and Vorbis encoding.Yes
mp3Enable mp3 format and encoding.No
mkvEnable mkv format.No
adpcmEnable adpcm encoding.No
flacEnable FLAC format and encoding.No
web_audioEnable the multi-threading web backend.No
hrtfEnable HRTF Spatialization.No
hrtf_subjectsEnable all HRTF embedded data.No
loudnessEnable LUFS analyzer node.Yes
streamEnable CPAL input and output stream nodes.Yes

§Frequently asked questions

§How do I dynamically change a sample’s volume?

The SamplePlayer::volume field cannot be changed after spawning or inserting the component. Nonetheless, there are a few ways to manage dynamic volume changes depending on your needs.

If you need individual control over each sample’s volume, you should add a VolumeNode as an effect.

commands.spawn((
    SamplePlayer::new(server.load("my_sample.wav")),
    sample_effects![VolumeNode {
        volume: Volume::Decibels(-6.0),
        ..Default::default()
    }],
));

To see how to query for effects, refer to the EffectsQuery trait.

If you want to control groups of samples, such as all music, you’ll probably want to spawn a SamplerPool and update the pool’s VolumeNode rather than using a node for each sample.

#[derive(PoolLabel, Debug, Clone, PartialEq, Eq, Hash)]
struct MusicPool;

commands.spawn(SamplerPool(MusicPool));

commands.spawn((MusicPool, SamplePlayer::new(server.load("my_music.wav"))));

// Update the volume of all music at once
fn update_music_volume(mut music: Single<&mut VolumeNode, With<SamplerPool<MusicPool>>>) {
    music.volume = Volume::Decibels(-6.0);
}

§Why aren’t my mp3 samples making any sound?

bevy_seedling enables a few formats and encodings by default. If your format isn’t included in the default features, you’ll need to enable it in your Cargo.toml.

[dependencies]
bevy_seedling = { version = "0.3.0", features = ["mp3"] }

§Why isn’t my custom node doing anything?

bevy_seedling does quite a bit with Firewheel nodes under the hood. To enable this machinery, you need to register your audio node.

use bevy::prelude::*;
use bevy_seedling::prelude::*;

// Let's assume the relevant traits are implemented.
struct CustomNode;

fn main() {
    App::new()
        .add_plugins((DefaultPlugins, SeedlingPlugin::default()))
        .register_simple_node::<CustomNode>();
}

§Why are my custom nodes crunchy (underrunning)?

If you compile your project without optimizations, your custom audio nodes may perform poorly enough to frequently underrun. You can compensate for this by moving your audio code into a separate crate, selectively applying optimizations.

// Cargo.toml
[dependencies]
my_custom_nodes = { path = "my_custom_nodes" }

[profile.dev.package.my_custom_nodes]
opt-level = 3

§Why am I getting “PlaybackSettings, Volume, etc. is ambiguous” errors?

bevy_seedling re-uses some type names from bevy_audio. To avoid ambiguous imports, you’ll need to prevent bevy_audio from being compiled. You may need to update your Cargo.lock file to ensure bevy_audio isn’t included.

It’s also possible one of your third-part Bevy dependencies depends directly on the bevy crate without disabling default features, causing bevy_audio to be transitively enabled. In this case, encourage the crate authors to depend on sub-crates (like bevy_ecs) or disable Bevy’s default features!

§Glossary

§Bus

In general audio processing, a bus is typically some connection point, to which we route many tracks of audio.

In bevy_seedling, a bus is nothing special; it’s really just a label applied to a normal audio node. Since connecting many inputs to a node is trivial, there’s no need for special support. All of bevy_seedling’s buses use VolumeNode, but you can apply a bus label to whatever node you like.

§Node

A node is the smallest unit of audio processing. It can receive inputs, produce outputs, or both, meaning nodes can be used as sources, sinks, or effects.

Nodes in bevy_seedling generally consist of two parts: an ECS handle, like VolumeNode, and the actual audio processor that we insert into the real-time audio graph. “Node” may refer to either or both of these.

§Pool

A pool (or sampler pool) is a group of SamplerNodes connected to a local bus. Sampler pools are roughly analogous to bevy_kira_audio’s tracks, where both allow you to play sounds in the same “place” in the audio graph.

§Routing

Digital audio is a relentless stream of discrete values. Routing allows us to direct this stream though various stages (or nodes, in Firewheel’s case). Each node has some number of input and output channels, to and from which we can arbitrarily route audio.

In the simplest case, we’d route the output of a source like SamplerNode directly to the graph’s output. If we want to change the volume, we could insert a VolumeNode in between the sampler and the output. If we wanted to add reverb, we could also route the SamplerNode to a FreeverbNode.

 ┌─────────────┐
 │SamplerNode  │
 └┬───────────┬┘
 ┌▽─────────┐┌▽───────────┐
 │VolumeNode││FreeverbNode│
 └┬─────────┘└┬───────────┘
 ┌▽───────────▽┐
 │GraphOutput  │
 └─────────────┘

As you can see, this routing is very powerful!

§Sample

In bevy_seedling, sample primarily refers to a piece of recorded sound, like an audio file. Samples aren’t limited to audio files, however; anything implementing SampleResource can work with AudioSample.

Note that “sample” can also refer to the individual amplitude measurements that make up a sound. “Sample rate,” often 44.1kHz or 48kHz, refers to these measurements.

Re-exports§

pub use firewheel;

Modules§

configuration
Audio graph and I/O initialization.
context
Glue code for interfacing with the underlying audio context.
edge
Node connection and disconnection utilities.
error
bevy_seedling’s error types.
node
Audio node registration and management.
nodes
All of bevy_seedling’s audio nodes.
pool
Sampler pools, bevy_seedling’s primary sample playing mechanism.
prelude
All bevy_seedlings’s important types and traits.
sample
Audio sample components.
spatial
Spatial audio components.
time
The audio DSP clock.
utils
A collection of audio utilities.

Macros§

sample_effects
Returns a spawnable list of SampleEffects.

Structs§

SeedlingPlugin
bevy_seedling’s top-level plugin.

Enums§

SeedlingSystems
Sets for all bevy_seedling systems.