shared-libraries/ScStwLibraries/sources/scstwstartsoundplayer.cpp

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;
}
}