QSoundEffect - setVolume setting whole app volume?



  • I'm using "QSoundEffect":http://qt-project.org/doc/qt-5/qsoundeffect.html to play some sound inside my app.
    I also have a video player integrated in my app.

    What happen is when I change the volume of the sound effect inside my app, it also change the volume of the video player. Not sure this is the normal behavior? Strange because i'm calling setVolume only on the QSoundEffect I need to change volume, not the whole Qt app. Any advice appreciated!

    Screenshot :
    https://www.dropbox.com/s/5bqo5a082a3rfzp/soundEffectVol.png?dl=0

    Here is some code :

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

    soundStartWorkout = new QSoundEffect(this);
    soundPauseWorkout = new QSoundEffect(this);
    soundEndWorkout = new QSoundEffect(this);
    soundAchievement = new QSoundEffect(this);
    soundFirstBeepInterval = new QSoundEffect(this);
    soundLastBeepInterval = new QSoundEffect(this);
    soundPowerTooLow = new QSoundEffect(this);
    soundPowerTooHigh = new QSoundEffect(this);
    soundCadenceTooLow = new QSoundEffect(this);
    soundCadenceTooHigh = new QSoundEffect(this);
    
    soundStartWorkout->setSource(QUrl::fromLocalFile(":/sound/resume"));
    soundPauseWorkout->setSource(QUrl::fromLocalFile(":/sound/resume"));
    soundEndWorkout->setSource(QUrl::fromLocalFile(":/sound/end_workout"));
    soundAchievement->setSource(QUrl::fromLocalFile(":/sound/fireTorch"));
    soundFirstBeepInterval->setSource(QUrl::fromLocalFile(":/sound/firstBeep"));
    soundLastBeepInterval->setSource(QUrl::fromLocalFile(":/sound/secondBeep"));
    soundPowerTooLow->setSource(QUrl::fromLocalFile(":/sound/powerTooLow"));
    soundPowerTooHigh->setSource(QUrl::fromLocalFile(":/sound/powerTooHigh"));
    soundCadenceTooLow->setSource(QUrl::fromLocalFile(":/sound/cadenceTooLow"));
    soundCadenceTooHigh->setSource(QUrl::fromLocalFile(":/sound/cadenceTooHigh"));
    

    }

    /////////////////////////////////////////////////////////////////
    void SoundPlayer::setVolume(double volume) {

    soundStartWorkout->setVolume(volume);
    soundPauseWorkout->setVolume(volume);
    soundEndWorkout->setVolume(volume);
    soundAchievement->setVolume(volume);
    soundFirstBeepInterval->setVolume(volume);
    soundLastBeepInterval->setVolume(volume);
    soundPowerTooLow->setVolume(volume);
    soundPowerTooHigh->setVolume(volume);
    soundCadenceTooLow->setVolume(volume);
    soundCadenceTooHigh->setVolume(volume);
    

    }@



  • Really strange, the last played QSoundEffect volume sets the sound volume for all the other QSoundEffect and the whole app at the same level.

    to "hack" this, I have tried this to check when a QSoundEffect is over playing, and play a "dummy" sound right after with the volume at maximal. So while the sound is played, all the other sounds have their level also changed..

    Also tried to put the soundPlayer object in a different thread, same problem

    @connect(soundFirstBeepInterval, SIGNAL(playingChanged()), this, SLOT(testSlot()));

    void SoundPlayer::testSlot() {

    if (!soundFirstBeepInterval->isPlaying()) {
        emit afterVolumeChanged();
        soundBidon->setSource(QUrl::fromLocalFile(":/sound/cadenceTooHigh"));
        soundBidon->setVolume(1.0f);
        soundBidon->play();  //dirty workaround, not good
    }
    

    }@

    So after trying QSound::play (no setVolume function) and QSoundEffect, I think i'm hitting a wall here.
    I want to have 2 separate volume, 1 for my sound effects, 1 for all the other audio in the app. QSoundEffect can't do that?



  • I can post a minimal example if this is not intended behavior and report a bug?

    pseudo code:

    • create 2 QSoundEffect
    • setVolume on first sound
    • setVolume on second sound
    • play first sound
    • the second sound effect will take the same volume as the first even if no setVolume was called on it.

    Tested on Windows 7 x64 - Qt 5.1.2 MSVC2012



  • Anyone know a good alternative to QSoundEffect to play simple .wav file with different sound level? QSound is not an option (can't set volume)

    Thanks, any suggestion welcome!


  • Lifetime Qt Champion

    Hi,

    From a quick look, I'd say all QSoundEffect uses the same audio output and thus setting the volume on one changes for all.

    What you could do is use something like the dspfilters library that would allow you to easily modify the volume (and also apply other audio filters) on you wav files

    Hope it helps



  • Thanks SGaist,

    I also took a look at "QAudioOuput":http://qt-project.org/doc/qt-5/qaudiooutput.html#details

    I'm thinking creating a QAudioOuput for all my sound effects, then would this QAudioOuput be the same output used for other sounds inside my app?

    All I need is two output, one for the sound effect, and another for general sounds. so I can control their volume independently



  • I'm almost there with QAudioOuput,
    Only problem, I can play the sound just once, the second call to .play on the same sound doesn't work.. investigating

    @SoundPlayer::SoundPlayer(QObject *parent) : QObject(parent)
    {
    sourceAchievement.setFileName(":/sound/fireTorch");
    sourceLastBeepInterval.setFileName(":/sound/secondBeep");

    sourceAchievement.open(QIODevice::ReadOnly);
    sourceLastBeepInterval.open(QIODevice::ReadOnly);
    
    /// All wav file got the same format
    QAudioFormat format;
    format.setSampleRate(44100);
    format.setChannelCount(2);
    format.setSampleSize(16);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::UnSignedInt);
    
    QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
    if (!info.isFormatSupported(format)) {
        qDebug() << "Raw audio format not supported by backend, cannot play audio.";
        return;
    }
    
    audio = new QAudioOutput(format, this);
    connect(audio, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State)));
    

    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void SoundPlayer::setVolume(double volume) {

    audio->setVolume(volume);
    

    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void SoundPlayer::playSound() {
    audio->stop();
    audio->start(&sourcePauseWorkout);
    }
    void SoundPlayer::playSoundEffectTest() {
    audio->stop();
    audio->start(&sourcePauseWorkout);
    }

    void SoundPlayer::playSoundAchievement() {
    audio->stop();
    audio->start(&sourceAchievement);
    }
    void SoundPlayer::playSoundLastBeepInterval() {
    audio->stop();
    audio->start(&sourceLastBeepInterval);
    }

    void SoundPlayer::handleStateChanged(QAudio::State newState)
    {
    switch (newState) {
    case QAudio::IdleState:
    qDebug() << "finished playing";
    // Finished playing (no more data)
    audio->stop();
    // sourceFile.close();
    // delete audio;
    break;

    case QAudio::StoppedState:
        // Stopped for other reasons
        qDebug() << "stopped playing";
        if (audio->error() != QAudio::NoError) {
            // Error handling
            qDebug() << "AUDIO ERROR HERE";
        }
        break;
    case QAudio::ActiveState:
        qDebug() << "active State";
        break;
    
    default:
        qDebug() << "other cases as appropriate";
        break;
    }
    

    }
    @



  • Bah.. the sound level is still shared with the VideoPlayer.. sigh

    Created a thread on vlc-qt, will see
    https://github.com/ntadej/vlc-qt/issues/56

    Trying this :
    http://sfml-dev.org/



  • Fixed by using SFML
    Really powerful tool, I recommend it strongly

    http://sfml-dev.org/


  • Lifetime Qt Champion

    Looks nice !

    Thanks for sharing :)


Log in to reply
 

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