aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2018-04-01 21:11:23 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2018-04-01 21:11:23 +0200
commitbb089c9f1f08f73cfc3eb97304ab4d6864fa174c (patch)
treef3b90854a80193c8cd35e805041724beb9a10faf
parent8ebf45362cc8c2b550753d5f681f885f205b5f9d (diff)
downloaddabmod-bb089c9f1f08f73cfc3eb97304ab4d6864fa174c.tar.gz
dabmod-bb089c9f1f08f73cfc3eb97304ab4d6864fa174c.tar.bz2
dabmod-bb089c9f1f08f73cfc3eb97304ab4d6864fa174c.zip
Add s16 file output format
-rw-r--r--doc/example.ini2
-rw-r--r--src/DabMod.cpp9
-rw-r--r--src/FormatConverter.cpp53
-rw-r--r--src/FormatConverter.h6
4 files changed, 25 insertions, 45 deletions
diff --git a/doc/example.ini b/doc/example.ini
index 624f29a..4f8115e 100644
--- a/doc/example.ini
+++ b/doc/example.ini
@@ -174,6 +174,8 @@ output=uhd
;
; The format u8 is the same as s8, except that the values are mapped
; between 0 and 255.
+;
+; Also supported is s16, with system endianness (little endian on x86_64 and ARM)
;format=s8
; The output file:
diff --git a/src/DabMod.cpp b/src/DabMod.cpp
index 1266147..f384e78 100644
--- a/src/DabMod.cpp
+++ b/src/DabMod.cpp
@@ -187,6 +187,12 @@ static shared_ptr<ModOutput> prepare_output(
s.normalise = 1.0f / normalise_factor_file_var;
output = make_shared<OutputFile>(s.outputName, s.fileOutputShowMetadata);
}
+ else if (s.fileOutputFormat == "s16") {
+ // We must normalise the samples to the interval [-32767.0; 32767.0]
+ s.normalise = 32767.0f / normalise_factor;
+
+ output = make_shared<OutputFile>(s.outputName, s.fileOutputShowMetadata);
+ }
else if (s.fileOutputFormat == "s8" or
s.fileOutputFormat == "u8") {
// We must normalise the samples to the interval [-127.0; 127.0]
@@ -278,7 +284,8 @@ int launch_modulator(int argc, char* argv[])
shared_ptr<FormatConverter> format_converter;
if (mod_settings.useFileOutput and
(mod_settings.fileOutputFormat == "s8" or
- mod_settings.fileOutputFormat == "u8")) {
+ mod_settings.fileOutputFormat == "u8" or
+ mod_settings.fileOutputFormat == "s16")) {
format_converter = make_shared<FormatConverter>(mod_settings.fileOutputFormat);
}
diff --git a/src/FormatConverter.cpp b/src/FormatConverter.cpp
index 60c0545..dcfbcf3 100644
--- a/src/FormatConverter.cpp
+++ b/src/FormatConverter.cpp
@@ -40,55 +40,28 @@
FormatConverter::FormatConverter(const std::string& format) :
ModCodec(),
- m_offset_by_127(format == "u8")
+ m_format(format)
{ }
-/* Expect the input samples to be in the range [-255.0, 255.0] */
+/* Expect the input samples to be in the correct range for the required format */
int FormatConverter::process(Buffer* const dataIn, Buffer* dataOut)
{
PDEBUG("FormatConverter::process(dataIn: %p, dataOut: %p)\n",
dataIn, dataOut);
size_t sizeIn = dataIn->getLength() / sizeof(float);
- dataOut->setLength(sizeIn * sizeof(int8_t));
-
float* in = reinterpret_cast<float*>(dataIn->getData());
-#if 0
-#error "TODO: SSE FormatConvert does not support u8 yet"
-
- // Disabled because subscripting a __m64 doesn't seem to work
- // on all platforms.
-
- /*
- _mm_cvtps_pi8 does:
- |<----------- 128 bits ------------>|
- __m128 | I1 | Q1 | I2 | Q2 | in float
- __m64 |I1Q1I2Q2|00000000| in int8_t
- */
-
- uint32_t* out = reinterpret_cast<uint32_t*>(dataOut->getData());
-
- assert(sizeIn % 16 == 0);
- assert((uintptr_t)in % 16 == 0);
- for(size_t i = 0, j = 0; i < sizeIn; i+=16, j+=4)
- {
- __m128 a1 = _mm_load_ps(in+i+0);
- __m128 a2 = _mm_load_ps(in+i+4);
- __m128 a3 = _mm_load_ps(in+i+8);
- __m128 a4 = _mm_load_ps(in+i+12);
- __m64 b1 = _mm_cvtps_pi8(a1);
- __m64 b2 = _mm_cvtps_pi8(a2);
- __m64 b3 = _mm_cvtps_pi8(a3);
- __m64 b4 = _mm_cvtps_pi8(a4);
- out[j+0] = b1[0];
- out[j+1] = b2[0];
- out[j+2] = b3[0];
- out[j+3] = b4[0];
+ if (m_format == "s16") {
+ dataOut->setLength(sizeIn * sizeof(int16_t));
+ uint16_t* out = reinterpret_cast<uint16_t*>(dataOut->getData());
+
+ for (size_t i = 0; i < sizeIn; i++) {
+ out[i] = in[i];
+ }
}
-#else
- // Slow implementation that uses _ftol()
- if (m_offset_by_127) {
+ 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++) {
@@ -96,15 +69,15 @@ int FormatConverter::process(Buffer* const dataIn, Buffer* dataOut)
}
}
else {
+ dataOut->setLength(sizeIn * sizeof(int8_t));
int8_t* out = reinterpret_cast<int8_t*>(dataOut->getData());
for (size_t i = 0; i < sizeIn; i++) {
out[i] = in[i];
}
}
-#endif
- return 1;
+ return dataOut->getLength();
}
const char* FormatConverter::name()
diff --git a/src/FormatConverter.h b/src/FormatConverter.h
index 4370314..cc8a606 100644
--- a/src/FormatConverter.h
+++ b/src/FormatConverter.h
@@ -35,9 +35,7 @@
#include "ModPlugin.h"
#include <complex>
#include <string>
-#include <stdint.h>
-
-typedef std::complex<float> complexf;
+#include <cstdint>
class FormatConverter : public ModCodec
{
@@ -48,7 +46,7 @@ class FormatConverter : public ModCodec
const char* name();
private:
- bool m_offset_by_127 = false;
+ std::string m_format;
};