Heatmap spectral view (#423)

This commit is contained in:
Tim Wilkinson 2022-07-01 15:53:18 +01:00 committed by GitHub
parent 4e6b68c612
commit 82b0cb5903
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 68 additions and 43 deletions

View File

@ -292,7 +292,7 @@ elseif rfband == "3400" then
html.print("const freq2chan = (f) => (f - 5000) / 5;"); html.print("const freq2chan = (f) => (f - 5000) / 5;");
else else
start_freq = 5650 start_freq = 5650
end_freq = 5925 end_freq = 5920
html.print("const freq2chan = (f) => (f - 5000) / 5;"); html.print("const freq2chan = (f) => (f - 5000) / 5;");
end end
local bw local bw
@ -304,12 +304,22 @@ do
end end
end end
bw = tonumber(bw) or 10 bw = tonumber(bw) or 10
if bw == 10 then
cnf = cnf - 3
elseif bw == 5 then
cnf = cnf - 6
end
local fbuckets = {}
for freq = 1, (end_freq - start_freq + bw) * 56 / bw
do
fbuckets[math.floor(freq)] = {}
end
local xscale = cwidth / (end_freq - start_freq) local xscale = cwidth / (end_freq - start_freq)
local min_sig = cnf local min_sig = -125
local max_sig = -60 local max_sig = -60
local i = 1 local i = 1
html.write("const p = [")
while i < #samples while i < #samples
do do
local t = samples:byte(i) local t = samples:byte(i)
@ -334,15 +344,13 @@ do
local datasq = v[dptr] local datasq = v[dptr]
if datasq ~= 0 then if datasq ~= 0 then
local sig = noise + rssi + 10 * math.log10(datasq / datasqsum) local sig = noise + rssi + 10 * math.log10(datasq / datasqsum)
local fr = freq + bw * (dptr / 56 - 0.5) - start_freq if sig >= min_sig then
if sig >= -125 then
if sig < min_sig then
min_sig = sig
end
if sig > max_sig then if sig > max_sig then
max_sig = sig max_sig = sig
end end
html.write(math.floor(fr * xscale) .. "," .. math.floor(-sig * 4) .. ",") local bidx = math.floor((freq - start_freq) / bw * 56 + dptr - 28)
local bucket = fbuckets[bidx]
bucket[#bucket + 1] = math.floor((sig - min_sig) * 4)
end end
end end
end end
@ -350,41 +358,64 @@ do
end end
i = i + 3 + l i = i + 3 + l
end end
html.print("-1,-1];");
local max_fsize = 0
for _, b in ipairs(fbuckets)
do
table.sort(b)
if #b > max_fsize then
max_fsize = #b
end
end
html.print("const n = null;")
html.write("const p=[")
local sizes = { 0.20, 0.30, 0.40, 0.50, 0.60 }
for _, b in ipairs(fbuckets)
do
local len = #b
local last = 0
for _, size in ipairs(sizes)
do
local max = math.floor(size * max_fsize)
if len >= max then
html.write((b[max] - last) .. ",")
last = b[max]
end
end
if len > 0 and b[#b] ~= last then
html.write((b[#b] - last) .. ",")
end
html.write("n,")
end
html.print("-1];")
html.print("const yscale = " .. (-cheight / (max_sig - min_sig) / 4) .. ";") html.print("const yscale = " .. (-cheight / (max_sig - min_sig) / 4) .. ";")
html.print("const ytran = " .. (-max_sig * 4) .. ";")
html.print([[ html.print([[
const img = ctx.createImageData(]] .. cwidth .. [[,]] .. cheight ..[[); const bcolors = [ "red", "yellow", "green", "cyan", "blue", "purple" ];
const d = img.data; let xcursor = 0;
for (let i = 0; i < p.length; i += 2) { let ycursor = 0;
const sig = p[i+1]; let ccursor = 0;
const idx = 4 * (p[i] + ]] .. cwidth .. [[ * Math.floor(yscale * (ytran - sig))); for (let i = 0; i < p.length; i++) {
if (sig < ]] .. (-4 * cnf) .. [[) { let v = p[i];
d[idx] = 0; if (v === null) {
d[idx+1] = 0; xcursor += ]] .. (xscale * bw / 56) .. [[;
d[idx+2] = 255; ycursor = 0;
d[idx+4] = 0; ccursor = 0;
d[idx+5] = 0;
d[idx+6] = 255;
} }
else { else {
d[idx] = 128; v *= yscale;
d[idx+1] = 128; ycursor += v;
d[idx+2] = 128; ctx.fillStyle = bcolors[ccursor];
d[idx+4] = 128; ctx.fillRect(xcursor, ]] .. cheight .. [[ + ycursor, ]] .. (xscale * bw / 56) .. [[, -v);
d[idx+5] = 128; ccursor++;
d[idx+6] = 128;
} }
d[idx+3] = 255;
d[idx+7] = 255;
} }
ctx.putImageData(img, 0, 0); ctx.strokeStyle = "rgba(0,0,0,0.5)";
ctx.strokeStyle = "lightgrey";
ctx.fillStyle = "black"; ctx.fillStyle = "black";
ctx.font = "12px Arial"; ctx.font = "bold 12px Arial";
ctx.textAlign = "center"; ctx.textAlign = "center";
ctx.beginPath() ctx.beginPath()
for (let f = ]] .. start_freq .. [[; f < ]] .. end_freq .. [[; f += 10) { for (let f = ]] .. start_freq .. [[; f <= ]] .. end_freq .. [[; f += 10) {
const x = Math.floor((f - ]] .. start_freq .. [[) * ]] .. xscale .. [[); const x = Math.floor((f - ]] .. start_freq .. [[) * ]] .. xscale .. [[);
ctx.moveTo(x, 0); ctx.moveTo(x, 0);
ctx.lineTo(x, ]] .. (cheight - 20) .. [[); ctx.lineTo(x, ]] .. (cheight - 20) .. [[);
@ -392,21 +423,15 @@ html.print([[
} }
ctx.stroke(); ctx.stroke();
ctx.textAlign = "left"; ctx.textAlign = "left";
ctx.strokeStyle = "lightblue"; ctx.strokeStyle = "rgba(0,0,0,0.5)";
ctx.beginPath(); ctx.beginPath();
for (let snr = 60; snr >= 0; snr -= 10) { for (let snr = 60; snr >= 0; snr -= 10) {
const y = Math.floor(yscale * (ytran + ]] .. (cnf * 4) .. [[ + snr * 4)); const y = ]] .. cheight .. [[ + yscale * (snr - ]] .. (min_sig - cnf) .. [[) * 4;
ctx.moveTo(20, y); ctx.moveTo(20, y);
ctx.lineTo(]] .. cwidth .. [[, y); ctx.lineTo(]] .. cwidth .. [[, y);
ctx.fillText("" + snr, 2, y); ctx.fillText("" + snr, 2, y);
} }
ctx.stroke(); ctx.stroke();
ctx.strokeStyle = "blue";
ctx.beginPath();
const y = Math.floor(yscale * (]] .. (cnf * 4) .. [[ + ytran));
ctx.moveTo(30, y);
ctx.lineTo(]] .. cwidth .. [[, y);
ctx.stroke();
</script></form> </script></form>
]]) ]])