mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
feat(dmr): decode and route AMBE voice
This commit is contained in:
+42
-1
@@ -405,6 +405,7 @@ type
|
||||
// вызывающим (GUI или демон) после CreateEngines.
|
||||
procedure OnAudioReady(const Left, Right: array of Single; Count: Integer);
|
||||
procedure OnDemodAudioReady(const Left, Right: array of Single; Count: Integer);
|
||||
procedure OnDMRAudioReady(const PCM: array of Single; Count: Integer);
|
||||
procedure OnSpectrumReady(const Pixels: array of Single; Count: Integer);
|
||||
procedure OnWaterfallReady(const Pixels: array of Single; Count: Integer);
|
||||
procedure OnMicPacket(const Data: TMicDataPacket);
|
||||
@@ -851,6 +852,7 @@ begin
|
||||
|
||||
// DMR front-end owns a worker thread. It stays idle until MODE_DMR is active.
|
||||
FDMRDec := TDMRDecoder.Create;
|
||||
FDMRDec.OnAudio := OnDMRAudioReady;
|
||||
|
||||
// Audio out/in — объекты создаём сейчас, Open вызывается позже (после показа
|
||||
// формы / при подключении устройства).
|
||||
@@ -862,6 +864,13 @@ end;
|
||||
procedure TRadioController.FreeEngines;
|
||||
var i: Integer;
|
||||
begin
|
||||
// Stop the DMR worker before destroying any of its audio destinations.
|
||||
if Assigned(FDMRDec) then
|
||||
begin
|
||||
FDMRDec.SetEnabled(False);
|
||||
FDMRDec.OnAudio := nil;
|
||||
FreeAndNil(FDMRDec);
|
||||
end;
|
||||
if Assigned(FNetwork) then
|
||||
begin
|
||||
if FNetwork.Connected then FNetwork.Disconnect;
|
||||
@@ -883,7 +892,6 @@ begin
|
||||
FDSPEngine.Close;
|
||||
FreeAndNil(FDSPEngine);
|
||||
end;
|
||||
if Assigned(FDMRDec) then FreeAndNil(FDMRDec);
|
||||
if Assigned(FBeaconDec) then FreeAndNil(FBeaconDec);
|
||||
end;
|
||||
|
||||
@@ -1186,6 +1194,39 @@ begin
|
||||
FDMRDec.SetEnabled(False);
|
||||
end;
|
||||
|
||||
procedure TRadioController.OnDMRAudioReady(const PCM: array of Single;
|
||||
Count: Integer);
|
||||
// DMR worker thread, 8 kHz mono from mbelib. Linear 6x interpolation brings
|
||||
// it to the common 48 kHz output route used by local, web and radio speakers.
|
||||
var
|
||||
Left, Right: array of Single;
|
||||
i, Phase, OutPos, N: Integer;
|
||||
A, B, V, Gain: Single;
|
||||
begin
|
||||
if (FMode <> MODE_DMR) or FMuted or (Count <= 0) then Exit;
|
||||
N := Min(Count, Length(PCM));
|
||||
SetLength(Left, N * 6);
|
||||
SetLength(Right, N * 6);
|
||||
Gain := FVolume / 100.0;
|
||||
OutPos := 0;
|
||||
for i := 0 to N - 1 do
|
||||
begin
|
||||
A := PCM[i];
|
||||
if i + 1 < N then B := PCM[i + 1] else B := A;
|
||||
for Phase := 0 to 5 do
|
||||
begin
|
||||
V := (A + (B - A) * (Phase / 6.0)) * Gain;
|
||||
Left[OutPos] := V;
|
||||
Right[OutPos] := V;
|
||||
Inc(OutPos);
|
||||
end;
|
||||
end;
|
||||
if FSendAudioToRadio and Assigned(FNetwork) then
|
||||
FNetwork.SendSpeakerAudio(Left, Right, OutPos);
|
||||
if Assigned(FOnAudioConsume) and FOnAudioConsume(Left, Right, OutPos) then Exit;
|
||||
if FLocalAudio and Assigned(FAudioOut) then FAudioOut.Write(Left, Right, OutPos);
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Мультислайсы (софт-fan-out)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user