mirror of
https://github.com/jketterl/openwebrx.git
synced 2026-01-02 14:50:04 +01:00
add more sample rate validation
This commit is contained in:
parent
374bbb599e
commit
402eadd280
|
|
@ -15,14 +15,16 @@ class RequiredValidator(Validator):
|
|||
|
||||
|
||||
class Range(object):
|
||||
def __init__(self, start: int, end: int):
|
||||
def __init__(self, start: int, end: int = None):
|
||||
self.start = start
|
||||
self.end = end
|
||||
self.end = end if end is not None else start
|
||||
|
||||
def isInRange(self, value):
|
||||
return self.start <= value <= self.end
|
||||
|
||||
def __str__(self):
|
||||
if self.start == self.end:
|
||||
return str(self.start)
|
||||
return "{start}...{end}".format(**vars(self))
|
||||
|
||||
|
||||
|
|
@ -46,7 +48,7 @@ class RangeListValidator(Validator):
|
|||
def validate(self, key, value) -> None:
|
||||
if not any(range for range in self.rangeList if range.isInRange(value)):
|
||||
raise ValidationError(
|
||||
key, "Value is out of range {}".format(self._rangeStr())
|
||||
key, "Value is outside of the allowed range(s) {}".format(self._rangeStr())
|
||||
)
|
||||
|
||||
def _rangeStr(self):
|
||||
|
|
|
|||
|
|
@ -679,6 +679,6 @@ class SdrDeviceDescription(object):
|
|||
self.getProfileOptionalKeys(),
|
||||
)
|
||||
|
||||
def getSampleRateRanges(self) -> List[Range]:
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
# semi-sane default value. should be overridden with more specific values per device.
|
||||
return [Range(500000, 10000000)]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import re
|
||||
from ipaddress import IPv4Address, AddressValueError
|
||||
from owrx.source.soapy import SoapyConnectorSource, SoapyConnectorDeviceDescription
|
||||
from owrx.form.input import Input, CheckboxInput, DropdownInput, Option
|
||||
from owrx.form.input.device import TextInput
|
||||
from owrx.form.input.validator import Validator, ValidationError
|
||||
from owrx.form.input.validator import Validator, ValidationError, Range
|
||||
from typing import List
|
||||
|
||||
|
||||
|
|
@ -123,3 +122,6 @@ class AfedriDeviceDescription(SoapyConnectorDeviceDescription):
|
|||
|
||||
def getNumberOfChannels(self) -> int:
|
||||
return 4
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [Range(48000, 2400000)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from owrx.source.soapy import SoapyConnectorSource, SoapyConnectorDeviceDescription
|
||||
from owrx.form.input import Input, CheckboxInput
|
||||
from owrx.form.input.device import BiasTeeInput
|
||||
from owrx.form.input.validator import Range
|
||||
from typing import List
|
||||
|
||||
|
||||
|
|
@ -48,3 +49,14 @@ class AirspyDeviceDescription(SoapyConnectorDeviceDescription):
|
|||
|
||||
def getGainStages(self):
|
||||
return ["LNA", "MIX", "VGA"]
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
# Airspy R2 does 2.5 or 10 MS/s
|
||||
# Airspy mini does 3 or 6 MS/s
|
||||
# we don't know what device we're actually dealing with, but we can still clamp it down to a sum of the options.
|
||||
return [
|
||||
Range(2500000),
|
||||
Range(3000000),
|
||||
Range(6000000),
|
||||
Range(10000000),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from owrx.source.soapy import SoapyConnectorSource, SoapyConnectorDeviceDescription
|
||||
from owrx.form.input.validator import Range
|
||||
|
||||
|
||||
class AirspyhfSource(SoapyConnectorSource):
|
||||
|
|
@ -13,3 +14,13 @@ class AirspyhfDeviceDescription(SoapyConnectorDeviceDescription):
|
|||
def supportsPpm(self):
|
||||
# not currently supported by the SoapySDR module.
|
||||
return False
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [
|
||||
Range(192000),
|
||||
Range(256000),
|
||||
Range(384000),
|
||||
Range(456000),
|
||||
Range(768000),
|
||||
Range(912000),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from owrx.source.soapy import SoapyConnectorSource, SoapyConnectorDeviceDescription
|
||||
from owrx.form.input.validator import Range
|
||||
|
||||
|
||||
class BladerfSource(SoapyConnectorSource):
|
||||
|
|
@ -9,3 +10,6 @@ class BladerfSource(SoapyConnectorSource):
|
|||
class BladerfDeviceDescription(SoapyConnectorDeviceDescription):
|
||||
def getName(self):
|
||||
return "Blade RF"
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [Range(160000, 40000000)]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from owrx.source.soapy import SoapyConnectorSource, SoapyConnectorDeviceDescription
|
||||
from owrx.form.input.validator import Range
|
||||
|
||||
|
||||
class FcdppSource(SoapyConnectorSource):
|
||||
|
|
@ -9,3 +10,9 @@ class FcdppSource(SoapyConnectorSource):
|
|||
class FcdppDeviceDescription(SoapyConnectorDeviceDescription):
|
||||
def getName(self):
|
||||
return "FunCube Dongle Pro+"
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [
|
||||
Range(96000),
|
||||
Range(192000),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ from pycsdr.modules import Convert, Gain
|
|||
from pycsdr.types import Format
|
||||
from typing import List
|
||||
from owrx.form.input import Input, TextInput
|
||||
from owrx.form.input.validator import Range
|
||||
import logging
|
||||
|
||||
|
||||
|
|
@ -69,3 +70,10 @@ class FifiSdrDeviceDescription(DirectSourceDeviceDescription):
|
|||
|
||||
def getDeviceOptionalKeys(self):
|
||||
return super().getDeviceOptionalKeys() + ["device"]
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [
|
||||
Range(48000),
|
||||
Range(96000),
|
||||
Range(192000),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from owrx.source.soapy import SoapyConnectorSource, SoapyConnectorDeviceDescription
|
||||
from owrx.form.input import Input
|
||||
from owrx.form.input.device import BiasTeeInput
|
||||
from owrx.form.input.validator import Range
|
||||
from typing import List
|
||||
|
||||
|
||||
|
|
@ -34,3 +35,6 @@ class HackrfDeviceDescription(SoapyConnectorDeviceDescription):
|
|||
|
||||
def getGainStages(self):
|
||||
return ["LNA", "AMP", "VGA"]
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [Range(1000000, 20000000)]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
from owrx.source.connector import ConnectorSource, ConnectorDeviceDescription
|
||||
from owrx.command import Option, Flag
|
||||
from owrx.form.error import ValidationError
|
||||
from owrx.form.input import Input, NumberInput, TextInput, CheckboxInput
|
||||
from owrx.form.input.validator import RangeValidator
|
||||
from owrx.form.input.validator import RangeValidator, Range
|
||||
from typing import List
|
||||
|
||||
# These are the command line options available:
|
||||
|
|
@ -28,6 +27,7 @@ from typing import List
|
|||
# Radio 1: (Remote IP: 192.168.1.11, Server port: 7300)
|
||||
# Radio 2: (Remote IP: 192.168.1.22, Server port: 7301)
|
||||
|
||||
|
||||
class HpsdrSource(ConnectorSource):
|
||||
def getCommandMapper(self):
|
||||
return (
|
||||
|
|
@ -46,6 +46,7 @@ class HpsdrSource(ConnectorSource):
|
|||
)
|
||||
)
|
||||
|
||||
|
||||
class RemoteInput(TextInput):
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
|
|
@ -57,6 +58,7 @@ class RemoteInput(TextInput):
|
|||
)
|
||||
)
|
||||
|
||||
|
||||
class HpsdrDeviceDescription(ConnectorDeviceDescription):
|
||||
def getName(self):
|
||||
return "HPSDR devices (Hermes / Hermes Lite 2 / Red Pitaya)"
|
||||
|
|
@ -88,3 +90,10 @@ class HpsdrDeviceDescription(ConnectorDeviceDescription):
|
|||
def getProfileOptionalKeys(self):
|
||||
return list(filter(lambda x : x != "iqswap", super().getProfileOptionalKeys()))
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [
|
||||
Range(48000),
|
||||
Range(96000),
|
||||
Range(192000),
|
||||
Range(384000),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from owrx.source.soapy import SoapyConnectorSource, SoapyConnectorDeviceDescription
|
||||
from owrx.form.input.validator import Range
|
||||
|
||||
|
||||
class LimeSdrSource(SoapyConnectorSource):
|
||||
|
|
@ -9,3 +10,6 @@ class LimeSdrSource(SoapyConnectorSource):
|
|||
class LimeSdrDeviceDescription(SoapyConnectorDeviceDescription):
|
||||
def getName(self):
|
||||
return "LimeSDR device"
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [Range(100000, 65000000)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from owrx.source.direct import DirectSource, DirectSourceDeviceDescription
|
||||
from owrx.command import Option, Flag
|
||||
from owrx.form.input import Input, DropdownEnum, DropdownInput, CheckboxInput
|
||||
from owrx.form.input.validator import Range
|
||||
from typing import List
|
||||
|
||||
|
||||
|
|
@ -81,3 +82,12 @@ class PerseussdrDeviceDescription(DirectSourceDeviceDescription):
|
|||
"adc_dither",
|
||||
"wideband",
|
||||
]
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [
|
||||
Range(125000),
|
||||
Range(250000),
|
||||
Range(500000),
|
||||
Range(1000000),
|
||||
Range(2000000),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from owrx.source.soapy import SoapyConnectorSource, SoapyConnectorDeviceDescription
|
||||
from owrx.form.input.validator import Range
|
||||
|
||||
|
||||
class PlutoSdrSource(SoapyConnectorSource):
|
||||
|
|
@ -9,3 +10,6 @@ class PlutoSdrSource(SoapyConnectorSource):
|
|||
class PlutoSdrDeviceDescription(SoapyConnectorDeviceDescription):
|
||||
def getName(self):
|
||||
return "PlutoSDR"
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [Range(520833, 61440000)]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from owrx.source.soapy import SoapyConnectorSource, SoapyConnectorDeviceDescription
|
||||
from owrx.form.input.validator import Range
|
||||
|
||||
|
||||
class RadioberrySource(SoapyConnectorSource):
|
||||
|
|
@ -9,3 +10,11 @@ class RadioberrySource(SoapyConnectorSource):
|
|||
class RadioberryDeviceDescription(SoapyConnectorDeviceDescription):
|
||||
def getName(self):
|
||||
return "RadioBerry"
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [
|
||||
Range(48000),
|
||||
Range(96000),
|
||||
Range(192000),
|
||||
Range(384000),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -37,5 +37,5 @@ class RtlSdrDeviceDescription(ConnectorDeviceDescription):
|
|||
def getProfileOptionalKeys(self):
|
||||
return super().getProfileOptionalKeys() + ["bias_tee", "direct_sampling"]
|
||||
|
||||
def getSampleRateRanges(self) -> List[Range]:
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [Range(250000, 3200000)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from owrx.source.soapy import SoapyConnectorSource, SoapyConnectorDeviceDescription
|
||||
from owrx.form.input import Input
|
||||
from owrx.form.input.device import BiasTeeInput, DirectSamplingInput
|
||||
from owrx.form.input.validator import Range
|
||||
from typing import List
|
||||
|
||||
|
||||
|
|
@ -26,3 +27,6 @@ class RtlSdrSoapyDeviceDescription(SoapyConnectorDeviceDescription):
|
|||
|
||||
def getProfileOptionalKeys(self):
|
||||
return super().getProfileOptionalKeys() + ["bias_tee", "direct_sampling"]
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [Range(250000, 3200000)]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from owrx.source.connector import ConnectorSource, ConnectorDeviceDescription
|
|||
from owrx.command import Flag, Option, Argument
|
||||
from owrx.form.input import Input
|
||||
from owrx.form.input.device import RemoteInput, DirectSamplingInput
|
||||
from owrx.form.input.validator import Range
|
||||
from typing import List
|
||||
|
||||
|
||||
|
|
@ -36,3 +37,6 @@ class RtlTcpDeviceDescription(ConnectorDeviceDescription):
|
|||
|
||||
def getProfileOptionalKeys(self):
|
||||
return super().getProfileOptionalKeys() + ["direct_sampling"]
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
return [Range(250000, 3200000)]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from owrx.source.connector import ConnectorSource, ConnectorDeviceDescription
|
|||
from owrx.command import Argument, Flag, Option
|
||||
from owrx.form.input import Input, DropdownInput, DropdownEnum, CheckboxInput
|
||||
from owrx.form.input.device import RemoteInput
|
||||
from owrx.form.input.validator import Range
|
||||
from typing import List
|
||||
|
||||
|
||||
|
|
@ -56,3 +57,7 @@ class RundsDeviceDescription(ConnectorDeviceDescription):
|
|||
|
||||
def getDeviceOptionalKeys(self):
|
||||
return super().getDeviceOptionalKeys() + ["protocol", "long"]
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
# can't be very specific here due to the wide range of devices, so this is more of a sanity check.
|
||||
return [Range(0, 20000000)]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from owrx.source.connector import ConnectorSource, ConnectorDeviceDescription
|
||||
from owrx.form.input.validator import Range
|
||||
|
||||
|
||||
class SddcSource(ConnectorSource):
|
||||
|
|
@ -12,3 +13,7 @@ class SddcDeviceDescription(ConnectorDeviceDescription):
|
|||
|
||||
def hasAgc(self):
|
||||
return False
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
# resampling is done in software... it can't cover the full range, but it's not finished either.
|
||||
return [Range(0, 64000000)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from owrx.source.soapy import SoapyConnectorSource, SoapyConnectorDeviceDescription
|
||||
from owrx.form.input import Input, CheckboxInput, DropdownInput, DropdownEnum
|
||||
from owrx.form.input.device import BiasTeeInput
|
||||
from owrx.form.input.validator import Range
|
||||
from typing import List
|
||||
|
||||
|
||||
|
|
@ -62,3 +63,29 @@ class SdrplayDeviceDescription(SoapyConnectorDeviceDescription):
|
|||
|
||||
def getProfileOptionalKeys(self):
|
||||
return super().getProfileOptionalKeys() + ["bias_tee", "rf_notch", "dab_notch", "if_mode"]
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
# this is from SoapySDRPlay3's implementation of listSampleRates().
|
||||
# i don't think it's accurate, but this is the limitation we'd be running into if we had proper soapy
|
||||
# integration.
|
||||
return [
|
||||
Range(62500),
|
||||
Range(96000),
|
||||
Range(125000),
|
||||
Range(192000),
|
||||
Range(250000),
|
||||
Range(384000),
|
||||
Range(500000),
|
||||
Range(768000),
|
||||
Range(1000000),
|
||||
Range(2000000),
|
||||
Range(2048000),
|
||||
Range(3000000),
|
||||
Range(4000000),
|
||||
Range(5000000),
|
||||
Range(6000000),
|
||||
Range(7000000),
|
||||
Range(8000000),
|
||||
Range(9000000),
|
||||
Range(10000000),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from owrx.source.soapy import SoapyConnectorSource, SoapyConnectorDeviceDescription
|
||||
from owrx.form.input.validator import Range
|
||||
|
||||
|
||||
class UhdSource(SoapyConnectorSource):
|
||||
|
|
@ -9,3 +10,7 @@ class UhdSource(SoapyConnectorSource):
|
|||
class UhdDeviceDescription(SoapyConnectorDeviceDescription):
|
||||
def getName(self):
|
||||
return "Ettus Research USRP device"
|
||||
|
||||
def getSampleRateRanges(self) -> list[Range]:
|
||||
# not sure since this depends of the specific model
|
||||
return [Range(0, 64000000)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue