use bevy::audio::AddAudioSource;
use bevy::audio::Source;
use bevy::prelude::*;
use bevy::reflect::TypeUuid;
use bevy::utils::Duration;
#[derive(TypeUuid)]
#[uuid = "c2090c23-78fd-44f1-8508-c89b1f3cec29"]
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)
.add_audio_source::<SineAudio>()
.add_startup_system(setup)
.run();
}
fn setup(mut assets: ResMut<Assets<SineAudio>>, audio: Res<Audio<SineAudio>>) {
let audio_handle = assets.add(SineAudio {
frequency: 440., });
audio.play(audio_handle);
}