Algorithms for sound filters, like reverb, dynamic range compression, lowpass, highpass, notch, etc

Overview

sndfilter

Algorithms for sound filters, like reverb, dynamic range compression, lowpass, highpass, notch, etc.

It's easy to find countless math equations on sound filters, but a bit harder to find simple source code. This library is my attempt at cleaning up and presenting the math-heavy filter algorithms for the programming community.

Please note that I favored simple code over fast code. Hopefully it's made it more understandable.

(MIT License)

Build Instructions

The ./build script is a simple bash script that compiles the source files using clang. It's dirt simple, I promise.

Simply run ./build and the executable should be ./tgt/sndfilter.

C++ Support

This project is pure C, but I've left PRs open for those who want C++ support. Check them out, they might save you some time:

Filters

Implementation

The reverb.c, compressor.c, and biquad.c are the core algorithms.

I do not understand the biquad math, so please don't ask me any questions :-). The core formulas were extracted from Biquad.cpp (Chromium source), and cleaned up a bit to make easier to read.

The compressor came from DynamicsCompressorKernel.cpp (also from Chromium), and cleaned up a bit more. I swapped out the adaptive release curve and simplified the knee calculations. I feel a little more comfortable with that algorithm because there isn't a whole lot of magical math involved.

The reverb effect is a complete rewrite of Freeverb3's Progenitor2 algorithm. It took quite a lot of effort to tear apart the algorithm and rebuild it, but I'm pretty sure it's right.

