[Q] Crashing issue with CSND in my program

Discussion in '3DS - Homebrew Development and Emulators' started by LeifEricson, Aug 22, 2015.

  1. LeifEricson
    OP

    LeifEricson Coming Soon™

    Member
    214
    166
    Jun 22, 2012
    United States
    New York, USA
    So I've been working on a implementation of Fibbage by Jackbox Games on the 3DS. For the uninitiated it's a party game where you bluff to fill in the blanks of a weird fact and try to fool other players into believing your lie.

    Anyway, progress is coming along slowly but surely, but I've hit a major snag. No matter how many times I try, I cannot for the life of me get CSND_playsound to work properly.

    For reference, I'm using an old version of libctru with the old CSND calls, only because when the new one didn't work I decided maybe implementing the older version would work. NOPE! As of current, it works perfectly fine on Citra, but when I go to load it via Tubehax, this is what happens:

    [​IMG]

    In a normal boot my game shows some random sprites with a messed up palette, wrong coordinates, etc. for a split second and then draws the title screen:

    [​IMG]


    I guess it's just the way the game loads the assets. Anyways, my app gets frozen at the first image when a CSND_playsound call is in my code, and plays fine when there isn't.

    For reference,here's my main.c, since that's the only place currently that I'm attempting to test the sound:

    Code:
    /*
    This file is a part of FIBBAGE 3DS, by LeifEricson.
    Some assets are taken from the official FIBBAGE and FIBBAGE XL games, all credit
    to those original assets belong to JACKBOX GAMES.
    
    All assets are used under the understanding that this game is to not be sold for
    any monetary value, and that I do not claim any of the borrowed content as my own.
    
    Please do not re-distribute without credit.
    
    #------------------------------------------------------------------------------#
    This is the main file, which sets up default variable values and controls the
    overhead app loop and function calls.
    #------------------------------------------------------------------------------#
    */
    
    #include <3ds.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <malloc.h>
    #include <time.h>
    #include "main.h"
    #include "app.h"
    #include "draw.h"
    #include "input.h"
    #include "rendering.h"
    #include "gui.h"
    #include "core.h"
    #include "audio.h"
    
    //FPS Counter
    bool GW_MODE;
    extern int gamestate = 0;
    extern int substate = 0;
    
    player players[7];
    int categories[4];
    int numPlayers;
    int chosenPlayer;
    int chosenFact;
    
    int main()
    {
        int audio_initialized = 0;
        // Randomize seed
        srand(osGetTime());
     
        // Initialize services
        srvInit();
        aptInit();
        hidInit(NULL);
        gfxInitDefault();
        CSND_initialize(NULL);
     
        //Nullify player array to set defaults
        int i; for (i = 0; i < 8; ++i) {
            strcpy(players[i].name, "null");
            strcpy(players[i].lie, "null");
            players[i].score = 0;
            players[i].catIndex = -1;
            players[i].choiceIndex = -1;
        }
        numPlayers = 0;
     
        // Default variables
        categories[0] = -1; // Current category index bank
        chosenPlayer = -1; // Current chosen player (to pick category)
        chosenFact = -1; // Current fact chosen by player
    
        // Load test audio file (RAW PCM16 @32000)
        u8* sndbuffer;
        bool playing = false;
        FILE *file = fopen("test.bin", "rb");
        fseek(file, 0, SEEK_END);
        off_t sndsize = ftell(file);
        sndbuffer = linearAlloc(sndsize);
        fseek(file, 0, SEEK_SET);
        off_t bytesRead = fread(sndbuffer, 1, sndsize, file);
        fclose(file);
     
        // Main loop
        while (aptMainLoop())
        {
            getFB();
    
            //Gets input (keys and touch)
            getInput();
    
            //Prints the GUI
            printGUI();
    
            // Main app handler
            app(players);
    
            // Exit code
            if (input & KEY_START) break;
         
            // Flush and swap framebuffers
            gfxFlushBuffers();
            gfxSwapBuffers();
    
            //Wait for VBlank
            gspWaitForVBlank();
         
            // Audio test
            CSND_playsound(8, CSND_LOOP_ENABLE, CSND_ENCODING_PCM16, 32000, sndbuffer, NULL, (u32)sndsize, 0xFFFF, 0xFFFF);
        }
    
        // Exit services
        gfxExit();
        hidExit();
        aptExit();
        srvExit();
    
        CSND_shutdown();
        linearFree(sndbuffer);
        return 0;
    }
    If someone could help me out, I'd really appreciate it.
     
  2. LeifEricson
    OP

    LeifEricson Coming Soon™

    Member
    214
    166
    Jun 22, 2012
    United States
    New York, USA
    Bump.
     
  3. The_Meistro

    The_Meistro GBATemp's "Official" Hank Hill

    Banned
    633
    336
    Aug 22, 2015
    The Magic School Bus
    Will this be a .3dsx?
     
  4. machinamentum

    machinamentum GBAtemp Regular

    Member
    163
    450
    Jul 5, 2015
    United States
    You should update your ctrulib and use the new enums that automatically set the sound bitfields correctly.
    Code:
    GSPGPU_FlushDataCache(NULL, (u8*)audiobuf, audiobuf_size);
    csndPlaySound(SOUND_CHANNEL(8), SOUND_REPEAT | SOUND_LINEAR_INTERP | SOUND_FORMAT_16BIT, SampleRate * 2, 1.0, 0.0, (u32*)audiobuf, (u32*)audiobuf, audiobuf_size);
    
    The above should play a PCM16 interleaved buffer just fine (taken directly from my music playing app).
     
  5. LeifEricson
    OP

    LeifEricson Coming Soon™

    Member
    214
    166
    Jun 22, 2012
    United States
    New York, USA
    Yes. I'm running 9.9 ironhax, so I'd only make a .cia for final release.

    So would you say that not flushing the buffer (the first command) would be my issue, or the parameters of the csnd call (second command)? Also, am I supposed to call csndPlaySound once, or am I supposed to call it each frame? Just to make sure since I've been pulling my hair out trying to get sound implemented correctly.
     
  6. machinamentum

    machinamentum GBAtemp Regular

    Member
    163
    450
    Jul 5, 2015
    United States
    Most examples I've seen flush the buffer. I can't recall if I've tested to see if it works without flushing in the past. You need only call it once if you have it set to looping/repeat then after that you can just write directly to the buffer to update it (though I don't think there's a way to track the play cursor).
     
  7. LeifEricson
    OP

    LeifEricson Coming Soon™

    Member
    214
    166
    Jun 22, 2012
    United States
    New York, USA
    Thank you so much!! It works now. Can you play on other channels than 8, to for example play sound effects while music is playing?

    EDIT: Also, whenever I write a new sound to the buffer after it's already been playing, it plays the new sound from the middle (I'm guessing from the point in the buffer it was at when playing the previous sound). Is there a way to restart playback?
     
    Last edited by LeifEricson, Aug 24, 2015