fix: stabilize desktop audio playback
Some checks failed
CI / rust (push) Has been cancelled

This commit is contained in:
2026-03-13 19:20:33 +03:00
parent f86e3c2284
commit d2be893cfe
12 changed files with 398 additions and 1343 deletions

View File

@@ -23,6 +23,7 @@ pub struct NativeBus {
odd_frame: bool,
in_vblank: bool,
frame_complete: bool,
cpu_cycles_since_poll: u32,
mmc3_a12_prev_high: bool,
mmc3_a12_low_dots: u16,
mmc3_last_irq_scanline: u32,
@@ -47,6 +48,7 @@ impl NativeBus {
odd_frame: false,
in_vblank: false,
frame_complete: false,
cpu_cycles_since_poll: 0,
mmc3_a12_prev_high: false,
mmc3_a12_low_dots: 8,
mmc3_last_irq_scanline: u32::MAX,
@@ -84,6 +86,12 @@ impl NativeBus {
pub fn clock_cpu(&mut self, cycles: u8) {
self.clock_cpu_cycles(cycles as u32);
}
pub fn take_cpu_cycles_since_poll(&mut self) -> u32 {
let cycles = self.cpu_cycles_since_poll;
self.cpu_cycles_since_poll = 0;
cycles
}
}
// CpuBus trait implementation (memory map + side effects).

View File

@@ -312,3 +312,23 @@ fn dmc_playback_updates_output_level_from_sample_bits() {
assert!(bus.apu.dmc_output_level < initial);
}
#[test]
fn pulse_channel_outputs_become_audible_after_setup() {
let mut bus = NativeBus::new(Box::new(StubMapper));
bus.write(0x4015, 0x01); // enable pulse1
bus.write(0x4000, 0b0101_1111); // 25% duty, constant volume=15
bus.write(0x4002, 0x08); // low timer period, not sweep-muted
bus.write(0x4003, 0x00); // reload length + reset duty sequencer
let mut saw_non_zero = false;
for _ in 0..64u32 {
bus.clock_cpu(1);
if bus.apu_channel_outputs().pulse1 > 0 {
saw_non_zero = true;
break;
}
}
assert!(saw_non_zero, "pulse1 never produced audible output");
}

View File

@@ -7,6 +7,7 @@ use crate::native_core::mapper::Mapper;
impl NativeBus {
fn clock_one_cpu_cycle(&mut self) {
self.cpu_cycles_since_poll = self.cpu_cycles_since_poll.saturating_add(1);
for _ in 0..3 {
self.clock_ppu_dot();
}