Homebrew Need help with homebrew developing

  • Thread starter Thread starter EinTim
  • Start date Start date
  • Views Views 2,328
  • Replies Replies 11
  • Likes Likes 1

EinTim

Member
Newcomer
Joined
Jan 26, 2021
Messages
6
Reaction score
2
Trophies
0
Age
26
XP
88
Country
Germany
Hello,

Is there a way to play sound files from romfs or any other place without having an extra folder for sounds on the sdcard?
I tried this:

void audio_load(const char *audio){

FILE *file = fopen(audio, "rb");
fseek(file, 0, SEEK_END);
off_t size = ftell(file);
fseek(file, 0, SEEK_SET);
buffer = linearAlloc(size);
off_t bytesRead = fread(buffer, 1, size, file);
fclose(file);
csndPlaySound(8, SOUND_FORMAT_16BIT | SOUND_REPEAT, 48000, 1, 0, buffer, buffer, size);
linearFree(buffer);
}

audio_load("romfs:/audio/original_raw.bin");//and then call it like this.

When i try to run it, it will crash my 3ds with an Error message. Pls help.

Bye Tim
 
  • Like
Reactions: Julie_Pilgrim
Are you sure the audio file is not too big to fit into the 3DS's memory? It probably crashes when you allocate the memory. Try streaming it instead, like in the audio/streaming 3ds example.
 
Are you sure the audio file is not too big to fit into the 3DS's memory? It probably crashes when you allocate the memory. Try streaming it instead, like in the audio/streaming 3ds example.
It's 11mb big.
 
It's 11mb big.
That's probably still too big when using linearAlloc, I really don't understand the differences between that and the standard malloc in devkitpro but memory allocated with linearAlloc seems to be some special kind of memory that works with the DSP. With streaming you'll only have to allocate a few kilobytes with linearAlloc and the actual audio data can be copied to the buffer either from a separately allocated file buffer or streamed directly from the file.
 
That's probably still too big when using linearAlloc, I really don't understand the differences between that and the standard malloc in devkitpro but memory allocated with linearAlloc seems to be some special kind of memory that works with the DSP. With streaming you'll only have to allocate a few kilobytes with linearAlloc and the actual audio data can be copied to the buffer either from a separately allocated file buffer or streamed directly from the file.
Do i need an extra folder to stream
That's probably still too big when using linearAlloc, I really don't understand the differences between that and the standard malloc in devkitpro but memory allocated with linearAlloc seems to be some special kind of memory that works with the DSP. With streaming you'll only have to allocate a few kilobytes with linearAlloc and the actual audio data can be copied to the buffer either from a separately allocated file buffer or streamed directly from the file.
can you give me a little example to stream a raw audio file?
 
Do i need an extra folder to stream

can you give me a little example to stream a raw audio file?
You don't need an extra folder, you can open the file from the same location in the same way. The basic streaming example from 3ds-examples is here: https://github.com/devkitPro/3ds-examples/blob/master/audio/streaming/source/main.c
You could also look at my attempts of streaming audio if the official example does not explain everything, but there's a lot of other unimportant code in this file: https://github.com/ic-scm/smashcustommusic-client-3ds/blob/master/3ds/source/audio.h
If you're still having trouble figuring it out, I could try writing a simple raw file streamer later.
 
Ok, I understand the examle in devkitpro now, but how do i get the notes from the bin file?

Edit: Yes, it would be nice if you could write a simple raw streamer
 
Last edited by EinTim,
Ok, I understand the examle in devkitpro now, but how do i get the notes from the bin file?
You should remove the code for notes and sine waves, the important thing here is setting up the NDSP buffers and then filling them. In the fill_buffer function, the "s16 sample" variable is the audio sample that is about to be added to the buffer. In the next line it is then duplicated into 2 stereo samples, if you are trying to play stereo audio then you could replace the two mentions of "sample" in that line with two different sample variables. If you had two input buffers (2 channels for stereo) of the same size as the output buffer that is passed to the fill_buffer function, the fill_buffer function could look something like this:
Code:
void fill_buffer(void *audioBuffer,size_t offset, size_t size, s16 *buffer_left, s16 *buffer_right ) {
    u32 *dest = (u32*)audioBuffer;
    
    for (int i=0; i<size; i++) {
        dest[i] = (buffer_left[i] << 16) | (buffer_right[i] & 0xffff);
    }
    
    DSP_FlushDataCache(audioBuffer,size);
}

I'll try writing the streamer in a few hours, currently busy with some other things. Would you be able to attach one of your raw audio files so I can understand the format of it?
 
You should remove the code for notes and sine waves, the important thing here is setting up the NDSP buffers and then filling them. In the fill_buffer function, the "s16 sample" variable is the audio sample that is about to be added to the buffer. In the next line it is then duplicated into 2 stereo samples, if you are trying to play stereo audio then you could replace the two mentions of "sample" in that line with two different sample variables. If you had two input buffers (2 channels for stereo) of the same size as the output buffer that is passed to the fill_buffer function, the fill_buffer function could look something like this:
Code:
void fill_buffer(void *audioBuffer,size_t offset, size_t size, s16 *buffer_left, s16 *buffer_right ) {
    u32 *dest = (u32*)audioBuffer;
  
    for (int i=0; i<size; i++) {
        dest[i] = (buffer_left[i] << 16) | (buffer_right[i] & 0xffff);
    }
  
    DSP_FlushDataCache(audioBuffer,size);
}

I'll try writing the streamer in a few hours, currently busy with some other things. Would you be able to attach one of your raw audio files so I can understand the format of it?
yes i can. It's a 16 bit signed pcm in raw format. mono 48000khz
 

Attachments

I really don't understand the differences between that and the standard malloc in devkitpro but memory allocated with linearAlloc seems to be some special kind of memory that works with the DSP.
The difference is regular heap makes no guarantee whatsoever that the virtual memory you map is contiguous physical memory. Linear heap does and it's required for hardware like the DSP because it doesn't know/care about virtual memory.
 
  • Like
Reactions: IC and EinTim
@EinTim I wrote the streaming example: https://github.com/ic-scm/3ds-simple-audio-stream
This still loads the entire file into memory instead of streaming directly from file, but it should work for files that aren't too big to fit into the 3DS memory. The audio file is loaded from romfs:/audio.bin, but you can change that in the code.
 
  • Like
Reactions: EinTim and Nutez
  • Like
Reactions: IC

Site & Scene News

Popular threads in this forum