diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-04-01 21:11:23 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-04-01 21:11:23 +0200 |
commit | bb089c9f1f08f73cfc3eb97304ab4d6864fa174c (patch) | |
tree | f3b90854a80193c8cd35e805041724beb9a10faf | |
parent | 8ebf45362cc8c2b550753d5f681f885f205b5f9d (diff) | |
download | dabmod-bb089c9f1f08f73cfc3eb97304ab4d6864fa174c.tar.gz dabmod-bb089c9f1f08f73cfc3eb97304ab4d6864fa174c.tar.bz2 dabmod-bb089c9f1f08f73cfc3eb97304ab4d6864fa174c.zip |
Add s16 file output format
-rw-r--r-- | doc/example.ini | 2 | ||||
-rw-r--r-- | src/DabMod.cpp | 9 | ||||
-rw-r--r-- | src/FormatConverter.cpp | 53 | ||||
-rw-r--r-- | src/FormatConverter.h | 6 |
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; }; |