summaryrefslogtreecommitdiff
path: root/libavcodec/opusenc_utils.h
diff options
context:
space:
mode:
authorRostislav Pehlivanov <atomnuker@gmail.com>2017-09-23 00:38:37 +0100
committerRostislav Pehlivanov <atomnuker@gmail.com>2017-09-23 08:27:44 +0100
commit2ad1768c7b48b6c77bbe9c42a4c2744f7b029182 (patch)
treecf97ad8da31d2e5695b4135f88ae92b90fe2f053 /libavcodec/opusenc_utils.h
parent1ef7752d64cbe9af2f27cc65aba3a2ca3831c128 (diff)
opusenc: implement a psychoacoustic system
This commit implements a psychoacoustic system for the native Opus encoder. Its unlike any other psychoacoustic system known since its capable of using a lookahead to make better choices on how to treat the current frame and how many bits to allocate for it (and future frames). Also, whilst the main bulk of the analysis function has to run in a single thread, the per-frame anaylsis functions does not modify the main psychoacoustic context, so in the future it will be fairly trivial to run those as slice threads. Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
Diffstat (limited to 'libavcodec/opusenc_utils.h')
-rw-r--r--libavcodec/opusenc_utils.h82
1 files changed, 82 insertions, 0 deletions
diff --git a/libavcodec/opusenc_utils.h b/libavcodec/opusenc_utils.h
new file mode 100644
index 0000000000..8b9c5bffaf
--- /dev/null
+++ b/libavcodec/opusenc_utils.h
@@ -0,0 +1,82 @@
+/*
+ * Opus encoder
+ * Copyright (c) 2017 Rostislav Pehlivanov <atomnuker@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "opus.h"
+
+typedef struct FFBesselFilter {
+ float a[3];
+ float b[2];
+ float x[3];
+ float y[3];
+} FFBesselFilter;
+
+/* Fills the coefficients, returns 1 if filter will be unstable */
+static inline int bessel_reinit(FFBesselFilter *s, float n, float f0, float fs,
+ int highpass)
+{
+ int unstable;
+ float c, cfreq, w0, k1, k2;
+
+ if (!highpass) {
+ c = (1.0f/sqrtf(sqrtf(pow(2.0f, 1.0f/n) - 3.0f/4.0f) - 0.5f))/sqrtf(3.0f);
+ cfreq = c*f0/fs;
+ unstable = (cfreq <= 0.0f || cfreq >= 1.0f/4.0f);
+ } else {
+ c = sqrtf(3.0f)*sqrtf(sqrtf(pow(2.0f, 1.0f/n) - 3.0f/4.0f) - 0.5f);
+ cfreq = 0.5f - c*f0/fs;
+ unstable = (cfreq <= 3.0f/8.0f || cfreq >= 1.0f/2.0f);
+ }
+
+ w0 = tanf(M_PI*cfreq);
+ k1 = 3.0f * w0;
+ k2 = 3.0f * w0;
+
+ s->a[0] = k2/(1.0f + k1 + k2);
+ s->a[1] = 2.0f * s->a[0];
+ s->a[2] = s->a[0];
+ s->b[0] = 2.0f * s->a[0] * (1.0f/k2 - 1.0f);
+ s->b[1] = 1.0f - (s->a[0] + s->a[1] + s->a[2] + s->b[0]);
+
+ if (highpass) {
+ s->a[1] *= -1;
+ s->b[0] *= -1;
+ }
+
+ return unstable;
+}
+
+static inline int bessel_init(FFBesselFilter *s, float n, float f0, float fs,
+ int highpass)
+{
+ memset(s, 0, sizeof(FFBesselFilter));
+ return bessel_reinit(s, n, f0, fs, highpass);
+}
+
+static inline float bessel_filter(FFBesselFilter *s, float x)
+{
+ s->x[2] = s->x[1];
+ s->x[1] = s->x[0];
+ s->x[0] = x;
+ s->y[2] = s->y[1];
+ s->y[1] = s->y[0];
+ s->y[0] = s->a[0]*s->x[0] + s->a[1]*s->x[1] + s->a[2]*s->x[2] + s->b[0]*s->y[1] + s->b[1]*s->y[2];
+ return s->y[0];
+}