Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [SOLVED] Qt Resources - Loading a sound from a ressource  (Read 16483 times)

0 Members and 1 Guest are viewing this topic.

MaximumTrainer

  • Newbie
  • *
  • Posts: 16
    • View Profile
    • MaximumTrainer
    • Email
[SOLVED] Qt Resources - Loading a sound from a ressource
« on: October 16, 2014, 06:22:52 pm »
Hi guys,

First thanks SFML, I just tried it for the first time and it works so easily!

In my Qt project, all my sounds are mapped to resources,
I would like to play the sound from the resource instead of from the hard drive.

I can play the sound fine when I load from the disk, however, is there a way to use the ressource syntax to load a sound?

Thanks in advance!

    if (!buffer.loadFromFile(":/sound/resume")) {
        qDebug() << "cant play";
        return 0;
    }
//    if (!buffer.loadFromFile("C:\\Dropbox\\PowerVelo2\\sound\\CadenceTooHigh.wav")) {
//        qDebug() << "cant play";
//        return 0;
//    }
    sf::Sound sound(buffer);
    sound.play();

I suspect I may have to use "loadFromMemory" as the file should be in memory (it is inside the .exe)
« Last Edit: November 05, 2014, 07:04:24 pm by MaximumTrainer »
Free Indoor Cycling Software - https://maximumtrainer.com

MaximumTrainer

  • Newbie
  • *
  • Posts: 16
    • View Profile
    • MaximumTrainer
    • Email
Re: Qt Resources - Loading a sound from a ressource
« Reply #1 on: October 16, 2014, 06:35:01 pm »
Got it! not sure it's the cleanest way though..


    QResource mySound(":/sound/resume");


    if (!buffer.loadFromMemory(mySound.data(), mySound.size())) {
        qDebug() << "cant play";
        return 0;
    }
    sf::Sound sound(buffer);
    sound.play();
Free Indoor Cycling Software - https://maximumtrainer.com

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SOLVED] Qt Resources - Loading a sound from a ressource
« Reply #2 on: October 16, 2014, 08:04:31 pm »
Quote
not sure it's the cleanest way though..
I think it is ;)
Laurent Gomila - SFML developer

MaximumTrainer

  • Newbie
  • *
  • Posts: 16
    • View Profile
    • MaximumTrainer
    • Email
Re: [SOLVED] Qt Resources - Loading a sound from a ressource
« Reply #3 on: October 17, 2014, 07:58:07 pm »
I think i'm not freeing the ressource properly after using SFML
I get this error : The program has unexpectedly finished.
If I comment the use of my SoundPlayer, no error -_-

int main(int argc, char *argv[]) {

    SoundPlayer *soundPlayer = new SoundPlayer();
    app.setProperty("SoundPlayer", QVariant::fromValue<SoundPlayer*>(soundPlayer));
    //do stuff with the player

       /// App terminated, Trying to force resource delete so I don't get the error..
    soundPlayer->~SoundPlayer();
}

//------------------------------------- soundPlayer.cpp
#include "soundplayer.h"
#include <QDebug>


SoundPlayer::~SoundPlayer() {


    qDebug() << "DESTRUCTOR SOUNDPLAYER";
    freeMemory();

}

void SoundPlayer::freeMemory() {

    qDebug() << "freeing memory";

    soundAchievement.resetBuffer();
    soundAchievement.~Sound();

    //    bufferSoundAchievement.~SoundBuffer();

    qDebug() << "end freeing memory";
}

SoundPlayer::SoundPlayer(QObject *parent) : QObject(parent)
{

    QResource qrcAchievement(":/sound/fireTorch");
    bufferSoundAchievement.loadFromMemory(qrcAchievement.data(), qrcAchievement.size());
    soundAchievement =  sf::Sound(bufferSoundAchievement);
}


void SoundPlayer::setVolume(double volume) {

    qDebug() << "setVolume soundPlayer";
    soundAchievement.setVolume(volume);
}

void SoundPlayer::playSoundAchievement() {
    soundAchievement.play();
}
...

 
Free Indoor Cycling Software - https://maximumtrainer.com

