Homebrew [Q] Crashing issue with CSND in my program

LeifEricson

Coming Soon™
OP
Member
Joined
Jun 22, 2012
Messages
234
Trophies
0
Age
27
Location
New York, USA
Website
www.youtube.com
XP
534
Country
United States
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:

5M7cbIv.jpg


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:

3or48f7.png



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.
 

machinamentum

Well-Known Member
Member
Joined
Jul 5, 2015
Messages
163
Trophies
0
XP
549
Country
United States
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.
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).
 

LeifEricson

Coming Soon™
OP
Member
Joined
Jun 22, 2012
Messages
234
Trophies
0
Age
27
Location
New York, USA
Website
www.youtube.com
XP
534
Country
United States
Will this be a .3dsx?
Yes. I'm running 9.9 ironhax, so I'd only make a .cia for final release.

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).

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.
 

machinamentum

Well-Known Member
Member
Joined
Jul 5, 2015
Messages
163
Trophies
0
XP
549
Country
United States
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.
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).
 

LeifEricson

Coming Soon™
OP
Member
Joined
Jun 22, 2012
Messages
234
Trophies
0
Age
27
Location
New York, USA
Website
www.youtube.com
XP
534
Country
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).

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,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Xdqwerty @ Xdqwerty: *yawn*