From 3fd0707a3b73e624689afc37c9482d6efe436c37 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 20 Jan 2018 15:59:39 +0100 Subject: Add libclipper, a library to 'smoothly' clip overdriven audio levels --- .gitignore | 1 + configure.ac | 1 + src/Makefile.am | 3 +- src/libclipper/Makefile.am | 6 ++++ src/libclipper/clipper.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++ src/libclipper/clipper.h | 4 +++ 6 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 src/libclipper/Makefile.am create mode 100644 src/libclipper/clipper.c create mode 100644 src/libclipper/clipper.h diff --git a/.gitignore b/.gitignore index 23bbc3d..6f875a6 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ src/libmncc/libmncc.a src/libsound/libsound.a src/libsdr/libsdr.a src/libsample/libsample.a +src/libclipper/libclipper.a src/anetz/libgermanton.a src/anetz/anetz src/bnetz/bnetz diff --git a/configure.ac b/configure.ac index 8f729d2..470e46e 100644 --- a/configure.ac +++ b/configure.ac @@ -73,6 +73,7 @@ AC_OUTPUT( src/libsound/Makefile src/libsdr/Makefile src/libsample/Makefile + src/libclipper/Makefile src/anetz/Makefile src/bnetz/Makefile src/cnetz/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 197ec5b..0de7471 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,7 +22,8 @@ SUBDIRS = \ libfilter \ libwave \ libfft \ - libmncc + libmncc \ + libclipper if HAVE_ALSA SUBDIRS += \ diff --git a/src/libclipper/Makefile.am b/src/libclipper/Makefile.am new file mode 100644 index 0000000..76de4b3 --- /dev/null +++ b/src/libclipper/Makefile.am @@ -0,0 +1,6 @@ +AM_CPPFLAGS = -Wall -Wextra -g $(all_includes) + +noinst_LIBRARIES = libclipper.a + +libclipper_a_SOURCES = \ + clipper.c diff --git a/src/libclipper/clipper.c b/src/libclipper/clipper.c new file mode 100644 index 0000000..2201051 --- /dev/null +++ b/src/libclipper/clipper.c @@ -0,0 +1,81 @@ +/* Clipper implementation, based on code by Jonathan Olds + * + * (C) 2017 by Andreas Eversberg + * All Rights Reserved + * + * 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 +#include +#include +#include +#include "../libsample/sample.h" +#include "clipper.h" + +static double clipper_lut[6000]; + +static double clipper_point = NAN; + +void clipper_init(double point) +{ + double a; + int i; + + if (point > 0.99) + point = 0.99; + if (point < 0.01) + point = 0.01; + clipper_point = point; + + a = M_PI / (2.0 * (1.0 - clipper_point)); + + for (i = 0; i < 6000; i++) + clipper_lut[i] = clipper_point + atan(a * i / 1000.0) / a; +} + +void clipper_process(sample_t *samples, int length) +{ + int i; + double val, inv, shiftmultval; + int n, q; + + if (isnan(clipper_point)) { + fprintf(stderr, "Clipper not initialized, aborting!\n"); + abort(); + } + + for (i = 0; i < length; i++) { + val = samples[i]; + if (val < 0) { + inv = -1.0; + val = -val; + } else + inv = 1.0; + shiftmultval = (val - clipper_point) * 1000.0; + /* no clipping up to clipping point */ + if (shiftmultval <= 0.0) + continue; + n = (int)shiftmultval; + q = n + 1; + if (q >= 6000) { + samples[i] = inv; + continue; + } + /* get clipped value from lut, interpolate between table entries */ + val = clipper_lut[n] + (shiftmultval - (double)n) * (clipper_lut[q] - clipper_lut[n]); + samples[i] = val * inv; + } +} + diff --git a/src/libclipper/clipper.h b/src/libclipper/clipper.h new file mode 100644 index 0000000..772be5c --- /dev/null +++ b/src/libclipper/clipper.h @@ -0,0 +1,4 @@ + +void clipper_init(double point); +void clipper_process(sample_t *samples, int length); + -- cgit v1.2.3