Support Warning
WebGPU is currently only supported on Chrome starting with version 113, and only on desktop. If they don't work on your configuration, you can check the WebGL2 examples
here.
use bevy::audio::AddAudioSource;
use bevy::audio::AudioPlugin;
use bevy::audio::Source;
use bevy::prelude::*;
use bevy::reflect::TypePath;
use bevy::utils::Duration;
#[derive(Asset, TypePath)]
struct SineAudio {
frequency: f32,
}
struct SineDecoder {
current_progress: f32,
progress_per_frame: f32,
period: f32,
sample_rate: u32,
}
impl SineDecoder {
fn new(frequency: f32) -> Self {
let sample_rate = 44_100;
SineDecoder {
current_progress: 0.,
progress_per_frame: frequency / sample_rate as f32,
period: std::f32::consts::PI * 2.,
sample_rate,
}
}
}
impl Iterator for SineDecoder {
type Item = f32;
fn next(&mut self) -> Option<Self::Item> {
self.current_progress += self.progress_per_frame;
self.current_progress %= 1.;
Some(f32::sin(self.period * self.current_progress))
}
}
impl Source for SineDecoder {
fn current_frame_len(&self) -> Option<usize> {
None
}
fn channels(&self) -> u16 {
1
}
fn sample_rate(&self) -> u32 {
self.sample_rate
}
fn total_duration(&self) -> Option<Duration> {
None
}
}
impl Decodable for SineAudio {
type Decoder = SineDecoder;
type DecoderItem = <SineDecoder as Iterator>::Item;
fn decoder(&self) -> Self::Decoder {
SineDecoder::new(self.frequency)
}
}
fn main() {
let mut app = App::new();
app.add_plugins(DefaultPlugins.set(AudioPlugin {
global_volume: GlobalVolume::new(0.2),
..default()
}))
.add_audio_source::<SineAudio>()
.add_systems(Startup, setup)
.run();
}
fn setup(mut assets: ResMut<Assets<SineAudio>>, mut commands: Commands) {
let audio_handle = assets.add(SineAudio {
frequency: 440., });
commands.spawn(AudioSourceBundle {
source: audio_handle,
..default()
});
}