diff --git a/src/bin/wasm/main.rs b/src/bin/wasm/main.rs index 472c0ca..b2f1197 100644 --- a/src/bin/wasm/main.rs +++ b/src/bin/wasm/main.rs @@ -11,7 +11,7 @@ use web_sys::{ AudioBuffer, AudioBufferOptions, AudioContext, AudioContextOptions, AudioContextState, CanvasRenderingContext2d, HtmlButtonElement, HtmlCanvasElement, HtmlInputElement, ImageBitmap, ImageData, KeyboardEvent, - js_sys::{Function, Uint8Array}, + js_sys::{Function, Reflect, Uint8Array}, wasm_bindgen::{Clamped, JsValue, UnwrapThrowExt, closure::Closure}, window, }; @@ -54,7 +54,7 @@ pub fn main() { let _ = audio.suspend().expect_throw("Failed to suspend AudioCtx"); const BUFFER_SIZE: usize = 1 << 10; - const SAMPLE_RATE: f64 = 60. * 3723.; + const SAMPLE_RATE: f64 = 60. * 3722.; let audio_buffer_opts = AudioBufferOptions::new(BUFFER_SIZE as u32, SAMPLE_RATE as f32); audio_buffer_opts.set_number_of_channels(1); // let audio_buffer = @@ -70,21 +70,21 @@ pub fn main() { .create_gain() .expect_throw("Failed to create gain node"); gain_node.set_channel_count(1); - gain_node.gain().set_value(0.01); + gain_node.gain().set_value(0.1); gain_node .connect_with_audio_node_and_output(&audio.destination(), 0) .expect_throw("Failed to connect to audio destination"); // gain_node // .connect_with_audio_node_and_output(&audio.destination(), 1) // .expect_throw("Failed to connect to audio destination 2"); - let delay_node = audio - .create_delay() - .expect_throw("Failed to create delay node"); - delay_node.set_channel_count(1); - delay_node.delay_time().set_value(0.); - delay_node - .connect_with_audio_node(&gain_node) - .expect_throw("Failed to connect to audio destination"); + // let delay_node = audio + // .create_delay() + // .expect_throw("Failed to create delay node"); + // delay_node.set_channel_count(1); + // delay_node.delay_time().set_value(0.); + // delay_node + // .connect_with_audio_node(&gain_node) + // .expect_throw("Failed to connect to audio destination"); // source_node.start_with_when(when) let nes = Arc::new(Mutex::new({ @@ -139,6 +139,25 @@ pub fn main() { .add_event_listener_with_callback("click", &Function::from(f.into_js_value())) .expect_throw("Failed to setup pause callback"); } + doc.get_element_by_id("mute") + .unwrap() + .add_event_listener_with_callback( + "click", + &Function::from( + Closure::::new(move || { + let win = window().expect_throw("Failed to get window"); + let v = win.get("play_audio").is_none_or(|v| v.is_falsy()); + Reflect::set( + &win, + &JsValue::from_str("play_audio"), + &JsValue::from_bool(!v), + ) + .expect_throw("Failed to update audio mute"); + }) + .into_js_value(), + ), + ) + .expect_throw("Failed to setup pause callback"); { let nes = nes.clone(); let poisoned = poisoned.clone(); @@ -204,7 +223,7 @@ pub fn main() { let mut last_frame = audio.current_time(); let mut raw_audio_buffer = [0f32; BUFFER_SIZE]; let mut cur_pos = 0; - let mut cur_total = BUFFER_SIZE; // Start time in samples, set to buffer size... + let mut cur_total = 3722 * 5; // Start time in samples, set to buffer size... let period = Arc::new(Mutex::new(None as Option)); let period_cl = period.clone(); let periodic: Closure = Closure::new(move |_v| { @@ -235,14 +254,17 @@ pub fn main() { } } // info!("New samples: {}", n.apu().get_frame_samples().len()); - for s in n.apu().get_frame_samples() { + for s in + &n.apu().get_frame_samples()[..n.apu().get_frame_samples().len().min(3722)] + { // raw_audio_buffer[cur_pos] = ((*s as f32) - 127.5) / 128.; raw_audio_buffer[cur_pos] = (*s as f32) / 256.; cur_pos += 1; if cur_pos == BUFFER_SIZE { cur_pos = 0; cur_total += BUFFER_SIZE; - if win.get("play_audio").is_some_and(|v| v.is_truthy()) { + if win.get("play_audio").is_none_or(|v| v.is_falsy()) { + // info!("{:?}", &raw_audio_buffer[..50]); let audio_buffer = AudioBuffer::new(&audio_buffer_opts) .expect_throw("Failed to create audio buffer"); audio_buffer @@ -265,9 +287,14 @@ pub fn main() { // "At {cur_total} samples, {:02.04}s ahead !loop", // (cur_total as f64) / SAMPLE_RATE - audio.current_time() // ); + if (cur_total as f64) / SAMPLE_RATE - audio.current_time() < 0. { + info!("Bumping audio playback"); + cur_total += BUFFER_SIZE; + } } } } + // info!("New samples: {}", n.apu().get_frame_samples().len()); n.apu_mut().reset_frame_samples(); // Discard audio samples // info!("Completed Frame in {} cycles", count); let data = Clamped(n.ppu().render_buffer.raw_image()); diff --git a/wasm/wasm.html b/wasm/wasm.html index a9770be..3213ec5 100644 --- a/wasm/wasm.html +++ b/wasm/wasm.html @@ -31,6 +31,7 @@

Start: Q key

Select: W key

+

Load new ROM:

@@ -46,8 +47,8 @@ Source is available for those interested.

- The APU isn't fully emulated yet, and many of the features implemented don't work properly yet. Audio - is disabled. + The APU isn't fully emulated yet, and many of the features implemented don't work properly yet. +