參考資訊:
https://hub.docker.com/r/greatwizard/devkitarm-3ds
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <3ds.h>
#define SAMPLERATE 22050
#define SAMPLESPERBUF (SAMPLERATE / 30)
#define BYTESPERSAMPLE 4
void fill_buffer(void *audioBuffer, size_t offset, size_t size, int frequency)
{
u32 *dest = (u32 *)audioBuffer;
for (int i=0; i<size; i++) {
s16 sample = INT16_MAX * sin(frequency * (2 * M_PI) * (offset + i) / SAMPLERATE);
dest[i] = (sample << 16) | (sample & 0xffff);
}
DSP_FlushDataCache(audioBuffer, size);
}
int main(void)
{
int note = 4;
bool fillBlock = false;
u32 *audioBuffer = NULL;
size_t stream_offset = 0;
float vol[12] = { 1.0, 1.0 };
ndspWaveBuf waveBuf[2] = { 0 };
gfxInitDefault();
audioBuffer = (u32 *)linearAlloc(SAMPLESPERBUF * BYTESPERSAMPLE * 2);
ndspInit();
ndspSetOutputMode(NDSP_OUTPUT_STEREO);
ndspChnSetInterp(0, NDSP_INTERP_LINEAR);
ndspChnSetRate(0, SAMPLERATE);
ndspChnSetFormat(0, NDSP_FORMAT_STEREO_PCM16);
ndspChnSetMix(0, vol);
waveBuf[0].data_vaddr = &audioBuffer[0];
waveBuf[0].nsamples = SAMPLESPERBUF;
waveBuf[1].data_vaddr = &audioBuffer[SAMPLESPERBUF];
waveBuf[1].nsamples = SAMPLESPERBUF;
ndspChnWaveBufAdd(0, &waveBuf[0]);
ndspChnWaveBufAdd(0, &waveBuf[1]);
while (aptMainLoop()) {
gfxSwapBuffers();
gfxFlushBuffers();
gspWaitForVBlank();
if (waveBuf[fillBlock].status == NDSP_WBUF_DONE) {
fill_buffer(waveBuf[fillBlock].data_pcm16, stream_offset, waveBuf[fillBlock].nsamples, 440);
ndspChnWaveBufAdd(0, &waveBuf[fillBlock]);
stream_offset += waveBuf[fillBlock].nsamples;
fillBlock = !fillBlock;
}
}
ndspExit();
linearFree(audioBuffer);
gfxExit();
return 0;
}