From 8049e90853f1a39661e9435a2c9d79084069b284 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Mon, 31 Aug 2026 15:43:29 -0500 Subject: [PATCH] Fix Dolphin ansnd audio failing to configure on GameCube/Wii ansnd_configure_pcm_voice requires frame_data_ptr to be a physical address - it rejects cached virtual pointers (0x8xxxxxxx) as ANSND_ERROR_INVALID_MEMORY. Convert via MEM_VIRTUAL_TO_PHYSICAL and flush the CPU cache first so the DSP's DMA read sees what was actually written. Root-caused by disassembling libansnd's ansnd_configure_pcm_voice (no source available, only the static lib) and confirming via a temporary debug print that frame_data_ptr's top bit being set was what tripped the check. Confirmed fixed by running the Wii DOL build in Dolphin under -a LLE - voice configure/start now succeed with no errors. --- src/duskdolphin/audio/audiostreamdolphin.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/duskdolphin/audio/audiostreamdolphin.c b/src/duskdolphin/audio/audiostreamdolphin.c index e7cbab55..8a96a3b5 100644 --- a/src/duskdolphin/audio/audiostreamdolphin.c +++ b/src/duskdolphin/audio/audiostreamdolphin.c @@ -10,6 +10,8 @@ #include "assert/assert.h" #include "util/memory.h" #include +#include +#include errorret_t audioStreamDolphinInit(audiostream_t *stream) { assertNotNull(stream, "Stream cannot be NULL."); @@ -57,7 +59,14 @@ errorret_t audioStreamDolphinBuffer(audiostream_t *stream) { config.pitch = 1.0f; config.left_volume = baseVolume * (pan > 0 ? (1.0f - pan) : 1.0f); config.right_volume = baseVolume * (pan < 0 ? (1.0f + pan) : 1.0f); - config.frame_data_ptr = (u32) stream->data; + // The DSP DMAs frame_data_ptr directly out of main memory, bypassing the + // CPU cache, and rejects any pointer in cached virtual address space + // (0x8xxxxxxx.. - checked as "negative" internally, returned as + // ANSND_ERROR_INVALID_MEMORY) - it needs the physical address instead. + // Flush first so the DMA sees what the CPU actually wrote, not stale + // memory contents. + DCFlushRange(stream->data, stream->dataSize); + config.frame_data_ptr = MEM_VIRTUAL_TO_PHYSICAL(stream->data); config.frame_count = (u32) (stream->dataSize / frameSize); config.voice_callback = audioStreamDolphinVoiceCallback; config.stream_callback = NULL; // single-buffer playback