D
Don't quote me on this, but I'm fairly sure he wants to use it on, you know, 3DS. Since this is the 3DS homebrew development section.What platform are you targeting? (...) but without knowing what hardware you want to use (...)
Don't quote me on this, but I'm fairly sure he wants to use it on, you know, 3DS. Since this is the 3DS homebrew development section.
Yeah, I was hoping for one already ported to the 3ds because I'm not experienced with audio enough to port one myself.
By simple, I mean something like this C code I made up that's similar to SoLoud.
Code:OggSound myGoodOggSound; OggStream myGoodOggStream; PlayHandle myPlayHandle1; PlayHandle myPlayHandle2; initAudio(OGG); loadSound(&myGoodOggSound,"sfx.ogg"); loadStream(&myGoodOggStream,"music.ogg"); myPlayHandle1= playSound(myGoodOggSound); myPlayHandle2 = playStream(myGoodOggStream); while(1);
If there are no alternatives, I'll try SDL_Mixer. I don't want to though because it can only play one music stream at a time.
You could also borrow some some of the code from ctrmus. It's licensed under the GPL v3.0.Yeah, I was hoping for one already ported to the 3ds because I'm not experienced with audio enough to port one myself.
By simple, I mean something like this C code I made up that's similar to SoLoud.
Code:OggSound myGoodOggSound; OggStream myGoodOggStream; PlayHandle myPlayHandle1; PlayHandle myPlayHandle2; initAudio(OGG); loadSound(&myGoodOggSound,"sfx.ogg"); loadStream(&myGoodOggStream,"music.ogg"); myPlayHandle1= playSound(myGoodOggSound); myPlayHandle2 = playStream(myGoodOggStream); while(1);
If there are no alternatives, I'll try SDL_Mixer. I don't want to though because it can only play one music stream at a time.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <tremor/ivorbiscodec.h>
#include <tremor/ivorbisfile.h>
#include <3ds.h>
#define MUSIC_CHANNEL 1
#define BUFFER_SIZE 4096
#define STACKSIZE (4 * 1024)
typedef struct {
float rate;
u32 channels;
u32 encoding;
u32 nsamples;
u32 size;
char* data;
bool loop;
int audiochannel;
float mix[12];
ndspInterpType interp;
OggVorbis_File ovf;
} Music;
Music music;
void load() {
FILE * file = fopen("example.ogg", "rb");
if (ov_open(file, &music.ovf, NULL, 0) < 0) {
printf("ogg vorbis file error\n");
}
vorbis_info * vorbisInfo = ov_info(&music.ovf, -1);
if (vorbisInfo == NULL) {
printf("could not retrieve ogg audio stream information\n");
}
music.rate = (float)vorbisInfo->rate;
music.channels = (u32)vorbisInfo->channels;
music.encoding = NDSP_ENCODING_PCM16;
music.nsamples = (u32)ov_pcm_total(&music.ovf, -1);
music.size = music.nsamples * music.channels * 2;
music.audiochannel = 0;
music.loop = false;
if (linearSpaceFree() < music.size) {
printf("not enough linear memory available\n");
}
music.data = (char*)linearAlloc(music.size);
printf("rate:%f\n", music.rate);
printf("channels:%ld\n", music.channels);
printf("encoding:%ld\n", music.encoding);
printf("nsamples:%ld\n", music.nsamples);
printf("size:%ld\n", music.size);
int offset = 0;
int eof = 0;
int currentSection;
while (!eof) {
long ret = ov_read(&music.ovf, &music.data[offset], 4096, ¤tSection);
if (ret == 0) {
eof = 1;
}
else if (ret < 0) {
ov_clear(&music.ovf);
linearFree(music.data);
printf("error in the ogg vorbis stream\n");
}
else {
offset += ret;
}
}
linearFree(&music.ovf);
ov_clear(&music.ovf);
fclose(file);
}
int play() {
if (music.audiochannel == -1) {
printf("No available audio channel\n");
return -1;
}
ndspChnWaveBufClear(music.audiochannel);
ndspChnReset(music.audiochannel);
ndspChnInitParams(music.audiochannel);
ndspChnSetMix(music.audiochannel, music.mix);
ndspChnSetInterp(music.audiochannel, music.interp);
ndspChnSetRate(music.audiochannel, music.rate);
ndspChnSetFormat(music.audiochannel, NDSP_CHANNELS(music.channels) | NDSP_ENCODING(music.encoding));
ndspWaveBuf waveBuf;
waveBuf.data_vaddr = music.data;
waveBuf.nsamples = music.nsamples;
waveBuf.looping = music.loop;
DSP_FlushDataCache((u32*)music.data, music.size);
ndspChnWaveBufAdd(music.audiochannel, &waveBuf);
return 0;
}
int main() {
gfxInitDefault();
consoleInit(GFX_TOP, nullptr);
load();
play();
while (1) {
hidScanInput();
u32 kDown = hidKeysDown();
if (kDown & KEY_START) break;
gfxFlushBuffers();
gfxSwapBuffers();
gspWaitForVBlank();
}
gfxExit();
ndspExit();
return 0;
}
I don’t see a call to ndspInit?I attempted to play the ogg file using libtremor but failed.
Is there a mistake in the code?
Code:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <cstdlib> #include <cstring> #include <cstdio> #include <tremor/ivorbiscodec.h> #include <tremor/ivorbisfile.h> #include <3ds.h> #define MUSIC_CHANNEL 1 #define BUFFER_SIZE 4096 #define STACKSIZE (4 * 1024) typedef struct { float rate; u32 channels; u32 encoding; u32 nsamples; u32 size; char* data; bool loop; int audiochannel; float mix[12]; ndspInterpType interp; OggVorbis_File ovf; } Music; Music music; void load() { FILE * file = fopen("example.ogg", "rb"); if (ov_open(file, &music.ovf, NULL, 0) < 0) { printf("ogg vorbis file error\n"); } vorbis_info * vorbisInfo = ov_info(&music.ovf, -1); if (vorbisInfo == NULL) { printf("could not retrieve ogg audio stream information\n"); } music.rate = (float)vorbisInfo->rate; music.channels = (u32)vorbisInfo->channels; music.encoding = NDSP_ENCODING_PCM16; music.nsamples = (u32)ov_pcm_total(&music.ovf, -1); music.size = music.nsamples * music.channels * 2; music.audiochannel = 0; music.loop = false; if (linearSpaceFree() < music.size) { printf("not enough linear memory available\n"); } music.data = (char*)linearAlloc(music.size); printf("rate:%f\n", music.rate); printf("channels:%ld\n", music.channels); printf("encoding:%ld\n", music.encoding); printf("nsamples:%ld\n", music.nsamples); printf("size:%ld\n", music.size); int offset = 0; int eof = 0; int currentSection; while (!eof) { long ret = ov_read(&music.ovf, &music.data[offset], 4096, ¤tSection); if (ret == 0) { eof = 1; } else if (ret < 0) { ov_clear(&music.ovf); linearFree(music.data); printf("error in the ogg vorbis stream\n"); } else { offset += ret; } } linearFree(&music.ovf); ov_clear(&music.ovf); fclose(file); } int play() { if (music.audiochannel == -1) { printf("No available audio channel\n"); return -1; } ndspChnWaveBufClear(music.audiochannel); ndspChnReset(music.audiochannel); ndspChnInitParams(music.audiochannel); ndspChnSetMix(music.audiochannel, music.mix); ndspChnSetInterp(music.audiochannel, music.interp); ndspChnSetRate(music.audiochannel, music.rate); ndspChnSetFormat(music.audiochannel, NDSP_CHANNELS(music.channels) | NDSP_ENCODING(music.encoding)); ndspWaveBuf waveBuf; waveBuf.data_vaddr = music.data; waveBuf.nsamples = music.nsamples; waveBuf.looping = music.loop; DSP_FlushDataCache((u32*)music.data, music.size); ndspChnWaveBufAdd(music.audiochannel, &waveBuf); return 0; } int main() { gfxInitDefault(); consoleInit(GFX_TOP, nullptr); load(); play(); while (1) { hidScanInput(); u32 kDown = hidKeysDown(); if (kDown & KEY_START) break; gfxFlushBuffers(); gfxSwapBuffers(); gspWaitForVBlank(); } gfxExit(); ndspExit(); return 0; }
I made those improvements but got errors.I don’t see a call to ndspInit?
[HW.Memory <Error> core\memory.cpp:GetPointer:283: unknown GetPointer @ 0x00000000
[Audio.DSP <Warning> audio_core\hle\source.cpp:DequeueBuffer:312: source_id=0 buffer_id=20 length=0: Invalid physical address 0x00000000
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <tremor/ivorbiscodec.h>
#include <tremor/ivorbisfile.h>
#include <3ds.h>
#define MUSIC_CHANNEL 1
#define BUFFER_SIZE 4096
#define STACKSIZE (4 * 1024)
typedef struct {
float rate;
u32 channels;
u32 encoding;
u32 nsamples;
u32 size;
u8* data;
bool loop;
int audiochannel;
float mix[12];
ndspInterpType interp;
OggVorbis_File ovf;
} Music;
Music music;
void load() {
FILE * file = fopen("example.ogg", "rb");
if (ov_open(file, &music.ovf, NULL, 0) < 0) {
printf("ogg vorbis file error\n");
}
vorbis_info * vorbisInfo = ov_info(&music.ovf, -1);
if (vorbisInfo == NULL) {
printf("could not retrieve ogg audio stream information\n");
}
music.rate = (float)vorbisInfo->rate;
music.channels = (u32)vorbisInfo->channels;
music.encoding = NDSP_ENCODING_PCM16;
music.nsamples = (u32)ov_pcm_total(&music.ovf, -1);
music.size = music.nsamples * music.channels * 2;
music.audiochannel = 0;
music.loop = false;
if (linearSpaceFree() < music.size) {
printf("not enough linear memory available\n");
music.data = static_cast<u8*>(linearAlloc(music.size));
printf("rate:%f\n", music.rate);
printf("channels:%ld\n", music.channels);
printf("encoding:%ld\n", music.encoding);
printf("nsamples:%ld\n", music.nsamples);
printf("size:%ld\n", music.size);
int offset = 0;
int eof = 0;
int currentSection;
while (!eof) {
long ret = ov_read(&music.ovf, &music.data[offset], 4096, ¤tSection);
if (ret == 0) {
eof = 1;
}
else if (ret < 0) {
ov_clear(&music.ovf);
linearFree(music.data);
printf("error in the ogg vorbis stream\n");
}
else {
offset += ret;
}
}
linearFree(&music.ovf);
ov_clear(&music.ovf);
fclose(file);
}
int play() {
if (music.audiochannel == -1) {
printf("No available audio channel\n");
return -1;
}
ndspChnWaveBufClear(music.audiochannel);
ndspChnReset(music.audiochannel);
ndspChnInitParams(music.audiochannel);
ndspChnSetMix(music.audiochannel, music.mix);
ndspChnSetInterp(music.audiochannel, music.interp);
ndspChnSetRate(music.audiochannel, music.rate);
ndspChnSetFormat(music.audiochannel, NDSP_CHANNELS(music.channels) | NDSP_ENCODING(music.encoding));
ndspWaveBuf waveBuf;
memset(&waveBuf, 0, sizeof(ndspWaveBuf));
waveBuf.data_vaddr = music.data;
waveBuf.nsamples = music.nsamples;
waveBuf.looping = music.loop;
waveBuf.status = NDSP_WBUF_FREE;
DSP_FlushDataCache(music.data, music.size);
ndspChnWaveBufAdd(music.audiochannel, &waveBuf);
return 0;
}
int main() {
gfxInitDefault();
consoleInit(GFX_TOP, nullptr);
ndspInit();
ndspSetOutputMode(NDSP_OUTPUT_STEREO);
ndspSetOutputCount(1);
load();
play();
while (aptMainLoop()) {
hidScanInput();
u32 keys = hidKeysDown();
if (keys & KEY_START)
break;
gfxFlushBuffers();
gfxSwapBuffers();
gspWaitForVBlank();
}
ndspChnWaveBufClear(music.audiochannel);
gfxExit();
ndspExit();
return 0;
}
Check if linearAlloc succeeded?I made those improvements but got errors.
Code:[HW.Memory <Error> core\memory.cpp:GetPointer:283: unknown GetPointer @ 0x00000000 [Audio.DSP <Warning> audio_core\hle\source.cpp:DequeueBuffer:312: source_id=0 buffer_id=20 length=0: Invalid physical address 0x00000000
Code:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <cstdlib> #include <cstring> #include <cstdio> #include <tremor/ivorbiscodec.h> #include <tremor/ivorbisfile.h> #include <3ds.h> #define MUSIC_CHANNEL 1 #define BUFFER_SIZE 4096 #define STACKSIZE (4 * 1024) typedef struct { float rate; u32 channels; u32 encoding; u32 nsamples; u32 size; u8* data; bool loop; int audiochannel; float mix[12]; ndspInterpType interp; OggVorbis_File ovf; } Music; Music music; void load() { FILE * file = fopen("example.ogg", "rb"); if (ov_open(file, &music.ovf, NULL, 0) < 0) { printf("ogg vorbis file error\n"); } vorbis_info * vorbisInfo = ov_info(&music.ovf, -1); if (vorbisInfo == NULL) { printf("could not retrieve ogg audio stream information\n"); } music.rate = (float)vorbisInfo->rate; music.channels = (u32)vorbisInfo->channels; music.encoding = NDSP_ENCODING_PCM16; music.nsamples = (u32)ov_pcm_total(&music.ovf, -1); music.size = music.nsamples * music.channels * 2; music.audiochannel = 0; music.loop = false; if (linearSpaceFree() < music.size) { printf("not enough linear memory available\n"); music.data = static_cast<u8*>(linearAlloc(music.size)); printf("rate:%f\n", music.rate); printf("channels:%ld\n", music.channels); printf("encoding:%ld\n", music.encoding); printf("nsamples:%ld\n", music.nsamples); printf("size:%ld\n", music.size); int offset = 0; int eof = 0; int currentSection; while (!eof) { long ret = ov_read(&music.ovf, &music.data[offset], 4096, ¤tSection); if (ret == 0) { eof = 1; } else if (ret < 0) { ov_clear(&music.ovf); linearFree(music.data); printf("error in the ogg vorbis stream\n"); } else { offset += ret; } } linearFree(&music.ovf); ov_clear(&music.ovf); fclose(file); } int play() { if (music.audiochannel == -1) { printf("No available audio channel\n"); return -1; } ndspChnWaveBufClear(music.audiochannel); ndspChnReset(music.audiochannel); ndspChnInitParams(music.audiochannel); ndspChnSetMix(music.audiochannel, music.mix); ndspChnSetInterp(music.audiochannel, music.interp); ndspChnSetRate(music.audiochannel, music.rate); ndspChnSetFormat(music.audiochannel, NDSP_CHANNELS(music.channels) | NDSP_ENCODING(music.encoding)); ndspWaveBuf waveBuf; memset(&waveBuf, 0, sizeof(ndspWaveBuf)); waveBuf.data_vaddr = music.data; waveBuf.nsamples = music.nsamples; waveBuf.looping = music.loop; waveBuf.status = NDSP_WBUF_FREE; DSP_FlushDataCache(music.data, music.size); ndspChnWaveBufAdd(music.audiochannel, &waveBuf); return 0; } int main() { gfxInitDefault(); consoleInit(GFX_TOP, nullptr); ndspInit(); ndspSetOutputMode(NDSP_OUTPUT_STEREO); ndspSetOutputCount(1); load(); play(); while (aptMainLoop()) { hidScanInput(); u32 keys = hidKeysDown(); if (keys & KEY_START) break; gfxFlushBuffers(); gfxSwapBuffers(); gspWaitForVBlank(); } ndspChnWaveBufClear(music.audiochannel); gfxExit(); ndspExit(); return 0; }
I made a mistake in placing linearFree.Check if linearAlloc succeeded?
Why are you calling linearFree in the load function - on non “linear” region memory(music.ovf)?
If gspWaitForVBlank is having problems - then something else is causing it.I made a mistake in placing linearFree.
linearAlloc seemed to be successful.
It seems that gspWaitForVBlank () is causing problems, but is it OK to delete this?
guys i know this sounds silly but i am new to the modding scene and also to gba temp . BUT I DONT KNOW HOW TO POST A FU#%ING question!!!!!!!!!!!!!!!HOW DO U POST ON GBATEMP NET!!!!!!!!!!!!!!!!!!
I made those improvements but got errors.
Code:[HW.Memory <Error> core\memory.cpp:GetPointer:283: unknown GetPointer @ 0x00000000 [Audio.DSP <Warning> audio_core\hle\source.cpp:DequeueBuffer:312: source_id=0 buffer_id=20 length=0: Invalid physical address 0x00000000
Code:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <cstdlib> #include <cstring> #include <cstdio> #include <tremor/ivorbiscodec.h> #include <tremor/ivorbisfile.h> #include <3ds.h> #define MUSIC_CHANNEL 1 #define BUFFER_SIZE 4096 #define STACKSIZE (4 * 1024) typedef struct { float rate; u32 channels; u32 encoding; u32 nsamples; u32 size; u8* data; bool loop; int audiochannel; float mix[12]; ndspInterpType interp; OggVorbis_File ovf; } Music; Music music; void load() { FILE * file = fopen("example.ogg", "rb"); if (ov_open(file, &music.ovf, NULL, 0) < 0) { printf("ogg vorbis file error\n"); } vorbis_info * vorbisInfo = ov_info(&music.ovf, -1); if (vorbisInfo == NULL) { printf("could not retrieve ogg audio stream information\n"); } music.rate = (float)vorbisInfo->rate; music.channels = (u32)vorbisInfo->channels; music.encoding = NDSP_ENCODING_PCM16; music.nsamples = (u32)ov_pcm_total(&music.ovf, -1); music.size = music.nsamples * music.channels * 2; music.audiochannel = 0; music.loop = false; if (linearSpaceFree() < music.size) { printf("not enough linear memory available\n"); music.data = static_cast<u8*>(linearAlloc(music.size)); printf("rate:%f\n", music.rate); printf("channels:%ld\n", music.channels); printf("encoding:%ld\n", music.encoding); printf("nsamples:%ld\n", music.nsamples); printf("size:%ld\n", music.size); int offset = 0; int eof = 0; int currentSection; while (!eof) { long ret = ov_read(&music.ovf, &music.data[offset], 4096, ¤tSection); if (ret == 0) { eof = 1; } else if (ret < 0) { ov_clear(&music.ovf); linearFree(music.data); printf("error in the ogg vorbis stream\n"); } else { offset += ret; } } linearFree(&music.ovf); ov_clear(&music.ovf); fclose(file); } int play() { if (music.audiochannel == -1) { printf("No available audio channel\n"); return -1; } ndspChnWaveBufClear(music.audiochannel); ndspChnReset(music.audiochannel); ndspChnInitParams(music.audiochannel); ndspChnSetMix(music.audiochannel, music.mix); ndspChnSetInterp(music.audiochannel, music.interp); ndspChnSetRate(music.audiochannel, music.rate); ndspChnSetFormat(music.audiochannel, NDSP_CHANNELS(music.channels) | NDSP_ENCODING(music.encoding)); ndspWaveBuf waveBuf; memset(&waveBuf, 0, sizeof(ndspWaveBuf)); waveBuf.data_vaddr = music.data; waveBuf.nsamples = music.nsamples; waveBuf.looping = music.loop; waveBuf.status = NDSP_WBUF_FREE; DSP_FlushDataCache(music.data, music.size); ndspChnWaveBufAdd(music.audiochannel, &waveBuf); return 0; } int main() { gfxInitDefault(); consoleInit(GFX_TOP, nullptr); ndspInit(); ndspSetOutputMode(NDSP_OUTPUT_STEREO); ndspSetOutputCount(1); load(); play(); while (aptMainLoop()) { hidScanInput(); u32 keys = hidKeysDown(); if (keys & KEY_START) break; gfxFlushBuffers(); gfxSwapBuffers(); gspWaitForVBlank(); } ndspChnWaveBufClear(music.audiochannel); gfxExit(); ndspExit(); return 0; }
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <tremor/ivorbiscodec.h>
#include <tremor/ivorbisfile.h>
#include <3ds.h>
typedef struct {
float rate;
u32 channels;
u32 encoding;
u32 nsamples;
u32 size;
char* data;
bool loop;
int audiochannel;
float mix[12];
ndspInterpType interp;
OggVorbis_File ovf;
} Music;
Music music;
void load() {
FILE * file = fopen("test.ogg", "rb");
if (ov_open(file, &music.ovf, NULL, 0) < 0) {
printf("ogg vorbis file error\n");
}
vorbis_info * vorbisInfo = ov_info(&music.ovf, -1);
if (vorbisInfo == NULL) {
printf("could not retrieve ogg audio stream information\n");
}
music.rate = (float)vorbisInfo->rate;
music.channels = (u32)vorbisInfo->channels;
music.encoding = NDSP_ENCODING_PCM16;
music.nsamples = (u32)ov_pcm_total(&music.ovf, -1);
music.size = music.nsamples * music.channels * 2;
music.audiochannel = 0;
music.loop = false;
music.interp = NDSP_INTERP_NONE;
if (linearSpaceFree() < music.size) {
printf("not enough linear memory available\n");
}
music.data = static_cast<char*>(linearAlloc(music.size));
if (!music.data){
fclose(file);
}
printf("buffersize:%d\n", linearGetSize(music.data));
printf("rate:%f\n", music.rate);
printf("channels:%ld\n", music.channels);
printf("encoding:%ld\n", music.encoding);
printf("nsamples:%ld\n", music.nsamples);
printf("size:%ld\n", music.size);
// Decoding loop
int offset = 0;
int eof = 0;
int currentSection = 0;
int readSize = 0;
int comSize = 0;
char* tmpBuffer = static_cast<char*>(linearAlloc(music.size));
while (1) {
readSize = ov_read(&music.ovf, (char*)tmpBuffer, 4096, ¤tSection);
if (readSize == 0) break; //EOF
memcpy(music.data + comSize, tmpBuffer, readSize);
comSize += readSize;
}
fclose(file);
}
int play() {
if (music.audiochannel == -1) {
printf("No available audio channel\n");
return -1;
}
ndspChnReset(music.audiochannel);
ndspChnInitParams(music.audiochannel);
ndspChnSetMix(music.audiochannel, music.mix);
ndspChnSetInterp(music.audiochannel, music.interp);
ndspChnSetRate(music.audiochannel, music.rate);
ndspChnSetFormat(music.audiochannel, NDSP_CHANNELS(music.channels) | NDSP_ENCODING(music.encoding));
ndspWaveBuf waveBuf;
memset(&waveBuf, 0, sizeof(ndspWaveBuf));
waveBuf.data_vaddr = (const void*)music.data;
waveBuf.nsamples = music.nsamples;
waveBuf.looping = music.loop;
waveBuf.status = NDSP_WBUF_FREE;
DSP_FlushDataCache(music.data, music.size);
ndspChnWaveBufAdd(music.audiochannel, &waveBuf);
return 0;
}
int main() {
gfxInitDefault();
consoleInit(GFX_TOP, nullptr);
ndspInit();
ndspSetOutputMode(NDSP_OUTPUT_STEREO);
ndspSetOutputCount(1);
load();
play();
while (aptMainLoop()) {
hidScanInput();
u32 keys = hidKeysDown();
if (keys & KEY_START)
break;
gfxFlushBuffers();
gfxSwapBuffers();
gspWaitForVBlank();
}
linearFree(&music.ovf);
ov_clear(&music.ovf);
ndspChnWaveBufClear(music.audiochannel);
gfxExit();
ndspExit();
return 0;
}
I tried it on 3DS but it ended with an error "an exception occurred".That's not necessarily a problem with your code. Even legit games have that error in Citra. You will need to use the real hardware to test it.