95 lines
3.2 KiB
C++
95 lines
3.2 KiB
C++
|
#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;
|
||
|
}
|
||
|
}
|