mirror of
https://github.com/jketterl/openwebrx.git
synced 2025-12-06 07:12:09 +01:00
add DAB service selector
This commit is contained in:
parent
f33dfda005
commit
ad1b693dcb
|
|
@ -1,4 +1,5 @@
|
||||||
from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, MetaProvider
|
from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, \
|
||||||
|
MetaProvider, DabServiceSelector
|
||||||
from csdr.module import PickleModule
|
from csdr.module import PickleModule
|
||||||
from csdreti.modules import EtiDecoder
|
from csdreti.modules import EtiDecoder
|
||||||
from owrx.dab.dablin import DablinModule
|
from owrx.dab.dablin import DablinModule
|
||||||
|
|
@ -46,7 +47,7 @@ class MetaProcessor(PickleModule):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class Dablin(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, MetaProvider):
|
class Dablin(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, MetaProvider, DabServiceSelector):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
shift = Shift(0)
|
shift = Shift(0)
|
||||||
decoder = EtiDecoder()
|
decoder = EtiDecoder()
|
||||||
|
|
@ -59,10 +60,12 @@ class Dablin(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain,
|
||||||
# will be replaced by setMetaWriter().
|
# will be replaced by setMetaWriter().
|
||||||
self.processor.setWriter(Buffer(Format.CHAR))
|
self.processor.setWriter(Buffer(Format.CHAR))
|
||||||
|
|
||||||
|
self.dablin = DablinModule()
|
||||||
|
|
||||||
workers = [
|
workers = [
|
||||||
shift,
|
shift,
|
||||||
decoder,
|
decoder,
|
||||||
DablinModule(),
|
self.dablin,
|
||||||
Downmix(Format.FLOAT),
|
Downmix(Format.FLOAT),
|
||||||
]
|
]
|
||||||
super().__init__(workers)
|
super().__init__(workers)
|
||||||
|
|
@ -84,3 +87,6 @@ class Dablin(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain,
|
||||||
|
|
||||||
def setMetaWriter(self, writer: Writer) -> None:
|
def setMetaWriter(self, writer: Writer) -> None:
|
||||||
self.processor.setWriter(writer)
|
self.processor.setWriter(writer)
|
||||||
|
|
||||||
|
def setDabServiceId(self, serviceId: int) -> None:
|
||||||
|
self.dablin.setDabServiceId(serviceId)
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,12 @@ class RdsChain(ABC):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DabServiceSelector(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def setDabServiceId(self, serviceId: int) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BaseDemodulatorChain(Chain):
|
class BaseDemodulatorChain(Chain):
|
||||||
def supportsSquelch(self) -> bool:
|
def supportsSquelch(self) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,13 @@ popd
|
||||||
rm -rf js8py
|
rm -rf js8py
|
||||||
|
|
||||||
git clone https://github.com/jketterl/csdr.git
|
git clone https://github.com/jketterl/csdr.git
|
||||||
# latest develop as of 2024-01-22 (downmix format)
|
# latest develop as of 2024-01-25 (exemodule setargs)
|
||||||
cmakebuild csdr e6ae546a6a1d3fd052fe962eb5a04fd33e794214
|
cmakebuild csdr 344179a616cdbadf501479ce9ed1b836543e657b
|
||||||
|
|
||||||
git clone https://github.com/jketterl/pycsdr.git
|
git clone https://github.com/jketterl/pycsdr.git
|
||||||
cd pycsdr
|
cd pycsdr
|
||||||
# latest develop as of 2024-01-22 (downmix format)
|
# latest develop as of 2024-01-25 (execmodule setargs)
|
||||||
git checkout c7dafe83d08b74012e233502dff0bc6e6f17c01c
|
git checkout 9063b8a119e366c31d089596641a24a427e3cbdc
|
||||||
./setup.py install install_headers
|
./setup.py install install_headers
|
||||||
cd ..
|
cd ..
|
||||||
rm -rf pycsdr
|
rm -rf pycsdr
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,7 @@ function Demodulator(offset_frequency, modulation) {
|
||||||
this.filter = new Filter(this);
|
this.filter = new Filter(this);
|
||||||
this.squelch_level = -150;
|
this.squelch_level = -150;
|
||||||
this.dmr_filter = 3;
|
this.dmr_filter = 3;
|
||||||
|
this.dab_service_id = 0;
|
||||||
this.started = false;
|
this.started = false;
|
||||||
this.state = {};
|
this.state = {};
|
||||||
this.secondary_demod = false;
|
this.secondary_demod = false;
|
||||||
|
|
@ -294,6 +295,7 @@ Demodulator.prototype.set = function () { //this function sends demodulator par
|
||||||
"offset_freq": this.offset_frequency,
|
"offset_freq": this.offset_frequency,
|
||||||
"mod": this.modulation,
|
"mod": this.modulation,
|
||||||
"dmr_filter": this.dmr_filter,
|
"dmr_filter": this.dmr_filter,
|
||||||
|
"dab_service_id": this.dab_service_id,
|
||||||
"squelch_level": this.squelch_level,
|
"squelch_level": this.squelch_level,
|
||||||
"secondary_mod": this.secondary_demod,
|
"secondary_mod": this.secondary_demod,
|
||||||
"secondary_offset_freq": this.secondary_offset_freq
|
"secondary_offset_freq": this.secondary_offset_freq
|
||||||
|
|
@ -331,6 +333,11 @@ Demodulator.prototype.setDmrFilter = function(dmr_filter) {
|
||||||
this.set();
|
this.set();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Demodulator.prototype.setDabServiceId = function(dab_service_id) {
|
||||||
|
this.dab_service_id = dab_service_id;
|
||||||
|
this.set();
|
||||||
|
}
|
||||||
|
|
||||||
Demodulator.prototype.setBandpass = function(bandpass) {
|
Demodulator.prototype.setBandpass = function(bandpass) {
|
||||||
this.bandpass = bandpass;
|
this.bandpass = bandpass;
|
||||||
this.low_cut = bandpass.low_cut;
|
this.low_cut = bandpass.low_cut;
|
||||||
|
|
|
||||||
|
|
@ -553,9 +553,12 @@ WfmMetaPanel.prototype.clear = function() {
|
||||||
function DabMetaPanel(el) {
|
function DabMetaPanel(el) {
|
||||||
MetaPanel.call(this, el);
|
MetaPanel.call(this, el);
|
||||||
this.modes = ['DAB'];
|
this.modes = ['DAB'];
|
||||||
$(this.el).html(
|
this.$select = $('<select id="dab-service-id"></select>');
|
||||||
'<select id="dab-service-id"></select>'
|
$(this.el).append(this.$select);
|
||||||
)
|
this.$select.on("change", function() {
|
||||||
|
var service_id = parseInt($(this).val());
|
||||||
|
$('#openwebrx-panel-receiver').demodulatorPanel().getDemodulator().setDabServiceId(service_id);
|
||||||
|
});
|
||||||
this.clear();
|
this.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -573,7 +576,10 @@ DabMetaPanel.prototype.update = function(data) {
|
||||||
var options = Object.entries(data.programmes).map(function(e) {
|
var options = Object.entries(data.programmes).map(function(e) {
|
||||||
return '<option value="' + e[0] + '">' + e[1] + '</option>';
|
return '<option value="' + e[0] + '">' + e[1] + '</option>';
|
||||||
});
|
});
|
||||||
$(this.el).find('#dab-service-id').html(options.join(''));
|
$(this.el).find('#dab-service-id').html(
|
||||||
|
'<option value="0" disabled selected></option>' +
|
||||||
|
options.join('')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.info(data);
|
console.info(data);
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,17 @@ from pycsdr.types import Format
|
||||||
|
|
||||||
class DablinModule(ExecModule):
|
class DablinModule(ExecModule):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.serviceId = 0
|
||||||
super().__init__(
|
super().__init__(
|
||||||
Format.CHAR,
|
Format.CHAR,
|
||||||
Format.FLOAT,
|
Format.FLOAT,
|
||||||
["dablin", "-1", "-p"]
|
self._buildArgs()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _buildArgs(self):
|
||||||
|
return ["dablin", "-p", "-s", "{:#06x}".format(self.serviceId)]
|
||||||
|
|
||||||
|
def setDabServiceId(self, serviceId: int) -> None:
|
||||||
|
self.serviceId = serviceId
|
||||||
|
self.setArgs(self._buildArgs())
|
||||||
|
self.restart()
|
||||||
|
|
|
||||||
11
owrx/dsp.py
11
owrx/dsp.py
|
|
@ -3,7 +3,9 @@ from owrx.property import PropertyStack, PropertyLayer, PropertyValidator, Prope
|
||||||
from owrx.property.validators import OrValidator, RegexValidator, BoolValidator
|
from owrx.property.validators import OrValidator, RegexValidator, BoolValidator
|
||||||
from owrx.modes import Modes, DigitalMode
|
from owrx.modes import Modes, DigitalMode
|
||||||
from csdr.chain import Chain
|
from csdr.chain import Chain
|
||||||
from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, SecondaryDemodulator, DialFrequencyReceiver, MetaProvider, SlotFilterChain, SecondarySelectorChain, DeemphasisTauChain, DemodulatorError, RdsChain
|
from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, \
|
||||||
|
SecondaryDemodulator, DialFrequencyReceiver, MetaProvider, SlotFilterChain, SecondarySelectorChain, \
|
||||||
|
DeemphasisTauChain, DemodulatorError, RdsChain, DabServiceSelector
|
||||||
from csdr.chain.selector import Selector, SecondarySelector
|
from csdr.chain.selector import Selector, SecondarySelector
|
||||||
from csdr.chain.clientaudio import ClientAudioChain
|
from csdr.chain.clientaudio import ClientAudioChain
|
||||||
from csdr.chain.fft import FftChain
|
from csdr.chain.fft import FftChain
|
||||||
|
|
@ -328,6 +330,11 @@ class ClientDemodulatorChain(Chain):
|
||||||
return
|
return
|
||||||
self.demodulator.setSlotFilter(filter)
|
self.demodulator.setSlotFilter(filter)
|
||||||
|
|
||||||
|
def setDabServiceId(self, serviceId: int) -> None:
|
||||||
|
if not isinstance(self.demodulator, DabServiceSelector):
|
||||||
|
return
|
||||||
|
self.demodulator.setDabServiceId(serviceId)
|
||||||
|
|
||||||
def setSecondaryFftSize(self, size: int) -> None:
|
def setSecondaryFftSize(self, size: int) -> None:
|
||||||
if size == self.secondaryFftSize:
|
if size == self.secondaryFftSize:
|
||||||
return
|
return
|
||||||
|
|
@ -422,6 +429,7 @@ class DspManager(SdrSourceEventClient, ClientDemodulatorSecondaryDspEventClient)
|
||||||
"mod": ModulationValidator(),
|
"mod": ModulationValidator(),
|
||||||
"secondary_offset_freq": "int",
|
"secondary_offset_freq": "int",
|
||||||
"dmr_filter": "int",
|
"dmr_filter": "int",
|
||||||
|
"dab_service_id": "int",
|
||||||
}
|
}
|
||||||
self.localProps = PropertyValidator(PropertyLayer().filter(*validators.keys()), validators)
|
self.localProps = PropertyValidator(PropertyLayer().filter(*validators.keys()), validators)
|
||||||
|
|
||||||
|
|
@ -502,6 +510,7 @@ class DspManager(SdrSourceEventClient, ClientDemodulatorSecondaryDspEventClient)
|
||||||
self.props.wireProperty("high_cut", self.setHighCut),
|
self.props.wireProperty("high_cut", self.setHighCut),
|
||||||
self.props.wireProperty("mod", self.setDemodulator),
|
self.props.wireProperty("mod", self.setDemodulator),
|
||||||
self.props.wireProperty("dmr_filter", self.chain.setSlotFilter),
|
self.props.wireProperty("dmr_filter", self.chain.setSlotFilter),
|
||||||
|
self.props.wireProperty("dab_service_id", self.chain.setDabServiceId),
|
||||||
self.props.wireProperty("wfm_deemphasis_tau", self.chain.setWfmDeemphasisTau),
|
self.props.wireProperty("wfm_deemphasis_tau", self.chain.setWfmDeemphasisTau),
|
||||||
self.props.wireProperty("wfm_rds_rbds", self.chain.setRdsRbds),
|
self.props.wireProperty("wfm_rds_rbds", self.chain.setRdsRbds),
|
||||||
self.props.wireProperty("secondary_mod", self.setSecondaryDemodulator),
|
self.props.wireProperty("secondary_mod", self.setSecondaryDemodulator),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue