prototypes/life: fix some audio jank, still janky just less

main
Elijah Voigt 1 month ago
parent c731eeb49c
commit e0194b53e2

@ -2,7 +2,7 @@
use std::time::Duration; use std::time::Duration;
use bevy::{picking::hover::Hovered, platform::collections::HashMap}; use bevy::{audio::Volume, picking::hover::Hovered, platform::collections::HashMap};
use engine::*; use engine::*;
const TILE: &str = "tileGrey_01.png"; const TILE: &str = "tileGrey_01.png";
@ -27,6 +27,7 @@ fn main() {
.init_resource::<Coordinates>() .init_resource::<Coordinates>()
.init_resource::<CellAssets>() .init_resource::<CellAssets>()
.init_state::<SimulationState>() .init_state::<SimulationState>()
.insert_resource(GlobalVolume::new(Volume::Linear(1.0)))
.add_message::<Lifecycle>() .add_message::<Lifecycle>()
.add_message::<SimulationState>() .add_message::<SimulationState>()
.add_systems(Startup, setup) .add_systems(Startup, setup)
@ -37,6 +38,10 @@ fn main() {
Update, Update,
update_grid_position.run_if(on_message::<CursorMoved>), update_grid_position.run_if(on_message::<CursorMoved>),
) )
.add_systems(
Update,
modulate_volume // TODO: .run_if(any_component_added::<AudioSink>)
)
.add_systems(Update, grid_gizmo) .add_systems(Update, grid_gizmo)
.add_systems( .add_systems(
Update, Update,
@ -58,6 +63,10 @@ fn main() {
.run_if(in_state(SimulationState::Run)) .run_if(in_state(SimulationState::Run))
.run_if(cooldown_secs(FRAME_DURATION)), .run_if(cooldown_secs(FRAME_DURATION)),
) )
.add_systems(
Update,
start_audio_synced.run_if(cooldown_secs(FRAME_DURATION))
)
.add_systems( .add_systems(
Update, Update,
simulation_step.run_if(on_message::<SimulationState>), simulation_step.run_if(on_message::<SimulationState>),
@ -325,7 +334,17 @@ fn on_add_coordinates(
commands.entity(trigger.entity).insert(t); commands.entity(trigger.entity).insert(t);
let p = cell_assets.pitches.get(&c.as_cell_pitch()).unwrap(); let p = cell_assets.pitches.get(&c.as_cell_pitch()).unwrap();
commands.entity(trigger.entity).insert((AudioPlayer(p.clone()), PlaybackSettings::LOOP)); commands.entity(trigger.entity).insert((AudioPlayer(p.clone()), PlaybackSettings::ONCE));
}
/// All audio starts paused so we can keep them in sync
/// This starts audios when the system is triggered, which is on a timer
fn start_audio_synced(query: Query<&AudioSink, With<Cell>>) {
query.iter().for_each(|sink| {
if sink.is_paused() {
sink.play()
}
});
} }
/// When the cursor moves, update the Coordiantes /// When the cursor moves, update the Coordiantes
@ -552,6 +571,12 @@ enum Note {
} }
impl Note { impl Note {
/// Pitches:
/// A -440 Hz
/// B - 493.88 Hz
/// C# - 554.37 Hz
/// E - 659.25 Hz
/// F# - 698.46 Hz
fn as_frequency(&self) -> f32 { fn as_frequency(&self) -> f32 {
match self { match self {
Note::A => 440.0, Note::A => 440.0,
@ -570,26 +595,13 @@ struct CellPitch {
} }
impl CellPitch { impl CellPitch {
/// Pitches:
/// A -440 Hz
/// B - 493.88 Hz
/// C# - 554.37 Hz
/// E - 659.25 Hz
/// F# - 698.46 Hz
fn to_frequency(&self) -> f32 { fn to_frequency(&self) -> f32 {
let base_note = self.note.as_frequency(); // Thanks Claude Opus 4.8
match self.octave { self.note.as_frequency() * 2f32.powi(self.octave as i32)
// Negative octave values -> lower notes
..=-1 => base_note / (self.octave as f32),
0 => base_note,
// Positive octave values -> higher notes
1.. => base_note * (self.octave as f32),
}
} }
} }
fn load_audio_tones(mut pitches: ResMut<Assets<Pitch>>, mut cell_assets: ResMut<CellAssets>) { fn load_audio_tones(mut pitches: ResMut<Assets<Pitch>>, mut cell_assets: ResMut<CellAssets>) {
let duration = Duration::from_secs_f32(FRAME_DURATION);
let notes = [Note::A, Note::B, Note::CSharp, Note::E, Note::FSharp]; let notes = [Note::A, Note::B, Note::CSharp, Note::E, Note::FSharp];
let octaves = [-2, -1, 0, 1, 2]; let octaves = [-2, -1, 0, 1, 2];
@ -600,6 +612,7 @@ fn load_audio_tones(mut pitches: ResMut<Assets<Pitch>>, mut cell_assets: ResMut<
octave: *octave, octave: *octave,
}; };
let frequency = cell_pitch.to_frequency(); let frequency = cell_pitch.to_frequency();
let duration = Duration::from_secs(100);
let handle = pitches.add(Pitch { let handle = pitches.add(Pitch {
frequency, frequency,
duration, duration,
@ -610,6 +623,11 @@ fn load_audio_tones(mut pitches: ResMut<Assets<Pitch>>, mut cell_assets: ResMut<
debug_assert!(cell_assets.pitches.iter().len() == 25); debug_assert!(cell_assets.pitches.iter().len() == 25);
} }
fn modulate_volume(mut gv: ResMut<GlobalVolume>, active: Query<Entity, With<AudioSink>>) {
let ratio = 1.0 / active.count() as f32;
gv.volume = Volume::Linear(ratio);
}
fn load_materials( fn load_materials(
server: ResMut<AssetServer>, server: ResMut<AssetServer>,
mut cell_assets: ResMut<CellAssets>, mut cell_assets: ResMut<CellAssets>,
@ -638,14 +656,3 @@ fn load_materials(
fn load_meshes(mut cell_assets: ResMut<CellAssets>, mut meshes: ResMut<Assets<Mesh>>) { fn load_meshes(mut cell_assets: ResMut<CellAssets>, mut meshes: ResMut<Assets<Mesh>>) {
cell_assets.mesh = meshes.add(Rectangle::new(SCALE, SCALE)); cell_assets.mesh = meshes.add(Rectangle::new(SCALE, SCALE));
} }
fn play_audio_tone(cell_assets: Res<CellAssets>, mut commands: Commands) {
let handle = cell_assets
.pitches
.get(&CellPitch {
note: Note::A,
octave: 0,
})
.unwrap();
commands.spawn((AudioPlayer(handle.clone()), PlaybackSettings::LOOP));
}

Loading…
Cancel
Save