#include "../headers/scstwstartsoundplayer.h" ScStwStartSoundPlayer::ScStwStartSoundPlayer(QObject *parent) : QObject(parent) { this->waitLoop = new QEventLoop(); this->startSoundFile = new QFile(":/sound/StartsignalSound.wav", this); if(!this->startSoundFile->open(QFile::ReadOnly)) { qWarning() << "Cannot open audio File!!"; return; } // init sound format QAudioFormat format; format.setSampleRate(44100); format.setChannelCount(2); format.setSampleSize(16); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::SignedInt); // check if format is valid QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); if (!info.isFormatSupported(format)) { qWarning() << "Raw audio format not supported by backend, cannot play audio."; return; } this->audioOutput = new QAudioOutput(format); this->audioOutput->setCategory("ScStw start sound"); connect(this->audioOutput, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State))); } bool ScStwStartSoundPlayer::play(double volume, double *timeOfStop) { double st = QDateTime::currentMSecsSinceEpoch(); // update volume this->audioOutput->setVolume(volume); // start this->audioOutput->start(this->startSoundFile); double ed = QDateTime::currentMSecsSinceEpoch(); qDebug() << "time passed: " << ed-st << " playback elapsed: " << this->audioOutput->elapsedUSecs(); // wait until the audio output reports the sound is over waitLoop->exec(); qDebug() << "waitLoop exited!! elapsed: " << this->audioOutput->elapsedUSecs() << " processed: " << this->audioOutput->processedUSecs(); // wait until the sound is actually over // the timeOffset is the buffer time before the audio started! int timeOffset = ((this->audioOutput->processedUSecs() - this->audioOutput->elapsedUSecs()) / 1000); if(timeOffset > 0) { QTimer timer; timer.singleShot(timeOffset, this->waitLoop, &QEventLoop::quit); waitLoop->exec(); } // calculate the point in time where the sound playback actually ended if(timeOfStop != nullptr) { int latency = (this->audioOutput->processedUSecs() - this->audioOutput->elapsedUSecs()) / 1000; *timeOfStop = QDateTime::currentMSecsSinceEpoch() - latency; } // check for errors and return if(this->audioOutput->state() == QAudio::IdleState) return true; return false; } void ScStwStartSoundPlayer::handleStateChanged(QAudio::State newState) { switch (newState) { case QAudio::IdleState: // Finished playing (no more data) qDebug() << "sound reported over!! elapsed: " << this->audioOutput->elapsedUSecs() << " processed: " << this->audioOutput->processedUSecs(); waitLoop->exit(); break; case QAudio::StoppedState: // Stopped for other reasons if (this->audioOutput->error() != QAudio::NoError) { // Error handling } break; default: // ... other cases as appropriate break; } }