mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
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:
co-authored by
Claude Opus 4.8
parent
d8584323ac
commit
aff17aa3a6
@@ -112,6 +112,15 @@ type
|
||||
FSeqAudio: LongWord;
|
||||
FSeqDUCIQ: LongWord;
|
||||
|
||||
// Накопитель RX-аудио для встроенного динамика радио: DDC Audio пакет несёт
|
||||
// ровно 64 L/R пары (128 SmallInt). Копим интерливом между вызовами, чтобы
|
||||
// не вставлять тишину при некратном размере буфера WDSP.
|
||||
FSpeakerBuf: array[0..127] of SmallInt;
|
||||
FSpeakerCount: Integer;
|
||||
// True = поток аудио шлётся И динамик радио включён (byte 1400 bit1 = 0);
|
||||
// False = мьют динамика (bit1 = 1) и поток не накапливается.
|
||||
FSpeakerAudioEnabled: Boolean;
|
||||
|
||||
FReceiveThread: TThread;
|
||||
FKeepaliveThread: TThread;
|
||||
FDUCIQThread: TThread;
|
||||
@@ -233,6 +242,13 @@ type
|
||||
// Не меняет FIsTransmitting — вызывать после UpdateState+SendFullHP.
|
||||
procedure SendPTT(Active: Boolean);
|
||||
procedure SendDDCAudio(const LeftRight: array of SmallInt);
|
||||
// Принимает RX-аудио (float [-1..1]) из DSP, конвертирует в 16-bit и
|
||||
// отправляет на радио пакетами по 64 L/R пары. Хвост копится между вызовами.
|
||||
procedure SendSpeakerAudio(const Left, Right: array of Single; Count: Integer);
|
||||
// Единый переключатель встроенного динамика: True = слать аудио и снять мьют,
|
||||
// False = замьютить динамик (byte 1400 bit1) и не накапливать поток.
|
||||
// Применяется немедленно (шлёт HP-пакет, если подключены).
|
||||
procedure SetSpeakerAudio(AEnabled: Boolean);
|
||||
procedure SendDUCIQ(const IData, QData: array of Integer);
|
||||
procedure ClearDUCIQQueue;
|
||||
|
||||
@@ -1562,6 +1578,12 @@ begin
|
||||
Buf[1400] := Buf[1400] or $01;
|
||||
end;
|
||||
|
||||
// Audio mute (byte 1400 bit 1) — ANAN-8000DLE: IO1 output, 0=audio enabled,
|
||||
// 1=mute. Когда отправка аудио в радио выключена, держим динамик в мьюте.
|
||||
// На прочих платах бит «not assigned» и игнорируется.
|
||||
if not FSpeakerAudioEnabled then
|
||||
Buf[1400] := Buf[1400] or $02;
|
||||
|
||||
// Step attenuators ADC0/ADC1 (bytes 1443/1442)
|
||||
// 0 dB = 0, max 31 dB
|
||||
Buf[1443] := FStepAtten; // ADC0 attenuation
|
||||
@@ -1610,6 +1632,44 @@ begin
|
||||
DoSendTo(FSocket, Pkt, SizeOf(Pkt), FDevice.IPAddress, FPortDDCAudio);
|
||||
end;
|
||||
|
||||
procedure THPSDRNetwork.SetSpeakerAudio(AEnabled: Boolean);
|
||||
begin
|
||||
FSpeakerAudioEnabled := AEnabled;
|
||||
if not AEnabled then FSpeakerCount := 0; // сброс накопленного хвоста
|
||||
if FConnected then SendFullHP; // применить мьют (byte 1400 bit1)
|
||||
end;
|
||||
|
||||
procedure THPSDRNetwork.SendSpeakerAudio(const Left, Right: array of Single;
|
||||
Count: Integer);
|
||||
|
||||
function ToS16(V: Single): SmallInt;
|
||||
begin
|
||||
if V > 1.0 then V := 1.0
|
||||
else if V < -1.0 then V := -1.0;
|
||||
Result := SmallInt(Round(V * 32767.0));
|
||||
end;
|
||||
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
if not (FSpeakerAudioEnabled and FConnected and FRunning) then
|
||||
begin
|
||||
FSpeakerCount := 0;
|
||||
Exit;
|
||||
end;
|
||||
for i := 0 to Count - 1 do
|
||||
begin
|
||||
FSpeakerBuf[FSpeakerCount] := ToS16(Left[i]);
|
||||
FSpeakerBuf[FSpeakerCount + 1] := ToS16(Right[i]);
|
||||
Inc(FSpeakerCount, 2);
|
||||
if FSpeakerCount >= Length(FSpeakerBuf) then
|
||||
begin
|
||||
SendDDCAudio(FSpeakerBuf);
|
||||
FSpeakerCount := 0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THPSDRNetwork.SendDUCIQ(const IData, QData: array of Integer);
|
||||
var
|
||||
Pkt: TDUCIQPacket;
|
||||
|
||||
Reference in New Issue
Block a user