diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2018-01-20 15:59:39 +0100 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2018-02-16 15:54:41 +0100 |
commit | 3fd0707a3b73e624689afc37c9482d6efe436c37 (patch) | |
tree | 558854fc450767a2c7c574c115ca796e721c7eea /src | |
parent | 9197320ee63735715b7300b4d0026498f300b556 (diff) |
Add libclipper, a library to 'smoothly' clip overdriven audio levels
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/libclipper/Makefile.am | 6 | ||||
-rw-r--r-- | src/libclipper/clipper.c | 81 | ||||
-rw-r--r-- | src/libclipper/clipper.h | 4 |
4 files changed, 93 insertions, 1 deletions
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 <jolly@eversberg.eu> + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <math.h> +#include <stdint.h> +#include <stdlib.h> +#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); + |