Reusable C++ DSP code library
  • C++ 99.7%
  • Makefile 0.3%
Find a file
2023-04-17 10:36:04 +02:00
tests use -O2 with -ffast-math and -ftree-vectorize 2022-04-07 21:42:21 +02:00
.gitignore Initial commit 2018-03-02 14:04:46 +01:00
amd.hh use well known order of lerp arguments 2021-05-07 17:18:06 +02:00
atan2.hh added FMD{1..5}, atan and atan2 approximations 2019-02-06 19:58:00 +01:00
bip_buffer.hh added empty operator 2022-12-02 12:50:20 +01:00
biquad.hh added biquad allpass filter 2019-03-03 11:08:40 +01:00
blockdc.hh added DC blocker 2019-02-24 17:36:11 +01:00
calculus.hh added integrator and differentiator 2019-02-28 21:40:53 +01:00
cdc.hh set history to zero 2020-03-16 17:57:50 +01:00
coeffs.hh be able to normalize at construction 2019-01-20 17:45:26 +01:00
complex.hh added some more operators 2023-04-17 10:36:04 +02:00
const.hh time to embrace #pragma once 2019-01-19 14:07:07 +01:00
cordic.hh added fixed-point CORDIC atan2 2019-02-13 11:04:54 +01:00
decibel.hh use exp10() 2019-02-27 18:56:31 +01:00
delay.hh initialize buffer optionally with provided value 2020-10-13 15:49:58 +02:00
deque.hh removed system includes 2020-10-13 10:47:14 +02:00
ema.hh use well known order of lerp arguments 2021-05-07 17:18:06 +02:00
exp.hh added exponentiation approximations 2019-02-27 18:54:39 +01:00
fdzp.hh made count of input and output samples independent 2020-02-16 22:26:38 +01:00
fft.hh added RealToHalfComplexTransform 2019-04-25 15:14:19 +02:00
filter.hh made methods const 2021-04-01 12:34:11 +02:00
fmd.hh unwrap -> wrap_around 2019-02-08 08:17:32 +01:00
hilbert.hh set history to zero 2020-03-16 17:57:50 +01:00
kahan.hh time to embrace #pragma once 2019-01-19 14:07:07 +01:00
LICENSE Initial commit 2018-03-02 14:04:46 +01:00
lms.hh added least mean squares filter implementations 2020-10-23 11:51:20 +02:00
movext.hh use Delay in MovExt while avoiding code duplication 2020-10-15 22:30:29 +02:00
netpbm.hh use revised value K0 for SRGB 2021-04-16 17:31:44 +02:00
normalize.hh init lpf to 0.5 2019-02-25 13:28:17 +01:00
pcm.hh added const 2020-04-29 16:01:09 +02:00
pel.hh added reader and writer for Netpbm P5 and P6 files 2020-04-29 14:22:43 +02:00
phasor.hh added reset() 2020-04-30 19:55:52 +02:00
README.md added the repeated median estimator of Siegel 2021-09-10 00:09:26 +02:00
regression.hh made *x and *y args const 2021-09-11 16:34:35 +02:00
repeated_median.hh made *x and *y args const 2021-09-11 16:34:35 +02:00
resampler.hh limit reading from input array to 0 .. samples-1 2021-04-12 11:25:50 +02:00
sma.hh use the std wrappers 2020-10-13 10:26:26 +02:00
spline.hh made *x and *y args const 2021-09-11 16:34:35 +02:00
stack.hh added fixed-size stack implementation 2020-10-13 17:10:59 +02:00
swa.hh initialize buffer with provided neutral element 2020-10-10 23:30:17 +02:00
theil_sen.hh made *x and *y args const 2021-09-11 16:34:35 +02:00
trigger.hh added support to change thresholds independently 2020-04-23 00:27:14 +02:00
unit_circle.hh make it work for negative n too 2019-01-18 22:21:51 +01:00
utils.hh added clamp() 2021-05-07 17:43:17 +02:00
wav.hh relax test for files with garbage at end 2020-11-03 17:18:24 +01:00
window.hh made methods const 2021-04-01 12:34:11 +02:00

This is a work in progress and a long overdue attempt to bring all our DSP code together and make it reusable for our future projects.

Before using any of this you should enter the tests directory and execute "make". This will check if your compiler is able to create binaries that are able to produce correct results when executed.

