Files
mpsk_rx_gui/Source/Transmitter.h
T
2014-09-24 17:21:29 +00:00

254 lines
5.0 KiB
C++

#ifndef _TRANSMITTER_H_
#define _TRANSMITTER_H_
#include <cstdint>
#include <radio/symbol.h>
#include <radio/nco.h>
#include <radio/interpolation.h>
#include <radio/Frame.hpp>
#include "JuceHeader.h"
#include "LogComponent.h"
#define TRANSMITTER_RCF_OVERSAMPLING ((uint32_t)32)
#define TRANSMITTER_RCF_ROLLOFF ((radio_float_t)0.35)
class Transmitter;
// ---------------------------------------------------
class TransmitterInterface
{
public:
TransmitterInterface() {}
virtual ~TransmitterInterface() {}
virtual void reset() = 0;
virtual void setBuffersize(uint32_t size) = 0;
virtual void setCarrierFrequency(float frequency_hz) = 0;
virtual void setSamplerate(float samplerate_hz) = 0;
virtual void setSymbolRate(float symbolrate_bit_per_sec) = 0;
virtual void setNumBitPerSymbol(uint32_t numBitPerSymbol) = 0;
virtual void getData(float *pRF, uint32_t len) = 0;
};
class TxBuffer
{
public:
TxBuffer(uint32_t size, uint32_t numBuffers)
: m_ppBuffer(0)
, m_capacityPerBuffer(0)
, m_numBuffers(0)
, m_pT(0)
{
resize(size, numBuffers);
}
~TxBuffer()
{
resize(0, 0);
}
void write(float *pData, uint32_t len)
{
uint32_t i;
m_pT = Thread::getCurrentThread();
while (m_numfill.get() >= m_numBuffers)
{
m_pT->wait(100);
if (m_pT->threadShouldExit())
return;
}
for (i=0; i < len; i++)
{
m_ppBuffer[m_w][i] = pData[i];
}
m_w++;
if (m_w >= m_numBuffers)
m_w = 0;
m_numfill += 1;
}
uint32_t read(float *pData)
{
uint32_t i;
if (m_numfill.get() == 0)
return 0;
for (i=0; i < m_capacityPerBuffer; i++)
{
pData[i] = m_ppBuffer[m_r][i];
}
m_r++;
if (m_r >= m_numBuffers)
m_r = 0;
m_numfill -= 1;
if (m_pT)
m_pT->notify();
return i;
}
void resize(uint32_t size, uint32_t numBuffers)
{
uint32_t i;
if ((size != m_capacityPerBuffer) || (numBuffers != m_numBuffers))
{
if (m_ppBuffer)
{
for (i=0; i < m_numBuffers; i++)
{
delete m_ppBuffer[i];
}
delete m_ppBuffer;
m_ppBuffer = nullptr;
}
m_r = 0;
m_w = 0;
m_numfill = 0;
}
m_numBuffers = numBuffers;
m_capacityPerBuffer = size;
if (!size || !numBuffers)
return;
m_ppBuffer = new float*[m_numBuffers];
for (i=0; i < m_numBuffers; i++)
{
m_ppBuffer[i] = new float[m_capacityPerBuffer];
}
}
private:
Atomic<uint32_t> m_numfill;
float **m_ppBuffer;
uint32_t m_capacityPerBuffer;
uint32_t m_numBuffers;
uint32_t m_r;
uint32_t m_w;
Thread *m_pT;
};
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;
fir_cpx_multirate_t m_firUpRcf;
uint32_t m_bufferSize;
float *m_bufferRF;
cpx_t *m_bufferSymRcf;
cpx_t *m_bufferSym;
float m_samplerate;
float m_ddcFrequency;
float m_symbolrate;
uint32_t m_numBitPerSymbol;
radio_float_t *m_CoeffRCF;
radio_float_t m_kRcf;
radio_float_t m_carrierFreq;
nco_t m_duc;
TxBuffer m_txBuf;
uint32_t m_symCount;
// 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++] = SymMapMap(&m_symbolMapper, symbol);
if (m_symCount >= m_bufferSize/m_firUpRcf.L)
{
symCountRcf = FirCpxUpProcess(&m_firUpRcf, m_bufferSym, m_bufferSymRcf, m_symCount);
NCO_MixComplexRealV(&m_duc, m_bufferRF, m_bufferSymRcf, Cpx(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(float samplerate_hz) override
{
m_samplerate = samplerate_hz;
m_carrierFreq = samplerate_hz/4;
m_symbolrate = samplerate_hz/4;
paramChanged();
}
void setCarrierFrequency(float frequency_hz) override
{
const ScopedLock sl (m_lock);
m_carrierFreq = frequency_hz;
NCO_Reinit(&m_duc, m_carrierFreq/m_samplerate, 0);
}
void setSymbolRate(float symbolrate_bit_per_sec) override
{
m_symbolrate = symbolrate_bit_per_sec;
paramChanged();
}
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_H_