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 fft_codec;
 | 
				
			||||||
var waterfall_setup_done = 0;
 | 
					var waterfall_setup_done = 0;
 | 
				
			||||||
var secondary_fft_size;
 | 
					var secondary_fft_size;
 | 
				
			||||||
 | 
					var tuning_step = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function updateVolume() {
 | 
					function updateVolume() {
 | 
				
			||||||
    audioEngine.setVolume(parseFloat($("#openwebrx-panel-volume").val()) / 100);
 | 
					    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) {
 | 
					function scale_offset_freq_from_px(x, visible_range) {
 | 
				
			||||||
    if (typeof visible_range === "undefined") visible_range = get_visible_freq_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) {
 | 
					function scale_canvas_mousemove(evt) {
 | 
				
			||||||
@@ -513,11 +516,16 @@ function resize_scale() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function canvas_get_freq_offset(relativeX) {
 | 
					function canvas_get_freq_offset(relativeX) {
 | 
				
			||||||
    var rel = (relativeX / canvas_container.clientWidth);
 | 
					    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) {
 | 
					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 = false;
 | 
				
			||||||
var canvas_drag_min_delta = 1;
 | 
					var canvas_drag_min_delta = 1;
 | 
				
			||||||
var canvas_mouse_down = false;
 | 
					var canvas_mouse_down = false;
 | 
				
			||||||
 | 
					var canvas_mouse2_down = 0;
 | 
				
			||||||
var canvas_drag_last_x;
 | 
					var canvas_drag_last_x;
 | 
				
			||||||
var canvas_drag_last_y;
 | 
					var canvas_drag_last_y;
 | 
				
			||||||
var canvas_drag_start_x;
 | 
					var canvas_drag_start_x;
 | 
				
			||||||
var canvas_drag_start_y;
 | 
					var canvas_drag_start_y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function canvas_mousedown(evt) {
 | 
					function canvas_mousedown(evt) {
 | 
				
			||||||
 | 
					    if (evt.button > 0)
 | 
				
			||||||
 | 
					        if (canvas_mouse2_down == 0)
 | 
				
			||||||
 | 
					            canvas_mouse2_down = evt.button;
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
        canvas_mouse_down = true;
 | 
					        canvas_mouse_down = true;
 | 
				
			||||||
        canvas_drag = false;
 | 
					        canvas_drag = false;
 | 
				
			||||||
        canvas_drag_last_x = canvas_drag_start_x = evt.pageX;
 | 
					        canvas_drag_last_x = canvas_drag_start_x = evt.pageX;
 | 
				
			||||||
        canvas_drag_last_y = canvas_drag_start_y = evt.pageY;
 | 
					        canvas_drag_last_y = canvas_drag_start_y = evt.pageY;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    evt.preventDefault(); //don't show text selection mouse pointer
 | 
					    evt.preventDefault(); //don't show text selection mouse pointer
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -581,6 +596,10 @@ function canvas_container_mouseleave() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function canvas_mouseup(evt) {
 | 
					function canvas_mouseup(evt) {
 | 
				
			||||||
 | 
					    if (evt.button > 0) {
 | 
				
			||||||
 | 
					        if (evt.button == canvas_mouse2_down)
 | 
				
			||||||
 | 
					            canvas_mouse2_down = 0;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
        if (!waterfall_setup_done) return;
 | 
					        if (!waterfall_setup_done) return;
 | 
				
			||||||
        var relativeX = get_relative_x(evt);
 | 
					        var relativeX = get_relative_x(evt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -591,6 +610,7 @@ function canvas_mouseup(evt) {
 | 
				
			|||||||
            canvas_end_drag();
 | 
					            canvas_end_drag();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        canvas_mouse_down = false;
 | 
					        canvas_mouse_down = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function canvas_end_drag() {
 | 
					function canvas_end_drag() {
 | 
				
			||||||
@@ -616,14 +636,18 @@ function get_relative_x(evt) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function canvas_mousewheel(evt) {
 | 
					function canvas_mousewheel(evt) {
 | 
				
			||||||
    if (!waterfall_setup_done) return;
 | 
					    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);
 | 
					    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();
 | 
					    evt.preventDefault();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -783,6 +807,9 @@ function on_ws_recv(evt) {
 | 
				
			|||||||
                        if ('tuning_precision' in config)
 | 
					                        if ('tuning_precision' in config)
 | 
				
			||||||
                            $('#openwebrx-panel-receiver').demodulatorPanel().setTuningPrecision(config['tuning_precision']);
 | 
					                            $('#openwebrx-panel-receiver').demodulatorPanel().setTuningPrecision(config['tuning_precision']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if ('tuning_step' in config)
 | 
				
			||||||
 | 
					                            tuning_step = config['tuning_step'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    case "secondary_config":
 | 
					                    case "secondary_config":
 | 
				
			||||||
                        var s = json['value'];
 | 
					                        var s = json['value'];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,6 +33,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
                        samp_rate=2400000,
 | 
					                        samp_rate=2400000,
 | 
				
			||||||
                        start_freq=439275000,
 | 
					                        start_freq=439275000,
 | 
				
			||||||
                        start_mod="nfm",
 | 
					                        start_mod="nfm",
 | 
				
			||||||
 | 
					                        tuning_step="1000",
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                    "2m": PropertyLayer(
 | 
					                    "2m": PropertyLayer(
 | 
				
			||||||
                        name="2m",
 | 
					                        name="2m",
 | 
				
			||||||
@@ -41,6 +42,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
                        samp_rate=2048000,
 | 
					                        samp_rate=2048000,
 | 
				
			||||||
                        start_freq=145725000,
 | 
					                        start_freq=145725000,
 | 
				
			||||||
                        start_mod="nfm",
 | 
					                        start_mod="nfm",
 | 
				
			||||||
 | 
					                        tuning_step="1000",
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
@@ -57,6 +59,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
                        samp_rate=384000,
 | 
					                        samp_rate=384000,
 | 
				
			||||||
                        start_freq=14070000,
 | 
					                        start_freq=14070000,
 | 
				
			||||||
                        start_mod="usb",
 | 
					                        start_mod="usb",
 | 
				
			||||||
 | 
					                        tuning_step="500",
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                    "30m": PropertyLayer(
 | 
					                    "30m": PropertyLayer(
 | 
				
			||||||
                        name="30m",
 | 
					                        name="30m",
 | 
				
			||||||
@@ -64,6 +67,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
                        samp_rate=192000,
 | 
					                        samp_rate=192000,
 | 
				
			||||||
                        start_freq=10142000,
 | 
					                        start_freq=10142000,
 | 
				
			||||||
                        start_mod="usb",
 | 
					                        start_mod="usb",
 | 
				
			||||||
 | 
					                        tuning_step="500",
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                    "40m": PropertyLayer(
 | 
					                    "40m": PropertyLayer(
 | 
				
			||||||
                        name="40m",
 | 
					                        name="40m",
 | 
				
			||||||
@@ -71,6 +75,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
                        samp_rate=256000,
 | 
					                        samp_rate=256000,
 | 
				
			||||||
                        start_freq=7070000,
 | 
					                        start_freq=7070000,
 | 
				
			||||||
                        start_mod="lsb",
 | 
					                        start_mod="lsb",
 | 
				
			||||||
 | 
					                        tuning_step="500",
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                    "80m": PropertyLayer(
 | 
					                    "80m": PropertyLayer(
 | 
				
			||||||
                        name="80m",
 | 
					                        name="80m",
 | 
				
			||||||
@@ -78,6 +83,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
                        samp_rate=384000,
 | 
					                        samp_rate=384000,
 | 
				
			||||||
                        start_freq=3570000,
 | 
					                        start_freq=3570000,
 | 
				
			||||||
                        start_mod="lsb",
 | 
					                        start_mod="lsb",
 | 
				
			||||||
 | 
					                        tuning_step="500",
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                    "49m": PropertyLayer(
 | 
					                    "49m": PropertyLayer(
 | 
				
			||||||
                        name="49m Broadcast",
 | 
					                        name="49m Broadcast",
 | 
				
			||||||
@@ -85,6 +91,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
                        samp_rate=384000,
 | 
					                        samp_rate=384000,
 | 
				
			||||||
                        start_freq=6070000,
 | 
					                        start_freq=6070000,
 | 
				
			||||||
                        start_mod="am",
 | 
					                        start_mod="am",
 | 
				
			||||||
 | 
					                        tuning_step="1000",
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
@@ -102,6 +109,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
                        samp_rate=500000,
 | 
					                        samp_rate=500000,
 | 
				
			||||||
                        start_freq=14070000,
 | 
					                        start_freq=14070000,
 | 
				
			||||||
                        start_mod="usb",
 | 
					                        start_mod="usb",
 | 
				
			||||||
 | 
					                        tuning_step="500",
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                    "30m": PropertyLayer(
 | 
					                    "30m": PropertyLayer(
 | 
				
			||||||
                        name="30m",
 | 
					                        name="30m",
 | 
				
			||||||
@@ -110,6 +118,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
                        samp_rate=250000,
 | 
					                        samp_rate=250000,
 | 
				
			||||||
                        start_freq=10142000,
 | 
					                        start_freq=10142000,
 | 
				
			||||||
                        start_mod="usb",
 | 
					                        start_mod="usb",
 | 
				
			||||||
 | 
					                        tuning_step="500",
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                    "40m": PropertyLayer(
 | 
					                    "40m": PropertyLayer(
 | 
				
			||||||
                        name="40m",
 | 
					                        name="40m",
 | 
				
			||||||
@@ -118,6 +127,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
                        samp_rate=500000,
 | 
					                        samp_rate=500000,
 | 
				
			||||||
                        start_freq=7070000,
 | 
					                        start_freq=7070000,
 | 
				
			||||||
                        start_mod="lsb",
 | 
					                        start_mod="lsb",
 | 
				
			||||||
 | 
					                        tuning_step="500",
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                    "80m": PropertyLayer(
 | 
					                    "80m": PropertyLayer(
 | 
				
			||||||
                        name="80m",
 | 
					                        name="80m",
 | 
				
			||||||
@@ -126,6 +136,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
                        samp_rate=500000,
 | 
					                        samp_rate=500000,
 | 
				
			||||||
                        start_freq=3570000,
 | 
					                        start_freq=3570000,
 | 
				
			||||||
                        start_mod="lsb",
 | 
					                        start_mod="lsb",
 | 
				
			||||||
 | 
					                        tuning_step="500",
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                    "49m": PropertyLayer(
 | 
					                    "49m": PropertyLayer(
 | 
				
			||||||
                        name="49m Broadcast",
 | 
					                        name="49m Broadcast",
 | 
				
			||||||
@@ -134,6 +145,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
                        samp_rate=500000,
 | 
					                        samp_rate=500000,
 | 
				
			||||||
                        start_freq=6070000,
 | 
					                        start_freq=6070000,
 | 
				
			||||||
                        start_mod="am",
 | 
					                        start_mod="am",
 | 
				
			||||||
 | 
					                        tuning_step="1000",
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -120,6 +120,7 @@ class OpenWebRxReceiverClient(OpenWebRxClient, SdrSourceEventClient):
 | 
				
			|||||||
        "start_mod",
 | 
					        "start_mod",
 | 
				
			||||||
        "start_freq",
 | 
					        "start_freq",
 | 
				
			||||||
        "center_freq",
 | 
					        "center_freq",
 | 
				
			||||||
 | 
					        "tuning_step",
 | 
				
			||||||
        "initial_squelch_level",
 | 
					        "initial_squelch_level",
 | 
				
			||||||
        "sdr_id",
 | 
					        "sdr_id",
 | 
				
			||||||
        "profile_id",
 | 
					        "profile_id",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,8 +12,8 @@ from owrx.command import CommandMapper
 | 
				
			|||||||
from owrx.socket import getAvailablePort
 | 
					from owrx.socket import getAvailablePort
 | 
				
			||||||
from owrx.property import PropertyStack, PropertyLayer, PropertyFilter, PropertyCarousel, PropertyDeleted
 | 
					from owrx.property import PropertyStack, PropertyLayer, PropertyFilter, PropertyCarousel, PropertyDeleted
 | 
				
			||||||
from owrx.property.filter import ByLambda
 | 
					from owrx.property.filter import ByLambda
 | 
				
			||||||
from owrx.form.input import Input, TextInput, NumberInput, CheckboxInput, ModesInput, ExponentialInput
 | 
					from owrx.form.input import Input, TextInput, NumberInput, CheckboxInput, ModesInput, ExponentialInput, DropdownInput, Option
 | 
				
			||||||
from owrx.form.input.converter import OptionalConverter
 | 
					from owrx.form.input.converter import OptionalConverter, IntConverter
 | 
				
			||||||
from owrx.form.input.device import GainInput, SchedulerInput, WaterfallLevelsInput
 | 
					from owrx.form.input.device import GainInput, SchedulerInput, WaterfallLevelsInput
 | 
				
			||||||
from owrx.form.input.validator import RequiredValidator
 | 
					from owrx.form.input.validator import RequiredValidator
 | 
				
			||||||
from owrx.form.section import OptionalSection
 | 
					from owrx.form.section import OptionalSection
 | 
				
			||||||
@@ -565,6 +565,12 @@ class SdrDeviceDescription(object):
 | 
				
			|||||||
            ExponentialInput("samp_rate", "Sample rate", "S/s"),
 | 
					            ExponentialInput("samp_rate", "Sample rate", "S/s"),
 | 
				
			||||||
            ExponentialInput("start_freq", "Initial frequency", "Hz"),
 | 
					            ExponentialInput("start_freq", "Initial frequency", "Hz"),
 | 
				
			||||||
            ModesInput("start_mod", "Initial modulation"),
 | 
					            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"),
 | 
					            NumberInput("initial_squelch_level", "Initial squelch level", append="dBFS"),
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -589,7 +595,7 @@ class SdrDeviceDescription(object):
 | 
				
			|||||||
        return keys
 | 
					        return keys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def getProfileMandatoryKeys(self):
 | 
					    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):
 | 
					    def getProfileOptionalKeys(self):
 | 
				
			||||||
        return ["initial_squelch_level", "rf_gain", "lfo_offset", "waterfall_levels"]
 | 
					        return ["initial_squelch_level", "rf_gain", "lfo_offset", "waterfall_levels"]
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user