From e0f26246b08122cef31c1ac85f7ed228e2daca61 Mon Sep 17 00:00:00 2001
From: Jean-Marc Valin <jmvalin@jmvalin.ca>
Date: Sat, 14 Dec 2013 11:07:13 -0500
Subject: [PATCH] fixed-point: adds rounding to some shifts to eliminate bias

This reduces the peak decoding error by removing small (inaudible) spikes in
the error at the frame boundaries. These were due to the frequency-domain bias
ending up as a small pulse in the middle of the IMDCT overlap. None of this
was ever audible, but fixing it is still cleaner.
---
 celt/bands.c | 6 +++---
 celt/vq.c    | 8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/celt/bands.c b/celt/bands.c
index c6b5f0b89..73346445c 100644
--- a/celt/bands.c
+++ b/celt/bands.c
@@ -430,7 +430,7 @@ static void stereo_merge(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT
    {
       celt_norm r, l;
       /* Apply mid scaling (side is already scaled) */
-      l = MULT16_16_Q15(mid, X[j]);
+      l = MULT16_16_P15(mid, X[j]);
       r = Y[j];
       X[j] = EXTRACT16(PSHR32(MULT16_16(lgain, SUB16(l,r)), kl+1));
       Y[j] = EXTRACT16(PSHR32(MULT16_16(rgain, ADD16(l,r)), kr+1));
@@ -600,8 +600,8 @@ void haar1(celt_norm *X, int N0, int stride)
          opus_val32 tmp1, tmp2;
          tmp1 = MULT16_16(QCONST16(.70710678f,15), X[stride*2*j+i]);
          tmp2 = MULT16_16(QCONST16(.70710678f,15), X[stride*(2*j+1)+i]);
-         X[stride*2*j+i] = EXTRACT16(SHR32(ADD32(tmp1, tmp2), 15));
-         X[stride*(2*j+1)+i] = EXTRACT16(SHR32(SUB32(tmp1, tmp2), 15));
+         X[stride*2*j+i] = EXTRACT16(PSHR32(ADD32(tmp1, tmp2), 15));
+         X[stride*(2*j+1)+i] = EXTRACT16(PSHR32(SUB32(tmp1, tmp2), 15));
       }
 }
 
diff --git a/celt/vq.c b/celt/vq.c
index 9fac08456..189bf23bc 100644
--- a/celt/vq.c
+++ b/celt/vq.c
@@ -49,8 +49,8 @@ static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_
       celt_norm x1, x2;
       x1 = Xptr[0];
       x2 = Xptr[stride];
-      Xptr[stride] = EXTRACT16(SHR32(MULT16_16(c,x2) + MULT16_16(s,x1), 15));
-      *Xptr++      = EXTRACT16(SHR32(MULT16_16(c,x1) - MULT16_16(s,x2), 15));
+      Xptr[stride] = EXTRACT16(PSHR32(MULT16_16(c,x2) + MULT16_16(s,x1), 15));
+      *Xptr++      = EXTRACT16(PSHR32(MULT16_16(c,x1) - MULT16_16(s,x2), 15));
    }
    Xptr = &X[len-2*stride-1];
    for (i=len-2*stride-1;i>=0;i--)
@@ -58,8 +58,8 @@ static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_
       celt_norm x1, x2;
       x1 = Xptr[0];
       x2 = Xptr[stride];
-      Xptr[stride] = EXTRACT16(SHR32(MULT16_16(c,x2) + MULT16_16(s,x1), 15));
-      *Xptr--      = EXTRACT16(SHR32(MULT16_16(c,x1) - MULT16_16(s,x2), 15));
+      Xptr[stride] = EXTRACT16(PSHR32(MULT16_16(c,x2) + MULT16_16(s,x1), 15));
+      *Xptr--      = EXTRACT16(PSHR32(MULT16_16(c,x1) - MULT16_16(s,x2), 15));
    }
 }
 
-- 
GitLab