Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to use QSoundEffect (desparate to get simple code to work)



  • Hiya!

    I am having a devil of a time to get a simple sound to play! First, I've read all the docs I can read and now I'm barfing up text. I have even compiled and run the sample application "Maroon in Trouble". Maroon works fine, it plays sound. I thought maybe it was my wav file giving a problem, so I confiscated wav file from Maroon and I still can't get it to work. This project was created using the new project wizard for a Qt Widgets Application.

    OS: Windows 10, using ming32 compiler, Qt 5.13.0. BTW, I get same result with Qt 5.12.x, I upgraded to 5.13.0 thinking hoping it would help, the upgrade was a "Full uninstall, full install of new version". Here is my very simple QWidget app that won't play sound for nothing. Please, any advice here, how do I even troubleshoot this? Excluding the generated main.cpp. Also, the sound file is put into a resource file and it is directly taken from Maroon sample app.

    Project file .pro

    QT       += core gui multimedia
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = SoundTest
    TEMPLATE = app
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which has been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    CONFIG += c++11
    
    SOURCES += \
            main.cpp \
            mainwindow.cpp
    
    HEADERS += \
            mainwindow.h
    
    FORMS += \
            mainwindow.ui
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    RESOURCES += \
        sounds.qrc
    

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QSoundEffect>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    public slots:
        void playSound();
    
    private:
        Ui::MainWindow *ui;
    
    
    };
    
    #endif // MAINWINDOW_H
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        connect(ui->actionMakeSomeNoise, &QAction::triggered, this, &MainWindow::playSound);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::playSound()
    {
        QSoundEffect effect;
        effect.setSource(QUrl("://projectile-action.wav"));
        effect.setLoopCount(10);
        effect.setMuted(false);
        effect.setVolume(1.0);
        effect.play();
    }
    
    

  • Moderators

    @Snorkelbuckle said in How to use QSoundEffect (desparate to get simple code to work):

    QSoundEffect effect;
    
    • Fact #1: QSoundEffect::play() is asynchronous. This means the function returns before the sound finishes playing.
    • Fact #2: You created your QSoundEffect object as a local variable. This means the object gets destroyed when MainWindow::playSound() returns.
    • Result: Your QSoundEffect object gets destroyed before it has the chance to play the sound.

    The fix? Make sure your QSoundEffect does not get destroyed too early. Make it a member variable of MainWindow, not a local variable of playSound().



  • Thanks for that, but now this still doesn't work. But the commented section does. When I check the status, it goes from 3 to 0.

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    
    {
        ui->setupUi(this);
        efx = new QSoundEffect(this);
        efx->setSource(QUrl(":/projectile-action.wav"));
        efx->setVolume(0.90);
        efx->setLoopCount(2);
        connect(ui->actionMakeSomeNoise, &QAction::triggered, this, &MainWindow::playSound);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::playSound()
    {
        // THIS works when uncommented
        //QSound *efx2 = new QSound(":/projectile-action.wav");
        //efx2->setLoops(2);
        //efx2->play();
    
        ui->statusBar->showMessage(QString("efx status: %1").arg(efx->status()));
        efx->play();
    }
    


  • Any other ideas, anybody? So far it is looking like a bug to me, can anybody post some code that actually works on Windows 10 for a QWidget app? Or is the updated code I posted technically correct?


  • Lifetime Qt Champion

    Hi
    Your code works fine for me? ( win 10, Qt 5.12.3
    Only change i did was to use fromLocalFile

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        efx = new QSoundEffect(this);
        efx->setSource(QUrl::fromLocalFile(":/1.wav"));
        efx->setVolume(0.90);
        efx->setLoopCount(2);
    }
    
    void MainWindow::on_pushButton_released()
    {
        efx->play();
        ui->statusBar->showMessage(QString("efx status: %1").arg(efx->status()));
    }
    
    

    test project
    https://www.dropbox.com/s/r7h92vtm6mrk6aa/SoundTest.zip?dl=0



  • Thank you, mrjj!

    Works now! It was just that I needed the QUrl::fromLocalFile().


  • Moderators

    @Snorkelbuckle said in How to use QSoundEffect (desparate to get simple code to work):

    It was just that I needed the QUrl::fromLocalFile().

    Or don't use QUrl (which you found when you wrote efx2)


Log in to reply