Nintendo 3DS >> C/C++
Audio (Streaming)
參考資訊:
1. libctru doc
2. 3ds-examples
說明:
API |
---|
Result DSP_FlushDataCache(const void *address, u32 size) |
void* linearAlloc(size_t size) |
Result ndspInit(void) |
void ndspSetOutputMode(ndspOutputMode mode) |
void ndspChnSetInterp(int id, ndspInterpType type) |
void ndspChnSetRate(int id, float rate) |
void ndspChnSetFormat(int id, u16 format) |
void ndspChnSetMix(int id, float mix[12]) |
void ndspChnWaveBufAdd(int id, ndspWaveBuf *buf) |
void ndspExit(void) |
void linearFree(void* mem) |
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; }