Issues
  • Possible bug in down sample function in reverb?

    Possible bug in down sample function in reverb?

    The function oversample_stepdown appears to put the samples through the recovery low pass filter but always returns the first input value. I think it should look more like this:

    // input length must be oversample->factor
    static float oversample_stepdown(sf_rv_oversample_st *oversample, float *input)
    {
        if (oversample->factor == 1)
        {
            return input[0];
        }
        else
        {
            int i;
            float   accum = 0.0f;
            for (i = 0; i < oversample->factor; i++)
            {
                accum += biquad_step(&oversample->lpfD, input[i]);
            }
            accum /= (float)oversample->factor;
            return accum;
        }
    }
    
    opened by SwarmSysUser 5
  • Low pass filter infinite alpha

    Low pass filter infinite alpha

    In the biquad_makeLPF function in reverb.c:

    static inline void biquad_makeLPF(sf_rv_biquad_st *biquad, int rate, float freq, float bw){
      freq = clampf(freq, 0, rate / 2);
      float omega = 2.0f * (float)M_PI * freq / (float)rate;
      float cs = cosf(omega);
      float sn = sinf(omega);
      float alpha = sn * sinhf((float)M_LN2 * 0.5f * bw * omega / sn);
      float a0inv = 1.0f / (1.0f + alpha);
      biquad->b0 = a0inv * (1.0f - cs) * 0.5f;
      biquad->b1 = 2.0f * biquad->b0;
      biquad->b2 = biquad->b0;
      biquad->a1 = a0inv * -2.0f * cs;
      biquad->a2 = a0inv * (1.0f - alpha);
      biquad->xn1 = 0;
      biquad->xn2 = 0;
      biquad->yn1 = 0;
      biquad->yn2 = 0;
    }
    

    If rate is integral multiple of freq, then omega will be integral multiple of PI, and sn = sinf(M_PI) is 0, sn is used as a divisor for calculating alpha, the result of alpha will be INFINITY, which causes any other values to be NaN when calculated with alpha.

    Can I test the value of alpha with isinf(), if it is true, assign a valid value to it? But what is the valid value range of alpha? Or what is the valid value for it if it is INFINITY?

    opened by neevek 5
  • Reverb performance issue

    Reverb performance issue

    Hi, first of all Thank you so much for your amazing works. I tried using your reverb and it works well and sounds very good. But it seems like it is pretty heavy in terms of CPU usage. I wonder if you have any suggestion to reduce it's CPU usage other than reducing the channel to mono. Thanks!

    question 
    opened by cuinjune 5
  • using a compressor on streaming audio

    using a compressor on streaming audio

    Hiya - I'm wondering how to go about using the compressor in a context of streaming since it's using a chunk size of 32 and so always return <= the input buffer.

    opened by weepy 4
  • meson build system support

    meson build system support

    Hi @velipso First of all, many thanks for this library!

    I started from also wanting this to be used by c++, but then also added support for the meson build system. Other changes are moving the headers to the include/sndfilter folder, so that it can be properly used as a library.

    In fact, I just used it for this project

    I was hesitant of this PR cause of noticing you being reluctant on any unnecessary changes in the simple codebase (in the c++ abovely mentioned MR), but figured why not.

    Thank you again for your work

    opened by actondev 2
  • How to control wetness/dryness of reverb without repopulating entirely?

    How to control wetness/dryness of reverb without repopulating entirely?

    The only explicit means of changing the reverb wetness/dryness is by repopulating the reverb structure with the same parameters but with different wet/dry values. This seems cumbersome for the computer. What am I missing?

    opened by codingisnuanced 1
  • Expander/Upward compressor

    Expander/Upward compressor

    Your classes are very good. How about altering the compressor to support a) upward (compress when audio is below threshold) and b) expand (increase range instead of reduce it by ratio).

    opened by WindowsNT 1
  • reverb algorithm performance

    reverb algorithm performance

    I have ported the lib to my Android project, the algorithm works well, but it is time cost. Can you give me some suggestion about this? Should I reduce some parameters or reduce effect quality?

    opened by ghost 1
  • IIR filter math wrong?

    IIR filter math wrong?

    https://github.com/voidqk/sndfilter/blob/master/src/reverb.c#L128

    static inline float iir1_step(sf_rv_iir1_st *iir1, float v){
    	float out = v * iir1->b1 + iir1->y1;
    	iir1->y1 = out * iir1->a2 + v * iir1->b2;
    	return out;
    }
    

    I think that should be:

    	iir1->y1 = out * iir1->a2 - v * iir1->b2;
    

    need to confirm

    opened by velipso 1
  • Request Audio Wav sample test

    Request Audio Wav sample test

    Hi voidqk! I'm very interesting with your dynamic range compressor project. i'm making it like you (nuc505 and Keil C), but i have some issues and i really want to get a wav file to test your code.

    Could you send me a link to download it? Thanks P/s: sorry about my English skill.

    opened by minhhieuec 0
  • Fix V519 warning from PVS-Studio Static Analyzer

    Fix V519 warning from PVS-Studio Static Analyzer

    I'm a member of the Pinguem.ru competition on finding errors in open source projects. A bug, found using PVS-Studio.

    Warning: The 'state->wet' variable is assigned values twice successively.

    opened by buslov 0
  • Biquad filter is hard clipping the audio

    Biquad filter is hard clipping the audio

    I'm using sndfilter biquad filter as a chain of filters, i.e. combining lowshelf, peaking and highshelf filters.

    In general, the equalizer should not over amplify the audio with the params I use.

    I can see that you have ported Web Audio API biquad filter and the code is almost the same, but it results in completely different output.

    eq-hard-clipping-diff
    1. Original
    2. GarageBand
    3. sndfilter

    GarageBand is just an example, we will get almost the same result with other tools.

    Could you please confirm whether this behavior is expected or maybe it's a known issue?

    How to reproduce

    Download drum-beat.wav

    sndfilter drum-beat.wav filtered.wav lowshelf 250 1 20
    sndfilter filtered.wav filtered.wav peaking 500 3 20
    

    You can reproduce it only by using lowshelf or peaking, but it's more demonstrative when combining them too.

    And also biquad filters affect only starting from around 1.3 seconds of the input audio. This is a separate issue BTW.

    opened by hosembafer 0
  • Sidechain compression?

    Sidechain compression?

    It 'd be nice to be able to add a parameter for sidechain: Different input signal than output signal.

    So for example, sf_compressor_process with an additional input 2: If the input 2 is above threshold, then compress input 1.

    opened by WindowsNT 0
  • License issue?

    License issue?

    Hello, first of all, nice work. :squirrel: I'm working on an opensource code that will be released under a permissive license and i have add some reverberation to an audio source, your reverb implementation is exactly what im looking for, but i've read the readme and it says

    The reverb effect is a complete rewrite of Freeverb3's Progenitor2 algorithm.

    afaik Freeverb3 is a gnu library under gnu gpl license, due to the properties of this license, shouldn't this code be licensed under gpl aswell?

    opened by riccardobl 4
