some more error handling for sound playing
This commit is contained in:
parent
6709a1fd2b
commit
e4700cd355
5 changed files with 64 additions and 32 deletions
|
@ -134,7 +134,7 @@ private slots:
|
||||||
void handleTimerWantsToBeDisabledChange(ScStwTimer* timer, bool wantsToBeDisabled);
|
void handleTimerWantsToBeDisabledChange(ScStwTimer* timer, bool wantsToBeDisabled);
|
||||||
int handleFalseStart();
|
int handleFalseStart();
|
||||||
bool playSoundsAndStartTimers();
|
bool playSoundsAndStartTimers();
|
||||||
bool doDelayAndSoundOfCurrentStartState(double *timeOfSoundPlaybackStart = nullptr);
|
ScStwSoundPlayer::PlayResult doDelayAndSoundOfCurrentStartState(double *timeOfSoundPlaybackStart = nullptr);
|
||||||
void technicalIncident();
|
void technicalIncident();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -49,6 +49,12 @@ public:
|
||||||
FalseStart = 3
|
FalseStart = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PlayResult {
|
||||||
|
Success = 0,
|
||||||
|
Cancelled = -1,
|
||||||
|
Error = -2
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*!
|
/*!
|
||||||
* \brief A map containing all sound files
|
* \brief A map containing all sound files
|
||||||
|
@ -91,16 +97,16 @@ public slots:
|
||||||
* \param action The action to play (0: AtYourMarks, 1:Ready, 2:Start)
|
* \param action The action to play (0: AtYourMarks, 1:Ready, 2:Start)
|
||||||
* \param volume The volume to play at
|
* \param volume The volume to play at
|
||||||
* \param timeOfStop The time the playback actually started (msecs since epoch)
|
* \param timeOfStop The time the playback actually started (msecs since epoch)
|
||||||
* \return true if the playback was successfully started, false otherwise
|
* \return TODO true if the playback was successfully started, false otherwise
|
||||||
*/
|
*/
|
||||||
bool play(StartSound sound, double volume, double *timeOfStart = nullptr);
|
ScStwSoundPlayer::PlayResult play(StartSound sound, double volume, double *timeOfStart = nullptr);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Function to wait for the playback to finish
|
* \brief Function to wait for the playback to finish
|
||||||
* \param timeOfStop the point in time when the plyback actually stopped (msecs since epoch)
|
* \param timeOfStop the point in time when the plyback actually stopped (msecs since epoch)
|
||||||
* \return false if there was any error (eg. there was no playback currently), true otherwise
|
* \return false if there was any error (eg. there was no playback currently), true otherwise
|
||||||
*/
|
*/
|
||||||
bool waitForSoundFinish(double *timeOfStop = nullptr);
|
ScStwSoundPlayer::PlayResult waitForSoundFinish(double *timeOfStop = nullptr);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Function to cancel the current playback
|
* \brief Function to cancel the current playback
|
||||||
|
|
|
@ -197,6 +197,8 @@ void ScStwRace::technicalIncident() {
|
||||||
foreach(ScStwTimer *timer, this->timers){
|
foreach(ScStwTimer *timer, this->timers){
|
||||||
timer->cancel();
|
timer->cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->soundPlayer->cancel();
|
||||||
this->setState(INCIDENT);
|
this->setState(INCIDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,8 +225,16 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// The check if all timers are ready has already happened at this point
|
// The check if all timers are ready has already happened at this point
|
||||||
if(!this->doDelayAndSoundOfCurrentStartState())
|
ScStwSoundPlayer::PlayResult res = this->doDelayAndSoundOfCurrentStartState();
|
||||||
|
|
||||||
|
if(res == ScStwSoundPlayer::Error) {
|
||||||
|
qDebug() << "[ERROR][RACE] error playing at your marks sound";
|
||||||
|
this->technicalIncident();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
else if(res == ScStwSoundPlayer::Cancelled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// check if the start was cancelled
|
// check if the start was cancelled
|
||||||
if(!this->isStarting())
|
if(!this->isStarting())
|
||||||
|
@ -234,8 +244,6 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
||||||
|
|
||||||
// do climber readiness tests
|
// do climber readiness tests
|
||||||
|
|
||||||
// wait until both climbers are ready
|
|
||||||
|
|
||||||
// if the automatic ready tone is enabled, wait for the climbers to become ready
|
// if the automatic ready tone is enabled, wait for the climbers to become ready
|
||||||
if(this->competitionMode && this->getSoundEnabledSetting(ScStwSoundPlayer::Ready)) {
|
if(this->competitionMode && this->getSoundEnabledSetting(ScStwSoundPlayer::Ready)) {
|
||||||
|
|
||||||
|
@ -290,11 +298,16 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
||||||
qDebug() << "[DEBUG][RACE] Wait finished, starting now!";
|
qDebug() << "[DEBUG][RACE] Wait finished, starting now!";
|
||||||
|
|
||||||
// play ready tone
|
// play ready tone
|
||||||
if(!this->soundPlayer->play(ScStwSoundPlayer::Ready, this->getSoundVolume())) {
|
ScStwSoundPlayer::PlayResult res = this->soundPlayer->play(ScStwSoundPlayer::Ready, this->getSoundVolume());
|
||||||
qDebug() << "[ERROR][RACE] Ready sound returned false!";
|
|
||||||
|
if(res == ScStwSoundPlayer::Error) {
|
||||||
|
qDebug() << "[ERROR][RACE] error playing ready sound";
|
||||||
this->technicalIncident();
|
this->technicalIncident();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if(res == ScStwSoundPlayer::Cancelled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(this->competitionMode) {
|
else if(this->competitionMode) {
|
||||||
// wait for climbers and manual start
|
// wait for climbers and manual start
|
||||||
|
@ -308,8 +321,14 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
||||||
} while(loopExitCode != LoopManualExit || !this->getIsReadyForNextState());
|
} while(loopExitCode != LoopManualExit || !this->getIsReadyForNextState());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!this->doDelayAndSoundOfCurrentStartState()) {
|
ScStwSoundPlayer::PlayResult res = this->doDelayAndSoundOfCurrentStartState();
|
||||||
this->cancel();
|
|
||||||
|
if(res == ScStwSoundPlayer::Error) {
|
||||||
|
qDebug() << "[ERROR][RACE] error playing ready sound";
|
||||||
|
this->technicalIncident();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(res == ScStwSoundPlayer::Cancelled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,10 +338,16 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
||||||
|
|
||||||
// play start tone
|
// play start tone
|
||||||
double timeOfSoundPlaybackStart;
|
double timeOfSoundPlaybackStart;
|
||||||
if(!this->doDelayAndSoundOfCurrentStartState(&timeOfSoundPlaybackStart)) {
|
res = this->doDelayAndSoundOfCurrentStartState(&timeOfSoundPlaybackStart);
|
||||||
|
|
||||||
|
if(res == ScStwSoundPlayer::Error) {
|
||||||
|
qDebug() << "[ERROR][RACE] error playing at your marks sound";
|
||||||
this->technicalIncident();
|
this->technicalIncident();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if(res == ScStwSoundPlayer::Cancelled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// perform start
|
// perform start
|
||||||
|
|
||||||
|
@ -339,7 +364,7 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this->soundPlayer->waitForSoundFinish()) {
|
if(this->soundPlayer->waitForSoundFinish() == ScStwSoundPlayer::Error) {
|
||||||
qDebug() << "[ERROR][RACE] start sound wait error";
|
qDebug() << "[ERROR][RACE] start sound wait error";
|
||||||
this->technicalIncident();
|
this->technicalIncident();
|
||||||
return false;
|
return false;
|
||||||
|
@ -347,7 +372,7 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
||||||
|
|
||||||
// check if a false start occured
|
// check if a false start occured
|
||||||
if(!this->isStarting())
|
if(!this->isStarting())
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
this->setState(RUNNING);
|
this->setState(RUNNING);
|
||||||
|
|
||||||
|
@ -356,7 +381,7 @@ bool ScStwRace::playSoundsAndStartTimers() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScStwRace::doDelayAndSoundOfCurrentStartState(double *timeOfSoundPlaybackStart) {
|
ScStwSoundPlayer::PlayResult ScStwRace::doDelayAndSoundOfCurrentStartState(double *timeOfSoundPlaybackStart) {
|
||||||
ScStwSoundPlayer::StartSound sound = this->getSoundForState(this->state);
|
ScStwSoundPlayer::StartSound sound = this->getSoundForState(this->state);
|
||||||
|
|
||||||
if(this->getSoundEnabledSetting(sound)) {
|
if(this->getSoundEnabledSetting(sound)) {
|
||||||
|
@ -374,18 +399,18 @@ bool ScStwRace::doDelayAndSoundOfCurrentStartState(double *timeOfSoundPlaybackSt
|
||||||
emit this->currentStartDelayChanged();
|
emit this->currentStartDelayChanged();
|
||||||
|
|
||||||
if(this->startWaitLoop->exec() == LoopCancelExit)
|
if(this->startWaitLoop->exec() == LoopCancelExit)
|
||||||
return false;
|
return ScStwSoundPlayer::Cancelled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this->isStarting())
|
if(!this->isStarting())
|
||||||
return false;
|
return ScStwSoundPlayer::Error;
|
||||||
|
|
||||||
if(!this->soundPlayer->play(sound, this->getSoundVolume(), timeOfSoundPlaybackStart))
|
|
||||||
return false;
|
return this->soundPlayer->play(sound, this->getSoundVolume(), timeOfSoundPlaybackStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return ScStwSoundPlayer::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScStwRace::setState(RaceState newState) {
|
void ScStwRace::setState(RaceState newState) {
|
||||||
|
|
|
@ -35,9 +35,11 @@ ScStwSoundPlayer::ScStwSoundPlayer(QObject *parent) : QObject(parent)
|
||||||
connect(this->soundEffect, &QSoundEffect::playingChanged, this->waitLoop, &QEventLoop::quit);
|
connect(this->soundEffect, &QSoundEffect::playingChanged, this->waitLoop, &QEventLoop::quit);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScStwSoundPlayer::play(ScStwSoundPlayer::StartSound sound, double volume, double *timeOfStart) {
|
ScStwSoundPlayer::PlayResult ScStwSoundPlayer::play(ScStwSoundPlayer::StartSound sound, double volume, double *timeOfStart) {
|
||||||
if(!this->soundFiles.contains(sound))
|
if(!this->soundFiles.contains(sound)) {
|
||||||
return false;
|
qDebug() << "[ERROR][SoundPlayer] Sound file was not found for sound" << sound;
|
||||||
|
return ScStwSoundPlayer::Error;
|
||||||
|
}
|
||||||
|
|
||||||
// stop playback
|
// stop playback
|
||||||
if(this->soundEffect->isPlaying())
|
if(this->soundEffect->isPlaying())
|
||||||
|
@ -55,6 +57,7 @@ bool ScStwSoundPlayer::play(ScStwSoundPlayer::StartSound sound, double volume, d
|
||||||
// wait for the effect to load
|
// wait for the effect to load
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
while(this->soundEffect->status() != QSoundEffect::Ready) {
|
while(this->soundEffect->status() != QSoundEffect::Ready) {
|
||||||
|
qDebug() << "[DEBUG][Sound] Sound is not ready yet, status is: " << this->soundEffect->status();
|
||||||
QObject::connect(this->soundEffect, &QSoundEffect::statusChanged, &loop, &QEventLoop::quit);
|
QObject::connect(this->soundEffect, &QSoundEffect::statusChanged, &loop, &QEventLoop::quit);
|
||||||
loop.exec();
|
loop.exec();
|
||||||
}
|
}
|
||||||
|
@ -76,7 +79,7 @@ bool ScStwSoundPlayer::play(ScStwSoundPlayer::StartSound sound, double volume, d
|
||||||
if(sound < Start)
|
if(sound < Start)
|
||||||
return this->waitForSoundFinish();
|
return this->waitForSoundFinish();
|
||||||
|
|
||||||
return true;
|
return ScStwSoundPlayer::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScStwSoundPlayer::cancel() {
|
bool ScStwSoundPlayer::cancel() {
|
||||||
|
@ -85,17 +88,18 @@ bool ScStwSoundPlayer::cancel() {
|
||||||
|
|
||||||
// stop playback
|
// stop playback
|
||||||
this->soundEffect->stop();
|
this->soundEffect->stop();
|
||||||
this->waitLoop->quit();
|
this->waitLoop->exit(-1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScStwSoundPlayer::waitForSoundFinish(double *timeOfStop) {
|
ScStwSoundPlayer::PlayResult ScStwSoundPlayer::waitForSoundFinish(double *timeOfStop) {
|
||||||
if(!this->soundEffect->isPlaying())
|
if(!this->soundEffect->isPlaying())
|
||||||
return false;
|
return ScStwSoundPlayer::Error;
|
||||||
|
|
||||||
// wait until the audio output reports the sound is over
|
// wait until the audio output reports the sound is over
|
||||||
waitLoop->exec();
|
if(waitLoop->exec() == -1)
|
||||||
|
return ScStwSoundPlayer::Cancelled;
|
||||||
|
|
||||||
// wait until the sound is actually over
|
// wait until the sound is actually over
|
||||||
// the timeOffset is the buffer time before the audio started!
|
// the timeOffset is the buffer time before the audio started!
|
||||||
|
@ -113,7 +117,7 @@ bool ScStwSoundPlayer::waitForSoundFinish(double *timeOfStop) {
|
||||||
*timeOfStop = QDateTime::currentMSecsSinceEpoch() - latency;
|
*timeOfStop = QDateTime::currentMSecsSinceEpoch() - latency;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return ScStwSoundPlayer::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScStwSoundPlayer::isPlaying() {
|
bool ScStwSoundPlayer::isPlaying() {
|
||||||
|
|
|
@ -217,9 +217,6 @@ QString ScStwTimer::getLetter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ScStwTimer::getText() {
|
QString ScStwTimer::getText() {
|
||||||
|
|
||||||
qDebug() << "getting text: start time: " << this->startTime << " state: " << this->state;
|
|
||||||
|
|
||||||
QString newText = "";
|
QString newText = "";
|
||||||
int newTime = 0;
|
int newTime = 0;
|
||||||
switch (this->state) {
|
switch (this->state) {
|
||||||
|
|
Reference in a new issue