diff --git a/csdr/chain/fft.py b/csdr/chain/fft.py index ac3907f..5456ec2 100644 --- a/csdr/chain/fft.py +++ b/csdr/chain/fft.py @@ -7,11 +7,18 @@ logger.setLevel(logging.INFO) class FftChain(Chain): - def __init__(self, fft_size, fft_block_size, fft_averages, fft_compression): - logger.debug("new fft: fft_size={0}, fft_block_size={1}, fft_averages={2}, fft_compression={3}".format(fft_size, fft_block_size, fft_averages, fft_compression)) - self.fft = Fft(size=fft_size, every_n_samples=int(fft_block_size)) - self.logAveragePower = LogAveragePower(add_db=-70, fft_size=fft_size, avg_number=fft_averages) - self.fftExchangeSides = FftExchangeSides(fft_size=fft_size) + def __init__(self, samp_rate, fft_size, fft_v_overlap_factor, fft_fps, fft_compression): + self.sampleRate = samp_rate + self.vOverlapFactor = fft_v_overlap_factor + self.fps = fft_fps + self.size = fft_size + + self.blockSize = 0 + self.fftAverages = 0 + + self.fft = Fft(size=self.size, every_n_samples=self.blockSize) + self.logAveragePower = LogAveragePower(add_db=-70, fft_size=self.size, avg_number=self.fftAverages) + self.fftExchangeSides = FftExchangeSides(fft_size=self.size) workers = [ self.fft, self.logAveragePower, @@ -19,14 +26,52 @@ class FftChain(Chain): ] self.compressFftAdpcm = None if fft_compression == "adpcm": - self.compressFftAdpcm = CompressFftAdpcm(fft_size=fft_size) + self.compressFftAdpcm = CompressFftAdpcm(fft_size=self.size) workers += [self.compressFftAdpcm] + + self._updateParameters() + super().__init__(*workers) - def setFftAverages(self, fft_averages): - logger.debug("setting fft_averages={0}".format(fft_averages)) - self.logAveragePower.setFftAverages(avg_number=fft_averages) + def _setFftAverages(self, fft_averages): + if self.fftAverages == fft_averages: + return + self.fftAverages = fft_averages + self.logAveragePower.setFftAverages(avg_number=self.fftAverages) - def setFftBlockSize(self, fft_block_size): - logger.debug("setting fft_block_size={0}".format(fft_block_size)) - self.fft.setEveryNSamples(int(fft_block_size)) + def _setBlockSize(self, fft_block_size): + if self.blockSize == int(fft_block_size): + return + self.blockSize = int(fft_block_size) + self.fft.setEveryNSamples(self.blockSize) + + def setVOverlapFactor(self, fft_v_overlap_factor): + if self.vOverlapFactor == fft_v_overlap_factor: + return + self.vOverlapFactor = fft_v_overlap_factor + self._updateParameters() + + def setFps(self, fft_fps): + if self.fps == fft_fps: + return + self.fps = fft_fps + self._updateParameters() + + def setSampleRate(self, samp_rate): + if self.sampleRate == samp_rate: + return + self.sampleRate = samp_rate + self._updateParameters() + + def _updateParameters(self): + if self.vOverlapFactor > 0: + self._setFftAverages( + int(round(1.0 * self.sampleRate / self.size / self.fps / (1.0 - self.vOverlapFactor))) + ) + else: + self._setFftAverages(0) + + if self.fftAverages == 0: + self._setBlockSize(self.sampleRate / self.fps) + else: + self._setBlockSize(self.sampleRate / self.fps / self.fftAverages) diff --git a/csdr/csdr.py b/csdr/csdr.py index 32d1418..ebd81b9 100644 --- a/csdr/csdr.py +++ b/csdr/csdr.py @@ -113,7 +113,6 @@ class dsp(object): self.secondary_process_fft = None self.secondary_process_demod = None self.fft_voverlap_factor = 0 - self.fft_block_size = 0 self.pipe_names = { "bpf_pipe": Pipe.WRITE, "shift_pipe": Pipe.WRITE, @@ -531,10 +530,11 @@ class dsp(object): return self.samp_rate = samp_rate self.calculate_decimation() - self.update_fft_averages() - self.update_fft_block_size() - if self.running and self.pycsdr_chain is None: - self.restart() + if self.running: + if self.pycsdr_chain is not None: + self.pycsdr_chain.setSampleRate(self.samp_rate) + else: + self.restart() def calculate_decimation(self): (self.decimation, self.last_decimation, _) = self.get_decimation(self.samp_rate, self.get_audio_rate()) @@ -650,52 +650,22 @@ class dsp(object): if self.fft_size == fft_size: return self.fft_size = fft_size - self.update_fft_averages() + # TODO implement setting fft size in chain dynamically self.restart() def set_fft_fps(self, fft_fps): if self.fft_fps == fft_fps: return self.fft_fps = fft_fps - self.update_fft_averages() - self.update_fft_block_size() - self.restart() + if self.pycsdr_chain: + self.pycsdr_chain.setFps(self.fft_fps) def set_fft_voverlap_factor(self, fft_voverlap_factor): if self.fft_voverlap_factor == fft_voverlap_factor: return self.fft_voverlap_factor = fft_voverlap_factor - self.update_fft_averages() - - def update_fft_averages(self): - self.set_fft_averages( - int(round(1.0 * self.samp_rate / self.fft_size / self.fft_fps / (1.0 - self.fft_voverlap_factor))) - if self.fft_voverlap_factor > 0 - else 0 - ) - - def set_fft_averages(self, fft_averages): - if self.fft_averages == fft_averages: - return - self.fft_averages = fft_averages - self.update_fft_block_size() if self.pycsdr_chain: - self.pycsdr_chain.setFftAverages(fft_averages) - else: - self.restart() - - def update_fft_block_size(self): - if self.fft_averages == 0: - self.set_fft_block_size(self.samp_rate / self.fft_fps) - else: - self.set_fft_block_size(self.samp_rate / self.fft_fps / self.fft_averages) - - def set_fft_block_size(self, fft_block_size): - if self.fft_block_size == fft_block_size: - return - self.fft_block_size = fft_block_size - if self.pycsdr_chain: - self.pycsdr_chain.setFftBlockSize(fft_block_size) + self.pycsdr_chain.setVOverlapFactor(self.fft_voverlap_factor) def set_offset_freq(self, offset_freq): if offset_freq is None: @@ -813,9 +783,10 @@ class dsp(object): self.running = True self.pycsdr_chain = FftChain( + samp_rate=self.samp_rate, fft_size=self.fft_size, - fft_block_size=self.fft_block_size, - fft_averages=self.fft_averages, + fft_v_overlap_factor=self.fft_voverlap_factor, + fft_fps=self.fft_fps, fft_compression=self.fft_compression ) @@ -858,7 +829,6 @@ class dsp(object): decimation=self.decimation, last_decimation=self.last_decimation, fft_size=self.fft_size, - fft_block_size=self.fft_block_size, fft_averages=self.fft_averages, bpf_transition_bw=float(self.bpf_transition_bw) / self.if_samp_rate(), ddc_transition_bw=self.ddc_transition_bw(),