MaximumTrainer

  • Newbie
  • *
  • Posts: 16
    • View Profile
    • MaximumTrainer
    • Email
After further debugging, I found that as soon as I create a class with a "sf::SoundBuffer" private member, I get this error.

e.g:
class SoundPlayer
{

public:
    explicit SoundPlayer();

private :
    sf::SoundBuffer bufferSoundAchievement;

};
Q_DECLARE_METATYPE(SoundPlayer*)

#endif // SOUNDPLAYER_H

As soon as I create a pointer to this class, my program crashes, if I comment the sf::SoundBuffer, it doesn't crash. still investigating
« Last Edit: October 17, 2014, 10:04:21 pm by MaximumTrainer »
Free Indoor Cycling Software - https://maximumtrainer.com

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Please provide a complete and minimal example that reproduces the problem.

And:
soundAchievement.~Sound();
Never ever call a destructor yourself. The compiler does it automatically when the object is destroyed.
Laurent Gomila - SFML developer

MaximumTrainer

  • Newbie
  • *
  • Posts: 16
    • View Profile
    • MaximumTrainer
    • Email
Minimal example :


int main(int argc, char *argv[]) {
 SoundPlayer *soundPlayer = new SoundPlayer();
}

// SoundPlayer.h
#ifndef SOUNDPLAYER_H
#define SOUNDPLAYER_H

#include <QResource>
#include <QtCore>

#include "SFML/Audio.hpp"
#include <iomanip>
#include <iostream>


class SoundPlayer
{

public:
    SoundPlayer();
private :
    sf::SoundBuffer bufferSoundAchievement;
};
Q_DECLARE_METATYPE(SoundPlayer*)

#endif // SOUNDPLAYER_H


// SoundPlayer.cpp
SoundPlayer::SoundPlayer()
{}


log :
Starting C:\Dropbox\build-PowerVelo2-Desktop_Qt_5_2_1_MSVC2012_32bit-Release\release\MaximumTrainer.exe...
The program has unexpectedly finished.
C:\Dropbox\build-PowerVelo2-Desktop_Qt_5_2_1_MSVC2012_32bit-Release\release\MaximumTrainer.exe crashed

Note :
I can use the soundPlayer just fine to play sounds, setVolume, etc.  The crash happen only when the application is closing.
Merci beaucoup!

In case you need, my Qt project file:
QT       += core gui widgets webkit webkitwidgets
QT       -= sql

TARGET = MaximumTrainer
TEMPLATE = app


CONFIG += qwt qt thread
RC_FILE = myapp.rc

DEFINES += NOMINMAX

#SFML
INCLUDEPATH += C:/Dropbox/SFML-master/include
LIBS +=  C:/Dropbox/SFML-2.1-win-vc11-32bits/lib/sfml-audio.lib


debug :
https://www.dropbox.com/s/7xjnjgk7hqvt465/debugSound.png?dl=0
Is it possible that my app close and the buffer is still open?
« Last Edit: October 18, 2014, 12:06:25 am by MaximumTrainer »
Free Indoor Cycling Software - https://maximumtrainer.com

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Do you think dynamically allocated memory magically frees itself?
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

MaximumTrainer

  • Newbie
  • *
  • Posts: 16
    • View Profile
    • MaximumTrainer
    • Email
Do you think dynamically allocated memory magically frees itself?

Well I'm not using "new" on the buffer and it is a member of the "SoundPlayer" object, so the buffer should get deleted when my SoundPlayer object is deleted.

Not sure what happen when the program is over, I supposed all the pointer and data used is deleted by default, could be wrong, worked too much with Java -_-
Free Indoor Cycling Software - https://maximumtrainer.com

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
so the buffer should get deleted when my SoundPlayer object is deleted.

Again, I repeat my question - do you think dynamically allocated memory magically frees itself?

Quote
I supposed all the pointer and data used is deleted by default

Go learn C++ before using SFML, just because you may know something in Java doesn't give you any credit in C++. Sorry if this sounds rude, but its just the way things are. Assuming that just because Java objects created with the 'new' keyword will be automatically deleted is a very bad way to go about programming (its because Java includes a built in GC). As said in many threads before, go RTFM - meaning a good C++ book.
« Last Edit: October 18, 2014, 02:20:53 am by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
You must link to debug libraries in debug mode. Mixing debug and release with Visual C++ leads to undefined behaviours.
Laurent Gomila - SFML developer

