Skip to content

Commit fed33f5

Browse files
committed
Delay playback thread until TX and harden RX startup guards
1 parent 587a679 commit fed33f5

File tree

2 files changed

+22
-29
lines changed

2 files changed

+22
-29
lines changed

src/gui/app.cpp

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ App::App(const Options& opts) : options_(opts), sim_ui_visible_(opts.enable_sim)
341341
if (waterfall_) {
342342
waterfall_->addSamples(samples.data(), samples.size());
343343
}
344+
audio_.startPlayback();
344345
audio_.queueTxSamples(samples);
345346
}
346347
}
@@ -368,6 +369,7 @@ App::App(const Options& opts) : options_(opts), sim_ui_visible_(opts.enable_sim)
368369
if (waterfall_) {
369370
waterfall_->addSamples(samples.data(), samples.size());
370371
}
372+
audio_.startPlayback();
371373
audio_.queueTxSamples(samples);
372374
}
373375
}
@@ -456,6 +458,7 @@ App::App(const Options& opts) : options_(opts), sim_ui_visible_(opts.enable_sim)
456458
if (waterfall_) {
457459
waterfall_->addSamples(samples.data(), samples.size());
458460
}
461+
audio_.startPlayback();
459462
audio_.queueTxSamples(samples);
460463
}
461464
}
@@ -483,6 +486,7 @@ App::App(const Options& opts) : options_(opts), sim_ui_visible_(opts.enable_sim)
483486
if (waterfall_) {
484487
waterfall_->addSamples(samples.data(), samples.size());
485488
}
489+
audio_.startPlayback();
486490
audio_.queueTxSamples(samples);
487491
}
488492
}
@@ -729,7 +733,6 @@ App::App(const Options& opts) : options_(opts), sim_ui_visible_(opts.enable_sim)
729733
audio_.setOutputGain(settings_.tx_drive);
730734
std::string output_dev = getOutputDeviceName();
731735
audio_.openOutput(output_dev);
732-
audio_.startPlayback();
733736
startRadioRx();
734737
}
735738
});
@@ -749,7 +752,6 @@ App::App(const Options& opts) : options_(opts), sim_ui_visible_(opts.enable_sim)
749752
audio_.setOutputGain(settings_.tx_drive);
750753
std::string output_dev = getOutputDeviceName();
751754
audio_.openOutput(output_dev);
752-
audio_.startPlayback();
753755
startRadioRx();
754756
}
755757
});
@@ -812,15 +814,10 @@ App::App(const Options& opts) : options_(opts), sim_ui_visible_(opts.enable_sim)
812814
if (audio_initialized_) {
813815
std::string output_dev = getOutputDeviceName();
814816
if (audio_.openOutput(output_dev)) {
815-
audio_.startPlayback();
816-
if (audio_.isPlaying()) {
817-
deferred_radio_rx_start_pending_ = true;
818-
deferred_radio_rx_start_deadline_ms_ = SDL_GetTicks() + 250;
819-
deferred_radio_rx_start_attempts_ = 0;
820-
guiLog("Startup audio stage: playback active, delaying RX capture by 250ms");
821-
} else {
822-
guiLog("Startup audio stage: playback did not start, capture deferred");
823-
}
817+
deferred_radio_rx_start_pending_ = true;
818+
deferred_radio_rx_start_deadline_ms_ = SDL_GetTicks() + 250;
819+
deferred_radio_rx_start_attempts_ = 0;
820+
guiLog("Startup audio stage 1/2 complete: output ready, delaying RX capture by 250ms");
824821
} else {
825822
guiLog("Startup audio stage: openOutput failed");
826823
}
@@ -1535,19 +1532,12 @@ void App::render() {
15351532
ultra::gui::startupTrace("App", "deferred-audio-open-output-enter");
15361533
std::string output_dev = getOutputDeviceName();
15371534
if (audio_.openOutput(output_dev)) {
1538-
audio_.startPlayback();
1539-
if (audio_.isPlaying()) {
1540-
deferred_radio_rx_start_pending_ = true;
1541-
deferred_radio_rx_start_deadline_ms_ = now_ms + 250;
1542-
deferred_radio_rx_start_attempts_ = 0;
1543-
guiLog("Deferred audio stage 1/2 complete: playback active, waiting 250ms before capture");
1544-
ultra::gui::startupTrace("App", "deferred-audio-open-output-exit");
1545-
deferred_audio_auto_init_pending_ = false;
1546-
} else {
1547-
guiLog("Deferred audio auto-init: playback did not start");
1548-
ultra::gui::startupTrace("App", "deferred-audio-open-output-fail");
1549-
deferred_audio_auto_init_pending_ = false;
1550-
}
1535+
deferred_radio_rx_start_pending_ = true;
1536+
deferred_radio_rx_start_deadline_ms_ = now_ms + 250;
1537+
deferred_radio_rx_start_attempts_ = 0;
1538+
guiLog("Deferred audio stage 1/2 complete: output ready, waiting 250ms before capture");
1539+
ultra::gui::startupTrace("App", "deferred-audio-open-output-exit");
1540+
deferred_audio_auto_init_pending_ = false;
15511541
} else {
15521542
guiLog("Deferred audio auto-init: openOutput failed");
15531543
ultra::gui::startupTrace("App", "deferred-audio-open-output-fail");
@@ -1598,16 +1588,19 @@ void App::render() {
15981588
// === DEBUG: Test signal keys (F1-F7) ===
15991589
if (ImGui::IsKeyPressed(ImGuiKey_F1)) {
16001590
auto tone = modem_.generateTestTone(1.0f);
1591+
audio_.startPlayback();
16011592
audio_.queueTxSamples(tone);
16021593
appendRxLogLine("[TEST] Sent 1500 Hz tone");
16031594
}
16041595
if (ImGui::IsKeyPressed(ImGuiKey_F2)) {
16051596
auto samples = modem_.transmitTestPattern(0);
1597+
audio_.startPlayback();
16061598
audio_.queueTxSamples(samples);
16071599
appendRxLogLine("[TEST] Sent pattern: ALL ZEROS (LDPC encoded)");
16081600
}
16091601
if (ImGui::IsKeyPressed(ImGuiKey_F3)) {
16101602
auto samples = modem_.transmitTestPattern(1);
1603+
audio_.startPlayback();
16111604
audio_.queueTxSamples(samples);
16121605
appendRxLogLine("[TEST] Sent pattern: DEADBEEF (LDPC encoded)");
16131606
}
@@ -1785,8 +1778,8 @@ bool App::startRadioRx() {
17851778
guiLog("startRadioRx guard: simulation enabled");
17861779
return false;
17871780
}
1788-
if (!audio_.isPlaying()) {
1789-
guiLog("startRadioRx guard: playback not active yet");
1781+
if (!audio_.hasOutputDevice()) {
1782+
guiLog("startRadioRx guard: output device not open");
17901783
return false;
17911784
}
17921785
if (radio_rx_enabled_) {
@@ -2091,7 +2084,7 @@ void App::renderOperateTab() {
20912084
modem_.reset();
20922085
if (audio_initialized_) {
20932086
audio_.openOutput(getOutputDeviceName());
2094-
audio_.startPlayback(); startRadioRx();
2087+
startRadioRx();
20952088
}
20962089
}
20972090
}
@@ -2142,7 +2135,6 @@ void App::renderOperateTab() {
21422135
if (ImGui::SmallButton("Start RX")) {
21432136
if (!audio_initialized_) initAudio();
21442137
audio_.openOutput(getOutputDeviceName());
2145-
audio_.startPlayback();
21462138
startRadioRx();
21472139
}
21482140
} else {
@@ -2193,7 +2185,6 @@ void App::renderOperateTab() {
21932185
if (!simulation_enabled_ && !radio_rx_enabled_) {
21942186
if (!audio_initialized_) initAudio();
21952187
audio_.openOutput(getOutputDeviceName());
2196-
audio_.startPlayback();
21972188
startRadioRx();
21982189
}
21992190
std::string remote_call(remote_callsign_, boundedCStringLen(remote_callsign_));

src/gui/audio_engine.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class AudioEngine {
5757
bool openInput(const std::string& device = "");
5858
void closeOutput();
5959
void closeInput();
60+
bool hasOutputDevice() const { return output_device_ != 0; }
61+
bool hasInputDevice() const { return input_device_ != 0; }
6062

6163
// TX: Queue samples to play
6264
void queueTxSamples(const std::vector<float>& samples);

0 commit comments

Comments
 (0)