diff --git a/Source/Transmitter.cpp b/Source/Transmitter.cpp index 8c5096a..a0b2d7d 100644 --- a/Source/Transmitter.cpp +++ b/Source/Transmitter.cpp @@ -3,8 +3,8 @@ Transmitter::Transmitter(void) : Thread("Transmitter") - , m_symbolizer(this) - , m_formatter(&m_symbolizer) + , m_formatter() + , m_symbolizer() , m_symbolMapper() , m_bufferSize(0) , m_samplerate(192000) @@ -15,13 +15,27 @@ Transmitter::Transmitter(void) , m_symCount(0) , m_pCoeffRCF(0) , m_upsampleFactor(1) + , m_buffer_data_in(BUFFERSIZE_DATA) + , m_buffer_symbol_in(BUFFERSIZE_DATA+64) + , m_buffer_symbol_out(BUFFERSIZE_SYMBOL) { SymMapInit(&m_symbolMapper, m_numBitPerSymbol, MAP_MODE_QAM); m_duc.init(m_carrierFreq/m_samplerate, 0); paramChanged(); + // Setup Buffers bufferResize(2048); + + // Formatter + m_formatter.buffer_in_add(&m_buffer_data_in); + m_formatter.buffer_out_add(&m_buffer_symbol_in); + m_formatter.prepare(); + + // Symbolizer + m_symbolizer.buffer_in_add(&m_buffer_symbol_in); + m_symbolizer.buffer_out_add(&m_buffer_symbol_out); + m_symbolizer.prepare(); } Transmitter::~Transmitter(void) @@ -36,6 +50,49 @@ Transmitter::~Transmitter(void) SymMapFree(&m_symbolMapper); } +// Thread +void Transmitter::run() +{ + uint64_t data = 0; + while(!threadShouldExit()) + { + // Create Data + while(m_buffer_data_in.free()) + { + m_buffer_data_in.write((uint8_t*)&data, sizeof(data)); + data++; + } + + // Format + m_formatter.process(); + + // Symbolize + m_symbolizer.process(); + + // Transmit symbols + transmit(); + } +} + +// Transmit symbols +void Transmitter::transmit() +{ + while(m_buffer_symbol_out.len()) + { + symbol_t symbol; + m_buffer_symbol_out.read(&symbol, 1); + m_bufferSym[m_symCount++] = toComplexScalar(SymMapMap(&m_symbolMapper, symbol)); + + if (m_symCount >= m_bufferSize/m_upsampleFactor) + { + uint32_t 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 Transmitter::paramChanged() { uint32_t n_mf; @@ -49,13 +106,21 @@ void Transmitter::paramChanged() n_mf = (uint32_t)(TRANSMITTER_RCF_OVERSAMPLING*m_upsampleFactor) + 1; if (m_pCoeffRCF) + { delete m_pCoeffRCF; + } m_pCoeffRCF = new radio_float_t[n_mf]; m_kRcf = CalcFirSRRC(m_pCoeffRCF, (radio_float_t)m_samplerate, (radio_float_t)2.0/m_symbolrate, TRANSMITTER_RCF_ROLLOFF, n_mf); m_firUp.init(m_upsampleFactor, m_pCoeffRCF, n_mf); m_duc.init(m_carrierFreq/m_samplerate, 0); + + symbol_t sync_syms[4]; // 4 Corners + sync_syms[0] = SymMapDemap(&m_symbolMapper, toCpx(ComplexScalar(+1,+1))); + sync_syms[1] = SymMapDemap(&m_symbolMapper, toCpx(ComplexScalar(-1,+1))); + sync_syms[2] = SymMapDemap(&m_symbolMapper, toCpx(ComplexScalar(-1,-1))); + sync_syms[3] = SymMapDemap(&m_symbolMapper, toCpx(ComplexScalar(+1,-1))); } void Transmitter::bufferResize(uint32_t size) @@ -73,3 +138,70 @@ void Transmitter::bufferResize(uint32_t size) startThread(0); } + +void Transmitter::reset() +{ +} + +void Transmitter::setBuffersize(uint32_t size) +{ + bufferResize(size); + paramChanged(); +} + +void Transmitter::setSamplerate(radio_float_t samplerate_hz) +{ + m_samplerate = samplerate_hz; + m_carrierFreq = samplerate_hz/4; + m_symbolrate = samplerate_hz/4; + paramChanged(); +} + +void Transmitter::setCarrierFrequency(radio_float_t frequency_hz) +{ + const ScopedLock sl (m_lock); + m_carrierFreq = frequency_hz; + m_duc.init(m_carrierFreq/m_samplerate, 0); +} + +radio_float_t Transmitter::getCarrierFrequency() +{ + return m_carrierFreq; +} + +void Transmitter::setSymbolRate(radio_float_t symbolrate_bit_per_sec) +{ + m_symbolrate = symbolrate_bit_per_sec; + paramChanged(); +} + +radio_float_t Transmitter::getSymbolRate() +{ + return m_symbolrate; +} + +void Transmitter::setNumBitPerSymbol(uint32_t numBitPerSymbol) +{ + m_numBitPerSymbol = numBitPerSymbol; + if (m_numBitPerSymbol > 16) + m_numBitPerSymbol = 16; + + paramChanged(); +} + +void Transmitter::getData(float *pRF, uint32_t len) +{ + 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)); + +} diff --git a/Source/Transmitter.hpp b/Source/Transmitter.hpp index 8e28e7f..f85d02c 100644 --- a/Source/Transmitter.hpp +++ b/Source/Transmitter.hpp @@ -23,8 +23,11 @@ using namespace Radio; // --------------------------------------------------- -class Transmitter : public TransmitterInterface, public ISymbolizer, public juce::Thread +class Transmitter : public TransmitterInterface, public juce::Thread { + const size_t BUFFERSIZE_DATA = 256; + const size_t BUFFERSIZE_SYMBOL = 8*256; + public: Transmitter(void); ~Transmitter(void); @@ -33,8 +36,8 @@ public: private: CriticalSection m_lock; - Symbolizer m_symbolizer; Formatter m_formatter; + Symbolizer m_symbolizer; sym_map_t m_symbolMapper; Interpolation::UpSampler m_firUp; uint32_t m_bufferSize; @@ -54,101 +57,29 @@ private: uint32_t m_symCount; uint32_t m_upsampleFactor; + // Processor Buffers + Processor::Buffer m_buffer_data_in; + Processor::Buffer m_buffer_symbol_in; + Processor::Buffer m_buffer_symbol_out; + // Thread - void run() override - { - uint32_t data; + void run() override; - 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; - } - } + // Transmit symbols + void transmit(); 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)); - - } + void reset() override; + void setBuffersize(uint32_t size) override; + void setSamplerate(radio_float_t samplerate_hz) override; + void setCarrierFrequency(radio_float_t frequency_hz) override; + radio_float_t getCarrierFrequency() override; + void setSymbolRate(radio_float_t symbolrate_bit_per_sec) override; + radio_float_t getSymbolRate() override; + void setNumBitPerSymbol(uint32_t numBitPerSymbol) override; + void getData(float *pRF, uint32_t len) override; }; #endif // _TRANSMITTER_HPP_