diff options
Diffstat (limited to 'src/DabModulator.cpp')
-rw-r--r-- | src/DabModulator.cpp | 97 |
1 files changed, 68 insertions, 29 deletions
diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index 4a29132..5f7aaf6 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -3,7 +3,7 @@ Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2023 + Copyright (C) 2024 Matthias P. Braendli, matthias.braendli@mpb.li http://opendigitalradio.org @@ -54,7 +54,6 @@ #include "SignalMultiplexer.h" #include "TII.h" #include "TimeInterleaver.h" -#include "TimestampDecoder.h" using namespace std; @@ -142,14 +141,15 @@ int DabModulator::process(Buffer* dataOut) auto cifMux = make_shared<FrameMultiplexer>(m_etiSource); auto cifPart = make_shared<BlockPartitioner>(mode); - auto cifMap = make_shared<QpskSymbolMapper>(m_nbCarriers); - auto cifRef = make_shared<PhaseReference>(mode); - auto cifFreq = make_shared<FrequencyInterleaver>(mode); - auto cifDiff = make_shared<DifferentialModulator>(m_nbCarriers); + const bool fixedPoint = m_settings.fftEngine != FFTEngine::FFTW; + auto cifMap = make_shared<QpskSymbolMapper>(m_nbCarriers, fixedPoint); + auto cifRef = make_shared<PhaseReference>(mode, fixedPoint); + auto cifFreq = make_shared<FrequencyInterleaver>(mode, fixedPoint); + auto cifDiff = make_shared<DifferentialModulator>(m_nbCarriers, fixedPoint); - auto cifNull = make_shared<NullSymbol>(m_nbCarriers); - auto cifSig = make_shared<SignalMultiplexer>( - (1 + m_nbSymbols) * m_nbCarriers * sizeof(complexf)); + auto cifNull = make_shared<NullSymbol>(m_nbCarriers, + fixedPoint ? sizeof(complexfix) : sizeof(complexf)); + auto cifSig = make_shared<SignalMultiplexer>(); // TODO this needs a review bool useCicEq = false; @@ -180,46 +180,79 @@ int DabModulator::process(Buffer* dataOut) try { tii = make_shared<TII>( m_settings.dabMode, - m_settings.tiiConfig); + m_settings.tiiConfig, + fixedPoint); rcs.enrol(tii.get()); - tiiRef = make_shared<PhaseReference>(mode); + tiiRef = make_shared<PhaseReference>(mode, fixedPoint); } catch (const TIIError& e) { etiLog.level(error) << "Could not initialise TII: " << e.what(); } - auto cifOfdm = make_shared<OfdmGenerator>( - (1 + m_nbSymbols), - m_nbCarriers, - m_spacing, - m_settings.enableCfr, - m_settings.cfrClip, - m_settings.cfrErrorClip); + shared_ptr<ModPlugin> cifOfdm; + + switch (m_settings.fftEngine) { + case FFTEngine::FFTW: + { + auto ofdm = make_shared<OfdmGeneratorCF32>( + (1 + m_nbSymbols), + m_nbCarriers, + m_spacing, + m_settings.enableCfr, + m_settings.cfrClip, + m_settings.cfrErrorClip); + rcs.enrol(ofdm.get()); + cifOfdm = ofdm; + } + break; + case FFTEngine::KISS: + cifOfdm = make_shared<OfdmGeneratorFixed>( + (1 + m_nbSymbols), + m_nbCarriers, + m_spacing); + break; + case FFTEngine::DEXTER: +#if defined(HAVE_DEXTER) + cifOfdm = make_shared<OfdmGeneratorDEXTER>( + (1 + m_nbSymbols), + m_nbCarriers, + m_spacing); +#else + throw std::runtime_error("Cannot use DEXTER fft engine without --enable-dexter"); +#endif + break; + } - rcs.enrol(cifOfdm.get()); + shared_ptr<GainControl> cifGain; - auto cifGain = make_shared<GainControl>( - m_spacing, - m_settings.gainMode, - m_settings.digitalgain, - m_settings.normalise, - m_settings.gainmodeVariance); + if (not fixedPoint) { + cifGain = make_shared<GainControl>( + m_spacing, + m_settings.gainMode, + m_settings.digitalgain, + m_settings.normalise, + m_settings.gainmodeVariance); - rcs.enrol(cifGain.get()); + rcs.enrol(cifGain.get()); + } auto cifGuard = make_shared<GuardIntervalInserter>( m_nbSymbols, m_spacing, m_nullSize, m_symSize, - m_settings.ofdmWindowOverlap); + m_settings.ofdmWindowOverlap, m_settings.fftEngine); rcs.enrol(cifGuard.get()); shared_ptr<FIRFilter> cifFilter; if (not m_settings.filterTapsFilename.empty()) { + if (fixedPoint) throw std::runtime_error("fixed point doesn't support fir filter"); + cifFilter = make_shared<FIRFilter>(m_settings.filterTapsFilename); rcs.enrol(cifFilter.get()); } shared_ptr<MemlessPoly> cifPoly; if (not m_settings.polyCoefFilename.empty()) { + if (fixedPoint) throw std::runtime_error("fixed point doesn't support predistortion"); + cifPoly = make_shared<MemlessPoly>(m_settings.polyCoefFilename, m_settings.polyNumThreads); rcs.enrol(cifPoly.get()); @@ -227,15 +260,21 @@ int DabModulator::process(Buffer* dataOut) shared_ptr<Resampler> cifRes; if (m_settings.outputRate != 2048000) { + if (fixedPoint) throw std::runtime_error("fixed point doesn't support resampler"); + cifRes = make_shared<Resampler>( 2048000, m_settings.outputRate, m_spacing); } - if (not m_format.empty()) { - m_formatConverter = make_shared<FormatConverter>(m_format); + if (m_settings.fftEngine == FFTEngine::FFTW and not m_format.empty()) { + m_formatConverter = make_shared<FormatConverter>(false, m_format); + } + else if (m_settings.fftEngine == FFTEngine::DEXTER) { + m_formatConverter = make_shared<FormatConverter>(true, m_format); } + // KISS is already in s16 m_output = make_shared<OutputMemory>(dataOut); |