[SOLVED]FMOD does not play a sound from qresource?



  • Hello,
    I am making a sound player in FMOD with Qt. The code is simple:
    @
    bool FMPlayer::systemInit(const char *fname) {

    FMOD::Channel* channel;
    FMOD::System* system;
    FMOD::Sound* sound;
    FMOD::System_Create(&system);
    system->init(32, FMOD_INIT_NORMAL, 0);
    system->createSound(fname,
                       0, 0, &sound);
    sound->setMode(FMOD_LOOP_OFF);
    system->playSound(sound, false, 0, &channel);
    

    }
    @
    If I pass my hard drive full path as a parameter the sound is played. But if I use
    @
    FMPlayer::
    systemInit(":/resources/sounds/blop.wav");
    @
    It plays nothing. Why is that?


  • Moderators

    @":/resources/sounds/blop.wav"@

    This path format is a Qt mechanism. FMOD knows nothing about it and doesn't understand Qt embedded resources.

    What you can do is use a QFile to readAll() the sound into a QByteArray.
    createSound() takes a mode parameter. Pass FMOD_OPENMEMORY_POINT there and use the data() pointer of the array as the first argument to createSound(), as described in the "FMOD docs":http://www.fmod.org/documentation/#content/generated/FMOD_System_CreateSound.html
    If you don't want to keep the array around then use FMOD_OPENMEMORY instead of FMOD_OPENMEMORY_POINT and FMOD will copy the data and take care of it.

    Btw. You should really check return codes of FMOD functions. Each call can fail and if you don't check which is it then debugging such code is pretty much pure guesswork.



  • Thank you. Before you replied I got the idea of output to byte array. I want to ask something else- can I redirect the resources I have ( png, wav, xml ) to different thing than the exe of my program?


  • Moderators

    Redirect? What do you mean?



  • Well, when I use qt resource system, the files, pictures, music and so go into the executable binary. So I was wondering if I can move them to archive like structure and read from there.


  • Moderators

    -Well sure, but this has nothing to do with Qt resource system. It is only for embedding resources in executables or libraries.-

    EDIT: I forgot that Qt also allows you to create "external resource packages":https://qt-project.org/doc/qt-5-snapshot/resources.html#external-binary-resources

    You would have to provide some mechanism for extracting them from such archive, but that is out of Qt scope (apart maybe from using QFile to access such file). If I rememer correctly FMOD can also stream data from external files and you can give it an offset into the file and size. Should be easy enough to "glue" together files and provide some index-like structure for it.

    FMOD also provides a higher level API - FMOD Studio, which packages sounds into single file banks and manages compression, extraction etc. Maybe you could switch to that? It's quite pleasant to work with in my experience.



  • [quote author="Chris Kawa" date="1418912871"]-
    EDIT: I forgot that Qt also allows you to create "external resource packages":https://qt-project.org/doc/qt-5-snapshot/resources.html#external-binary-resources
    [/quote]
    Thanks for this.
    Another one. I need a bit of help here. This is test for sound. However the FMPlayer::systemInit() fails me.
    @
    QFile io(":/resources/sounds/blop.wav");

    if ( !io.open(QFile::ReadOnly)) {
        qDebug() << "Error loading file";
    } {
        QByteArray qba;
        qba = io.readAll();
       const char *begin = qba.constData(); 
       if ( FMPlayer::
             systemInit(begin) ) {
            qDebug() << "Played sound";
        } else {
            qDebug() << "FMOD failed";
        }
    } /* END FMOD TEST */
    

    @
    And here is my FMPlayer::systemInit(...):
    @
    bool FMPlayer::systemInit(const char *fname) {

    FMOD::Channel* channel;
    FMOD::System* system;
    FMOD::Sound* sound;
    FMOD::System_Create(&system);
    system->init(32, FMOD_INIT_NORMAL, 0);
    if ( FMOD_OK == system->createSound(fname,
                       FMOD_OPENMEMORY, 0, &sound) ) {
        sound->setMode(FMOD_LOOP_OFF);
        system->playSound(sound, false, 0, &channel);
        return true;
    } else {
        return false;
    }
    

    }
    @
    I am sure I am making some mistake, but cant figure it out... Id really appreciate the help.


  • Moderators

    As I said: "read the docs":http://www.fmod.org/documentation/#content/generated/FMOD_System_CreateSound.html ;)

    I'll quote the relevant part:

    bq. Note that FMOD_OPENRAW, FMOD_OPENMEMORY, FMOD_OPENMEMORY_POINT and FMOD_OPENUSER will not work here without the exinfo structure present, as more information is needed.

    When you use a FMOD_OPENMEMORY flag you also need to pass a pointer to FMOD_CREATESOUNDEXINFO structure with a single field filled in: the length of the data.



  • [quote author="Chris Kawa" date="1418916536"]As I said: "read the docs":http://www.fmod.org/documentation/#content/generated/FMOD_System_CreateSound.html ;)

    I'll quote the relevant part:

    bq. Note that FMOD_OPENRAW, FMOD_OPENMEMORY, FMOD_OPENMEMORY_POINT and FMOD_OPENUSER will not work here without the exinfo structure present, as more information is needed.

    When you use a FMOD_OPENMEMORY flag you also need to pass a pointer to FMOD_CREATESOUNDEXINFO structure with a single field filled in: the length of the data.[/quote]

    You were in a word "saviour". I learned about FMOD yesterday so I had almost no time to track all the stuff. Now I get it - the FMOD_SOUNDEXINFO must be some header for info... It makes sense. The file can be from ogg to wav. Thanks. The problem is [SOLVED].
    P.S. I had to rewrote my function to recieve QByteArray::size() for this...


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.