summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2016-08-14 17:56:45 -0400
committerJean-Marc Valin <jmvalin@jmvalin.ca>2016-08-14 17:56:45 -0400
commit11dba8d902983e271da4a7499ef56e4d7bd7111f (patch)
tree9fd86f24d2b7075e2c0be1a56b736d4da6a6545a
parentcd159fd1ec8ae64e6cd1b69854034560b5f1c419 (diff)
downloadopus-11dba8d902983e271da4a7499ef56e4d7bd7111f.tar.gz
Apply deemphasis to both channels in the same loop for the simple case
This makes the decoder ~2.5% faster on x86 because the stereo loop takes the same processing time as one mono loop due to the dependency chain
-rw-r--r--celt/celt_decoder.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/celt/celt_decoder.c b/celt/celt_decoder.c
index 43b876b8..e441d045 100644
--- a/celt/celt_decoder.c
+++ b/celt/celt_decoder.c
@@ -177,6 +177,36 @@ void opus_custom_decoder_destroy(CELTDecoder *st)
}
#endif /* CUSTOM_MODES */
+#ifndef CUSTOM_MODES
+/* Special case for stereo with no downsampling and no accumulation. This is
+ quite common and we can make it faster by processing both channels in the
+ same loop, reducing overhead due to the dependency loop in the IIR filter. */
+static void deemphasis_stereo_simple(celt_sig *in[], opus_val16 *pcm, int N, const opus_val16 coef0,
+ celt_sig *mem)
+{
+ celt_sig * OPUS_RESTRICT x0;
+ celt_sig * OPUS_RESTRICT x1;
+ celt_sig m0, m1;
+ int j;
+ x0=in[0];
+ x1=in[1];
+ m0 = mem[0];
+ m1 = mem[1];
+ for (j=0;j<N;j++)
+ {
+ celt_sig tmp0, tmp1;
+ /* Add VERY_SMALL to x[] first to reduce dependency chain. */
+ tmp0 = x0[j] + VERY_SMALL + m0;
+ tmp1 = x1[j] + VERY_SMALL + m1;
+ m0 = MULT16_32_Q15(coef0, tmp0);
+ m1 = MULT16_32_Q15(coef0, tmp1);
+ pcm[2*j ] = SCALEOUT(SIG2WORD16(tmp0));
+ pcm[2*j+1] = SCALEOUT(SIG2WORD16(tmp1));
+ }
+ mem[0] = m0;
+ mem[1] = m1;
+}
+#endif
#ifndef RESYNTH
static
@@ -190,6 +220,14 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
opus_val16 coef0;
VARDECL(celt_sig, scratch);
SAVE_STACK;
+#ifndef CUSTOM_MODES
+ /* Short version for common case. */
+ if (downsample == 1 && C == 2 && !accum)
+ {
+ deemphasis_stereo_simple(in, pcm, N, coef[0], mem);
+ return;
+ }
+#endif
#ifndef FIXED_POINT
(void)accum;
celt_assert(accum==0);