Added S-meter
This commit is contained in:
parent
06bd8b92aa
commit
34bd5cceab
@ -108,8 +108,13 @@
|
|||||||
<div class="openwebrx-button openwebrx-square-button" onclick="zoomOutOneStep();" title="Zoom out one step"> <img src="gfx/openwebrx-zoom-out.png" /></div>
|
<div class="openwebrx-button openwebrx-square-button" onclick="zoomOutOneStep();" title="Zoom out one step"> <img src="gfx/openwebrx-zoom-out.png" /></div>
|
||||||
<div class="openwebrx-button openwebrx-square-button" onclick="zoomInTotal();" title="Zoom in totally"><img src="gfx/openwebrx-zoom-in-total.png" /></div>
|
<div class="openwebrx-button openwebrx-square-button" onclick="zoomInTotal();" title="Zoom in totally"><img src="gfx/openwebrx-zoom-in-total.png" /></div>
|
||||||
<div class="openwebrx-button openwebrx-square-button" onclick="zoomOutTotal();" title="Zoom out totally"><img src="gfx/openwebrx-zoom-out-total.png" /></div>
|
<div class="openwebrx-button openwebrx-square-button" onclick="zoomOutTotal();" title="Zoom out totally"><img src="gfx/openwebrx-zoom-out-total.png" /></div>
|
||||||
|
<div id="openwebrx-smeter-db">0 dB</div>
|
||||||
|
</div>
|
||||||
|
<div class="openwebrx-panel-line">
|
||||||
|
<div id="openwebrx-smeter-outer">
|
||||||
|
<div id="openwebrx-smeter-bar"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="openwebrx-panel" id="openwebrx-panel-log" data-panel-name="debug" data-panel-pos="left" data-panel-order="1" data-panel-size="619,142">
|
<div class="openwebrx-panel" id="openwebrx-panel-log" data-panel-name="debug" data-panel-pos="left" data-panel-order="1" data-panel-size="619,142">
|
||||||
|
@ -36,7 +36,7 @@ input
|
|||||||
input[type=range]
|
input[type=range]
|
||||||
{
|
{
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
margin: 10px 0;
|
margin: 0 0;
|
||||||
}
|
}
|
||||||
input[type=range]:focus
|
input[type=range]:focus
|
||||||
{
|
{
|
||||||
@ -745,3 +745,36 @@ img.openwebrx-mirror-img
|
|||||||
{
|
{
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#openwebrx-smeter-outer
|
||||||
|
{
|
||||||
|
border-color: #888;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0px;
|
||||||
|
width: 255px;
|
||||||
|
height: 7px;
|
||||||
|
background-color: #373737;
|
||||||
|
border-radius: 3px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
#openwebrx-smeter-bar
|
||||||
|
{
|
||||||
|
transition: all 0.2s linear;
|
||||||
|
width: 0px;
|
||||||
|
height: 7px;
|
||||||
|
background: linear-gradient(to top, #ff5939 , #961700);
|
||||||
|
position: absolute;
|
||||||
|
margin: 0; padding: 0; left: 0;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#openwebrx-smeter-db
|
||||||
|
{
|
||||||
|
color: #aaa;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 10pt;
|
||||||
|
float: right;
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-top: 29px;
|
||||||
|
font-family: 'expletus-sans-medium';
|
||||||
|
}
|
||||||
|
@ -178,6 +178,36 @@ function waterfallColorsAuto()
|
|||||||
updateWaterfallColors(0);
|
updateWaterfallColors(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setSmeterRelativeValue(value)
|
||||||
|
{
|
||||||
|
if(value<0) value=0;
|
||||||
|
if(value>1.0) value=1.0;
|
||||||
|
var bar=e("openwebrx-smeter-bar");
|
||||||
|
var outer=e("openwebrx-smeter-outer");
|
||||||
|
bar.style.width=(outer.offsetWidth*value).toString()+"px";
|
||||||
|
bgRed="linear-gradient(to top, #ff5939 , #961700)";
|
||||||
|
bgGreen="linear-gradient(to top, #22ff2f , #008908)";
|
||||||
|
bgYellow="linear-gradient(to top, #fff720 , #a49f00)";
|
||||||
|
bar.style.background=(value>0.9)?bgRed:((value>0.7)?bgYellow:bgGreen);
|
||||||
|
//bar.style.backgroundColor=(value>0.9)?"#ff5939":((value>0.7)?"#fff720":"#22ff2f");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLogSmeterValue(value)
|
||||||
|
{
|
||||||
|
return 10*Math.log10(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSmeterAbsoluteValue(value) //the value that comes from `csdr squelch_and_smeter_cc`
|
||||||
|
{
|
||||||
|
var logValue=getLogSmeterValue(value);
|
||||||
|
var lowLevel=waterfall_min_level-20;
|
||||||
|
var highLevel=waterfall_max_level+20;
|
||||||
|
var percent=(logValue-lowLevel)/(highLevel-lowLevel);
|
||||||
|
setSmeterRelativeValue(percent);
|
||||||
|
e("openwebrx-smeter-db").innerHTML=logValue.toFixed(1)+" dB";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// ================= ANIMATION ROUTINES =================
|
// ================= ANIMATION ROUTINES =================
|
||||||
// ========================================================
|
// ========================================================
|
||||||
@ -1145,6 +1175,10 @@ function on_ws_recv(evt)
|
|||||||
case "max_clients":
|
case "max_clients":
|
||||||
max_clients_num=parseInt(param[1]);
|
max_clients_num=parseInt(param[1]);
|
||||||
break;
|
break;
|
||||||
|
case "s":
|
||||||
|
smeter_level=parseFloat(param[1]);
|
||||||
|
setSmeterAbsoluteValue(smeter_level);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*}
|
/*}
|
||||||
|
13
openwebrx.py
13
openwebrx.py
@ -460,6 +460,16 @@ class WebRXHandler(BaseHTTPRequestHandler):
|
|||||||
# (it seems GNU Radio exchanges the first and second part of the FFT output, we correct it)
|
# (it seems GNU Radio exchanges the first and second part of the FFT output, we correct it)
|
||||||
rxws.send(self, spectrum_data[0],"FFT ")
|
rxws.send(self, spectrum_data[0],"FFT ")
|
||||||
|
|
||||||
|
# ========= send smeter_level =========
|
||||||
|
smeter_level=None
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
smeter_level=dsp.get_smeter_level()
|
||||||
|
if smeter_level == None: break
|
||||||
|
except:
|
||||||
|
break
|
||||||
|
if smeter_level!=None: rxws.send(self, "MSG s={0}".format(smeter_level))
|
||||||
|
|
||||||
# ========= send bcastmsg =========
|
# ========= send bcastmsg =========
|
||||||
if myclient.bcastmsg!="":
|
if myclient.bcastmsg!="":
|
||||||
rxws.send(self,myclient.bcastmsg)
|
rxws.send(self,myclient.bcastmsg)
|
||||||
@ -486,6 +496,8 @@ class WebRXHandler(BaseHTTPRequestHandler):
|
|||||||
new_bpf[1]=int(param_value)
|
new_bpf[1]=int(param_value)
|
||||||
elif param_name == "offset_freq" and -cfg.samp_rate/2 <= float(param_value) <= cfg.samp_rate/2:
|
elif param_name == "offset_freq" and -cfg.samp_rate/2 <= float(param_value) <= cfg.samp_rate/2:
|
||||||
dsp.set_offset_freq(int(param_value))
|
dsp.set_offset_freq(int(param_value))
|
||||||
|
elif param_name == "squelch_level" and float(param_value) >= 0:
|
||||||
|
dsp.set_squelch_level(float(param_value))
|
||||||
elif param_name=="mod":
|
elif param_name=="mod":
|
||||||
if (dsp.get_demodulator()!=param_value):
|
if (dsp.get_demodulator()!=param_value):
|
||||||
if dsp_initialized: dsp.stop()
|
if dsp_initialized: dsp.stop()
|
||||||
@ -622,4 +634,3 @@ def get_cpu_usage():
|
|||||||
|
|
||||||
if __name__=="__main__":
|
if __name__=="__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import time
|
|||||||
import os
|
import os
|
||||||
import code
|
import code
|
||||||
import signal
|
import signal
|
||||||
|
import fcntl
|
||||||
|
|
||||||
class dsp_plugin:
|
class dsp_plugin:
|
||||||
|
|
||||||
@ -49,6 +50,7 @@ class dsp_plugin:
|
|||||||
self.csdr_dynamic_bufsize = False
|
self.csdr_dynamic_bufsize = False
|
||||||
self.csdr_print_bufsizes = False
|
self.csdr_print_bufsizes = False
|
||||||
self.csdr_through = False
|
self.csdr_through = False
|
||||||
|
self.squelch_level = 0
|
||||||
|
|
||||||
def chain(self,which):
|
def chain(self,which):
|
||||||
any_chain_base="ncat -v 127.0.0.1 {nc_port} | "
|
any_chain_base="ncat -v 127.0.0.1 {nc_port} | "
|
||||||
@ -61,7 +63,7 @@ class dsp_plugin:
|
|||||||
return fft_chain_base+" | csdr compress_fft_adpcm_f_u8 {fft_size}"
|
return fft_chain_base+" | csdr compress_fft_adpcm_f_u8 {fft_size}"
|
||||||
else:
|
else:
|
||||||
return fft_chain_base
|
return fft_chain_base
|
||||||
chain_begin=any_chain_base+"csdr shift_addition_cc --fifo {shift_pipe} | csdr fir_decimate_cc {decimation} {ddc_transition_bw} HAMMING | csdr bandpass_fir_fft_cc --fifo {bpf_pipe} {bpf_transition_bw} HAMMING | "
|
chain_begin=any_chain_base+"csdr shift_addition_cc --fifo {shift_pipe} | csdr fir_decimate_cc {decimation} {ddc_transition_bw} HAMMING | csdr bandpass_fir_fft_cc --fifo {bpf_pipe} {bpf_transition_bw} HAMMING | csdr squelch_and_smeter_cc --fifo {squelch_pipe} --outfifo {smeter_pipe} 5 1 | "
|
||||||
chain_end = ""
|
chain_end = ""
|
||||||
if self.audio_compression=="adpcm":
|
if self.audio_compression=="adpcm":
|
||||||
chain_end = " | csdr encode_ima_adpcm_i16_u8"
|
chain_end = " | csdr encode_ima_adpcm_i16_u8"
|
||||||
@ -137,6 +139,17 @@ class dsp_plugin:
|
|||||||
def get_bpf(self):
|
def get_bpf(self):
|
||||||
return [self.low_cut, self.high_cut]
|
return [self.low_cut, self.high_cut]
|
||||||
|
|
||||||
|
def set_squelch_level(self, squelch_level):
|
||||||
|
self.squelch_level=squelch_level
|
||||||
|
if self.running:
|
||||||
|
self.squelch_pipe_file.write( "%g\n"%(float(self.squelch_level)) )
|
||||||
|
self.squelch_pipe_file.flush()
|
||||||
|
|
||||||
|
def get_smeter_level(self):
|
||||||
|
if self.running:
|
||||||
|
line=self.smeter_pipe_file.readline()
|
||||||
|
return float(line[:-1])
|
||||||
|
|
||||||
def mkfifo(self,path):
|
def mkfifo(self,path):
|
||||||
try:
|
try:
|
||||||
os.unlink(path)
|
os.unlink(path)
|
||||||
@ -152,19 +165,26 @@ class dsp_plugin:
|
|||||||
|
|
||||||
#create control pipes for csdr
|
#create control pipes for csdr
|
||||||
pipe_base_path="/tmp/openwebrx_pipe_{myid}_".format(myid=id(self))
|
pipe_base_path="/tmp/openwebrx_pipe_{myid}_".format(myid=id(self))
|
||||||
self.bpf_pipe = self.shift_pipe = None
|
self.bpf_pipe = self.shift_pipe = self.squelch_pipe = self.smeter_pipe = None
|
||||||
if "{bpf_pipe}" in command_base:
|
if "{bpf_pipe}" in command_base:
|
||||||
self.bpf_pipe=pipe_base_path+"bpf"
|
self.bpf_pipe=pipe_base_path+"bpf"
|
||||||
self.mkfifo(self.bpf_pipe)
|
self.mkfifo(self.bpf_pipe)
|
||||||
if "{shift_pipe}" in command_base:
|
if "{shift_pipe}" in command_base:
|
||||||
self.shift_pipe=pipe_base_path+"shift"
|
self.shift_pipe=pipe_base_path+"shift"
|
||||||
self.mkfifo(self.shift_pipe)
|
self.mkfifo(self.shift_pipe)
|
||||||
|
if "{squelch_pipe}" in command_base:
|
||||||
|
self.squelch_pipe=pipe_base_path+"squelch"
|
||||||
|
self.mkfifo(self.squelch_pipe)
|
||||||
|
if "{smeter_pipe}" in command_base:
|
||||||
|
self.smeter_pipe=pipe_base_path+"smeter"
|
||||||
|
self.mkfifo(self.smeter_pipe)
|
||||||
|
|
||||||
#run the command
|
#run the command
|
||||||
command=command_base.format( bpf_pipe=self.bpf_pipe, shift_pipe=self.shift_pipe, decimation=self.decimation, \
|
command=command_base.format( bpf_pipe=self.bpf_pipe, shift_pipe=self.shift_pipe, decimation=self.decimation, \
|
||||||
last_decimation=self.last_decimation, fft_size=self.fft_size, fft_block_size=self.fft_block_size(), \
|
last_decimation=self.last_decimation, fft_size=self.fft_size, fft_block_size=self.fft_block_size(), \
|
||||||
bpf_transition_bw=float(self.bpf_transition_bw)/self.if_samp_rate(), ddc_transition_bw=self.ddc_transition_bw(), \
|
bpf_transition_bw=float(self.bpf_transition_bw)/self.if_samp_rate(), ddc_transition_bw=self.ddc_transition_bw(), \
|
||||||
flowcontrol=int(self.samp_rate*2), start_bufsize=self.base_bufsize*self.decimation, nc_port=self.nc_port)
|
flowcontrol=int(self.samp_rate*2), start_bufsize=self.base_bufsize*self.decimation, nc_port=self.nc_port, \
|
||||||
|
squelch_pipe=self.squelch_pipe, smeter_pipe=self.smeter_pipe )
|
||||||
|
|
||||||
print "[openwebrx-dsp-plugin:csdr] Command =",command
|
print "[openwebrx-dsp-plugin:csdr] Command =",command
|
||||||
#code.interact(local=locals())
|
#code.interact(local=locals())
|
||||||
@ -181,6 +201,12 @@ class dsp_plugin:
|
|||||||
if self.shift_pipe != None:
|
if self.shift_pipe != None:
|
||||||
self.shift_pipe_file=open(self.shift_pipe,"w")
|
self.shift_pipe_file=open(self.shift_pipe,"w")
|
||||||
self.set_offset_freq(self.offset_freq)
|
self.set_offset_freq(self.offset_freq)
|
||||||
|
if self.squelch_pipe != None:
|
||||||
|
self.squelch_pipe_file=open(self.squelch_pipe,"w")
|
||||||
|
self.set_squelch_level(self.squelch_level)
|
||||||
|
if self.smeter_pipe != None:
|
||||||
|
self.smeter_pipe_file=open(self.smeter_pipe,"r")
|
||||||
|
fcntl.fcntl(self.smeter_pipe_file, fcntl.F_SETFL, os.O_NONBLOCK)
|
||||||
|
|
||||||
def read(self,size):
|
def read(self,size):
|
||||||
return self.process.stdout.read(size)
|
return self.process.stdout.read(size)
|
||||||
@ -195,15 +221,17 @@ class dsp_plugin:
|
|||||||
#
|
#
|
||||||
# time.sleep(0.1)
|
# time.sleep(0.1)
|
||||||
if self.bpf_pipe:
|
if self.bpf_pipe:
|
||||||
try:
|
try: os.unlink(self.bpf_pipe)
|
||||||
os.unlink(self.bpf_pipe)
|
except: print "[openwebrx-dsp-plugin:csdr] stop() :: unlink failed: " + self.bpf_pipe
|
||||||
except:
|
|
||||||
print "[openwebrx-dsp-plugin:csdr] stop() :: unlink failed: " + self.bpf_pipe
|
|
||||||
if self.shift_pipe:
|
if self.shift_pipe:
|
||||||
try:
|
try: os.unlink(self.shift_pipe)
|
||||||
os.unlink(self.shift_pipe)
|
except: print "[openwebrx-dsp-plugin:csdr] stop() :: unlink failed: " + self.shift_pipe
|
||||||
except:
|
if self.squelch_pipe:
|
||||||
print "[openwebrx-dsp-plugin:csdr] stop() :: unlink failed: " + self.bpf_pipe
|
try: os.unlink(self.squelch_pipe)
|
||||||
|
except: print "[openwebrx-dsp-plugin:csdr] stop() :: unlink failed: " + self.squelch_pipe
|
||||||
|
if self.smeter_pipe:
|
||||||
|
try: os.unlink(self.smeter_pipe)
|
||||||
|
except: print "[openwebrx-dsp-plugin:csdr] stop() :: unlink failed: " + self.smeter_pipe
|
||||||
self.running = False
|
self.running = False
|
||||||
|
|
||||||
def restart(self):
|
def restart(self):
|
||||||
@ -213,4 +241,3 @@ class dsp_plugin:
|
|||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.stop()
|
self.stop()
|
||||||
del(self.process)
|
del(self.process)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user