From e0194b53e293d12632bb1ca4536724407483db09 Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Fri, 12 Jun 2026 14:57:23 -0700 Subject: [PATCH] prototypes/life: fix some audio jank, still janky just less --- prototypes/src/bin/life.rs | 63 +++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/prototypes/src/bin/life.rs b/prototypes/src/bin/life.rs index f23e7fc..bf341a4 100644 --- a/prototypes/src/bin/life.rs +++ b/prototypes/src/bin/life.rs @@ -2,7 +2,7 @@ use std::time::Duration; -use bevy::{picking::hover::Hovered, platform::collections::HashMap}; +use bevy::{audio::Volume, picking::hover::Hovered, platform::collections::HashMap}; use engine::*; const TILE: &str = "tileGrey_01.png"; @@ -27,6 +27,7 @@ fn main() { .init_resource::() .init_resource::() .init_state::() + .insert_resource(GlobalVolume::new(Volume::Linear(1.0))) .add_message::() .add_message::() .add_systems(Startup, setup) @@ -37,6 +38,10 @@ fn main() { Update, update_grid_position.run_if(on_message::), ) + .add_systems( + Update, + modulate_volume // TODO: .run_if(any_component_added::) + ) .add_systems(Update, grid_gizmo) .add_systems( Update, @@ -58,6 +63,10 @@ fn main() { .run_if(in_state(SimulationState::Run)) .run_if(cooldown_secs(FRAME_DURATION)), ) + .add_systems( + Update, + start_audio_synced.run_if(cooldown_secs(FRAME_DURATION)) + ) .add_systems( Update, simulation_step.run_if(on_message::), @@ -325,7 +334,17 @@ fn on_add_coordinates( commands.entity(trigger.entity).insert(t); 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>) { + query.iter().for_each(|sink| { + if sink.is_paused() { + sink.play() + } + }); } /// When the cursor moves, update the Coordiantes @@ -552,6 +571,12 @@ enum 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 { match self { Note::A => 440.0, @@ -570,26 +595,13 @@ struct 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 { - let base_note = self.note.as_frequency(); - match self.octave { - // 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), - } + // Thanks Claude Opus 4.8 + self.note.as_frequency() * 2f32.powi(self.octave as i32) } } fn load_audio_tones(mut pitches: ResMut>, mut cell_assets: ResMut) { - let duration = Duration::from_secs_f32(FRAME_DURATION); let notes = [Note::A, Note::B, Note::CSharp, Note::E, Note::FSharp]; let octaves = [-2, -1, 0, 1, 2]; @@ -600,6 +612,7 @@ fn load_audio_tones(mut pitches: ResMut>, mut cell_assets: ResMut< octave: *octave, }; let frequency = cell_pitch.to_frequency(); + let duration = Duration::from_secs(100); let handle = pitches.add(Pitch { frequency, duration, @@ -610,6 +623,11 @@ fn load_audio_tones(mut pitches: ResMut>, mut cell_assets: ResMut< debug_assert!(cell_assets.pitches.iter().len() == 25); } +fn modulate_volume(mut gv: ResMut, active: Query>) { + let ratio = 1.0 / active.count() as f32; + gv.volume = Volume::Linear(ratio); +} + fn load_materials( server: ResMut, mut cell_assets: ResMut, @@ -638,14 +656,3 @@ fn load_materials( fn load_meshes(mut cell_assets: ResMut, mut meshes: ResMut>) { cell_assets.mesh = meshes.add(Rectangle::new(SCALE, SCALE)); } - -fn play_audio_tone(cell_assets: Res, mut commands: Commands) { - let handle = cell_assets - .pitches - .get(&CellPitch { - note: Note::A, - octave: 0, - }) - .unwrap(); - commands.spawn((AudioPlayer(handle.clone()), PlaybackSettings::LOOP)); -}