diff --git a/ScStwLibraries/headers/ScStw.hpp b/ScStwLibraries/headers/ScStw.hpp index 47f6ba7..fac3f33 100644 --- a/ScStwLibraries/headers/ScStw.hpp +++ b/ScStwLibraries/headers/ScStw.hpp @@ -79,6 +79,7 @@ public: StartRaceCommand = 1000, StopRaceCommand = 1001, ResetRaceCommand = 1002, + CancelRaceCommand = 1003, GetRaceStateCommand = 2000, GetNextStartActionCommand = 2005, diff --git a/ScStwLibraries/headers/scstwrace.h b/ScStwLibraries/headers/scstwrace.h index 3f4cafb..80906da 100644 --- a/ScStwLibraries/headers/scstwrace.h +++ b/ScStwLibraries/headers/scstwrace.h @@ -106,21 +106,21 @@ public slots: * or if if should wait until the start sequence is over and quit after that (false) * \return 200: OK; 904: state not matching */ - int start(bool asyncronous = true); + virtual ScStw::StatusCode start(bool asyncronous = true); /*! * \brief Function to stop the currently running race * * \return 200: OK; 904: state not matching */ - virtual int stop(); + virtual ScStw::StatusCode stop(); /*! * \brief Function to reset a stopped race * \return */ - virtual int reset(); - virtual int cancel(); + virtual ScStw::StatusCode reset(); + virtual ScStw::StatusCode cancel(); // setters bool writeStartSoundSetting(ScStwSoundPlayer::StartSound sound, bool enabled, int delay); diff --git a/ScStwLibraries/headers/scstwsoundplayer.h b/ScStwLibraries/headers/scstwsoundplayer.h index 561e995..1e977db 100644 --- a/ScStwLibraries/headers/scstwsoundplayer.h +++ b/ScStwLibraries/headers/scstwsoundplayer.h @@ -42,9 +42,10 @@ public: explicit ScStwSoundPlayer(QObject *parent = nullptr); enum StartSound { - Start, + AtYourMarks, Ready, - AtYourMarks + Start, + FalseStart }; private: @@ -55,7 +56,7 @@ private: * 2: StartSound * 3: FalseStartSound */ - QMap soundFiles; + QMap soundFiles; /*! * \brief The sound effect object @@ -75,7 +76,7 @@ private: /*! * \brief The action that is currently played */ - int currentlyPlayingAction; + StartSound currentlyPlayingSound; /*! * \brief Holds the time the playback started at @@ -91,7 +92,7 @@ public slots: * \param timeOfStop The time the playback actually started (msecs since epoch) * \return true if the playback was successfully started, false otherwise */ - bool play(int action, double volume, double *timeOfStart = nullptr); + bool play(StartSound sound, double volume, double *timeOfStart = nullptr); /*! * \brief Function to wait for the playback to finish diff --git a/ScStwLibraries/sources/scstwrace.cpp b/ScStwLibraries/sources/scstwrace.cpp index 1321918..eb65e9e 100644 --- a/ScStwLibraries/sources/scstwrace.cpp +++ b/ScStwLibraries/sources/scstwrace.cpp @@ -206,6 +206,7 @@ bool ScStwRace::playSoundsAndStartTimers() { return true; // The check if all timers are ready has already happened at this point + qDebug() << "now playing at marks sound"; if(!this->doDelayAndSoundOfCurrentStartState()) return false; @@ -213,6 +214,7 @@ bool ScStwRace::playSoundsAndStartTimers() { if(!this->isStarting()) return false; + qDebug() << "Now in waiting state"; this->setState(WAITING); // do climber readiness tests @@ -220,7 +222,7 @@ bool ScStwRace::playSoundsAndStartTimers() { // wait until both climbers are ready // if the automatic ready tone is enabled, wait for the climbers to become ready - if(this->startSoundSettings.contains(ScStwSoundPlayer::Ready) && this->startSoundSettings[ScStwSoundPlayer::Ready]["Enabled"].toBool()) { + if(this->competitionMode && this->startSoundSettings.contains(ScStwSoundPlayer::Ready) && this->startSoundSettings[ScStwSoundPlayer::Ready]["Enabled"].toBool()) { qDebug() << "[RACE][INFO] Now waiting for climbers"; @@ -245,11 +247,15 @@ bool ScStwRace::playSoundsAndStartTimers() { else { this->startDelayTimer->stop(); this->startDelayTimer->start(); + timerTriggered = true; } emit this->currentStartDelayChanged(); + + qDebug() << "entering wait loop..."; int loopExitCode = this->startWaitLoop->exec(); + qDebug() << "wait loop exited with code " << loopExitCode; switch (loopExitCode) { case LoopAutomaticExit: @@ -262,6 +268,8 @@ bool ScStwRace::playSoundsAndStartTimers() { return false; } + qDebug() << "At end of loop: remaining time: " << this->startDelayTimer->remainingTime() << " timer triggered: " << timerTriggered << " ready for next state: " << this->isReadyForNextState(); + } while(this->startDelayTimer->remainingTime() > 0 || !timerTriggered || !this->isReadyForNextState()); qDebug() << "[RACE][DEBUG] Initial wait finished"; @@ -276,7 +284,7 @@ bool ScStwRace::playSoundsAndStartTimers() { if(!this->soundPlayer->play(ScStwSoundPlayer::Ready, this->soundVolume)) return false; } - else { + else if(this->competitionMode) { // wait for climbers and manual start int loopExitCode; do { @@ -287,11 +295,19 @@ bool ScStwRace::playSoundsAndStartTimers() { } while(loopExitCode != LoopManualExit || !this->isReadyForNextState()); } + else { + qDebug() << "now playing ready sound"; + if(!this->doDelayAndSoundOfCurrentStartState()) + return false; + } + + qDebug() << "now in starting state"; // enter starting state this->setState(STARTING); // play start tone + qDebug() << "now playing start sound"; double timeOfSoundPlaybackStart; this->doDelayAndSoundOfCurrentStartState(&timeOfSoundPlaybackStart); @@ -343,8 +359,6 @@ bool ScStwRace::doDelayAndSoundOfCurrentStartState(double *timeOfSoundPlaybackSt } if(this->startSoundSettings.contains(sound) && this->startSoundSettings[sound]["Enabled"].toBool()) { - - if(sound != ScStwSoundPlayer::Start && this->startSoundSettings[sound]["Delay"].toInt() > 0) { // perform the delay before the start @@ -426,6 +440,10 @@ void ScStwRace::refreshTimerStates() { // ------------------------ bool ScStwRace::isReadyForNextState() { + if(!this->competitionMode) { + return true; + } + switch (this->state) { case IDLE: { foreach (ScStwTimer *timer, this->timers) { @@ -434,11 +452,6 @@ bool ScStwRace::isReadyForNextState() { if(timer->getReadyState() == ScStwTimer::ExtensionIsNotConnected || timer->getReadyState() == ScStwTimer::ExtensionBatteryNotFine) { - if(!this->competitionMode) { - timer->setDisabled(true); - continue; - } - qDebug() << "Timer ready state is: " << timer->getReadyState(); timer->technicalIncident(); diff --git a/ScStwLibraries/sources/scstwsoundplayer.cpp b/ScStwLibraries/sources/scstwsoundplayer.cpp index 0c576a5..79b82d0 100644 --- a/ScStwLibraries/sources/scstwsoundplayer.cpp +++ b/ScStwLibraries/sources/scstwsoundplayer.cpp @@ -23,10 +23,10 @@ ScStwSoundPlayer::ScStwSoundPlayer(QObject *parent) : QObject(parent) this->waitLoop = new QEventLoop(this); this->waitTimer = new QTimer(this); - this->soundFiles.insert(0, {{"path","qrc:/sound/AtYourMarksSound.wav"}, {"duration", 1000}}); - this->soundFiles.insert(1, {{"path","qrc:/sound/ReadySound.wav"}, {"duration", 570}}); - this->soundFiles.insert(2, {{"path","qrc:/sound/StartsignalSoundExtended.wav"}, {"duration", 3200}}); - this->soundFiles.insert(3, {{"path","qrc:/sound/FalseStartSound.wav"}, {"duration", 2000}}); + this->soundFiles.insert(AtYourMarks, {{"path","qrc:/sound/AtYourMarksSound.wav"}, {"duration", 1000}}); + this->soundFiles.insert(Ready, {{"path","qrc:/sound/ReadySound.wav"}, {"duration", 570}}); + this->soundFiles.insert(Start, {{"path","qrc:/sound/StartsignalSoundExtended.wav"}, {"duration", 3200}}); + this->soundFiles.insert(FalseStart, {{"path","qrc:/sound/FalseStartSound.wav"}, {"duration", 2000}}); this->soundEffect = new QSoundEffect(this); this->soundEffect->setLoopCount(1); @@ -35,11 +35,11 @@ ScStwSoundPlayer::ScStwSoundPlayer(QObject *parent) : QObject(parent) connect(this->soundEffect, &QSoundEffect::playingChanged, this->waitLoop, &QEventLoop::quit); } -bool ScStwSoundPlayer::play(int action, double volume, double *timeOfStart) { - if(!this->soundFiles.contains(action)) +bool ScStwSoundPlayer::play(ScStwSoundPlayer::StartSound sound, double volume, double *timeOfStart) { + if(!this->soundFiles.contains(sound)) return false; - if(action > 2 || action < 0) + if(sound > Start || sound < AtYourMarks) return false; // stop playback @@ -47,13 +47,13 @@ bool ScStwSoundPlayer::play(int action, double volume, double *timeOfStart) { this->soundEffect->stop(); // update currently playing action - this->currentlyPlayingAction = action; + this->currentlyPlayingSound = sound; // update volume this->soundEffect->setVolume(volume); // load - this->soundEffect->setSource(this->soundFiles[action]["path"].toString()); + this->soundEffect->setSource(this->soundFiles[sound]["path"].toString()); // wait for the effect to load QEventLoop loop; @@ -76,7 +76,7 @@ bool ScStwSoundPlayer::play(int action, double volume, double *timeOfStart) { *timeOfStart = this->playingStartedAt; } - if(action < 2) + if(sound < 2) return this->waitForSoundFinish(); return true; @@ -90,14 +90,14 @@ bool ScStwSoundPlayer::cancel(double volume) { this->soundEffect->stop(); this->waitLoop->quit(); - if(this->currentlyPlayingAction != 2) + if(this->currentlyPlayingSound != 2) return true; // update volume this->soundEffect->setVolume(volume); // load - this->soundEffect->setSource(this->soundFiles[3]["path"].toString()); + this->soundEffect->setSource(this->soundFiles[FalseStart]["path"].toString()); // play this->soundEffect->play(); @@ -114,7 +114,7 @@ bool ScStwSoundPlayer::waitForSoundFinish(double *timeOfStop) { // wait until the sound is actually over // the timeOffset is the buffer time before the audio started! - int timeOffset = this->soundFiles[this->currentlyPlayingAction]["duration"].toDouble() - (QDateTime::currentMSecsSinceEpoch() - playingStartedAt); + int timeOffset = this->soundFiles[this->currentlyPlayingSound]["duration"].toDouble() - (QDateTime::currentMSecsSinceEpoch() - playingStartedAt); if(timeOffset > 0) { QTimer timer; @@ -124,7 +124,7 @@ bool ScStwSoundPlayer::waitForSoundFinish(double *timeOfStop) { // calculate the point in time where the sound playback actually ended if(timeOfStop != nullptr) { - int latency = this->playingStartedAt + this->soundFiles[this->currentlyPlayingAction]["duration"].toDouble(); + int latency = this->playingStartedAt + this->soundFiles[this->currentlyPlayingSound]["duration"].toDouble(); *timeOfStop = QDateTime::currentMSecsSinceEpoch() - latency; }