Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved QSoundEffect - setVolume setting whole app volume?

    General and Desktop
    2
    10
    6007
    Loading More Posts
    • 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.
    • M
      maximus last edited by A Former User

      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);
      

      }@


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

      1 Reply Last reply Reply Quote 0
      • M
        maximus last edited by

        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?


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

        1 Reply Last reply Reply Quote 0
        • M
          maximus last edited by

          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


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

          1 Reply Last reply Reply Quote 0
          • M
            maximus last edited by

            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!


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

            1 Reply Last reply Reply Quote 0
            • SGaist
              SGaist Lifetime Qt Champion last edited by

              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

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply Reply Quote 0
              • M
                maximus last edited by

                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


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

                1 Reply Last reply Reply Quote 0
                • M
                  maximus last edited by

                  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;
                  }
                  

                  }
                  @


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

                  1 Reply Last reply Reply Quote 0
                  • M
                    maximus last edited by

                    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/


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

                    1 Reply Last reply Reply Quote 0
                    • M
                      maximus last edited by

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

                      http://sfml-dev.org/


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

                      1 Reply Last reply Reply Quote 0
                      • SGaist
                        SGaist Lifetime Qt Champion last edited by

                        Looks nice !

                        Thanks for sharing :)

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post