mirror of
https://github.com/F4HTB/Universal_HamRadio_Remote_HTML5.git
synced 2024-09-21 07:27:10 +00:00
add FI panadapter
This commit is contained in:
parent
a09c3afc90
commit
dd833d6b54
179
UHRR
179
UHRR
@ -16,6 +16,9 @@ import datetime
|
||||
import configparser
|
||||
import sys
|
||||
import Hamlib
|
||||
from rtlsdr import RtlSdr
|
||||
import numpy as np
|
||||
import math
|
||||
|
||||
############ Global variables ##################################
|
||||
CTRX=None
|
||||
@ -23,6 +26,154 @@ config = configparser.ConfigParser()
|
||||
config.read('UHRR.conf')
|
||||
e="No"
|
||||
|
||||
############ Generate and send FFT from RTLSDR ##############
|
||||
|
||||
is_rtlsdr_present = True
|
||||
|
||||
try:
|
||||
sdr = RtlSdr()
|
||||
sdr.sample_rate = int(config['PANADAPTER']['sample_rate']) # Hz
|
||||
sdr.center_freq = int(config['PANADAPTER']['center_freq']) # Hz
|
||||
sdr.freq_correction = int(config['PANADAPTER']['freq_correction']) # PPM
|
||||
sdr.gain = int(config['PANADAPTER']['gain']) #or 'auto'
|
||||
FFTSIZE=2048
|
||||
nbBuffer=24
|
||||
nbsamples=nbBuffer/2*FFTSIZE
|
||||
ptime=nbsamples/int(config['PANADAPTER']['sample_rate'])
|
||||
except:
|
||||
is_rtlsdr_present = False
|
||||
|
||||
AudioPanaHandlerClients = []
|
||||
|
||||
class loadFFTdata(threading.Thread):
|
||||
|
||||
def __init__(self):
|
||||
threading.Thread.__init__(self)
|
||||
self.get_log_power_spectrum_w = np.empty(FFTSIZE)
|
||||
for i in range(FFTSIZE):
|
||||
self.get_log_power_spectrum_w[i] = 0.5 * (1. - math.cos((2 * math.pi * i) / (FFTSIZE - 1)))
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
time.sleep(0.2)
|
||||
self.getFFT_data()
|
||||
|
||||
|
||||
def get_log_power_spectrum(self,data):
|
||||
|
||||
pulse = 10
|
||||
rejected_count = 0
|
||||
power_spectrum = np.zeros(FFTSIZE)
|
||||
db_adjust = 20. * math.log10(FFTSIZE * 2 ** 15)
|
||||
|
||||
# Time-domain analysis: Often we have long normal signals interrupted
|
||||
# by huge wide-band pulses that degrade our power spectrum average.
|
||||
# We find the "normal" signal level, by computing the median of the
|
||||
# absolute value. We only do this for the first buffer of a chunk,
|
||||
# using the median for the remaining buffers in the chunk.
|
||||
# A "noise pulse" is a signal level greater than some threshold
|
||||
# times the median. When such a pulse is found, we skip the current
|
||||
# buffer. It would be better to blank out just the pulse, but that
|
||||
# would be more costly in CPU time.
|
||||
|
||||
# Find the median abs value of first buffer to use for this chunk.
|
||||
td_median = np.median(np.abs(data[:FFTSIZE]))
|
||||
# Calculate our current threshold relative to measured median.
|
||||
td_threshold = pulse * td_median
|
||||
nbuf_taken = 0 # Actual number of buffers accumulated
|
||||
for ic in range(nbBuffer-1):
|
||||
start=ic * int(FFTSIZE/2)
|
||||
end=start+FFTSIZE
|
||||
td_segment = data[start:end]
|
||||
|
||||
# remove the 0hz spike
|
||||
td_segment = np.subtract(td_segment, np.average(td_segment))
|
||||
|
||||
td_max = np.amax(np.abs(td_segment)) # Do we have a noise pulse?
|
||||
if td_max < td_threshold: # No, get pwr spectrum etc.
|
||||
# EXPERIMENTAL TAPERfd
|
||||
td_segment *= self.get_log_power_spectrum_w
|
||||
|
||||
fd_spectrum = np.fft.fft(td_segment)
|
||||
# Frequency-domain:
|
||||
# Rotate array to place 0 freq. in center. (It was at left.)
|
||||
fd_spectrum_rot = np.fft.fftshift(fd_spectrum)
|
||||
# Compute the real-valued squared magnitude (ie power) and
|
||||
# accumulate into pwr_acc.
|
||||
# fastest way to sum |z|**2 ??
|
||||
nbuf_taken += 1
|
||||
power_spectrum = power_spectrum + \
|
||||
np.real(fd_spectrum_rot * fd_spectrum_rot.conj())
|
||||
else: # Yes, abort buffer.
|
||||
rejected_count += 1
|
||||
# if DEBUG: print "REJECT! %d" % self.rejected_count
|
||||
if nbuf_taken > 0:
|
||||
power_spectrum = power_spectrum / nbuf_taken # normalize the sum.
|
||||
else:
|
||||
power_spectrum = np.ones(FFTSIZE) # if no good buffers!
|
||||
# Convert to dB. Note log(0) = "-inf" in Numpy. It can happen if ADC
|
||||
# isn't working right. Numpy issues a warning.
|
||||
log_power_spectrum = 10. * np.log10(power_spectrum)
|
||||
return log_power_spectrum - db_adjust # max poss. signal = 0 dB
|
||||
|
||||
def getFFT_data(self):
|
||||
samples = sdr.read_samples(nbsamples)
|
||||
samples = np.imag(samples) + 1j * np.real(samples)
|
||||
|
||||
max_pow = 0
|
||||
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:
|
||||
if dat > max_pow:
|
||||
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)
|
||||
|
||||
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)
|
||||
return ret
|
||||
|
||||
class panFFTHandler(tornado.websocket.WebSocketHandler):
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def sendFFT(self):
|
||||
global ptime
|
||||
try:
|
||||
while len(self.fftframes)>0:
|
||||
for i in range(8):
|
||||
yield self.write_message(self.fftframes[0][i*256:(i+1)*256])
|
||||
yield self.write_message("NewLine")
|
||||
del self.fftframes[0]
|
||||
except:
|
||||
return None
|
||||
tornado.ioloop.IOLoop.instance().add_timeout(datetime.timedelta(seconds=ptime), self.sendFFT)
|
||||
|
||||
def open(self):
|
||||
global is_rtlsdr_present
|
||||
print('new connection on FFT socket, is_rtlsdr_present = '+str(is_rtlsdr_present))
|
||||
if self not in AudioPanaHandlerClients:
|
||||
AudioPanaHandlerClients.append(self)
|
||||
self.fftframes = []
|
||||
if is_rtlsdr_present:
|
||||
self.sendFFT()
|
||||
|
||||
def on_close(self):
|
||||
print('connection closed for FFT socket')
|
||||
|
||||
############ websocket for send RX audio from TRX ##############
|
||||
flagWavstart = False
|
||||
AudioRXHandlerClients = []
|
||||
@ -289,6 +440,8 @@ class ControlTRX(tornado.websocket.WebSocketHandler):
|
||||
self.sendPTINFOS()
|
||||
CTRX.setPower(1)
|
||||
print('new connection on ControlTRX socket.')
|
||||
if(is_rtlsdr_present):
|
||||
self.write_message("panfft")
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def on_message(self, data) :
|
||||
@ -416,7 +569,28 @@ class ConfigHandler(tornado.web.RequestHandler):
|
||||
self.write("""<option value=\"True\">\"True\"</option>""")
|
||||
self.write("""<option value=\"False\">\"False\"</option>""")
|
||||
self.write("""</select><br/><br/>""")
|
||||
|
||||
self.write("""[PANADAPTER]<br/><br/>""")
|
||||
self.write("""PANADAPTER FI frequency (hz):<input type="text" name="PANADAPTER.center_freq" value="""+config['PANADAPTER']['center_freq']+"""><br/><br/>""")
|
||||
|
||||
self.write("""HAMLIB radio rate (samples/s):<select name="PANADAPTER.sample_rate">""")
|
||||
if(config['PANADAPTER']['sample_rate']!="null"):
|
||||
self.write("""<option value="""+config['PANADAPTER']['sample_rate']+""" selected>"""+config['PANADAPTER']['sample_rate']+"""</option>""")
|
||||
self.write("""<option value=3200000>3200000</option>""")
|
||||
self.write("""<option value=2880000>2880000</option>""")
|
||||
self.write("""<option value=2400000>2400000</option>""")
|
||||
self.write("""<option value=1800000>1800000</option>""")
|
||||
self.write("""<option value=1440000>1440000</option>""")
|
||||
self.write("""<option value=1200000>1200000</option>""")
|
||||
self.write("""<option value=1020000>1020000</option>""")
|
||||
self.write("""<option value=960000>960000</option>""")
|
||||
self.write("""<option value=250000>250000</option>""")
|
||||
self.write("""</select><br/><br/>""")
|
||||
|
||||
self.write("""PANADAPTER frequency correction (ppm):<input type="text" name="PANADAPTER.freq_correction" value="""+config['PANADAPTER']['freq_correction']+"""><br/><br/>""")
|
||||
|
||||
self.write("""PANADAPTER initial gain:<input type="text" name="PANADAPTER.gain" value="""+config['PANADAPTER']['gain']+"""><br/><br/>""")
|
||||
|
||||
self.write("""<input type="submit" value="Save & Restart server"><br/><br/></form>Possible problem:"""+e+"""</html>""")
|
||||
|
||||
def post(self):
|
||||
@ -437,6 +611,10 @@ class ConfigHandler(tornado.web.RequestHandler):
|
||||
if __name__ == "__main__":
|
||||
|
||||
try:
|
||||
if is_rtlsdr_present:
|
||||
threadFFT = loadFFTdata()
|
||||
threadFFT.start()
|
||||
|
||||
threadloadWavdata = loadWavdata()
|
||||
threadloadWavdata.start()
|
||||
|
||||
@ -454,6 +632,7 @@ if __name__ == "__main__":
|
||||
(r'/audioRX', AudioRXHandler),
|
||||
(r'/audioTX', AudioTXHandler),
|
||||
(r'/CTRX', ControlTRX),
|
||||
(r'/panFFT', panFFTHandler),
|
||||
(r'/CONFIG', ConfigHandler),
|
||||
(r'/', MainHandler),
|
||||
(r'/(.*)', tornado.web.StaticFileHandler, { 'path' : './www' })
|
||||
|
@ -19,3 +19,9 @@ rig_model = FT817
|
||||
trxautopower = True
|
||||
rig_rate = 38400
|
||||
|
||||
[PANADAPTER]
|
||||
sample_rate = 250000
|
||||
center_freq = 68330000
|
||||
freq_correction = 1
|
||||
gain = 100
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
12
www/controls.js
vendored
12
www/controls.js
vendored
@ -113,9 +113,19 @@ function powertogle()
|
||||
poweron = false;
|
||||
button_unlight_all("div-filtershortcut");
|
||||
button_unlight_all("div-mode_menu");
|
||||
document.getElementById("div-panfft").style.display = "none";
|
||||
if (typeof panfft !== 'undefined') {panfft.close();}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('beforeunload', function (e) {
|
||||
if(poweron)e.preventDefault();
|
||||
if (typeof panfft !== 'undefined') {
|
||||
panfft.close();
|
||||
e.returnValue = '';
|
||||
}
|
||||
});
|
||||
|
||||
function check_connected() {
|
||||
setTimeout(function () {
|
||||
if (wsAudioRX.readyState === WebSocket.OPEN && wsAudioTX.readyState === WebSocket.OPEN && wsControlTRX.readyState === WebSocket.OPEN){document.getElementById("ombre-body").style.display = "none";document.getElementById("pop-upspinner").style.display = "none";}
|
||||
@ -378,12 +388,12 @@ function ControlTRX_start(){
|
||||
|
||||
var SignalLevel=0;
|
||||
function wsControlTRXcrtol( msg ){
|
||||
console.log(String(msg.data));
|
||||
words = String(msg.data).split(':');
|
||||
if(words[0] == "PONG"){showlatency();}
|
||||
else if(words[0] == "getFreq"){showTRXfreq(words[1]);}
|
||||
else if(words[0] == "getMode"){showTRXmode(words[1]);}
|
||||
else if(words[0] == "getSignalLevel"){SignalLevel=words[1];drawRXSmeter();}
|
||||
else if(words[0] == "panfft"){document.getElementById("div-panfft").style.display = "block";}
|
||||
}
|
||||
|
||||
function ControlTRX_stop()
|
||||
|
BIN
www/img/panfft.png
Normal file
BIN
www/img/panfft.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
@ -163,6 +163,7 @@
|
||||
<label id="callsign"></label>
|
||||
|
||||
<div id="div-conf"><a href="/CONFIG" target="_UHRRconfig"><img src="img/config.png"></a></div>
|
||||
<div id="div-panfft"><a onclick="panfft = window.open( this.href, 'UHRRpanfft', 'width=1000, height=1000, menubar=no, toolbar=no, location=no, resizable=yes, scrollbars=no, status=no, dependent=yes'); return false;" href="/panfft.html" target="_UHRRpanfft"><img src="img/panfft.png"></a></div>
|
||||
|
||||
<canvas id="canRXsmeter" width=250 height=50 ></canvas>
|
||||
|
||||
|
64
www/panfft.css
Normal file
64
www/panfft.css
Normal file
@ -0,0 +1,64 @@
|
||||
body {
|
||||
color: white;
|
||||
font:normal bold 14px tahoma;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
}
|
||||
|
||||
#div-sp
|
||||
{
|
||||
position:relative;
|
||||
width:100%;
|
||||
height:45%;
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
}
|
||||
|
||||
#cansp{
|
||||
width:100%;
|
||||
height:100%;
|
||||
float:center;
|
||||
background-color:black;
|
||||
}
|
||||
|
||||
#div-wf
|
||||
{
|
||||
position:relative;
|
||||
width:100%;
|
||||
height:45%;
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
}
|
||||
|
||||
#canwf{
|
||||
width:100%;
|
||||
height:100%;
|
||||
background:#00007f;
|
||||
background-color:bleu;
|
||||
}
|
||||
|
||||
#div-ctrl
|
||||
{
|
||||
background-color:#171717;
|
||||
position:relative;
|
||||
width:100%;
|
||||
height:10%;
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
}
|
||||
|
||||
#div-scoketscontrols > img
|
||||
{
|
||||
margin-right:5px;
|
||||
width:25px;
|
||||
height:25px;
|
||||
}
|
||||
|
||||
|
||||
|
22
www/panfft.html
Normal file
22
www/panfft.html
Normal file
@ -0,0 +1,22 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>FFT Universal Hamradio Remote by F4HTB</title>
|
||||
<link rel="stylesheet" type="text/css" href="panfft.css">
|
||||
</head>
|
||||
<body onload="bodyload();">
|
||||
<div id="div-princ">
|
||||
<div id="div-sp">
|
||||
<canvas id="cansp" width=2048 height=256></canvas>
|
||||
</div>
|
||||
<div id="div-wf">
|
||||
<canvas id="canwf" width=2048 height=256></canvas>
|
||||
</div>
|
||||
<div id="div-ctrl">
|
||||
aaa
|
||||
<div id="div-scoketscontrols"><img src="img/critsred.png">wsFFT</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="panfft.js"></script>
|
||||
</body>
|
||||
</html>
|
135
www/panfft.js
Normal file
135
www/panfft.js
Normal file
@ -0,0 +1,135 @@
|
||||
const canvas_width=2048;
|
||||
const canvas_height=256;
|
||||
var wshFFT = "";
|
||||
|
||||
function bodyload(){
|
||||
initFFT();
|
||||
startFFT();
|
||||
}
|
||||
|
||||
function startFFT(){
|
||||
document.getElementById("div-scoketscontrols").innerHTML='<img src="img/critsgrey.png">wsFFT';
|
||||
wshFFT = new WebSocket( 'wss://' + window.location.href.split( '/' )[2] + '/panFFT' );
|
||||
wshFFT.onopen = appendwshFFTOpen;
|
||||
wshFFT.onmessage = showFFT;
|
||||
wshFFT.onerror = appendwshFFTError;
|
||||
wshFFT.onclose = appendwshFFTclose;
|
||||
}
|
||||
|
||||
function appendwshFFTclose(){
|
||||
document.getElementById("div-scoketscontrols").innerHTML='<img src="img/critsred.png">wsFFT';
|
||||
}
|
||||
|
||||
function appendwshFFTOpen(){
|
||||
document.getElementById("div-scoketscontrols").innerHTML='<img src="img/critsgreen.png">wsFFT';
|
||||
}
|
||||
|
||||
function appendwshFFTError(err){
|
||||
document.getElementById("div-scoketscontrols").innerHTML='<img src="img/critsred.png">wsFFT';
|
||||
wshFFT.close();
|
||||
startFFT();
|
||||
}
|
||||
|
||||
function stopFFT(){
|
||||
wshFFT.close();
|
||||
initFFT();
|
||||
}
|
||||
|
||||
function initFFT(){
|
||||
initCanvas("cansp");
|
||||
initCanvas("canwf");
|
||||
}
|
||||
|
||||
var globmsg = "";
|
||||
|
||||
function showFFT( msg ){
|
||||
if(msg.data != "NewLine"){globmsg += msg.data;}
|
||||
else{
|
||||
if(globmsg.length == canvas_width){
|
||||
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);
|
||||
}
|
||||
console.log(globmsg.length);
|
||||
console.log(canvas_width);
|
||||
globmsg="";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const canvasSP = document.getElementById("cansp"),ctxSP = canvasSP.getContext("2d");// imgObjSP = ctxSP.createImageData(canvasSP.width, canvas_height);
|
||||
const midle = canvas_width*2;
|
||||
|
||||
function SetImageDataSP(datas) {
|
||||
imgObjSP = new ImageData(canvasSP.width, canvas_height);
|
||||
let i = 0;
|
||||
for(let Line = 0; Line < canvas_height; Line++){
|
||||
i = 4*(Line * canvas_width);
|
||||
y = canvas_height - Line;
|
||||
for (let px = 0; px < canvas_width; px++) {
|
||||
|
||||
if(y <= datas[px]){
|
||||
//imgObjSP.data[i] = 0; // red
|
||||
imgObjSP.data[++i] = 215; // green
|
||||
imgObjSP.data[++i] = 233; // blue
|
||||
imgObjSP.data[++i] = 255; // alpha
|
||||
++i;
|
||||
}
|
||||
else{i += 4 ;}
|
||||
}
|
||||
i -= midle ;
|
||||
//imgObjSP.data[i] = 0; // red
|
||||
imgObjSP.data[++i] = 255; // green
|
||||
imgObjSP.data[++i] = 0; // blue
|
||||
imgObjSP.data[++i] = 255; // alpha
|
||||
}
|
||||
ctxSP.putImageData(imgObjSP, 0, 0);
|
||||
}
|
||||
|
||||
const canvasWF = document.getElementById("canwf"),ctxWF = canvasWF.getContext("2d"),imgObjWF = ctxWF.createImageData(canvasWF.width, 1);
|
||||
//const colMap = [[0,0,0,255],[40,0,0,255],[56,0,4,255],[61,0,9,255],[64,0,12,255],[66,0,14,255],[69,0,17,255],[73,0,20,255],[74,0,22,255],[78,0,25,255],[79,0,27,255],[83,0,30,255],[85,0,31,255],[86,0,33,255],[90,0,36,255],[91,0,38,255],[93,0,39,255],[95,0,41,255],[96,0,43,255],[100,0,46,255],[102,0,47,255],[103,0,49,255],[105,0,51,255],[107,0,52,255],[108,0,54,255],[110,0,55,255],[112,0,57,255],[112,0,57,255],[113,0,58,255],[115,0,60,255],[117,0,62,255],[119,0,63,255],[120,0,65,255],[122,0,66,255],[124,0,68,255],[125,0,70,255],[127,0,71,255],[129,0,73,255],[129,0,73,255],[130,0,74,255],[132,0,76,255],[134,0,78,255],[136,0,79,255],[137,0,81,255],[139,0,82,255],[141,0,84,255],[142,0,86,255],[144,0,87,255],[146,0,89,255],[147,0,90,255],[149,0,92,255],[151,0,94,255],[151,0,94,255],[153,0,95,255],[154,0,97,255],[156,0,98,255],[158,0,100,255],[159,0,102,255],[161,0,103,255],[163,0,105,255],[164,0,106,255],[166,0,108,255],[168,0,109,255],[170,0,111,255],[171,0,113,255],[173,0,114,255],[175,0,116,255],[176,0,117,255],[178,0,119,255],[180,0,121,255],[180,0,121,255],[181,0,122,255],[183,0,124,255],[185,0,125,255],[187,0,127,255],[188,0,129,255],[190,0,130,255],[192,0,132,255],[193,0,133,255],[195,0,135,255],[197,0,137,255],[198,0,138,255],[200,0,140,255],[202,0,141,255],[204,0,143,255],[204,0,143,255],[205,0,145,255],[207,0,146,255],[209,0,148,255],[210,0,149,255],[212,0,151,255],[214,0,153,255],[215,0,154,255],[217,0,156,255],[219,0,157,255],[221,0,159,255],[222,0,160,255],[222,0,160,255],[224,0,162,255],[226,0,164,255],[227,0,165,255],[229,0,167,255],[231,0,168,255],[232,0,170,255],[234,0,172,255],[236,0,173,255],[238,0,175,255],[238,0,175,255],[239,0,176,255],[241,0,178,255],[243,0,180,255],[244,0,181,255],[246,0,183,255],[248,2,184,255],[249,4,186,255],[249,4,186,255],[249,4,186,255],[251,6,188,255],[251,6,188,255],[253,9,189,255],[253,9,189,255],[255,11,191,255],[255,11,191,255],[255,13,192,255],[255,13,192,255],[255,13,192,255],[255,16,194,255],[255,18,196,255],[255,20,197,255],[255,20,197,255],[255,23,199,255],[255,25,200,255],[255,27,202,255],[255,30,204,255],[255,32,205,255],[255,34,207,255],[255,37,208,255],[255,37,208,255],[255,39,210,255],[255,41,211,255],[255,44,213,255],[255,46,215,255],[255,48,216,255],[255,51,218,255],[255,53,219,255],[255,53,219,255],[255,55,221,255],[255,57,223,255],[255,60,224,255],[255,62,226,255],[255,64,227,255],[255,67,229,255],[255,67,229,255],[255,69,231,255],[255,71,232,255],[255,74,234,255],[255,76,235,255],[255,78,237,255],[255,81,239,255],[255,81,239,255],[255,83,240,255],[255,85,242,255],[255,88,243,255],[255,90,245,255],[255,92,247,255],[255,95,248,255],[255,95,248,255],[255,97,250,255],[255,99,251,255],[255,102,253,255],[255,104,255,255],[255,106,255,255],[255,106,255,255],[255,108,255,255],[255,111,255,255],[255,113,255,255],[255,115,255,255],[255,115,255,255],[255,118,255,255],[255,120,255,255],[255,122,255,255],[255,122,255,255],[255,125,255,255],[255,127,255,255],[255,129,255,255],[255,129,255,255],[255,132,255,255],[255,134,255,255],[255,136,255,255],[255,136,255,255],[255,139,255,255],[255,141,255,255],[255,143,255,255],[255,143,255,255],[255,146,255,255],[255,148,255,255],[255,150,255,255],[255,150,255,255],[255,153,255,255],[255,155,255,255],[255,155,255,255],[255,157,255,255],[255,159,255,255],[255,159,255,255],[255,162,255,255],[255,164,255,255],[255,164,255,255],[255,166,255,255],[255,169,255,255],[255,171,255,255],[255,171,255,255],[255,173,255,255],[255,176,255,255],[255,176,255,255],[255,178,255,255],[255,180,255,255],[255,180,255,255],[255,183,255,255],[255,185,255,255],[255,185,255,255],[255,187,255,255],[255,190,255,255],[255,190,255,255],[255,192,255,255],[255,194,255,255],[255,197,255,255],[255,197,255,255],[255,199,255,255],[255,201,255,255],[255,204,255,255],[255,204,255,255],[255,206,255,255],[255,208,255,255],[255,210,255,255],[255,210,255,255],[255,213,255,255],[255,215,255,255],[255,217,255,255],[255,217,255,255],[255,220,255,255],[255,222,255,255],[255,224,255,255],[255,227,255,255],[255,229,255,255],[255,229,255,255],[255,231,255,255],[255,234,255,255],[255,236,255,255],[255,238,255,255],[255,241,255,255],[255,243,255,255],[255,243,255,255],[255,245,255,255],[255,248,255,255],[255,250,255,255],[255,255,255,255]];
|
||||
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]];
|
||||
|
||||
function SetImageDataWF(datas) {
|
||||
console.log("aaa");
|
||||
var canvasBuffer = document.createElement("canvas");
|
||||
canvasBuffer.width = canvas_width;
|
||||
canvasBuffer.height = canvas_height;
|
||||
var ctxBuffer = canvasBuffer.getContext("2d");
|
||||
|
||||
ctxBuffer.clearRect(0,0,canvas_width,canvas_height); //clear buffer
|
||||
ctxBuffer.drawImage(canvasWF,0,0); //store display data in buffer
|
||||
ctxWF.clearRect(0,0,canvas_width,canvas_height); //clear display
|
||||
ctxWF.drawImage(canvasBuffer,0,1); //copy buffer to display
|
||||
|
||||
|
||||
var px=0;
|
||||
var i=0;
|
||||
for (px = 0; px < canvas_width; px++) {
|
||||
i = 4*px;
|
||||
|
||||
// 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[midle] = 0;
|
||||
imgObjWF.data[midle+1] = 255;
|
||||
imgObjWF.data[midle+2] = 0;
|
||||
imgObjWF.data[midle+3] = 255;
|
||||
|
||||
ctxWF.putImageData(imgObjWF, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
function initCanvas(cvsIDwf) {
|
||||
var canvas = document.getElementById(cvsIDwf);
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.fillStyle = "black";
|
||||
ctx.fillRect(0, 0, canvas_width, canvas_height);
|
||||
}
|
||||
|
@ -285,6 +285,22 @@ overflow: hidden;
|
||||
height:25px;
|
||||
}
|
||||
|
||||
#div-panfft
|
||||
{
|
||||
position:absolute;
|
||||
left: 1750px;
|
||||
top:55px;
|
||||
width: 580px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#div-panfft > a > img
|
||||
{
|
||||
margin-right:5px;
|
||||
width:25px;
|
||||
height:25px;
|
||||
}
|
||||
|
||||
#div-latencymeter
|
||||
{
|
||||
font:normal bold 25px tahoma;
|
||||
|
Loading…
Reference in New Issue
Block a user