FFT modification

This commit is contained in:
F4HTB 2020-11-23 04:31:10 +00:00
parent d0bcde3304
commit 6c7fb6fba4
4 changed files with 73 additions and 42 deletions

43
UHRR
View File

@ -53,6 +53,17 @@ except:
AudioPanaHandlerClients = []
def to_byte_array(num):
bytea = []
n = num
while n:
bytea.append(n % 256)
n //= 256
n_bytes = len(bytea)
if 2 ** (n_bytes * 8 - 1) <= num < 2 ** (n_bytes * 8):
bytea.append(0)
return bytearray(bytea)
class loadFFTdata(threading.Thread):
def __init__(self):
@ -128,11 +139,10 @@ class loadFFTdata(threading.Thread):
samples = sdr.read_samples(nbsamples)
samples = np.imag(samples) + 1j * np.real(samples)
max_pow = 0
max_pow = -254
min_pow = 0
power = self.get_log_power_spectrum(samples)
power += 60
# search whole data set for maximum and minimum value
for dat in power:
@ -140,16 +150,21 @@ class loadFFTdata(threading.Thread):
max_pow = dat
elif dat < min_pow:
min_pow = dat
asciilist=""
for dat in power:
try:
asciilist+=(chr(self.FFTmymap(dat, min_pow, max_pow, 0, 125)))
except (RuntimeError, TypeError, NameError):
asciilist+=chr(0)
pass
for c in AudioPanaHandlerClients:
c.fftframes.append(asciilist)
byteslist=bytearray()
try:
for dat in power:
try:
byteslist.append(self.FFTmymap(dat, min_pow, max_pow, 0, 255))
except (RuntimeError, TypeError, NameError):
byteslist.append(255)
pass
byteslist+=bytearray((65280+int(min_pow)).to_bytes(2, byteorder="big"))
byteslist+=bytearray((65280+int(max_pow)).to_bytes(2, byteorder="big"))
for c in AudioPanaHandlerClients:
c.fftframes.append(bytes(byteslist))
except:
return None
def FFTmymap(self, x, in_min, in_max, out_min, out_max):
ret=int((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)
@ -164,9 +179,7 @@ class panFFTHandler(tornado.websocket.WebSocketHandler):
global ptime, fftpaquetlen
try:
while len(self.fftframes)>0:
for i in range(fftpaquetlen):
yield self.write_message(self.fftframes[0][i*256:(i+1)*256])
yield self.write_message("NewLine")
yield self.write_message(self.fftframes[0],binary=True)
del self.fftframes[0]
except:
return None

View File

@ -53,6 +53,7 @@ body {
padding:0px;
margin:0px;
left: 0%;
align-items: center; /* Vertical */
}
.ctrl_visual{

View File

@ -6,19 +6,25 @@
</head>
<body onload="bodyload();">
<div id="div-princ">
<div id="div-sp">
<canvas id="cansp" class="cansp" width=4096 height=256 "></canvas>
<canvas id="cansp" class="cansp" width="4096" height="256"></canvas>
</div>
<div id="div-wf">
<canvas id="canwf" class="canwf" width=4096 height=256 "></canvas>
<canvas id="canwf" class="canwf" width="4096" height="256"></canvas>
</div>
<div id="div-ctrl">
Center Frequency:<div class="ctrl_visual" id="div-CenterFrequency"></div>|
SampleRate:<div class="ctrl_visual" id="div-SampleRate"></div>|
FFT resolution:<div class="ctrl_visual" id="div-FFtResolution"></div>|
Mouse Frequency:<div class="ctrl_visual" id="div-mouseFrequency"></div>|
Windows Zoom:<div class="ctrl_visual" id="div-WindowsZoom">100%</div>|
Spectrogram dynamic: <input oninput="set_FFT_Viso_Dynamic(this.value);" onchange="set_FFT_Viso_Dynamic(this.value);" value="60" step="5" type="range" name="FFT_Viso_Dynamic" min="20" max="120">
Spectrogram min: <input oninput="set_FFT_Viso_min(this.value);" onchange="set_FFT_Viso_min(this.value);" value="-180" step="5" type="range" name="FFT_Viso_min" min="-200" max="30">
</div>
<div id="div-scoketscontrols"><img src="img/critsred.png">wsFFT</div>
</div>
<script src="panfft.js"></script>

View File

@ -9,6 +9,9 @@ var FFTSIZE = 4096;
var localcenterfrequency=0;
var freqmouse=0;
var FFT_Viso_Dynamic=50
var FFT_Viso_min=-180
const visual_CenterFrequency = document.getElementById("div-CenterFrequency");
const visual_SampleRate = document.getElementById("div-SampleRate");
@ -24,6 +27,10 @@ function bodyload(){
startFFT();
}
function set_FFT_Viso_Dynamic(v){FFT_Viso_Dynamic=v;}
function set_FFT_Viso_min(v){FFT_Viso_min=v;}
function startFFT(){
@ -66,14 +73,13 @@ var globmsg = "";
function init_showFFT( msg ){
datas = msg.data.split(':');
console.log(datas);
if(datas[0] == "fftsr"){
samplerate=datas[1];
}
else if(datas[0] == "fftsz"){
FFTSIZE=datas[1];
canvasSP.width=FFTSIZE;
canvasWF.width=FFTSIZE;
FFTSIZE=parseInt(datas[1]);
canvasSP.width=parseInt(FFTSIZE);
canvasWF.width=parseInt(FFTSIZE);
var canvas_width_SP=document.getElementById("cansp").width;
var canvas_height_SP=document.getElementById("cansp").height;
var canvas_width_WF=document.getElementById("canwf").width;
@ -84,37 +90,37 @@ function init_showFFT( msg ){
visual_FFtResolution.innerHTML=samplerate/FFTSIZE+"hz/px";
wshFFT.send("ready");
window.opener.ControlTRX_getFreq();
wshFFT.binaryType = 'arraybuffer';
wshFFT.onmessage = showFFT;
}
}
function showFFT( msg ){
if(msg.data != "NewLine"){globmsg += msg.data;}
else{
if(globmsg.length == canvas_width_WF){
let FFTdata = [];
FFTdata = globmsg.split('');
FFTdata.forEach((item, index) => { FFTdata[index]= (item.charCodeAt(0))<< 1; }) // FFTdata[index]= Math.round(item.charCodeAt(0))*2; })
SetImageDataWF(FFTdata);
SetImageDataSP(FFTdata);
}
globmsg="";
}
var buffer = new Uint8Array(msg.data);
let FFTdata = buffer.subarray(0, FFTSIZE);
FFTdata_scale_min = ((buffer[FFTSIZE] << 8) + (buffer[FFTSIZE+1]))-65280;
FFTdata_scale_max= ((buffer[FFTSIZE+2] << 8) + (buffer[FFTSIZE+3]))-65280;
min_Factor=FFTdata_scale_min-FFT_Viso_min;
max_Factor=(FFTdata_scale_max-FFTdata_scale_min)/FFT_Viso_Dynamic;
SetImageDataWF(FFTdata,min_Factor,max_Factor);
SetImageDataSP(FFTdata,min_Factor,max_Factor);
}
const ctxSP = canvasSP.getContext("2d");// imgObjSP = ctxSP.createImageData(canvasSP.width, canvas_height);
const midle_SP = canvas_width_SP*2;
function SetImageDataSP(datas) {
function SetImageDataSP(datas,scale_min,scale_max) {
imgObjSP = new ImageData(canvasSP.width, canvas_height_SP);
let i = 0;
for(let Line = 0; Line < canvas_height_SP; Line++){
i = 4*(Line * canvas_width_SP);
y = canvas_height_SP - Line;
for (let px = 0; px < canvas_width_SP; px++) {
if(y <= datas[px]){
let dat = (datas[px]*scale_max + scale_min);
if(y <= dat){
//imgObjSP.data[i] = 0; // red
imgObjSP.data[++i] = 215; // green
imgObjSP.data[++i] = 233; // blue
@ -137,7 +143,7 @@ const ctxWF = canvasWF.getContext("2d"),imgObjWF = ctxWF.createImageData(canvasW
const colMap = [[0,0,127,255],[0,0,131,255],[0,0,135,255],[0,0,139,255],[0,0,143,255],[0,0,147,255],[0,0,151,255],[0,0,155,255],[0,0,159,255],[0,0,163,255],[0,0,167,255],[0,0,171,255],[0,0,175,255],[0,0,179,255],[0,0,183,255],[0,0,187,255],[0,0,191,255],[0,0,195,255],[0,0,199,255],[0,0,203,255],[0,0,207,255],[0,0,211,255],[0,0,215,255],[0,0,219,255],[0,0,223,255],[0,0,227,255],[0,0,231,255],[0,0,235,255],[0,0,239,255],[0,0,243,255],[0,0,247,255],[0,0,251,255],[0,0,255,255],[0,4,255,255],[0,8,255,255],[0,12,255,255],[0,16,255,255],[0,20,255,255],[0,24,255,255],[0,28,255,255],[0,32,255,255],[0,36,255,255],[0,40,255,255],[0,44,255,255],[0,48,255,255],[0,52,255,255],[0,56,255,255],[0,60,255,255],[0,64,255,255],[0,68,255,255],[0,72,255,255],[0,76,255,255],[0,80,255,255],[0,84,255,255],[0,88,255,255],[0,92,255,255],[0,96,255,255],[0,100,255,255],[0,104,255,255],[0,108,255,255],[0,112,255,255],[0,116,255,255],[0,120,255,255],[0,124,255,255],[0,128,255,255],[0,132,255,255],[0,136,255,255],[0,140,255,255],[0,144,255,255],[0,148,255,255],[0,152,255,255],[0,156,255,255],[0,160,255,255],[0,164,255,255],[0,168,255,255],[0,172,255,255],[0,176,255,255],[0,180,255,255],[0,184,255,255],[0,188,255,255],[0,192,255,255],[0,196,255,255],[0,200,255,255],[0,204,255,255],[0,208,255,255],[0,212,255,255],[0,216,255,255],[0,220,255,255],[0,224,255,255],[0,228,255,255],[0,232,255,255],[0,236,255,255],[0,240,255,255],[0,244,255,255],[0,248,255,255],[0,252,255,255],[1,255,253,255],[5,255,249,255],[9,255,245,255],[13,255,241,255],[17,255,237,255],[21,255,233,255],[25,255,229,255],[29,255,225,255],[33,255,221,255],[37,255,217,255],[41,255,213,255],[45,255,209,255],[49,255,205,255],[53,255,201,255],[57,255,197,255],[61,255,193,255],[65,255,189,255],[69,255,185,255],[73,255,181,255],[77,255,177,255],[81,255,173,255],[85,255,169,255],[89,255,165,255],[93,255,161,255],[97,255,157,255],[101,255,153,255],[105,255,149,255],[109,255,145,255],[113,255,141,255],[117,255,137,255],[121,255,133,255],[125,255,129,255],[129,255,125,255],[133,255,121,255],[137,255,117,255],[141,255,113,255],[145,255,109,255],[149,255,105,255],[153,255,101,255],[157,255,97,255],[161,255,93,255],[165,255,89,255],[169,255,85,255],[173,255,81,255],[177,255,77,255],[181,255,73,255],[185,255,69,255],[189,255,65,255],[193,255,61,255],[197,255,57,255],[201,255,53,255],[205,255,49,255],[209,255,45,255],[213,255,41,255],[217,255,37,255],[221,255,33,255],[225,255,29,255],[229,255,25,255],[233,255,21,255],[237,255,17,255],[241,255,13,255],[245,255,9,255],[249,255,5,255],[253,255,1,255],[255,252,0,255],[255,248,0,255],[255,244,0,255],[255,240,0,255],[255,236,0,255],[255,232,0,255],[255,228,0,255],[255,224,0,255],[255,220,0,255],[255,216,0,255],[255,212,0,255],[255,208,0,255],[255,204,0,255],[255,200,0,255],[255,196,0,255],[255,192,0,255],[255,188,0,255],[255,184,0,255],[255,180,0,255],[255,176,0,255],[255,172,0,255],[255,168,0,255],[255,164,0,255],[255,160,0,255],[255,156,0,255],[255,152,0,255],[255,148,0,255],[255,144,0,255],[255,140,0,255],[255,136,0,255],[255,132,0,255],[255,128,0,255],[255,124,0,255],[255,120,0,255],[255,116,0,255],[255,112,0,255],[255,108,0,255],[255,104,0,255],[255,100,0,255],[255,96,0,255],[255,92,0,255],[255,88,0,255],[255,84,0,255],[255,80,0,255],[255,76,0,255],[255,72,0,255],[255,68,0,255],[255,64,0,255],[255,60,0,255],[255,56,0,255],[255,52,0,255],[255,48,0,255],[255,44,0,255],[255,40,0,255],[255,36,0,255],[255,32,0,255],[255,28,0,255],[255,24,0,255],[255,20,0,255],[255,16,0,255],[255,12,0,255],[255,8,0,255],[255,4,0,255],[255,0,0,255],[251,0,0,255],[247,0,0,255],[243,0,0,255],[239,0,0,255],[235,0,0,255],[231,0,0,255],[227,0,0,255],[223,0,0,255],[219,0,0,255],[215,0,0,255],[211,0,0,255],[207,0,0,255],[203,0,0,255],[199,0,0,255],[195,0,0,255],[191,0,0,255],[187,0,0,255],[183,0,0,255],[179,0,0,255],[175,0,0,255],[171,0,0,255],[167,0,0,255],[163,0,0,255],[159,0,0,255],[155,0,0,255],[151,0,0,255],[147,0,0,255],[143,0,0,255],[139,0,0,255],[135,0,0,255],[131,0,0,255],[127,0,0,255]];
const midle_WF = canvas_width_WF*2;
function SetImageDataWF(datas) {
function SetImageDataWF(datas,scale_min,scale_max) {
var canvasBuffer = document.createElement("canvas");
canvasBuffer.width = canvas_width_WF;
canvasBuffer.height = canvas_height_WF;
@ -154,11 +160,16 @@ function SetImageDataWF(datas) {
for (px = 0; px < canvas_width_WF; px++) {
i = 4*px;
let dat = Math.floor(datas[px]*scale_max + scale_min);
if(dat<0){dat=0;}
if(dat>255){dat=255;}
// let rgba = colMap[datas[px]]; // lookup color rgba values
imgObjWF.data[i] = colMap[datas[px]][0]; // red
imgObjWF.data[i+1] = colMap[datas[px]][1]; // green
imgObjWF.data[i+2] = colMap[datas[px]][2]; // blue
imgObjWF.data[i+3] = colMap[datas[px]][3]; // alpha
imgObjWF.data[i] = colMap[dat][0]; // red
imgObjWF.data[i+1] = colMap[dat][1]; // green
imgObjWF.data[i+2] = colMap[dat][2]; // blue
imgObjWF.data[i+3] = colMap[dat][3]; // alpha
}
imgObjWF.data[midle_WF] = 0;
@ -196,8 +207,8 @@ function showOnmouseInfo(event) {
var rect = this.getBoundingClientRect()
var scaleX = this.width / rect.width; // relationship bitmap vs. element for X
var hzperpixel=samplerate/this.width;
console.log(this.width);
console.log(rect.width);
// console.log(this.width);
// console.log(rect.width);
hz=((window.scrollX+event.clientX)*scaleX*hzperpixel)-(samplerate/2);
freqmouse=window.opener.TRXfrequency+hz;