Hello! While porting a game over to the 3DS via devkitpro, I've struggled with the audio. I'm using ndsp's wave buffers to stream audio as the game I'm porting uses such format, yet I've had a constant problem where the audio's crackly, likely due to buffers not being filled in time.
I've tried moving the audio callback to another thread, disabling game logic and rendering to leave processing entirely to audio, and setting the buffer size to 8000, the sample rate of the audio, and none gave good results. The first two didn't change anything, and the last one, while removing gaps, delayed and malformed the audio. The game's SDL2 frontend, the one I based the audio callback on, doesn't have issues with 256 buffers per sample, assuming it checks every frame. The 3DS port still has such an issue even if running at 60 FPS. I have yet to find a solution.
For some context, here's some code I'm using for the callbacks, written in C:
I've tried moving the audio callback to another thread, disabling game logic and rendering to leave processing entirely to audio, and setting the buffer size to 8000, the sample rate of the audio, and none gave good results. The first two didn't change anything, and the last one, while removing gaps, delayed and malformed the audio. The game's SDL2 frontend, the one I based the audio callback on, doesn't have issues with 256 buffers per sample, assuming it checks every frame. The 3DS port still has such an issue even if running at 60 FPS. I have yet to find a solution.
For some context, here's some code I'm using for the callbacks, written in C:
void audioFillCallback(void *s, size_t l)
{
uint16_t *s16 = (uint16_t *) s;
for (unsigned int i = 0; i < l; ++i)
{
s16[i] = musicOn ?
mixSamples(audioBuff[audioPos], 16 *
(SFG_getNextMusicSample() - SFG_musicTrackAverages[SFG_MusicState.track]))
: audioBuff[audioPos];
audioBuff[audioPos] = 0;
audioPos = (audioPos < SFG_SFX_SAMPLE_COUNT - 1) ? (audioPos + 1) : 0;
}
audioUpdateFrame = SFG_game.frame;
DSP_FlushDataCache(s, l);
}
...
while (aptMainLoop()) {
...
if (wbuffer.status == NDSP_WBUF_DONE) {
audioFillCallback(wbuffer.data_pcm16, wbuffer.nsamples);
ndspChnWaveBufAdd(0, &wbuffer);
};
...
};







