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;
}


返回上一頁