#include <3ds.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
ndspWaveBuf waveBuf;
u8* data = NULL;
using namespace std;
int playWav(string path, int channel = 1, bool toloop = true) {
u32 sampleRate;
u32 dataSize;
u16 channels;
u16 bitsPerSample;
ndspSetOutputMode(NDSP_OUTPUT_STEREO);
ndspSetOutputCount(2); // Num of buffers
// Reading wav file
FILE* fp = fopen(path.c_str(), "rb");
if(!fp)
{
printf("Could not open the example.wav file.\n");
return -1;
}
char signature[4];
fread(signature, 1, 4, fp);
if( signature[0] != 'R' &&
signature[1] != 'I' &&
signature[2] != 'F' &&
signature[3] != 'F')
{
printf("Wrong file format.\n");
fclose(fp);
return -1;
}
fseek(fp,0,SEEK_END);
dataSize = ftell(fp);
fseek(fp, 22, SEEK_SET);
fread(&channels, 2, 1, fp);
fseek(fp, 24, SEEK_SET);
fread(&sampleRate, 4, 1, fp);
fseek(fp, 34, SEEK_SET);
fread(&bitsPerSample, 2, 1, fp);
if(dataSize == 0 || (channels != 1 && channels != 2) ||
(bitsPerSample != 8 && bitsPerSample != 16))
{
printf("Corrupted wav file.\n");
fclose(fp);
return -1;
}
// Allocating and reading samples
data = static_cast<u8*>(linearAlloc(dataSize));
fseek(fp, 44, SEEK_SET);
fread(data, 1, dataSize, fp);
fclose(fp);
fseek(fp, 44, SEEK_SET);
fread(data, 1, dataSize, fp);
fclose(fp);
dataSize/=2;
// Find the right format
u16 ndspFormat;
if(bitsPerSample == 8)
{
ndspFormat = (channels == 1) ?
NDSP_FORMAT_MONO_PCM8 :
NDSP_FORMAT_STEREO_PCM8;
}
else
{
ndspFormat = (channels == 1) ?
NDSP_FORMAT_MONO_PCM16 :
NDSP_FORMAT_STEREO_PCM16;
}
ndspChnReset(channel);
ndspChnSetInterp(channel, NDSP_INTERP_NONE);
ndspChnSetRate(channel, float(sampleRate));
ndspChnSetFormat(channel, ndspFormat);
// Create and play a wav buffer
std::memset(&waveBuf, 0, sizeof(waveBuf));
waveBuf.data_vaddr = reinterpret_cast<u32*>(data);
waveBuf.nsamples = dataSize / (bitsPerSample >> 3);
waveBuf.looping = toloop;
waveBuf.status = NDSP_WBUF_FREE;
DSP_FlushDataCache(data, dataSize);
ndspChnWaveBufAdd(channel, &waveBuf);
return ((dataSize / (bitsPerSample >> 3)) / sampleRate); // Return duration in seconds, for debugging purposes
}
int main(int argc, char* argv[]){
gfxInitDefault();
ndspInit();
consoleInit(GFX_TOP, nullptr);
ndspChnWaveBufClear(1);
playWav("sdmc:/example.wav");
while(aptMainLoop())
{
hidScanInput();
u32 keys = hidKeysDown();
if(keys & KEY_START)
break;
gfxFlushBuffers();
gfxSwapBuffers();
gspWaitForVBlank();
}
gfxExit();
ndspExit();
return 0;
}