Added more sliders and buttons, waterfall colors are now adjustable from the GUI.
This commit is contained in:
parent
3c1d3b5b42
commit
06bd8b92aa
@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
This file is part of OpenWebRX,
|
This file is part of OpenWebRX,
|
||||||
an open-source SDR receiver software with a web UI.
|
an open-source SDR receiver software with a web UI.
|
||||||
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
|
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
|
||||||
|
|
||||||
@ -31,8 +31,8 @@
|
|||||||
var starting_mod = "%[START_MOD]";
|
var starting_mod = "%[START_MOD]";
|
||||||
var starting_offset_frequency = %[START_OFFSET_FREQ];
|
var starting_offset_frequency = %[START_OFFSET_FREQ];
|
||||||
var waterfall_colors=%[WATERFALL_COLORS];
|
var waterfall_colors=%[WATERFALL_COLORS];
|
||||||
var waterfall_min_level=%[WATERFALL_MIN_LEVEL];
|
var waterfall_min_level_default=%[WATERFALL_MIN_LEVEL];
|
||||||
var waterfall_max_level=%[WATERFALL_MAX_LEVEL];
|
var waterfall_max_level_default=%[WATERFALL_MAX_LEVEL];
|
||||||
</script>
|
</script>
|
||||||
<script src="sdr.js"></script>
|
<script src="sdr.js"></script>
|
||||||
<script src="openwebrx.js"></script>
|
<script src="openwebrx.js"></script>
|
||||||
@ -42,8 +42,8 @@
|
|||||||
<body onload="openwebrx_init();">
|
<body onload="openwebrx_init();">
|
||||||
<div id="webrx-page-container">
|
<div id="webrx-page-container">
|
||||||
<div id="webrx-top-container">
|
<div id="webrx-top-container">
|
||||||
<div id="webrx-top-photo-clip">
|
<div id="webrx-top-photo-clip">
|
||||||
<img src="gfx/openwebrx-top-photo.jpg" id="webrx-top-photo"/>
|
<img src="gfx/openwebrx-top-photo.jpg" id="webrx-top-photo"/>
|
||||||
<div id="webrx-rx-photo-title">%[RX_PHOTO_TITLE]</div>
|
<div id="webrx-rx-photo-title">%[RX_PHOTO_TITLE]</div>
|
||||||
<div id="webrx-rx-photo-desc">%[RX_PHOTO_DESC]</div>
|
<div id="webrx-rx-photo-desc">%[RX_PHOTO_DESC]</div>
|
||||||
</div>
|
</div>
|
||||||
@ -72,27 +72,43 @@
|
|||||||
<div id="openwebrx-scale-container">
|
<div id="openwebrx-scale-container">
|
||||||
<canvas id="openwebrx-scale-canvas" width="0" height="0"></canvas>
|
<canvas id="openwebrx-scale-canvas" width="0" height="0"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="webrx-canvas-container">
|
<div id="webrx-canvas-container">
|
||||||
|
|
||||||
<div id="openwebrx-phantom-canvas"></div>
|
<div id="openwebrx-phantom-canvas"></div>
|
||||||
<!-- add canvas here by javascript -->
|
<!-- add canvas here by javascript -->
|
||||||
</div>
|
</div>
|
||||||
<div id="openwebrx-panels-container">
|
<div id="openwebrx-panels-container">
|
||||||
<div class="openwebrx-panel" id="openwebrx-panel-receiver" data-panel-name="client-params" data-panel-pos="right" data-panel-order="0" data-panel-size="215,115">
|
<div class="openwebrx-panel" id="openwebrx-panel-receiver" data-panel-name="client-params" data-panel-pos="right" data-panel-order="0" data-panel-size="259,115">
|
||||||
<div id="webrx-actual-freq">---.--- MHz</div>
|
<div id="webrx-actual-freq">---.--- MHz</div>
|
||||||
<div id="webrx-mouse-freq">---.--- MHz</div>
|
<div id="webrx-mouse-freq">---.--- MHz</div>
|
||||||
<!--<div class="openwebrx-button" onclick="ws.send('SET mod=wfm');" >WFM</div>-->
|
<!--<div class="openwebrx-button" onclick="ws.send('SET mod=wfm');" >WFM</div>-->
|
||||||
|
|
||||||
<div class="openwebrx-panel-line">
|
<div class="openwebrx-panel-line">
|
||||||
<div class="openwebrx-button" onclick="demodulator_analog_replace('nfm');">FM</div>
|
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('nfm');">FM</div>
|
||||||
<div class="openwebrx-button" onclick="demodulator_analog_replace('am');">AM</div>
|
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('am');">AM</div>
|
||||||
<div class="openwebrx-button" onclick="demodulator_analog_replace('lsb');">LSB</div>
|
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('lsb');">LSB</div>
|
||||||
<div class="openwebrx-button" onclick="demodulator_analog_replace('usb');">USB</div>
|
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('usb');">USB</div>
|
||||||
<div class="openwebrx-button" onclick="demodulator_analog_replace('cw');">CW</div>
|
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('cw');">CW</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="openwebrx-panel-line">
|
<div class="openwebrx-panel-line">
|
||||||
<div id="openwebrx-mute-off" class="openwebrx-button" onclick="toggleMute()"><img src="gfx/openwebrx-speaker.png" id="openwebrx-mute-img"></div>
|
<div title="Mute on/off" id="openwebrx-mute-off" class="openwebrx-button" onclick="toggleMute();"><img src="gfx/openwebrx-speaker.png" class="openwebrx-sliderbtn-img"></div>
|
||||||
<input id="openwebrx-panel-volume" type="range" min="0" max="150" value="50" step="1" onchange="updateVolume()" oninput="updateVolume()">
|
<input title="Volume" id="openwebrx-panel-volume" class="openwebrx-panel-slider" type="range" min="0" max="150" value="50" step="1" onchange="updateVolume()" oninput="updateVolume()">
|
||||||
|
<div title="Auto-adjust waterfall colors" id="openwebrx-waterfall-colors-auto" class="openwebrx-button" onclick="waterfall_measure_minmax_now=true;"><img src="gfx/openwebrx-waterfall-auto.png" class="openwebrx-sliderbtn-img"></div>
|
||||||
|
<input title="Waterfall minimum level" id="openwebrx-waterfall-color-min" class="openwebrx-panel-slider" type="range" min="-200" max="100" value="50" step="1" onchange="updateWaterfallColors(0);" oninput="updateVolume()">
|
||||||
|
</div>
|
||||||
|
<div class="openwebrx-panel-line">
|
||||||
|
<div title="Disable squelch" id="openwebrx-squelch-default" class="openwebrx-button" onclick="setSquelchDefault()"><img src="gfx/openwebrx-squelch-button.png" class="openwebrx-sliderbtn-img"></div>
|
||||||
|
<input title="Squelch" id="openwebrx-panel-squelch" class="openwebrx-panel-slider" type="range" min="0" max="100" value="0" step="1" onchange="updateVolume()" oninput="updateVolume()">
|
||||||
|
<div title="Set waterfall colors to default" id="openwebrx-waterfall-colors-default" class="openwebrx-button" onclick="waterfallColorsDefault()"><img src="gfx/openwebrx-waterfall-default.png" class="openwebrx-sliderbtn-img"></div>
|
||||||
|
<input title="Waterfall maximum level" id="openwebrx-waterfall-color-max" class="openwebrx-panel-slider" type="range" min="-200" max="100" value="50" step="1" onchange="updateWaterfallColors(1);" oninput="updateVolume()">
|
||||||
|
</div>
|
||||||
|
<div class="openwebrx-panel-line">
|
||||||
|
<div class="openwebrx-button openwebrx-square-button" onclick="zoomInOneStep();" title="Zoom in one step"> <img src="gfx/openwebrx-zoom-in.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="zoomOutTotal();" title="Zoom out totally"><img src="gfx/openwebrx-zoom-out-total.png" /></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
This file is part of OpenWebRX,
|
This file is part of OpenWebRX,
|
||||||
an open-source SDR receiver software with a web UI.
|
an open-source SDR receiver software with a web UI.
|
||||||
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
|
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
|
||||||
|
|
||||||
@ -37,7 +37,6 @@ input[type=range]
|
|||||||
{
|
{
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
input[type=range]:focus
|
input[type=range]:focus
|
||||||
{
|
{
|
||||||
@ -242,7 +241,7 @@ input[type=range]:focus::-ms-fill-upper
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
background-image:url(gfx/webrx-photo-gradient-corner.png);
|
background-image:url(gfx/webrx-photo-gradient-corner.png);
|
||||||
width: 59px;
|
width: 59px;
|
||||||
height: 92px;
|
height: 92px;
|
||||||
|
|
||||||
@ -255,7 +254,7 @@ input[type=range]:focus::-ms-fill-upper
|
|||||||
left: 59px;
|
left: 59px;
|
||||||
right: 59px;
|
right: 59px;
|
||||||
height: 92px;
|
height: 92px;
|
||||||
background-image:url(gfx/webrx-photo-gradient-middle.png);
|
background-image:url(gfx/webrx-photo-gradient-middle.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
#webrx-photo-gradient-right
|
#webrx-photo-gradient-right
|
||||||
@ -263,7 +262,7 @@ input[type=range]:focus::-ms-fill-upper
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
background-image:url(gfx/webrx-photo-gradient-corner.png);
|
background-image:url(gfx/webrx-photo-gradient-corner.png);
|
||||||
width: 59px;
|
width: 59px;
|
||||||
height: 92px;
|
height: 92px;
|
||||||
-webkit-transform:scaleX(-1);
|
-webkit-transform:scaleX(-1);
|
||||||
@ -456,7 +455,7 @@ input[type=range]:focus::-ms-fill-upper
|
|||||||
background-color: #999999;
|
background-color: #999999;
|
||||||
color: White;
|
color: White;
|
||||||
z-index:9999; /*should be higher?
|
z-index:9999; /*should be higher?
|
||||||
|
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
/* removed non-free fonts like that: */
|
/* removed non-free fonts like that: */
|
||||||
@ -484,7 +483,7 @@ input[type=range]:focus::-ms-fill-upper
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
line-height:22px;
|
line-height:22px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#webrx-mouse-freq
|
#webrx-mouse-freq
|
||||||
@ -497,6 +496,7 @@ input[type=range]:focus::-ms-fill-upper
|
|||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.openwebrx-panel
|
.openwebrx-panel
|
||||||
{
|
{
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
@ -551,13 +551,72 @@ input[type=range]:focus::-ms-fill-upper
|
|||||||
color: #FFFF50;
|
color: #FFFF50;
|
||||||
}
|
}
|
||||||
|
|
||||||
.openwebrx-button:active
|
.openwebrx-button:active
|
||||||
{
|
{
|
||||||
background: #777777;
|
background: #777777;
|
||||||
color: #FFFF50;
|
color: #FFFF50;
|
||||||
}
|
}
|
||||||
|
|
||||||
#openwebrx-client-log-title
|
.openwebrx-demodulator-button
|
||||||
|
{
|
||||||
|
width: 35px;
|
||||||
|
height: 19px;
|
||||||
|
font-size: 12pt;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openwebrx-square-button img
|
||||||
|
{
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openwebrx-round-button
|
||||||
|
{
|
||||||
|
margin-right: -2px;
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
border-radius: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openwebrx-round-button img
|
||||||
|
{
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openwebrx-round-button-small
|
||||||
|
{
|
||||||
|
margin-right: -3px;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openwebrx-round-button-small img
|
||||||
|
{
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.openwebrx-mirror-img
|
||||||
|
{
|
||||||
|
transform: scale(-1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.openwebrx-round-rightarrow img
|
||||||
|
{
|
||||||
|
position: relative;
|
||||||
|
left: 12px;
|
||||||
|
top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openwebrx-round-leftarrow img
|
||||||
|
{
|
||||||
|
position: relative;
|
||||||
|
left: 7px;
|
||||||
|
top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#openwebrx-client-log-title
|
||||||
{
|
{
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -626,7 +685,7 @@ input[type=range]:focus::-ms-fill-upper
|
|||||||
display: table-cell;
|
display: table-cell;
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
cursor:pointer;
|
cursor:pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#openwebrx-main-buttons li:hover
|
#openwebrx-main-buttons li:hover
|
||||||
@ -668,14 +727,14 @@ input[type=range]:focus::-ms-fill-upper
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
#openwebrx-panel-volume
|
.openwebrx-panel-slider
|
||||||
{
|
{
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -2px;
|
top: -2px;
|
||||||
width:170px;
|
width:91px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#openwebrx-mute-img
|
.openwebrx-sliderbtn-img
|
||||||
{
|
{
|
||||||
width: 14px;
|
width: 14px;
|
||||||
position:relative;
|
position:relative;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
This file is part of OpenWebRX,
|
This file is part of OpenWebRX,
|
||||||
an open-source SDR receiver software with a web UI.
|
an open-source SDR receiver software with a web UI.
|
||||||
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
|
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
|
||||||
|
|
||||||
@ -58,12 +58,12 @@ var waterfall_timer;
|
|||||||
something.fade_i=0;
|
something.fade_i=0;
|
||||||
n_of_iters=time_ms/(1000/fps);
|
n_of_iters=time_ms/(1000/fps);
|
||||||
change=(to-from)/(n_of_iters-1);
|
change=(to-from)/(n_of_iters-1);
|
||||||
|
|
||||||
something.fade_timer=window.setInterval(
|
something.fade_timer=window.setInterval(
|
||||||
function(){
|
function(){
|
||||||
if(something.fade_i++<n_of_iters)
|
if(something.fade_i++<n_of_iters)
|
||||||
something.style.opacity=parseFloat(something.style.opacity)+change;
|
something.style.opacity=parseFloat(something.style.opacity)+change;
|
||||||
else
|
else
|
||||||
{something.style.opacity=to; window.clearInterval(something.fade_timer); }
|
{something.style.opacity=to; window.clearInterval(something.fade_timer); }
|
||||||
},1000/fps);
|
},1000/fps);
|
||||||
}*/
|
}*/
|
||||||
@ -115,12 +115,12 @@ function open_rx_photo()
|
|||||||
function style_value(of_what,which)
|
function style_value(of_what,which)
|
||||||
{
|
{
|
||||||
if(of_what.currentStyle) return of_what.currentStyle[which];
|
if(of_what.currentStyle) return of_what.currentStyle[which];
|
||||||
else if (window.getComputedStyle) return document.defaultView.getComputedStyle(of_what,null).getPropertyValue(which);
|
else if (window.getComputedStyle) return document.defaultView.getComputedStyle(of_what,null).getPropertyValue(which);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateVolume()
|
function updateVolume()
|
||||||
{
|
{
|
||||||
volume = parseFloat(e("openwebrx-panel-volume").value) / 100;
|
volume = parseFloat(e("openwebrx-panel-volume").value) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleMute()
|
function toggleMute()
|
||||||
@ -137,15 +137,46 @@ function toggleMute()
|
|||||||
e("openwebrx-mute-off").id="openwebrx-mute-on";
|
e("openwebrx-mute-off").id="openwebrx-mute-on";
|
||||||
e("openwebrx-mute-img").src="gfx/openwebrx-speaker-muted.png";
|
e("openwebrx-mute-img").src="gfx/openwebrx-speaker-muted.png";
|
||||||
e("openwebrx-panel-volume").disabled=true;
|
e("openwebrx-panel-volume").disabled=true;
|
||||||
e("openwebrx-panel-volume").style.opacity=0.5;
|
e("openwebrx-panel-volume").style.opacity=0.5;
|
||||||
volumeBeforeMute = e("openwebrx-panel-volume").value;
|
volumeBeforeMute = e("openwebrx-panel-volume").value;
|
||||||
e("openwebrx-panel-volume").value=0;
|
e("openwebrx-panel-volume").value=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateVolume();
|
updateVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function zoomInOneStep () { zoom_set(zoom_level+1); }
|
||||||
|
function zoomOutOneStep () { zoom_set(zoom_level-1); }
|
||||||
|
function zoomInTotal () { zoom_set(zoom_levels.length-1); }
|
||||||
|
function zoomOutTotal () { zoom_set(0); }
|
||||||
|
function setSquelchDefault() { e("openwebrx-panel-squelch").value=0; }
|
||||||
|
|
||||||
|
function updateWaterfallColors(which)
|
||||||
|
{
|
||||||
|
wfmax=e("openwebrx-waterfall-color-max");
|
||||||
|
wfmin=e("openwebrx-waterfall-color-min");
|
||||||
|
if(parseInt(wfmin.value)>=parseInt(wfmax.value))
|
||||||
|
{
|
||||||
|
if(!which) wfmin.value=(parseInt(wfmax.value)-1).toString();
|
||||||
|
else wfmax.value=(parseInt(wfmin.value)+1).toString();
|
||||||
|
}
|
||||||
|
waterfall_min_level=parseInt(wfmin.value);
|
||||||
|
waterfall_max_level=parseInt(wfmax.value);
|
||||||
|
}
|
||||||
|
function waterfallColorsDefault()
|
||||||
|
{
|
||||||
|
waterfall_min_level=waterfall_min_level_default;
|
||||||
|
waterfall_max_level=waterfall_max_level_default;
|
||||||
|
e("openwebrx-waterfall-color-min").value=waterfall_min_level.toString();
|
||||||
|
e("openwebrx-waterfall-color-max").value=waterfall_max_level.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
function waterfallColorsAuto()
|
||||||
|
{
|
||||||
|
e("openwebrx-waterfall-color-min").value=(waterfall_measure_minmax_min-20).toString();
|
||||||
|
e("openwebrx-waterfall-color-max").value=(waterfall_measure_minmax_max+30).toString();
|
||||||
|
updateWaterfallColors(0);
|
||||||
|
}
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// ================= ANIMATION ROUTINES =================
|
// ================= ANIMATION ROUTINES =================
|
||||||
@ -165,8 +196,8 @@ function animate(object,style_name,unit,from,to,accel,time_ms,fps,to_exec)
|
|||||||
if(object.anim_i++<n_of_iters)
|
if(object.anim_i++<n_of_iters)
|
||||||
{
|
{
|
||||||
if(accel==1) object.style[style_name]=(parseFloat(object.style[style_name])+change).toString()+unit;
|
if(accel==1) object.style[style_name]=(parseFloat(object.style[style_name])+change).toString()+unit;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
remain=parseFloat(object.style[style_name])-to;
|
remain=parseFloat(object.style[style_name])-to;
|
||||||
if(Math.abs(remain)>9||unit!="px") new_val=(to+accel*remain);
|
if(Math.abs(remain)>9||unit!="px") new_val=(to+accel*remain);
|
||||||
else {if(Math.abs(remain)<2) new_val=to;
|
else {if(Math.abs(remain)<2) new_val=to;
|
||||||
@ -174,7 +205,7 @@ function animate(object,style_name,unit,from,to,accel,time_ms,fps,to_exec)
|
|||||||
object.style[style_name]=new_val.toString()+unit;
|
object.style[style_name]=new_val.toString()+unit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{object.style[style_name]=to.toString()+unit; window.clearInterval(object.anim_timer); delete object.anim_timer; }
|
{object.style[style_name]=to.toString()+unit; window.clearInterval(object.anim_timer); delete object.anim_timer; }
|
||||||
if(to_exec!=0) to_exec();
|
if(to_exec!=0) to_exec();
|
||||||
},1000/fps);
|
},1000/fps);
|
||||||
@ -209,7 +240,7 @@ function demod_envelope_draw(range, from, to, color, line)
|
|||||||
// A "drag range" object is returned, containing information about the draggable areas of the envelope
|
// A "drag range" object is returned, containing information about the draggable areas of the envelope
|
||||||
// (beginning, ending and the line showing the offset frequency).
|
// (beginning, ending and the line showing the offset frequency).
|
||||||
if(typeof color == "undefined") color="#ffff00"; //yellow
|
if(typeof color == "undefined") color="#ffff00"; //yellow
|
||||||
env_bounding_line_w=5; //
|
env_bounding_line_w=5; //
|
||||||
env_att_w=5; // _______ ___env_h2 in px ___|_____
|
env_att_w=5; // _______ ___env_h2 in px ___|_____
|
||||||
env_h1=17; // _/| \_ ___env_h1 in px _/ |_ \_
|
env_h1=17; // _/| \_ ___env_h1 in px _/ |_ \_
|
||||||
env_h2=5; // |||env_att_line_w |_env_lineplus
|
env_h2=5; // |||env_att_line_w |_env_lineplus
|
||||||
@ -219,11 +250,11 @@ function demod_envelope_draw(range, from, to, color, line)
|
|||||||
from_px=scale_px_from_freq(from,range);
|
from_px=scale_px_from_freq(from,range);
|
||||||
to_px=scale_px_from_freq(to,range);
|
to_px=scale_px_from_freq(to,range);
|
||||||
if(to_px<from_px) /* swap'em */ { temp_px=to_px; to_px=from_px; from_px=temp_px; }
|
if(to_px<from_px) /* swap'em */ { temp_px=to_px; to_px=from_px; from_px=temp_px; }
|
||||||
|
|
||||||
/*from_px-=env_bounding_line_w/2;
|
/*from_px-=env_bounding_line_w/2;
|
||||||
to_px+=env_bounding_line_w/2;*/
|
to_px+=env_bounding_line_w/2;*/
|
||||||
from_px-=(env_att_w+env_bounding_line_w);
|
from_px-=(env_att_w+env_bounding_line_w);
|
||||||
to_px+=(env_att_w+env_bounding_line_w);
|
to_px+=(env_att_w+env_bounding_line_w);
|
||||||
// do drawing:
|
// do drawing:
|
||||||
scale_ctx.lineWidth=3;
|
scale_ctx.lineWidth=3;
|
||||||
scale_ctx.strokeStyle=color;
|
scale_ctx.strokeStyle=color;
|
||||||
@ -247,7 +278,7 @@ function demod_envelope_draw(range, from, to, color, line)
|
|||||||
scale_ctx.globalAlpha = 1;
|
scale_ctx.globalAlpha = 1;
|
||||||
scale_ctx.stroke();
|
scale_ctx.stroke();
|
||||||
}
|
}
|
||||||
if(typeof line != "undefined") // out of screen?
|
if(typeof line != "undefined") // out of screen?
|
||||||
{
|
{
|
||||||
line_px=scale_px_from_freq(line,range);
|
line_px=scale_px_from_freq(line,range);
|
||||||
if(!(line_px<0||line_px>window.innerWidth))
|
if(!(line_px<0||line_px>window.innerWidth))
|
||||||
@ -275,12 +306,12 @@ function demod_envelope_where_clicked(x, drag_ranges, key_modifiers)
|
|||||||
if(drag_ranges.envelope_on_screen&&in_range(x,drag_ranges.whole_envelope)) return dr.pbs;
|
if(drag_ranges.envelope_on_screen&&in_range(x,drag_ranges.whole_envelope)) return dr.pbs;
|
||||||
}
|
}
|
||||||
if(drag_ranges.envelope_on_screen)
|
if(drag_ranges.envelope_on_screen)
|
||||||
{
|
{
|
||||||
// For low and high cut:
|
// For low and high cut:
|
||||||
if(in_range(x,drag_ranges.beginning)) return dr.beginning;
|
if(in_range(x,drag_ranges.beginning)) return dr.beginning;
|
||||||
if(in_range(x,drag_ranges.ending)) return dr.ending;
|
if(in_range(x,drag_ranges.ending)) return dr.ending;
|
||||||
// Last priority: having clicked anything else on the envelope, without holding the shift key
|
// Last priority: having clicked anything else on the envelope, without holding the shift key
|
||||||
if(in_range(x,drag_ranges.whole_envelope)) return dr.anything_else;
|
if(in_range(x,drag_ranges.whole_envelope)) return dr.anything_else;
|
||||||
}
|
}
|
||||||
return dr.none; //User doesn't drag the envelope for this demodulator
|
return dr.none; //User doesn't drag the envelope for this demodulator
|
||||||
}
|
}
|
||||||
@ -304,7 +335,7 @@ demodulator.draggable_ranges={none: 0, beginning:1 /*from*/, ending: 2 /*to*/, a
|
|||||||
// This can be used as a base for basic audio demodulators.
|
// This can be used as a base for basic audio demodulators.
|
||||||
// It already supports most basic modulations used for ham radio and commercial services: AM/FM/LSB/USB
|
// It already supports most basic modulations used for ham radio and commercial services: AM/FM/LSB/USB
|
||||||
|
|
||||||
demodulator_response_time=50;
|
demodulator_response_time=50;
|
||||||
//in ms; if we don't limit the number of SETs sent to the server, audio will underrun (possibly output buffer is cleared on SETs in GNU Radio
|
//in ms; if we don't limit the number of SETs sent to the server, audio will underrun (possibly output buffer is cleared on SETs in GNU Radio
|
||||||
|
|
||||||
function demodulator_default_analog(offset_frequency,subtype)
|
function demodulator_default_analog(offset_frequency,subtype)
|
||||||
@ -318,7 +349,7 @@ function demodulator_default_analog(offset_frequency,subtype)
|
|||||||
high_cut_limit: audio_context.sampleRate/2,
|
high_cut_limit: audio_context.sampleRate/2,
|
||||||
low_cut_limit: -audio_context.sampleRate/2
|
low_cut_limit: -audio_context.sampleRate/2
|
||||||
};
|
};
|
||||||
//Subtypes only define some filter parameters and the mod string sent to server,
|
//Subtypes only define some filter parameters and the mod string sent to server,
|
||||||
//so you may set these parameters in your custom child class.
|
//so you may set these parameters in your custom child class.
|
||||||
//Why? As of demodulation is done on the server, difference is mainly on the server side.
|
//Why? As of demodulation is done on the server, difference is mainly on the server side.
|
||||||
this.server_mod=subtype;
|
this.server_mod=subtype;
|
||||||
@ -339,23 +370,23 @@ function demodulator_default_analog(offset_frequency,subtype)
|
|||||||
this.low_cut=700;
|
this.low_cut=700;
|
||||||
this.high_cut=900;
|
this.high_cut=900;
|
||||||
this.server_mod="ssb";
|
this.server_mod="ssb";
|
||||||
}
|
}
|
||||||
else if(subtype=="nfm")
|
else if(subtype=="nfm")
|
||||||
{
|
{
|
||||||
this.low_cut=-4000;
|
this.low_cut=-4000;
|
||||||
this.high_cut=4000;
|
this.high_cut=4000;
|
||||||
}
|
}
|
||||||
else if(subtype=="am")
|
else if(subtype=="am")
|
||||||
{
|
{
|
||||||
this.low_cut=-4000;
|
this.low_cut=-4000;
|
||||||
this.high_cut=4000;
|
this.high_cut=4000;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.wait_for_timer=false;
|
this.wait_for_timer=false;
|
||||||
this.set_after=false;
|
this.set_after=false;
|
||||||
this.set=function()
|
this.set=function()
|
||||||
{ //set() is a wrapper to call doset(), but it ensures that doset won't execute more frequently than demodulator_response_time.
|
{ //set() is a wrapper to call doset(), but it ensures that doset won't execute more frequently than demodulator_response_time.
|
||||||
if(!this.wait_for_timer)
|
if(!this.wait_for_timer)
|
||||||
{
|
{
|
||||||
this.doset(false);
|
this.doset(false);
|
||||||
this.set_after=false;
|
this.set_after=false;
|
||||||
@ -384,7 +415,7 @@ function demodulator_default_analog(offset_frequency,subtype)
|
|||||||
// for drawing the filter envelope above scale
|
// for drawing the filter envelope above scale
|
||||||
this.envelope.parent=this;
|
this.envelope.parent=this;
|
||||||
|
|
||||||
this.envelope.draw=function(visible_range)
|
this.envelope.draw=function(visible_range)
|
||||||
{
|
{
|
||||||
this.visible_range=visible_range;
|
this.visible_range=visible_range;
|
||||||
this.drag_ranges=demod_envelope_draw(range,
|
this.drag_ranges=demod_envelope_draw(range,
|
||||||
@ -428,22 +459,22 @@ function demodulator_default_analog(offset_frequency,subtype)
|
|||||||
//dragging any other parts of the filter envelope while holding Shift does emulate the PBS knob
|
//dragging any other parts of the filter envelope while holding Shift does emulate the PBS knob
|
||||||
//(PassBand Shift) on radio equipment: PBS does move the whole passband without moving the offset
|
//(PassBand Shift) on radio equipment: PBS does move the whole passband without moving the offset
|
||||||
//frequency.
|
//frequency.
|
||||||
if(this.dragged_range==dr.beginning||this.dragged_range==dr.bfo||this.dragged_range==dr.pbs)
|
if(this.dragged_range==dr.beginning||this.dragged_range==dr.bfo||this.dragged_range==dr.pbs)
|
||||||
{
|
{
|
||||||
//we don't let low_cut go beyond its limits
|
//we don't let low_cut go beyond its limits
|
||||||
if((new_value=this.drag_origin.low_cut+minus*freq_change)<this.parent.filter.low_cut_limit) return true;
|
if((new_value=this.drag_origin.low_cut+minus*freq_change)<this.parent.filter.low_cut_limit) return true;
|
||||||
//nor the filter passband be too small
|
//nor the filter passband be too small
|
||||||
if(this.parent.high_cut-new_value<this.parent.filter.min_passband) return true;
|
if(this.parent.high_cut-new_value<this.parent.filter.min_passband) return true;
|
||||||
//sanity check to prevent GNU Radio "firdes check failed: fa <= fb"
|
//sanity check to prevent GNU Radio "firdes check failed: fa <= fb"
|
||||||
if(new_value>=this.parent.high_cut) return true;
|
if(new_value>=this.parent.high_cut) return true;
|
||||||
this.parent.low_cut=new_value;
|
this.parent.low_cut=new_value;
|
||||||
}
|
}
|
||||||
if(this.dragged_range==dr.ending||this.dragged_range==dr.bfo||this.dragged_range==dr.pbs)
|
if(this.dragged_range==dr.ending||this.dragged_range==dr.bfo||this.dragged_range==dr.pbs)
|
||||||
{
|
{
|
||||||
//we don't let high_cut go beyond its limits
|
//we don't let high_cut go beyond its limits
|
||||||
if((new_value=this.drag_origin.high_cut+minus*freq_change)>this.parent.filter.high_cut_limit) return true;
|
if((new_value=this.drag_origin.high_cut+minus*freq_change)>this.parent.filter.high_cut_limit) return true;
|
||||||
//nor the filter passband be too small
|
//nor the filter passband be too small
|
||||||
if(new_value-this.parent.low_cut<this.parent.filter.min_passband) return true;
|
if(new_value-this.parent.low_cut<this.parent.filter.min_passband) return true;
|
||||||
//sanity check to prevent GNU Radio "firdes check failed: fa <= fb"
|
//sanity check to prevent GNU Radio "firdes check failed: fa <= fb"
|
||||||
if(new_value<=this.parent.low_cut) return true;
|
if(new_value<=this.parent.low_cut) return true;
|
||||||
this.parent.high_cut=new_value;
|
this.parent.high_cut=new_value;
|
||||||
@ -459,17 +490,17 @@ function demodulator_default_analog(offset_frequency,subtype)
|
|||||||
mkenvelopes(this.visible_range);
|
mkenvelopes(this.visible_range);
|
||||||
this.parent.set();
|
this.parent.set();
|
||||||
//will have to change this when changing to multi-demodulator mode:
|
//will have to change this when changing to multi-demodulator mode:
|
||||||
e("webrx-actual-freq").innerHTML=format_frequency("{x} MHz",center_freq+this.parent.offset_frequency,1e6,4);
|
e("webrx-actual-freq").innerHTML=format_frequency("{x} MHz",center_freq+this.parent.offset_frequency,1e6,4);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.envelope.drag_end=function(x)
|
this.envelope.drag_end=function(x)
|
||||||
{ //in this demodulator we've already changed values in the drag_move() function so we shouldn't do too much here.
|
{ //in this demodulator we've already changed values in the drag_move() function so we shouldn't do too much here.
|
||||||
to_return=this.dragged_range!=demodulator.draggable_ranges.none; //this part is required for cliking anywhere on the scale to set offset
|
to_return=this.dragged_range!=demodulator.draggable_ranges.none; //this part is required for cliking anywhere on the scale to set offset
|
||||||
this.dragged_range=demodulator.draggable_ranges.none;
|
this.dragged_range=demodulator.draggable_ranges.none;
|
||||||
return to_return;
|
return to_return;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
demodulator_default_analog.prototype=new demodulator();
|
demodulator_default_analog.prototype=new demodulator();
|
||||||
@ -496,9 +527,9 @@ function demodulator_add(what)
|
|||||||
}
|
}
|
||||||
|
|
||||||
function demodulator_analog_replace(subtype)
|
function demodulator_analog_replace(subtype)
|
||||||
{ //this function should only exist until the multi-demodulator capability is added
|
{ //this function should only exist until the multi-demodulator capability is added
|
||||||
var temp_offset=0;
|
var temp_offset=0;
|
||||||
if(demodulators.length)
|
if(demodulators.length)
|
||||||
{
|
{
|
||||||
temp_offset=demodulators[0].offset_frequency;
|
temp_offset=demodulators[0].offset_frequency;
|
||||||
demodulator_remove(0);
|
demodulator_remove(0);
|
||||||
@ -525,7 +556,7 @@ var scale_canvas;
|
|||||||
function scale_setup()
|
function scale_setup()
|
||||||
{
|
{
|
||||||
e("webrx-actual-freq").innerHTML=format_frequency("{x} MHz",canvas_get_frequency(window.innerWidth/2),1e6,4);
|
e("webrx-actual-freq").innerHTML=format_frequency("{x} MHz",canvas_get_frequency(window.innerWidth/2),1e6,4);
|
||||||
scale_canvas=e("openwebrx-scale-canvas");
|
scale_canvas=e("openwebrx-scale-canvas");
|
||||||
scale_ctx=scale_canvas.getContext("2d");
|
scale_ctx=scale_canvas.getContext("2d");
|
||||||
scale_canvas.addEventListener("mousedown", scale_canvas_mousedown, false);
|
scale_canvas.addEventListener("mousedown", scale_canvas_mousedown, false);
|
||||||
scale_canvas.addEventListener("mousemove", scale_canvas_mousemove, false);
|
scale_canvas.addEventListener("mousemove", scale_canvas_mousemove, false);
|
||||||
@ -563,7 +594,7 @@ function scale_offset_freq_from_px(x, visible_range)
|
|||||||
function scale_canvas_mousemove(evt)
|
function scale_canvas_mousemove(evt)
|
||||||
{
|
{
|
||||||
var event_handled;
|
var event_handled;
|
||||||
if(scale_canvas_drag_params.mouse_down&&!scale_canvas_drag_params.drag&&Math.abs(evt.pageX-scale_canvas_drag_params.start_x)>canvas_drag_min_delta)
|
if(scale_canvas_drag_params.mouse_down&&!scale_canvas_drag_params.drag&&Math.abs(evt.pageX-scale_canvas_drag_params.start_x)>canvas_drag_min_delta)
|
||||||
//we can use the main drag_min_delta thing of the main canvas
|
//we can use the main drag_min_delta thing of the main canvas
|
||||||
{
|
{
|
||||||
scale_canvas_drag_params.drag=true;
|
scale_canvas_drag_params.drag=true;
|
||||||
@ -577,7 +608,7 @@ function scale_canvas_mousemove(evt)
|
|||||||
for (var i=0;i<demodulators.length;i++) event_handled|=demodulators[i].envelope.drag_move(evt.pageX);
|
for (var i=0;i<demodulators.length;i++) event_handled|=demodulators[i].envelope.drag_move(evt.pageX);
|
||||||
if (!event_handled) demodulator_set_offset_frequency(0,scale_offset_freq_from_px(evt.pageX));
|
if (!event_handled) demodulator_set_offset_frequency(0,scale_offset_freq_from_px(evt.pageX));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function scale_canvas_end_drag(x)
|
function scale_canvas_end_drag(x)
|
||||||
@ -681,13 +712,13 @@ var scale_min_space_bw_small_markers=7;
|
|||||||
function get_scale_mark_spacing(range)
|
function get_scale_mark_spacing(range)
|
||||||
{
|
{
|
||||||
out={};
|
out={};
|
||||||
fcalc=function(freq)
|
fcalc=function(freq)
|
||||||
{
|
{
|
||||||
out.numlarge=(range.bw/freq);
|
out.numlarge=(range.bw/freq);
|
||||||
out.large=canvas_container.clientWidth/out.numlarge; //distance between large markers (these have text)
|
out.large=canvas_container.clientWidth/out.numlarge; //distance between large markers (these have text)
|
||||||
out.ratio=5; //(ratio-1) small markers exist per large marker
|
out.ratio=5; //(ratio-1) small markers exist per large marker
|
||||||
out.small=out.large/out.ratio; //distance between small markers
|
out.small=out.large/out.ratio; //distance between small markers
|
||||||
if(out.small<scale_min_space_bw_small_markers) return false;
|
if(out.small<scale_min_space_bw_small_markers) return false;
|
||||||
if(out.small/2>=scale_min_space_bw_small_markers&&freq.toString()[0]!="5") {out.small/=2; out.ratio*=2; }
|
if(out.small/2>=scale_min_space_bw_small_markers&&freq.toString()[0]!="5") {out.small/=2; out.ratio*=2; }
|
||||||
out.smallbw=freq/out.ratio;
|
out.smallbw=freq/out.ratio;
|
||||||
return true;
|
return true;
|
||||||
@ -725,11 +756,11 @@ function mkscale()
|
|||||||
{
|
{
|
||||||
var x=scale_px_from_freq(marker_hz,range);
|
var x=scale_px_from_freq(marker_hz,range);
|
||||||
if(x>window.innerWidth) break;
|
if(x>window.innerWidth) break;
|
||||||
scale_ctx.beginPath();
|
scale_ctx.beginPath();
|
||||||
scale_ctx.moveTo(x, 22);
|
scale_ctx.moveTo(x, 22);
|
||||||
if(marker_hz%spacing.params.large_marker_per_hz==0)
|
if(marker_hz%spacing.params.large_marker_per_hz==0)
|
||||||
{ //large marker
|
{ //large marker
|
||||||
if(typeof first_large == "undefined") var first_large=marker_hz;
|
if(typeof first_large == "undefined") var first_large=marker_hz;
|
||||||
last_large=marker_hz;
|
last_large=marker_hz;
|
||||||
scale_ctx.lineWidth=3.5;
|
scale_ctx.lineWidth=3.5;
|
||||||
scale_ctx.lineTo(x,22+11);
|
scale_ctx.lineTo(x,22+11);
|
||||||
@ -742,16 +773,16 @@ function mkscale()
|
|||||||
if(scale_px_from_freq(marker_hz+spacing.smallbw*spacing.ratio,range)-text_measured.width>=scale_min_space_bw_texts)
|
if(scale_px_from_freq(marker_hz+spacing.smallbw*spacing.ratio,range)-text_measured.width>=scale_min_space_bw_texts)
|
||||||
{ //and if we have enough space to draw it correctly without clipping
|
{ //and if we have enough space to draw it correctly without clipping
|
||||||
scale_ctx.textAlign = "left";
|
scale_ctx.textAlign = "left";
|
||||||
scale_ctx.fillText(text_to_draw, 0, text_h_pos);
|
scale_ctx.fillText(text_to_draw, 0, text_h_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( zoom_level==0 && (range.end-spacing.smallbw*spacing.ratio<marker_hz) && (x>window.innerWidth-text_measured.width/2) )
|
else if( zoom_level==0 && (range.end-spacing.smallbw*spacing.ratio<marker_hz) && (x>window.innerWidth-text_measured.width/2) )
|
||||||
{ // if this is the last overall marker when zoomed out... and if it would be clipped off the screen...
|
{ // if this is the last overall marker when zoomed out... and if it would be clipped off the screen...
|
||||||
if(window.innerWidth-text_measured.width-scale_px_from_freq(marker_hz-spacing.smallbw*spacing.ratio,range)>=scale_min_space_bw_texts)
|
if(window.innerWidth-text_measured.width-scale_px_from_freq(marker_hz-spacing.smallbw*spacing.ratio,range)>=scale_min_space_bw_texts)
|
||||||
{ //and if we have enough space to draw it correctly without clipping
|
{ //and if we have enough space to draw it correctly without clipping
|
||||||
scale_ctx.textAlign = "right";
|
scale_ctx.textAlign = "right";
|
||||||
scale_ctx.fillText(text_to_draw, window.innerWidth, text_h_pos);
|
scale_ctx.fillText(text_to_draw, window.innerWidth, text_h_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else scale_ctx.fillText(text_to_draw, x, text_h_pos); //draw text normally
|
else scale_ctx.fillText(text_to_draw, x, text_h_pos); //draw text normally
|
||||||
}
|
}
|
||||||
@ -791,7 +822,7 @@ function resize_scale()
|
|||||||
function canvas_mouseover(evt)
|
function canvas_mouseover(evt)
|
||||||
{
|
{
|
||||||
if(!waterfall_setup_done) return;
|
if(!waterfall_setup_done) return;
|
||||||
//e("webrx-freq-show").style.visibility="visible";
|
//e("webrx-freq-show").style.visibility="visible";
|
||||||
}
|
}
|
||||||
|
|
||||||
function canvas_mouseout(evt)
|
function canvas_mouseout(evt)
|
||||||
@ -854,17 +885,17 @@ function canvas_mousemove(evt)
|
|||||||
element.style.left=realX.toString()+"px";*/
|
element.style.left=realX.toString()+"px";*/
|
||||||
if(canvas_mouse_down)
|
if(canvas_mouse_down)
|
||||||
{
|
{
|
||||||
if(!canvas_drag&&Math.abs(evt.pageX-canvas_drag_start_x)>canvas_drag_min_delta)
|
if(!canvas_drag&&Math.abs(evt.pageX-canvas_drag_start_x)>canvas_drag_min_delta)
|
||||||
{
|
{
|
||||||
canvas_drag=true;
|
canvas_drag=true;
|
||||||
canvas_container.style.cursor="move";
|
canvas_container.style.cursor="move";
|
||||||
}
|
}
|
||||||
if(canvas_drag)
|
if(canvas_drag)
|
||||||
{
|
{
|
||||||
var deltaX=canvas_drag_last_x-evt.pageX;
|
var deltaX=canvas_drag_last_x-evt.pageX;
|
||||||
var deltaY=canvas_drag_last_y-evt.pageY;
|
var deltaY=canvas_drag_last_y-evt.pageY;
|
||||||
//zoom_center_where=zoom_center_where_calc(evt.pageX);
|
//zoom_center_where=zoom_center_where_calc(evt.pageX);
|
||||||
var dpx=range.hps*deltaX;
|
var dpx=range.hps*deltaX;
|
||||||
if(
|
if(
|
||||||
!(zoom_center_rel+dpx>(bandwidth/2-canvas_container.clientWidth*(1-zoom_center_where)*range.hps)) &&
|
!(zoom_center_rel+dpx>(bandwidth/2-canvas_container.clientWidth*(1-zoom_center_where)*range.hps)) &&
|
||||||
!(zoom_center_rel+dpx<-bandwidth/2+canvas_container.clientWidth*zoom_center_where*range.hps)
|
!(zoom_center_rel+dpx<-bandwidth/2+canvas_container.clientWidth*zoom_center_where*range.hps)
|
||||||
@ -892,10 +923,10 @@ function canvas_mouseup(evt)
|
|||||||
if(!waterfall_setup_done) return;
|
if(!waterfall_setup_done) return;
|
||||||
relativeX=(evt.offsetX)?evt.offsetX:evt.layerX;
|
relativeX=(evt.offsetX)?evt.offsetX:evt.layerX;
|
||||||
|
|
||||||
if(!canvas_drag)
|
if(!canvas_drag)
|
||||||
{
|
{
|
||||||
//ws.send("SET offset_freq="+canvas_get_freq_offset(relativeX).toString());
|
//ws.send("SET offset_freq="+canvas_get_freq_offset(relativeX).toString());
|
||||||
demodulator_set_offset_frequency(0, canvas_get_freq_offset(relativeX));
|
demodulator_set_offset_frequency(0, canvas_get_freq_offset(relativeX));
|
||||||
e("webrx-actual-freq").innerHTML=format_frequency("{x} MHz",canvas_get_frequency(relativeX),1e6,4);
|
e("webrx-actual-freq").innerHTML=format_frequency("{x} MHz",canvas_get_frequency(relativeX),1e6,4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -928,7 +959,7 @@ function canvas_mousewheel(evt)
|
|||||||
//console.log(dir);
|
//console.log(dir);
|
||||||
//i/=120;
|
//i/=120;
|
||||||
/*while (i--)*/ zoom_step(dir, relativeX, zoom_center_where_calc(evt.pageX));
|
/*while (i--)*/ zoom_step(dir, relativeX, zoom_center_where_calc(evt.pageX));
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
//evt.returnValue = false; //disable scrollbar move
|
//evt.returnValue = false; //disable scrollbar move
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -961,12 +992,26 @@ function mkzoomlevels()
|
|||||||
function zoom_step(out, where, onscreen)
|
function zoom_step(out, where, onscreen)
|
||||||
{
|
{
|
||||||
if((out&&zoom_level==0)||(!out&&zoom_level>=zoom_levels_count-1)) return;
|
if((out&&zoom_level==0)||(!out&&zoom_level>=zoom_levels_count-1)) return;
|
||||||
|
|
||||||
if(out) --zoom_level;
|
if(out) --zoom_level;
|
||||||
else ++zoom_level;
|
else ++zoom_level;
|
||||||
|
|
||||||
zoom_center_rel=canvas_get_freq_offset(where);
|
zoom_center_rel=canvas_get_freq_offset(where);
|
||||||
//console.log("zoom_step || zlevel: "+zoom_level.toString()+" zlevel_val: "+zoom_levels[zoom_level].toString()+" zoom_center_rel: "+zoom_center_rel.toString());
|
//console.log("zoom_step || zlevel: "+zoom_level.toString()+" zlevel_val: "+zoom_levels[zoom_level].toString()+" zoom_center_rel: "+zoom_center_rel.toString());
|
||||||
zoom_center_where=onscreen;
|
zoom_center_where=onscreen;
|
||||||
|
console.log(zoom_center_where, zoom_center_rel, where);
|
||||||
|
resize_canvases(true);
|
||||||
|
mkscale();
|
||||||
|
}
|
||||||
|
|
||||||
|
function zoom_set(level)
|
||||||
|
{
|
||||||
|
if(!(level>=0&&level<=zoom_levels.length-1)) return;
|
||||||
|
level=parseInt(level);
|
||||||
|
zoom_level = level;
|
||||||
|
//zoom_center_rel=canvas_get_freq_offset(-canvases[0].offsetLeft+canvas_container.clientWidth/2); //zoom to screen center instead of demod envelope
|
||||||
|
zoom_center_rel=demodulators[0].offset_frequency;
|
||||||
|
zoom_center_where=0.5+(zoom_center_rel/bandwidth); //this is a kind of hack
|
||||||
|
console.log(zoom_center_where, zoom_center_rel, -canvases[0].offsetLeft+canvas_container.clientWidth/2);
|
||||||
resize_canvases(true);
|
resize_canvases(true);
|
||||||
mkscale();
|
mkscale();
|
||||||
}
|
}
|
||||||
@ -977,7 +1022,7 @@ function zoom_calc()
|
|||||||
var canvases_new_width=winsize*zoom_levels[zoom_level];
|
var canvases_new_width=winsize*zoom_levels[zoom_level];
|
||||||
zoom_offset_px=-((canvases_new_width*(0.5+zoom_center_rel/bandwidth))-(winsize*zoom_center_where));
|
zoom_offset_px=-((canvases_new_width*(0.5+zoom_center_rel/bandwidth))-(winsize*zoom_center_where));
|
||||||
if(zoom_offset_px>0) zoom_offset_px=0;
|
if(zoom_offset_px>0) zoom_offset_px=0;
|
||||||
if(zoom_offset_px<winsize-canvases_new_width)
|
if(zoom_offset_px<winsize-canvases_new_width)
|
||||||
zoom_offset_px=winsize-canvases_new_width;
|
zoom_offset_px=winsize-canvases_new_width;
|
||||||
//console.log("zoom_calc || zopx:"+zoom_offset_px.toString()+ " maxoff:"+(winsize-canvases_new_width).toString()+" relval:"+(0.5+zoom_center_rel/bandwidth).toString() );
|
//console.log("zoom_calc || zopx:"+zoom_offset_px.toString()+ " maxoff:"+(winsize-canvases_new_width).toString()+" relval:"+(0.5+zoom_center_rel/bandwidth).toString() );
|
||||||
}
|
}
|
||||||
@ -1001,9 +1046,9 @@ function audio_calculate_resampling(targetRate)
|
|||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
audio_server_output_rate = Math.floor(targetRate / i);
|
audio_server_output_rate = Math.floor(targetRate / i);
|
||||||
if(audio_server_output_rate < output_range_min)
|
if(audio_server_output_rate < output_range_min)
|
||||||
{
|
{
|
||||||
audio_client_resampling_factor = audio_server_output_rate = 0;
|
audio_client_resampling_factor = audio_server_output_rate = 0;
|
||||||
divlog("Your audio card sampling rate ("+targetRate.toString()+") is not supported.<br />Please change your operating system default settings in order to fix this.",1);
|
divlog("Your audio card sampling rate ("+targetRate.toString()+") is not supported.<br />Please change your operating system default settings in order to fix this.",1);
|
||||||
}
|
}
|
||||||
if(audio_server_output_rate >= output_range_min && audio_server_output_rate <= output_range_max) break; //okay, we're done
|
if(audio_server_output_rate >= output_range_min && audio_server_output_rate <= output_range_max) break; //okay, we're done
|
||||||
@ -1029,7 +1074,7 @@ function on_ws_recv(evt)
|
|||||||
{
|
{
|
||||||
var stringData=arrayBufferToString(evt.data);
|
var stringData=arrayBufferToString(evt.data);
|
||||||
if(stringData.substring(0,16)=="CLIENT DE SERVER") divlog("Acknowledged WebSocket connection: "+stringData);
|
if(stringData.substring(0,16)=="CLIENT DE SERVER") divlog("Acknowledged WebSocket connection: "+stringData);
|
||||||
|
|
||||||
}
|
}
|
||||||
if(firstChars=="AUD")
|
if(firstChars=="AUD")
|
||||||
{
|
{
|
||||||
@ -1048,7 +1093,7 @@ function on_ws_recv(evt)
|
|||||||
else if(fft_compression="adpcm")
|
else if(fft_compression="adpcm")
|
||||||
{
|
{
|
||||||
fft_codec.reset();
|
fft_codec.reset();
|
||||||
|
|
||||||
var waterfall_i16=fft_codec.decode(new Uint8Array(evt.data,4));
|
var waterfall_i16=fft_codec.decode(new Uint8Array(evt.data,4));
|
||||||
var waterfall_f32=new Float32Array(waterfall_i16.length-COMPRESS_FFT_PAD_N);
|
var waterfall_f32=new Float32Array(waterfall_i16.length-COMPRESS_FFT_PAD_N);
|
||||||
for(var i=0;i<waterfall_i16.length;i++) waterfall_f32[i]=waterfall_i16[i+COMPRESS_FFT_PAD_N]/100;
|
for(var i=0;i<waterfall_i16.length;i++) waterfall_f32[i]=waterfall_i16[i+COMPRESS_FFT_PAD_N]/100;
|
||||||
@ -1068,10 +1113,10 @@ function on_ws_recv(evt)
|
|||||||
case "setup":
|
case "setup":
|
||||||
waterfall_init();
|
waterfall_init();
|
||||||
audio_preinit();
|
audio_preinit();
|
||||||
break;
|
break;
|
||||||
case "bandwidth":
|
case "bandwidth":
|
||||||
bandwidth=parseInt(param[1]);
|
bandwidth=parseInt(param[1]);
|
||||||
break;
|
break;
|
||||||
case "center_freq":
|
case "center_freq":
|
||||||
center_freq=parseInt(param[1]); //there was no ; and it was no problem... why?
|
center_freq=parseInt(param[1]); //there was no ; and it was no problem... why?
|
||||||
break;
|
break;
|
||||||
@ -1122,6 +1167,7 @@ function add_problem(what)
|
|||||||
}
|
}
|
||||||
|
|
||||||
waterfall_measure_minmax=false;
|
waterfall_measure_minmax=false;
|
||||||
|
waterfall_measure_minmax_now=false;
|
||||||
waterfall_measure_minmax_min=1e100;
|
waterfall_measure_minmax_min=1e100;
|
||||||
waterfall_measure_minmax_max=-1e100;
|
waterfall_measure_minmax_max=-1e100;
|
||||||
|
|
||||||
@ -1139,13 +1185,14 @@ function waterfall_measure_minmax_print()
|
|||||||
function waterfall_add_queue(what)
|
function waterfall_add_queue(what)
|
||||||
{
|
{
|
||||||
if(waterfall_measure_minmax) waterfall_measure_minmax_do(what);
|
if(waterfall_measure_minmax) waterfall_measure_minmax_do(what);
|
||||||
|
if(waterfall_measure_minmax_now) { waterfall_measure_minmax_do(what); waterfall_measure_minmax_now=false; waterfallColorsAuto(); }
|
||||||
waterfall_queue.push(what);
|
waterfall_queue.push(what);
|
||||||
}
|
}
|
||||||
|
|
||||||
function waterfall_dequeue()
|
function waterfall_dequeue()
|
||||||
{
|
{
|
||||||
if(waterfall_queue.length) waterfall_add(waterfall_queue.shift());
|
if(waterfall_queue.length) waterfall_add(waterfall_queue.shift());
|
||||||
if(waterfall_queue.length>Math.max(fft_fps/2,20)) //in case of emergency
|
if(waterfall_queue.length>Math.max(fft_fps/2,20)) //in case of emergency
|
||||||
{
|
{
|
||||||
console.log("waterfall queue length:", waterfall_queue.length);
|
console.log("waterfall queue length:", waterfall_queue.length);
|
||||||
add_problem("fft overflow");
|
add_problem("fft overflow");
|
||||||
@ -1165,7 +1212,7 @@ function divlog(what, is_error)
|
|||||||
{
|
{
|
||||||
is_error=!!is_error;
|
is_error=!!is_error;
|
||||||
was_error |= is_error;
|
was_error |= is_error;
|
||||||
if(is_error)
|
if(is_error)
|
||||||
{
|
{
|
||||||
what="<span class=\"webrx-error\">"+what+"</span>";
|
what="<span class=\"webrx-error\">"+what+"</span>";
|
||||||
if(e("openwebrx-panel-log").openwebrxHidden) toggle_panel("openwebrx-panel-log"); //show panel if any error is present
|
if(e("openwebrx-panel-log").openwebrxHidden) toggle_panel("openwebrx-panel-log"); //show panel if any error is present
|
||||||
@ -1213,7 +1260,7 @@ function gain_ff(gain_value,data) //great! solved clicking! will have to move to
|
|||||||
|
|
||||||
function audio_prepare(data)
|
function audio_prepare(data)
|
||||||
{
|
{
|
||||||
|
|
||||||
//audio_rebuffer.push(sdrjs.ConvertI16_F(data));//no resampling
|
//audio_rebuffer.push(sdrjs.ConvertI16_F(data));//no resampling
|
||||||
//audio_rebuffer.push(audio_resampler.process(sdrjs.ConvertI16_F(data)));//resampling without ADPCM
|
//audio_rebuffer.push(audio_resampler.process(sdrjs.ConvertI16_F(data)));//resampling without ADPCM
|
||||||
if(audio_compression=="none")
|
if(audio_compression=="none")
|
||||||
@ -1223,7 +1270,7 @@ function audio_prepare(data)
|
|||||||
else return;
|
else return;
|
||||||
|
|
||||||
//console.log("prepare",data.length,audio_rebuffer.remaining());
|
//console.log("prepare",data.length,audio_rebuffer.remaining());
|
||||||
while(audio_rebuffer.remaining())
|
while(audio_rebuffer.remaining())
|
||||||
{
|
{
|
||||||
audio_prepared_buffers.push(audio_rebuffer.take());
|
audio_prepared_buffers.push(audio_rebuffer.take());
|
||||||
audio_buffer_current_count_debug++;
|
audio_buffer_current_count_debug++;
|
||||||
@ -1236,7 +1283,7 @@ function audio_prepare_without_resampler(data)
|
|||||||
{
|
{
|
||||||
audio_rebuffer.push(sdrjs.ConvertI16_F(data));
|
audio_rebuffer.push(sdrjs.ConvertI16_F(data));
|
||||||
console.log("prepare",data.length,audio_rebuffer.remaining());
|
console.log("prepare",data.length,audio_rebuffer.remaining());
|
||||||
while(audio_rebuffer.remaining())
|
while(audio_rebuffer.remaining())
|
||||||
{
|
{
|
||||||
audio_prepared_buffers.push(audio_rebuffer.take());
|
audio_prepared_buffers.push(audio_rebuffer.take());
|
||||||
audio_buffer_current_count_debug++;
|
audio_buffer_current_count_debug++;
|
||||||
@ -1271,7 +1318,7 @@ function audio_prepare_old(data)
|
|||||||
if(audio_last_output_offset==audio_buffer_size) dopush();
|
if(audio_last_output_offset==audio_buffer_size) dopush();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //array is larger than the remaining space in the output buffer
|
{ //array is larger than the remaining space in the output buffer
|
||||||
var copied=audio_buffer_size-audio_last_output_offset;
|
var copied=audio_buffer_size-audio_last_output_offset;
|
||||||
var remain=data.length-copied;
|
var remain=data.length-copied;
|
||||||
for(var i=0;i<audio_buffer_size-audio_last_output_offset;i++) //fill the remaining space in the output buffer
|
for(var i=0;i<audio_buffer_size-audio_last_output_offset;i++) //fill the remaining space in the output buffer
|
||||||
@ -1320,12 +1367,12 @@ function audio_buffer_progressbar_update()
|
|||||||
var text="buffer";
|
var text="buffer";
|
||||||
if(overrun) { text="overrun"; console.log("audio overrun, "+(++audio_overrun_cnt).toString()); }
|
if(overrun) { text="overrun"; console.log("audio overrun, "+(++audio_overrun_cnt).toString()); }
|
||||||
if(underrun) { text="underrun"; console.log("audio underrun, "+(++audio_underrun_cnt).toString()); }
|
if(underrun) { text="underrun"; console.log("audio underrun, "+(++audio_underrun_cnt).toString()); }
|
||||||
if(overrun||underrun)
|
if(overrun||underrun)
|
||||||
{
|
{
|
||||||
audio_buffer_progressbar_update_disabled=true;
|
audio_buffer_progressbar_update_disabled=true;
|
||||||
window.setTimeout(function(){audio_buffer_progressbar_update_disabled=false; audio_buffer_progressbar_update();},1000);
|
window.setTimeout(function(){audio_buffer_progressbar_update_disabled=false; audio_buffer_progressbar_update();},1000);
|
||||||
}
|
}
|
||||||
progressbar_set(e("openwebrx-bar-audio-buffer"),(underrun)?1:audio_buffer_value/1.5,"Audio "+text+" ["+(audio_buffer_value).toFixed(1)+" s]",overrun||underrun||audio_buffer_value<0.25);
|
progressbar_set(e("openwebrx-bar-audio-buffer"),(underrun)?1:audio_buffer_value/1.5,"Audio "+text+" ["+(audio_buffer_value).toFixed(1)+" s]",overrun||underrun||audio_buffer_value<0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1344,10 +1391,10 @@ function audio_flush()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function audio_onprocess_notused(e)
|
function audio_onprocess_notused(e)
|
||||||
{
|
{
|
||||||
//https://github.com/0xfe/experiments/blob/master/www/tone/js/sinewave.js
|
//https://github.com/0xfe/experiments/blob/master/www/tone/js/sinewave.js
|
||||||
if(audio_received.length==0)
|
if(audio_received.length==0)
|
||||||
{ add_problem("audio underrun"); return; }
|
{ add_problem("audio underrun"); return; }
|
||||||
output = e.outputBuffer.getChannelData(0);
|
output = e.outputBuffer.getChannelData(0);
|
||||||
int_buffer = audio_received[0];
|
int_buffer = audio_received[0];
|
||||||
@ -1356,7 +1403,7 @@ function audio_onprocess_notused(e)
|
|||||||
|
|
||||||
obi=0; //output buffer index
|
obi=0; //output buffer index
|
||||||
debug_str=""
|
debug_str=""
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
if(int_buffer.length-audio_buffer_index>read_remain)
|
if(int_buffer.length-audio_buffer_index>read_remain)
|
||||||
{
|
{
|
||||||
@ -1367,7 +1414,7 @@ function audio_onprocess_notused(e)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i=audio_buffer_index; i<int_buffer.length; i++)
|
for (i=audio_buffer_index; i<int_buffer.length; i++)
|
||||||
output[obi++] = int_buffer[i]/32768;
|
output[obi++] = int_buffer[i]/32768;
|
||||||
read_remain-=(int_buffer.length-audio_buffer_index);
|
read_remain-=(int_buffer.length-audio_buffer_index);
|
||||||
@ -1380,7 +1427,7 @@ function audio_onprocess_notused(e)
|
|||||||
else*/
|
else*/
|
||||||
audio_received.splice(0,1);
|
audio_received.splice(0,1);
|
||||||
//debug_str+="added remain, remain="+read_remain.toString()+" abi="+audio_buffer_index.toString()+" alen="+int_buffer.length.toString()+" i="+i.toString()+" arecva="+audio_received.length.toString()+" obi="+obi.toString()+"\n";
|
//debug_str+="added remain, remain="+read_remain.toString()+" abi="+audio_buffer_index.toString()+" alen="+int_buffer.length.toString()+" i="+i.toString()+" arecva="+audio_received.length.toString()+" obi="+obi.toString()+"\n";
|
||||||
audio_buffer_index = 0;
|
audio_buffer_index = 0;
|
||||||
if(audio_received.length == 0 || read_remain == 0) return;
|
if(audio_received.length == 0 || read_remain == 0) return;
|
||||||
int_buffer = audio_received[0];
|
int_buffer = audio_received[0];
|
||||||
}
|
}
|
||||||
@ -1392,7 +1439,7 @@ function audio_onprocess_notused(e)
|
|||||||
function audio_flush_notused()
|
function audio_flush_notused()
|
||||||
{
|
{
|
||||||
if (audio_buffer_current_size>audio_buffer_maximal_length_sec*audio_context.sampleRate)
|
if (audio_buffer_current_size>audio_buffer_maximal_length_sec*audio_context.sampleRate)
|
||||||
{
|
{
|
||||||
add_problem("audio overrun");
|
add_problem("audio overrun");
|
||||||
console.log("audio_flush() :: size: "+audio_buffer_current_size.toString()+" allowed: "+(audio_buffer_maximal_length_sec*audio_context.sampleRate).toString());
|
console.log("audio_flush() :: size: "+audio_buffer_current_size.toString()+" allowed: "+(audio_buffer_maximal_length_sec*audio_context.sampleRate).toString());
|
||||||
while (audio_buffer_current_size>audio_buffer_maximal_length_sec*audio_context.sampleRate*0.5)
|
while (audio_buffer_current_size>audio_buffer_maximal_length_sec*audio_context.sampleRate*0.5)
|
||||||
@ -1410,7 +1457,7 @@ function webrx_set_param(what, value)
|
|||||||
|
|
||||||
function parsehash()
|
function parsehash()
|
||||||
{
|
{
|
||||||
if(h=window.location.hash)
|
if(h=window.location.hash)
|
||||||
{
|
{
|
||||||
h.substring(1).split(",").forEach(function(x){
|
h.substring(1).split(",").forEach(function(x){
|
||||||
harr=x.split("=");
|
harr=x.split("=");
|
||||||
@ -1418,28 +1465,28 @@ function parsehash()
|
|||||||
if(harr[0]=="mod") starting_mod = harr[1];
|
if(harr[0]=="mod") starting_mod = harr[1];
|
||||||
if(harr[0]=="freq") {
|
if(harr[0]=="freq") {
|
||||||
console.log(parseInt(harr[1]));
|
console.log(parseInt(harr[1]));
|
||||||
console.log(center_freq);
|
console.log(center_freq);
|
||||||
starting_offset_frequency = parseInt(harr[1])-center_freq;
|
starting_offset_frequency = parseInt(harr[1])-center_freq;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function audio_preinit()
|
function audio_preinit()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
window.AudioContext = window.AudioContext||window.webkitAudioContext;
|
window.AudioContext = window.AudioContext||window.webkitAudioContext;
|
||||||
audio_context = new AudioContext();
|
audio_context = new AudioContext();
|
||||||
}
|
}
|
||||||
catch(e)
|
catch(e)
|
||||||
{
|
{
|
||||||
divlog('Your browser does not support Web Audio API, which is required for WebRX to run. Please upgrade to a HTML5 compatible browser.', 1);
|
divlog('Your browser does not support Web Audio API, which is required for WebRX to run. Please upgrade to a HTML5 compatible browser.', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//we send our setup packet
|
//we send our setup packet
|
||||||
|
|
||||||
parsehash();
|
parsehash();
|
||||||
//needs audio_context.sampleRate to exist
|
//needs audio_context.sampleRate to exist
|
||||||
|
|
||||||
@ -1465,7 +1512,7 @@ function audio_init()
|
|||||||
audio_node = createjsnode_function(audio_buffer_size, 0, 1);
|
audio_node = createjsnode_function(audio_buffer_size, 0, 1);
|
||||||
audio_node.onaudioprocess = audio_onprocess;
|
audio_node.onaudioprocess = audio_onprocess;
|
||||||
audio_node.connect(audio_context.destination);
|
audio_node.connect(audio_context.destination);
|
||||||
// --- Resampling ---
|
// --- Resampling ---
|
||||||
//https://github.com/grantgalitz/XAudioJS/blob/master/XAudioServer.js
|
//https://github.com/grantgalitz/XAudioJS/blob/master/XAudioServer.js
|
||||||
//audio_resampler = new Resampler(audio_received_sample_rate, audio_context.sampleRate, 1, audio_buffer_size, true);
|
//audio_resampler = new Resampler(audio_received_sample_rate, audio_context.sampleRate, 1, audio_buffer_size, true);
|
||||||
//audio_input_buffer_size = audio_buffer_size*(audio_received_sample_rate/audio_context.sampleRate);
|
//audio_input_buffer_size = audio_buffer_size*(audio_received_sample_rate/audio_context.sampleRate);
|
||||||
@ -1478,8 +1525,8 @@ function audio_init()
|
|||||||
audio_source.buffer = buffer;
|
audio_source.buffer = buffer;
|
||||||
audio_source.noteOn(0);*/
|
audio_source.noteOn(0);*/
|
||||||
demodulator_analog_replace(starting_mod);
|
demodulator_analog_replace(starting_mod);
|
||||||
if(starting_offset_frequency)
|
if(starting_offset_frequency)
|
||||||
{
|
{
|
||||||
demodulators[0].offset_frequency = starting_offset_frequency;
|
demodulators[0].offset_frequency = starting_offset_frequency;
|
||||||
e("webrx-actual-freq").innerHTML=format_frequency("{x} MHz",center_freq+starting_offset_frequency,1e6,4);
|
e("webrx-actual-freq").innerHTML=format_frequency("{x} MHz",center_freq+starting_offset_frequency,1e6,4);
|
||||||
demodulators[0].set();
|
demodulators[0].set();
|
||||||
@ -1499,11 +1546,11 @@ function audio_init()
|
|||||||
function on_ws_closed()
|
function on_ws_closed()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
audio_node.disconnect();
|
audio_node.disconnect();
|
||||||
}
|
}
|
||||||
catch (dont_care) {}
|
catch (dont_care) {}
|
||||||
divlog("WebSocket has closed unexpectedly. Please reload the page.", 1);
|
divlog("WebSocket has closed unexpectedly. Please reload the page.", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function on_ws_error(event)
|
function on_ws_error(event)
|
||||||
@ -1516,11 +1563,11 @@ String.prototype.startswith=function(str){ return this.indexOf(str) == 0; }; //h
|
|||||||
function open_websocket()
|
function open_websocket()
|
||||||
{
|
{
|
||||||
//if(ws_url.startswith("ws://localhost:")&&window.location.hostname!="127.0.0.1"&&window.location.hostname!="localhost")
|
//if(ws_url.startswith("ws://localhost:")&&window.location.hostname!="127.0.0.1"&&window.location.hostname!="localhost")
|
||||||
//{
|
//{
|
||||||
//divlog("Server administrator should set <em>server_hostname</em> correctly, because it is left as <em>\"localhost\"</em>. Now guessing hostname from page URL.",1);
|
//divlog("Server administrator should set <em>server_hostname</em> correctly, because it is left as <em>\"localhost\"</em>. Now guessing hostname from page URL.",1);
|
||||||
ws_url="ws://"+(window.location.origin.split("://")[1])+"/ws/"; //guess automatically -> now default behaviour
|
ws_url="ws://"+(window.location.origin.split("://")[1])+"/ws/"; //guess automatically -> now default behaviour
|
||||||
//}
|
//}
|
||||||
if (!("WebSocket" in window))
|
if (!("WebSocket" in window))
|
||||||
divlog("Your browser does not support WebSocket, which is required for WebRX to run. Please upgrade to a HTML5 compatible browser.");
|
divlog("Your browser does not support WebSocket, which is required for WebRX to run. Please upgrade to a HTML5 compatible browser.");
|
||||||
ws = new WebSocket(ws_url+client_id);
|
ws = new WebSocket(ws_url+client_id);
|
||||||
ws.onopen = on_ws_opened;
|
ws.onopen = on_ws_opened;
|
||||||
@ -1566,15 +1613,15 @@ var canvas_container;
|
|||||||
var canvas_phantom;
|
var canvas_phantom;
|
||||||
|
|
||||||
function add_canvas()
|
function add_canvas()
|
||||||
{
|
{
|
||||||
new_canvas = document.createElement("canvas");
|
new_canvas = document.createElement("canvas");
|
||||||
new_canvas.width=fft_size;
|
new_canvas.width=fft_size;
|
||||||
new_canvas.height=canvas_default_height;
|
new_canvas.height=canvas_default_height;
|
||||||
canvas_actual_line=canvas_default_height-1;
|
canvas_actual_line=canvas_default_height-1;
|
||||||
new_canvas.style.width=(canvas_container.clientWidth*zoom_levels[zoom_level]).toString()+"px";
|
new_canvas.style.width=(canvas_container.clientWidth*zoom_levels[zoom_level]).toString()+"px";
|
||||||
new_canvas.style.left=zoom_offset_px.toString()+"px";
|
new_canvas.style.left=zoom_offset_px.toString()+"px";
|
||||||
new_canvas.style.height=canvas_default_height.toString()+"px";
|
new_canvas.style.height=canvas_default_height.toString()+"px";
|
||||||
new_canvas.openwebrx_top=(-canvas_default_height+1);
|
new_canvas.openwebrx_top=(-canvas_default_height+1);
|
||||||
new_canvas.style.top=new_canvas.openwebrx_top.toString()+"px";
|
new_canvas.style.top=new_canvas.openwebrx_top.toString()+"px";
|
||||||
canvas_context = new_canvas.getContext("2d");
|
canvas_context = new_canvas.getContext("2d");
|
||||||
canvas_container.appendChild(new_canvas);
|
canvas_container.appendChild(new_canvas);
|
||||||
@ -1608,7 +1655,7 @@ canvas_maxshift=0;
|
|||||||
|
|
||||||
function shift_canvases()
|
function shift_canvases()
|
||||||
{
|
{
|
||||||
canvases.forEach(function(p)
|
canvases.forEach(function(p)
|
||||||
{
|
{
|
||||||
p.style.top=(p.openwebrx_top++).toString()+"px";
|
p.style.top=(p.openwebrx_top++).toString()+"px";
|
||||||
});
|
});
|
||||||
@ -1621,8 +1668,8 @@ function shift_canvases()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
canvas_phantom.style.display="none";
|
canvas_phantom.style.display="none";
|
||||||
|
|
||||||
|
|
||||||
//canvas_container.style.height=(((canvases.length-1)*canvas_default_height)+(canvas_default_height-canvas_actual_line)).toString()+"px";
|
//canvas_container.style.height=(((canvases.length-1)*canvas_default_height)+(canvas_default_height-canvas_actual_line)).toString()+"px";
|
||||||
//canvas_container.style.height="100%";
|
//canvas_container.style.height="100%";
|
||||||
}
|
}
|
||||||
@ -1634,7 +1681,7 @@ function resize_canvases(zoom)
|
|||||||
zoom_calc();
|
zoom_calc();
|
||||||
new_width=(canvas_container.clientWidth*zoom_levels[zoom_level]).toString()+"px";
|
new_width=(canvas_container.clientWidth*zoom_levels[zoom_level]).toString()+"px";
|
||||||
var zoom_value=zoom_offset_px.toString()+"px";
|
var zoom_value=zoom_offset_px.toString()+"px";
|
||||||
canvases.forEach(function(p)
|
canvases.forEach(function(p)
|
||||||
{
|
{
|
||||||
p.style.width=new_width;
|
p.style.width=new_width;
|
||||||
p.style.left=zoom_value;
|
p.style.left=zoom_value;
|
||||||
@ -1695,7 +1742,7 @@ function waterfall_add(data)
|
|||||||
remain=pixel_per_point-(1-remain);
|
remain=pixel_per_point-(1-remain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //make line smaller (linear decimation, moving average)
|
{ //make line smaller (linear decimation, moving average)
|
||||||
@ -1708,7 +1755,7 @@ function waterfall_add(data)
|
|||||||
{
|
{
|
||||||
if(remain>1)
|
if(remain>1)
|
||||||
{
|
{
|
||||||
last_pixel+=data[i];
|
last_pixel+=data[i];
|
||||||
remain--;
|
remain--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1722,8 +1769,8 @@ function waterfall_add(data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add line to waterfall image
|
//Add line to waterfall image
|
||||||
base=(h-1)*w*4;
|
base=(h-1)*w*4;
|
||||||
for(x=0;x<w;x++)
|
for(x=0;x<w;x++)
|
||||||
{
|
{
|
||||||
color=waterfall_mkcolor(scaled[x]);
|
color=waterfall_mkcolor(scaled[x]);
|
||||||
@ -1731,7 +1778,7 @@ function waterfall_add(data)
|
|||||||
waterfall_image.data[base+x*4+i] = ((color>>>0)>>((3-i)*8))&0xff;
|
waterfall_image.data[base+x*4+i] = ((color>>>0)>>((3-i)*8))&0xff;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
//Add line to waterfall image
|
//Add line to waterfall image
|
||||||
oneline_image = canvas_context.createImageData(w,1);
|
oneline_image = canvas_context.createImageData(w,1);
|
||||||
for(x=0;x<w;x++)
|
for(x=0;x<w;x++)
|
||||||
{
|
{
|
||||||
@ -1740,12 +1787,12 @@ function waterfall_add(data)
|
|||||||
oneline_image.data[x*4+i] = ((color>>>0)>>((3-i)*8))&0xff;
|
oneline_image.data[x*4+i] = ((color>>>0)>>((3-i)*8))&0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Draw image
|
//Draw image
|
||||||
canvas_context.putImageData(oneline_image, 0, canvas_actual_line--);
|
canvas_context.putImageData(oneline_image, 0, canvas_actual_line--);
|
||||||
shift_canvases();
|
shift_canvases();
|
||||||
if(canvas_actual_line<0) add_canvas();
|
if(canvas_actual_line<0) add_canvas();
|
||||||
|
|
||||||
//divlog("Drawn FFT");
|
//divlog("Drawn FFT");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1769,14 +1816,14 @@ function check_top_bar_congestion()
|
|||||||
var rightmost=Math.max(rmf(wet),rmf(wed));
|
var rightmost=Math.max(rmf(wet),rmf(wed));
|
||||||
var tl=e("openwebrx-main-buttons");
|
var tl=e("openwebrx-main-buttons");
|
||||||
|
|
||||||
[wet, wed].map(function(what) {
|
[wet, wed].map(function(what) {
|
||||||
if(rmf(what)>tl.offsetLeft-20) what.style.opacity=what.style.opacity="0";
|
if(rmf(what)>tl.offsetLeft-20) what.style.opacity=what.style.opacity="0";
|
||||||
else wet.style.opacity=wed.style.opacity="1";
|
else wet.style.opacity=wed.style.opacity="1";
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function openwebrx_resize()
|
function openwebrx_resize()
|
||||||
{
|
{
|
||||||
resize_canvases();
|
resize_canvases();
|
||||||
resize_waterfall_container(true);
|
resize_waterfall_container(true);
|
||||||
@ -1795,10 +1842,11 @@ function openwebrx_init()
|
|||||||
|
|
||||||
//Synchronise volume with slider
|
//Synchronise volume with slider
|
||||||
updateVolume();
|
updateVolume();
|
||||||
|
waterfallColorsDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
window.setInterval(function(){
|
window.setInterval(function(){
|
||||||
sum=0;
|
sum=0;
|
||||||
for(i=0;i<audio_received.length;i++)
|
for(i=0;i<audio_received.length;i++)
|
||||||
sum+=audio_received[i].length;
|
sum+=audio_received[i].length;
|
||||||
@ -1833,15 +1881,15 @@ function debug_audio()
|
|||||||
// ((audio_buffer_current_count_debug*audio_buffer_size)/audio_debug_time_taken).toFixed(1)+" sps output";
|
// ((audio_buffer_current_count_debug*audio_buffer_size)/audio_debug_time_taken).toFixed(1)+" sps output";
|
||||||
|
|
||||||
var audio_speed_value=audio_buffer_current_size_debug*kbps_mult/audio_debug_time_since_last_call;
|
var audio_speed_value=audio_buffer_current_size_debug*kbps_mult/audio_debug_time_since_last_call;
|
||||||
progressbar_set(e("openwebrx-bar-audio-speed"),audio_speed_value/500000,"Audio stream ["+(audio_speed_value/1000).toFixed(0)+" kbps]",false);
|
progressbar_set(e("openwebrx-bar-audio-speed"),audio_speed_value/500000,"Audio stream ["+(audio_speed_value/1000).toFixed(0)+" kbps]",false);
|
||||||
|
|
||||||
var audio_output_value=(audio_buffer_current_count_debug*audio_buffer_size)/audio_debug_time_taken;
|
var audio_output_value=(audio_buffer_current_count_debug*audio_buffer_size)/audio_debug_time_taken;
|
||||||
progressbar_set(e("openwebrx-bar-audio-output"),audio_output_value/55000,"Audio output ["+(audio_output_value/1000).toFixed(1)+" ksps]",audio_output_value>55000||audio_output_value<10000);
|
progressbar_set(e("openwebrx-bar-audio-output"),audio_output_value/55000,"Audio output ["+(audio_output_value/1000).toFixed(1)+" ksps]",audio_output_value>55000||audio_output_value<10000);
|
||||||
|
|
||||||
audio_buffer_progressbar_update();
|
audio_buffer_progressbar_update();
|
||||||
|
|
||||||
var network_speed_value=debug_ws_data_received/audio_debug_time_taken;
|
var network_speed_value=debug_ws_data_received/audio_debug_time_taken;
|
||||||
progressbar_set(e("openwebrx-bar-network-speed"),network_speed_value*8/2000,"Network usage ["+(network_speed_value*8).toFixed(1)+" kbps]",false);
|
progressbar_set(e("openwebrx-bar-network-speed"),network_speed_value*8/2000,"Network usage ["+(network_speed_value*8).toFixed(1)+" kbps]",false);
|
||||||
|
|
||||||
audio_buffer_current_size_debug=0;
|
audio_buffer_current_size_debug=0;
|
||||||
|
|
||||||
@ -1858,10 +1906,10 @@ function pop_bottommost_panel(from)
|
|||||||
{
|
{
|
||||||
min_order=parseInt(from[0].dataset.panelOrder);
|
min_order=parseInt(from[0].dataset.panelOrder);
|
||||||
min_index=0;
|
min_index=0;
|
||||||
for(i=0;i<from.length;i++)
|
for(i=0;i<from.length;i++)
|
||||||
{
|
{
|
||||||
actual_order=parseInt(from[i].dataset.panelOrder);
|
actual_order=parseInt(from[i].dataset.panelOrder);
|
||||||
if(actual_order<min_order)
|
if(actual_order<min_order)
|
||||||
{
|
{
|
||||||
min_index=i;
|
min_index=i;
|
||||||
min_order=actual_order;
|
min_order=actual_order;
|
||||||
@ -1893,7 +1941,7 @@ function place_panels()
|
|||||||
c=plist[i];
|
c=plist[i];
|
||||||
if(c.className=="openwebrx-panel")
|
if(c.className=="openwebrx-panel")
|
||||||
{
|
{
|
||||||
if(c.openwebrxHidden)
|
if(c.openwebrxHidden)
|
||||||
{
|
{
|
||||||
c.style.display="none";
|
c.style.display="none";
|
||||||
continue;
|
continue;
|
||||||
@ -1907,7 +1955,7 @@ function place_panels()
|
|||||||
//c.style.height=newSize[1]+"px";
|
//c.style.height=newSize[1]+"px";
|
||||||
if(!c.openwebrxPanelTransparent) c.style.margin=panel_margin.toString()+"px";
|
if(!c.openwebrxPanelTransparent) c.style.margin=panel_margin.toString()+"px";
|
||||||
else c.style.marginLeft=panel_margin.toString()+"px";
|
else c.style.marginLeft=panel_margin.toString()+"px";
|
||||||
c.openwebrxPanelWidth=parseInt(newSize[0]);
|
c.openwebrxPanelWidth=parseInt(newSize[0]);
|
||||||
c.openwebrxPanelHeight=parseInt(newSize[1]);
|
c.openwebrxPanelHeight=parseInt(newSize[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1938,7 +1986,7 @@ function progressbar_set(obj,val,text,over)
|
|||||||
if (val>1) val=1;
|
if (val>1) val=1;
|
||||||
var innerBar=null;
|
var innerBar=null;
|
||||||
var innerText=null;
|
var innerText=null;
|
||||||
for(var i=0;i<obj.children.length;i++)
|
for(var i=0;i<obj.children.length;i++)
|
||||||
{
|
{
|
||||||
if(obj.children[i].className=="openwebrx-progressbar-text") innerText=obj.children[i];
|
if(obj.children[i].className=="openwebrx-progressbar-text") innerText=obj.children[i];
|
||||||
else if(obj.children[i].className=="openwebrx-progressbar-bar") innerBar=obj.children[i];
|
else if(obj.children[i].className=="openwebrx-progressbar-bar") innerBar=obj.children[i];
|
||||||
@ -1951,4 +1999,3 @@ function progressbar_set(obj,val,text,over)
|
|||||||
if(innerText==null) return;
|
if(innerText==null) return;
|
||||||
innerText.innerHTML=text;
|
innerText.innerHTML=text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user