Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED]FMOD does not play a sound from qresource?
Forum Updated to NodeBB v4.3 + New Features

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

Scheduled Pinned Locked Moved General and Desktop
10 Posts 3 Posters 3.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    heatblazer
    wrote on 17 Dec 2014, 17:24 last edited by Chris Kawa 6 Jul 2022, 08:26
    #1

    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?

    1 Reply Last reply
    1
    • C Offline
      C Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on 17 Dec 2014, 19:59 last edited by Chris Kawa 6 Jul 2022, 08:29
      #2

      ":/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
      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.

      1 Reply Last reply
      1
      • H Offline
        H Offline
        heatblazer
        wrote on 18 Dec 2014, 07:05 last edited by
        #3

        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?

        1 Reply Last reply
        0
        • C Offline
          C Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on 18 Dec 2014, 10:07 last edited by
          #4

          Redirect? What do you mean?

          1 Reply Last reply
          0
          • H Offline
            H Offline
            heatblazer
            wrote on 18 Dec 2014, 14:17 last edited by
            #5

            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.

            1 Reply Last reply
            0
            • C Offline
              C Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on 18 Dec 2014, 14:27 last edited by
              #6

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

              1 Reply Last reply
              0
              • H Offline
                H Offline
                heatblazer
                wrote on 18 Dec 2014, 14:45 last edited by Chris Kawa 6 Jul 2022, 08:28
                #7

                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

                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 can't figure it out... I'd really appreciate the help.

                1 Reply Last reply
                0
                • C Offline
                  C Offline
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on 18 Dec 2014, 15:28 last edited by Chris Kawa 6 Jul 2022, 08:31
                  #8

                  As I said: read the docs ;)

                  I'll quote the relevant part:

                  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.

                  1 Reply Last reply
                  0
                  • H Offline
                    H Offline
                    heatblazer
                    wrote on 18 Dec 2014, 16:11 last edited by Chris Kawa 6 Jul 2022, 08:32
                    #9

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

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

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      luke murray
                      wrote on 6 Mar 2018, 21:36 last edited by Chris Kawa 6 Jul 2022, 08:27
                      #10

                      For anyone else stuck here. I give you the gift of working code.

                      m_system is a pointer to the FMOD system
                      m_sound is a pointer to the FMOD sound

                      void Sound::createSoundFromResource(std::string filePath)
                      {
                          // get the file based on the path
                          QFile resourceFile(QString::fromStdString(filePath));
                          Q_ASSERT_X(resourceFile.exists(), "createSoundFromResource", "the filepath does not exist");
                          
                          // open the file and read all the data from it
                          if (resourceFile.open(QIODevice::ReadOnly)) {
                              auto data = resourceFile.readAll();
                              
                              // set metadata about the file so FMOD can read it
                              FMOD_CREATESOUNDEXINFO* exinfo = new FMOD_CREATESOUNDEXINFO();
                              exinfo->length = static_cast<unsigned int>(data.length());
                              exinfo->cbsize = sizeof(FMOD_CREATESOUNDEXINFO); // the unmentioned line which was killing me
                              auto result = FMOD_System_CreateSound(m_system, data.data(), FMOD_OPENMEMORY, exinfo, &m_sound);
                              SoundWrapper::CheckError(result);
                          } else {
                              Q_ASSERT_X(false, "createSoundFromResource", "opening the files failed");
                          }
                      }
                      
                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved