aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2024-10-29 22:55:41 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2024-10-29 22:55:41 +0100
commit933021ed44e6c1bd2cf1dee91fc033c145c061af (patch)
tree394a40921470502054b678924d060fc5b882fc91 /src
parent004ff5c13515f61728245ccd3d1f281be987b041 (diff)
downloaddabmod-933021ed44e6c1bd2cf1dee91fc033c145c061af.tar.gz
dabmod-933021ed44e6c1bd2cf1dee91fc033c145c061af.tar.bz2
dabmod-933021ed44e6c1bd2cf1dee91fc033c145c061af.zip
Change to 16-bit fixed point
Diffstat (limited to 'src')
-rw-r--r--src/Buffer.h4
-rw-r--r--src/DabMod.cpp3
-rw-r--r--src/DabModulator.cpp15
-rw-r--r--src/FormatConverter.cpp121
-rw-r--r--src/OfdmGenerator.cpp30
-rw-r--r--src/PhaseReference.cpp4
6 files changed, 78 insertions, 99 deletions
diff --git a/src/Buffer.h b/src/Buffer.h
index 711b804..f6c94e0 100644
--- a/src/Buffer.h
+++ b/src/Buffer.h
@@ -37,7 +37,9 @@
#include "fpm/fixed.hpp"
typedef std::complex<float> complexf;
-typedef std::complex<fpm::fixed_16_16> complexfix;
+
+using fixed_16 = fpm::fixed<std::int16_t, std::int32_t, 6>;
+typedef std::complex<fixed_16> complexfix;
/* Buffer is a container for a byte array, which is memory-aligned
* to 32 bytes for SSE performance.
diff --git a/src/DabMod.cpp b/src/DabMod.cpp
index b745271..4726df9 100644
--- a/src/DabMod.cpp
+++ b/src/DabMod.cpp
@@ -313,7 +313,6 @@ static shared_ptr<ModOutput> prepare_output(mod_settings_t& s)
else if (s.useDexterOutput) {
/* We normalise specifically range [-32768; 32767] */
s.normalise = 32767.0f / normalise_factor;
- if (s.fixedPoint) throw runtime_error("dexter fixed_point unsupported");
s.sdr_device_config.sampleRate = s.outputRate;
auto dexterdevice = make_shared<Output::Dexter>(s.sdr_device_config);
output = make_shared<Output::SDR>(s.sdr_device_config, dexterdevice);
@@ -448,7 +447,7 @@ int launch_modulator(int argc, char* argv[])
std::string output_format;
if (mod_settings.fixedPoint) {
- output_format = "fixedpoint";
+ output_format = ""; //fixed point is native sc16, no converter needed
}
else if (mod_settings.useFileOutput and
(mod_settings.fileOutputFormat == "s8" or
diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp
index 757b01f..5f01725 100644
--- a/src/DabModulator.cpp
+++ b/src/DabModulator.cpp
@@ -178,11 +178,16 @@ int DabModulator::process(Buffer* dataOut)
shared_ptr<TII> tii;
shared_ptr<PhaseReference> tiiRef;
try {
- tii = make_shared<TII>(
- m_settings.dabMode,
- m_settings.tiiConfig);
- rcs.enrol(tii.get());
- tiiRef = make_shared<PhaseReference>(mode, m_settings.fixedPoint);
+ if (m_settings.fixedPoint) {
+ etiLog.level(warn) << "TII does not yet support fixed point";
+ }
+ else {
+ tii = make_shared<TII>(
+ m_settings.dabMode,
+ m_settings.tiiConfig);
+ rcs.enrol(tii.get());
+ tiiRef = make_shared<PhaseReference>(mode, m_settings.fixedPoint);
+ }
}
catch (const TIIError& e) {
etiLog.level(error) << "Could not initialise TII: " << e.what();
diff --git a/src/FormatConverter.cpp b/src/FormatConverter.cpp
index 9e59a4a..a52f501 100644
--- a/src/FormatConverter.cpp
+++ b/src/FormatConverter.cpp
@@ -55,99 +55,68 @@ int FormatConverter::process(Buffer* const dataIn, Buffer* dataOut)
size_t num_clipped_samples = 0;
- bool source_is_complexf = m_format != "fixedpoint";
-
- if (source_is_complexf) {
- 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];
- }
- }
- }
- 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;
- }
+ 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 (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 if (in[i] > INT8_MAX) {
- out[i] = INT8_MAX;
- num_clipped_samples++;
- }
- else {
- out[i] = in[i];
- }
+ else if (in[i] > INT16_MAX) {
+ out[i] = INT16_MAX;
+ num_clipped_samples++;
+ }
+ else {
+ out[i] = in[i];
}
}
- else {
- throw std::runtime_error("FormatConverter: Invalid format " + m_format);
- }
-
}
- else {
- // Output is always sc16, because that's what UHD accepts
+ else if (m_format == "u8") {
+ dataOut->setLength(sizeIn * sizeof(int8_t));
+ uint8_t* out = reinterpret_cast<uint8_t*>(dataOut->getData());
- using fixed_t = complexfix::value_type;
- size_t sizeIn = dataIn->getLength() / sizeof(fixed_t);
- fixed_t* in = reinterpret_cast<fixed_t*>(dataIn->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;
+ }
- dataOut->setLength(sizeIn * sizeof(int16_t));
- int16_t* out = reinterpret_cast<int16_t*>(dataOut->getData());
+ }
+ }
+ 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++) {
- const auto v = (in[i] * 2).raw_value();
-
- if (v < INT16_MIN) {
- out[i] = INT16_MIN;
+ if (in[i] < INT8_MIN) {
+ out[i] = INT8_MIN;
num_clipped_samples++;
}
- else if (v > INT16_MAX) {
- out[i] = INT16_MAX;
+ else if (in[i] > INT8_MAX) {
+ out[i] = INT8_MAX;
num_clipped_samples++;
}
else {
- out[i] = (int16_t)v;
+ out[i] = in[i];
}
}
}
+ else {
+ throw std::runtime_error("FormatConverter: Invalid format " + m_format);
+ }
m_num_clipped_samples.store(num_clipped_samples);
return dataOut->getLength();
diff --git a/src/OfdmGenerator.cpp b/src/OfdmGenerator.cpp
index 62a0ee5..4f6eeb9 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 int N = mySpacing; // The size of the FFT
- const size_t nbytes = N * sizeof(complexfix);
+ const size_t nbytes = mySpacing * sizeof(complexfix);
+ fprintf(stderr, "sizeof(complexfix)=%zu\n", sizeof(complexfix));
#define IIO_ENSURE(expr, err) { \
if (!(expr)) { \
@@ -721,17 +721,6 @@ int OfdmGeneratorDEXTER::process(Buffer* const dataIn, Buffer* dataOut)
throw std::runtime_error("OfdmGenerator::process incorrect iio buffer size!");
}
- ptrdiff_t p_inc = iio_buffer_step(m_buf_out);
- if (p_inc != 1) {
- throw std::runtime_error("OfdmGenerator::process Wrong p_inc");
- }
-
- 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))) != 0) {
- throw std::runtime_error("OfdmGenerator::process fft_out length invalid!");
- }
-
complexfix *fft_in = reinterpret_cast<complexfix*>(iio_buffer_start(m_buf_in));
fft_in[0] = static_cast<complexfix::value_type>(0);
@@ -758,6 +747,21 @@ int OfdmGeneratorDEXTER::process(Buffer* const dataIn, Buffer* dataOut)
throw std::runtime_error("OfdmGenerator::process error refilling IIO buffer!");
}
+ fprintf(stderr, "IIO refill %zd\n", nbytes_rx);
+
+ ptrdiff_t p_inc = iio_buffer_step(m_buf_out);
+ if (p_inc != 1) {
+ throw std::runtime_error("OfdmGenerator::process Wrong p_inc");
+ }
+
+ 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))) {
+ fprintf(stderr, "FFT_OUT: %p %p %zu %zu\n",
+ fft_out, fft_out_end, (fft_out_end - fft_out), mySpacing * sizeof(complexfix));
+ throw std::runtime_error("OfdmGenerator::process fft_out length invalid!");
+ }
+
memcpy(out, fft_out, mySpacing * sizeof(complexfix));
in += myNbCarriers;
diff --git a/src/PhaseReference.cpp b/src/PhaseReference.cpp
index d7b89bf..e2fb9a9 100644
--- a/src/PhaseReference.cpp
+++ b/src/PhaseReference.cpp
@@ -137,8 +137,8 @@ complexf PhaseRefGen<complexf>::convert(uint8_t data) {
template <>
complexfix PhaseRefGen<complexfix>::convert(uint8_t data) {
- constexpr auto one = fpm::fixed_16_16{1};
- constexpr auto zero = fpm::fixed_16_16{0};
+ constexpr auto one = fixed_16{1};
+ constexpr auto zero = fixed_16{0};
const complexfix value[] = {
complexfix(one, zero),