diff --git a/Cargo.lock b/Cargo.lock index 45a3bc8..2975a45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ "accesskit", "accesskit_consumer", "hashbrown", - "objc2", + "objc2 0.5.2", "objc2-app-kit", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -438,8 +438,8 @@ dependencies = [ "bevy_math", "bevy_reflect", "bevy_transform", - "cpal", - "rodio", + "cpal 0.15.3", + "rodio 0.20.1", "tracing", ] @@ -1139,6 +1139,9 @@ name = "bevy_test" version = "0.1.0" dependencies = [ "bevy", + "cpal 0.16.0", + "crossbeam-channel", + "rodio 0.21.1", ] [[package]] @@ -1412,7 +1415,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "objc2", + "objc2 0.5.2", ] [[package]] @@ -1672,6 +1675,20 @@ dependencies = [ "coreaudio-sys", ] +[[package]] +name = "coreaudio-rs" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aae284fbaf7d27aa0e292f7677dfbe26503b0d555026f702940805a630eac17" +dependencies = [ + "bitflags 1.3.2", + "libc", + "objc2-audio-toolbox", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", +] + [[package]] name = "coreaudio-sys" version = "0.2.17" @@ -1712,7 +1729,7 @@ checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779" dependencies = [ "alsa", "core-foundation-sys", - "coreaudio-rs", + "coreaudio-rs 0.11.3", "dasp_sample", "jni", "js-sys", @@ -1727,6 +1744,32 @@ dependencies = [ "windows 0.54.0", ] +[[package]] +name = "cpal" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd307f43cc2a697e2d1f8bc7a1d824b5269e052209e28883e5bc04d095aaa3f" +dependencies = [ + "alsa", + "coreaudio-rs 0.13.0", + "dasp_sample", + "jni", + "js-sys", + "libc", + "mach2", + "ndk 0.9.0", + "ndk-context", + "num-derive", + "num-traits", + "objc2-audio-toolbox", + "objc2-core-audio", + "objc2-core-audio-types", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows 0.54.0", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -1827,6 +1870,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.9.3", + "objc2 0.6.2", +] + [[package]] name = "disqualified" version = "1.0.0" @@ -1901,6 +1954,15 @@ dependencies = [ "syn", ] +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -1957,6 +2019,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "extended" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" + [[package]] name = "fastrand" version = "2.3.0" @@ -2953,6 +3021,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-derive" version = "0.4.2" @@ -2964,6 +3042,26 @@ dependencies = [ "syn", ] +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -3021,6 +3119,15 @@ dependencies = [ "objc2-encode", ] +[[package]] +name = "objc2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc" +dependencies = [ + "objc2-encode", +] + [[package]] name = "objc2-app-kit" version = "0.2.2" @@ -3030,13 +3137,28 @@ dependencies = [ "bitflags 2.9.3", "block2", "libc", - "objc2", + "objc2 0.5.2", "objc2-core-data", "objc2-core-image", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-quartz-core", ] +[[package]] +name = "objc2-audio-toolbox" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cbe18d879e20a4aea544f8befe38bcf52255eb63d3f23eca2842f3319e4c07" +dependencies = [ + "bitflags 2.9.3", + "libc", + "objc2 0.6.2", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", + "objc2-foundation 0.3.1", +] + [[package]] name = "objc2-cloud-kit" version = "0.2.2" @@ -3045,9 +3167,9 @@ checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ "bitflags 2.9.3", "block2", - "objc2", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -3057,8 +3179,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-audio" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca44961e888e19313b808f23497073e3f6b3c22bb485056674c8b49f3b025c82" +dependencies = [ + "dispatch2", + "objc2 0.6.2", + "objc2-core-audio-types", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-core-audio-types" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f1cc99bb07ad2ddb6527ddf83db6a15271bb036b3eb94b801cd44fdc666ee1" +dependencies = [ + "bitflags 2.9.3", + "objc2 0.6.2", ] [[package]] @@ -3069,8 +3213,8 @@ checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.9.3", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -3080,6 +3224,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ "bitflags 2.9.3", + "dispatch2", + "objc2 0.6.2", ] [[package]] @@ -3089,8 +3235,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-metal", ] @@ -3101,9 +3247,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ "block2", - "objc2", + "objc2 0.5.2", "objc2-contacts", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -3122,7 +3268,16 @@ dependencies = [ "block2", "dispatch", "libc", - "objc2", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +dependencies = [ + "objc2 0.6.2", ] [[package]] @@ -3132,9 +3287,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ "block2", - "objc2", + "objc2 0.5.2", "objc2-app-kit", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -3145,8 +3300,8 @@ checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.9.3", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -3157,8 +3312,8 @@ checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.9.3", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-metal", ] @@ -3168,8 +3323,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" dependencies = [ - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -3180,12 +3335,12 @@ checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ "bitflags 2.9.3", "block2", - "objc2", + "objc2 0.5.2", "objc2-cloud-kit", "objc2-core-data", "objc2-core-image", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-link-presentation", "objc2-quartz-core", "objc2-symbols", @@ -3200,8 +3355,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -3212,9 +3367,9 @@ checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ "bitflags 2.9.3", "block2", - "objc2", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -3633,10 +3788,22 @@ version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7ceb6607dd738c99bc8cb28eff249b7cd5c8ec88b9db96c0608c1480d140fb1" dependencies = [ - "cpal", + "cpal 0.15.3", "lewton", ] +[[package]] +name = "rodio" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e40ecf59e742e03336be6a3d53755e789fd05a059fa22dfa0ed624722319e183" +dependencies = [ + "cpal 0.16.0", + "dasp_sample", + "num-rational", + "symphonia", +] + [[package]] name = "ron" version = "0.8.1" @@ -3926,6 +4093,153 @@ dependencies = [ "zeno", ] +[[package]] +name = "symphonia" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "815c942ae7ee74737bb00f965fa5b5a2ac2ce7b6c01c0cc169bbeaf7abd5f5a9" +dependencies = [ + "lazy_static", + "symphonia-bundle-flac", + "symphonia-bundle-mp3", + "symphonia-codec-aac", + "symphonia-codec-pcm", + "symphonia-codec-vorbis", + "symphonia-core", + "symphonia-format-isomp4", + "symphonia-format-ogg", + "symphonia-format-riff", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-bundle-flac" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e34f34298a7308d4397a6c7fbf5b84c5d491231ce3dd379707ba673ab3bd97" +dependencies = [ + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-bundle-mp3" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c01c2aae70f0f1fb096b6f0ff112a930b1fb3626178fba3ae68b09dce71706d4" +dependencies = [ + "lazy_static", + "log", + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-codec-aac" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdbf25b545ad0d3ee3e891ea643ad115aff4ca92f6aec472086b957a58522f70" +dependencies = [ + "lazy_static", + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-codec-pcm" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f395a67057c2ebc5e84d7bb1be71cce1a7ba99f64e0f0f0e303a03f79116f89b" +dependencies = [ + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-codec-vorbis" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a98765fb46a0a6732b007f7e2870c2129b6f78d87db7987e6533c8f164a9f30" +dependencies = [ + "log", + "symphonia-core", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-core" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "798306779e3dc7d5231bd5691f5a813496dc79d3f56bf82e25789f2094e022c3" +dependencies = [ + "arrayvec", + "bitflags 1.3.2", + "bytemuck", + "lazy_static", + "log", +] + +[[package]] +name = "symphonia-format-isomp4" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abfdf178d697e50ce1e5d9b982ba1b94c47218e03ec35022d9f0e071a16dc844" +dependencies = [ + "encoding_rs", + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-format-ogg" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ada3505789516bcf00fc1157c67729eded428b455c27ca370e41f4d785bfa931" +dependencies = [ + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-format-riff" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f7be232f962f937f4b7115cbe62c330929345434c834359425e043bfd15f50" +dependencies = [ + "extended", + "log", + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-metadata" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc622b9841a10089c5b18e99eb904f4341615d5aa55bbf4eedde1be721a4023c" +dependencies = [ + "encoding_rs", + "lazy_static", + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-utils-xiph" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "484472580fa49991afda5f6550ece662237b00c6f562c7d9638d1b086ed010fe" +dependencies = [ + "symphonia-core", + "symphonia-metadata", +] + [[package]] name = "syn" version = "2.0.106" @@ -5027,9 +5341,9 @@ dependencies = [ "js-sys", "libc", "ndk 0.9.0", - "objc2", + "objc2 0.5.2", "objc2-app-kit", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-ui-kit", "orbclient", "percent-encoding", diff --git a/Cargo.toml b/Cargo.toml index 04f14a7..ca1bc1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,9 @@ [dependencies] bevy = { version = "0.16", features = ["file_watcher"] } + cpal = "0.16" + crossbeam-channel = "0.5" + rodio = "0.21" # Enable a small amount of optimization in the dev profile. [profile.dev] diff --git a/assets/shaders/default.wgsl b/assets/shaders/default.wgsl index 75962f9..2a5e7f5 100644 --- a/assets/shaders/default.wgsl +++ b/assets/shaders/default.wgsl @@ -1,19 +1,48 @@ #import bevy_sprite::mesh2d_vertex_output::VertexOutput @group(2) @binding(0) var u_time: f32; -@group(2) @binding(1) var u_resolution: vec2; -@group(2) @binding(2) var u_mouse_position: vec2; +@group(2) @binding(1) var u_resolution: vec2f; +@group(2) @binding(2) var u_mouse_position: vec2f; + +fn lerp(v0: f32, v1: f32, t: f32) -> f32 { + return v0 + t * (v1 - v0); +} @fragment -fn fragment(mesh: VertexOutput) -> @location(0) vec4 { - var uv = mesh.uv * 2 - 1; - uv.x = uv.x * (u_resolution.x / u_resolution.y); +fn fragment(mesh: VertexOutput) -> @location(0) vec4f { + var uv = vec2f(lerp(-2, 0.47, mesh.uv.x), lerp(-1.12, 1.12, mesh.uv.y)); - let red = vec3(1, 0, 0); - let blue = vec3(0, 0, 1.0); + // Progressive time-based zoom toward the known interesting point + // c = -0.743643887037151 + 0.13182590420533i + let center = vec2f(-0.743643887037151, 0.13182590420533); + let zoomSpeed: f32 = 0.2; // tune this to control how fast we zoom + let zoom = exp(u_time * zoomSpeed); // zoom factor grows with time + let c = center + (uv - center) / zoom; // move coordinates toward center as zoom increases - let t = step(0.2 + u_mouse_position.x / u_resolution.x, length(uv)); + var zx = 0.0; + var zy = 0.0; + let maxIter: i32 = 100 + i32(u_time); + var it: i32 = 0; - let color = mix(red, blue, t); - return vec4(color, 1); + for (var i: i32 = 0; i < maxIter; i = i + 1) { + let x = zx * zx - zy * zy + c.x; + let y = 2.0 * zx * zy + c.y; + zx = x; + zy = y; + if (zx * zx + zy * zy > 4.0) { + it = i; + break; + } + } + + let t = f32(it) / f32(maxIter); + + let palette = vec3f(0.5) + 0.5 * cos(6.2831853 * (vec3f(0.0, 0.33, 0.66) + t * 1.5) + u_time * 0.2); + + var color = vec3f(0, 0, 0); + if (t < 0.999999) { + color = palette; + } + + return vec4f(color, 1); } diff --git a/src/audio_input.rs b/src/audio_input.rs new file mode 100644 index 0000000..45931e7 --- /dev/null +++ b/src/audio_input.rs @@ -0,0 +1,130 @@ +use { + bevy::prelude::*, + cpal::{ + FromSample, Sample, SizedSample, + traits::{DeviceTrait, HostTrait, StreamTrait}, + }, + crossbeam_channel::{Receiver, Sender}, +}; + +/// Event carrying interleaved mic samples as f32 in the device's native +/// sample rate and channel layout. +#[derive(Event, Debug, Clone)] +pub struct MicData { + pub samples: Vec, + pub sample_rate: u32, + pub channels: u16, +} + +pub fn handle_mic_events(mut reader: EventReader) { + for event in reader.read() { + // Process mic data here. + // For example, print the number of samples received. + println!( + "Received mic data: {} samples at {} Hz, {} channels", + event.samples.len(), + event.sample_rate, + event.channels + ); + } +} + +/// Holds the CPAL stream alive and a channel for transferring audio to Bevy world. +#[derive(Resource)] +struct MicStream { + rx: Receiver>, + #[allow(dead_code)] + stream: cpal::Stream, // kept to prevent drop + sample_rate: u32, + channels: u16, +} + +pub struct AudioInputPlugin; + +impl Plugin for AudioInputPlugin { + fn build(&self, app: &mut App) { + app.add_event::() + .add_systems(Startup, init_audio_input_stream) + .add_systems(Update, pump_mic_events); + } +} + +fn init_audio_input_stream(mut commands: Commands) { + let default_host = cpal::default_host(); + + let default_device = default_host + .default_input_device() + .expect("Failed to get default input device"); + + let default_input_config = default_device + .default_input_config() + .expect("Failed to get default input config"); + + let sample_rate = default_input_config.sample_rate().0; + let channels = default_input_config.channels(); + + let config = default_input_config.config(); + let (tx, rx) = crossbeam_channel::unbounded::>(); + + let stream = match default_input_config.sample_format() { + cpal::SampleFormat::F32 => build_input_stream::(&default_device, &config, tx), + cpal::SampleFormat::I16 => build_input_stream::(&default_device, &config, tx), + cpal::SampleFormat::U16 => build_input_stream::(&default_device, &config, tx), + other => panic!("Unsupported sample format: {other:?}"), + } + .expect("Failed to build input stream"); + + stream.play().expect("Failed to play input stream"); + + info!( + "Mic stream started: {} ch @ {} Hz (default OS input)", + channels, sample_rate + ); + + commands.insert_resource(MicStream { + rx, + stream, + sample_rate, + channels, + }); +} + +/// Helper to build a typed CPAL input stream and forward f32 samples via channel. +fn build_input_stream( + device: &cpal::Device, + config: &cpal::StreamConfig, + tx: Sender>, +) -> Result +where + T: SizedSample + Sample, + f32: FromSample, +{ + device.build_input_stream( + config, + move |data: &[T], _| { + // Convert to f32 and ship to the main thread. + // NOTE: allocate-per-callback is simple; use a ring buffer for lower GC/latency if needed. + let mut out = Vec::with_capacity(data.len()); + for &s in data { + out.push(f32::from_sample(s)); + } + // Ignore send errors if receiver was dropped. + let _ = tx.send(out); + }, + move |err| { + eprintln!("CPAL input stream error: {err}"); + }, + Some(std::time::Duration::from_millis(10)), // latency + ) +} + +fn pump_mic_events(mic: Res, mut writer: EventWriter) { + // Drain any available audio buffers without blocking the frame. + while let Ok(samples) = mic.rx.try_recv() { + writer.write(MicData { + samples, + sample_rate: mic.sample_rate, + channels: mic.channels, + }); + } +} diff --git a/src/main.rs b/src/main.rs index bf00114..7517bd7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ //! A shader that uses the WGSL shading language. +mod audio_input; mod material; mod systems; @@ -11,12 +12,14 @@ fn main() { .add_plugins(( DefaultPlugins, Material2dPlugin::::default(), + audio_input::AudioInputPlugin, )) .add_systems(Startup, systems::setup) .add_systems( Update, ( material::update_material_time, + audio_input::handle_mic_events, systems::screen_resized, systems::mouse_moved, systems::exit_app.run_if(input_just_pressed(KeyCode::Escape)),