Homebrew Development

Discussion in '3DS - Homebrew Development and Emulators' started by aliak11, Jan 16, 2014.

  1. MyLegGuy

    MyLegGuy Moron

    Member
    562
    358
    Nov 26, 2014
    United States
    Do I also need to free any memory allocated with malloc, or can the 3ds free it itself after the program is closed?
     
  2. elhobbs

    elhobbs GBAtemp Advanced Fan

    Member
    818
    302
    Jul 28, 2008
    United States
    No, the system releases the entire memory regions used by malloc and linearAlloc back to the system when your program ends.
     
    MyLegGuy likes this.
  3. Joel16

    Joel16 Ils ne passeront pas

    Member
    516
    1,036
    May 8, 2011
    United States
    Doesn't concern you.
    True, although it's good practice to free once it's no longer being used.
     
  4. MaiconErick

    MaiconErick GBAtemp Regular

    Member
    102
    7
    Jan 4, 2016
    Brazil
    How can I search for all instaled titles and store their title IDs in a list?
    I'm playing and learning with the DevKit's examples, but didn't find anything related.
    Help :)
     
  5. elhobbs

    elhobbs GBAtemp Advanced Fan

    Member
    818
    302
    Jul 28, 2008
    United States
    You could look at the source for FBI and see how it does it.
     
    MaiconErick likes this.
  6. MaiconErick

    MaiconErick GBAtemp Regular

    Member
    102
    7
    Jan 4, 2016
    Brazil
    That's what I'm doing, I'm starting with 3DSident's "Installed title count", to have an idea of how it works first.
    It's really the hard way, I don't know what they're doing, I'm just trying to follow along haha

    I can't even find where the method(s) for listing the titles are in fbi source.
     
    Last edited by MaiconErick, Dec 24, 2017
  7. elhobbs

    elhobbs GBAtemp Advanced Fan

    Member
    818
    302
    Jul 28, 2008
    United States
  8. MaiconErick

    MaiconErick GBAtemp Regular

    Member
    102
    7
    Jan 4, 2016
    Brazil
    I got my TitleID value stored in a u64 titleID[1] in decimal.
    I need help on how to use it on this function:
    APT_PrepareToDoApplicationJump(0, 0x000XLL, 0),
    where X stands for the titleID value in hexadecimal.
    Spent some hours already trying to look up how to do this using C, so I decided to ask for help here.


    the titleID is 16 (decimal) numbers long.
    the X value I need, should be 13 (hex) numbers long.

    EDIT: Figured it out.
     
    Last edited by MaiconErick, Dec 24, 2017
  9. roytam1

    roytam1 Member

    Newcomer
    47
    3
    Dec 24, 2017
    Hong Kong
    Is it possible to change receive buffer size when using httpc service to download file?
     
  10. tgaiu

    tgaiu Member

    Newcomer
    33
    3
    Sep 10, 2017
    Japan
    I attempted to play the stream of ogg files, but the playback speed got a little faster.
    Please help me.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <tremor/ivorbiscodec.h>
    #include <tremor/ivorbisfile.h>
    #include <3ds.h>
    
    #define BUFF_SIZE 8 * 4096
    typedef struct {
        float rate;
        u32 channels;
        u32 encoding;
        u32 nsamples;
        u32 size;
        char* data1;
        char* data2;
        bool loop;
        int audiochannel;
        float mix[12];
        ndspInterpType interp;
        OggVorbis_File ovf;
    } Music;
    Music music;
    ndspWaveBuf waveBuf[2];
    
    uint64_t fillVorbisBuffer(OggVorbis_File ovf, char* buffer) {
        uint64_t samplesRead = 0;
        int samplesToRead = BUFF_SIZE;
    
        while (samplesToRead > 0) {
    
            static int current_section;
            int samplesJustRead =
                ov_read(&ovf,
                    buffer,
                    samplesToRead > 4096 ? 4096 : samplesToRead,
                    &current_section);
            if (samplesJustRead < 0)
                return samplesJustRead;
            else if (samplesJustRead == 0){
                break;
            }
            samplesRead += samplesJustRead;
            samplesToRead -= samplesJustRead;
            buffer += samplesJustRead;
        }
        return samplesRead / sizeof(int16_t);
    }
    
    
    int load() {
        memset(&music, 0, sizeof(music));
        music.mix[0] = 1.0f;
        music.mix[1] = 1.0f;
        FILE * file = fopen("example.ogg", "rb");
        if (file == 0) {
            printf("no file\n");
            while (1);
        }
        if (ov_open(file, &music.ovf, NULL, 0) < 0) {
            printf("ogg vorbis file error\n");
            while (1);
        }
        vorbis_info * vorbisInfo = ov_info(&music.ovf, -1);
        if (vorbisInfo == NULL) {
            printf("could not retrieve ogg audio stream information\n");
            while (1);
        }
        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.interp = NDSP_INTERP_NONE;
        music.loop = false;
        if (linearSpaceFree() < music.size) {
            printf("not enough linear memory available %ld\n", music.size);
        }
        music.data1 = (char *)linearAlloc(BUFF_SIZE * sizeof(int16_t));
        music.data2 = (char *)linearAlloc(BUFF_SIZE * sizeof(int16_t));
        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);
        //fclose(file);
        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));
        memset(&waveBuf, 0, sizeof(ndspWaveBuf));
        waveBuf[0].data_vaddr = &music.data1[0];
        waveBuf[0].nsamples = fillVorbisBuffer(music.ovf, &music.data1[0]) / music.channels;
        waveBuf[0].looping = music.loop;
        waveBuf[1].data_vaddr = &music.data2[0];
        waveBuf[1].nsamples = fillVorbisBuffer(music.ovf, &music.data1[0]) / music.channels;
        waveBuf[1].looping = music.loop;
        return 0;
    }
    
    int main(int argc, char **argv) {
        gfxInitDefault();
        consoleInit(GFX_TOP, 0);
        ndspInit();
        ndspSetOutputMode(NDSP_OUTPUT_STEREO);
        ndspSetOutputCount(1);
        load();
      
        ndspChnWaveBufAdd(0, &waveBuf[0]);
        ndspChnWaveBufAdd(0, &waveBuf[1]);
    
        while (aptMainLoop()) {
            hidScanInput();
            u32 keys = hidKeysDown();
            if (keys & KEY_START)
                break;
    
            if (waveBuf[0].status == NDSP_WBUF_DONE){
                size_t read = fillVorbisBuffer(music.ovf, &music.data1[0]);
    
                if (read <= 0){
                    continue;
                }
                else if (read < BUFF_SIZE)
                    waveBuf[0].nsamples = read / music.channels;
    
                ndspChnWaveBufAdd(music.audiochannel, &waveBuf[0]);
            }
    
            if (waveBuf[1].status == NDSP_WBUF_DONE){
                size_t read = fillVorbisBuffer(music.ovf, &music.data2[0]);
    
                if (read <= 0){
                    continue;
                }
                else if (read < BUFF_SIZE)
                    waveBuf[1].nsamples = read / music.channels;
    
                ndspChnWaveBufAdd(music.audiochannel, &waveBuf[1]);
            }
            DSP_FlushDataCache(music.data1, BUFF_SIZE * sizeof(int16_t));
            DSP_FlushDataCache(music.data2, BUFF_SIZE * sizeof(int16_t));
            //printf("%d:%d\n", waveBuf[0].status, waveBuf[1].status);
            gfxFlushBuffers();
            gfxSwapBuffers();
            gspWaitForVBlank();
        }
        ndspChnWaveBufClear(music.audiochannel);
        ndspExit();
        gfxExit();
        return 0;
    }
    
     
    Last edited by tgaiu, Jan 13, 2018 at 3:14 AM