diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt index 32191b24f..d29478331 100644 --- a/sdrbase/CMakeLists.txt +++ b/sdrbase/CMakeLists.txt @@ -3,6 +3,7 @@ project (sdrbase) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined") set(sdrbase_SOURCES + audio/audiocompressor.cpp audio/audiodevicemanager.cpp audio/audiofifo.cpp audio/audiooutput.cpp @@ -90,6 +91,7 @@ set(sdrbase_SOURCES ) set(sdrbase_HEADERS + audio/audiocompressor.h audio/audiodevicemanager.h audio/audiofifo.h audio/audiooutput.h diff --git a/sdrbase/audio/audiocompressor.cpp b/sdrbase/audio/audiocompressor.cpp new file mode 100644 index 000000000..fd25257f7 --- /dev/null +++ b/sdrbase/audio/audiocompressor.cpp @@ -0,0 +1,87 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 F4EXB // +// written by Edouard Griffiths // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "audiocompressor.h" + +AudioCompressor::AudioCompressor() +{ + fillLUT2(); +} + +AudioCompressor::~AudioCompressor() +{} + +void AudioCompressor::fillLUT() +{ + for (int i=0; i<8192; i++) { + m_lut[i] = (24576/8192)*i; + } + + for (int i=8192; i<2*8192; i++) { + m_lut[i] = 24576 + 0.5f*(i-8192); + } + + for (int i=2*8192; i<3*8192; i++) { + m_lut[i] = 24576 + 4096 + 0.25f*(i-2*8192); + } + + for (int i=3*8192; i<4*8192; i++) { + m_lut[i] = 24576 + 4096 + 2048 + 0.125f*(i-3*8192); + } +} + +void AudioCompressor::fillLUT2() +{ + for (int i=0; i<4096; i++) { + m_lut[i] = (24576/4096)*i; + } + + for (int i=4096; i<2*4096; i++) { + m_lut[i] = 24576 + 0.5f*(i-4096); + } + + for (int i=2*4096; i<3*4096; i++) { + m_lut[i] = 24576 + 2048 + 0.25f*(i-2*4096); + } + + for (int i=3*4096; i<4*4096; i++) { + m_lut[i] = 24576 + 2048 + 1024 + 0.125f*(i-3*4096); + } + + for (int i=4*4096; i<5*4096; i++) { + m_lut[i] = 24576 + 2048 + 1024 + 512 + 0.0625f*(i-4*4096); + } + + for (int i=5*4096; i<6*4096; i++) { + m_lut[i] = 24576 + 2048 + 1024 + 512 + 256 + 0.03125f*(i-5*4096); + } + + for (int i=6*4096; i<7*4096; i++) { + m_lut[i] = 24576 + 2048 + 1024 + 512 + 256 + 128 + 0.015625f*(i-6*4096); + } + + for (int i=7*4096; i<8*4096; i++) { + m_lut[i] = 24576 + 2048 + 1024 + 512 + 256 + 128 + 64 + 0.0078125f*(i-7*4096); + } +} + +int16_t AudioCompressor::compress(int16_t sample) +{ + int16_t sign = sample < 0 ? -1 : 1; + int16_t abs = sample < 0 ? -sample : sample; + return sign * m_lut[abs]; +} diff --git a/sdrbase/audio/audiocompressor.h b/sdrbase/audio/audiocompressor.h new file mode 100644 index 000000000..7f7ba0edd --- /dev/null +++ b/sdrbase/audio/audiocompressor.h @@ -0,0 +1,39 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 F4EXB // +// written by Edouard Griffiths // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRBASE_AUDIO_AUDIOCOMPRESSOR_H_ +#define SDRBASE_AUDIO_AUDIOCOMPRESSOR_H_ + +#include +#include "export.h" + +class SDRBASE_API AudioCompressor +{ +public: + AudioCompressor(); + ~AudioCompressor(); + void fillLUT(); //!< 4 bands + void fillLUT2(); //!< 8 bands (default) + int16_t compress(int16_t sample); + +private: + int16_t m_lut[32768]; +}; + + + +#endif /* SDRBASE_AUDIO_AUDIOCOMPRESSOR_H_ */ diff --git a/sdrbase/dsp/dvserialworker.cpp b/sdrbase/dsp/dvserialworker.cpp index 7600c3cce..99603c942 100644 --- a/sdrbase/dsp/dvserialworker.cpp +++ b/sdrbase/dsp/dvserialworker.cpp @@ -159,7 +159,7 @@ void DVSerialWorker::upsample(int upsampling, short *in, int nbSamplesIn, unsign { for (int i = 0; i < nbSamplesIn; i++) { - float cur = m_upsampleFilter.usesHP() ? m_upsampleFilter.runHP((float) in[i]) : (float) in[i]; + float cur = m_upsampleFilter.usesHP() ? m_upsampleFilter.runHP((float) m_compressor.compress(in[i])) : (float) m_compressor.compress(in[i]); float prev = m_upsamplerLastValue; qint16 upsample; diff --git a/sdrbase/dsp/dvserialworker.h b/sdrbase/dsp/dvserialworker.h index e1ea1a347..e395a5850 100644 --- a/sdrbase/dsp/dvserialworker.h +++ b/sdrbase/dsp/dvserialworker.h @@ -32,6 +32,7 @@ #include "export.h" #include "dsp/filtermbe.h" #include "dsp/dsptypes.h" +#include "audio/audiocompressor.h" class AudioFifo; @@ -153,6 +154,7 @@ private: int m_upsampling; float m_volume; float m_upsamplingFactors[7]; + AudioCompressor m_compressor; }; #endif /* SDRBASE_DSP_DVSERIALWORKER_H_ */