From 042188770b869b18bb2e9138d100ead73f0ee84d Mon Sep 17 00:00:00 2001 From: Geoffrey Merck Date: Sat, 4 Apr 2020 16:16:46 +0200 Subject: [PATCH] Back to block processing, more efficient and does not introduce delay --- ambed/cagc.cpp | 40 +++++++++++-------- ambed/cagc.h | 6 +-- ambed/cfirfilter.cpp | 40 +++++++++++-------- ambed/cfirfilter.h | 6 +-- ambed/cfixedgain.cpp | 13 +++++- ambed/cfixedgain.h | 6 +-- ...pleprocessor.h => csampleblockprocessor.h} | 10 +++-- ambed/csignalprocessor.cpp | 17 +++++--- ambed/csignalprocessor.h | 4 +- 9 files changed, 85 insertions(+), 57 deletions(-) rename ambed/{csampleprocessor.h => csampleblockprocessor.h} (83%) diff --git a/ambed/cagc.cpp b/ambed/cagc.cpp index 23ef6e4..880323d 100644 --- a/ambed/cagc.cpp +++ b/ambed/cagc.cpp @@ -62,27 +62,33 @@ float CAGC::GetGain() //////////////////////////////////////////////////////////////////////////////////////// // process -inline float CAGC::ProcessSample(float input) +inline void CAGC::ProcessSampleBlock(uint8* voice, int length) { - //apply AGC - // apply gain to input sample - float output = input * m_Gain; + for(int i = 0; i < length; i += 2) + { + float input = (float)(short)MAKEWORD(voice[i+1], voice[i]); + //apply AGC + // apply gain to input sample + float output = input * m_Gain; - // compute output signal energy, scaled to 0 to 1 - float instantEnergy = abs(output) / m_targetEnergy; + // compute output signal energy, scaled to 0 to 1 + float instantEnergy = abs(output) / m_targetEnergy; - // smooth energy estimate using single-pole low-pass filter - m_EnergyPrime = (1.0f - m_Alpha) * m_EnergyPrime + m_Alpha * instantEnergy; + // smooth energy estimate using single-pole low-pass filter + m_EnergyPrime = (1.0f - m_Alpha) * m_EnergyPrime + m_Alpha * instantEnergy; - // update gain according to output energy - if (m_EnergyPrime > 1e-6f) - m_Gain *= exp( -0.5f * m_Alpha * log(m_EnergyPrime) ); + // update gain according to output energy + if (m_EnergyPrime > 1e-6f) + m_Gain *= exp( -0.5f * m_Alpha * log(m_EnergyPrime) ); - // clamp gain - if (m_Gain > m_GainMax) - m_Gain = m_GainMax; - else if(m_Gain < m_GainMin) - m_Gain = m_GainMin; + // clamp gain + if (m_Gain > m_GainMax) + m_Gain = m_GainMax; + else if(m_Gain < m_GainMin) + m_Gain = m_GainMin; - return output; + //write processed sample back + voice[i] = HIBYTE((short)output); + voice[i+1] = LOBYTE((short)output); + } } diff --git a/ambed/cagc.h b/ambed/cagc.h index db22b22..f0ebf75 100644 --- a/ambed/cagc.h +++ b/ambed/cagc.h @@ -28,16 +28,16 @@ #ifndef cagc_h #define cagc_h -#include "csampleprocessor.h" +#include "csampleblockprocessor.h" -class CAGC : CSampleProcessor +class CAGC : CSampleBlockProcessor { public: //Constructor CAGC(float initialLeveldB); //methods - float ProcessSample(float input); + void ProcessSampleBlock(uint8* voice, int length) ; float GetGain();//gets current gain private: diff --git a/ambed/cfirfilter.cpp b/ambed/cfirfilter.cpp index c7bd0ca..1b704c2 100644 --- a/ambed/cfirfilter.cpp +++ b/ambed/cfirfilter.cpp @@ -43,27 +43,33 @@ CFIRFilter::~CFIRFilter() delete[] m_buffer; } -inline float CFIRFilter::ProcessSample(float inputSample) +inline void CFIRFilter::ProcessSampleBlock(uint8* voice, int length) { - float output = 0.0f; - int iTaps = 0; - - // Buffer latest sample into delay line - m_buffer[m_currentBufferPosition] = inputSample; - - for(int i = m_currentBufferPosition; i >= 0; i--) + for(int i = 0; i < length; i++) { - output += m_taps[iTaps++] * m_buffer[i]; - } + float input = (float)(short)MAKEWORD(voice[i+1], voice[i]); + float output = 0.0f; + int iTaps = 0; - for(int i = m_tapsLength - 1; i > m_currentBufferPosition; i--) - { - output += m_taps[iTaps++] * m_buffer[i]; - } - - m_currentBufferPosition = (m_currentBufferPosition + 1) % m_tapsLength; + // Buffer latest sample into delay line + m_buffer[m_currentBufferPosition] = input; - return output; + for(int i = m_currentBufferPosition; i >= 0; i--) + { + output += m_taps[iTaps++] * m_buffer[i]; + } + + for(int i = m_tapsLength - 1; i > m_currentBufferPosition; i--) + { + output += m_taps[iTaps++] * m_buffer[i]; + } + + m_currentBufferPosition = (m_currentBufferPosition + 1) % m_tapsLength; + + //write processed sample back + voice[i] = HIBYTE((short)output); + voice[i+1] = LOBYTE((short)output); + } } diff --git a/ambed/cfirfilter.h b/ambed/cfirfilter.h index 52e4b7b..85026fb 100644 --- a/ambed/cfirfilter.h +++ b/ambed/cfirfilter.h @@ -26,9 +26,9 @@ #ifndef cfirfilter_h #define cfirfilter_h -#include "csampleprocessor.h" +#include "csampleblockprocessor.h" -class CFIRFilter : CSampleProcessor +class CFIRFilter : CSampleBlockProcessor { public : //Constructor @@ -38,7 +38,7 @@ public : ~CFIRFilter(); // Processing - float ProcessSample(float inputSample); + void ProcessSampleBlock(uint8* voice, int length); private: float* m_taps; diff --git a/ambed/cfixedgain.cpp b/ambed/cfixedgain.cpp index 4e8645c..55faebc 100644 --- a/ambed/cfixedgain.cpp +++ b/ambed/cfixedgain.cpp @@ -38,7 +38,16 @@ CFixedGain::CFixedGain(float gaindB) //////////////////////////////////////////////////////////////////////////////////////// // processing -inline float CFixedGain::ProcessSample(float input) +inline void CFixedGain::ProcessSampleBlock(uint8* voice, int length) { - return input * m_gainLinear; + for(int i = 0; i < length; i++) + { + float input = (float)(short)MAKEWORD(voice[i+1], voice[i]); + //apply gain + float output = input * m_gainLinear; + + //write processed sample back + voice[i] = HIBYTE((short)output); + voice[i+1] = LOBYTE((short)output); + } } \ No newline at end of file diff --git a/ambed/cfixedgain.h b/ambed/cfixedgain.h index 39a2a3f..eadac47 100644 --- a/ambed/cfixedgain.h +++ b/ambed/cfixedgain.h @@ -26,16 +26,16 @@ #ifndef cfixedgain_h #define cfixedgain_h -#include "csampleprocessor.h" +#include "csampleblockprocessor.h" -class CFixedGain : CSampleProcessor +class CFixedGain : CSampleBlockProcessor { public: //Constructor CFixedGain(float gaindB); //processing - float ProcessSample(float input); + void ProcessSampleBlock(uint8* voice, int length); private: float m_gaindB; //gain in dB diff --git a/ambed/csampleprocessor.h b/ambed/csampleblockprocessor.h similarity index 83% rename from ambed/csampleprocessor.h rename to ambed/csampleblockprocessor.h index c9ec932..2c57f5f 100644 --- a/ambed/csampleprocessor.h +++ b/ambed/csampleblockprocessor.h @@ -23,14 +23,16 @@ // ---------------------------------------------------------------------------- // Geoffrey Merck F4FXL / KC3FRA -#ifndef csampleprocessor_h -#define csampleprocessor_h +#ifndef csamplebloclprocessor_h +#define csamplebloclprocessor_h -class CSampleProcessor +#include "main.h" + +class CSampleBlockProcessor { public: //processing - virtual float ProcessSample(float input) = 0; + virtual void ProcessSampleBlock(uint8* voice, int length) = 0; }; #endif /* csampleprocessor_h */ \ No newline at end of file diff --git a/ambed/csignalprocessor.cpp b/ambed/csignalprocessor.cpp index 3f67687..dbb88c2 100644 --- a/ambed/csignalprocessor.cpp +++ b/ambed/csignalprocessor.cpp @@ -43,12 +43,12 @@ CSignalProcessor::CSignalProcessor(float gaindB) { #if USE_BANDPASSFILTER - m_sampleProcessors.push_back((CSampleProcessor*)new CFIRFilter(FILTER_TAPS, FILTER_TAPS_LENGTH)); + m_sampleProcessors.push_back((CSampleBlockProcessor*)new CFIRFilter(FILTER_TAPS, FILTER_TAPS_LENGTH)); #endif #if USE_AGC == 1 m_sampleProcessors.push_back((CSampleProcessor*)new CAGC(gaindB)); #else - m_sampleProcessors.push_back((CSampleProcessor*)new CFixedGain(gaindB)); + m_sampleProcessors.push_back((CSampleBlockProcessor*)new CFixedGain(gaindB)); #endif } @@ -68,11 +68,16 @@ CSignalProcessor::~CSignalProcessor() void CSignalProcessor::Process(uint8* voice, int length) { - float sample; - int j; + /*float sample; + int j;*/ auto processorsSize = m_sampleProcessors.size(); - for(int i = 0; i < length; i += 2) + for(int j = 0; j < processorsSize; j++) + { + m_sampleProcessors[j]->ProcessSampleBlock(voice, length); + } + + /*for(int i = 0; i < length; i += 2) { //Get the sample sample = (float)(short)MAKEWORD(voice[i+1], voice[i]); @@ -85,5 +90,5 @@ void CSignalProcessor::Process(uint8* voice, int length) //write processed sample back voice[i] = HIBYTE((short)sample); voice[i+1] = LOBYTE((short)sample); - } + }*/ } \ No newline at end of file diff --git a/ambed/csignalprocessor.h b/ambed/csignalprocessor.h index da7cedf..a1081d7 100644 --- a/ambed/csignalprocessor.h +++ b/ambed/csignalprocessor.h @@ -27,7 +27,7 @@ #define csignalprocessor_h #include -#include "csampleprocessor.h" +#include "csampleblockprocessor.h" class CSignalProcessor { @@ -42,7 +42,7 @@ public: void Process(uint8* voice, int length); private: - std::vector m_sampleProcessors; + std::vector m_sampleProcessors; }; #endif /* csignalprocessor_h */ \ No newline at end of file