Add Audio tab toggle for transceiver built-in speaker

Adds a "Send audio stream to radio (built-in speaker)" checkbox on the
Settings → Audio tab. It is a single switch for the radio's built-in
speaker:

- ON  — RX audio is streamed to the radio via the DDC Audio packet
        (port 1028, 64 L/R pairs per packet) and the speaker is unmuted
        (High Priority byte 1400 bit1 = 0).
- OFF — speaker is muted (byte 1400 bit1 = 1, ANAN-8000DLE IO1 output)
        and no audio stream is sent.

The float->int16 conversion and 64-pair packet accumulation live in
THPSDRNetwork (SendSpeakerAudio/SetSpeakerAudio), next to SendDDCAudio;
MainForm only reads the setting and forwards the audio. State is
persisted per-MAC (send_audio_to_radio, default off) and re-applied on
each radio start.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Uladzimir Karpenka
2026-06-02 08:55:36 +03:00
co-authored by Claude Opus 4.8
parent d8584323ac
commit aff17aa3a6
4 changed files with 122 additions and 0 deletions
+23
View File
@@ -162,6 +162,9 @@ type
FAudioIn: TAudioInput;
FAudioOutDevName: string; // текущее имя выходного устройства
FAudioInDevName: string; // текущее имя входного устройства (TX mic)
// Отправка RX-аудио в трансивер (встроенный динамик радио, DDC Audio port 1028).
// Само накопление/конвертация живёт в THPSDRNetwork.SendSpeakerAudio.
FSendAudioToRadio: Boolean;
FTXSettings: TTXSettings; // полный TX-конфиг (загружается per-MAC)
FAlexSettings: TAlexSettings; // per-band antenna/routing config (Alex board)
FXvtrSettings: TXvtrSettings; // transverter slots (per-device)
@@ -724,6 +727,7 @@ type
procedure ApplyAudioDevice(DevIndex: Integer; const DevName: string);
procedure ApplyAudioInputDevice(DevIndex: Integer; const DevName: string);
procedure ApplyAudioBufferSize(BufferSize: Integer);
procedure ApplySendAudioToRadio(Enabled: Boolean);
// TX settings: применить FTXSettings к WDSP и переслать DUC Specific
// (mic-биты Boost/Bias/LineIn/PTT попадают в byte 50 DUCSpecific).
procedure ApplyTXSettingsToDSP;
@@ -961,6 +965,7 @@ begin
// Audio device names
Result.AudioOutDevice := FAudioOutDevName;
Result.AudioInDevice := FAudioInDevName;
Result.SendAudioToRadio := FSendAudioToRadio;
// CAT settings — carried from the last loaded/saved device config
Result.CATSerialEnabled := FCATLastGlobal.CATSerialEnabled;
Result.CATSerialPort := FCATLastGlobal.CATSerialPort;
@@ -4091,6 +4096,7 @@ begin
FWfNFEnabled := G_Settings.WfNFEnabled;
FDitherEnabled := G_Settings.DitherEnabled;
FRandomEnabled := G_Settings.RandomEnabled;
FSendAudioToRadio := G_Settings.SendAudioToRadio;
FWfManualHigh := G_Settings.WfManualHigh;
FWfManualLow := G_Settings.WfManualLow;
FWfAGCOffset := G_Settings.WfAGCOffset;
@@ -4239,6 +4245,8 @@ begin
// DDC и DUC Specific — теперь потоки эмулятора слушают на своих портах.
// DUC Specific содержит mic-конфигурацию (boost/bias/line/PTT) из FTXSettings.
FNetwork.ConfigureDDCs(1, FSampleRate div 1000, 0, FDitherEnabled, FRandomEnabled);
// Применяем сохранённое состояние динамика/отправки аудио (мьют byte 1400 bit1).
FNetwork.SetSpeakerAudio(FSendAudioToRadio);
SendDUCSpecificFromSettings;
// Применяем TX-цепь (фильтр, mic gain, EQ, leveler, ALC, comp, ...).
ApplyTXSettingsToDSP;
@@ -7366,6 +7374,9 @@ var
MonoBuf: array[0..1023] of Single;
i: Integer;
begin
// Дублируем RX-аудио во встроенный динамик трансивера (DDC Audio, port 1028).
if FSendAudioToRadio then
FNetwork.SendSpeakerAudio(Left, Right, Count);
if Assigned(FWebServer) and FWebServer.WebClientActive then
begin
for i := 0 to Count - 1 do
@@ -7513,6 +7524,16 @@ begin
FSettings.Save;
end;
procedure TMainForm.ApplySendAudioToRadio(Enabled: Boolean);
begin
FSendAudioToRadio := Enabled;
// Один переключатель: вкл = слать поток + снять мьют динамика,
// выкл = замьютить динамик (byte 1400 bit1) и не слать поток.
FNetwork.SetSpeakerAudio(Enabled);
if FDevConnected then
FSettings.SaveGlobal(FDevMAC, MakeGlobalSettings);
end;
procedure TMainForm.ApplyVisibility(ShowSpectrum, ShowWaterfall,
ShowWideband, WidebandFill, SpectrumFill: Boolean);
begin
@@ -7577,6 +7598,7 @@ begin
SF.OnAudioDevChange := ApplyAudioDevice;
SF.OnAudioInDevChange := ApplyAudioInputDevice;
SF.OnAudioBufferChange := ApplyAudioBufferSize;
SF.OnSendAudioToRadioChange := ApplySendAudioToRadio;
SF.OnVisibilityChange := ApplyVisibility;
SF.OnFPSChange := ApplyFPS;
SF.OnPAChange := OnPASettingsChange;
@@ -7619,6 +7641,7 @@ begin
SF.LoadLightTheme(FLightTheme);
SF.LoadFreqMhzDigits(FFreqMhzDigits);
SF.LoadAudioBufferSize(FAudioOut.OutputBufferSize);
SF.LoadSendAudioToRadio(FSendAudioToRadio);
// Загружаем текущие значения
if FWDSPReady then
SF.LoadValues(