aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2018-01-20 15:59:39 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2018-02-16 15:54:41 +0100
commit3fd0707a3b73e624689afc37c9482d6efe436c37 (patch)
tree558854fc450767a2c7c574c115ca796e721c7eea /src
parent9197320ee63735715b7300b4d0026498f300b556 (diff)
Add libclipper, a library to 'smoothly' clip overdriven audio levels
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/libclipper/Makefile.am6
-rw-r--r--src/libclipper/clipper.c81
-rw-r--r--src/libclipper/clipper.h4
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);
+