Add basic 3DS audio support
It's using the software mixer for now. I might be able to make it hardware-accelerated in the future.
This commit is contained in:
parent
7013c28e26
commit
75a31005d1
2 changed files with 167 additions and 0 deletions
|
@ -368,6 +368,14 @@ elseif(BACKEND_AUDIO MATCHES "WiiU-Software")
|
||||||
"src/Backends/Audio/SoftwareMixer/Backend.h"
|
"src/Backends/Audio/SoftwareMixer/Backend.h"
|
||||||
"src/Backends/Audio/SoftwareMixer/WiiU-Software.cpp"
|
"src/Backends/Audio/SoftwareMixer/WiiU-Software.cpp"
|
||||||
)
|
)
|
||||||
|
elseif(BACKEND_AUDIO MATCHES "3DS")
|
||||||
|
target_sources(CSE2 PRIVATE
|
||||||
|
"src/Backends/Audio/SoftwareMixer.cpp"
|
||||||
|
"src/Backends/Audio/SoftwareMixer/Mixer.cpp"
|
||||||
|
"src/Backends/Audio/SoftwareMixer/Mixer.h"
|
||||||
|
"src/Backends/Audio/SoftwareMixer/Backend.h"
|
||||||
|
"src/Backends/Audio/SoftwareMixer/3DS.cpp"
|
||||||
|
)
|
||||||
elseif(BACKEND_AUDIO MATCHES "Null")
|
elseif(BACKEND_AUDIO MATCHES "Null")
|
||||||
target_sources(CSE2 PRIVATE
|
target_sources(CSE2 PRIVATE
|
||||||
"src/Backends/Audio/Null.cpp"
|
"src/Backends/Audio/Null.cpp"
|
||||||
|
|
159
src/Backends/Audio/SoftwareMixer/3DS.cpp
Normal file
159
src/Backends/Audio/SoftwareMixer/3DS.cpp
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
#include "Backend.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <3ds.h>
|
||||||
|
|
||||||
|
#include "../../Misc.h"
|
||||||
|
|
||||||
|
#define SAMPLE_RATE 32000 // The native sample rate is 32728.4980469
|
||||||
|
#define FRAMES_PER_BUFFER (SAMPLE_RATE / 30) // 33.333 milliseconds
|
||||||
|
|
||||||
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
|
static void (*parent_callback)(long *stream, size_t frames_total);
|
||||||
|
|
||||||
|
static short *stream_buffer;
|
||||||
|
|
||||||
|
static ndspWaveBuf dsp_buffers[2];
|
||||||
|
static bool current_dsp_buffer;
|
||||||
|
|
||||||
|
static void FullBuffer(short *stream, size_t frames_total)
|
||||||
|
{
|
||||||
|
size_t frames_done = 0;
|
||||||
|
|
||||||
|
while (frames_done != frames_total)
|
||||||
|
{
|
||||||
|
long mix_buffer[FRAMES_PER_BUFFER * 2]; // 2 because stereo
|
||||||
|
|
||||||
|
size_t subframes = MIN(FRAMES_PER_BUFFER, frames_total - frames_done);
|
||||||
|
|
||||||
|
memset(mix_buffer, 0, subframes * sizeof(long) * 2);
|
||||||
|
|
||||||
|
parent_callback(mix_buffer, subframes);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < subframes * 2; ++i)
|
||||||
|
{
|
||||||
|
if (mix_buffer[i] > 0x7FFF)
|
||||||
|
*stream++ = 0x7FFF;
|
||||||
|
else if (mix_buffer[i] < -0x7FFF)
|
||||||
|
*stream++ = -0x7FFF;
|
||||||
|
else
|
||||||
|
*stream++ = mix_buffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
frames_done += subframes;
|
||||||
|
}
|
||||||
|
|
||||||
|
DSP_FlushDataCache(stream, frames_total * sizeof(short) * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Callback(void *user_data)
|
||||||
|
{
|
||||||
|
(void)user_data;
|
||||||
|
|
||||||
|
if (dsp_buffers[current_dsp_buffer].status == NDSP_WBUF_DONE)
|
||||||
|
{
|
||||||
|
FullBuffer(dsp_buffers[current_dsp_buffer].data_pcm16, dsp_buffers[current_dsp_buffer].nsamples);
|
||||||
|
|
||||||
|
ndspChnWaveBufAdd(0, &dsp_buffers[current_dsp_buffer]);
|
||||||
|
|
||||||
|
current_dsp_buffer = !current_dsp_buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long SoftwareMixerBackend_Init(void (*callback)(long *stream, size_t frames_total))
|
||||||
|
{
|
||||||
|
parent_callback = callback;
|
||||||
|
|
||||||
|
current_dsp_buffer = false;
|
||||||
|
|
||||||
|
stream_buffer = (short*)linearAlloc(FRAMES_PER_BUFFER * sizeof(short) * 2 * 2);
|
||||||
|
|
||||||
|
if (stream_buffer != NULL)
|
||||||
|
{
|
||||||
|
if (ndspInit() == 0)
|
||||||
|
{
|
||||||
|
ndspSetCallback(Callback, NULL);
|
||||||
|
|
||||||
|
ndspSetOutputMode(NDSP_OUTPUT_STEREO);
|
||||||
|
|
||||||
|
ndspChnSetInterp(0, NDSP_INTERP_LINEAR);
|
||||||
|
ndspChnSetRate(0, SAMPLE_RATE);
|
||||||
|
ndspChnSetFormat(0, NDSP_FORMAT_STEREO_PCM16);
|
||||||
|
|
||||||
|
float mix[12];
|
||||||
|
mix[0] = 1.0f;
|
||||||
|
mix[1] = 1.0f;
|
||||||
|
mix[2] = 0.0f;
|
||||||
|
mix[3] = 0.0f;
|
||||||
|
mix[4] = 0.0f;
|
||||||
|
mix[5] = 0.0f;
|
||||||
|
mix[6] = 0.0f;
|
||||||
|
mix[7] = 0.0f;
|
||||||
|
mix[8] = 0.0f;
|
||||||
|
mix[9] = 0.0f;
|
||||||
|
mix[10] = 0.0f;
|
||||||
|
mix[11] = 0.0f;
|
||||||
|
ndspChnSetMix(0, mix);
|
||||||
|
|
||||||
|
memset(dsp_buffers, 0, sizeof(dsp_buffers));
|
||||||
|
dsp_buffers[0].data_vaddr = &stream_buffer[FRAMES_PER_BUFFER * 2 * 0];
|
||||||
|
dsp_buffers[0].nsamples = FRAMES_PER_BUFFER;
|
||||||
|
dsp_buffers[1].data_vaddr = &stream_buffer[FRAMES_PER_BUFFER * 2 * 1];
|
||||||
|
dsp_buffers[1].nsamples = FRAMES_PER_BUFFER;
|
||||||
|
|
||||||
|
FullBuffer(stream_buffer, FRAMES_PER_BUFFER * 2);
|
||||||
|
|
||||||
|
return SAMPLE_RATE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("ndspInit failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
linearFree(stream_buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("linearAlloc failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareMixerBackend_Deinit(void)
|
||||||
|
{
|
||||||
|
ndspExit();
|
||||||
|
|
||||||
|
linearFree(stream_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SoftwareMixerBackend_Start(void)
|
||||||
|
{
|
||||||
|
ndspChnWaveBufAdd(0, &dsp_buffers[0]);
|
||||||
|
ndspChnWaveBufAdd(0, &dsp_buffers[1]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareMixerBackend_LockMixerMutex(void)
|
||||||
|
{
|
||||||
|
// ma_mutex_lock(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareMixerBackend_UnlockMixerMutex(void)
|
||||||
|
{
|
||||||
|
// ma_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareMixerBackend_LockOrganyaMutex(void)
|
||||||
|
{
|
||||||
|
// ma_mutex_lock(&organya_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareMixerBackend_UnlockOrganyaMutex(void)
|
||||||
|
{
|
||||||
|
// ma_mutex_unlock(&organya_mutex);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue