Merging htdocs from jketterl development branch.

This commit is contained in:
Marat Fayzullin 2023-09-09 17:32:54 -04:00 committed by Marat Fayzullin
parent 8c82853d18
commit d901e76ac1
11 changed files with 91 additions and 42 deletions

View File

@ -160,3 +160,7 @@ h1 {
.imageupload.is-invalid ~ .invalid-feedback { .imageupload.is-invalid ~ .invalid-feedback {
display: block; display: block;
} }
.device-log-messages {
max-height: 500px;
}

View File

@ -1,5 +1,5 @@
$(function(){ $(function(){
var converter = new showdown.Converter(); var converter = new showdown.Converter({openLinksInNewWindow: true});
$.ajax('api/features').done(function(data){ $.ajax('api/features').done(function(data){
var $table = $('table.features'); var $table = $('table.features');
$.each(data, function(name, details) { $.each(data, function(name, details) {

View File

@ -30,7 +30,7 @@
<div class="webrx-rx-photo-desc">${photo_desc}</div> <div class="webrx-rx-photo-desc">${photo_desc}</div>
</div> </div>
<a class="openwebrx-rx-details-arrow openwebrx-rx-details-arrow--down openwebrx-photo-trigger"> <a class="openwebrx-rx-details-arrow openwebrx-rx-details-arrow--down openwebrx-photo-trigger">
<svg class="down" viewBox="0 0 43 12"><use xlink:href="static/gfx/svg-defs.svg#rx-details-arrow-down"></use></svg> <svg class="down" viewBox="0 0 43 12"><use xlink:href="${document_root}static/gfx/svg-defs.svg#rx-details-arrow-down"></use></svg>
<svg class="up" viewBox="0 0 43 12"><use xlink:href="static/gfx/svg-defs.svg#rx-details-arrow-up"></use></svg> <svg class="up" viewBox="0 0 43 12"><use xlink:href="${document_root}static/gfx/svg-defs.svg#rx-details-arrow-up"></use></svg>
</a> </a>
</div> </div>

View File

@ -2,6 +2,18 @@ function AprsMarker() {}
AprsMarker.prototype = new google.maps.OverlayView(); AprsMarker.prototype = new google.maps.OverlayView();
AprsMarker.prototype.isFacingEast = function(symbol) {
var candidates = ''
if (symbol.table === '/') {
// primary table
candidates = '(*<=>CFPUXYabefghjkpsuv[';
} else {
// alternate table
candidates = 'hkluv';
}
return candidates.includes(symbol.symbol);
};
AprsMarker.prototype.draw = function() { AprsMarker.prototype.draw = function() {
var div = this.div; var div = this.div;
var overlay = this.overlay; var overlay = this.overlay;
@ -16,9 +28,15 @@ AprsMarker.prototype.draw = function() {
} }
if (this.course) { if (this.course) {
if (this.course > 180) { if (this.symbol && !this.isFacingEast(this.symbol)) {
// assume symbol points to the north
div.style.transform = 'rotate(' + this.course + ' deg)';
} else if (this.course > 180) {
// symbol is pointing east
// don't rotate more than 180 degrees, rather mirror
div.style.transform = 'scalex(-1) rotate(' + (270 - this.course) + 'deg)' div.style.transform = 'scalex(-1) rotate(' + (270 - this.course) + 'deg)'
} else { } else {
// symbol is pointing east
div.style.transform = 'rotate(' + (this.course - 90) + 'deg)'; div.style.transform = 'rotate(' + (this.course - 90) + 'deg)';
} }
} else { } else {
@ -70,7 +88,7 @@ AprsMarker.prototype.onAdd = function() {
div.appendChild(overlay); div.appendChild(overlay);
var self = this; var self = this;
google.maps.event.addDomListener(div, "click", function(event) { div.addEventListener("click", function(event) {
event.stopPropagation(); event.stopPropagation();
google.maps.event.trigger(self, "click", event); google.maps.event.trigger(self, "click", event);
}); });
@ -79,7 +97,7 @@ AprsMarker.prototype.onAdd = function() {
panes.overlayImage.appendChild(div); panes.overlayImage.appendChild(div);
}; };
AprsMarker.prototype.remove = function() { AprsMarker.prototype.onRemove = function() {
if (this.div) { if (this.div) {
this.div.parentNode.removeChild(this.div); this.div.parentNode.removeChild(this.div);
this.div = null; this.div = null;

View File

@ -413,7 +413,9 @@ ImaAdpcmCodec.prototype.reset = function() {
this.synchronized = 0; this.synchronized = 0;
this.syncWord = "SYNC"; this.syncWord = "SYNC";
this.syncCounter = 0; this.syncCounter = 0;
this.skip = 0; this.phase = 0;
this.syncBuffer = new Uint8Array(4);
this.syncBufferIndex = 0;
}; };
ImaAdpcmCodec.imaIndexTable = [ -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 ]; ImaAdpcmCodec.imaIndexTable = [ -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 ];
@ -441,38 +443,45 @@ ImaAdpcmCodec.prototype.decode = function(data) {
ImaAdpcmCodec.prototype.decodeWithSync = function(data) { ImaAdpcmCodec.prototype.decodeWithSync = function(data) {
var output = new Int16Array(data.length * 2); var output = new Int16Array(data.length * 2);
var index = this.skip;
var oi = 0; var oi = 0;
while (index < data.length) { for (var index = 0; index < data.length; index++) {
while (this.synchronized < 4 && index < data.length) { switch (this.phase) {
if (data[index] === this.syncWord.charCodeAt(this.synchronized)) { case 0:
this.synchronized++; // search for sync word
} else { if (data[index] !== this.syncWord.charCodeAt(this.synchronized++)) {
this.synchronized = 0; // reset if data is unexpected
} this.synchronized = 0;
index++; }
if (this.synchronized === 4) { // if sync word has been found pass on to next phase
if (index + 4 < data.length) { if (this.synchronized === 4) {
var syncData = new Int16Array(data.buffer.slice(index, index + 4)); this.syncBufferIndex = 0;
this.phase = 1;
}
break;
case 1:
// read codec runtime data from stream
this.syncBuffer[this.syncBufferIndex++] = data[index];
// if data is complete, apply and pass on to next phase
if (this.syncBufferIndex === 4) {
var syncData = new Int16Array(this.syncBuffer.buffer);
this.stepIndex = syncData[0]; this.stepIndex = syncData[0];
this.predictor = syncData[1]; this.predictor = syncData[1];
this.syncCounter = 1000;
this.phase = 2;
} }
this.syncCounter = 1000;
index += 4;
break; break;
} case 2:
} // decode actual audio data
while (index < data.length) { output[oi++] = this.decodeNibble(data[index] & 0x0F);
if (this.syncCounter-- < 0) { output[oi++] = this.decodeNibble(data[index] >> 4);
this.synchronized = 0; // if the next sync keyword is due, reset and return to phase 0
if (this.syncCounter-- === 0) {
this.synchronized = 0;
this.phase = 0;
}
break; break;
}
output[oi++] = this.decodeNibble(data[index] & 0x0F);
output[oi++] = this.decodeNibble(data[index] >> 4);
index++;
} }
} }
this.skip = index - data.length;
return output.slice(0, oi); return output.slice(0, oi);
}; };

View File

@ -347,6 +347,13 @@ Demodulator.prototype.setBandpass = function(bandpass) {
this.set(); this.set();
}; };
Demodulator.prototype.disableBandpass = function() {
delete this.bandpass;
this.low_cut = null;
this.high_cut = null;
this.set()
}
Demodulator.prototype.setLowCut = function(low_cut) { Demodulator.prototype.setLowCut = function(low_cut) {
this.low_cut = low_cut; this.low_cut = low_cut;
this.set(); this.set();

View File

@ -91,7 +91,7 @@ DemodulatorPanel.prototype.setMode = function(requestedModulation, underlyingMod
return; return;
} }
if (this.mode === mode && (!underlyingModulation || this.underlyingModulation === underlyingModulation)) { if (this.mode === mode && this.underlyingModulation === underlyingModulation) {
return; return;
} }
if (!mode.isAvailable()) { if (!mode.isAvailable()) {
@ -101,12 +101,9 @@ DemodulatorPanel.prototype.setMode = function(requestedModulation, underlyingMod
var modulation; var modulation;
if (mode.type === 'digimode') { if (mode.type === 'digimode') {
if (underlyingModulation) { modulation = underlyingModulation = underlyingModulation || mode.underlying[0];
modulation = underlyingModulation
} else {
modulation = mode.underlying[0];
}
} else { } else {
underlyingModulation = undefined;
modulation = mode.modulation; modulation = mode.modulation;
} }
@ -138,8 +135,12 @@ DemodulatorPanel.prototype.setMode = function(requestedModulation, underlyingMod
if (mode.type === 'digimode') { if (mode.type === 'digimode') {
this.demodulator.set_secondary_demod(mode.modulation); this.demodulator.set_secondary_demod(mode.modulation);
if (mode.bandpass) { var uMode = Modes.findByModulation(underlyingModulation);
this.demodulator.setBandpass(mode.bandpass); var bandpass = mode.bandpass || (uMode && uMode.bandpass);
if (bandpass) {
this.demodulator.setBandpass(bandpass);
} else {
this.demodulator.disableBandpass();
} }
} else { } else {
this.demodulator.set_secondary_demod(false); this.demodulator.set_secondary_demod(false);
@ -147,7 +148,7 @@ DemodulatorPanel.prototype.setMode = function(requestedModulation, underlyingMod
this.demodulator.start(); this.demodulator.start();
this.mode = mode; this.mode = mode;
this.underlyingModulation = modulation; this.underlyingModulation = underlyingModulation;
this.updateButtons(); this.updateButtons();
this.updatePanels(); this.updatePanels();
@ -161,7 +162,8 @@ DemodulatorPanel.prototype.disableDigiMode = function() {
DemodulatorPanel.prototype.updatePanels = function() { DemodulatorPanel.prototype.updatePanels = function() {
var modulation = this.getDemodulator().get_secondary_demod(); var modulation = this.getDemodulator().get_secondary_demod();
$('#openwebrx-panel-digimodes').attr('data-mode', modulation); $('#openwebrx-panel-digimodes').attr('data-mode', modulation);
toggle_panel("openwebrx-panel-digimodes", !!modulation); var mode = Modes.findByModulation(modulation);
toggle_panel("openwebrx-panel-digimodes", modulation && (!mode || mode.secondaryFft));
toggle_panel("openwebrx-panel-wsjt-message", ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65", "msk144"].indexOf(modulation) >= 0); toggle_panel("openwebrx-panel-wsjt-message", ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65", "msk144"].indexOf(modulation) >= 0);
toggle_panel("openwebrx-panel-js8-message", modulation == "js8"); toggle_panel("openwebrx-panel-js8-message", modulation == "js8");
toggle_panel("openwebrx-panel-packet-message", ["packet", "ais"].indexOf(modulation) >= 0); toggle_panel("openwebrx-panel-packet-message", ["packet", "ais"].indexOf(modulation) >= 0);
@ -393,6 +395,6 @@ DemodulatorPanel.prototype.setTuningPrecision = function(precision) {
$.fn.demodulatorPanel = function(){ $.fn.demodulatorPanel = function(){
if (!this.data('panel')) { if (!this.data('panel')) {
this.data('panel', new DemodulatorPanel(this)); this.data('panel', new DemodulatorPanel(this));
}; }
return this.data('panel'); return this.data('panel');
}; };

View File

@ -43,6 +43,7 @@ var Mode = function(json){
} }
if (this.type === 'digimode') { if (this.type === 'digimode') {
this.underlying = json.underlying; this.underlying = json.underlying;
this.secondaryFft = json.secondaryFft;
} }
}; };

View File

@ -0,0 +1,5 @@
$.fn.logMessages = function() {
$.each(this, function(){
$(this).scrollTop(this.scrollHeight);
});
};

View File

@ -8,4 +8,5 @@ $(function(){
$('.optional-section').optionalSection(); $('.optional-section').optionalSection();
$('#scheduler').schedulerInput(); $('#scheduler').schedulerInput();
$('.exponential-input').exponentialInput(); $('.exponential-input').exponentialInput();
$('.device-log-messages').logMessages();
}); });

View File

@ -1,9 +1,11 @@
[core] [core]
data_directory = /var/lib/openwebrx data_directory = /var/lib/openwebrx
temporary_directory = /tmp temporary_directory = /tmp
log_level = INFO
[web] [web]
port = 8073 port = 8073
ipv6 = true
[aprs] [aprs]
# path to the aprs symbols repository (get it here: https://github.com/hessu/aprs-symbols) # path to the aprs symbols repository (get it here: https://github.com/hessu/aprs-symbols)