diff options
Diffstat (limited to 'src/DabModulator.cpp')
-rw-r--r-- | src/DabModulator.cpp | 170 |
1 files changed, 97 insertions, 73 deletions
diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index 64ebf03..5213d8d 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -59,19 +59,22 @@ using namespace std; DabModulator::DabModulator(EtiSource& etiSource, - mod_settings_t& settings) : + mod_settings_t& settings, + const std::string& format) : ModInput(), RemoteControllable("modulator"), m_settings(settings), - myEtiSource(etiSource), - myFlowgraph() + m_format(format), + m_etiSource(etiSource), + m_flowgraph() { PDEBUG("DabModulator::DabModulator() @ %p\n", this); RC_ADD_PARAMETER(rate, "(Read-only) IQ output samplerate"); + RC_ADD_PARAMETER(num_clipped_samples, "(Read-only) Number of samples clipped in last frame during format conversion"); if (m_settings.dabMode == 0) { - setMode(2); + setMode(1); } else { setMode(m_settings.dabMode); @@ -83,36 +86,36 @@ void DabModulator::setMode(unsigned mode) { switch (mode) { case 1: - myNbSymbols = 76; - myNbCarriers = 1536; - mySpacing = 2048; - myNullSize = 2656; - mySymSize = 2552; - myFicSizeOut = 288; + m_nbSymbols = 76; + m_nbCarriers = 1536; + m_spacing = 2048; + m_nullSize = 2656; + m_symSize = 2552; + m_ficSizeOut = 288; break; case 2: - myNbSymbols = 76; - myNbCarriers = 384; - mySpacing = 512; - myNullSize = 664; - mySymSize = 638; - myFicSizeOut = 288; + m_nbSymbols = 76; + m_nbCarriers = 384; + m_spacing = 512; + m_nullSize = 664; + m_symSize = 638; + m_ficSizeOut = 288; break; case 3: - myNbSymbols = 153; - myNbCarriers = 192; - mySpacing = 256; - myNullSize = 345; - mySymSize = 319; - myFicSizeOut = 384; + m_nbSymbols = 153; + m_nbCarriers = 192; + m_spacing = 256; + m_nullSize = 345; + m_symSize = 319; + m_ficSizeOut = 384; break; case 4: - myNbSymbols = 76; - myNbCarriers = 768; - mySpacing = 1024; - myNullSize = 1328; - mySymSize = 1276; - myFicSizeOut = 288; + m_nbSymbols = 76; + m_nbCarriers = 768; + m_spacing = 1024; + m_nullSize = 1328; + m_symSize = 1276; + m_ficSizeOut = 288; break; default: throw std::runtime_error("DabModulator::setMode invalid mode size"); @@ -126,27 +129,27 @@ int DabModulator::process(Buffer* dataOut) PDEBUG("DabModulator::process(dataOut: %p)\n", dataOut); - if (not myFlowgraph) { + if (not m_flowgraph) { etiLog.level(debug) << "Setting up DabModulator..."; const unsigned mode = m_settings.dabMode; setMode(mode); - myFlowgraph = make_shared<Flowgraph>(m_settings.showProcessTime); + m_flowgraph = make_shared<Flowgraph>(m_settings.showProcessTime); //////////////////////////////////////////////////////////////// // CIF data initialisation //////////////////////////////////////////////////////////////// auto cifPrbs = make_shared<PrbsGenerator>(864 * 8, 0x110); - auto cifMux = make_shared<FrameMultiplexer>(myEtiSource); + auto cifMux = make_shared<FrameMultiplexer>(m_etiSource); auto cifPart = make_shared<BlockPartitioner>(mode); - auto cifMap = make_shared<QpskSymbolMapper>(myNbCarriers); + auto cifMap = make_shared<QpskSymbolMapper>(m_nbCarriers); auto cifRef = make_shared<PhaseReference>(mode); auto cifFreq = make_shared<FrequencyInterleaver>(mode); - auto cifDiff = make_shared<DifferentialModulator>(myNbCarriers); + auto cifDiff = make_shared<DifferentialModulator>(m_nbCarriers); - auto cifNull = make_shared<NullSymbol>(myNbCarriers); + auto cifNull = make_shared<NullSymbol>(m_nbCarriers); auto cifSig = make_shared<SignalMultiplexer>( - (1 + myNbSymbols) * myNbCarriers * sizeof(complexf)); + (1 + m_nbSymbols) * m_nbCarriers * sizeof(complexf)); // TODO this needs a review bool useCicEq = false; @@ -167,8 +170,8 @@ int DabModulator::process(Buffer* dataOut) shared_ptr<CicEqualizer> cifCicEq; if (useCicEq) { cifCicEq = make_shared<CicEqualizer>( - myNbCarriers, - (float)mySpacing * (float)m_settings.outputRate / 2048000.0f, + m_nbCarriers, + (float)m_spacing * (float)m_settings.outputRate / 2048000.0f, cic_ratio); } @@ -186,9 +189,9 @@ int DabModulator::process(Buffer* dataOut) } auto cifOfdm = make_shared<OfdmGenerator>( - (1 + myNbSymbols), - myNbCarriers, - mySpacing, + (1 + m_nbSymbols), + m_nbCarriers, + m_spacing, m_settings.enableCfr, m_settings.cfrClip, m_settings.cfrErrorClip); @@ -196,7 +199,7 @@ int DabModulator::process(Buffer* dataOut) rcs.enrol(cifOfdm.get()); auto cifGain = make_shared<GainControl>( - mySpacing, + m_spacing, m_settings.gainMode, m_settings.digitalgain, m_settings.normalise, @@ -205,7 +208,7 @@ int DabModulator::process(Buffer* dataOut) rcs.enrol(cifGain.get()); auto cifGuard = make_shared<GuardIntervalInserter>( - myNbSymbols, mySpacing, myNullSize, mySymSize, + m_nbSymbols, m_spacing, m_nullSize, m_symSize, m_settings.ofdmWindowOverlap); rcs.enrol(cifGuard.get()); @@ -227,17 +230,21 @@ int DabModulator::process(Buffer* dataOut) cifRes = make_shared<Resampler>( 2048000, m_settings.outputRate, - mySpacing); + m_spacing); } - myOutput = make_shared<OutputMemory>(dataOut); + if (not m_format.empty()) { + m_formatConverter = make_shared<FormatConverter>(m_format); + } + + m_output = make_shared<OutputMemory>(dataOut); - myFlowgraph->connect(cifPrbs, cifMux); + m_flowgraph->connect(cifPrbs, cifMux); //////////////////////////////////////////////////////////////// // Processing FIC //////////////////////////////////////////////////////////////// - shared_ptr<FicSource> fic(myEtiSource.getFic()); + shared_ptr<FicSource> fic(m_etiSource.getFic()); //////////////////////////////////////////////////////////////// // Data initialisation //////////////////////////////////////////////////////////////// @@ -269,15 +276,15 @@ int DabModulator::process(Buffer* dataOut) PDEBUG(" Adding tail\n"); ficPunc->append_tail_rule(PuncturingRule(3, 0xcccccc)); - myFlowgraph->connect(fic, ficPrbs); - myFlowgraph->connect(ficPrbs, ficConv); - myFlowgraph->connect(ficConv, ficPunc); - myFlowgraph->connect(ficPunc, cifPart); + m_flowgraph->connect(fic, ficPrbs); + m_flowgraph->connect(ficPrbs, ficConv); + m_flowgraph->connect(ficConv, ficPunc); + m_flowgraph->connect(ficPunc, cifPart); //////////////////////////////////////////////////////////////// // Configuring subchannels //////////////////////////////////////////////////////////////// - for (const auto& subchannel : myEtiSource.getSubchannels()) { + for (const auto& subchannel : m_etiSource.getSubchannels()) { //////////////////////////////////////////////////////////// // Data initialisation @@ -329,23 +336,23 @@ int DabModulator::process(Buffer* dataOut) // Configuring time interleaver auto subchInterleaver = make_shared<TimeInterleaver>(subchSizeOut); - myFlowgraph->connect(subchannel, subchPrbs); - myFlowgraph->connect(subchPrbs, subchConv); - myFlowgraph->connect(subchConv, subchPunc); - myFlowgraph->connect(subchPunc, subchInterleaver); - myFlowgraph->connect(subchInterleaver, cifMux); + m_flowgraph->connect(subchannel, subchPrbs); + m_flowgraph->connect(subchPrbs, subchConv); + m_flowgraph->connect(subchConv, subchPunc); + m_flowgraph->connect(subchPunc, subchInterleaver); + m_flowgraph->connect(subchInterleaver, cifMux); } - myFlowgraph->connect(cifMux, cifPart); - myFlowgraph->connect(cifPart, cifMap); - myFlowgraph->connect(cifMap, cifFreq); - myFlowgraph->connect(cifRef, cifDiff); - myFlowgraph->connect(cifFreq, cifDiff); - myFlowgraph->connect(cifNull, cifSig); - myFlowgraph->connect(cifDiff, cifSig); + m_flowgraph->connect(cifMux, cifPart); + m_flowgraph->connect(cifPart, cifMap); + m_flowgraph->connect(cifMap, cifFreq); + m_flowgraph->connect(cifRef, cifDiff); + m_flowgraph->connect(cifFreq, cifDiff); + m_flowgraph->connect(cifNull, cifSig); + m_flowgraph->connect(cifDiff, cifSig); if (tii) { - myFlowgraph->connect(tiiRef, tii); - myFlowgraph->connect(tii, cifSig); + m_flowgraph->connect(tiiRef, tii); + m_flowgraph->connect(tii, cifSig); } shared_ptr<ModPlugin> prev_plugin = static_pointer_cast<ModPlugin>(cifSig); @@ -354,15 +361,18 @@ int DabModulator::process(Buffer* dataOut) static_pointer_cast<ModPlugin>(cifOfdm), static_pointer_cast<ModPlugin>(cifGain), static_pointer_cast<ModPlugin>(cifGuard), - static_pointer_cast<ModPlugin>(cifFilter), // optional block - static_pointer_cast<ModPlugin>(cifRes), // optional block - static_pointer_cast<ModPlugin>(cifPoly), // optional block - static_pointer_cast<ModPlugin>(myOutput), + // optional blocks + static_pointer_cast<ModPlugin>(cifFilter), + static_pointer_cast<ModPlugin>(cifRes), + static_pointer_cast<ModPlugin>(cifPoly), + static_pointer_cast<ModPlugin>(m_formatConverter), + // mandatory block + static_pointer_cast<ModPlugin>(m_output), }); for (auto& p : plugins) { if (p) { - myFlowgraph->connect(prev_plugin, p); + m_flowgraph->connect(prev_plugin, p); prev_plugin = p; } } @@ -372,13 +382,13 @@ int DabModulator::process(Buffer* dataOut) //////////////////////////////////////////////////////////////////// // Processing data //////////////////////////////////////////////////////////////////// - return myFlowgraph->run(); + return m_flowgraph->run(); } meta_vec_t DabModulator::process_metadata(const meta_vec_t& metadataIn) { - if (myOutput) { - return myOutput->get_latest_metadata(); + if (m_output) { + return m_output->get_latest_metadata(); } return {}; @@ -390,6 +400,9 @@ void DabModulator::set_parameter(const string& parameter, const string& value) if (parameter == "rate") { throw ParameterError("Parameter 'rate' is read-only"); } + else if (parameter == "num_clipped_samples") { + throw ParameterError("Parameter 'num_clipped_samples' is read-only"); + } else { stringstream ss; ss << "Parameter '" << parameter << @@ -404,6 +417,16 @@ const string DabModulator::get_parameter(const string& parameter) const if (parameter == "rate") { ss << m_settings.outputRate; } + else if (parameter == "num_clipped_samples") { + if (m_formatConverter) { + ss << m_formatConverter->get_num_clipped_samples(); + } + else { + ss << "Parameter '" << parameter << + "' is not available when no format conversion is done."; + throw ParameterError(ss.str()); + } + } else { ss << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); @@ -416,5 +439,6 @@ const RemoteControllable::map_t DabModulator::get_all_values() const { map_t map; map["rate"] = m_settings.outputRate; + map["num_clipped_samples"] = m_formatConverter ? m_formatConverter->get_num_clipped_samples() : 0; return map; } |