Expand description
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
- Routing audio
- Stream configuration
- Graph configuration
§Event scheduling
§Custom nodes
§Feature flags
Flag | Description | Default |
---|---|---|
reflect | Enable bevy_reflect derive macros. | Yes |
rand | Enable the RandomPitch component. | Yes |
wav | Enable WAV format and PCM encoding. | Yes |
ogg | Enable Ogg format and Vorbis encoding. | Yes |
mp3 | Enable mp3 format and encoding. | No |
mkv | Enable mkv format. | No |
adpcm | Enable adpcm encoding. | No |
flac | Enable FLAC format and encoding. | No |
web_audio | Enable the multi-threading web backend. | No |
hrtf | Enable HRTF Spatialization. | No |
hrtf_subjects | Enable all HRTF embedded data. | No |
loudness | Enable LUFS analyzer node. | Yes |
stream | Enable 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 SamplerNode
s 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§
- Seedling
Plugin bevy_seedling
’s top-level plugin.
Enums§
- Seedling
Systems - Sets for all
bevy_seedling
systems.