QSoundEffect - setVolume setting whole app volume?
-
wrote on 13 Oct 2014, 22:57 last edited by A Former User 7 Jan 2016, 16:53
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=0Here 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);
}@
-
wrote on 14 Oct 2014, 02:50 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? -
wrote on 15 Oct 2014, 01:40 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
-
wrote on 15 Oct 2014, 19:06 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!
-
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
-
wrote on 16 Oct 2014, 12:11 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
-
wrote on 16 Oct 2014, 14:03 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; }
}
@ -
wrote on 16 Oct 2014, 14:22 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/56Trying this :
http://sfml-dev.org/ -
wrote on 16 Oct 2014, 17:17 last edited by
Fixed by using SFML
Really powerful tool, I recommend it strongly -
Looks nice !
Thanks for sharing :)
3/10