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.
This commit is contained in:
@@ -10,6 +10,8 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include <ansndlib.h>
|
#include <ansndlib.h>
|
||||||
|
#include <ogc/cache.h>
|
||||||
|
#include <ogc/system.h>
|
||||||
|
|
||||||
errorret_t audioStreamDolphinInit(audiostream_t *stream) {
|
errorret_t audioStreamDolphinInit(audiostream_t *stream) {
|
||||||
assertNotNull(stream, "Stream cannot be NULL.");
|
assertNotNull(stream, "Stream cannot be NULL.");
|
||||||
@@ -57,7 +59,14 @@ errorret_t audioStreamDolphinBuffer(audiostream_t *stream) {
|
|||||||
config.pitch = 1.0f;
|
config.pitch = 1.0f;
|
||||||
config.left_volume = baseVolume * (pan > 0 ? (1.0f - pan) : 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.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.frame_count = (u32) (stream->dataSize / frameSize);
|
||||||
config.voice_callback = audioStreamDolphinVoiceCallback;
|
config.voice_callback = audioStreamDolphinVoiceCallback;
|
||||||
config.stream_callback = NULL; // single-buffer playback
|
config.stream_callback = NULL; // single-buffer playback
|
||||||
|
|||||||
Reference in New Issue
Block a user