mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
feat(fm): add universal FM RAW decoder output
This commit is contained in:
@@ -57,6 +57,9 @@ type
|
||||
FLastAGCHangY: Integer;
|
||||
FLastMarkerText: string;
|
||||
FLastMarkerX: Integer;
|
||||
// 2TON/IMD: текстуры подписей маркеров (0..3 = кружки, 4 = сводка IMD3)
|
||||
FIMDLabelTex: array[0..4] of TGLTextureCache;
|
||||
FIMDLastText: array[0..4] of string;
|
||||
FLastADCVisible: Boolean;
|
||||
FLastSampleX: Integer;
|
||||
FLastSampleY: Integer;
|
||||
@@ -90,6 +93,8 @@ type
|
||||
procedure DrawSpectrumCurve(W, H: Integer; DBmax, InvRange: Double);
|
||||
procedure DrawMarker(W, H: Integer);
|
||||
procedure DrawBeaconMarkersGL(W, H: Integer);
|
||||
procedure DrawCircleGL(CX, CY: Integer; R: Single; C: TColor);
|
||||
procedure DrawIMDMarkersGL(W, H: Integer; DBmax, InvRange: Double);
|
||||
procedure DrawADCOverlay(W, H: Integer);
|
||||
procedure DrawCachedOverlays(W, H: Integer);
|
||||
procedure DrawSliceOverlays(W, H: Integer);
|
||||
@@ -170,6 +175,7 @@ begin
|
||||
DeleteTexture(FBandOverlayTex);
|
||||
for i := 0 to High(FSliceTex) do DeleteTexture(FSliceTex[i].Tex);
|
||||
for i := 0 to High(FLetterTex) do DeleteTexture(FLetterTex[i]);
|
||||
for i := 0 to High(FIMDLabelTex) do DeleteTexture(FIMDLabelTex[i]);
|
||||
end;
|
||||
SetLength(FSliceTex, 0);
|
||||
inherited Destroy;
|
||||
@@ -451,6 +457,11 @@ begin
|
||||
Zap(FBandOverlayTex);
|
||||
for i := 0 to High(FSliceTex) do Zap(FSliceTex[i].Tex);
|
||||
for i := 0 to High(FLetterTex) do Zap(FLetterTex[i]);
|
||||
for i := 0 to High(FIMDLabelTex) do
|
||||
begin
|
||||
Zap(FIMDLabelTex[i]);
|
||||
FIMDLastText[i] := '';
|
||||
end;
|
||||
FLastAGCText := '';
|
||||
FLastMarkerText := '';
|
||||
FGridDirty := True;
|
||||
@@ -803,6 +814,71 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSpectrumViewOpenGL.DrawCircleGL(CX, CY: Integer; R: Single; C: TColor);
|
||||
// Залитый кружок (triangle fan, 20 сегментов) — маркер пика 2TON/IMD.
|
||||
var
|
||||
CR, CG, CB: GLFloat;
|
||||
a: Integer;
|
||||
Ang: Single;
|
||||
begin
|
||||
ColorToRGB(C, CR, CG, CB);
|
||||
glColor4f(CR, CG, CB, 1);
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex2f(CX + 0.5, CY + 0.5);
|
||||
for a := 0 to 20 do
|
||||
begin
|
||||
Ang := a * 2 * Pi / 20;
|
||||
glVertex2f(CX + 0.5 + R * Cos(Ang), CY + 0.5 + R * Sin(Ang));
|
||||
end;
|
||||
glEnd;
|
||||
end;
|
||||
|
||||
procedure TSpectrumViewOpenGL.DrawIMDMarkersGL(W, H: Integer;
|
||||
DBmax, InvRange: Double);
|
||||
// GL-вариант DrawIMDMarkersRaw: замер общий (ComputeIMDMarkers), подписи —
|
||||
// текстуры с кэшем по строке (перезаливка только при смене значения).
|
||||
const
|
||||
CLR_TONE = TColor($0050FF50); // зелёный — основные тона
|
||||
CLR_IMD = TColor($000A8CFF); // оранжевый — продукты IMD3
|
||||
var
|
||||
M: array[0..3] of TIMDMarker;
|
||||
N, i, X, Y, TX, TY: Integer;
|
||||
Col: TColor;
|
||||
begin
|
||||
if FSpanHz <= 0 then Exit;
|
||||
N := ComputeIMDMarkers(M);
|
||||
if N = 0 then Exit;
|
||||
for i := 0 to N - 1 do
|
||||
begin
|
||||
if M[i].LevelDB < -500 then Continue; // частота вне окна буфера
|
||||
X := Round((M[i].FreqHz - (FCenterFreq - FSpanHz / 2)) / FSpanHz * W);
|
||||
if (X < 0) or (X >= W) then Continue;
|
||||
Y := Max(0, Min(H - 1, Round((DBmax - M[i].LevelDB) * InvRange * H)));
|
||||
if M[i].IsTone then Col := CLR_TONE else Col := CLR_IMD;
|
||||
DrawCircleGL(X, Y, 4.0, Col);
|
||||
if (M[i].Caption <> FIMDLastText[i]) or FIMDLabelTex[i].Dirty then
|
||||
begin
|
||||
UploadText(FIMDLabelTex[i], M[i].Caption, Col, 7, True);
|
||||
FIMDLastText[i] := M[i].Caption;
|
||||
end;
|
||||
TY := Y - 14;
|
||||
if TY < 2 then TY := Y + 6;
|
||||
TX := X + 6;
|
||||
if TX + FIMDLabelTex[i].W >= W then TX := X - 6 - FIMDLabelTex[i].W;
|
||||
DrawTexture(FIMDLabelTex[i], TX, TY);
|
||||
end;
|
||||
// Сводка в левом верхнем углу
|
||||
if FIMDSummary <> '' then
|
||||
begin
|
||||
if (FIMDSummary <> FIMDLastText[4]) or FIMDLabelTex[4].Dirty then
|
||||
begin
|
||||
UploadText(FIMDLabelTex[4], FIMDSummary, CLR_IMD, 9, True);
|
||||
FIMDLastText[4] := FIMDSummary;
|
||||
end;
|
||||
DrawTexture(FIMDLabelTex[4], 6, 6);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSpectrumViewOpenGL.DrawADCOverlay(W, H: Integer);
|
||||
var
|
||||
B: TBitmap;
|
||||
@@ -1016,6 +1092,9 @@ begin
|
||||
DrawSpectrumCurve(W, H, DBmax, InvRange);
|
||||
DrawMarker(W, H);
|
||||
if FBeaconMarkActive or FBeaconDecActive then DrawBeaconMarkersGL(W, H);
|
||||
// 2TON: кружки с уровнями на пиках тонов/IMD3 (активирует MainForm при
|
||||
// 2TON+TX+DUP — реальный сигнал после PA виден на RX-спектре)
|
||||
if FIMDActive then DrawIMDMarkersGL(W, H, DBmax, InvRange);
|
||||
DrawADCOverlay(W, H);
|
||||
DrawCachedOverlays(W, H);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user