Added per-profile tuning step, made receiver follow tuning step, made mouse wheel tune frequency (button+wheel to zoom).
This commit is contained in:
		@@ -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) {
 | 
			
		||||
    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,6 +596,10 @@ function canvas_container_mouseleave() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function canvas_mouseup(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);
 | 
			
		||||
 | 
			
		||||
@@ -592,6 +611,7 @@ function canvas_mouseup(evt) {
 | 
			
		||||
        }
 | 
			
		||||
        canvas_mouse_down = false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function canvas_end_drag() {
 | 
			
		||||
    canvas_container.style.cursor = "crosshair";
 | 
			
		||||
@@ -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'];
 | 
			
		||||
 
 | 
			
		||||
@@ -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",
 | 
			
		||||
                    ),
 | 
			
		||||
                }
 | 
			
		||||
            ),
 | 
			
		||||
 
 | 
			
		||||
@@ -120,6 +120,7 @@ class OpenWebRxReceiverClient(OpenWebRxClient, SdrSourceEventClient):
 | 
			
		||||
        "start_mod",
 | 
			
		||||
        "start_freq",
 | 
			
		||||
        "center_freq",
 | 
			
		||||
        "tuning_step",
 | 
			
		||||
        "initial_squelch_level",
 | 
			
		||||
        "sdr_id",
 | 
			
		||||
        "profile_id",
 | 
			
		||||
 
 | 
			
		||||
@@ -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"]
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user