What we have included so far:

kahan.hh

When working with Floating-point arithmetic we soon realize, that addition is not necessarily associative. For example, whenever we need to add values with an ever decreasing magnitude to a running sum with an ever increasing magnitude, the Kahan summation algorithm comes in handy and helps keeping the error growth small.

window.hh

Implemented are the follwing Window functions:

filter.hh

Implemented are the following finite impulse response filters:

ema.hh

The exponential moving average is an infinite impulse response low-pass filter. There is also support for cascading, to improve roll-off while a correction factor helps to keep the same cutoff frequency.

biquad.hh

The following infinite impulse response digital biquad filter implementations are available:

blockdc.hh

A notch filter at DC helps removing DC bias.

normalize.hh

Normalizers for periodic signals.

phasor.hh

Numerically controlled oscillator implemented using a phasor and complex multiplication instead of a lookup table.

cdc.hh

Fs/4 Complex down conversion

hilbert.hh

Discrete Hilbert transform

fmd.hh

Frequency modulation demodulation with and without atan2.

amd.hh

Amplitude modulation demodulation with automatic gain control.

atan2.hh

atan and atan2.

exp.hh

Exponentiation approximations.

cordic.hh

When working on a device where multiplication is expensive, the CORDIC comes in handy for computing trigonometric functions.

The following implementations are a good (max 1 LSB error at full range) starting point for your own designs:

trigger.hh

Implemented are the following trigger functions:

sma.hh

The simple moving average gives us the mean of the last N data points.

  • SMA1 computes the sum of its internal history buffer at each new input from scratch is and therefore very slow.
  • SMA2 updates its internal sum using only the new input and the oldest value in the history buffer. It is therefore the fastest of all and works perfect with integers but suffers from drift when used with floats on sequences having a high dynamic range.
  • SMA3 is based on SMA2 but uses the Kahan summation algorithm to reduce drift significantly.
  • SMA4 uses a tree and only updates nodes that depend on the new input value and is slower than SMA3 but it has no drift.

swa.hh

The sliding window accelerator uses a tree and only updates nodes that depend on the new input value for the pairwise reduction.

movext.hh

Amortized O(1) moving extrema implementations of:

  • Moving Minimum
  • Moving Maximum

bip_buffer.hh

The Bip buffer provides contiguous block access to the last N value stored in a circular buffer.

Example:

DSP::BipBuffer<TYPE, NUM> history;
*snip*
const TYPE *buf = history(new_value);
*snip*
TYPE newest_value = buf[NUM-1];
TYPE previous_value = buf[NUM-2];
TYPE oldest_value = buf[0];
*snip*
DSP::FastFourierTransform<NUM, TYPE, -1> fwd;
TYPE out[NUM];
fwd(out, history(another_value));

delay.hh

A Digital delay line can be used to align signals with different delays - after filtering, for example.

deque.hh

A ring buffer based, fixed-size double-ended queue.

stack.hh

A fixed-size stack with access to the first element.

calculus.hh

Some calculus functions:

const.hh

Some constants we need

pcm.hh

Interface for reading and writing PCM data

wav.hh

Read and write WAV files

pel.hh

Interface for reading and writing pixel data

netpbm.hh

Read and write Netpbm files

spline.hh

regression.hh

Implemented Simple linear regression for Regression analysis of data.

theil_sen.hh

The Theil-Sen estimator is a robust line fitting algorithm.

repeated_median.hh

The repeated median estimator is a robust line fitting algorithm.

complex.hh

Faster alternative (no Inf/NaN handling) to the std::complex implementation.

fft.hh

Mixed-radix decimation-in-time fast Fourier transform

utils.hh

Some everyday helpers:

decibel.hh

Decibel calculation helpers.

resampler.hh

When working with Analog-to-digital and Digital-to-analog converters, we often face the ugly truth, that we can't always have a precise Sampling rate. But if we can estimate the Sampling frequency offset, we can correct it by Resampling the sampled data.

fdzp.hh

Interpolation via frequency-domain zero padding.

unit_circle.hh

Sometimes we only need trigonometric functions that stay on the unit circle:

lms.hh

Some least mean squares filter implementations:

  • Normalized Least Mean Squares
  • Normalized Complex Least Mean Squares