#ifndef _TRANSMITTER_HPP_ #define _TRANSMITTER_HPP_ #include #include #include #include #include "JuceHeader.h" #include "LogComponent.h" #include #include #include #include "TransmitterInterface.hpp" #include "TransmitterBuffer.hpp" using namespace Radio; #define TRANSMITTER_RCF_OVERSAMPLING ((uint32_t)32) #define TRANSMITTER_RCF_ROLLOFF ((radio_float_t)0.35) // --------------------------------------------------- class Transmitter : public TransmitterInterface, public ISymbolizer, public juce::Thread { public: Transmitter(void); ~Transmitter(void); void bufferResize(uint32_t size); private: CriticalSection m_lock; Symbolizer m_symbolizer; Formatter m_formatter; sym_map_t m_symbolMapper; Interpolation::UpSampler m_firUp; uint32_t m_bufferSize; RVec m_bufferRF; CVec m_bufferSym; CVec m_bufferSymRcf; radio_float_t m_samplerate; radio_float_t m_ddcFrequency; radio_float_t m_symbolrate; uint32_t m_numBitPerSymbol; radio_float_t *m_pCoeffRCF; radio_float_t m_kRcf; radio_float_t m_carrierFreq; Nco m_duc; TransmitterBuffer m_txBuf; uint32_t m_symCount; uint32_t m_upsampleFactor; // Thread void run() override { uint32_t data; data = 0; while(!threadShouldExit()) { m_formatter.process(&data, sizeof(data)); data++; } } // ISymbolizer void onSymbol(symbol_t symbol) override { uint32_t symCountRcf; const ScopedLock sl (m_lock); m_bufferSym[m_symCount++] = toComplexScalar(SymMapMap(&m_symbolMapper, symbol)); if (m_symCount >= m_bufferSize/m_upsampleFactor) { symCountRcf = m_firUp.process(m_bufferSymRcf, m_bufferSym, m_symCount); m_duc.mixComplexRealV(m_bufferRF, m_bufferSymRcf, ComplexScalar(m_kRcf/4, m_kRcf/4), symCountRcf); m_txBuf.write(m_bufferRF, symCountRcf); m_symCount = 0; } } void paramChanged(); // TransmitterInterface void reset() override { } void setBuffersize(uint32_t size) override { bufferResize(size); paramChanged(); } void setSamplerate(radio_float_t samplerate_hz) override { m_samplerate = samplerate_hz; m_carrierFreq = samplerate_hz/4; m_symbolrate = samplerate_hz/4; paramChanged(); } void setCarrierFrequency(radio_float_t frequency_hz) override { const ScopedLock sl (m_lock); m_carrierFreq = frequency_hz; m_duc.init(m_carrierFreq/m_samplerate, 0); } radio_float_t getCarrierFrequency() override { return m_carrierFreq; } void setSymbolRate(radio_float_t symbolrate_bit_per_sec) override { m_symbolrate = symbolrate_bit_per_sec; paramChanged(); } radio_float_t getSymbolRate() override { return m_symbolrate; } void setNumBitPerSymbol(uint32_t numBitPerSymbol) override { m_numBitPerSymbol = numBitPerSymbol; if (m_numBitPerSymbol > 16) m_numBitPerSymbol = 16; paramChanged(); } void getData(float *pRF, uint32_t len) override { uint32_t res; if (len != m_bufferSize) { memset(pRF, 0, len*sizeof(float)); return; } res = m_txBuf.read(pRF); if (!res) memset(pRF, 0, len*sizeof(float)); } }; #endif // _TRANSMITTER_HPP_