MaximumTrainer

  • Newbie
  • *
  • Posts: 16
    • View Profile
    • MaximumTrainer
    • Email
Thanks for your kind help Laurent.

Yes I am new with C++ (1 year). I didn't delete the SoundPlayer because it is created in the main and lives for as long as my program lives.  I know C++ doesn't have a GC like Java.

Anyway, I don't think the problem is memory. I created a small test program below where everything is created on the stack.

int main() {

    sf::SoundBuffer buffer;
    if (!buffer.loadFromFile("C:/Dropbox/PowerVelo2/sound/resume.wav"))
        return 1;

    // Display sound informations
    std::cout << "canary.wav :" << std::endl;
    std::cout << " " << buffer.getSampleRate()           << " samples / sec" << std::endl;
    std::cout << " " << buffer.getChannelCount()         << " channels"      << std::endl;

    // Create a sound instance and play it
    sf::Sound sound(buffer);
    sound.play();

    // Loop while the sound is playing
    while (sound.getStatus() == sf::Sound::Playing)
    {
        QThread::msleep(200);
        qDebug() << "looping...waiting for sound to be over";
    }

    qDebug() << "done";

    return EXIT_SUCCESS;
}
 

log :
Starting C:\Dropbox\build-PowerVelo2-Desktop_Qt_5_2_1_MSVC2012_32bit-Release\release\MaximumTrainer.exe...
canary.wav :
 44100 samples / sec
 2 channels
looping...waiting for sound to be over
looping...waiting for sound to be over
looping...waiting for sound to be over
looping...waiting for sound to be over
looping...waiting for sound to be over
done
The program has unexpectedly finished.
C:\Dropbox\build-PowerVelo2-Desktop_Qt_5_2_1_MSVC2012_32bit-Release\release\MaximumTrainer.exe crashed
Free Indoor Cycling Software - https://maximumtrainer.com

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
No, the problem is not caused by the memory leak, but this is something that you definitely have to consider.

Can you show your new project file now that you've fixed the debug libraries error?
Laurent Gomila - SFML developer

MaximumTrainer

  • Newbie
  • *
  • Posts: 16
    • View Profile
    • MaximumTrainer
    • Email
Yes will definitely delete the object before the main program closes, I heard it's bad practice to let the OS do the job :)

Finally I was able to run the project in debug mode

Here is the debug message I get :
https://www.dropbox.com/s/5l62b7ol0hod81u/debugModeSFML.png?dl=0
I put a breakpoint and see that the error is triggered right after my main is over (after the return)

Here is the minimal example :
#Pro File
TARGET = testSound

SOURCES += main.cpp

#SFML
INCLUDEPATH += C:/Dropbox/SFML-2.1-windows-vc11-32bits/include
LIBS +=  C:/Dropbox/SFML-2.1-windows-vc11-32bits/lib/sfml-audio-d.lib


main.cpp
#include <QDebug>
#include <QThread>

#include <SFML/Audio.hpp>


int main() {

    qDebug() << "start main";

    sf::SoundBuffer buffer;
    if (!buffer.loadFromFile("C:/Dropbox/PowerVelo2/sound/resume.wav")) {
        qDebug() << "error open file";
        return 1;
    }
    else {
        qDebug() << "good";
    }


    // Create a sound instance and play it
    sf::Sound sound(buffer);
    sound.play();

    // Loop while the sound is playing
    while (sound.getStatus() == sf::Sound::Playing)
    {
        QThread::msleep(200);
        qDebug() << "looping...waiting for sound to be over" << sound.getStatus();
    }

    qDebug() << "done";

    return EXIT_SUCCESS;
}

Free Indoor Cycling Software - https://maximumtrainer.com

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Might be this bug: https://github.com/SFML/SFML/issues/30

A fix is pending, you'll find the corresponding branch at the end of the discussion.
Laurent Gomila - SFML developer