#pragma once #include "../dsp/buffer/frame_buffer.h" #include "../dsp/buffer/reshaper.h" #include "../dsp/multirate/power_decimator.h" #include "../dsp/correction/dc_blocker.h" #include "../dsp/chain.h" #include "../dsp/routing/splitter.h" #include "../dsp/channel/rx_vfo.h" #include "../dsp/sink/handler_sink.h" #include "../dsp/math/conjugate.h" #include class IQFrontEnd { public: ~IQFrontEnd(); enum FFTWindow { RECTANGULAR, BLACKMAN, NUTTALL }; void init(dsp::stream* in, double sampleRate, bool buffering, int decimRatio, bool dcBlocking, int fftSize, double fftRate, FFTWindow fftWindow, float* (*acquireFFTBuffer)(void* ctx), void (*releaseFFTBuffer)(void* ctx), void* fftCtx); void setInput(dsp::stream* in); void setSampleRate(double sampleRate); inline double getSampleRate() { return _sampleRate / _decimRatio; } void setBuffering(bool enabled); void setDecimation(int ratio); void setInvertIQ(bool enabled); void setDCBlocking(bool enabled); void bindIQStream(dsp::stream* stream); void unbindIQStream(dsp::stream* stream); dsp::channel::RxVFO* addVFO(std::string name, double sampleRate, double bandwidth, double offset); void removeVFO(std::string name); void setFFTSize(int size); void setFFTRate(double rate); void setFFTWindow(FFTWindow fftWindow); void flushInputBuffer(); void start(); void stop(); double getEffectiveSamplerate(); protected: static void handler(dsp::complex_t* data, int count, void* ctx); void updateFFTPath(bool updateWaterfall = false); static inline double genDCBlockRate(double sampleRate) { return 50.0 / sampleRate; } static inline void genReshapeParams(double sampleRate, int size, double rate, int& skip, int& nzSampCount) { int fftInterval = round(sampleRate / rate); nzSampCount = std::min(fftInterval, size); skip = fftInterval - nzSampCount; } // Input buffer dsp::buffer::SampleFrameBuffer inBuf; // Pre-processing chain dsp::multirate::PowerDecimator decim; dsp::math::Conjugate conjugate; dsp::correction::DCBlocker dcBlock; dsp::chain preproc; // Splitting dsp::routing::Splitter split; // FFT dsp::stream fftIn; dsp::buffer::Reshaper reshape; dsp::sink::Handler fftSink; // VFOs std::map*> vfoStreams; std::map vfos; // Parameters double _sampleRate; double _decimRatio; int _fftSize; double _fftRate; FFTWindow _fftWindow; float* (*_acquireFFTBuffer)(void* ctx); void (*_releaseFFTBuffer)(void* ctx); void* _fftCtx; // Processing data int _nzFFTSize; float* fftWindowBuf; fftwf_complex *fftInBuf, *fftOutBuf; fftwf_plan fftwPlan; float* fftDbOut; double effectiveSr; bool _init = false; };