Add DSP code with DC removal and FIR PWM filter compensation

Add generic FIR implementation, specialized to compensate the PWM filter
applied by STM32 targets when modulating M17 signal.
Add DC bias compensation to normalize audio signal received from STM32
ADC.

TG-85 #ready-for-test
TG-199 #ready-for-test
replace/f3130117fcd4e5ca8759661064087c3891c887d6
Niccolò Izzo 2021-04-16 09:41:08 +02:00
rodzic a850f9f1ab
commit e3a128f035
3 zmienionych plików z 146 dodań i 0 usunięć

Wyświetl plik

@ -25,6 +25,7 @@ openrtx_src = ['openrtx/src/state.c',
'openrtx/src/queue.c',
'openrtx/src/rtx.c',
'openrtx/src/gps.c',
'openrtx/src/dsp.cpp',
'openrtx/src/memory_profiling.cpp']
openrtx_inc = ['openrtx/include',

Wyświetl plik

@ -0,0 +1,75 @@
/***************************************************************************
* Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, *
* Niccolò Izzo IU2KIN, *
* Silvano Seva IU2KWO, *
* Frederik Saraci IU2NRO *
* *
* 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; either version 3 of the License, or *
* (at your option) any later version. *
* *
* 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 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef DSP_H
#define DSP_H
#include <inttypes.h>
#include <stdlib.h>
typedef int16_t audio_sample_t;
/*
* This header contains various DSP utilities which can be used to condition
* input or output signals when implementing digital modes on OpenRTX.
*/
#ifdef __cplusplus
#include <array>
extern "C" {
#endif
/*
* Compensate for the filtering applied by the PWM output over the modulated
* signal. The buffer will be processed in place to save memory.
*
* @param buffer: the buffer to be used as both source and destination.
* @param length: the length of the input buffer.
*/
void dsp_pwmCompensate(audio_sample_t *buffer, uint16_t length);
/*
* Remove any DC bias from the audio buffer passed as parameter.
* The buffer will be processed in place to save memory.
*
* @param buffer: the buffer to be used as both source and destination.
* @param length: the length of the input buffer.
*/
void dsp_dcRemoval(audio_sample_t *buffer, uint16_t length);
#ifdef __cplusplus
}
/*
* Applies a generic FIR filter on the audio buffer passed as parameter.
* The buffer will be processed in place to save memory.
*
* @param buffer: the buffer to be used as both source and destination.
* @param length: the length of the input buffer.
* @param taps: an array of coefficients which defines the transfer function.
*/
template<size_t order>
void dsp_applyFIR(audio_sample_t *buffer,
uint16_t length,
std::array<float, order> taps);
#endif // __cplusplus
#endif /* DSP_H */

Wyświetl plik

@ -0,0 +1,70 @@
/***************************************************************************
* Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, *
* Niccolò Izzo IU2KIN, *
* Silvano Seva IU2KWO, *
* Frederik Saraci IU2NRO *
* *
* 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; either version 3 of the License, or *
* (at your option) any later version. *
* *
* 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 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include <dsp.h>
/*
* Applies a generic FIR filter on the audio buffer passed as parameter.
* The buffer will be processed in place to save memory.
*/
template<size_t order>
void dsp_applyFIR(audio_sample_t *buffer,
uint16_t length,
std::array<float, order> taps)
{
for(int i = length - 1; i >= 0; i--) {
float acc = 0.0f;
for(uint16_t j = 0; j < order; j++) {
if (i >= j)
acc += buffer[i - j] * taps[j];
}
buffer[i] = (audio_sample_t) acc;
}
}
/*
* Compensate for the filtering applied by the PWM output over the modulated
* signal. The buffer will be processed in place to save memory.
*/
void dsp_pwmCompensate(audio_sample_t *buffer, uint16_t length)
{
// FIR filter designed by Wojciech SP5WWP
std::array<float, 5> taps = { 0.01f, -0.05f, 0.88, -0.05f, 0.01f };
dsp_applyFIR(buffer, length, taps);
}
/*
* Remove any DC bias from the audio buffer passed as parameter.
* The buffer will be processed in place to save memory.
*/
void dsp_dcRemoval(audio_sample_t *buffer, uint16_t length)
{
// Compute the average of all the samples
float acc = 0.0f;
for (int i = 0; i < length; i++) {
acc += buffer[i];
}
float mean = acc / (float) length;
// Subtract it to all the samples
for (int i = 0; i < length; i++) {
buffer[i] -= mean;
}
}