From 5855d6b251170f462babae95da3db302261cef03 Mon Sep 17 00:00:00 2001 From: Theron Spiegl Date: Thu, 12 Dec 2019 00:17:07 -0600 Subject: [PATCH] apu timing notes --- src/apu/mod.rs | 10 ++++++++++ src/audio.rs | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/apu/mod.rs b/src/apu/mod.rs index ba4ebed..944c188 100644 --- a/src/apu/mod.rs +++ b/src/apu/mod.rs @@ -7,6 +7,16 @@ mod dmc; // Frame counter only ticks every 3728.5 APU ticks, and in audio frames of 4 or 5. // Length counter controls note durations. +// How to sync clock to audio? +// Measure time slept to see if it will be a problem. +// What if the APU kept a ring buffer of audio data way longer than the audio device's sample size, +// and that was in a struct with some markers, so the audio device can just consume what it needs during PPU's sleep and mark +// where it left off? But wouldn't it catch up and consume buffer? It won't catch up if it's big enough, and the APU can +// change the markers somehow as it needs to? Or audio callback truncates what it consumed and adjusts head? No, audio device doesn't +// need all samples, it needs one from the stream 44100 time per second. So just an if statement, if time has passed grab a sample. +// But then that won't be running during PPU 60Hz sleep... So run audio in its own thread... Except then it won't work on Windows because of SDL... +// So just run the console in its own thread and video/audio in the main thread... But that's annoying. + pub struct Apu { square1: Square, square2: Square, diff --git a/src/audio.rs b/src/audio.rs index e1b9334..92c3d7f 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -4,13 +4,14 @@ use sdl2::audio::{AudioCallback, AudioSpecDesired}; pub struct Speaker { buffer: [f32; 4096], + head: usize, } impl AudioCallback for Speaker { type Channel = f32; fn callback(&mut self, out: &mut [f32]) { for (i, x) in out.iter_mut().enumerate() { - *x = self.buffer[i]; // get data from apu + *x = self.buffer[i+self.head..i+self.head+4096]; // get data from apu } } }