merge recent openwebrx changes into our work

This commit is contained in:
Jakob Ketterl
2018-09-25 14:56:47 +02:00
parent ac6e001fd6
commit bf4c70dfef
22 changed files with 3817 additions and 1168 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -1,9 +1,9 @@
<!DOCTYPE HTML>
<!--
This file is part of OpenWebRX,
an open-source SDR receiver software with a web UI.
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
This file is part of OpenWebRX,
an open-source SDR receiver software with a web UI.
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -20,133 +20,171 @@
-->
<html>
<head>
<title>OpenWebRX | Open Source SDR Web App for Everyone!</title>
<script type="text/javascript">
//Global variables
var client_id="%[CLIENT_ID]";
var ws_url="%[WS_URL]";
var rx_photo_height=%[RX_PHOTO_HEIGHT];
var audio_buffering_fill_to=%[AUDIO_BUFSIZE];
var starting_mod = "%[START_MOD]";
var starting_offset_frequency = %[START_OFFSET_FREQ];
var waterfall_colors=%[WATERFALL_COLORS];
var waterfall_min_level_default=%[WATERFALL_MIN_LEVEL];
var waterfall_max_level_default=%[WATERFALL_MAX_LEVEL];
</script>
<script src="sdr.js"></script>
<script src="openwebrx.js"></script>
<link rel="stylesheet" type="text/css" href="openwebrx.css" />
<meta charset="utf-8">
</head>
<body onload="openwebrx_init();">
<head>
<title>OpenWebRX | Open Source SDR Web App for Everyone!</title>
<script type="text/javascript">
//Global variables
var client_id="%[CLIENT_ID]";
var ws_url="%[WS_URL]";
var rx_photo_height=%[RX_PHOTO_HEIGHT];
var audio_buffering_fill_to=%[AUDIO_BUFSIZE];
var starting_mod="%[START_MOD]";
var starting_offset_frequency = %[START_OFFSET_FREQ];
var waterfall_colors=%[WATERFALL_COLORS];
var waterfall_min_level_default=%[WATERFALL_MIN_LEVEL];
var waterfall_max_level_default=%[WATERFALL_MAX_LEVEL];
var waterfall_auto_level_margin=%[WATERFALL_AUTO_LEVEL_MARGIN];
var server_enable_digimodes=%[DIGIMODES_ENABLE];
var mathbox_waterfall_frequency_resolution=%[MATHBOX_WATERFALL_FRES];
var mathbox_waterfall_history_length=%[MATHBOX_WATERFALL_THIST];
var mathbox_waterfall_colors=%[MATHBOX_WATERFALL_COLORS];
</script>
<script src="sdr.js"></script>
<script src="mathbox-bundle.min.js"></script>
<script src="openwebrx.js"></script>
<script src="jquery-3.2.1.min.js"></script>
<script src="jquery.nanoscroller.js"></script>
<link rel="stylesheet" type="text/css" href="nanoscroller.css" />
<link rel="stylesheet" type="text/css" href="openwebrx.css" />
<meta charset="utf-8">
</head>
<body onload="openwebrx_init();">
<div id="webrx-page-container">
<div id="webrx-top-container">
<div id="webrx-top-photo-clip">
<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-desc">%[RX_PHOTO_DESC]</div>
</div>
<div id="webrx-top-bar-background" class="webrx-top-bar-parts"></div>
<div id="webrx-top-bar" class="webrx-top-bar-parts">
<a href="http://openwebrx.org/" target="_blank"><img src="gfx/openwebrx-top-logo.png" id="webrx-top-logo" /></a>
<a href="http://ha5kfu.sch.bme.hu/" target="_blank"><img src="gfx/openwebrx-ha5kfu-top-logo.png" id="webrx-ha5kfu-top-logo" /></a>
<img id="webrx-rx-avatar-background" src="gfx/openwebrx-avatar-background.png" onclick="toggle_rx_photo();"/>
<img id="webrx-rx-avatar" src="gfx/openwebrx-avatar.png" onclick="toggle_rx_photo();"/>
<div id="webrx-rx-title" onclick="toggle_rx_photo();">%[RX_TITLE]</div>
<div id="webrx-rx-desc" onclick="toggle_rx_photo();">%[RX_LOC] | Loc: %[RX_QRA], ASL: %[RX_ASL] m, <a href="https://www.google.hu/maps/place/%[RX_GPS]" target="_blank" onclick="dont_toggle_rx_photo();">[maps]</a></div>
<div id="openwebrx-rx-details-arrow">
<a id="openwebrx-rx-details-arrow-up" onclick="toggle_rx_photo();"><img src="gfx/openwebrx-rx-details-arrow-up.png" /></a>
<a id="openwebrx-rx-details-arrow-down" onclick="toggle_rx_photo();"><img src="gfx/openwebrx-rx-details-arrow.png" /></a>
</div>
<section id="openwebrx-main-buttons">
<ul>
<li onmouseup="toggle_panel('openwebrx-panel-status');"><img src="gfx/openwebrx-panel-status.png" /><br/>Status</li>
<li onmouseup="toggle_panel('openwebrx-panel-log');"><img src="gfx/openwebrx-panel-log.png" /><br/>Log</li>
<li onmouseup="toggle_panel('openwebrx-panel-receiver');"><img src="gfx/openwebrx-panel-receiver.png" /><br/>Receiver</li>
</ul>
</section>
</div>
</div>
<div id="webrx-main-container">
<div id="openwebrx-scale-container">
<canvas id="openwebrx-scale-canvas" width="0" height="0"></canvas>
</div>
<div id="webrx-canvas-container">
<div id="openwebrx-phantom-canvas"></div>
<!-- add canvas here by javascript -->
</div>
<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="259,260">
<div id="webrx-actual-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-panel-line">
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('nfm');">FM</div>
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('am');">AM</div>
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('lsb');">LSB</div>
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('usb');">USB</div>
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('cw');">CW</div>
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('dmr');">DMR</div>
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('dstar');">DStar</div>
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('nxdn');">NXDN</div>
<div class="openwebrx-button openwebrx-demodulator-button" onclick="demodulator_analog_replace('ysf');">YSF</div>
</div>
<div class="openwebrx-panel-line">
<div title="Mute on/off" id="openwebrx-mute-off" class="openwebrx-button" onclick="toggleMute();"><img src="gfx/openwebrx-speaker.png" class="openwebrx-sliderbtn-img" id="openwebrx-mute-img"></div>
<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="Auto-set squelch level" id="openwebrx-squelch-default" class="openwebrx-button" onclick="setSquelchToAuto()"><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="-150" max="0" value="-150" step="1" onchange="updateSquelch()" oninput="updateSquelch()">
<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 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 class="openwebrx-panel" id="openwebrx-panel-log" data-panel-name="debug" data-panel-pos="left" data-panel-order="2" data-panel-size="619,142">
<div class="openwebrx-panel-inner" id="openwebrx-log-scroll">
<div id="openwebrx-client-log-title">OpenWebRX client log</strong><span id="openwebrx-problems"></span></div>
<span id="openwebrx-client-1">Author: </span><a href="http://blog.sdr.hu/about" target="_blank">András Retzler, HA7ILM</a><br />You can support OpenWebRX development via <a href="http://blog.sdr.hu/support" target="_blank">PayPal!</a><br/>
<div id="openwebrx-debugdiv"></div>
</div>
</div>
<div class="openwebrx-panel" id="openwebrx-panel-status" data-panel-name="status" data-panel-pos="left" data-panel-order="0" data-panel-size="615,50" data-panel-transparent="true">
<div class="openwebrx-progressbar" id="openwebrx-bar-audio-buffer"> <span class="openwebrx-progressbar-text">Audio buffer [0 ms]</span><div class="openwebrx-progressbar-bar"></div></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-audio-output"> <span class="openwebrx-progressbar-text">Audio output [0 sps]</span><div class="openwebrx-progressbar-bar"></div></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-audio-speed"> <span class="openwebrx-progressbar-text">Audio stream [0 kbps]</span><div class="openwebrx-progressbar-bar"></div></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-network-speed"> <span class="openwebrx-progressbar-text">Network usage [0 kbps]</span><div class="openwebrx-progressbar-bar"></div></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-server-cpu"> <span class="openwebrx-progressbar-text">Server CPU [0%]</span><div class="openwebrx-progressbar-bar"></div></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-clients"> <span class="openwebrx-progressbar-text">Clients [1]</span><div class="openwebrx-progressbar-bar"></div></div>
</div>
<div id="webrx-top-container">
<div id="webrx-top-photo-clip">
<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-desc">%[RX_PHOTO_DESC]</div>
</div>
<div id="webrx-top-bar-background" class="webrx-top-bar-parts"></div>
<div id="webrx-top-bar" class="webrx-top-bar-parts">
<a href="https://sdr.hu/openwebrx" target="_blank"><img src="gfx/openwebrx-top-logo.png" id="webrx-top-logo" /></a>
<a href="http://ha5kfu.sch.bme.hu/" target="_blank"><img src="gfx/openwebrx-ha5kfu-top-logo.png" id="webrx-ha5kfu-top-logo" /></a>
<img id="webrx-rx-avatar-background" src="gfx/openwebrx-avatar-background.png" onclick="toggle_rx_photo();"/>
<img id="webrx-rx-avatar" src="gfx/openwebrx-avatar.png" onclick="toggle_rx_photo();"/>
<div id="webrx-rx-title" onclick="toggle_rx_photo();">%[RX_TITLE]</div>
<div id="webrx-rx-desc" onclick="toggle_rx_photo();">%[RX_LOC] | Loc: %[RX_QRA], ASL: %[RX_ASL] m, <a href="https://www.google.hu/maps/place/%[RX_GPS]" target="_blank" onclick="dont_toggle_rx_photo();">[maps]</a></div>
<div id="openwebrx-rx-details-arrow">
<a id="openwebrx-rx-details-arrow-up" onclick="toggle_rx_photo();"><img src="gfx/openwebrx-rx-details-arrow-up.png" /></a>
<a id="openwebrx-rx-details-arrow-down" onclick="toggle_rx_photo();"><img src="gfx/openwebrx-rx-details-arrow.png" /></a>
</div>
<section id="openwebrx-main-buttons">
<ul>
<li onmouseup="toggle_panel('openwebrx-panel-status');"><img src="gfx/openwebrx-panel-status.png" /><br/>Status</li>
<li onmouseup="toggle_panel('openwebrx-panel-log');"><img src="gfx/openwebrx-panel-log.png" /><br/>Log</li>
<li onmouseup="toggle_panel('openwebrx-panel-receiver');"><img src="gfx/openwebrx-panel-receiver.png" /><br/>Receiver</li>
</ul>
</section>
</div>
</div>
<div id="webrx-main-container">
<div id="openwebrx-scale-container">
<canvas id="openwebrx-scale-canvas" width="0" height="0"></canvas>
</div>
<div id="openwebrx-mathbox-container"> </div>
<div id="webrx-canvas-container">
<div id="openwebrx-phantom-canvas"></div>
<!-- add canvas here by javascript -->
</div>
<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="259,115">
<div id="webrx-actual-freq">---.--- MHz</div>
<div id="webrx-mouse-freq">---.--- MHz</div>
<div class="openwebrx-panel-line">
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-nfm"
onclick="demodulator_analog_replace('nfm');">FM</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-am"
onclick="demodulator_analog_replace('am');">AM</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-lsb"
onclick="demodulator_analog_replace('lsb');">LSB</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-usb"
onclick="demodulator_analog_replace('usb');">USB</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-cw"
onclick="demodulator_analog_replace('cw');">CW</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-dmr"
onclick="demodulator_analog_replace('dmr');">DMR</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-dstar"
onclick="demodulator_analog_replace('dstar');">DStar</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-nxdn"
onclick="demodulator_analog_replace('nxdn');">NXDN</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-ysf"
onclick="demodulator_analog_replace('ysf');">YSF</div>
</div>
<div class="openwebrx-panel-line">
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-dig" onclick="demodulator_digital_replace_last();">DIG</div>
<select id="openwebrx-secondary-demod-listbox" onchange="secondary_demod_listbox_changed();">
<option value="none"></option>
<option value="bpsk31">BPSK31</option>
</select>
</div>
<div class="openwebrx-panel-line">
<div title="Mute on/off" id="openwebrx-mute-off" class="openwebrx-button" onclick="toggleMute();"><img src="gfx/openwebrx-speaker.png" class="openwebrx-sliderbtn-img" id="openwebrx-mute-img"></div>
<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="Auto-set squelch level" id="openwebrx-squelch-default" class="openwebrx-button" onclick="setSquelchToAuto()"><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="-150" max="0" value="-150" step="1" onchange="updateSquelch()" oninput="updateSquelch()">
<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 class="openwebrx-button openwebrx-square-button" onclick="mathbox_toggle();" title="Toggle 3D view"><img src="gfx/openwebrx-3d-spectrum.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 class="openwebrx-panel" id="openwebrx-panel-log" data-panel-name="debug" data-panel-pos="left" data-panel-order="1" data-panel-size="619,137">
<div class="openwebrx-panel-inner nano" id="openwebrx-log-scroll">
<div class="nano-content">
<div id="openwebrx-client-log-title">OpenWebRX client log</strong><span id="openwebrx-problems"></span></div>
<span id="openwebrx-client-1">Author: </span><a href="http://blog.sdr.hu/about" target="_blank">András Retzler, HA7ILM</a><br />You can support OpenWebRX development via <a href="http://blog.sdr.hu/support" target="_blank">PayPal!</a><br/>
<div id="openwebrx-debugdiv"></div>
</div>
</div>
</div>
<div class="openwebrx-panel" id="openwebrx-panel-status" data-panel-name="status" data-panel-pos="left" data-panel-order="0" data-panel-size="615,50" data-panel-transparent="true">
<div class="openwebrx-progressbar" id="openwebrx-bar-audio-buffer"> <span class="openwebrx-progressbar-text">Audio buffer [0 ms]</span><div class="openwebrx-progressbar-bar"></div></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-audio-output"> <span class="openwebrx-progressbar-text">Audio output [0 sps]</span><div class="openwebrx-progressbar-bar"></div></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-audio-speed"> <span class="openwebrx-progressbar-text">Audio stream [0 kbps]</span><div class="openwebrx-progressbar-bar"></div></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-network-speed"> <span class="openwebrx-progressbar-text">Network usage [0 kbps]</span><div class="openwebrx-progressbar-bar"></div></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-server-cpu"> <span class="openwebrx-progressbar-text">Server CPU [0%]</span><div class="openwebrx-progressbar-bar"></div></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-clients"> <span class="openwebrx-progressbar-text">Clients [1]</span><div class="openwebrx-progressbar-bar"></div></div>
</div>
<div class="openwebrx-panel" data-panel-name="client-under-devel" data-panel-pos="none" data-panel-order="0" data-panel-size="245,55" style="background-color: Red;">
<span style="font-size: 15pt; font-weight: bold;">Under construction</span>
<br />We're working on the code right now, so the application might fail.
</div>
<div class="openwebrx-panel" id="openwebrx-panel-digimodes" data-panel-name="digimodes" data-panel-pos="left" data-panel-order="2" data-panel-size="619,210">
<div id="openwebrx-digimode-canvas-container">
<div id="openwebrx-digimode-select-channel"></div>
</div>
<div id="openwebrx-digimode-content-container">
<div class="gradient"></div>
<div id="openwebrx-digimode-content">
<span id="openwebrx-cursor-blink"></span>
</div>
</div>
</div>
<div class="openwebrx-panel" data-panel-name="metadata" data-panel-pos="left" data-panel-order="1" data-panel-size="615,36">
</div>
<div class="openwebrx-panel" data-panel-name="client-under-devel" data-panel-pos="none" data-panel-order="0" data-panel-size="245,55" style="background-color: Red;">
<span style="font-size: 15pt; font-weight: bold;">Under construction</span>
<br />We're working on the code right now, so the application might fail.
</div>
</div>
</div>
</div>
</div>
</div>
<div id="openwebrx-big-grey" onclick="iosPlayButtonClick();">
<div id="openwebrx-play-button-text">
<img id="openwebrx-play-button" src="gfx/openwebrx-play-button.png" />
<br /><br />Start OpenWebRX
</div>
</div>
</body>
<div id="openwebrx-big-grey" onclick="iosPlayButtonClick();">
<div id="openwebrx-play-button-text">
<img id="openwebrx-play-button" src="gfx/openwebrx-play-button.png" />
<br /><br />Start OpenWebRX
</div>
</div>
</body>
</html>

