QT5.5 QЗвук закончен

Я занят созданием алгоритма реверберации. Во время работы с QSound я обнаружил несколько проблем.

Во-первых, звук не воспроизводится при попытке QSound::play() вот так:

/// Play output .wav file.
QSound sound("C:/Users/mvdelft/Documents/Reverb_configurator/output.wav", this);
sound.play();

Он воспроизводит звук только в том случае, если я снова укажу путь с файлом QSound::play (QString) следующим образом:

/// Play output .wav file.
QSound sound("C:/Users/mvdelft/Documents/Reverb_configurator/output.wav", this);
sound.play("C:/Users/mvdelft/Documents/Reverb_configurator/output.wav");

Связанная с этим проблема связана с функцией bool QSound::isFinshed(), которая у меня не работает. Код:

 /// Play output .wav file.
QSound sound("C:/Users/mvdelft/Documents/Reverb_configurator/output.wav", this);
sound.play("C:/Users/mvdelft/Documents/Reverb_configurator/output.wav");
sound.setLoops(10);

/// Check is sound is finished
while (!sound.isFinished()){}

ui->listWidget->addItem("Finished playing sound");
}/// End of scope

person Whiteshift    schedule 19.02.2016    source источник


Ответы (1)


В первой версии вы создаете объект QSound в стеке с файлом, начинаете его воспроизводить и тут же уничтожаете. Это остановит воспроизведение звука, и вы ничего не услышите.

Во второй версии QSound::play(const QString &) является статическим методом. Он будет воспроизводить звук в фоновом режиме. Вот почему ты что-то слышишь. Со статическим методом вызовы setLoops и isFinished не будут работать. Кроме того, петля занятости (while (!sound.isFinished()) ;) очень плоха, так как она потребляет 100% ресурсов ЦП и, возможно, блокирует воспроизведение звука.

Чтобы звук работал, вы должны создать его в куче и регулярно проверять isFinished() по событию таймера. Однако я предлагаю QSoundEffect, так как это дает вам больше контроля. Самое главное, сигнал playingChanged(), который сообщит вам об окончании игры без необходимости постоянно проверять.

Контур:

void MyObject::playSomeSound() {
   QSoundEffect *s = new QSoundEffect(this);
   connect(s, SIGNAL(playingChanged()), this, SLOT(soundPlayingChanged()));
   s->setSource("C:/Users/mvdelft/Documents/Reverb_configurator/output.wav");
   s->setLoopCount(10);
   s->play();
}

void MyObject::soundPlayingChanged() {
   QSoundEffect *s = qobject_cast<QSoundEffect *> (sender());
   // Will also be called when playing was started, so check if really finished
   if (!s->isPlaying()) {
      s->deleteLater();

      // Do what you need to do when playing finished
   }
}
person king_nak    schedule 19.02.2016
comment
Спасибо за быстрый комментарий, теперь это работает! Меня, как человека со средними навыками программирования, до сих пор сильно смущают проблемы с памятью. Спасибо хоть! - person Whiteshift; 19.02.2016