Owner
Sean
slinging code across america
Sean
C++17 (-O2) template for competitive programming algorithms, which contains numerous math algorithms.

cpplibForCP C++17 (-O2) template for competitive programming algorithms, which contains numerous math algorithms. Aims: build a stable, fast, easy-to-

null 25 Aug 1, 2022
CComp: A Parallel Compression Algorithm for Compressed Word Search

The goal of CComp is to achieve better compressed search times while achieving the same compression-decompression speed as other parallel compression algorithms. CComp achieves this by splitting both the word dictionaries and the input stream, processing them in parallel.

Emir Öztürk 4 Sep 30, 2021
A library of common data structures and algorithms written in C.

C Algorithms The C programming language includes a very limited standard library in comparison to other modern programming languages. This is a coll

Simon Howard 2.8k Aug 9, 2022
Algorithms & Data structures in C++.

Algorithms & Data Structures in C++ 目标 ( goal ) : 经典的算法实现 (classical algorithms implementations) 服务器端 (based on linux/gcc) 正确,易于使用和改造, 一个头文件一个算法,并附带一个

xtaci 4.6k Aug 3, 2022
Several algorithms and data structures implemented in C++ by me (credited to others where necessary).

Algorithms This repository contains my implementations of several algorithms and data structures in C++ (credited to others where necessary). It has i

Petar Veličković 575 Aug 3, 2022
C++ implementations of well-known (and some rare) algorithms, while following good software development practices

ProAlgos: C++ This project is focused on implementing algorithms and data structures in C++, while following good software engineering practices, such

ProAlgos 469 Jul 28, 2022
Collection of algorithms and data structures in C++ and Java

Collection of algorithms and data structures in C++ and Java

Andrei Navumenka 1.7k Aug 8, 2022
This repository contains path planning algorithms in C++ for a grid based search.

This repository contains path planning algorithms in C++ for a grid based search.

null 206 Aug 6, 2022
Provide building blocks (software, hardware and algorithms) for implementing SLAM using small sensors

RemoteSLAM The purpose of this repo is to provide the building blocks (software drivers, hardware and algorithms) for implementing SLAM systems using

Autonomous Drones Lab, Tel Aviv University 38 Jan 20, 2022
Fundamentals of Data structures and algorithms in c++

Data Structures & Algorithms About the repository: Contains theories and programming questions related to fundamentals of data structures and algorith

fifu 41 Aug 8, 2022
CXXGraph is a Header-Only C++ Library for Graph Representation and Algorithms

CXXGraph is a small library, header only, that manages the Graph and it's algorithms in C++. In other words a "Comprehensive C++ Graph Library".

ZigRazor 151 Aug 10, 2022
Library for building multi-level indoor routes using routing algorithms.

Library for building multi-level indoor routes using routing algorithms. You can easily construct routing graphs and find the shortest path for optimal indoor navigation.

Navigine 5 Mar 20, 2022
Header-only C++ library for robotics, control, and path planning algorithms.

Header-only C++ library for robotics, control, and path planning algorithms.

null 341 Aug 2, 2022
c++ library including few algorithms and datastructures

c++ library including few algorithms and datastructures

null 2 Dec 25, 2021
This library contains a set of algorithms for working with the routing graph.

Library for building multi-level indoor routes using routing algorithms. You can easily construct routing graphs and find the shortest path for optimal indoor navigation.

Navigine 5 Mar 20, 2022
IntX is a C++11 port of IntX arbitrary precision Integer library with speed, about O(N * log N) multiplication/division algorithms implementation.

IntX IntX is a C++11 port of IntX arbitrary precision Integer library with speed, about O(N * log N) multiplication/division algorithms implementation

Telepati 9 Mar 9, 2022
In this project, we implemented twelve different sorting algorithms.

C - Sorting algorithms & Big O In this project, we implemented twelve different sorting algorithms. Tests tests: Folder of test files. Provided by Alx

Nicholas M Mwanza 1 Oct 26, 2021
All basic algorithms for solving problems of CP

All basic algorithms for solving problems of CP

Islam Assanov 1 Nov 14, 2021
Every week exercises for Introduction to Algorithms and Programming

cen109-algorithms commands to compile and link C and C++ programs gcc filename.c -o executableFileName g++ filename.cpp -o executableFileName filename

null 3 Mar 19, 2022