From c4ad107076970a555ed838a75c0343dffe0cad36 Mon Sep 17 00:00:00 2001
From: Lynne <dev@lynne.ee>
Date: Mon, 29 Jan 2024 04:31:43 +0100
Subject: [PATCH] opusdsp: add ability to modify deemphasis constant
xHE-AAC relies on the same postfilter mechanism
that Opus uses to improve clarity (albeit with a steeper
deemphasis filter).
The code to apply it is identical, it's still just a
simple IIR low-pass filter. This commit makes it possible
to use alternative constants.
---
libavcodec/aarch64/opusdsp_init.c | 2 +-
libavcodec/aarch64/opusdsp_neon.S | 28 +++++-----------------------
libavcodec/opusdec_celt.c | 4 +++-
libavcodec/opusdsp.c | 28 ++++++++++++++++++++++++++--
libavcodec/opusdsp.h | 2 +-
libavcodec/x86/opusdsp.asm | 9 +++------
libavcodec/x86/opusdsp_init.c | 2 +-
7 files changed, 40 insertions(+), 35 deletions(-)
@@ -23,7 +23,7 @@
#include "libavcodec/opusdsp.h"
void ff_opus_postfilter_neon(float *data, int period, float *gains, int len);
-float ff_opus_deemphasis_neon(float *out, float *in, float coeff, int len);
+float ff_opus_deemphasis_neon(float *out, float *in, float coeff, float *weights, int len);
av_cold void ff_opus_dsp_init_aarch64(OpusDSP *ctx)
{
@@ -18,29 +18,11 @@
#include "libavutil/aarch64/asm.S"
- // 0.85..^1 0.85..^2 0.85..^3 0.85..^4
-const tab_st, align=4
- .word 0x3f599a00, 0x3f38f671, 0x3f1d382a, 0x3f05a32f
-endconst
-const tab_x0, align=4
- .word 0x0, 0x3f599a00, 0x3f38f671, 0x3f1d382a
-endconst
-const tab_x1, align=4
- .word 0x0, 0x0, 0x3f599a00, 0x3f38f671
-endconst
-const tab_x2, align=4
- .word 0x0, 0x0, 0x0, 0x3f599a00
-endconst
-
function ff_opus_deemphasis_neon, export=1
- movrel x4, tab_st
- ld1 {v4.4s}, [x4]
- movrel x4, tab_x0
- ld1 {v5.4s}, [x4]
- movrel x4, tab_x1
- ld1 {v6.4s}, [x4]
- movrel x4, tab_x2
- ld1 {v7.4s}, [x4]
+ ld1 {v4.4s}, [x2], #16
+ ld1 {v5.4s}, [x2], #16
+ ld1 {v6.4s}, [x2], #16
+ ld1 {v7.4s}, [x2]
fmul v0.4s, v4.4s, v0.s[0]
@@ -63,7 +45,7 @@ function ff_opus_deemphasis_neon, export=1
st1 {v1.4s, v2.4s}, [x0], #32
fmul v0.4s, v4.4s, v2.s[3]
- subs w2, w2, #8
+ subs w3, w3, #8
b.gt 1b
mov s0, v2.s[3]
@@ -460,7 +460,9 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
/* deemphasis */
block->emph_coeff = f->opusdsp.deemphasis(output[i],
&block->buf[1024 - frame_size],
- block->emph_coeff, frame_size);
+ block->emph_coeff,
+ ff_deemph_opus_weights,
+ frame_size);
}
if (channels == 1)
@@ -18,8 +18,31 @@
#include "config.h"
#include "libavutil/attributes.h"
+#include "libavutil/mem_internal.h"
#include "opusdsp.h"
+static const DECLARE_ALIGNED(16, float, ff_deemph_opus_weights)[] = {
+ CELT_EMPH_COEFF,
+ CELT_EMPH_COEFF*CELT_EMPH_COEFF,
+ CELT_EMPH_COEFF*CELT_EMPH_COEFF*CELT_EMPH_COEFF,
+ CELT_EMPH_COEFF*CELT_EMPH_COEFF*CELT_EMPH_COEFF*CELT_EMPH_COEFF,
+
+ 0,
+ CELT_EMPH_COEFF,
+ CELT_EMPH_COEFF*CELT_EMPH_COEFF,
+ CELT_EMPH_COEFF*CELT_EMPH_COEFF*CELT_EMPH_COEFF,
+
+ 0,
+ 0,
+ CELT_EMPH_COEFF,
+ CELT_EMPH_COEFF*CELT_EMPH_COEFF,
+
+ 0,
+ 0,
+ 0,
+ CELT_EMPH_COEFF,
+};
+
static void postfilter_c(float *data, int period, float *gains, int len)
{
const float g0 = gains[0];
@@ -43,10 +66,11 @@ static void postfilter_c(float *data, int period, float *gains, int len)
}
}
-static float deemphasis_c(float *y, float *x, float coeff, int len)
+static float deemphasis_c(float *y, float *x, float coeff, float *weights, int len)
{
+ float c = weights[0];
for (int i = 0; i < len; i++)
- coeff = y[i] = x[i] + coeff*CELT_EMPH_COEFF;
+ coeff = y[i] = x[i] + coeff*c;
return coeff;
}
@@ -23,7 +23,7 @@
typedef struct OpusDSP {
void (*postfilter)(float *data, int period, float *gains, int len);
- float (*deemphasis)(float *out, float *in, float coeff, int len);
+ float (*deemphasis)(float *out, float *in, float coeff, float *weights, int len);
} OpusDSP;
void ff_opus_dsp_init(OpusDSP *ctx);
@@ -22,16 +22,13 @@
SECTION_RODATA
- ; 0.85..^1 0.85..^2 0.85..^3 0.85..^4
-tab_st: dd 0x3f599a00, 0x3f38f671, 0x3f1d382a, 0x3f05a32f
-
SECTION .text
INIT_XMM fma3
%if UNIX64
-cglobal opus_deemphasis, 3, 3, 8, out, in, len
+cglobal opus_deemphasis, 4, 4, 8, out, in, weights, len
%else
-cglobal opus_deemphasis, 4, 4, 8, out, in, coeff, len
+cglobal opus_deemphasis, 5, 5, 8, out, in, coeff, weights, len
%endif
%if ARCH_X86_32
VBROADCASTSS m0, coeffm
@@ -41,7 +38,7 @@ cglobal opus_deemphasis, 4, 4, 8, out, in, coeff, len
shufps m0, m0, 0
%endif
- movaps m4, [tab_st]
+ movaps m4, [weightsq]
VBROADCASTSS m5, m4
shufps m6, m4, m4, q1111
shufps m7, m4, m4, q2222
@@ -23,7 +23,7 @@
#include "libavcodec/opusdsp.h"
void ff_opus_postfilter_fma3(float *data, int period, float *gains, int len);
-float ff_opus_deemphasis_fma3(float *out, float *in, float coeff, int len);
+float ff_opus_deemphasis_fma3(float *out, float *in, float coeff, float *weights, int len);
av_cold void ff_opus_dsp_init_x86(OpusDSP *ctx)
{
--
2.43.0.381.gb435a96ce8