Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.2.0, 5.9.1
-
None
-
Windows 7 64-bit
Description
#include <QtGui> #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) #include <QtWidgets> #endif #include <QtMultimedia/QSoundEffect> class AudioPlayer : public QWidget { Q_OBJECT public: AudioPlayer(QWidget *parent) : QWidget(parent), mLayout(new QVBoxLayout(this)), mButton(new QPushButton("Play", this)), mLabel(new QLabel("...", this)) { mLayout->addWidget(mButton); mLayout->addWidget(mLabel); setLayout(mLayout); mLabel->setAlignment(Qt::AlignHCenter); connect(mButton, SIGNAL(clicked()), this, SLOT(playPause())); mTimer.setInterval(5); mTimer.start(); connect(&mTimer, SIGNAL(timeout()), this, SLOT(animate())); resize(parent->width(), parent->height()); } private slots: void playPause() { if (!mSound.isPlaying()) { mSound.setSource(QUrl::fromLocalFile("test.wav")); mSound.setLoopCount(QSoundEffect::Infinite); mSound.setVolume(0.25); mSound.play(); connect(&mSound, SIGNAL(loadedChanged()), this, SLOT(doneLoading())); mButton->setEnabled(false); mButton->setText("Stop"); } else { QElapsedTimer elapsedTimer; elapsedTimer.start(); qDebug() << "Before QSoundEffect::stop()"; mSound.stop(); qDebug() << "After QSoundEffect::stop() (" << elapsedTimer.elapsed() << "ms)"; mButton->setEnabled(false); } } void doneLoading() { mButton->setEnabled(true); } void animate() { if (mLabel->text().size() == 40) { mLabel->setText(QString()); } mLabel->setText(mLabel->text() + "."); } private: QSoundEffect mSound; QVBoxLayout *mLayout; QPushButton *mButton; QLabel *mLabel; QTimer mTimer; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow mainWindow; AudioPlayer *audioPlayer = new AudioPlayer(&mainWindow); mainWindow.setCentralWidget(audioPlayer); mainWindow.show(); return a.exec(); } #include "main.moc"
The problem is the Sleep call:
void QAudioOutputPrivate::close() { if(deviceState == QAudio::StoppedState) return; deviceState = QAudio::StoppedState; errorState = QAudio::NoError; QElapsedTimer t; t.start(); int delay = (buffer_size-bytesFree())*1000/(settings.sampleRate() *settings.channelCount()*(settings.sampleSize()/8)); waveOutReset(hWaveOut); Sleep(delay+10); qDebug() << t.elapsed() << delay; freeBlocks(waveBlocks); waveOutClose(hWaveOut); delete [] audioBuffer; audioBuffer = 0; buffer_size = 0; }
http://msdn.microsoft.com/en-us/library/windows/desktop/dd743856(v=vs.85).aspx says:
Remarks
The close operation fails if the device is still playing a waveform-audio buffer that was previously sent by calling waveOutWrite. Before calling waveOutClose, the application must wait for all buffers to finish playing or call the waveOutReset function to terminate playback.
So the call to Sleep might not be necessary.