1use bevy::{app::{App, Plugin, Startup, Update}, ecs::{component::Component, system::{Commands, Query}}, math::{Quat, Vec3}, transform::components::Transform};
2use kira::{AudioManager, AudioManagerSettings, DefaultBackend, Tween, listener::ListenerHandle};
3
4use crate::source::FelixAudioSource;
5
6pub const SAMPLE_RATE: usize = 48_000;
7pub const BUFFER_SIZE: usize = 512;
8
9const MONO_20MS: usize = SAMPLE_RATE * 20 / 1000;
10
11pub mod source;
12pub mod utils;
13pub mod voice;
14
15// TODO: Make this use HRTF at some point
16// Maybe revisit steam audio?
17// Or just find some other library that does HRTFs.
18
19fn update_audio_system(
20 mut audio_system: Query<&mut FelixAudioComponent>,
21 listener: Query<(&FelixAudioListener, &Transform)>,
22 sources: Query<(&mut FelixAudioSource, &Transform)>,
23){
24 let mut audio_system = audio_system.single_mut().expect("Cannot find FelixAudioComponent, has audio system been initialised?");
25 let ( _, listener_transform ) = listener.single().expect("Cannot find FelixAudioListener.");
26
27 audio_system.main_listener.set_position(listener_transform.translation, Tween::default());
28 audio_system.main_listener.set_orientation(listener_transform.rotation, Tween::default());
29
30 for ( mut source, transform ) in sources{
31 if source.needs_init(){
32 source.init(&mut audio_system);
33 } else {
34 source.update(transform);
35 }
36 }
37}
38
39#[derive(Component)]
40pub struct FelixAudioListener;
41
42#[derive(Component)]
43pub struct FelixAudioComponent{
44 manager: AudioManager<DefaultBackend>,
45 main_listener: ListenerHandle
46}
47
48pub struct FelixAudio;
49
50impl Plugin for FelixAudio{
51 fn build(&self, app: &mut App) {
52 app.add_systems(Startup, move | mut commands: Commands | {
53 let mut manager = AudioManager::<DefaultBackend>::new(AudioManagerSettings::default()).unwrap();
54 let main_listener = manager.add_listener(Vec3::default(), Quat::default()).unwrap();
55
56 let handle = FelixAudioComponent { manager, main_listener };
57
58 commands.spawn(handle);
59 });
60
61 app.add_systems(Update, update_audio_system);
62 }
63}