4
htdocs/jquery-3.2.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

33
htdocs/mathbox-bundle.min.js vendored Normal file

File diff suppressed because one or more lines are too long

461
htdocs/mathbox.css Normal file
View File

@ -0,0 +1,461 @@
.shadergraph-graph {
font: 12px sans-serif;
line-height: 25px;
position: relative;
}
.shadergraph-graph:after {
content: ' ';
display: block;
height: 0;
font-size: 0;
clear: both;
}
.shadergraph-graph svg {
pointer-events: none;
}
.shadergraph-clear {
clear: both;
}
.shadergraph-graph svg {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: auto;
height: auto;
}
.shadergraph-column {
float: left;
}
.shadergraph-node .shadergraph-graph {
float: left;
clear: both;
overflow: visible;
}
.shadergraph-node .shadergraph-graph .shadergraph-node {
margin: 5px 15px 15px;
}
.shadergraph-node {
margin: 5px 15px 25px;
background: rgba(0, 0, 0, .1);
border-radius: 5px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .2),
0 1px 10px rgba(0, 0, 0, .2);
min-height: 35px;
float: left;
clear: left;
position: relative;
}
.shadergraph-type {
font-weight: bold;
}
.shadergraph-header {
font-weight: bold;
text-align: center;
height: 25px;
background: rgba(0, 0, 0, .3);
text-shadow: 0 1px 2px rgba(0, 0, 0, .25);
color: #fff;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
margin-bottom: 5px;
padding: 0 10px;
}
.shadergraph-outlet div {
}
.shadergraph-outlet-in .shadergraph-name {
margin-right: 7px;
}
.shadergraph-outlet-out .shadergraph-name {
margin-left: 7px;
}
.shadergraph-name {
margin: 0 4px;
}
.shadergraph-point {
margin: 6px;
width: 11px;
height: 11px;
border-radius: 7.5px;
background: rgba(255, 255, 255, 1);
}
.shadergraph-outlet-in {
float: left;
clear: left;
}
.shadergraph-outlet-in div {
float: left;
}
.shadergraph-outlet-out {
float: right;
clear: right;
}
.shadergraph-outlet-out div {
float: right;
}
.shadergraph-node-callback {
background: rgba(205, 209, 221, .5);
box-shadow: 0 1px 2px rgba(0, 10, 40, .2),
0 1px 10px rgba(0, 10, 40, .2);
}
.shadergraph-node-callback > .shadergraph-header {
background: rgba(0, 20, 80, .3);
}
.shadergraph-graph .shadergraph-graph .shadergraph-node-callback {
background: rgba(0, 20, 80, .1);
}
.shadergraph-node-call {
background: rgba(209, 221, 205, .5);
box-shadow: 0 1px 2px rgba(10, 40, 0, .2),
0 1px 10px rgba(10, 40, 0, .2);
}
.shadergraph-node-call > .shadergraph-header {
background: rgba(20, 80, 0, .3);
}
.shadergraph-graph .shadergraph-graph .shadergraph-node-call {
background: rgba(20, 80, 0, .1);
}
.shadergraph-node-isolate {
background: rgba(221, 205, 209, .5);
box-shadow: 0 1px 2px rgba(40, 0, 10, .2),
0 1px 10px rgba(40, 0, 10, .2);
}
.shadergraph-node-isolate > .shadergraph-header {
background: rgba(80, 0, 20, .3);
}
.shadergraph-graph .shadergraph-graph .shadergraph-node-isolate {
background: rgba(80, 0, 20, .1);
}
.shadergraph-node.shadergraph-has-code {
cursor: pointer;
}
.shadergraph-node.shadergraph-has-code::before {
position: absolute;
content: ' ';
top: 0;
left: 0;
right: 0;
bottom: 0;
display: none;
border: 2px solid rgba(0, 0, 0, .25);
border-radius: 5px;
}
.shadergraph-node.shadergraph-has-code:hover::before {
display: block;
}
.shadergraph-code {
z-index: 10000;
display: none;
position: absolute;
background: #fff;
color: #000;
white-space: pre;
padding: 10px;
border-radius: 5px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .2),
0 1px 10px rgba(0, 0, 0, .2);
font-family: monospace;
font-size: 10px;
line-height: 12px;
}
.shadergraph-overlay {
position: fixed;
top: 50%;
left: 0;
right: 0;
bottom: 0;
background: #fff;
border-top: 1px solid #CCC;
}
.shadergraph-overlay .shadergraph-view {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: auto;
}
.shadergraph-overlay .shadergraph-inside {
width: 4000px;
min-height: 100%;
box-sizing: border-box;
}
.shadergraph-overlay .shadergraph-close {
position: absolute;
top: 5px;
right: 5px;
padding: 4px;
border-radius: 16px;
background: rgba(255,255,255,.3);
color: rgba(0, 0, 0, .3);
cursor: pointer;
font-size: 24px;
line-height: 24px;
width: 24px;
text-align: center;
vertical-align: middle;
}
.shadergraph-overlay .shadergraph-close:hover {
background: rgba(255,255,255,1);
color: rgba(0, 0, 0, 1);
}
.shadergraph-overlay .shadergraph-graph {
padding-top: 10px;
overflow: visible;
min-height: 100%;
}
.shadergraph-overlay span {
display: block;
padding: 5px 15px;
margin: 0;
background: rgba(0, 0, 0, .1);
font-weight: bold;
font-family: sans-serif;
}
.mathbox-loader {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
padding: 10px;
border-radius: 50%;
background: #fff;
}
.mathbox-loader.mathbox-exit {
opacity: 0;
-webkit-transition:
opacity .15s ease-in-out;
transition:
opacity .15s ease-in-out;
}
.mathbox-progress {
height: 10px;
border-radius: 5px;
width: 80px;
margin: 0 auto 20px;
box-shadow:
1px 1px 1px rgba(255, 255, 255, .2),
1px -1px 1px rgba(255, 255, 255, .2),
-1px 1px 1px rgba(255, 255, 255, .2),
-1px -1px 1px rgba(255, 255, 255, .2);
background: #ccc;
overflow: hidden;
}
.mathbox-progress > div {
display: block;
width: 0px;
height: 10px;
background: #888;
}
.mathbox-logo {
position: relative;
width: 140px;
height: 100px;
margin: 0 auto 10px;
-webkit-perspective: 200px;
perspective: 200px;
}
.mathbox-logo > div {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.mathbox-logo > :nth-child(1) {
-webkit-transform: rotateZ(22deg) rotateX(24deg) rotateY(30deg);
transform: rotateZ(22deg) rotateX(24deg) rotateY(30deg);
}
.mathbox-logo > :nth-child(2) {
-webkit-transform: rotateZ(11deg) rotateX(12deg) rotateY(15deg) scale3d(.6, .6, .6);
transform: rotateZ(11deg) rotateX(12deg) rotateY(15deg) scale3d(.6, .6, .6);
}
.mathbox-logo > div > div {
position: absolute;
top: 50%;
left: 50%;
margin-left: -100px;
margin-top: -100px;
width: 200px;
height: 200px;
box-sizing: border-box;
border-radius: 50%;
}
.mathbox-logo > div > :nth-child(1) {
-webkit-transform: scale(0.5, 0.5);
transform: rotateX(30deg) scale(0.5, 0.5);
}
.mathbox-logo > div > :nth-child(2) {
-webkit-transform: rotateX(90deg) scale(0.42, 0.42);
transform: rotateX(90deg) scale(0.42, 0.42);
}
.mathbox-logo > div > :nth-child(3) {
-webkit-transform: rotateY(90deg) scale(0.35, 0.35);
transform: rotateY(90deg) scale(0.35, 0.35);
}
.mathbox-logo > :nth-child(1) > :nth-child(1) {
border: 16px solid #808080;
}
.mathbox-logo > :nth-child(1) > :nth-child(2) {
border: 19px solid #A0A0A0;
}
.mathbox-logo > :nth-child(1) > :nth-child(3) {
border: 23px solid #C0C0C0;
}
.mathbox-logo > :nth-child(2) > :nth-child(1) {
border: 27px solid #808080;
}
.mathbox-logo > :nth-child(2) > :nth-child(2) {
border: 32px solid #A0A0A0;
}
.mathbox-logo > :nth-child(2) > :nth-child(3) {
border: 38px solid #C0C0C0;
}
.mathbox-splash-blue .mathbox-progress {
background: #def;
}
.mathbox-splash-blue .mathbox-progress > div {
background: #1979e7;
}
.mathbox-splash-blue .mathbox-logo > :nth-child(1) > :nth-child(1) {
border-color: #1979e7;
}
.mathbox-splash-blue .mathbox-logo > :nth-child(1) > :nth-child(2) {
border-color: #33b0ff;
}
.mathbox-splash-blue .mathbox-logo > :nth-child(1) > :nth-child(3) {
border-color: #75eaff;
}
.mathbox-splash-blue .mathbox-logo > :nth-child(2) > :nth-child(1) {
border-color: #18487F;
}
.mathbox-splash-blue .mathbox-logo > :nth-child(2) > :nth-child(2) {
border-color: #33b0ff;
}
.mathbox-splash-blue .mathbox-logo > :nth-child(2) > :nth-child(3) {
border-color: #75eaff;
}
.mathbox-overlays {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
pointer-events: none;
transform-style: preserve-3d;
overflow: hidden;
}
.mathbox-overlays > div {
transform-style: preserve-3d;
}
.mathbox-overlay > div {
position: absolute;
will-change: transform, opacity;
}
.mathbox-label {
font-family: sans-serif;
}
.mathbox-outline-1 {
text-shadow:
-1px -1px 0px rgb(255, 255, 255),
1px 1px 0px rgb(255, 255, 255),
-1px 1px 0px rgb(255, 255, 255),
1px -1px 0px rgb(255, 255, 255),
1px 0px 1px rgb(255, 255, 255),
-1px 0px 1px rgb(255, 255, 255),
0px -1px 1px rgb(255, 255, 255),
0px 1px 1px rgb(255, 255, 255);
}
.mathbox-outline-2 {
text-shadow:
0px -2px 0px rgb(255, 255, 255),
0px 2px 0px rgb(255, 255, 255),
-2px 0px 0px rgb(255, 255, 255),
2px 0px 0px rgb(255, 255, 255),
-1px -2px 0px rgb(255, 255, 255),
-2px -1px 0px rgb(255, 255, 255),
-1px 2px 0px rgb(255, 255, 255),
-2px 1px 0px rgb(255, 255, 255),
1px 2px 0px rgb(255, 255, 255),
2px 1px 0px rgb(255, 255, 255),
1px -2px 0px rgb(255, 255, 255),
2px -1px 0px rgb(255, 255, 255);
}
.mathbox-outline-3 {
text-shadow:
3px 0px 0px rgb(255, 255, 255),
-3px 0px 0px rgb(255, 255, 255),
0px 3px 0px rgb(255, 255, 255),
0px -3px 0px rgb(255, 255, 255),
-2px -2px 0px rgb(255, 255, 255),
-2px 2px 0px rgb(255, 255, 255),
2px 2px 0px rgb(255, 255, 255),
2px -2px 0px rgb(255, 255, 255),
-1px -2px 1px rgb(255, 255, 255),
-2px -1px 1px rgb(255, 255, 255),
-1px 2px 1px rgb(255, 255, 255),
-2px 1px 1px rgb(255, 255, 255),
1px 2px 1px rgb(255, 255, 255),
2px 1px 1px rgb(255, 255, 255),
1px -2px 1px rgb(255, 255, 255),
2px -1px 1px rgb(255, 255, 255);
}
.mathbox-outline-4 {
text-shadow:
4px 0px 0px rgb(255, 255, 255),
-4px 0px 0px rgb(255, 255, 255),
0px 4px 0px rgb(255, 255, 255),
0px -4px 0px rgb(255, 255, 255),
-3px -2px 0px rgb(255, 255, 255),
-3px 2px 0px rgb(255, 255, 255),
3px 2px 0px rgb(255, 255, 255),
3px -2px 0px rgb(255, 255, 255),
-2px -3px 0px rgb(255, 255, 255),
-2px 3px 0px rgb(255, 255, 255),
2px 3px 0px rgb(255, 255, 255),
2px -3px 0px rgb(255, 255, 255),
-1px -2px 1px rgb(255, 255, 255),
-2px -1px 1px rgb(255, 255, 255),
-1px 2px 1px rgb(255, 255, 255),
-2px 1px 1px rgb(255, 255, 255),
1px 2px 1px rgb(255, 255, 255),
2px 1px 1px rgb(255, 255, 255),
1px -2px 1px rgb(255, 255, 255),
2px -1px 1px rgb(255, 255, 255);
}
.mathbox-outline-fill, .mathbox-outline-fill * {
color: #fff !important;
}

55
htdocs/nanoscroller.css Normal file
View File

@ -0,0 +1,55 @@
/** initial setup **/
.nano {
position : relative;
width : 100%;
height : 100%;
overflow : hidden;
}
.nano > .nano-content {
position : absolute;
overflow : scroll;
overflow-x : hidden;
top : 0;
right : 0;
bottom : 0;
left : 0;
}
.nano > .nano-content:focus {
outline: thin dotted;
}
.nano > .nano-content::-webkit-scrollbar {
display: none;
}
.has-scrollbar > .nano-content::-webkit-scrollbar {
display: block;
}
.nano > .nano-pane {
background : rgba(0,0,0,.25);
position : absolute;
width : 8px;
right : 0;
top : 0;
bottom : 0;
visibility : hidden\9; /* Target only IE7 and IE8 with this hack */
opacity : .01;
-webkit-transition : .2s;
-moz-transition : .2s;
-o-transition : .2s;
transition : .2s;
-moz-border-radius : 3px;
-webkit-border-radius : 3px;
border-radius : 3px;
}
.nano > .nano-pane > .nano-slider {
background: #444;
background: rgba(0,0,0,.5);
position : relative;
margin : 0 0px;
-moz-border-radius : 4px;
-webkit-border-radius : 4px;
border-radius : 4px;
}
.nano:hover > .nano-pane, .nano-pane.active, .nano-pane.flashed {
visibility : visible\9; /* Target only IE7 and IE8 with this hack */
opacity : 0.99;
}

View File

@ -28,6 +28,11 @@ html, body
overflow: hidden;
}
select
{
font-family: "DejaVu Sans", Verdana, Geneva, sans-serif;
}
input
{
vertical-align:middle;
@ -394,6 +399,13 @@ input[type=range]:focus::-ms-fill-upper
border-style: none;
image-rendering: crisp-edges;
image-rendering: -webkit-optimize-contrast;
/*transition: left 200ms, width 200ms;*/
}
#openwebrx-mathbox-container
{
overflow: none;
display: none;
}
#openwebrx-phantom-canvas
@ -410,11 +422,15 @@ input[type=range]:focus::-ms-fill-upper
height: 396px;
}*/
/*#webrx-debugdiv
#openwebrx-log-scroll
{
font-size: 10pt;
/*overflow-y:scroll;*/
/*}*/
/*overflow-y:auto;*/
height: 125px;
width: 619px
}
.nano .nano-pane { background: #444; }
.nano .nano-slider { background: #eee !important; }
#webrx-main-container
{
@ -499,7 +515,7 @@ input[type=range]:focus::-ms-fill-upper
.openwebrx-panel
{
transform: perspective( 600px );
transform: perspective( 600px ) rotateX( 90deg );
visibility: hidden;
background-color: #575757;
padding: 10px;
@ -526,7 +542,7 @@ input[type=range]:focus::-ms-fill-upper
.openwebrx-button
{
background-color: #373737;
padding: 5px;
padding: 4.2px;
border-radius: 5px;
-moz-border-radius: 5px;
color: White;
@ -544,7 +560,7 @@ input[type=range]:focus::-ms-fill-upper
display: inline-block;
}
.openwebrx-button:hover
.openwebrx-button:hover, .openwebrx-demodulator-button.highlighted
{
/*background:-webkit-gradient( linear, left top, left bottom, color-stop(0.0 , #3F3F3F), color-stop(1, #777777) );
background:-moz-linear-gradient( center top, #373737 5%, #4F4F4F 100% );*/
@ -560,7 +576,7 @@ input[type=range]:focus::-ms-fill-upper
.openwebrx-demodulator-button
{
width: 50px;
width: 38px;
height: 19px;
font-size: 12pt;
text-align: center;
@ -568,7 +584,7 @@ input[type=range]:focus::-ms-fill-upper
.openwebrx-square-button img
{
height: 30px;
height: 27px;
}
.openwebrx-round-button
@ -732,7 +748,7 @@ img.openwebrx-mirror-img
{
position: relative;
top: -2px;
width:91px;
width: 95px;
}
.openwebrx-sliderbtn-img
@ -776,7 +792,7 @@ img.openwebrx-mirror-img
font-size: 10pt;
float: right;
margin-right: 5px;
margin-top: 29px;
margin-top: 24px;
font-family: 'expletus-sans-medium';
}
@ -806,3 +822,152 @@ img.openwebrx-mirror-img
{
width: 150px;
}
#openwebrx-digimode-canvas-container
{
/*margin: -10px -10px 10px -10px;*/
margin: -10px -10px 0px -10px;
border-radius: 15px;
height: 150px;
background-color: #333;
position: relative;
overflow: hidden;
}
#openwebrx-digimode-canvas-container canvas
{
position: absolute;
pointer-events: none;
transition: width 500ms, left 500ms;
}
#openwebrx-secondary-demod-listbox
{
width: 201px;
height: 27px;
border-radius: 5px;
background-color: #373737;
color: White;
font-weight: normal;
font-size: 13pt;
margin-right: 1px;
background:-webkit-gradient( linear, left top, left bottom, color-stop(0.0 , #373737), color-stop(1, #4F4F4F) );
background:-moz-linear-gradient( center top, #373737 0%, #4F4F4F 100% );
border-color: transparent;
border-width: 0px;
-moz-appearance: none;
padding-left:3px;
}
#openwebrx-secondary-demod-listbox option
{
border-width: 0px;
background-color: #373737;
color: White;
}
#openwebrx-cursor-blink
{
animation: cursor-blink 1s infinite;
/*animation: cursor-3d 2s infinite;*/
animation-timing-function: linear;
animation-direction: alternate;
height: 1em;
width: 8px;
background-color: White;
display: inline-block;
position: relative;
top: 1px;
/*perspective: 60px;*/
}
@keyframes cursor-blink
{
0%{ opacity: 0; }
50% { opacity: 1; }
100%{ opacity: 0; }
}
@keyframes cursor-3d
{
0%{ transform: rotateX(0deg) rotateX(Ydeg); }
50% { transform: rotateX(180deg) rotateY(360deg); opacity: 0.1; }
100%{ transform: rotateX(360deg) rotateY(720deg); }
}
#openwebrx-digimode-content
{
word-wrap: break-word;
position: absolute;
bottom: 0;
width: 100%;
}
#openwebrx-digimode-content-container
{
overflow-y: hidden;
display: block;
height: 50px;
position: relative;
}
#openwebrx-digimode-content-container .gradient
{
width: 100%;
height: 20px;
background: linear-gradient(to top, rgba(87,87,87,0) 0%,rgba(87,87,87,1) 100%);
position: absolute;
top: 0;
z-index: 10;
}
#openwebrx-digimode-content .part
{
perspective: 700px;
}
#openwebrx-digimode-content .part
{
animation: new-digimode-data-3d 100ms;
animation-timing-function: linear;
display: inline-block;
perspective-origin: 50% 50%;
transform-origin: 0% 50%;
}
#openwebrx-digimode-content .part .subpart
{
}
@keyframes new-digimode-data
{
0%{ opacity: 0; }
100%{ opacity: 1; }
}
@keyframes new-digimode-data-3d
{
0%{ transform: rotateX(0deg) rotateY(-90deg) translateX(-5px) scale(1.3); }
100%{ transform: rotateX(0deg) rotateY(0deg) translateX(0) scale(1); }
}
#openwebrx-digimode-select-channel
{
transition: all 500ms;
background-color: Yellow;
display: block;
position: absolute;
pointer-events: none;
height: 100%;
width: 0px;
top: 0px;
left: 0px;
opacity: 0.7;
border-style: solid;
border-width: 0px;
border-color: Red;
}

View File

@ -51,6 +51,7 @@ var audio_compression="none";
var waterfall_setup_done=0;
var waterfall_queue = [];
var waterfall_timer;
var secondary_fft_size;
/*function fade(something,from,to,time_ms,fps)
{
@ -72,7 +73,8 @@ var rx_photo_state=1;
function e(what) { return document.getElementById(what); }
ios = /iPad|iPod|iPhone/.test(navigator.userAgent);
ios = /iPad|iPod|iPhone|Chrome/.test(navigator.userAgent);
is_chrome = /Chrome/.test(navigator.userAgent);
//alert("ios="+ios.toString()+" "+navigator.userAgent);
function init_rx_photo()
@ -183,8 +185,8 @@ function waterfallColorsDefault()
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();
e("openwebrx-waterfall-color-min").value=(waterfall_measure_minmax_min-waterfall_auto_level_margin[0]).toString();
e("openwebrx-waterfall-color-max").value=(waterfall_measure_minmax_max+waterfall_auto_level_margin[1]).toString();
updateWaterfallColors(0);
}
@ -559,6 +561,7 @@ function demodulator_default_analog(offset_frequency,subtype)
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.
demodulator_buttons_update();
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;
return to_return;
@ -575,6 +578,7 @@ function mkenvelopes(visible_range) //called from mkscale
{
demodulators[i].envelope.draw(visible_range);
}
if(demodulators.length) secondary_demod_waterfall_set_zoom(demodulators[0].low_cut, demodulators[0].high_cut);
}
function demodulator_remove(which)
@ -589,8 +593,17 @@ function demodulator_add(what)
mkenvelopes(get_visible_freq_range());
}
function demodulator_analog_replace(subtype)
last_analog_demodulator_subtype = 'nfm';
last_digital_demodulator_subtype = 'bpsk31';
function demodulator_analog_replace(subtype, for_digital)
{ //this function should only exist until the multi-demodulator capability is added
if(!(typeof for_digital !== "undefined" && for_digital && secondary_demod))
{
secondary_demod_close_window();
secondary_demod_listbox_update();
}
last_analog_demodulator_subtype = subtype;
var temp_offset=0;
if(demodulators.length)
{
@ -598,6 +611,7 @@ function demodulator_analog_replace(subtype)
demodulator_remove(0);
}
demodulator_add(new demodulator_default_analog(temp_offset,subtype));
demodulator_buttons_update();
}
function demodulator_set_offset_frequency(which,to_what)
@ -1028,7 +1042,7 @@ function canvas_mousewheel(evt)
zoom_max_level_hps=33; //Hz/pixel
zoom_levels_count=5;
zoom_levels_count=14;
function get_zoom_coeff_from_hps(hps)
{
@ -1050,8 +1064,10 @@ function mkzoomlevels()
zoom_levels=[1];
maxc=get_zoom_coeff_from_hps(zoom_max_level_hps);
if(maxc<1) return;
// logarithmic interpolation
zoom_ratio = Math.pow(maxc, 1/zoom_levels_count);
for(i=1;i<zoom_levels_count;i++)
zoom_levels.push(1+(maxc-1)*(i/(zoom_levels_count-1)));
zoom_levels.push(Math.pow(zoom_ratio, i));
}
function zoom_step(out, where, onscreen)
@ -1063,7 +1079,7 @@ function zoom_step(out, where, onscreen)
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());
zoom_center_where=onscreen;
console.log(zoom_center_where, zoom_center_rel, where);
//console.log(zoom_center_where, zoom_center_rel, where);
resize_canvases(true);
mkscale();
}
@ -1095,9 +1111,17 @@ function zoom_calc()
function resize_waterfall_container(check_init)
{
if(check_init&&!waterfall_setup_done) return;
canvas_container.style.height=(window.innerHeight-e("webrx-top-container").clientHeight-e("openwebrx-scale-container").clientHeight).toString()+"px";
}
var numHeight;
mathbox_container.style.height=canvas_container.style.height=(numHeight=window.innerHeight-e("webrx-top-container").clientHeight-e("openwebrx-scale-container").clientHeight).toString()+"px";
if(mathbox)
{
//mathbox.three.camera.aspect = document.body.offsetWidth / numHeight;
//mathbox.three.camera.updateProjectionMatrix();
mathbox.three.renderer.setSize(document.body.offsetWidth, numHeight);
console.log(document.body.offsetWidth, numHeight);
}
}
audio_server_output_rate=11025;
audio_client_resampling_factor=4;
@ -1134,14 +1158,15 @@ function on_ws_recv(evt)
if(!(evt.data instanceof ArrayBuffer)) { divlog("on_ws_recv(): Not ArrayBuffer received...",1); return; }
//
debug_ws_data_received+=evt.data.byteLength/1000;
firstChars=getFirstChars(evt.data,3);
if(firstChars=="CLI")
first4Chars=getFirstChars(evt.data,4);
first3Chars=first4Chars.slice(0,3);
if(first3Chars=="CLI")
{
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("Server acknowledged WebSocket connection.");
}
if(firstChars=="AUD")
if(first3Chars=="AUD")
{
var audio_data;
if(audio_compression=="adpcm") audio_data=new Uint8Array(evt.data,4)
@ -1149,11 +1174,12 @@ function on_ws_recv(evt)
audio_prepare(audio_data);
audio_buffer_current_size_debug+=audio_data.length;
audio_buffer_all_size_debug+=audio_data.length;
if(!ios && (audio_initialized==0 && audio_prepared_buffers.length>audio_buffering_fill_to)) audio_init()
if(!(ios||is_chrome) && (audio_initialized==0 && audio_prepared_buffers.length>audio_buffering_fill_to)) audio_init()
}
else if(firstChars=="FFT")
else if(first3Chars=="FFT")
{
//alert("Yupee! Doing FFT");
//if(first4Chars=="FFTS") console.log("FFTS");
if(fft_compression=="none") waterfall_add_queue(new Float32Array(evt.data,4));
else if(fft_compression="adpcm")
{
@ -1162,9 +1188,17 @@ function on_ws_recv(evt)
var waterfall_i16=fft_codec.decode(new Uint8Array(evt.data,4));
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;
waterfall_add_queue(waterfall_f32);
if(first4Chars=="FFTS") secondary_demod_waterfall_add_queue(waterfall_f32); //TODO digimodes
else waterfall_add_queue(waterfall_f32);
}
} else if(firstChars=="MSG")
}
else if(first3Chars=="DAT")
{
//secondary_demod_push_binary_data(new Uint8Array(evt.data,4));
secondary_demod_push_data(arrayBufferToString(evt.data).substring(4));
//console.log("DAT");
}
else if(first3Chars=="MSG")
{
/*try
{*/
@ -1188,6 +1222,18 @@ function on_ws_recv(evt)
case "fft_size":
fft_size=parseInt(param[1]);
break;
case "secondary_fft_size":
secondary_fft_size=parseInt(param[1]);
break;
case "secondary_setup":
secondary_demod_init_canvases();
break;
case "if_samp_rate":
if_samp_rate=parseInt(param[1]);
break;
case "secondary_bw":
secondary_bw=parseFloat(param[1]);
break;
case "fft_fps":
fft_fps=parseInt(param[1]);
break;
@ -1336,8 +1382,10 @@ function divlog(what, is_error)
if(e("openwebrx-panel-log").openwebrxHidden) toggle_panel("openwebrx-panel-log"); //show panel if any error is present
}
e("openwebrx-debugdiv").innerHTML+=what+"<br />";
var wls=e("openwebrx-log-scroll");
wls.scrollTop=wls.scrollHeight; //scroll to bottom
//var wls=e("openwebrx-log-scroll");
//wls.scrollTop=wls.scrollHeight; //scroll to bottom
$(".nano").nanoScroller();
$(".nano").nanoScroller({ scroll: 'bottom' });
}
var audio_context;
@ -1585,19 +1633,27 @@ function webrx_set_param(what, value)
ws.send("SET "+what+"="+value.toString());
}
var starting_mute = false;
function parsehash()
{
if(h=window.location.hash)
{
h.substring(1).split(",").forEach(function(x){
harr=x.split("=");
console.log(harr);
if(harr[0]=="mod") starting_mod = harr[1];
if(harr[0]=="sql") { e("openwebrx-panel-squelch").value=harr[1]; updateSquelch(); }
if(harr[0]=="freq") {
console.log(parseInt(harr[1]));
console.log(center_freq);
starting_offset_frequency = parseInt(harr[1])-center_freq;
//console.log(harr);
if(harr[0]=="mute") toggleMute();
else if(harr[0]=="mod") starting_mod = harr[1];
else if(harr[0]=="sql")
{
e("openwebrx-panel-squelch").value=harr[1];
updateSquelch();
}
else if(harr[0]=="freq")
{
console.log(parseInt(harr[1]));
console.log(center_freq);
starting_offset_frequency = parseInt(harr[1])-center_freq;
}
});
@ -1638,6 +1694,9 @@ function audio_preinit()
function audio_init()
{
if(is_chrome) audio_context.resume()
if(starting_mute) toggleMute();
if(audio_client_resampling_factor==0) return; //if failed to find a valid resampling factor...
audio_debug_time_start=(new Date()).getTime();
@ -1682,6 +1741,7 @@ function audio_init()
//window.setTimeout(function(){toggle_panel("openwebrx-panel-log");e("openwebrx-panel-log").style.opacity="1";},1200)
}
},2000);
}
function on_ws_closed()
@ -1722,17 +1782,18 @@ function open_websocket()
ws.onerror = on_ws_error;
}
function waterfall_mkcolor(db_value)
function waterfall_mkcolor(db_value, waterfall_colors_arg)
{
if(typeof waterfall_colors_arg === 'undefined') waterfall_colors_arg = waterfall_colors;
if(db_value<waterfall_min_level) db_value=waterfall_min_level;
if(db_value>waterfall_max_level) db_value=waterfall_max_level;
full_scale=waterfall_max_level-waterfall_min_level;
relative_value=db_value-waterfall_min_level;
value_percent=relative_value/full_scale;
percent_for_one_color=1/(waterfall_colors.length-1);
percent_for_one_color=1/(waterfall_colors_arg.length-1);
index=Math.floor(value_percent/percent_for_one_color);
remain=(value_percent-percent_for_one_color*index)/percent_for_one_color;
return color_between(waterfall_colors[index+1],waterfall_colors[index],remain);
return color_between(waterfall_colors_arg[index+1],waterfall_colors_arg[index],remain);
}
function color_between(first, second, percent)
@ -1755,7 +1816,7 @@ var canvas_phantom;
function add_canvas()
{
new_canvas = document.createElement("canvas");
var new_canvas = document.createElement("canvas");
new_canvas.width=fft_size;
new_canvas.height=canvas_default_height;
canvas_actual_line=canvas_default_height-1;
@ -1780,9 +1841,11 @@ function add_canvas()
}
}
function init_canvas_container()
{
canvas_container=e("webrx-canvas-container");
mathbox_container=e("openwebrx-mathbox-container");
canvas_container.addEventListener("mouseout",canvas_container_mouseout, false);
//window.addEventListener("mouseout",window_mouseout,false);
//document.body.addEventListener("mouseup",body_mouseup,false);
@ -1839,7 +1902,7 @@ function resize_canvases(zoom)
function waterfall_init()
{
init_canvas_container();
waterfall_timer = window.setInterval(waterfall_dequeue,900/fft_fps);
waterfall_timer = window.setInterval(()=>{waterfall_dequeue(); secondary_demod_waterfall_dequeue();},900/fft_fps);
resize_waterfall_container(false); /* then */ resize_canvases();
scale_setup();
mkzoomlevels();
@ -1848,6 +1911,42 @@ function waterfall_init()
var waterfall_dont_scale=0;
var mathbox_shift = function()
{
if(mathbox_data_current_depth < mathbox_data_max_depth) mathbox_data_current_depth++;
if(mathbox_data_index+1>=mathbox_data_max_depth) mathbox_data_index = 0;
else mathbox_data_index++;
mathbox_data_global_index++;
}
var mathbox_clear_data = function()
{
mathbox_data_index = 50;
mathbox_data_current_depth = 0;
}
//var mathbox_get_data_line = function(x) //x counts from 0 to mathbox_data_current_depth
//{
// return (mathbox_data_max_depth + mathbox_data_index - mathbox_data_current_depth + x - 1) % mathbox_data_max_depth;
//}
//
//var mathbox_data_index_valid = function(x) //x counts from 0 to mathbox_data_current_depth
//{
// return x<mathbox_data_current_depth;
//}
var mathbox_get_data_line = function(x)
{
return (mathbox_data_max_depth + mathbox_data_index + x - 1) % mathbox_data_max_depth;
}
var mathbox_data_index_valid = function(x)
{
return x>mathbox_data_max_depth-mathbox_data_current_depth;
}
function waterfall_add(data)
{
if(!waterfall_setup_done) return;
@ -1924,6 +2023,14 @@ function waterfall_add(data)
waterfall_image.data[base+x*4+i] = ((color>>>0)>>((3-i)*8))&0xff;
}*/
if(mathbox_mode==MATHBOX_MODES.WATERFALL)
{
//Handle mathbox
for(var i=0;i<fft_size;i++) mathbox_data[i+mathbox_data_index*fft_size]=data[i];
mathbox_shift();
}
else
{
//Add line to waterfall image
oneline_image = canvas_context.createImageData(w,1);
for(x=0;x<w;x++)
@ -1933,13 +2040,13 @@ function waterfall_add(data)
oneline_image.data[x*4+i] = ((color>>>0)>>((3-i)*8))&0xff;
}
//Draw image
canvas_context.putImageData(oneline_image, 0, canvas_actual_line--);
shift_canvases();
if(canvas_actual_line<0) add_canvas();
}
//divlog("Drawn FFT");
}
/*
@ -1969,6 +2076,180 @@ function check_top_bar_congestion()
}
var MATHBOX_MODES =
{
UNINITIALIZED: 0,
NONE: 1,
WATERFALL: 2,
CONSTELLATION: 3
};
var mathbox_mode = MATHBOX_MODES.UNINITIALIZED;
var mathbox;
var mathbox_element;
function mathbox_init()
{
//mathbox_waterfall_history_length is defined in the config
mathbox_data_max_depth = fft_fps * mathbox_waterfall_history_length; //how many lines can the buffer store
mathbox_data_current_depth = 0; //how many lines are in the buffer currently
mathbox_data_index = 0; //the index of the last empty line / the line to be overwritten
mathbox_data = new Float32Array(fft_size * mathbox_data_max_depth);
mathbox_data_global_index = 0;
mathbox_correction_for_z = 0;
mathbox = mathBox({
plugins: ['core', 'controls', 'cursor', 'stats'],
controls: { klass: THREE.OrbitControls },
});
three = mathbox.three;
if(typeof three == "undefined") divlog("3D waterfall cannot be initialized because WebGL is not supported in your browser.", true);
three.renderer.setClearColor(new THREE.Color(0x808080), 1.0);
mathbox_container.appendChild((mathbox_element=three.renderer.domElement));
view = mathbox
.set({
scale: 1080,
focus: 3,
})
.camera({
proxy: true,
position: [-2, 1, 3],
})
.cartesian({
range: [[-1, 1], [0, 1], [0, 1]],
scale: [2, 2/3, 1],
});
view.axis({
axis: 1,
width: 3,
color: "#fff",
});
view.axis({
axis: 2,
width: 3,
color: "#fff",
//offset: [0, 0, 0],
});
view.axis({
axis: 3,
width: 3,
color: "#fff",
});
view.grid({
width: 2,
opacity: 0.5,
axes: [1, 3],
zOrder: 1,
color: "#fff",
});
//var remap = function (v) { return Math.sqrt(.5 + .5 * v); };
var remap = function(x,z,t)
{
var currentTimePos = mathbox_data_global_index/(fft_fps*1.0);
var realZAdd = (-(t-currentTimePos)/mathbox_waterfall_history_length);
var zAdd = realZAdd - mathbox_correction_for_z;
if(zAdd<-0.2 || zAdd>0.2) { mathbox_correction_for_z = realZAdd; }
var xIndex = Math.trunc(((x+1)/2.0)*fft_size); //x: frequency
var zIndex = Math.trunc(z*(mathbox_data_max_depth-1)); //z: time
var realZIndex = mathbox_get_data_line(zIndex);
if(!mathbox_data_index_valid(zIndex)) return {y: undefined, dBValue: undefined, zAdd: 0 };
//if(realZIndex>=(mathbox_data_max_depth-1)) console.log("realZIndexundef", realZIndex, zIndex);
var index = Math.trunc(xIndex + realZIndex * fft_size);
/*if(mathbox_data[index]==undefined) console.log("Undef", index, mathbox_data.length, zIndex,
realZIndex, mathbox_data_max_depth,
mathbox_data_current_depth, mathbox_data_index);*/
var dBValue = mathbox_data[index];
//y=1;
if(dBValue>waterfall_max_level) y = 1;
else if(dBValue<waterfall_min_level) y = 0;
else y = (dBValue-waterfall_min_level)/(waterfall_max_level-waterfall_min_level);
mathbox_dbg = { dbv: dBValue, indexval: index, mbd: mathbox_data.length, yval: y };
if(!y) y=0;
return {y: y, dBValue: dBValue, zAdd: zAdd};
}
var points = view.area({
expr: function (emit, x, z, i, j, t) {
var y;
remapResult=remap(x,z,t);
if((y=remapResult.y)==undefined) return;
emit(x, y, z+remapResult.zAdd);
},
width: mathbox_waterfall_frequency_resolution,
height: mathbox_data_max_depth - 1,
channels: 3,
axes: [1, 3],
});
var colors = view.area({
expr: function (emit, x, z, i, j, t) {
var dBValue;
if((dBValue=remap(x,z,t).dBValue)==undefined) return;
var color=waterfall_mkcolor(dBValue, mathbox_waterfall_colors);
var b = (color&0xff)/255.0;
var g = ((color&0xff00)>>8)/255.0;
var r = ((color&0xff0000)>>16)/255.0;
emit(r, g, b, 1.0);
},
width: mathbox_waterfall_frequency_resolution,
height: mathbox_data_max_depth - 1,
channels: 4,
axes: [1, 3],
});
view.surface({
shaded: true,
points: '<<',
colors: '<',
color: 0xFFFFFF,
});
view.surface({
fill: false,
lineX: false,
lineY: false,
points: '<<',
colors: '<',
color: 0xFFFFFF,
width: 2,
blending: 'add',
opacity: .25,
zBias: 5,
});
mathbox_mode = MATHBOX_MODES.NONE;
//mathbox_element.style.width="100%";
//mathbox_element.style.height="100%";
}
function mathbox_toggle()
{
if(mathbox_mode == MATHBOX_MODES.UNINITIALIZED) mathbox_init();
mathbox_mode = (mathbox_mode == MATHBOX_MODES.NONE) ? MATHBOX_MODES.WATERFALL : MATHBOX_MODES.NONE;
mathbox_container.style.display = (mathbox_mode == MATHBOX_MODES.WATERFALL) ? "block" : "none";
mathbox_clear_data();
waterfall_clear();
}
function waterfall_clear()
{
while(canvases.length) //delete all canvases
{
var x=canvases.shift();
x.parentNode.removeChild(x);
delete x;
}
add_canvas();
}
function openwebrx_resize()
{
resize_canvases();
@ -1979,10 +2260,11 @@ function openwebrx_resize()
function openwebrx_init()
{
if(ios) e("openwebrx-big-grey").style.display="table-cell";
if(ios||is_chrome) e("openwebrx-big-grey").style.display="table-cell";
(opb=e("openwebrx-play-button-text")).style.marginTop=(window.innerHeight/2-opb.clientHeight/2).toString()+"px";
init_rx_photo();
open_websocket();
secondary_demod_init();
place_panels(first_show_panel);
window.setTimeout(function(){window.setInterval(debug_audio,1000);},1000);
window.addEventListener("resize",openwebrx_resize);
@ -2076,9 +2358,14 @@ function pop_bottommost_panel(from)
return to_return;
}
function toggle_panel(what)
function toggle_panel(what, on)
{
var item=e(what);
var item=e(what);
if(typeof on !== "undefined")
{
if(item.openwebrxHidden && !on) return;
if(!item.openwebrxHidden && on) return;
}
if(item.openwebrxDisableClick) return;
item.style.transitionDuration="599ms";
item.style.transitionDelay="0ms";
@ -2167,6 +2454,7 @@ function place_panels(function_apply)
p.style.visibility="visible";
y+=p.openwebrxPanelHeight+((p.openwebrxPanelTransparent)?0:3)*panel_margin;
if(function_apply) function_apply(p);
//console.log(p.id, y, p.openwebrxPanelTransparent);
}
y=hoffset;
while(right_col.length>0)
@ -2175,7 +2463,7 @@ function place_panels(function_apply)
p.style.right=(e("webrx-canvas-container").offsetWidth-e("webrx-canvas-container").clientWidth).toString()+"px"; //get scrollbar width
p.style.bottom=y.toString()+"px";
p.style.visibility="visible";
y+=p.openwebrxPanelHeight+((p.openwebrxPanelTransparent)?0:3)*panel_margin;
y+=p.openwebrxPanelHeight+((p.openwebrxPanelTransparent)?0:3)*panel_margin;
if(function_apply) function_apply(p);
}
}
@ -2199,3 +2487,331 @@ function progressbar_set(obj,val,text,over)
if(innerText==null) return;
innerText.innerHTML=text;
}
function demodulator_buttons_update()
{
$(".openwebrx-demodulator-button").removeClass("highlighted");
if(secondary_demod) $("#openwebrx-button-dig").addClass("highlighted");
else switch(demodulators[0].subtype)
{
case "nfm":
$("#openwebrx-button-nfm").addClass("highlighted");
break;
case "am":
$("#openwebrx-button-am").addClass("highlighted");
break;
case "lsb":
case "usb":
case "cw":
if(demodulators[0].high_cut-demodulators[0].low_cut<300)
$("#openwebrx-button-cw").addClass("highlighted");
else
{
if(demodulators[0].high_cut<0)
$("#openwebrx-button-lsb").addClass("highlighted");
else if(demodulators[0].low_cut>0)
$("#openwebrx-button-usb").addClass("highlighted");
else $("#openwebrx-button-lsb, #openwebrx-button-usb").addClass("highlighted");
}
break;
}
}
function demodulator_analog_replace_last() { demodulator_analog_replace(last_analog_demodulator_subtype); }
/*
_____ _ _ _
| __ \(_) (_) | |
| | | |_ __ _ _ _ __ ___ ___ __| | ___ ___
| | | | |/ _` | | '_ ` _ \ / _ \ / _` |/ _ \/ __|
| |__| | | (_| | | | | | | | (_) | (_| | __/\__ \
|_____/|_|\__, |_|_| |_| |_|\___/ \__,_|\___||___/
__/ |
|___/
*/
secondary_demod = false;
secondary_demod_offset_freq = 0;
secondary_demod_waterfall_queue = [];
function demodulator_digital_replace_last()
{
demodulator_digital_replace(last_digital_demodulator_subtype);
secondary_demod_listbox_update();
}
function demodulator_digital_replace(subtype)
{
switch(subtype)
{
case "bpsk31":
case "rtty":
secondary_demod_start(subtype);
demodulator_analog_replace('usb', true);
demodulator_buttons_update();
break;
}
toggle_panel("openwebrx-panel-digimodes", true);
}
function secondary_demod_create_canvas()
{
var new_canvas = document.createElement("canvas");
new_canvas.width=secondary_fft_size;
new_canvas.height=$(secondary_demod_canvas_container).height();
new_canvas.style.width=$(secondary_demod_canvas_container).width()+"px";
new_canvas.style.height=$(secondary_demod_canvas_container).height()+"px";
console.log(new_canvas.width, new_canvas.height, new_canvas.style.width, new_canvas.style.height);
secondary_demod_current_canvas_actual_line=new_canvas.height-1;
$(secondary_demod_canvas_container).children().last().before(new_canvas);
return new_canvas;
}
function secondary_demod_remove_canvases()
{
$(secondary_demod_canvas_container).children("canvas").remove();
}
function secondary_demod_init_canvases()
{
secondary_demod_remove_canvases();
secondary_demod_canvases=[];
secondary_demod_canvases.push(secondary_demod_create_canvas());
secondary_demod_canvases.push(secondary_demod_create_canvas());
secondary_demod_canvases[0].openwebrx_top=-$(secondary_demod_canvas_container).height();
secondary_demod_canvases[1].openwebrx_top=0;
secondary_demod_canvases_update_top();
secondary_demod_current_canvas_context = secondary_demod_canvases[0].getContext("2d");
secondary_demod_current_canvas_actual_line=$(secondary_demod_canvas_container).height()-1;
secondary_demod_current_canvas_index=0;
secondary_demod_canvases_initialized=true;
//secondary_demod_update_channel_freq_from_event();
mkscale(); //so that the secondary waterfall zoom level will be initialized
}
function secondary_demod_canvases_update_top()
{
for(var i=0;i<2;i++) secondary_demod_canvases[i].style.top=secondary_demod_canvases[i].openwebrx_top+"px";
}
function secondary_demod_swap_canvases()
{
console.log("swap");
secondary_demod_canvases[0+!secondary_demod_current_canvas_index].openwebrx_top-=$(secondary_demod_canvas_container).height()*2;
secondary_demod_current_canvas_index=0+!secondary_demod_current_canvas_index;
secondary_demod_current_canvas_context = secondary_demod_canvases[secondary_demod_current_canvas_index].getContext("2d");
secondary_demod_current_canvas_actual_line=$(secondary_demod_canvas_container).height()-1;
}
function secondary_demod_init()
{
$("#openwebrx-panel-digimodes")[0].openwebrxHidden = true;
secondary_demod_canvas_container = $("#openwebrx-digimode-canvas-container")[0];
$(secondary_demod_canvas_container)
.mousemove(secondary_demod_canvas_container_mousemove)
.mouseup(secondary_demod_canvas_container_mouseup)
.mousedown(secondary_demod_canvas_container_mousedown)
.mouseenter(secondary_demod_canvas_container_mousein)
.mouseleave(secondary_demod_canvas_container_mouseout);
}
function secondary_demod_start(subtype)
{
secondary_demod_canvases_initialized = false;
ws.send("SET secondary_mod="+subtype);
secondary_demod = subtype;
}
function secondary_demod_set()
{
ws.send("SET secondary_offset_freq="+secondary_demod_offset_freq.toString());
}
function secondary_demod_stop()
{
ws.send("SET secondary_mod=off");
secondary_demod = false;
secondary_demod_waterfall_queue = [];
}
function secondary_demod_waterfall_add_queue(x)
{
secondary_demod_waterfall_queue.push(x);
}
function secondary_demod_push_binary_data(x)
{
secondary_demod_push_data(Array.from(x).map( y => (y)?"1":"0" ).join(""));
}
function secondary_demod_push_data(x)
{
x=Array.from(x).map((y)=>{
var c=y.charCodeAt(0);
if(y=="\r") return "&nbsp;";
if(y=="\n") return "&nbsp;";
//if(y=="\n") return "<br />";
if(c<32||c>126) return "";
if(y=="&") return "&amp;";
if(y=="<") return "&lt;";
if(y==">") return "&gt;";
if(y==" ") return "&nbsp;";
return y;
}).join("");
$("#openwebrx-cursor-blink").before("<span class=\"part\"><span class=\"subpart\">"+x+"</span></span>");
}
function secondary_demod_data_clear()
{
$("#openwebrx-cursor-blink").prevAll().remove();
}
function secondary_demod_close_window()
{
secondary_demod_stop();
toggle_panel("openwebrx-panel-digimodes", false);
}
secondary_demod_fft_offset_db=30; //need to calculate that later
function secondary_demod_waterfall_add(data)
{
if(!secondary_demod) return;
var w=secondary_fft_size;
//Add line to waterfall image
var oneline_image = secondary_demod_current_canvas_context.createImageData(w,1);
for(x=0;x<w;x++)
{
var color=waterfall_mkcolor(data[x]+secondary_demod_fft_offset_db);
for(i=0;i<4;i++) oneline_image.data[x*4+i] = ((color>>>0)>>((3-i)*8))&0xff;
}
//Draw image
secondary_demod_current_canvas_context.putImageData(oneline_image, 0, secondary_demod_current_canvas_actual_line--);
secondary_demod_canvases.map((x)=>{x.openwebrx_top += 1;});
secondary_demod_canvases_update_top();
if(secondary_demod_current_canvas_actual_line<0) secondary_demod_swap_canvases();
}
var secondary_demod_canvases_initialized = false;
function secondary_demod_waterfall_dequeue()
{
if(!secondary_demod || !secondary_demod_canvases_initialized) return;
if(secondary_demod_waterfall_queue.length) secondary_demod_waterfall_add(secondary_demod_waterfall_queue.shift());
if(secondary_demod_waterfall_queue.length>Math.max(fft_fps/2,20)) //in case of fft overflow
{
console.log("secondary waterfall overflow, queue length:", secondary_demod_waterfall_queue.length);
while(secondary_demod_waterfall_queue.length) secondary_demod_waterfall_add(secondary_demod_waterfall_queue.shift());
}
}
secondary_demod_listbox_updating = false;
function secondary_demod_listbox_changed()
{
if(secondary_demod_listbox_updating) return;
switch ($("#openwebrx-secondary-demod-listbox")[0].value)
{
case "none":
demodulator_analog_replace_last();
break;
case "bpsk31":
demodulator_digital_replace('bpsk31');
break;
case "rtty":
demodulator_digital_replace('rtty');
break;
}
}
function secondary_demod_listbox_update()
{
secondary_demod_listbox_updating = true;
$("#openwebrx-secondary-demod-listbox").val((secondary_demod)?secondary_demod:"none");
console.log("update");
secondary_demod_listbox_updating = false;
}
secondary_demod_channel_freq=1000;
function secondary_demod_update_marker()
{
var width = Math.max( (secondary_bw / (if_samp_rate/2)) * secondary_demod_canvas_width, 5);
var center_at = (secondary_demod_channel_freq / (if_samp_rate/2)) * secondary_demod_canvas_width + secondary_demod_canvas_left;
var left = center_at-width/2;
//console.log("sdum", width, left);
$("#openwebrx-digimode-select-channel").width(width).css("left",left+"px")
}
secondary_demod_waiting_for_set = false;
function secondary_demod_update_channel_freq_from_event(evt)
{
if(typeof evt !== "undefined")
{
var relativeX=(evt.offsetX)?evt.offsetX:evt.layerX;
secondary_demod_channel_freq=secondary_demod_low_cut +
(relativeX/$(secondary_demod_canvas_container).width()) * (secondary_demod_high_cut-secondary_demod_low_cut);
}
//console.log("toset:", secondary_demod_channel_freq);
if(!secondary_demod_waiting_for_set)
{
secondary_demod_waiting_for_set = true;
window.setTimeout(()=>{
ws.send("SET secondary_offset_freq="+Math.floor(secondary_demod_channel_freq));
//console.log("doneset:", secondary_demod_channel_freq);
secondary_demod_waiting_for_set = false;
}, 50);
}
secondary_demod_update_marker();
}
secondary_demod_mousedown=false;
function secondary_demod_canvas_container_mousein()
{
$("#openwebrx-digimode-select-channel").css("opacity","0.7"); //.css("border-width", "1px");
}
function secondary_demod_canvas_container_mouseout()
{
$("#openwebrx-digimode-select-channel").css("opacity","0");
}
function secondary_demod_canvas_container_mousemove(evt)
{
if(secondary_demod_mousedown) secondary_demod_update_channel_freq_from_event(evt);
}
function secondary_demod_canvas_container_mousedown(evt)
{
if(evt.which==1) secondary_demod_mousedown=true;
}
function secondary_demod_canvas_container_mouseup(evt)
{
if(evt.which==1) secondary_demod_mousedown=false;
secondary_demod_update_channel_freq_from_event(evt);
}
function secondary_demod_waterfall_set_zoom(low_cut, high_cut)
{
if(!secondary_demod || !secondary_demod_canvases_initialized) return;
if(low_cut<0 && high_cut<0)
{
var hctmp = high_cut;
var lctmp = low_cut;
low_cut = -hctmp;
low_cut = -lctmp;
}
else if(low_cut<0 && high_cut>0)
{
high_cut=Math.max(Math.abs(high_cut), Math.abs(low_cut));
low_cut=0;
}
secondary_demod_low_cut = low_cut;
secondary_demod_high_cut = high_cut;
var shown_bw = high_cut-low_cut;
secondary_demod_canvas_width = $(secondary_demod_canvas_container).width() * (if_samp_rate/2)/shown_bw;
secondary_demod_canvas_left = -secondary_demod_canvas_width*(low_cut/(if_samp_rate/2));
//console.log("setzoom", secondary_demod_canvas_width, secondary_demod_canvas_left, low_cut, high_cut);
secondary_demod_canvases.map((x)=>{$(x).css("left",secondary_demod_canvas_left+"px").css("width",secondary_demod_canvas_width+"px");});
secondary_demod_update_channel_freq_from_event();
}