diff --git a/meson.build b/meson.build
index 1437e59a..b29506bc 100644
--- a/meson.build
+++ b/meson.build
@@ -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',
diff --git a/openrtx/include/dsp.h b/openrtx/include/dsp.h
new file mode 100644
index 00000000..f822239b
--- /dev/null
+++ b/openrtx/include/dsp.h
@@ -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 *
+ ***************************************************************************/
+
+#ifndef DSP_H
+#define DSP_H
+
+#include
+#include
+
+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
+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
+void dsp_applyFIR(audio_sample_t *buffer,
+ uint16_t length,
+ std::array taps);
+
+#endif // __cplusplus
+
+#endif /* DSP_H */
diff --git a/openrtx/src/dsp.cpp b/openrtx/src/dsp.cpp
new file mode 100644
index 00000000..4dc04d69
--- /dev/null
+++ b/openrtx/src/dsp.cpp
@@ -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 *
+ ***************************************************************************/
+
+#include
+
+/*
+ * Applies a generic FIR filter on the audio buffer passed as parameter.
+ * The buffer will be processed in place to save memory.
+ */
+template
+void dsp_applyFIR(audio_sample_t *buffer,
+ uint16_t length,
+ std::array 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 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;
+ }
+}