* [FFmpeg-devel] [PATCH v2] opusdsp: add ability to modify deemphasis constant
@ 2024-04-24 8:54 Lynne
[not found] ` <NwEJ54_--3-9@lynne.ee-NwEJ9Lk----9>
0 siblings, 1 reply; 4+ messages in thread
From: Lynne @ 2024-04-24 8:54 UTC (permalink / raw)
To: Ffmpeg Devel
[-- Attachment #1: Type: text/plain, Size: 368 bytes --]
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.
Version 2 changes:
Move the deemphasis constant table to opustab.c and
document its values better.
[-- Attachment #2: v2-0001-opusdsp-add-ability-to-modify-deemphasis-constant.patch --]
[-- Type: text/x-diff, Size: 8700 bytes --]
From e6d0621f61bb39929548cab5fa047c1827e1ab8c Mon Sep 17 00:00:00 2001
From: Lynne <dev@lynne.ee>
Date: Mon, 29 Jan 2024 04:31:43 +0100
Subject: [PATCH v2] 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 | 6 ++++--
libavcodec/opusdsp.c | 6 ++++--
libavcodec/opusdsp.h | 4 +---
libavcodec/opustab.c | 28 ++++++++++++++++++++++++++++
libavcodec/opustab.h | 2 ++
libavcodec/x86/opusdsp.asm | 9 +++------
libavcodec/x86/opusdsp_init.c | 2 +-
9 files changed, 49 insertions(+), 38 deletions(-)
diff --git a/libavcodec/aarch64/opusdsp_init.c b/libavcodec/aarch64/opusdsp_init.c
index bb6d71b66b..a727006593 100644
--- a/libavcodec/aarch64/opusdsp_init.c
+++ b/libavcodec/aarch64/opusdsp_init.c
@@ -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, const float *weights, int len);
av_cold void ff_opus_dsp_init_aarch64(OpusDSP *ctx)
{
diff --git a/libavcodec/aarch64/opusdsp_neon.S b/libavcodec/aarch64/opusdsp_neon.S
index e933151ab4..253825aa61 100644
--- a/libavcodec/aarch64/opusdsp_neon.S
+++ b/libavcodec/aarch64/opusdsp_neon.S
@@ -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]
diff --git a/libavcodec/opusdec_celt.c b/libavcodec/opusdec_celt.c
index fd8e9929e9..b19342337d 100644
--- a/libavcodec/opusdec_celt.c
+++ b/libavcodec/opusdec_celt.c
@@ -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_opus_deemph_weights,
+ frame_size);
}
if (channels == 1)
@@ -516,7 +518,7 @@ void ff_celt_flush(CeltFrame *f)
* a lesser discontinuity when seeking.
* The deemphasis functions differ from libopus in that they require
* an initial state divided by the coefficient. */
- block->emph_coeff = 0.0f / CELT_EMPH_COEFF;
+ block->emph_coeff = 0.0f / ff_opus_deemph_weights[0];
}
f->seed = 0;
diff --git a/libavcodec/opusdsp.c b/libavcodec/opusdsp.c
index 0764d712e4..e61cc36098 100644
--- a/libavcodec/opusdsp.c
+++ b/libavcodec/opusdsp.c
@@ -18,6 +18,7 @@
#include "config.h"
#include "libavutil/attributes.h"
+#include "libavutil/mem_internal.h"
#include "opusdsp.h"
static void postfilter_c(float *data, int period, float *gains, int len)
@@ -43,10 +44,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, const float *weights, int len)
{
+ const 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;
}
diff --git a/libavcodec/opusdsp.h b/libavcodec/opusdsp.h
index c2a301e832..9d93336cfe 100644
--- a/libavcodec/opusdsp.h
+++ b/libavcodec/opusdsp.h
@@ -19,11 +19,9 @@
#ifndef AVCODEC_OPUSDSP_H
#define AVCODEC_OPUSDSP_H
-#define CELT_EMPH_COEFF 0.8500061035f
-
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, const float *weights, int len);
} OpusDSP;
void ff_opus_dsp_init(OpusDSP *ctx);
diff --git a/libavcodec/opustab.c b/libavcodec/opustab.c
index 2a57511177..47624fe651 100644
--- a/libavcodec/opustab.c
+++ b/libavcodec/opustab.c
@@ -1159,3 +1159,31 @@ const uint32_t * const ff_celt_pvq_u_row[15] = {
celt_pvq_u + 1207, celt_pvq_u + 1226, celt_pvq_u + 1240,
celt_pvq_u + 1248, celt_pvq_u + 1254, celt_pvq_u + 1257
};
+
+/* Deemphasis constant (alpha_p), as specified in RFC6716 as 0.8500061035.
+ * libopus uses a slighly rounded constant, set to 0.85 exactly,
+ * to simplify its fixed-point version, but it's not significant to impact
+ * compliance. */
+#define CELT_EMPH_COEFF 0.8500061035f
+
+DECLARE_ALIGNED(16, const float, ff_opus_deemph_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,
+};
diff --git a/libavcodec/opustab.h b/libavcodec/opustab.h
index 9c9f1b9d98..57e546aef5 100644
--- a/libavcodec/opustab.h
+++ b/libavcodec/opustab.h
@@ -161,6 +161,8 @@ extern const float ff_celt_window2[120];
extern const float ff_celt_window_padded[];
static const float *const ff_celt_window = &ff_celt_window_padded[8];
+extern const float ff_opus_deemph_weights[];
+
extern const uint32_t * const ff_celt_pvq_u_row[15];
FF_VISIBILITY_POP_HIDDEN
diff --git a/libavcodec/x86/opusdsp.asm b/libavcodec/x86/opusdsp.asm
index 418cc16330..635f59f83c 100644
--- a/libavcodec/x86/opusdsp.asm
+++ b/libavcodec/x86/opusdsp.asm
@@ -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
diff --git a/libavcodec/x86/opusdsp_init.c b/libavcodec/x86/opusdsp_init.c
index 582fbb4f0c..66d6839589 100644
--- a/libavcodec/x86/opusdsp_init.c
+++ b/libavcodec/x86/opusdsp_init.c
@@ -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, const float *weights, int len);
av_cold void ff_opus_dsp_init_x86(OpusDSP *ctx)
{
--
2.43.0.381.gb435a96ce8
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2] opusdsp: add ability to modify deemphasis constant
[not found] ` <NwEJ54_--3-9@lynne.ee-NwEJ9Lk----9>
@ 2024-04-24 10:58 ` Lynne
2024-04-25 0:08 ` Michael Niedermayer
0 siblings, 1 reply; 4+ messages in thread
From: Lynne @ 2024-04-24 10:58 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1: Type: text/plain, Size: 481 bytes --]
Apr 24, 2024, 10:54 by dev@lynne.ee:
> 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.
>
> Version 2 changes:
> Move the deemphasis constant table to opustab.c and
> document its values better.
>
v3 attached, forgot to port the native opus encoder.
[-- Attachment #2: v3-0001-opusdsp-add-ability-to-modify-deemphasis-constant.patch --]
[-- Type: text/x-diff, Size: 10031 bytes --]
From 22fa7632e843785600b3ba3f56e476eed65e42f0 Mon Sep 17 00:00:00 2001
From: Lynne <dev@lynne.ee>
Date: Mon, 29 Jan 2024 04:31:43 +0100
Subject: [PATCH v3] 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 | 6 ++++--
libavcodec/opusdsp.c | 6 ++++--
libavcodec/opusdsp.h | 4 +---
libavcodec/opusenc.c | 5 +++--
libavcodec/opustab.c | 28 ++++++++++++++++++++++++++++
libavcodec/opustab.h | 2 ++
libavcodec/x86/opusdsp.asm | 9 +++------
libavcodec/x86/opusdsp_init.c | 2 +-
10 files changed, 52 insertions(+), 40 deletions(-)
diff --git a/libavcodec/aarch64/opusdsp_init.c b/libavcodec/aarch64/opusdsp_init.c
index bb6d71b66b..a727006593 100644
--- a/libavcodec/aarch64/opusdsp_init.c
+++ b/libavcodec/aarch64/opusdsp_init.c
@@ -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, const float *weights, int len);
av_cold void ff_opus_dsp_init_aarch64(OpusDSP *ctx)
{
diff --git a/libavcodec/aarch64/opusdsp_neon.S b/libavcodec/aarch64/opusdsp_neon.S
index e933151ab4..253825aa61 100644
--- a/libavcodec/aarch64/opusdsp_neon.S
+++ b/libavcodec/aarch64/opusdsp_neon.S
@@ -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]
diff --git a/libavcodec/opusdec_celt.c b/libavcodec/opusdec_celt.c
index fd8e9929e9..b19342337d 100644
--- a/libavcodec/opusdec_celt.c
+++ b/libavcodec/opusdec_celt.c
@@ -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_opus_deemph_weights,
+ frame_size);
}
if (channels == 1)
@@ -516,7 +518,7 @@ void ff_celt_flush(CeltFrame *f)
* a lesser discontinuity when seeking.
* The deemphasis functions differ from libopus in that they require
* an initial state divided by the coefficient. */
- block->emph_coeff = 0.0f / CELT_EMPH_COEFF;
+ block->emph_coeff = 0.0f / ff_opus_deemph_weights[0];
}
f->seed = 0;
diff --git a/libavcodec/opusdsp.c b/libavcodec/opusdsp.c
index 0764d712e4..e61cc36098 100644
--- a/libavcodec/opusdsp.c
+++ b/libavcodec/opusdsp.c
@@ -18,6 +18,7 @@
#include "config.h"
#include "libavutil/attributes.h"
+#include "libavutil/mem_internal.h"
#include "opusdsp.h"
static void postfilter_c(float *data, int period, float *gains, int len)
@@ -43,10 +44,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, const float *weights, int len)
{
+ const 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;
}
diff --git a/libavcodec/opusdsp.h b/libavcodec/opusdsp.h
index c2a301e832..9d93336cfe 100644
--- a/libavcodec/opusdsp.h
+++ b/libavcodec/opusdsp.h
@@ -19,11 +19,9 @@
#ifndef AVCODEC_OPUSDSP_H
#define AVCODEC_OPUSDSP_H
-#define CELT_EMPH_COEFF 0.8500061035f
-
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, const float *weights, int len);
} OpusDSP;
void ff_opus_dsp_init(OpusDSP *ctx);
diff --git a/libavcodec/opusenc.c b/libavcodec/opusenc.c
index e0c1732227..0e4c3752a5 100644
--- a/libavcodec/opusenc.c
+++ b/libavcodec/opusenc.c
@@ -164,6 +164,7 @@ static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f)
{
const int subframesize = s->avctx->frame_size;
const int subframes = OPUS_BLOCK_SIZE(s->packet.framesize) / subframesize;
+ const float c = ff_opus_deemph_weights[0];
/* Filter overlap */
for (int ch = 0; ch < f->channels; ch++) {
@@ -172,7 +173,7 @@ static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f)
for (int i = 0; i < CELT_OVERLAP; i++) {
float sample = b->overlap[i];
b->overlap[i] = sample - m;
- m = sample * CELT_EMPH_COEFF;
+ m = sample * c;
}
b->emph_coeff = m;
}
@@ -185,7 +186,7 @@ static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f)
for (int i = 0; i < subframesize; i++) {
float sample = b->samples[sf*subframesize + i];
b->samples[sf*subframesize + i] = sample - m;
- m = sample * CELT_EMPH_COEFF;
+ m = sample * c;
}
if (sf != (subframes - 1))
b->emph_coeff = m;
diff --git a/libavcodec/opustab.c b/libavcodec/opustab.c
index 2a57511177..47624fe651 100644
--- a/libavcodec/opustab.c
+++ b/libavcodec/opustab.c
@@ -1159,3 +1159,31 @@ const uint32_t * const ff_celt_pvq_u_row[15] = {
celt_pvq_u + 1207, celt_pvq_u + 1226, celt_pvq_u + 1240,
celt_pvq_u + 1248, celt_pvq_u + 1254, celt_pvq_u + 1257
};
+
+/* Deemphasis constant (alpha_p), as specified in RFC6716 as 0.8500061035.
+ * libopus uses a slighly rounded constant, set to 0.85 exactly,
+ * to simplify its fixed-point version, but it's not significant to impact
+ * compliance. */
+#define CELT_EMPH_COEFF 0.8500061035f
+
+DECLARE_ALIGNED(16, const float, ff_opus_deemph_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,
+};
diff --git a/libavcodec/opustab.h b/libavcodec/opustab.h
index 9c9f1b9d98..57e546aef5 100644
--- a/libavcodec/opustab.h
+++ b/libavcodec/opustab.h
@@ -161,6 +161,8 @@ extern const float ff_celt_window2[120];
extern const float ff_celt_window_padded[];
static const float *const ff_celt_window = &ff_celt_window_padded[8];
+extern const float ff_opus_deemph_weights[];
+
extern const uint32_t * const ff_celt_pvq_u_row[15];
FF_VISIBILITY_POP_HIDDEN
diff --git a/libavcodec/x86/opusdsp.asm b/libavcodec/x86/opusdsp.asm
index 418cc16330..635f59f83c 100644
--- a/libavcodec/x86/opusdsp.asm
+++ b/libavcodec/x86/opusdsp.asm
@@ -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
diff --git a/libavcodec/x86/opusdsp_init.c b/libavcodec/x86/opusdsp_init.c
index 582fbb4f0c..66d6839589 100644
--- a/libavcodec/x86/opusdsp_init.c
+++ b/libavcodec/x86/opusdsp_init.c
@@ -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, const float *weights, int len);
av_cold void ff_opus_dsp_init_x86(OpusDSP *ctx)
{
--
2.43.0.381.gb435a96ce8
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2] opusdsp: add ability to modify deemphasis constant
2024-04-24 10:58 ` Lynne
@ 2024-04-25 0:08 ` Michael Niedermayer
2024-04-25 7:53 ` Lynne
0 siblings, 1 reply; 4+ messages in thread
From: Michael Niedermayer @ 2024-04-25 0:08 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 1566 bytes --]
On Wed, Apr 24, 2024 at 12:58:54PM +0200, Lynne wrote:
> Apr 24, 2024, 10:54 by dev@lynne.ee:
>
> > 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.
> >
> > Version 2 changes:
> > Move the deemphasis constant table to opustab.c and
> > document its values better.
> >
>
> v3 attached, forgot to port the native opus encoder.
make V=2 fate-checkasm-opusdsp
TEST checkasm-opusdsp
./tests/fate-run.sh fate-checkasm-opusdsp "/home/michael/fatesamples/fate/fate-suite/" "" "/home/michael/ffmpeg-git/ffmpeg" 'run tests/checkasm/checkasm --test=opusdsp' 'null' '' '' '1' '' '' '' '' '' '' '' '' '' ''
/home/michael/ffmpeg-git/ffmpeg/tests/checkasm/checkasm --test=opusdsp
Test checkasm-opusdsp failed. Look at tests/data/fate/checkasm-opusdsp.err for details.
checkasm: using random seed 4190264620
FMA3:
- opusdsp.postfilter_15 [OK]
- opusdsp.postfilter_512 [OK]
- opusdsp.postfilter_1022 [OK]
deemphasis_fma3 (fatal signal 11: Segmentation fault)
- opusdsp.deemphasis [FAILED]
checkasm: 1 of 4 tests have failed
threads=1
make: *** [tests/Makefile:311: fate-checkasm-opusdsp] Error 1
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
During times of universal deceit, telling the truth becomes a
revolutionary act. -- George Orwell
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2] opusdsp: add ability to modify deemphasis constant
2024-04-25 0:08 ` Michael Niedermayer
@ 2024-04-25 7:53 ` Lynne
0 siblings, 0 replies; 4+ messages in thread
From: Lynne @ 2024-04-25 7:53 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1: Type: text/plain, Size: 1522 bytes --]
Apr 25, 2024, 02:08 by michael@niedermayer.cc:
> On Wed, Apr 24, 2024 at 12:58:54PM +0200, Lynne wrote:
>
>> Apr 24, 2024, 10:54 by dev@lynne.ee:
>>
>> > 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.
>> >
>> > Version 2 changes:
>> > Move the deemphasis constant table to opustab.c and
>> > document its values better.
>> >
>>
>> v3 attached, forgot to port the native opus encoder.
>>
>
> make V=2 fate-checkasm-opusdsp
> TEST checkasm-opusdsp
> ./tests/fate-run.sh fate-checkasm-opusdsp "/home/michael/fatesamples/fate/fate-suite/" "" "/home/michael/ffmpeg-git/ffmpeg" 'run tests/checkasm/checkasm --test=opusdsp' 'null' '' '' '1' '' '' '' '' '' '' '' '' '' ''
> /home/michael/ffmpeg-git/ffmpeg/tests/checkasm/checkasm --test=opusdsp
> Test checkasm-opusdsp failed. Look at tests/data/fate/checkasm-opusdsp.err for details.
> checkasm: using random seed 4190264620
> FMA3:
> - opusdsp.postfilter_15 [OK]
> - opusdsp.postfilter_512 [OK]
> - opusdsp.postfilter_1022 [OK]
> deemphasis_fma3 (fatal signal 11: Segmentation fault)
> - opusdsp.deemphasis [FAILED]
> checkasm: 1 of 4 tests have failed
> threads=1
> make: *** [tests/Makefile:311: fate-checkasm-opusdsp] Error 1
>
Forgot that I disabled asm to test with asan.
Fixed checkasm.
Patch attached.
[-- Attachment #2: v4-0001-opusdsp-add-ability-to-modify-deemphasis-constant.patch --]
[-- Type: text/x-diff, Size: 11354 bytes --]
From 6e956fc31ce487516bc4576facbd540baddb8a7b Mon Sep 17 00:00:00 2001
From: Lynne <dev@lynne.ee>
Date: Mon, 29 Jan 2024 04:31:43 +0100
Subject: [PATCH v4] 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 | 6 ++++--
libavcodec/opusdsp.c | 6 ++++--
libavcodec/opusdsp.h | 4 +---
libavcodec/opusenc.c | 5 +++--
libavcodec/opustab.c | 28 ++++++++++++++++++++++++++++
libavcodec/opustab.h | 2 ++
libavcodec/x86/opusdsp.asm | 9 +++------
libavcodec/x86/opusdsp_init.c | 2 +-
tests/checkasm/opusdsp.c | 9 +++++----
11 files changed, 57 insertions(+), 44 deletions(-)
diff --git a/libavcodec/aarch64/opusdsp_init.c b/libavcodec/aarch64/opusdsp_init.c
index bb6d71b66b..a727006593 100644
--- a/libavcodec/aarch64/opusdsp_init.c
+++ b/libavcodec/aarch64/opusdsp_init.c
@@ -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, const float *weights, int len);
av_cold void ff_opus_dsp_init_aarch64(OpusDSP *ctx)
{
diff --git a/libavcodec/aarch64/opusdsp_neon.S b/libavcodec/aarch64/opusdsp_neon.S
index e933151ab4..253825aa61 100644
--- a/libavcodec/aarch64/opusdsp_neon.S
+++ b/libavcodec/aarch64/opusdsp_neon.S
@@ -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]
diff --git a/libavcodec/opusdec_celt.c b/libavcodec/opusdec_celt.c
index fd8e9929e9..b19342337d 100644
--- a/libavcodec/opusdec_celt.c
+++ b/libavcodec/opusdec_celt.c
@@ -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_opus_deemph_weights,
+ frame_size);
}
if (channels == 1)
@@ -516,7 +518,7 @@ void ff_celt_flush(CeltFrame *f)
* a lesser discontinuity when seeking.
* The deemphasis functions differ from libopus in that they require
* an initial state divided by the coefficient. */
- block->emph_coeff = 0.0f / CELT_EMPH_COEFF;
+ block->emph_coeff = 0.0f / ff_opus_deemph_weights[0];
}
f->seed = 0;
diff --git a/libavcodec/opusdsp.c b/libavcodec/opusdsp.c
index 0764d712e4..e61cc36098 100644
--- a/libavcodec/opusdsp.c
+++ b/libavcodec/opusdsp.c
@@ -18,6 +18,7 @@
#include "config.h"
#include "libavutil/attributes.h"
+#include "libavutil/mem_internal.h"
#include "opusdsp.h"
static void postfilter_c(float *data, int period, float *gains, int len)
@@ -43,10 +44,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, const float *weights, int len)
{
+ const 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;
}
diff --git a/libavcodec/opusdsp.h b/libavcodec/opusdsp.h
index c2a301e832..9d93336cfe 100644
--- a/libavcodec/opusdsp.h
+++ b/libavcodec/opusdsp.h
@@ -19,11 +19,9 @@
#ifndef AVCODEC_OPUSDSP_H
#define AVCODEC_OPUSDSP_H
-#define CELT_EMPH_COEFF 0.8500061035f
-
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, const float *weights, int len);
} OpusDSP;
void ff_opus_dsp_init(OpusDSP *ctx);
diff --git a/libavcodec/opusenc.c b/libavcodec/opusenc.c
index e0c1732227..0e4c3752a5 100644
--- a/libavcodec/opusenc.c
+++ b/libavcodec/opusenc.c
@@ -164,6 +164,7 @@ static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f)
{
const int subframesize = s->avctx->frame_size;
const int subframes = OPUS_BLOCK_SIZE(s->packet.framesize) / subframesize;
+ const float c = ff_opus_deemph_weights[0];
/* Filter overlap */
for (int ch = 0; ch < f->channels; ch++) {
@@ -172,7 +173,7 @@ static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f)
for (int i = 0; i < CELT_OVERLAP; i++) {
float sample = b->overlap[i];
b->overlap[i] = sample - m;
- m = sample * CELT_EMPH_COEFF;
+ m = sample * c;
}
b->emph_coeff = m;
}
@@ -185,7 +186,7 @@ static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f)
for (int i = 0; i < subframesize; i++) {
float sample = b->samples[sf*subframesize + i];
b->samples[sf*subframesize + i] = sample - m;
- m = sample * CELT_EMPH_COEFF;
+ m = sample * c;
}
if (sf != (subframes - 1))
b->emph_coeff = m;
diff --git a/libavcodec/opustab.c b/libavcodec/opustab.c
index 2a57511177..47624fe651 100644
--- a/libavcodec/opustab.c
+++ b/libavcodec/opustab.c
@@ -1159,3 +1159,31 @@ const uint32_t * const ff_celt_pvq_u_row[15] = {
celt_pvq_u + 1207, celt_pvq_u + 1226, celt_pvq_u + 1240,
celt_pvq_u + 1248, celt_pvq_u + 1254, celt_pvq_u + 1257
};
+
+/* Deemphasis constant (alpha_p), as specified in RFC6716 as 0.8500061035.
+ * libopus uses a slighly rounded constant, set to 0.85 exactly,
+ * to simplify its fixed-point version, but it's not significant to impact
+ * compliance. */
+#define CELT_EMPH_COEFF 0.8500061035f
+
+DECLARE_ALIGNED(16, const float, ff_opus_deemph_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,
+};
diff --git a/libavcodec/opustab.h b/libavcodec/opustab.h
index 9c9f1b9d98..57e546aef5 100644
--- a/libavcodec/opustab.h
+++ b/libavcodec/opustab.h
@@ -161,6 +161,8 @@ extern const float ff_celt_window2[120];
extern const float ff_celt_window_padded[];
static const float *const ff_celt_window = &ff_celt_window_padded[8];
+extern const float ff_opus_deemph_weights[];
+
extern const uint32_t * const ff_celt_pvq_u_row[15];
FF_VISIBILITY_POP_HIDDEN
diff --git a/libavcodec/x86/opusdsp.asm b/libavcodec/x86/opusdsp.asm
index 418cc16330..635f59f83c 100644
--- a/libavcodec/x86/opusdsp.asm
+++ b/libavcodec/x86/opusdsp.asm
@@ -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
diff --git a/libavcodec/x86/opusdsp_init.c b/libavcodec/x86/opusdsp_init.c
index 582fbb4f0c..66d6839589 100644
--- a/libavcodec/x86/opusdsp_init.c
+++ b/libavcodec/x86/opusdsp_init.c
@@ -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, const float *weights, int len);
av_cold void ff_opus_dsp_init_x86(OpusDSP *ctx)
{
diff --git a/tests/checkasm/opusdsp.c b/tests/checkasm/opusdsp.c
index 34ee5a4edc..b9ecc55240 100644
--- a/tests/checkasm/opusdsp.c
+++ b/tests/checkasm/opusdsp.c
@@ -19,6 +19,7 @@
#include "libavutil/mem_internal.h"
#include "libavcodec/opusdsp.h"
+#include "libavcodec/opustab.h"
#include "checkasm.h"
@@ -69,17 +70,17 @@ static void test_deemphasis(void)
LOCAL_ALIGNED(16, float, dst1, [FFALIGN(MAX_SIZE, 4)]);
float coeff0 = (float)rnd() / (UINT_MAX >> 5) - 16.0f, coeff1 = coeff0;
- declare_func_float(float, float *out, float *in, float coeff, int len);
+ declare_func_float(float, float *out, float *in, float coeff, const float *weights, int len);
randomize_float(src, MAX_SIZE);
- coeff0 = call_ref(dst0, src, coeff0, MAX_SIZE);
- coeff1 = call_new(dst1, src, coeff1, MAX_SIZE);
+ coeff0 = call_ref(dst0, src, coeff0, ff_opus_deemph_weights, MAX_SIZE);
+ coeff1 = call_new(dst1, src, coeff1, ff_opus_deemph_weights, MAX_SIZE);
if (!float_near_abs_eps(coeff0, coeff1, EPS) ||
!float_near_abs_eps_array(dst0, dst1, EPS, MAX_SIZE))
fail();
- bench_new(dst1, src, coeff1, MAX_SIZE);
+ bench_new(dst1, src, coeff1, ff_opus_deemph_weights, MAX_SIZE);
}
void checkasm_check_opusdsp(void)
--
2.43.0.381.gb435a96ce8
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-04-25 7:54 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-24 8:54 [FFmpeg-devel] [PATCH v2] opusdsp: add ability to modify deemphasis constant Lynne
[not found] ` <NwEJ54_--3-9@lynne.ee-NwEJ9Lk----9>
2024-04-24 10:58 ` Lynne
2024-04-25 0:08 ` Michael Niedermayer
2024-04-25 7:53 ` Lynne
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git