added option to run demodulator without bandpass

This commit is contained in:
Jakob Ketterl 2023-08-25 21:12:13 +02:00
parent 5b86ebdcba
commit 37ee7796db
7 changed files with 64 additions and 15 deletions

View file

@ -94,19 +94,24 @@ class Chain(Module):
if self.writer is not None:
newWorker.setWriter(self.writer)
def insert(self, newWorker):
def insert(self, newWorker, index=0):
nextWorker = None
if self.workers:
nextWorker = self.workers[0]
previousWorker = None
if index < len(self.workers):
nextWorker = self.workers[index]
if index > 0:
previousWorker = self.workers[index - 1]
self.workers.insert(0, newWorker)
self.workers.insert(index, newWorker)
if nextWorker:
self._connect(newWorker, nextWorker)
elif self.writer is not None:
newWorker.setWriter(self.writer)
if self.reader is not None:
if previousWorker:
self._connect(previousWorker, newWorker)
elif self.reader is not None:
newWorker.setReader(self.reader)
def remove(self, index):

View file

@ -1,6 +1,7 @@
from csdr.chain import Chain
from pycsdr.modules import Shift, FirDecimate, Bandpass, Squelch, FractionalDecimator, Writer
from pycsdr.types import Format
from owrx.property import PropertyDeleted
import math
@ -80,7 +81,6 @@ class Selector(Chain):
self.bandpass = self._buildBandpass()
self.bandpassCutoffs = None
self.setBandpass(-4000, 4000)
workers = [self.shift, self.decimation, self.bandpass]
@ -93,6 +93,8 @@ class Selector(Chain):
super().__init__(workers)
self.setBandpass(-4000, 4000)
def _buildBandpass(self) -> Bandpass:
bp_transition = 320.0 / self.outputRate
return Bandpass(transition=bp_transition, use_fft=True)
@ -113,16 +115,34 @@ class Selector(Chain):
def setSquelchLevel(self, level: float) -> None:
self.squelch.setSquelchLevel(self._convertToLinear(level))
def _enableBandpass(self):
index = self.indexOf(lambda x: isinstance(x, Bandpass))
if index < 0:
self.insert(self.bandpass, 2)
def _disableBandpass(self):
index = self.indexOf(lambda x: isinstance(x, Bandpass))
if index >= 0:
self.remove(index)
def setBandpass(self, lowCut: float, highCut: float) -> None:
self.bandpassCutoffs = [lowCut, highCut]
scaled = [x / self.outputRate for x in self.bandpassCutoffs]
self.bandpass.setBandpass(*scaled)
if None in self.bandpassCutoffs:
self._disableBandpass()
else:
self._enableBandpass()
scaled = [x / self.outputRate for x in self.bandpassCutoffs]
self.bandpass.setBandpass(*scaled)
def setLowCut(self, lowCut: float) -> None:
if lowCut is PropertyDeleted:
lowCut = None
self.bandpassCutoffs[0] = lowCut
self.setBandpass(*self.bandpassCutoffs)
def setHighCut(self, highCut: float) -> None:
if highCut is PropertyDeleted:
highCut = None
self.bandpassCutoffs[1] = highCut
self.setBandpass(*self.bandpassCutoffs)
@ -136,9 +156,11 @@ class Selector(Chain):
self.decimation.setOutputRate(outputRate)
self.squelch.setReportInterval(int(outputRate / (self.readings_per_second * 1024)))
index = self.indexOf(lambda x: isinstance(x, Bandpass))
self.bandpass = self._buildBandpass()
self.setBandpass(*self.bandpassCutoffs)
self.replace(2, self.bandpass)
if index >= 0:
self.replace(index, self.bandpass)
def setInputRate(self, inputRate: int) -> None:
if inputRate == self.inputRate:

View file

@ -83,9 +83,13 @@ Envelope.prototype.draw = function(visible_range){
scale_ctx.stroke();
scale_ctx.lineWidth = 1;
scale_ctx.textAlign = "left";
scale_ctx.fillText(this.demodulator.high_cut.toString(), to_px + env_att_w, env_h2);
if (this.demodulator.high_cut) {
scale_ctx.fillText(this.demodulator.high_cut.toString(), to_px + env_att_w, env_h2);
}
scale_ctx.textAlign = "right";
scale_ctx.fillText(this.demodulator.low_cut.toString(), from_px - env_att_w, env_h2);
if (this.demodulator.low_cut) {
scale_ctx.fillText(this.demodulator.low_cut.toString(), from_px - env_att_w, env_h2);
}
scale_ctx.lineWidth = 3;
}
if (typeof line !== "undefined") // out of screen?
@ -332,6 +336,13 @@ Demodulator.prototype.setBandpass = function(bandpass) {
this.set();
};
Demodulator.prototype.disableBandpass = function() {
delete this.bandpass;
this.low_cut = null;
this.high_cut = null;
this.set()
}
Demodulator.prototype.setLowCut = function(low_cut) {
this.low_cut = low_cut;
this.set();

View file

@ -137,6 +137,8 @@ DemodulatorPanel.prototype.setMode = function(requestedModulation, underlyingMod
this.demodulator.set_secondary_demod(mode.modulation);
if (mode.bandpass) {
this.demodulator.setBandpass(mode.bandpass);
} else {
this.demodulator.disableBandpass();
}
} else {
this.demodulator.set_secondary_demod(false);

View file

@ -462,6 +462,8 @@ class DspManager(SdrSourceEventClient, ClientDemodulatorSecondaryDspEventClient)
if mode.bandpass:
bpf = [mode.bandpass.low_cut, mode.bandpass.high_cut]
self.chain.setBandpass(*bpf)
else:
self.chain.setBandpass(None, None)
else:
# TODO modes should be mandatory
self.setDemodulator(self.props["start_mod"])
@ -714,7 +716,11 @@ class DspManager(SdrSourceEventClient, ClientDemodulatorSecondaryDspEventClient)
self.setProperty(k, v)
def setProperty(self, prop, value):
self.localProps[prop] = value
if value is None:
if prop in self.localProps:
del self.localProps[prop]
else:
self.localProps[prop] = value
def getClientClass(self) -> SdrClientClass:
return SdrClientClass.USER

View file

@ -168,7 +168,7 @@ class Modes(object):
"adsb",
"ADS-B",
underlying=["empty"],
bandpass=Bandpass(-1e6, 1e6),
bandpass=None,
requirements=["dump1090"],
service=True,
squelch=False,

View file

@ -266,12 +266,15 @@ class ServiceHandler(SdrSourceEventClient):
secondaryDemod = self._getSecondaryDemodulator(modeObject.modulation)
center_freq = source.getProps()["center_freq"]
sampleRate = source.getProps()["samp_rate"]
bandpass = modeObject.get_bandpass()
if isinstance(secondaryDemod, DialFrequencyReceiver):
secondaryDemod.setDialFrequency(dial["frequency"])
chain = ServiceDemodulatorChain(demod, secondaryDemod, sampleRate, dial["frequency"] - center_freq)
chain.setBandPass(bandpass.low_cut, bandpass.high_cut)
bandpass = modeObject.get_bandpass()
if bandpass:
chain.setBandPass(bandpass.low_cut, bandpass.high_cut)
else:
chain.setBandPass(None, None)
chain.setReader(source.getBuffer().getReader())
# dummy buffer, we don't use the output right now