Воспроизведение синусоиды с использованием звука 3DS

Привет, я только начинаю заниматься звуковым программированием, и я хотел бы начать с 3DS, чтобы сделать базовый портативный синтезатор. Существует пример кода, который поставляется с devkitpro, который показывает простую реализацию синусоидальной волны, воспроизводимой из динамиков. Я пытался понять это, и это работало с некоторым успехом. Проблема в том, что код довольно плохо документирован и есть только некоторые вызываемые функции, которые я не могу понять только по их именам. Я посмотрел онлайн, но, увы, ничего не нашел. Я просто надеялся, что кто-то может указать мне правильное направление ресурса, который объясняет программирование звука 3DS, или если бы кто-то мог дать мне построчное объяснение кода.

Вот код (все комментарии сделаны мной, чтобы помочь мне понять это, я не знаю, верны ли они, но я думаю, что они это делают):

#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;//allows dest to access audio buffer
//fills audio buffer and adds a sample to it for each i
for (int i=0; i<size; i++) {

//divided by the sample rate to scale the wave to how time is
//freq*2PI*(offset+i) results in the angle at that time of the wave and INT16_MAX is equivalent to the amplitude
s16 sample = INT16_MAX * sin(frequency*(2*M_PI)*(offset+i)/SAMPLERATE);

dest[i] = (sample<<16) | (sample & 0xffff);
}

DSP_FlushDataCache(audioBuffer,size);

}

//----------------------------------------------------------------------------
int main(int argc, char **argv) {
//----------------------------------------------------------------------------
//initialises wave buffer
PrintConsole topScreen;
ndspWaveBuf waveBuf[2];
//initialises the graphics for the 3ds
gfxInitDefault();

//initialises screen

consoleInit(GFX_TOP, &topScreen);

consoleSelect(&topScreen);

printf("libctru streaming audio\n");
//sets aside memory for the audio buffer to be stored
u32 *audioBuffer = (u32*)linearAlloc(SAMPLESPERBUF*BYTESPERSAMPLE*2);
//acts as a toggle flag
bool fillBlock = false;
//initialises audio
ndspInit();

//initialises speakers to stereo output and sets the sample rate
ndspSetOutputMode(NDSP_OUTPUT_STEREO);

ndspChnSetInterp(0, NDSP_INTERP_LINEAR);
ndspChnSetRate(0, SAMPLERATE);
ndspChnSetFormat(0, NDSP_FORMAT_STEREO_PCM16);

float mix[12];
memset(mix, 0, sizeof(mix));//sets all elements of the array to zero
mix[0] = 1.0;
mix[1] = 1.0;
ndspChnSetMix(0, mix);

int notefreq[] = {
262, 294, 339, 349, 392, 440,
494, 440, 392, 349, 339, 294
};

int note = 4;

memset(waveBuf,0,sizeof(waveBuf));//clears waveBuf
waveBuf[0].data_vaddr = &audioBuffer[0];
waveBuf[0].nsamples = SAMPLESPERBUF;
waveBuf[1].data_vaddr = &audioBuffer[SAMPLESPERBUF];
waveBuf[1].nsamples = SAMPLESPERBUF;

size_t stream_offset = 0;//variable to hold how far into the wave has run

fill_buffer(audioBuffer,stream_offset, SAMPLESPERBUF * 2, notefreq[note]);

stream_offset += SAMPLESPERBUF;

ndspChnWaveBufAdd(0, &waveBuf[0]);
ndspChnWaveBufAdd(0, &waveBuf[1]);

printf("Press up/down to change tone\n");

while(aptMainLoop()) {

gfxSwapBuffers();
gfxFlushBuffers();
gspWaitForVBlank();

hidScanInput();
u32 kDown = hidKeysDown();

if (kDown & KEY_START)
break; // break in order to return to hbmenu

if (kDown & KEY_DOWN) {
note -= 1;

if (note<0) note = sizeof(notefreq)/sizeof(notefreq[0])-1;
}

if (kDown & KEY_UP) {
note += 1;

if (note > (sizeof(notefreq)/sizeof(notefreq[0])-1)) note = 0;
}
//checks if audio buffer has been emptied if it has, it refills it
if (waveBuf[fillBlock].status == NDSP_WBUF_DONE) {

fill_buffer(waveBuf[fillBlock].data_pcm16, stream_offset, waveBuf[fillBlock].nsamples,notefreq[note]);

ndspChnWaveBufAdd(0, &waveBuf[fillBlock]);
stream_offset += waveBuf[fillBlock].nsamples;

fillBlock = !fillBlock;
}
}

ndspExit();

linearFree(audioBuffer);

gfxExit();
return 0;
}

Спасибо, я был бы очень благодарен любому, кто ответит на это, потому что я хотел бы избежать слепого использования кода.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …