work on some todos
This commit is contained in:
		@@ -83,3 +83,14 @@ class FftChain(Chain):
 | 
			
		||||
            self._setBlockSize(self.sampleRate / self.fps)
 | 
			
		||||
        else:
 | 
			
		||||
            self._setBlockSize(self.sampleRate / self.fps / fftAverages)
 | 
			
		||||
 | 
			
		||||
    def setCompression(self, compression: str) -> None:
 | 
			
		||||
        if compression == "adpcm" and not self.compressFftAdpcm:
 | 
			
		||||
            self.compressFftAdpcm = FftAdpcm(self.size)
 | 
			
		||||
            # should always be at the end
 | 
			
		||||
            self.append(self.compressFftAdpcm)
 | 
			
		||||
        elif compression == "none" and self.compressFftAdpcm:
 | 
			
		||||
            self.compressFftAdpcm.stop()
 | 
			
		||||
            self.compressFftAdpcm = None
 | 
			
		||||
            # should always be at that position (right?)
 | 
			
		||||
            self.remove(3)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										125
									
								
								owrx/dsp.py
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								owrx/dsp.py
									
									
									
									
									
								
							@@ -36,6 +36,10 @@ class ClientDemodulatorChain(Chain):
 | 
			
		||||
        inputRate = demod.getFixedAudioRate() if isinstance(demod, FixedAudioRateChain) else outputRate
 | 
			
		||||
        oRate = hdOutputRate if isinstance(demod, HdAudio) else outputRate
 | 
			
		||||
        self.clientAudioChain = ClientAudioChain(demod.getOutputFormat(), inputRate, oRate, audioCompression)
 | 
			
		||||
        self.secondaryFftSize = 2048
 | 
			
		||||
        self.secondaryFftOverlapFactor = 0.3
 | 
			
		||||
        self.secondaryFftFps = 9
 | 
			
		||||
        self.secondaryFftCompression = "adpcm"
 | 
			
		||||
        self.secondaryFftChain = None
 | 
			
		||||
        self.metaWriter = None
 | 
			
		||||
        self.secondaryFftWriter = None
 | 
			
		||||
@@ -157,14 +161,18 @@ class ClientDemodulatorChain(Chain):
 | 
			
		||||
            self.secondaryFftChain = None
 | 
			
		||||
 | 
			
		||||
        if self.secondaryDemodulator is not None and self.secondaryFftChain is None:
 | 
			
		||||
            # TODO eliminate constants
 | 
			
		||||
            self.secondaryFftChain = FftChain(self._getSelectorOutputRate(), 2048, 0.3, 9, "adpcm")
 | 
			
		||||
            self.secondaryFftChain.setReader(self.selectorBuffer.getReader())
 | 
			
		||||
            self.secondaryFftChain.setWriter(self.secondaryFftWriter)
 | 
			
		||||
            self._createSecondaryFftChain()
 | 
			
		||||
 | 
			
		||||
        if self.secondaryFftChain is not None:
 | 
			
		||||
            self.secondaryFftChain.setSampleRate(rate)
 | 
			
		||||
 | 
			
		||||
    def _createSecondaryFftChain(self):
 | 
			
		||||
        if self.secondaryFftChain is not None:
 | 
			
		||||
            self.secondaryFftChain.stop()
 | 
			
		||||
        self.secondaryFftChain = FftChain(self._getSelectorOutputRate(), self.secondaryFftSize, self.secondaryFftOverlapFactor, self.secondaryFftFps, self.secondaryFftCompression)
 | 
			
		||||
        self.secondaryFftChain.setReader(self.selectorBuffer.getReader())
 | 
			
		||||
        self.secondaryFftChain.setWriter(self.secondaryFftWriter)
 | 
			
		||||
 | 
			
		||||
    def _syncSquelch(self):
 | 
			
		||||
        if not self.demodulator.supportsSquelch() or (self.secondaryDemodulator is not None and not self.secondaryDemodulator.supportsSquelch()):
 | 
			
		||||
            self.selector.setSquelchLevel(-150)
 | 
			
		||||
@@ -245,7 +253,6 @@ class ClientDemodulatorChain(Chain):
 | 
			
		||||
            return
 | 
			
		||||
        self.sampleRate = sampleRate
 | 
			
		||||
        self.selector.setInputRate(sampleRate)
 | 
			
		||||
        # TODO update secondary FFT
 | 
			
		||||
 | 
			
		||||
    def setPowerWriter(self, writer: Writer) -> None:
 | 
			
		||||
        self.selector.setPowerWriter(writer)
 | 
			
		||||
@@ -278,8 +285,12 @@ class ClientDemodulatorChain(Chain):
 | 
			
		||||
        self.demodulator.setSlotFilter(filter)
 | 
			
		||||
 | 
			
		||||
    def setSecondaryFftSize(self, size: int) -> None:
 | 
			
		||||
        # TODO
 | 
			
		||||
        pass
 | 
			
		||||
        if size == self.secondaryFftSize:
 | 
			
		||||
            return
 | 
			
		||||
        self.secondaryFftSize = size
 | 
			
		||||
        if not self.secondaryFftChain:
 | 
			
		||||
            return
 | 
			
		||||
        self._createSecondaryFftChain()
 | 
			
		||||
 | 
			
		||||
    def setSecondaryFrequencyOffset(self, freq: int) -> None:
 | 
			
		||||
        if self.secondaryFrequencyOffset == freq:
 | 
			
		||||
@@ -290,6 +301,35 @@ class ClientDemodulatorChain(Chain):
 | 
			
		||||
            return
 | 
			
		||||
        self.secondarySelector.setFrequencyOffset(self.secondaryFrequencyOffset)
 | 
			
		||||
 | 
			
		||||
    def setSecondaryFftCompression(self, compression: str) -> None:
 | 
			
		||||
        if compression == self.secondaryFftCompression:
 | 
			
		||||
            return
 | 
			
		||||
        self.secondaryFftCompression = compression
 | 
			
		||||
        if not self.secondaryFftChain:
 | 
			
		||||
            return
 | 
			
		||||
        self.secondaryFftChain.setCompression(self.secondaryFftCompression)
 | 
			
		||||
 | 
			
		||||
    def setSecondaryFftOverlapFactor(self, overlap: float) -> None:
 | 
			
		||||
        if overlap == self.secondaryFftOverlapFactor:
 | 
			
		||||
            return
 | 
			
		||||
        self.secondaryFftOverlapFactor = overlap
 | 
			
		||||
        if not self.secondaryFftChain:
 | 
			
		||||
            return
 | 
			
		||||
        self.secondaryFftChain.setVOverlapFactor(self.secondaryFftOverlapFactor)
 | 
			
		||||
 | 
			
		||||
    def setSecondaryFftFps(self, fps: int) -> None:
 | 
			
		||||
        if fps == self.secondaryFftFps:
 | 
			
		||||
            return
 | 
			
		||||
        self.secondaryFftFps = fps
 | 
			
		||||
        if not self.secondaryFftChain:
 | 
			
		||||
            return
 | 
			
		||||
        self.secondaryFftChain.setFps(self.secondaryFftFps)
 | 
			
		||||
 | 
			
		||||
    def getSecondaryFftOutputFormat(self) -> Format:
 | 
			
		||||
        if self.secondaryFftCompression == "adpcm":
 | 
			
		||||
            return Format.CHAR
 | 
			
		||||
        return Format.SHORT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ModulationValidator(OrValidator):
 | 
			
		||||
    """
 | 
			
		||||
@@ -307,6 +347,9 @@ class DspManager(SdrSourceEventClient):
 | 
			
		||||
 | 
			
		||||
        self.props = PropertyStack()
 | 
			
		||||
 | 
			
		||||
        # current audio mode. should be "audio" or "hd_audio" depending on what demodulatur is in use.
 | 
			
		||||
        self.audioOutput = None
 | 
			
		||||
 | 
			
		||||
        # local demodulator properties not forwarded to the sdr
 | 
			
		||||
        # ensure strict validation since these can be set from the client
 | 
			
		||||
        # and are used to build executable commands
 | 
			
		||||
@@ -361,34 +404,6 @@ class DspManager(SdrSourceEventClient):
 | 
			
		||||
 | 
			
		||||
        self.readers = {}
 | 
			
		||||
 | 
			
		||||
        # wire audio output
 | 
			
		||||
        buffer = Buffer(self.chain.getOutputFormat())
 | 
			
		||||
        self.chain.setWriter(buffer)
 | 
			
		||||
        # TODO check for hd audio
 | 
			
		||||
        self.wireOutput("audio", buffer)
 | 
			
		||||
 | 
			
		||||
        # wire power level output
 | 
			
		||||
        buffer = Buffer(Format.FLOAT)
 | 
			
		||||
        self.chain.setPowerWriter(buffer)
 | 
			
		||||
        self.wireOutput("smeter", buffer)
 | 
			
		||||
 | 
			
		||||
        # wire meta output
 | 
			
		||||
        buffer = Buffer(Format.CHAR)
 | 
			
		||||
        self.chain.setMetaWriter(buffer)
 | 
			
		||||
        self.wireOutput("meta", buffer)
 | 
			
		||||
 | 
			
		||||
        # wire secondary FFT
 | 
			
		||||
        # TODO format is different depending on compression
 | 
			
		||||
        buffer = Buffer(Format.CHAR)
 | 
			
		||||
        self.chain.setSecondaryFftWriter(buffer)
 | 
			
		||||
        self.wireOutput("secondary_fft", buffer)
 | 
			
		||||
 | 
			
		||||
        # wire secondary demodulator
 | 
			
		||||
        buffer = Buffer(Format.CHAR)
 | 
			
		||||
        self.chain.setSecondaryWriter(buffer)
 | 
			
		||||
        # TODO there's multiple outputs depending on the modulation right now
 | 
			
		||||
        self.wireOutput("secondary_demod", buffer)
 | 
			
		||||
 | 
			
		||||
        if "start_mod" in self.props:
 | 
			
		||||
            self.setDemodulator(self.props["start_mod"])
 | 
			
		||||
            mode = Modes.findByModulation(self.props["start_mod"])
 | 
			
		||||
@@ -404,8 +419,9 @@ class DspManager(SdrSourceEventClient):
 | 
			
		||||
 | 
			
		||||
        self.subscriptions = [
 | 
			
		||||
            self.props.wireProperty("audio_compression", self.setAudioCompression),
 | 
			
		||||
            # probably unused:
 | 
			
		||||
            # self.props.wireProperty("fft_compression", self.dsp.set_fft_compression),
 | 
			
		||||
            self.props.wireProperty("fft_compression", self.chain.setSecondaryFftCompression),
 | 
			
		||||
            self.props.wireProperty("fft_voverlap_factor", self.chain.setSecondaryFftOverlapFactor),
 | 
			
		||||
            self.props.wireProperty("fft_fps", self.chain.setSecondaryFftFps),
 | 
			
		||||
            self.props.wireProperty("digimodes_fft_size", self.chain.setSecondaryFftSize),
 | 
			
		||||
            self.props.wireProperty("samp_rate", self.chain.setSampleRate),
 | 
			
		||||
            self.props.wireProperty("output_rate", self.chain.setOutputRate),
 | 
			
		||||
@@ -437,6 +453,26 @@ class DspManager(SdrSourceEventClient):
 | 
			
		||||
            self.props.wireProperty("secondary_offset_freq", self.chain.setSecondaryFrequencyOffset),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        # wire power level output
 | 
			
		||||
        buffer = Buffer(Format.FLOAT)
 | 
			
		||||
        self.chain.setPowerWriter(buffer)
 | 
			
		||||
        self.wireOutput("smeter", buffer)
 | 
			
		||||
 | 
			
		||||
        # wire meta output
 | 
			
		||||
        buffer = Buffer(Format.CHAR)
 | 
			
		||||
        self.chain.setMetaWriter(buffer)
 | 
			
		||||
        self.wireOutput("meta", buffer)
 | 
			
		||||
 | 
			
		||||
        # wire secondary FFT
 | 
			
		||||
        buffer = Buffer(self.chain.getSecondaryFftOutputFormat())
 | 
			
		||||
        self.chain.setSecondaryFftWriter(buffer)
 | 
			
		||||
        self.wireOutput("secondary_fft", buffer)
 | 
			
		||||
 | 
			
		||||
        # wire secondary demodulator
 | 
			
		||||
        buffer = Buffer(Format.CHAR)
 | 
			
		||||
        self.chain.setSecondaryWriter(buffer)
 | 
			
		||||
        self.wireOutput("secondary_demod", buffer)
 | 
			
		||||
 | 
			
		||||
        self.startOnAvailable = False
 | 
			
		||||
 | 
			
		||||
        self.sdrSource.addClient(self)
 | 
			
		||||
@@ -487,13 +523,14 @@ class DspManager(SdrSourceEventClient):
 | 
			
		||||
            raise ValueError("unsupported demodulator: {}".format(mod))
 | 
			
		||||
        self.chain.setDemodulator(demodulator)
 | 
			
		||||
 | 
			
		||||
        # re-wire the audio to the correct client API
 | 
			
		||||
        buffer = Buffer(self.chain.getOutputFormat())
 | 
			
		||||
        self.chain.setWriter(buffer)
 | 
			
		||||
        if isinstance(demodulator, HdAudio):
 | 
			
		||||
            self.wireOutput("hd_audio", buffer)
 | 
			
		||||
        else:
 | 
			
		||||
            self.wireOutput("audio", buffer)
 | 
			
		||||
        output = "hd_audio" if isinstance(demodulator, HdAudio) else "audio"
 | 
			
		||||
 | 
			
		||||
        if output != self.audioOutput:
 | 
			
		||||
            self.audioOutput = output
 | 
			
		||||
            # re-wire the audio to the correct client API
 | 
			
		||||
            buffer = Buffer(self.chain.getOutputFormat())
 | 
			
		||||
            self.chain.setWriter(buffer)
 | 
			
		||||
            self.wireOutput(self.audioOutput, buffer)
 | 
			
		||||
 | 
			
		||||
    def sendSecondaryConfig(self):
 | 
			
		||||
        self.handler.write_secondary_dsp_config(
 | 
			
		||||
 
 | 
			
		||||
@@ -47,11 +47,12 @@ class SpectrumThread(SdrSourceEventClient):
 | 
			
		||||
        self.sdrSource.addClient(self)
 | 
			
		||||
 | 
			
		||||
        self.subscriptions += [
 | 
			
		||||
            self.props.filter("fft_size", "fft_compression").wire(self.restart),
 | 
			
		||||
            self.props.filter("fft_size").wire(self.restart),
 | 
			
		||||
            # these props can be set on the fly
 | 
			
		||||
            self.props.wireProperty("samp_rate", self.dsp.setSampleRate),
 | 
			
		||||
            self.props.wireProperty("fft_fps", self.dsp.setFps),
 | 
			
		||||
            self.props.wireProperty("fft_voverlap_factor", self.dsp.setVOverlapFactor),
 | 
			
		||||
            self.props.wireProperty("fft_compression", self.dsp.setCompression),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        buffer = Buffer(self.dsp.getOutputFormat())
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user