Added per-profile tuning step, made receiver follow tuning step, made mouse wheel tune frequency (button+wheel to zoom).

This commit is contained in:
Marat Fayzullin 2022-07-24 18:12:48 -04:00
parent 6192978f2f
commit 3fa7705245
4 changed files with 71 additions and 25 deletions

View File

@ -31,6 +31,7 @@ var fft_compression = "none";
var fft_codec;
var waterfall_setup_done = 0;
var secondary_fft_size;
var tuning_step = 1;
function updateVolume() {
audioEngine.setVolume(parseFloat($("#openwebrx-panel-volume").val()) / 100);
@ -268,7 +269,9 @@ function scale_canvas_mousedown(evt) {
function scale_offset_freq_from_px(x, visible_range) {
if (typeof visible_range === "undefined") visible_range = get_visible_freq_range();
return (visible_range.start + visible_range.bw * (x / waterfallWidth())) - center_freq;
var f = (visible_range.start + visible_range.bw * (x / waterfallWidth())) - center_freq;
return tuning_step>0? Math.round(f / tuning_step) * tuning_step : f;
}
function scale_canvas_mousemove(evt) {
@ -513,11 +516,16 @@ function resize_scale() {
function canvas_get_freq_offset(relativeX) {
var rel = (relativeX / canvas_container.clientWidth);
return Math.round((bandwidth * rel) - (bandwidth / 2));
var off = (bandwidth * rel) - (bandwidth / 2);
return tuning_step>0?
Math.round(off / tuning_step) * tuning_step : Math.round(off);
}
function canvas_get_frequency(relativeX) {
return center_freq + canvas_get_freq_offset(relativeX);
var f = center_freq + canvas_get_freq_offset(relativeX);
return tuning_step>0? Math.round(f / tuning_step) * tuning_step : f;
}
@ -535,16 +543,23 @@ function format_frequency(format, freq_hz, pre_divide, decimals) {
var canvas_drag = false;
var canvas_drag_min_delta = 1;
var canvas_mouse_down = false;
var canvas_mouse2_down = 0;
var canvas_drag_last_x;
var canvas_drag_last_y;
var canvas_drag_start_x;
var canvas_drag_start_y;
function canvas_mousedown(evt) {
canvas_mouse_down = true;
canvas_drag = false;
canvas_drag_last_x = canvas_drag_start_x = evt.pageX;
canvas_drag_last_y = canvas_drag_start_y = evt.pageY;
if (evt.button > 0)
if (canvas_mouse2_down == 0)
canvas_mouse2_down = evt.button;
else {
canvas_mouse_down = true;
canvas_drag = false;
canvas_drag_last_x = canvas_drag_start_x = evt.pageX;
canvas_drag_last_y = canvas_drag_start_y = evt.pageY;
}
evt.preventDefault(); //don't show text selection mouse pointer
}
@ -581,16 +596,21 @@ function canvas_container_mouseleave() {
}
function canvas_mouseup(evt) {
if (!waterfall_setup_done) return;
var relativeX = get_relative_x(evt);
if (evt.button > 0) {
if (evt.button == canvas_mouse2_down)
canvas_mouse2_down = 0;
} else {
if (!waterfall_setup_done) return;
var relativeX = get_relative_x(evt);
if (!canvas_drag) {
$('#openwebrx-panel-receiver').demodulatorPanel().getDemodulator().set_offset_frequency(canvas_get_freq_offset(relativeX));
if (!canvas_drag) {
$('#openwebrx-panel-receiver').demodulatorPanel().getDemodulator().set_offset_frequency(canvas_get_freq_offset(relativeX));
}
else {
canvas_end_drag();
}
canvas_mouse_down = false;
}
else {
canvas_end_drag();
}
canvas_mouse_down = false;
}
function canvas_end_drag() {
@ -616,14 +636,18 @@ function get_relative_x(evt) {
function canvas_mousewheel(evt) {
if (!waterfall_setup_done) return;
var delta = -evt.deltaY;
// deltaMode 0 means pixels instead of lines
if ('deltaMode' in evt && evt.deltaMode === 0) {
delta /= 50;
}
var relativeX = get_relative_x(evt);
zoom_step(delta, relativeX, zoom_center_where_calc(evt.pageX));
var dir = (evt.deltaY / Math.abs(evt.deltaY)) > 0;
// Zoom when mouse button down, tune otherwise
if (canvas_mouse2_down > 0) {
zoom_step(dir, relativeX, zoom_center_where_calc(evt.pageX));
} else {
var f = $('#openwebrx-panel-receiver').demodulatorPanel().getDemodulator().get_offset_frequency();
f += dir? -tuning_step : tuning_step;
$('#openwebrx-panel-receiver').demodulatorPanel().getDemodulator().set_offset_frequency(f);
}
evt.preventDefault();
}
@ -783,6 +807,9 @@ function on_ws_recv(evt) {
if ('tuning_precision' in config)
$('#openwebrx-panel-receiver').demodulatorPanel().setTuningPrecision(config['tuning_precision']);
if ('tuning_step' in config)
tuning_step = config['tuning_step'];
break;
case "secondary_config":
var s = json['value'];

View File

@ -33,6 +33,7 @@ defaultConfig = PropertyLayer(
samp_rate=2400000,
start_freq=439275000,
start_mod="nfm",
tuning_step="1000",
),
"2m": PropertyLayer(
name="2m",
@ -41,6 +42,7 @@ defaultConfig = PropertyLayer(
samp_rate=2048000,
start_freq=145725000,
start_mod="nfm",
tuning_step="1000",
),
}
),
@ -57,6 +59,7 @@ defaultConfig = PropertyLayer(
samp_rate=384000,
start_freq=14070000,
start_mod="usb",
tuning_step="500",
),
"30m": PropertyLayer(
name="30m",
@ -64,6 +67,7 @@ defaultConfig = PropertyLayer(
samp_rate=192000,
start_freq=10142000,
start_mod="usb",
tuning_step="500",
),
"40m": PropertyLayer(
name="40m",
@ -71,6 +75,7 @@ defaultConfig = PropertyLayer(
samp_rate=256000,
start_freq=7070000,
start_mod="lsb",
tuning_step="500",
),
"80m": PropertyLayer(
name="80m",
@ -78,6 +83,7 @@ defaultConfig = PropertyLayer(
samp_rate=384000,
start_freq=3570000,
start_mod="lsb",
tuning_step="500",
),
"49m": PropertyLayer(
name="49m Broadcast",
@ -85,6 +91,7 @@ defaultConfig = PropertyLayer(
samp_rate=384000,
start_freq=6070000,
start_mod="am",
tuning_step="1000",
),
}
),
@ -102,6 +109,7 @@ defaultConfig = PropertyLayer(
samp_rate=500000,
start_freq=14070000,
start_mod="usb",
tuning_step="500",
),
"30m": PropertyLayer(
name="30m",
@ -110,6 +118,7 @@ defaultConfig = PropertyLayer(
samp_rate=250000,
start_freq=10142000,
start_mod="usb",
tuning_step="500",
),
"40m": PropertyLayer(
name="40m",
@ -118,6 +127,7 @@ defaultConfig = PropertyLayer(
samp_rate=500000,
start_freq=7070000,
start_mod="lsb",
tuning_step="500",
),
"80m": PropertyLayer(
name="80m",
@ -126,6 +136,7 @@ defaultConfig = PropertyLayer(
samp_rate=500000,
start_freq=3570000,
start_mod="lsb",
tuning_step="500",
),
"49m": PropertyLayer(
name="49m Broadcast",
@ -134,6 +145,7 @@ defaultConfig = PropertyLayer(
samp_rate=500000,
start_freq=6070000,
start_mod="am",
tuning_step="1000",
),
}
),

View File

@ -120,6 +120,7 @@ class OpenWebRxReceiverClient(OpenWebRxClient, SdrSourceEventClient):
"start_mod",
"start_freq",
"center_freq",
"tuning_step",
"initial_squelch_level",
"sdr_id",
"profile_id",

View File

@ -12,8 +12,8 @@ from owrx.command import CommandMapper
from owrx.socket import getAvailablePort
from owrx.property import PropertyStack, PropertyLayer, PropertyFilter, PropertyCarousel, PropertyDeleted
from owrx.property.filter import ByLambda
from owrx.form.input import Input, TextInput, NumberInput, CheckboxInput, ModesInput, ExponentialInput
from owrx.form.input.converter import OptionalConverter
from owrx.form.input import Input, TextInput, NumberInput, CheckboxInput, ModesInput, ExponentialInput, DropdownInput, Option
from owrx.form.input.converter import OptionalConverter, IntConverter
from owrx.form.input.device import GainInput, SchedulerInput, WaterfallLevelsInput
from owrx.form.input.validator import RequiredValidator
from owrx.form.section import OptionalSection
@ -565,6 +565,12 @@ class SdrDeviceDescription(object):
ExponentialInput("samp_rate", "Sample rate", "S/s"),
ExponentialInput("start_freq", "Initial frequency", "Hz"),
ModesInput("start_mod", "Initial modulation"),
DropdownInput(
"tuning_step",
"Tuning step",
options=[Option(str(i), "{} Hz".format(i)) for i in [1, 100, 500, 1000, 2500, 3000, 5000, 6000, 10000, 12000, 50000]],
converter=IntConverter(),
),
NumberInput("initial_squelch_level", "Initial squelch level", append="dBFS"),
]
@ -589,7 +595,7 @@ class SdrDeviceDescription(object):
return keys
def getProfileMandatoryKeys(self):
return ["name", "center_freq", "samp_rate", "start_freq", "start_mod"]
return ["name", "center_freq", "samp_rate", "start_freq", "start_mod", "tuning_step"]
def getProfileOptionalKeys(self):
return ["initial_squelch_level", "rf_gain", "lfo_offset", "waterfall_levels"]