mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 19:45:09 +00:00
Render wideband spectrum with OpenGL primitives
This commit is contained in:
+142
-28
@@ -30,6 +30,7 @@ type
|
||||
FPoints: array of TPoint;
|
||||
FGLTex: GLuint;
|
||||
FDirty: Boolean;
|
||||
FGLBackgroundDirty: Boolean;
|
||||
FSampleRateHz: Double;
|
||||
FRefLevel: Double;
|
||||
FRange: Double;
|
||||
@@ -51,10 +52,14 @@ type
|
||||
function ComputeSpectrumWDSP(const Samples: array of SmallInt;
|
||||
Count: Integer): Boolean;
|
||||
procedure CloseWDSPAnalyzer;
|
||||
procedure DrawCPU(W, H: Integer);
|
||||
function BuildSpectrumPoints(PlotW, H: Integer): Boolean;
|
||||
procedure DrawCPU(W, H: Integer; IncludeSpectrum: Boolean = True);
|
||||
procedure PaintCPU(C: TCanvas);
|
||||
procedure PaintGL(C: TOpenGLControl);
|
||||
procedure ColorToGL(AColor: TColor; out R, G, B: GLFloat);
|
||||
procedure DrawSpectrumGL(PlotW, H: Integer);
|
||||
procedure DrawHamBandGL(PlotW, H: Integer; F1, F2: Double; AColor: TColor);
|
||||
procedure DrawHamBandsGL(PlotW, H: Integer);
|
||||
function SourceFreqToBin(FreqHz: Double; BinCount: Integer): Integer;
|
||||
function FreqToX(FreqHz: Double; W: Integer): Integer;
|
||||
function GridStepHz(W: Integer): Double;
|
||||
@@ -123,6 +128,7 @@ begin
|
||||
SetLength(FWDSPPixels, WB_WDSP_PIXELS);
|
||||
FGLTex := 0;
|
||||
FDirty := True;
|
||||
FGLBackgroundDirty := True;
|
||||
end;
|
||||
|
||||
destructor TWidebandView.Destroy;
|
||||
@@ -139,6 +145,7 @@ procedure TWidebandView.SetTheme(const T: TAppTheme);
|
||||
begin
|
||||
FTheme := T;
|
||||
FDirty := True;
|
||||
FGLBackgroundDirty := True;
|
||||
end;
|
||||
|
||||
procedure TWidebandView.SetSampleRateHz(AHz: Double);
|
||||
@@ -180,6 +187,7 @@ begin
|
||||
FSourceStartHz := SourceStartHz;
|
||||
FSourceEndHz := SourceEndHz;
|
||||
FDirty := True;
|
||||
FGLBackgroundDirty := True;
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
@@ -218,7 +226,10 @@ begin
|
||||
W := Max(1, W);
|
||||
H := Max(1, H);
|
||||
if (FBitmap.Width <> W) or (FBitmap.Height <> H) then
|
||||
begin
|
||||
FBitmap.SetSize(W, H);
|
||||
FGLBackgroundDirty := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TWidebandView.SetBitmapSize(W, H: Integer);
|
||||
@@ -560,11 +571,42 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TWidebandView.DrawCPU(W, H: Integer);
|
||||
function TWidebandView.BuildSpectrumPoints(PlotW, H: Integer): Boolean;
|
||||
var
|
||||
X, Y, Bin, N, TopH: Integer;
|
||||
DB, InvRange, SrcHz, Nyq: Double;
|
||||
begin
|
||||
Result := False;
|
||||
N := Length(FData);
|
||||
if (N <= 1) or (PlotW <= 0) or (H <= 0) then Exit;
|
||||
TopH := Max(1, H - 1);
|
||||
InvRange := 1.0 / Max(1.0, FRange);
|
||||
SetLength(FPoints, PlotW);
|
||||
Nyq := FSampleRateHz * 0.5;
|
||||
if Nyq <= 0.0 then Nyq := 61440000.0;
|
||||
for X := 0 to PlotW - 1 do
|
||||
begin
|
||||
SrcHz := FSourceStartHz +
|
||||
X / Max(1, PlotW - 1) * (FSourceEndHz - FSourceStartHz);
|
||||
if (SrcHz < 0.0) or (SrcHz > Nyq) then
|
||||
DB := -200.0
|
||||
else
|
||||
begin
|
||||
Bin := SourceFreqToBin(SrcHz, N);
|
||||
DB := FData[Bin];
|
||||
end;
|
||||
Y := Round((FRefLevel - DB) * InvRange * TopH);
|
||||
Y := EnsureRange(Y, 1, TopH);
|
||||
FPoints[X] := Point(X, Y);
|
||||
end;
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TWidebandView.DrawCPU(W, H: Integer; IncludeSpectrum: Boolean);
|
||||
var
|
||||
C: TCanvas;
|
||||
X, Y, Bin, N, TopH, PlotW, ScaleX: Integer;
|
||||
DB, DBMin, InvRange, StepHz, FreqHz, SrcHz, Nyq: Double;
|
||||
X, Y, TopH, PlotW, ScaleX: Integer;
|
||||
DB, DBMin, InvRange, StepHz, FreqHz: Double;
|
||||
begin
|
||||
EnsureBitmap(W, H);
|
||||
C := FBitmap.Canvas;
|
||||
@@ -614,27 +656,8 @@ begin
|
||||
DB := DB - 20.0;
|
||||
end;
|
||||
|
||||
N := Length(FData);
|
||||
if N > 1 then
|
||||
if IncludeSpectrum and BuildSpectrumPoints(PlotW, H) then
|
||||
begin
|
||||
SetLength(FPoints, PlotW);
|
||||
Nyq := FSampleRateHz * 0.5;
|
||||
if Nyq <= 0.0 then Nyq := 61440000.0;
|
||||
for X := 0 to PlotW - 1 do
|
||||
begin
|
||||
SrcHz := FSourceStartHz +
|
||||
X / Max(1, PlotW - 1) * (FSourceEndHz - FSourceStartHz);
|
||||
if (SrcHz < 0.0) or (SrcHz > Nyq) then
|
||||
DB := -200.0
|
||||
else
|
||||
begin
|
||||
Bin := SourceFreqToBin(SrcHz, N);
|
||||
DB := FData[Bin];
|
||||
end;
|
||||
Y := Round((FRefLevel - DB) * InvRange * TopH);
|
||||
Y := EnsureRange(Y, 1, TopH);
|
||||
FPoints[X] := Point(X, Y);
|
||||
end;
|
||||
if FFillSpectrum then
|
||||
DrawSpectrumGradient(FPoints, PlotW, H);
|
||||
C.Pen.Color := TColor($0040FF80);
|
||||
@@ -645,7 +668,10 @@ begin
|
||||
|
||||
C.Font.Color := FTheme.Text;
|
||||
C.TextOut(6, 4, 'Wideband');
|
||||
FDirty := False;
|
||||
if IncludeSpectrum then
|
||||
FDirty := False
|
||||
else
|
||||
FGLBackgroundDirty := False;
|
||||
end;
|
||||
|
||||
procedure TWidebandView.DrawRuler;
|
||||
@@ -716,6 +742,90 @@ begin
|
||||
B := ((AColor shr 16) and $FF) / 255.0;
|
||||
end;
|
||||
|
||||
procedure TWidebandView.DrawSpectrumGL(PlotW, H: Integer);
|
||||
var
|
||||
I: Integer;
|
||||
R, G, B: GLFloat;
|
||||
ATop, ABot: GLFloat;
|
||||
begin
|
||||
if not BuildSpectrumPoints(PlotW, H) then Exit;
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
if FFillSpectrum then
|
||||
begin
|
||||
R := FTheme.SpecGradR / 255.0;
|
||||
G := FTheme.SpecGradG / 255.0;
|
||||
B := FTheme.SpecGradB / 255.0;
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
for I := 0 to PlotW - 1 do
|
||||
begin
|
||||
ATop := 0.44;
|
||||
ABot := 0.02;
|
||||
glColor4f(R, G, B, ATop);
|
||||
glVertex2f(FPoints[I].X, H - FPoints[I].Y);
|
||||
glColor4f(R, G, B, ABot);
|
||||
glVertex2f(FPoints[I].X, 0);
|
||||
end;
|
||||
glEnd;
|
||||
end;
|
||||
|
||||
glColor4f(0.25, 1.0, 0.50, 1.0);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for I := 0 to PlotW - 1 do
|
||||
glVertex2f(FPoints[I].X, H - FPoints[I].Y);
|
||||
glEnd;
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
end;
|
||||
|
||||
procedure TWidebandView.DrawHamBandGL(PlotW, H: Integer; F1, F2: Double;
|
||||
AColor: TColor);
|
||||
var
|
||||
X1, X2: Integer;
|
||||
R, G, B: GLFloat;
|
||||
begin
|
||||
X1 := FreqToX(F1, PlotW);
|
||||
X2 := FreqToX(F2, PlotW);
|
||||
if (X2 <= 0) or (X1 >= PlotW) then Exit;
|
||||
X1 := EnsureRange(X1, 0, PlotW - 1);
|
||||
X2 := EnsureRange(X2, 0, PlotW - 1);
|
||||
if X2 <= X1 then Exit;
|
||||
ColorToGL(AColor, R, G, B);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4f(R, G, B, 0.34);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(X1, 0);
|
||||
glVertex2f(X2 + 1, 0);
|
||||
glVertex2f(X2 + 1, H);
|
||||
glVertex2f(X1, H);
|
||||
glEnd;
|
||||
glColor4f(R, G, B, 0.46);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(X1, H - Min(H, 15));
|
||||
glVertex2f(X2 + 1, H - Min(H, 15));
|
||||
glVertex2f(X2 + 1, H);
|
||||
glVertex2f(X1, H);
|
||||
glEnd;
|
||||
glDisable(GL_BLEND);
|
||||
end;
|
||||
|
||||
procedure TWidebandView.DrawHamBandsGL(PlotW, H: Integer);
|
||||
begin
|
||||
DrawHamBandGL(PlotW, H, 1810000, 2000000, TColor($003B8F5A));
|
||||
DrawHamBandGL(PlotW, H, 3500000, 3800000, TColor($004D8F3B));
|
||||
DrawHamBandGL(PlotW, H, 5258500, 5403500, TColor($00688F3B));
|
||||
DrawHamBandGL(PlotW, H, 7000000, 7300000, TColor($00808D34));
|
||||
DrawHamBandGL(PlotW, H, 10100000, 10150000, TColor($008F7834));
|
||||
DrawHamBandGL(PlotW, H, 14000000, 14350000, TColor($008F5D34));
|
||||
DrawHamBandGL(PlotW, H, 18068000, 18168000, TColor($008F4934));
|
||||
DrawHamBandGL(PlotW, H, 21000000, 21450000, TColor($008C3E58));
|
||||
DrawHamBandGL(PlotW, H, 24890000, 24990000, TColor($007A3E8C));
|
||||
DrawHamBandGL(PlotW, H, 28000000, 29700000, TColor($005B4B9A));
|
||||
DrawHamBandGL(PlotW, H, 50000000, 51990000, TColor($003C729A));
|
||||
end;
|
||||
|
||||
procedure TWidebandView.UploadBitmapToGL;
|
||||
var
|
||||
X, Y, I: Integer;
|
||||
@@ -767,9 +877,9 @@ begin
|
||||
SetBitmapSize(W, H);
|
||||
NeedUpload := True;
|
||||
end;
|
||||
if FDirty then
|
||||
if FGLBackgroundDirty then
|
||||
begin
|
||||
DrawCPU(W, H);
|
||||
DrawCPU(W, H, False);
|
||||
NeedUpload := True;
|
||||
end;
|
||||
if FGLTex = 0 then
|
||||
@@ -797,9 +907,13 @@ begin
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
PlotW := Max(1, W - WB_DB_SCALE_W);
|
||||
DrawSpectrumGL(PlotW, H);
|
||||
DrawHamBandsGL(PlotW, H);
|
||||
FDirty := False;
|
||||
|
||||
if (FMarkerHz >= FViewStartHz) and (FMarkerHz <= FViewEndHz) then
|
||||
begin
|
||||
PlotW := Max(1, W - WB_DB_SCALE_W);
|
||||
X := EnsureRange(FreqToX(FMarkerHz, PlotW), 0, PlotW - 1);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
Reference in New Issue
Block a user