refactor demodulator classes, part 1

This commit is contained in:
Jakob Ketterl
2020-05-02 00:05:20 +02:00
parent 5013af2117
commit b8f7686a6d
8 changed files with 273 additions and 239 deletions

View File

@ -9,11 +9,11 @@ function BookmarkBar() {
me.$container.find('.bookmark').removeClass('selected');
var b = $bookmark.data();
if (!b || !b.frequency || (!b.modulation && !b.digital_modulation)) return;
demodulators[0].set_offset_frequency(b.frequency - center_freq);
me.getDemodulator().set_offset_frequency(b.frequency - center_freq);
if (b.modulation) {
demodulator_analog_replace(b.modulation);
me.getDemodulatorPanel().setMode(b.modulation);
} else if (b.digital_modulation) {
demodulator_digital_replace(b.digital_modulation);
me.getDemodulatorPanel().setDigiMode(b.digital_modulation);
}
$bookmark.addClass('selected');
});
@ -108,8 +108,8 @@ BookmarkBar.prototype.showEditDialog = function(bookmark) {
if (!bookmark) {
bookmark = {
name: "",
frequency: center_freq + demodulators[0].offset_frequency,
modulation: demodulators[0].subtype
frequency: center_freq + this.getDemodulator().get_offset_frequency(),
modulation: this.getDemodulator().get_modulation()
}
}
['name', 'frequency', 'modulation'].forEach(function(key){
@ -154,6 +154,14 @@ BookmarkBar.prototype.storeBookmark = function() {
me.$dialog.hide();
};
BookmarkBar.prototype.getDemodulatorPanel = function() {
return $('#openwebrx-panel-receiver').demodulatorPanel();
};
BookmarkBar.prototype.getDemodulator = function() {
return this.getDemodulatorPanel().getDemodulator();
};
BookmarkLocalStorage = function(){
};
@ -171,7 +179,3 @@ BookmarkLocalStorage.prototype.deleteBookmark = function(data) {
bookmarks = bookmarks.filter(function(b) { return b.id !== data; });
this.setBookmarks(bookmarks);
};

View File

@ -157,18 +157,15 @@ Envelope.prototype.drag_move = function(x) {
//when any other part of the envelope is dragged, the offset frequency is changed (whole passband also moves with it)
new_value = this.drag_origin.offset_frequency + freq_change;
if (new_value > bandwidth / 2 || new_value < -bandwidth / 2) return true; //we don't allow tuning above Nyquist frequency :-)
this.demodulator.offset_frequency = new_value;
this.demodulator.set_offset_frequency(new_value);
}
//now do the actual modifications:
mkenvelopes(this.visible_range);
this.demodulator.set();
//will have to change this when changing to multi-demodulator mode:
tunedFrequencyDisplay.setFrequency(center_freq + this.demodulator.offset_frequency);
//mkenvelopes(this.visible_range);
//this.demodulator.set();
return true;
};
Envelope.prototype.drag_end = function(){
demodulator_buttons_update();
var 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;
@ -194,6 +191,9 @@ function Demodulator(offset_frequency, modulation) {
this.low_cut = mode.bandpass.low_cut;
this.high_cut = mode.bandpass.high_cut;
}
this.listeners = {
"frequencychange": []
};
}
//ranges on filter envelope that can be dragged:
@ -216,12 +216,27 @@ Demodulator.get_next_color = function() {
Demodulator.prototype.on = function(event, handler) {
this.listeners[event].push(handler);
};
Demodulator.prototype.emit = function(event, params) {
this.listeners[event].forEach(function(fn) {
fn(params);
});
};
Demodulator.prototype.set_offset_frequency = function(to_what) {
if (to_what > bandwidth / 2 || to_what < -bandwidth / 2) return;
this.offset_frequency = Math.round(to_what);
to_what = Math.round(to_what);
if (this.offset_frequency === to_what) {
return;
}
this.offset_frequency = to_what;
this.set();
this.emit("frequencychange", to_what);
mkenvelopes(get_visible_freq_range());
tunedFrequencyDisplay.setFrequency(center_freq + to_what);
//tunedFrequencyDisplay.setFrequency(center_freq + to_what);
updateHash();
};
@ -300,11 +315,21 @@ Demodulator.prototype.getBandpass = function() {
};
Demodulator.prototype.set_secondary_demod = function(secondary_demod) {
if (this.secondary_demod === secondary_demod) {
return;
}
this.secondary_demod = secondary_demod;
this.set();
};
Demodulator.prototype.get_secondary_demod = function() {
return this.secondary_demod;
};
Demodulator.prototype.set_secondary_offset_freq = function(secondary_offset) {
if (this.secondary_offset_freq === secondary_offset) {
return;
}
this.secondary_offset_freq = secondary_offset;
this.set();
};

View File

@ -0,0 +1,158 @@
function DemodulatorPanel(el) {
var self = this;
self.el = el;
self.demodulator = null;
var displayEl = el.find('.webrx-actual-freq')
this.tuneableFrequencyDisplay = displayEl.tuneableFrequencyDisplay();
displayEl.on('frequencychange', function(event, freq) {
self.getDemodulator().set_offset_frequency(freq - center_freq);
});
Modes.registerModePanel(this);
el.on('click', '.openwebrx-demodulator-button[data-modulation]', function() {
self.setMode($(this).data('modulation'));
});
el.on('change', '.openwebrx-secondary-demod-listbox', function() {
self.setDigiMode($(this).val());
});
// TODO: disable digimodes
};
DemodulatorPanel.prototype.render = function() {
var available = Modes.getModes().filter(function(m){ return m.isAvailable(); });
var normalModes = available.filter(function(m){ return m.type === 'analog'; });
var digiModes = available.filter(function(m){ return m.type === 'digimode'; });
var html = []
var buttons = normalModes.map(function(m){
return $(
'<div ' +
'class="openwebrx-button openwebrx-demodulator-button" ' +
'data-modulation="' + m.modulation + '" ' +
'id="openwebrx-button-' + m.modulation + '" r' +
'>' + m.name + '</div>'
);
});
var index = 0;
var arrayLength = buttons.length;
var chunks = [];
for (index = 0; index < arrayLength; index += 5) {
chunks.push(buttons.slice(index, index + 5));
}
html.push.apply(html, chunks.map(function(chunk){
$line = $('<div class="openwebrx-panel-line openwebrx-panel-flex-line"></div>');
$line.append.apply($line, chunk);
return $line
}));
html.push($(
'<div class="openwebrx-panel-line openwebrx-panel-flex-line">' +
'<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-dig" onclick="demodulator_digital_replace_last();">DIG</div>' +
'<select class="openwebrx-secondary-demod-listbox">' +
'<option value="none"></option>' +
digiModes.map(function(m){
return '<option value="' + m.modulation + '">' + m.name + '</option>';
}).join('') +
'</select>' +
'</div>'
));
this.el.find(".openwebrx-modes").html(html);
};
DemodulatorPanel.prototype.setMode = function(mode) {
var offset_frequency = 0;
if (this.demodulator) {
if (this.demodulator.get_modulation() === mode) {
return;
}
offset_frequency = this.demodulator.get_offset_frequency();
this.demodulator.stop();
}
this.demodulator = new Demodulator(offset_frequency, mode);
var self = this;
this.demodulator.on("frequencychange", function(freq) {
self.tuneableFrequencyDisplay.setFrequency(center_freq + freq);
});
this.demodulator.start();
this.updateButtons();
};
DemodulatorPanel.prototype.setDigiMode = function(modulation) {
var mode = Modes.findByModulation(modulation);
if (!mode) {
return;
}
if (!mode.isAvailable()) {
divlog('Digital mode "' + mode.name + '" not supported. Please check requirements', true);
return;
}
this.setMode(mode.underlying[0]);
this.getDemodulator().set_secondary_demod(modulation);
if (mode.bandpass) {
this.getDemodulator().setBandpass(mode.bandpass);
}
$('#openwebrx-panel-digimodes').attr('data-mode', modulation);
toggle_panel("openwebrx-panel-digimodes", true);
toggle_panel("openwebrx-panel-wsjt-message", ['ft8', 'wspr', 'jt65', 'jt9', 'ft4'].indexOf(modulation) >= 0);
toggle_panel("openwebrx-panel-js8-message", modulation == "js8");
toggle_panel("openwebrx-panel-packet-message", modulation === "packet");
toggle_panel("openwebrx-panel-pocsag-message", modulation === "pocsag");
updateHash();
};
DemodulatorPanel.prototype.getDemodulator = function() {
return this.demodulator;
};
DemodulatorPanel.prototype.startDemodulator = function() {
var params = $.extend(this.initialParams || {}, validateHash());
this._apply(params);
};
DemodulatorPanel.prototype._apply = function(params) {
this.setMode(params.mod);
this.getDemodulator().set_offset_frequency(params.offset_frequency);
this.updateButtons();
};
DemodulatorPanel.prototype.setInitialParams = function(params) {
this.initialParams = params;
};
DemodulatorPanel.prototype.setHashParams = function(params) {
this._apply(params);
};
DemodulatorPanel.prototype.updateButtons = function() {
var $buttons = this.el.find(".openwebrx-demodulator-button");
$buttons.removeClass("highlighted").removeClass('disabled');
var demod = this.getDemodulator()
if (!demod) return;
var mod = demod.get_modulation();
this.el.find('[data-modulation=' + mod + ']').addClass("highlighted");
var secondary_demod = this.getDemodulator().get_secondary_demod()
if (secondary_demod) {
this.el.find("#openwebrx-button-dig").addClass("highlighted");
this.el.find('#openwebrx-secondary-demod-listbox').val(secondary_demod);
var mode = Modes.findByModulation(secondary_demod);
if (mode) {
var active = mode.underlying.map(function(u){ return 'openwebrx-button-' + u; });
$buttons.filter(function(){
return this.id !== "openwebrx-button-dig" && active.indexOf(this.id) < 0;
}).addClass('disabled');
}
}
}
$.fn.demodulatorPanel = function(){
if (!this.data('panel')) {
this.data('panel', new DemodulatorPanel(this));
};
return this.data('panel');
};

View File

@ -50,7 +50,6 @@ TuneableFrequencyDisplay.prototype.setupElements = function() {
TuneableFrequencyDisplay.prototype.setupEvents = function() {
var me = this;
me.listeners = [];
me.element.on('wheel', function(e){
e.preventDefault();
@ -63,17 +62,13 @@ TuneableFrequencyDisplay.prototype.setupEvents = function() {
if (e.originalEvent.deltaY > 0) delta *= -1;
var newFrequency = me.frequency + delta;
me.listeners.forEach(function(l) {
l(newFrequency);
});
me.element.trigger('frequencychange', newFrequency);
});
var submit = function(){
var freq = parseInt(me.input.val());
if (!isNaN(freq)) {
me.listeners.forEach(function(l) {
l(freq);
});
me.element.trigger('frequencychange', freq);
}
me.input.hide();
me.displayContainer.show();
@ -96,6 +91,16 @@ TuneableFrequencyDisplay.prototype.setupEvents = function() {
});
};
TuneableFrequencyDisplay.prototype.onFrequencyChange = function(listener){
this.listeners.push(listener);
};
$.fn.frequencyDisplay = function() {
if (!this.data('frequencyDisplay')) {
this.data('frequencyDisplay', new FrequencyDisplay(this));
}
return this.data('frequencyDisplay');
}
$.fn.tuneableFrequencyDisplay = function() {
if (!this.data('frequencyDisplay')) {
this.data('frequencyDisplay', new TuneableFrequencyDisplay(this));
}
return this.data('frequencyDisplay');
}

View File

@ -1,61 +1,33 @@
var Modes = {
modes: [],
features: {},
panels: [],
setModes:function(json){
this.modes = json.map(function(m){ return new Mode(m); });
this.updateModePanel();
this.updatePanels();
},
getModes:function(){
return this.modes;
},
setFeatures:function(features){
this.features = features;
this.updateModePanel();
this.updatePanels();
},
findByModulation:function(modulation){
matches = this.modes.filter(function(m) { return m.modulation === modulation; });
if (matches.length) return matches[0]
},
updateModePanel:function() {
var available = this.modes.filter(function(m){ return m.isAvailable(); });
var normalModes = available.filter(function(m){ return m.type === 'analog'; });
var digiModes = available.filter(function(m){ return m.type === 'digimode'; });
var html = []
var buttons = normalModes.map(function(m){
return $(
'<div class="openwebrx-button openwebrx-demodulator-button"' +
'id="openwebrx-button-' + m.modulation + '"' +
'onclick="demodulator_analog_replace(\'' + m.modulation + '\');">' +
m.name + '</div>'
);
registerModePanel: function(el) {
this.panels.push(el);
},
updatePanels: function() {
var init_complete = this.modes && this.features;
this.panels.forEach(function(p) {
p.render();
if (init_complete) {
p.startDemodulator();
}
});
var index = 0;
var arrayLength = buttons.length;
var chunks = [];
for (index = 0; index < arrayLength; index += 5) {
chunks.push(buttons.slice(index, index + 5));
}
html.push.apply(html, chunks.map(function(chunk){
$line = $('<div class="openwebrx-panel-line openwebrx-panel-flex-line"></div>');
$line.append.apply($line, chunk);
return $line
}));
html.push($(
'<div class="openwebrx-panel-line openwebrx-panel-flex-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>' +
digiModes.map(function(m){
return '<option value="' + m.modulation + '">' + m.name + '</option>';
}).join('') +
'</select>' +
'</div>'
));
$("#openwebrx-panel-receiver").find(".openwebrx-modes").html(html);
}
};
@ -78,4 +50,4 @@ Mode.prototype.isAvailable = function(){
}).reduce(function(a, b){
return a && b;
}, true);
}
};