ref: 9e3b1589737a38f2b3af7dd6c1aaa534cf597dd1
parent: 288c2dccee44be697544639d4717dada80dafe6e
author: Clownacy <Clownacy@users.noreply.github.com>
date: Sun Apr 19 15:27:02 EDT 2020
Add stereo support to Wii U software mixer
--- a/src/Backends/Audio/WiiU-Software.cpp
+++ b/src/Backends/Audio/WiiU-Software.cpp
@@ -26,9 +26,9 @@
static OSMutex sound_list_mutex;
static OSMutex organya_mutex;
-static AXVoice *voice;
+static AXVoice *voices[2];
-static short *stream_buffer;
+static short *stream_buffers[2];
static float *stream_buffer_float;
static size_t buffer_length;
static unsigned long output_frequency;
@@ -100,9 +100,11 @@
unsigned int half;
+ // Just assume both voices are in-sync
+
AXVoiceOffsets offsets;
- AXGetVoiceOffsets(voice, &offsets);
+ AXGetVoiceOffsets(voices[0], &offsets);
if (offsets.currentOffset > (buffer_length / 2))
{
@@ -125,17 +127,21 @@
for (unsigned int i = 0; i < buffer_length / 2; ++i)
{
- float sample = stream_buffer_float[i * 2];
+ for (unsigned int j = 0; j < 2; ++j)
+ {
+ float sample = stream_buffer_float[(i * 2) + j];
- if (sample < -1.0f)
- sample = -1.0f;
- else if (sample > 1.0f)
- sample = 1.0f;
+ if (sample < -1.0f)
+ sample = -1.0f;
+ else if (sample > 1.0f)
+ sample = 1.0f;
- stream_buffer[((buffer_length / 2) * last_half) + i] = sample * 32767.0f;
+ stream_buffers[j][((buffer_length / 2) * last_half) + i] = sample * 32767.0f;
+ }
}
- DCStoreRange(&stream_buffer[(buffer_length / 2) * last_half], buffer_length / 2 * sizeof(short));
+ DCStoreRange(&stream_buffers[0][(buffer_length / 2) * last_half], buffer_length / 2 * sizeof(short));
+ DCStoreRange(&stream_buffers[1][(buffer_length / 2) * last_half], buffer_length / 2 * sizeof(short));
last_half = half;
}
@@ -160,49 +166,78 @@
Mixer_Init(output_frequency);
- voice = AXAcquireVoice(31, NULL, NULL);
+ buffer_length = output_frequency / 100; // 10ms buffer
- if (voice != NULL)
+ stream_buffer_float = (float*)malloc(buffer_length * sizeof(float) * 2);
+
+ if (stream_buffer_float != NULL)
{
- AXVoiceBegin(voice);
+ stream_buffers[0] = (short*)malloc(buffer_length * sizeof(short));
- AXSetVoiceType(voice, 0);
+ if (stream_buffers[0] != NULL)
+ {
+ stream_buffers[1] = (short*)malloc(buffer_length * sizeof(short));
- AXVoiceVeData vol = {.volume = 0x8000};
- AXSetVoiceVe(voice, &vol);
+ if (stream_buffers[1] != NULL)
+ {
+ voices[0] = AXAcquireVoice(31, NULL, NULL);
- AXVoiceDeviceMixData mix_data[6];
- memset(mix_data, 0, sizeof(mix_data));
- mix_data[0].bus[0].volume = 0x8000;
- mix_data[1].bus[0].volume = 0x8000;
+ if (voices[0] != NULL)
+ {
+ voices[1] = AXAcquireVoice(31, NULL, NULL);
- AXSetVoiceDeviceMix(voice, AX_DEVICE_TYPE_DRC, 0, mix_data);
- AXSetVoiceDeviceMix(voice, AX_DEVICE_TYPE_TV, 0, mix_data);
+ if (voices[1] != NULL)
+ {
+ for (unsigned int i = 0; i < 2; ++i)
+ {
+ AXVoiceBegin(voices[i]);
- AXSetVoiceSrcRatio(voice, 1.0f); // We use the native sample rate
- AXSetVoiceSrcType(voice, AX_VOICE_SRC_TYPE_NONE);
+ AXSetVoiceType(voices[i], 0);
- buffer_length = output_frequency / 100; // 10ms buffer
+ AXVoiceVeData vol = {.volume = 0x8000};
+ AXSetVoiceVe(voices[i], &vol);
- stream_buffer = (short*)malloc(buffer_length * sizeof(short));
- stream_buffer_float = (float*)malloc(buffer_length * sizeof(float) * 2);
+ AXVoiceDeviceMixData mix_data[6];
+ memset(mix_data, 0, sizeof(mix_data));
+ mix_data[0].bus[0].volume = i == 0 ? 0x8000 : 0;
+ mix_data[1].bus[0].volume = i == 1 ? 0x8000 : 0;
- AXVoiceOffsets offs;
- offs.dataType = AX_VOICE_FORMAT_LPCM16;
- offs.endOffset = buffer_length;
- offs.loopingEnabled = AX_VOICE_LOOP_ENABLED;
- offs.loopOffset = 0;
- offs.currentOffset = 0;
- offs.data = stream_buffer;
- AXSetVoiceOffsets(voice, &offs);
+ AXSetVoiceDeviceMix(voices[i], AX_DEVICE_TYPE_DRC, 0, mix_data);
+ AXSetVoiceDeviceMix(voices[i], AX_DEVICE_TYPE_TV, 0, mix_data);
- AXSetVoiceState(voice, AX_VOICE_STATE_PLAYING);
+ AXSetVoiceSrcRatio(voices[i], 1.0f); // We use the native sample rate
+ AXSetVoiceSrcType(voices[i], AX_VOICE_SRC_TYPE_NONE);
- AXVoiceEnd(voice);
- AXRegisterAppFrameCallback(FrameCallback);
+ AXVoiceOffsets offs;
+ offs.dataType = AX_VOICE_FORMAT_LPCM16;
+ offs.endOffset = buffer_length;
+ offs.loopingEnabled = AX_VOICE_LOOP_ENABLED;
+ offs.loopOffset = 0;
+ offs.currentOffset = 0;
+ offs.data = stream_buffers[i];
+ AXSetVoiceOffsets(voices[i], &offs);
- return true;
+ AXSetVoiceState(voices[i], AX_VOICE_STATE_PLAYING);
+
+ AXVoiceEnd(voices[i]);
+ }
+
+ AXRegisterAppFrameCallback(FrameCallback);
+
+ return true;
+ }
+
+ AXFreeVoice(voices[0]);
+ }
+
+ free(stream_buffers[1]);
+ }
+
+ free(stream_buffers[0]);
+ }
+
+ free(stream_buffer_float);
}
return false;
@@ -210,7 +245,11 @@
void AudioBackend_Deinit(void)
{
- AXFreeVoice(voice);
+ for (unsigned int i = 0; i < 2; ++i)
+ {
+ AXFreeVoice(voices[i]);
+ free(stream_buffers[i]);
+ }
AXQuit();
}