diff options
| author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2024-10-29 23:52:22 +0100 | 
|---|---|---|
| committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2024-10-29 23:52:22 +0100 | 
| commit | f1a3db6d7dc1461bcf4a8933a77267698fdffd30 (patch) | |
| tree | b20e5054899335f340e26b9220c85691eeb70087 /src | |
| parent | 933021ed44e6c1bd2cf1dee91fc033c145c061af (diff) | |
| download | dabmod-f1a3db6d7dc1461bcf4a8933a77267698fdffd30.tar.gz dabmod-f1a3db6d7dc1461bcf4a8933a77267698fdffd30.tar.bz2 dabmod-f1a3db6d7dc1461bcf4a8933a77267698fdffd30.zip  | |
Rework fixed point config setting
Diffstat (limited to 'src')
| -rw-r--r-- | src/Buffer.h | 1 | ||||
| -rw-r--r-- | src/ConfigParser.cpp | 24 | ||||
| -rw-r--r-- | src/ConfigParser.h | 8 | ||||
| -rw-r--r-- | src/DabMod.cpp | 18 | ||||
| -rw-r--r-- | src/DabModulator.cpp | 96 | ||||
| -rw-r--r-- | src/FormatConverter.cpp | 142 | ||||
| -rw-r--r-- | src/FormatConverter.h | 9 | ||||
| -rw-r--r-- | src/GuardIntervalInserter.cpp | 23 | ||||
| -rw-r--r-- | src/GuardIntervalInserter.h | 5 | ||||
| -rw-r--r-- | src/OfdmGenerator.cpp | 24 | 
10 files changed, 213 insertions, 137 deletions
diff --git a/src/Buffer.h b/src/Buffer.h index f6c94e0..bf3b5f4 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -40,6 +40,7 @@ typedef std::complex<float> complexf;  using fixed_16 = fpm::fixed<std::int16_t, std::int32_t, 6>;  typedef std::complex<fixed_16> complexfix; +typedef std::complex<fpm::fixed_16_16> complexfix_wide;  /* Buffer is a container for a byte array, which is memory-aligned   * to 32 bytes for SSE performance. diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index a48f7e7..5d9f6f3 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -65,6 +65,27 @@ static GainMode parse_gainmode(const std::string &gainMode_setting)      throw std::runtime_error("Configuration error");  } +static FFTEngine parse_fft_engine(const std::string &fft_engine_setting) +{ +    string fft_engine_minuscule(fft_engine_setting); +    std::transform(fft_engine_minuscule.begin(), fft_engine_minuscule.end(), +            fft_engine_minuscule.begin(), ::tolower); + +    if (fft_engine_minuscule == "fftw") { +        return FFTEngine::FFTW; +    } +    else if (fft_engine_minuscule == "kiss") { +        return FFTEngine::KISS; +    } +    else if (fft_engine_minuscule == "dexter") { +        return FFTEngine::DEXTER; +    } + +    cerr << "Modulator fft_engine setting '" << fft_engine_setting << +        "' not recognised." << endl; +    throw std::runtime_error("Configuration error"); +} +  static void parse_configfile(          const std::string& configuration_file,          mod_settings_t& mod_settings) @@ -154,7 +175,8 @@ static void parse_configfile(              mod_settings.showProcessTime);      // modulator parameters: -    mod_settings.fixedPoint = pt.GetInteger("modulator.fixed_point", mod_settings.fixedPoint); +    const string fft_engine_setting = pt.Get("modulator.fft_engine", "fftw"); +    mod_settings.fftEngine = parse_fft_engine(fft_engine_setting);      const string gainMode_setting = pt.Get("modulator.gainmode", "var");      mod_settings.gainMode = parse_gainmode(gainMode_setting); diff --git a/src/ConfigParser.h b/src/ConfigParser.h index f3a2af9..3bacfdd 100644 --- a/src/ConfigParser.h +++ b/src/ConfigParser.h @@ -36,6 +36,12 @@  #include "TII.h"  #include "output/SDRDevice.h" +enum class FFTEngine { +    FFTW, // floating point in software +    KISS, // fixed-point in software +    DEXTER // fixed-point in FPGA +}; +  struct mod_settings_t {      std::string startupCheck; @@ -51,7 +57,7 @@ struct mod_settings_t {      bool useLimeOutput = false;      bool useBladeRFOutput = false; -    bool fixedPoint = false; +    FFTEngine fftEngine = FFTEngine::FFTW;      size_t outputRate = 2048000;      size_t clockRate = 0; diff --git a/src/DabMod.cpp b/src/DabMod.cpp index 4726df9..361e0d4 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -252,7 +252,7 @@ static shared_ptr<ModOutput> prepare_output(mod_settings_t& s)      shared_ptr<ModOutput> output;      if (s.useFileOutput) { -        if (s.fixedPoint) { +        if (s.fftEngine != FFTEngine::FFTW) {              // Intentionally ignore fileOutputFormat, it is always sc16              output = make_shared<OutputFile>(s.outputName, s.fileOutputShowMetadata);          } @@ -292,7 +292,7 @@ static shared_ptr<ModOutput> prepare_output(mod_settings_t& s)      else if (s.useUHDOutput) {          s.normalise = 1.0f / normalise_factor;          s.sdr_device_config.sampleRate = s.outputRate; -        s.sdr_device_config.fixedPoint = s.fixedPoint; +        s.sdr_device_config.fixedPoint = (s.fftEngine != FFTEngine::FFTW);          auto uhddevice = make_shared<Output::UHD>(s.sdr_device_config);          output = make_shared<Output::SDR>(s.sdr_device_config, uhddevice);          rcs.enrol((Output::SDR*)output.get()); @@ -303,7 +303,7 @@ static shared_ptr<ModOutput> prepare_output(mod_settings_t& s)          /* We normalise the same way as for the UHD output */          s.normalise = 1.0f / normalise_factor;          s.sdr_device_config.sampleRate = s.outputRate; -        if (s.fixedPoint) throw runtime_error("soapy fixed_point unsupported"); +        if (s.fftEngine != FFTEngine::FFTW) throw runtime_error("soapy fixed_point unsupported");          auto soapydevice = make_shared<Output::Soapy>(s.sdr_device_config);          output = make_shared<Output::SDR>(s.sdr_device_config, soapydevice);          rcs.enrol((Output::SDR*)output.get()); @@ -323,7 +323,7 @@ static shared_ptr<ModOutput> prepare_output(mod_settings_t& s)      else if (s.useLimeOutput) {          /* We normalise the same way as for the UHD output */          s.normalise = 1.0f / normalise_factor; -        if (s.fixedPoint) throw runtime_error("limesdr fixed_point unsupported"); +        if (s.fftEngine != FFTEngine::FFTW) throw runtime_error("limesdr fixed_point unsupported");          s.sdr_device_config.sampleRate = s.outputRate;          auto limedevice = make_shared<Output::Lime>(s.sdr_device_config);          output = make_shared<Output::SDR>(s.sdr_device_config, limedevice); @@ -334,7 +334,7 @@ static shared_ptr<ModOutput> prepare_output(mod_settings_t& s)      else if (s.useBladeRFOutput) {          /* We normalise specifically for the BladeRF output : range [-2048; 2047] */          s.normalise = 2047.0f / normalise_factor; -        if (s.fixedPoint) throw runtime_error("bladerf fixed_point unsupported"); +        if (s.fftEngine != FFTEngine::FFTW) throw runtime_error("bladerf fixed_point unsupported");          s.sdr_device_config.sampleRate = s.outputRate;          auto bladerfdevice = make_shared<Output::BladeRF>(s.sdr_device_config);          output = make_shared<Output::SDR>(s.sdr_device_config, bladerfdevice); @@ -424,7 +424,7 @@ int launch_modulator(int argc, char* argv[])      rcs.enrol(&m);      // Neither KISS FFT used for fixedpoint nor the FFT Accelerator used for DEXTER need planning. -    if (not (mod_settings.fixedPoint or mod_settings.useDexterOutput)) { +    if (mod_settings.fftEngine == FFTEngine::FFTW) {          // This is mostly useful on ARM systems where FFTW planning takes some time. If we do it here          // it will be done before the modulator starts up          etiLog.level(debug) << "Running FFTW planning..."; @@ -446,9 +446,13 @@ int launch_modulator(int argc, char* argv[])      }      std::string output_format; -    if (mod_settings.fixedPoint) { +    if (mod_settings.fftEngine == FFTEngine::KISS) {          output_format = ""; //fixed point is native sc16, no converter needed      } +    else if (mod_settings.fftEngine == FFTEngine::DEXTER) { +        output_format = "s16"; // FPGA FFT Engine outputs s32 +    } +    // else FFTW, i.e. floating point      else if (mod_settings.useFileOutput and              (mod_settings.fileOutputFormat == "s8" or               mod_settings.fileOutputFormat == "u8" or diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index 5f01725..4cbd0f5 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -142,13 +142,14 @@ 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, m_settings.fixedPoint); -        auto cifRef = make_shared<PhaseReference>(mode, m_settings.fixedPoint); -        auto cifFreq = make_shared<FrequencyInterleaver>(mode, m_settings.fixedPoint); -        auto cifDiff = make_shared<DifferentialModulator>(m_nbCarriers, m_settings.fixedPoint); +        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, -                m_settings.fixedPoint ? sizeof(complexfix) : sizeof(complexf)); +                fixedPoint ? sizeof(complexfix) : sizeof(complexf));          auto cifSig = make_shared<SignalMultiplexer>();          // TODO this needs a review @@ -178,7 +179,7 @@ int DabModulator::process(Buffer* dataOut)          shared_ptr<TII> tii;          shared_ptr<PhaseReference> tiiRef;          try { -            if (m_settings.fixedPoint) { +            if (fixedPoint) {                  etiLog.level(warn) << "TII does not yet support fixed point";              }              else { @@ -186,7 +187,7 @@ int DabModulator::process(Buffer* dataOut)                          m_settings.dabMode,                          m_settings.tiiConfig);                  rcs.enrol(tii.get()); -                tiiRef = make_shared<PhaseReference>(mode, m_settings.fixedPoint); +                tiiRef = make_shared<PhaseReference>(mode, fixedPoint);              }          }          catch (const TIIError& e) { @@ -195,40 +196,43 @@ int DabModulator::process(Buffer* dataOut)          shared_ptr<ModPlugin> cifOfdm; -        if (m_settings.useDexterOutput) { -            cifOfdm = make_shared<OfdmGeneratorDEXTER>( -                    (1 + m_nbSymbols), -                    m_nbCarriers, -                    m_spacing, -                    m_settings.enableCfr, -                    m_settings.cfrClip, -                    m_settings.cfrErrorClip); -        } -        else if (m_settings.fixedPoint) { -            cifOfdm = make_shared<OfdmGeneratorFixed>( -                    (1 + m_nbSymbols), -                    m_nbCarriers, -                    m_spacing, -                    m_settings.enableCfr, -                    m_settings.cfrClip, -                    m_settings.cfrErrorClip); -        } -        else { -            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; +        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, +                        m_settings.enableCfr, +                        m_settings.cfrClip, +                        m_settings.cfrErrorClip); +                break; +            case FFTEngine::DEXTER: +                cifOfdm = make_shared<OfdmGeneratorDEXTER>( +                        (1 + m_nbSymbols), +                        m_nbCarriers, +                        m_spacing, +                        m_settings.enableCfr, +                        m_settings.cfrClip, +                        m_settings.cfrErrorClip); +                break;          }          shared_ptr<GainControl> cifGain; -        if (not m_settings.fixedPoint) { +        if (not fixedPoint) {              cifGain = make_shared<GainControl>(                      m_spacing,                      m_settings.gainMode, @@ -241,12 +245,12 @@ int DabModulator::process(Buffer* dataOut)          auto cifGuard = make_shared<GuardIntervalInserter>(                  m_nbSymbols, m_spacing, m_nullSize, m_symSize, -                m_settings.ofdmWindowOverlap, m_settings.fixedPoint); +                m_settings.ofdmWindowOverlap, m_settings.fftEngine);          rcs.enrol(cifGuard.get());          shared_ptr<FIRFilter> cifFilter;          if (not m_settings.filterTapsFilename.empty()) { -            if (m_settings.fixedPoint) throw std::runtime_error("fixed point doesn't support fir filter"); +            if (fixedPoint) throw std::runtime_error("fixed point doesn't support fir filter");              cifFilter = make_shared<FIRFilter>(m_settings.filterTapsFilename);              rcs.enrol(cifFilter.get()); @@ -254,7 +258,7 @@ int DabModulator::process(Buffer* dataOut)          shared_ptr<MemlessPoly> cifPoly;          if (not m_settings.polyCoefFilename.empty()) { -            if (m_settings.fixedPoint) throw std::runtime_error("fixed point doesn't support predistortion"); +            if (fixedPoint) throw std::runtime_error("fixed point doesn't support predistortion");              cifPoly = make_shared<MemlessPoly>(m_settings.polyCoefFilename,                                                 m_settings.polyNumThreads); @@ -263,7 +267,7 @@ int DabModulator::process(Buffer* dataOut)          shared_ptr<Resampler> cifRes;          if (m_settings.outputRate != 2048000) { -            if (m_settings.fixedPoint) throw std::runtime_error("fixed point doesn't support resampler"); +            if (fixedPoint) throw std::runtime_error("fixed point doesn't support resampler");              cifRes = make_shared<Resampler>(                      2048000, @@ -271,11 +275,13 @@ int DabModulator::process(Buffer* dataOut)                      m_spacing);          } -        if (not m_format.empty()) { -            // This handles both complexf and fixedpoint: -            // Convert from complexfix to interleaved int16_t I/Q -            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); diff --git a/src/FormatConverter.cpp b/src/FormatConverter.cpp index a52f501..1821442 100644 --- a/src/FormatConverter.cpp +++ b/src/FormatConverter.cpp @@ -34,9 +34,10 @@  #include <stdexcept>  #include <assert.h> -FormatConverter::FormatConverter(const std::string& format) : +FormatConverter::FormatConverter(bool input_is_complexfix_wide, const std::string& format_out) :      ModCodec(), -    m_format(format) +    m_input_complexfix_wide(input_is_complexfix_wide), +    m_format_out(format_out)  { }  FormatConverter::~FormatConverter() @@ -55,67 +56,95 @@ int FormatConverter::process(Buffer* const dataIn, Buffer* dataOut)      size_t num_clipped_samples = 0; -    size_t sizeIn = dataIn->getLength() / sizeof(float); -    float* in = reinterpret_cast<float*>(dataIn->getData()); -    if (m_format == "s16") { -        dataOut->setLength(sizeIn * sizeof(int16_t)); -        int16_t* out = reinterpret_cast<int16_t*>(dataOut->getData()); - -        for (size_t i = 0; i < sizeIn; i++) { -            if (in[i] < INT16_MIN) { -                out[i] = INT16_MIN; -                num_clipped_samples++; -            } -            else if (in[i] > INT16_MAX) { -                out[i] = INT16_MAX; -                num_clipped_samples++; -            } -            else { -                out[i] = in[i]; +    if (m_input_complexfix_wide) { +        size_t sizeIn = dataIn->getLength() / sizeof(int32_t); +        int32_t* in = reinterpret_cast<int32_t*>(dataIn->getData()); +        if (m_format_out == "s16") { +            dataOut->setLength(sizeIn * sizeof(int16_t)); +            int16_t* out = reinterpret_cast<int16_t*>(dataOut->getData()); + +            for (size_t i = 0; i < sizeIn; i++) { +                if (in[i] < INT16_MIN) { +                    out[i] = INT16_MIN; +                    num_clipped_samples++; +                } +                else if (in[i] > INT16_MAX) { +                    out[i] = INT16_MAX; +                    num_clipped_samples++; +                } +                else { +                    out[i] = in[i]; +                }              }          } -    } -    else if (m_format == "u8") { -        dataOut->setLength(sizeIn * sizeof(int8_t)); -        uint8_t* out = reinterpret_cast<uint8_t*>(dataOut->getData()); - -        for (size_t i = 0; i < sizeIn; i++) { -            const auto samp = in[i] + 128.0f; -            if (samp < 0) { -                out[i] = 0; -                num_clipped_samples++; -            } -            else if (samp > UINT8_MAX) { -                out[i] = UINT8_MAX; -                num_clipped_samples++; -            } -            else { -                out[i] = samp; -            } - +        else { +            throw std::runtime_error("FormatConverter: Invalid fix format " + m_format_out);          }      } -    else if (m_format == "s8") { -        dataOut->setLength(sizeIn * sizeof(int8_t)); -        int8_t* out = reinterpret_cast<int8_t*>(dataOut->getData()); - -        for (size_t i = 0; i < sizeIn; i++) { -            if (in[i] < INT8_MIN) { -                out[i] = INT8_MIN; -                num_clipped_samples++; +    else { +        size_t sizeIn = dataIn->getLength() / sizeof(float); +        float* in = reinterpret_cast<float*>(dataIn->getData()); + +        if (m_format_out == "s16") { +            dataOut->setLength(sizeIn * sizeof(int16_t)); +            int16_t* out = reinterpret_cast<int16_t*>(dataOut->getData()); + +            for (size_t i = 0; i < sizeIn; i++) { +                if (in[i] < INT16_MIN) { +                    out[i] = INT16_MIN; +                    num_clipped_samples++; +                } +                else if (in[i] > INT16_MAX) { +                    out[i] = INT16_MAX; +                    num_clipped_samples++; +                } +                else { +                    out[i] = in[i]; +                }              } -            else if (in[i] > INT8_MAX) { -                out[i] = INT8_MAX; -                num_clipped_samples++; +        } +        else if (m_format_out == "u8") { +            dataOut->setLength(sizeIn * sizeof(int8_t)); +            uint8_t* out = reinterpret_cast<uint8_t*>(dataOut->getData()); + +            for (size_t i = 0; i < sizeIn; i++) { +                const auto samp = in[i] + 128.0f; +                if (samp < 0) { +                    out[i] = 0; +                    num_clipped_samples++; +                } +                else if (samp > UINT8_MAX) { +                    out[i] = UINT8_MAX; +                    num_clipped_samples++; +                } +                else { +                    out[i] = samp; +                } +              } -            else { -                out[i] = in[i]; +        } +        else if (m_format_out == "s8") { +            dataOut->setLength(sizeIn * sizeof(int8_t)); +            int8_t* out = reinterpret_cast<int8_t*>(dataOut->getData()); + +            for (size_t i = 0; i < sizeIn; i++) { +                if (in[i] < INT8_MIN) { +                    out[i] = INT8_MIN; +                    num_clipped_samples++; +                } +                else if (in[i] > INT8_MAX) { +                    out[i] = INT8_MAX; +                    num_clipped_samples++; +                } +                else { +                    out[i] = in[i]; +                }              }          } -    } -    else { -        throw std::runtime_error("FormatConverter: Invalid format " + m_format); +        else { +            throw std::runtime_error("FormatConverter: Invalid format " + m_format_out); +        }      }      m_num_clipped_samples.store(num_clipped_samples); @@ -136,10 +165,7 @@ size_t FormatConverter::get_num_clipped_samples() const  size_t FormatConverter::get_format_size(const std::string& format)  {      // Returns 2*sizeof(SAMPLE_TYPE) because we have I + Q -    if (format == "fixedpoint") { -        return 4; -    } -    else if (format == "s16") { +    if (format == "s16") {          return 4;      }      else if (format == "u8") { diff --git a/src/FormatConverter.h b/src/FormatConverter.h index 27ca0b1..1ed2283 100644 --- a/src/FormatConverter.h +++ b/src/FormatConverter.h @@ -41,8 +41,10 @@ class FormatConverter : public ModCodec      public:          static size_t get_format_size(const std::string& format); -        // Allowed formats: s8, u8 and s16 -        FormatConverter(const std::string& format); +        // floating-point input allows output formats: s8, u8 and s16 +        // complexfix_wide input allows output formats: s16 +        // complexfix input is already in s16, and needs no converter +        FormatConverter(bool input_is_complexfix_wide, const std::string& format_out);          virtual ~FormatConverter();          int process(Buffer* const dataIn, Buffer* dataOut); @@ -51,7 +53,8 @@ class FormatConverter : public ModCodec          size_t get_num_clipped_samples() const;      private: -        std::string m_format; +        bool m_input_complexfix_wide; +        std::string m_format_out;          std::atomic<size_t> m_num_clipped_samples = 0;  }; diff --git a/src/GuardIntervalInserter.cpp b/src/GuardIntervalInserter.cpp index 4e22367..7061e47 100644 --- a/src/GuardIntervalInserter.cpp +++ b/src/GuardIntervalInserter.cpp @@ -49,10 +49,10 @@ GuardIntervalInserter::GuardIntervalInserter(          size_t nullSize,          size_t symSize,          size_t& windowOverlap, -        bool fixedPoint) : +        FFTEngine fftEngine) :      ModCodec(),      RemoteControllable("guardinterval"), -    m_fixedPoint(fixedPoint), +    m_fftEngine(fftEngine),      m_params(nbSymbols, spacing, nullSize, symSize, windowOverlap)  {      if (nullSize == 0) { @@ -277,15 +277,18 @@ int do_process(const GuardIntervalInserter::Params& p, Buffer* const dataIn, Buf  int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut)  { -    if (m_fixedPoint) { -        if (m_params.windowOverlap) { -            throw std::runtime_error("fixed point and ofdm windowing not supported"); -        } -        return do_process<complexfix>(m_params, dataIn, dataOut); -    } -    else { -        return do_process<complexf>(m_params, dataIn, dataOut); +    switch (m_fftEngine) { +        case FFTEngine::FFTW: +            return do_process<complexf>(m_params, dataIn, dataOut); +        case FFTEngine::KISS: +            if (m_params.windowOverlap) { +                throw std::runtime_error("fixed point and ofdm windowing not supported"); +            } +            return do_process<complexfix>(m_params, dataIn, dataOut); +        case FFTEngine::DEXTER: +            return do_process<complexfix_wide>(m_params, dataIn, dataOut);      } +    throw std::logic_error("Unhandled fftEngine variant");  }  void GuardIntervalInserter::set_parameter( diff --git a/src/GuardIntervalInserter.h b/src/GuardIntervalInserter.h index 380142e..8d329ff 100644 --- a/src/GuardIntervalInserter.h +++ b/src/GuardIntervalInserter.h @@ -30,6 +30,7 @@  #   include <config.h>  #endif +#include "ConfigParser.h"  #include "ModPlugin.h"  #include "RemoteControl.h"  #include <stdint.h> @@ -51,7 +52,7 @@ class GuardIntervalInserter : public ModCodec, public RemoteControllable                  size_t nullSize,                  size_t symSize,                  size_t& windowOverlap, -                bool fixedPoint); +                FFTEngine fftEngine);          virtual ~GuardIntervalInserter() {} @@ -84,7 +85,7 @@ class GuardIntervalInserter : public ModCodec, public RemoteControllable      protected:          void update_window(size_t new_window_overlap); -        bool m_fixedPoint; +        FFTEngine m_fftEngine;          Params m_params; diff --git a/src/OfdmGenerator.cpp b/src/OfdmGenerator.cpp index 4f6eeb9..11f5bf1 100644 --- a/src/OfdmGenerator.cpp +++ b/src/OfdmGenerator.cpp @@ -633,8 +633,8 @@ OfdmGeneratorDEXTER::OfdmGeneratorDEXTER(size_t nbSymbols,      PDEBUG("  myZeroDst: %u\n", myZeroDst);      PDEBUG("  myZeroSize: %u\n", myZeroSize); -    const size_t nbytes = mySpacing * sizeof(complexfix); -    fprintf(stderr, "sizeof(complexfix)=%zu\n", sizeof(complexfix)); +    const size_t nbytes_in = mySpacing * sizeof(complexfix); +    const size_t nbytes_out = mySpacing * 2 * sizeof(int32_t);  #define IIO_ENSURE(expr, err) { \      if (!(expr)) { \ @@ -651,12 +651,12 @@ OfdmGeneratorDEXTER::OfdmGeneratorDEXTER(size_t nbSymbols,      iio_channel_enable(m_channel_in);      iio_channel_enable(m_channel_out); -    m_buf_in = iio_device_create_buffer(m_dev_in, nbytes, false); +    m_buf_in = iio_device_create_buffer(m_dev_in, nbytes_in, false);      if (!m_buf_in) {          throw std::runtime_error("OfdmGeneratorDEXTER could not create in buffer");      } -    m_buf_out = iio_device_create_buffer(m_dev_out, nbytes, false); +    m_buf_out = iio_device_create_buffer(m_dev_out, nbytes_out, false);      if (!m_buf_out) {          throw std::runtime_error("OfdmGeneratorDEXTER could not create out buffer");      } @@ -692,13 +692,13 @@ OfdmGeneratorDEXTER::~OfdmGeneratorDEXTER()  int OfdmGeneratorDEXTER::process(Buffer* const dataIn, Buffer* dataOut)  { -    dataOut->setLength(myNbSymbols * mySpacing * sizeof(complexfix)); +    dataOut->setLength(myNbSymbols * mySpacing * sizeof(complexfix_wide));      complexfix *in = reinterpret_cast<complexfix*>(dataIn->getData()); -    complexfix *out = reinterpret_cast<complexfix*>(dataOut->getData()); +    complexfix_wide *out = reinterpret_cast<complexfix_wide*>(dataOut->getData());      size_t sizeIn = dataIn->getLength() / sizeof(complexfix); -    size_t sizeOut = dataOut->getLength() / sizeof(complexfix); +    size_t sizeOut = dataOut->getLength() / sizeof(complexfix_wide);      if (sizeIn != myNbSymbols * myNbCarriers) {          PDEBUG("Nb symbols: %zu\n", myNbSymbols); @@ -754,15 +754,19 @@ int OfdmGeneratorDEXTER::process(Buffer* const dataIn, Buffer* dataOut)              throw std::runtime_error("OfdmGenerator::process Wrong p_inc");          } +        // The FFT Accelerator takes 16-bit I + 16-bit Q, and outputs 32-bit I and 32-bit Q. +        // The formatconvert will take care of this          const uint8_t *fft_out = (const uint8_t*)iio_buffer_first(m_buf_out, m_channel_out);          const uint8_t *fft_out_end = (const uint8_t*)iio_buffer_end(m_buf_out); -        if ((fft_out_end - fft_out) != (ssize_t)(mySpacing * sizeof(complexfix))) { +        constexpr size_t sizeof_out_iq = sizeof(complexfix_wide); +        if ((fft_out_end - fft_out) != (ssize_t)(mySpacing * sizeof_out_iq)) {              fprintf(stderr, "FFT_OUT: %p %p %zu %zu\n", -                    fft_out, fft_out_end, (fft_out_end - fft_out), mySpacing * sizeof(complexfix)); +                    fft_out, fft_out_end, (fft_out_end - fft_out), +                    mySpacing * sizeof_out_iq);              throw std::runtime_error("OfdmGenerator::process fft_out length invalid!");          } -        memcpy(out, fft_out, mySpacing * sizeof(complexfix)); +        memcpy(out, fft_out, mySpacing * sizeof_out_iq);          in += myNbCarriers;          out += mySpacing;  | 
