[s### Title: PC microphone with AetherVoice is silent after startup until mic source is switched to BAL and back to PC
What happened?
When AetherSDR starts with the microphone routed through the Windows PC and the radio microphone source set to PC, transmit microphone audio does not work.
The radio can be keyed, but no usable microphone audio is transmitted through the PC/AetherVoice path.
The problem can be recovered without restarting AetherSDR by temporarily switching the microphone source from PC to the radio's BAL input, keying the radio once, and then switching the microphone source back to PC.
After performing that sequence, the PC microphone/AetherVoice path begins working normally and continues to work for the session.
This appears to be a startup initialization or TX-audio-stream re-arm issue rather than a microphone hardware or AetherVoice processing issue, because simply cycling the radio microphone source through a hardware input causes the existing PC microphone configuration to begin working.
Working workaround:
- Start AetherSDR with the microphone configured for PC routing.
- Attempt to transmit using the PC microphone/AetherVoice path — no microphone audio is produced.
- Change the radio microphone source from
PC to BAL.
- Key the transmitter once.
- Change the microphone source back to
PC.
- Transmit again.
- PC microphone audio now works normally through AetherVoice.
What did you expect?
If the radio's microphone source is already configured as PC when AetherSDR starts/connects, AetherSDR should automatically initialize the Windows microphone capture path and the FlexRadio remote_audio_tx stream.
The microphone should therefore be ready for transmission immediately after connection without requiring the operator to:
- switch to a hardware microphone input,
- key the transmitter,
- or toggle the microphone source away from and back to
PC.
AetherVoice and the rest of the client-side TX audio chain should receive the PC microphone audio on the first transmission after startup.
Steps to reproduce
- Configure the FLEX-8600 microphone source for
PC.
- Configure AetherSDR to use a Windows microphone as the PC microphone input.
- Enable/use AetherVoice in the client-side transmit audio chain.
- Exit AetherSDR.
- Start AetherSDR and connect to the FLEX-8600.
- Leave the microphone source set to
PC.
- Key the transmitter and speak into the PC-connected microphone.
- Observe that no microphone audio is transmitted.
- Change the microphone source from
PC to BAL.
- Key the transmitter once.
- Unkey the transmitter.
- Change the microphone source from
BAL back to PC.
- Key the transmitter and speak into the same PC microphone.
- Observe that microphone audio now works normally through the PC/AetherVoice path.
Radio model & firmware
- Radio: FLEX-8600
- Firmware: 4.2.20.41343
- AetherSDR: 26.9.1
- Qt: 6.8.3
OS & version
- OS: Windows
- Windows version: Not specified
Developer Notes
This looks most likely to be a PC-microphone capture / remote_audio_tx initialization ordering problem rather than an AetherVoice DSP failure.
The relevant startup and mic-source routing logic is in:
src/gui/MainWindow_Session.cpp
In particular, the TX stream wiring around approximately lines 954-1013 should be examined.
txAudioStreamReady currently starts PC TX capture when the current radio mic selection is already PC:
if (m_radioModel.transmitModel().micSelection() == "PC") {
audioStartTx(m_radioModel.radioAddress(), 4991);
}
The remoteTxStreamReady handler similarly starts local PC microphone capture only when micSelection() == "PC" and the AudioEngine is not already reporting that TX is streaming.
The especially interesting path is the TransmitModel::micStateChanged handler around approximately lines 987-1013. When the mic source changes back to PC, it explicitly:
- restores
PcMicGain,
- verifies that a TX stream exists using
hasAnyTxStream(), and
- calls
audioStartTx() if the AudioEngine is not already streaming.
That source-change handler is a strong candidate for why the workaround succeeds: cycling PC -> BAL -> PC forces this initialization/re-arm path to execute after the radio session and remote_audio_tx stream are fully established.
Relevant code:
src/gui/MainWindow_Session.cpp
~954-985 txAudioStreamReady / remoteTxStreamReady
~987-1013 TransmitModel::micStateChanged PC-mic start/stop logic
The microphone capture implementation itself is in:
particularly:
AudioEngine::startTxStream()
around approximately lines 7272+.
Important startup behavior there includes:
if (m_audioSource)
return true;
followed by Windows/WASAPI input-device negotiation, creation of QAudioSource, and the Windows silent-open watchdog.
The Windows path around approximately lines 7557-7700 is also worth checking. AetherSDR already contains recovery logic for a WASAPI source that opens successfully but produces no bytes:
"TX source opened but produced no bytes in 1.5 s"
and retries the TX capture format ladder.
It would be useful to determine whether this bug is one of two cases:
-
startTxStream() is never called during initial connection
The radio may report mic_selection=PC before remoteTxStreamReady / TX stream assignment has completed, and the later stream-ready event may fail to arm capture because of state/order timing.
Cycling to BAL and back to PC then generates a fresh micStateChanged after hasAnyTxStream() is true, allowing:
to run successfully.
-
A QAudioSource exists but is not actually delivering microphone samples
AudioEngine::startTxStream() may have run during startup, causing isTxStreaming() to report true even though the Windows capture source is not producing usable data.
If so, the early guard:
if (m_audioSource)
return true;
could prevent another startup attempt until changing away from PC calls audioStopTx(). Returning to PC would then create a completely fresh QAudioSource, explaining the recovery.
The second possibility would be particularly interesting if the initial support log shows:
but there are no subsequent PC-mic level/sample events.
AetherVoice itself is downstream of microphone capture in the client-side TX voice chain. Since the same AetherVoice configuration works immediately after re-arming the PC route, the first investigation should probably be whether audio reaches AudioEngine::onTxAudioReady() at all before examining the AetherVoice processor.
Logging to enable
Please capture a Help -> Support log from application startup through the failed first transmit, then continue the same log while performing:
PC -> BAL -> key TX -> unkey -> PC -> successful TX
The most useful logging would be:
- Audio /
aether.audio — detailed QAudioSource, device negotiation, TX capture, and TX stream lifecycle
aether.audio.summary — normally enabled in the support log; records selected/default devices, current TX route intent, successful TX opens, negotiated formats, and final open failures
- Protocol — radio
mic_selection, remote_audio_tx, and related status/command traffic
- Connection — ordering of radio connection/session initialization
Specific log entries to compare before and after the workaround:
remote audio TX stream ID set
TX stream started
selected TX input format
TX source opened but produced no bytes
TX source produced no bytes
mic_selection=PC
mic_selection=BAL
Also check whether the first failed transmission ever generates PC microphone level activity or reaches:
AudioEngine::onTxAudioReady()
If there are no captured microphone samples before the BAL -> PC cycle, the failure is upstream of AetherVoice.
If samples are present before the cycle but no modulation reaches the radio, then the next areas to inspect are:
TxVoiceProcessor
Opus remote_audio_tx packetization
remote TX stream ID assignment
Potential root causes
Most likely possibilities, in approximate order:
-
Startup ordering/race between mic_selection=PC and remoteTxStreamReady.
The PC route becomes known before the usable remote TX stream is established, but no later event reliably re-arms microphone capture.
-
micStateChanged is not emitted for the initial radio-reported PC state.
The runtime toggle path therefore works, while the startup state bypasses the logic that normally starts PC capture.
-
isTxStreaming() / m_audioSource indicates an initialized source that is actually silent.
The existing source prevents a new start until changing to BAL calls audioStopTx().
-
Windows WASAPI source opens in a non-functional state during early application startup.
Reopening it after the radio has been keyed and the route has changed creates a working capture source.
-
Remote TX stream ID becomes valid after microphone initialization but the existing capture path is not rebound/restarted.
The later BAL -> PC transition performs that missing re-arm.
A useful fix may be to make PC-mic initialization idempotent and explicitly reconcile the desired state after both pieces of state are known:
mic_selection == PC
AND
remote_audio_tx stream is assigned
Once both are true, AetherSDR should ensure that a functioning local microphone capture source exists, regardless of which event arrived first.
A regression test should exercise both event orderings:
mic_selection=PC -> remoteTxStreamReady
remoteTxStreamReady -> mic_selection=PC
and verify that both result in an active PC microphone capture path without requiring a subsequent microphone-source change.
support-bundle-20260905-083100.zip
[s### Title: PC microphone with AetherVoice is silent after startup until mic source is switched to BAL and back to PC
What happened?
When AetherSDR starts with the microphone routed through the Windows PC and the radio microphone source set to
PC, transmit microphone audio does not work.The radio can be keyed, but no usable microphone audio is transmitted through the PC/AetherVoice path.
The problem can be recovered without restarting AetherSDR by temporarily switching the microphone source from
PCto the radio'sBALinput, keying the radio once, and then switching the microphone source back toPC.After performing that sequence, the PC microphone/AetherVoice path begins working normally and continues to work for the session.
This appears to be a startup initialization or TX-audio-stream re-arm issue rather than a microphone hardware or AetherVoice processing issue, because simply cycling the radio microphone source through a hardware input causes the existing PC microphone configuration to begin working.
Working workaround:
PCtoBAL.PC.What did you expect?
If the radio's microphone source is already configured as
PCwhen AetherSDR starts/connects, AetherSDR should automatically initialize the Windows microphone capture path and the FlexRadioremote_audio_txstream.The microphone should therefore be ready for transmission immediately after connection without requiring the operator to:
PC.AetherVoice and the rest of the client-side TX audio chain should receive the PC microphone audio on the first transmission after startup.
Steps to reproduce
PC.PC.PCtoBAL.BALback toPC.Radio model & firmware
OS & version
Developer Notes
This looks most likely to be a PC-microphone capture /
remote_audio_txinitialization ordering problem rather than an AetherVoice DSP failure.The relevant startup and mic-source routing logic is in:
In particular, the TX stream wiring around approximately lines 954-1013 should be examined.
txAudioStreamReadycurrently starts PC TX capture when the current radio mic selection is alreadyPC:The
remoteTxStreamReadyhandler similarly starts local PC microphone capture only whenmicSelection() == "PC"and the AudioEngine is not already reporting that TX is streaming.The especially interesting path is the
TransmitModel::micStateChangedhandler around approximately lines 987-1013. When the mic source changes back toPC, it explicitly:PcMicGain,hasAnyTxStream(), andaudioStartTx()if the AudioEngine is not already streaming.That source-change handler is a strong candidate for why the workaround succeeds: cycling
PC -> BAL -> PCforces this initialization/re-arm path to execute after the radio session andremote_audio_txstream are fully established.Relevant code:
The microphone capture implementation itself is in:
particularly:
around approximately lines 7272+.
Important startup behavior there includes:
followed by Windows/WASAPI input-device negotiation, creation of
QAudioSource, and the Windows silent-open watchdog.The Windows path around approximately lines 7557-7700 is also worth checking. AetherSDR already contains recovery logic for a WASAPI source that opens successfully but produces no bytes:
and retries the TX capture format ladder.
It would be useful to determine whether this bug is one of two cases:
startTxStream()is never called during initial connectionThe radio may report
mic_selection=PCbeforeremoteTxStreamReady/ TX stream assignment has completed, and the later stream-ready event may fail to arm capture because of state/order timing.Cycling to
BALand back toPCthen generates a freshmicStateChangedafterhasAnyTxStream()is true, allowing:audioStartTx(...)to run successfully.
A
QAudioSourceexists but is not actually delivering microphone samplesAudioEngine::startTxStream()may have run during startup, causingisTxStreaming()to report true even though the Windows capture source is not producing usable data.If so, the early guard:
could prevent another startup attempt until changing away from
PCcallsaudioStopTx(). Returning toPCwould then create a completely freshQAudioSource, explaining the recovery.The second possibility would be particularly interesting if the initial support log shows:
but there are no subsequent PC-mic level/sample events.
AetherVoice itself is downstream of microphone capture in the client-side TX voice chain. Since the same AetherVoice configuration works immediately after re-arming the
PCroute, the first investigation should probably be whether audio reachesAudioEngine::onTxAudioReady()at all before examining the AetherVoice processor.Logging to enable
Please capture a Help -> Support log from application startup through the failed first transmit, then continue the same log while performing:
The most useful logging would be:
aether.audio— detailedQAudioSource, device negotiation, TX capture, and TX stream lifecycleaether.audio.summary— normally enabled in the support log; records selected/default devices, current TX route intent, successful TX opens, negotiated formats, and final open failuresmic_selection,remote_audio_tx, and related status/command trafficSpecific log entries to compare before and after the workaround:
Also check whether the first failed transmission ever generates PC microphone level activity or reaches:
If there are no captured microphone samples before the
BAL -> PCcycle, the failure is upstream of AetherVoice.If samples are present before the cycle but no modulation reaches the radio, then the next areas to inspect are:
Potential root causes
Most likely possibilities, in approximate order:
Startup ordering/race between
mic_selection=PCandremoteTxStreamReady.The PC route becomes known before the usable remote TX stream is established, but no later event reliably re-arms microphone capture.
micStateChangedis not emitted for the initial radio-reported PC state.The runtime toggle path therefore works, while the startup state bypasses the logic that normally starts PC capture.
isTxStreaming()/m_audioSourceindicates an initialized source that is actually silent.The existing source prevents a new start until changing to
BALcallsaudioStopTx().Windows WASAPI source opens in a non-functional state during early application startup.
Reopening it after the radio has been keyed and the route has changed creates a working capture source.
Remote TX stream ID becomes valid after microphone initialization but the existing capture path is not rebound/restarted.
The later
BAL -> PCtransition performs that missing re-arm.A useful fix may be to make PC-mic initialization idempotent and explicitly reconcile the desired state after both pieces of state are known:
Once both are true, AetherSDR should ensure that a functioning local microphone capture source exists, regardless of which event arrived first.
A regression test should exercise both event orderings:
and verify that both result in an active PC microphone capture path without requiring a subsequent microphone-source change.
support-bundle-20260905-083100.zip