1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
2470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Use of this source code is governed by a BSD-style license
5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  that can be found in the LICENSE file in the root of the source
6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  tree. An additional intellectual property rights grant can be found
7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  in the file PATENTS.  All contributing project authors may
8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  be found in the AUTHORS file in the root of the source tree.
9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
11470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/******************************************************************
12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com iLBC Speech Coder ANSI-C Source Code
14470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIlbcfix_HpInput.c
16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
17470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com******************************************************************/
18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "defines.h"
20470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*----------------------------------------------------------------*
22470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  high-pass filter of input with *0.5 and saturation
23470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *---------------------------------------------------------------*/
24470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
25470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid WebRtcIlbcfix_HpInput(
260946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t *signal,     /* (i/o) signal vector */
270946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t *ba,      /* (i)   B- and A-coefficients (2:nd order)
28470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                                                   {b[0] b[1] b[2] -a[1] -a[2]} a[0]
29470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                                                   is assumed to be 1.0 */
300946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t *y,      /* (i/o) Filter state yhi[n-1] ylow[n-1]
31470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                                                   yhi[n-2] ylow[n-2] */
320946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t *x,      /* (i/o) Filter state x[n-1] x[n-2] */
33dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting    size_t len)      /* (i)   Number of samples to filter */
34470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
35dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  size_t i;
360946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t tmpW32;
370946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t tmpW32b;
38470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
39470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (i=0; i<len; i++) {
40470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
41470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /*
42470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]
43470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        + (-a[1])*y[i-1] + (-a[2])*y[i-2];
44470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    */
45470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
46ba97ea69f0b8bb73a837869211627b705eac8f98bjornv@webrtc.org    tmpW32 = y[1] * ba[3];  /* (-a[1])*y[i-1] (low part) */
47ba97ea69f0b8bb73a837869211627b705eac8f98bjornv@webrtc.org    tmpW32 += y[3] * ba[4];  /* (-a[2])*y[i-2] (low part) */
48470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    tmpW32 = (tmpW32>>15);
49ba97ea69f0b8bb73a837869211627b705eac8f98bjornv@webrtc.org    tmpW32 += y[0] * ba[3];  /* (-a[1])*y[i-1] (high part) */
50ba97ea69f0b8bb73a837869211627b705eac8f98bjornv@webrtc.org    tmpW32 += y[2] * ba[4];  /* (-a[2])*y[i-2] (high part) */
51470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    tmpW32 = (tmpW32<<1);
52470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
53ba97ea69f0b8bb73a837869211627b705eac8f98bjornv@webrtc.org    tmpW32 += signal[i] * ba[0];  /* b[0]*x[0] */
54ba97ea69f0b8bb73a837869211627b705eac8f98bjornv@webrtc.org    tmpW32 += x[0] * ba[1];  /* b[1]*x[i-1] */
55ba97ea69f0b8bb73a837869211627b705eac8f98bjornv@webrtc.org    tmpW32 += x[1] * ba[2];  /* b[2]*x[i-2] */
56470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
57470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Update state (input part) */
58470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    x[1] = x[0];
59470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    x[0] = signal[i];
60470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
61470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Rounding in Q(12+1), i.e. add 2^12 */
62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    tmpW32b = tmpW32 + 4096;
63470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
64470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Saturate (to 2^28) so that the HP filtered signal does not overflow */
650946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    tmpW32b = WEBRTC_SPL_SAT((int32_t)268435455, tmpW32b, (int32_t)-268435456);
66470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
67470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Convert back to Q0 and multiply with 0.5 */
6878ea06dd34a584acad4a2cf2142de218cb06eef4bjornv@webrtc.org    signal[i] = (int16_t)(tmpW32b >> 13);
69470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
70470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Update state (filtered part) */
71470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    y[2] = y[0];
72470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    y[3] = y[1];
73470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
74470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* upshift tmpW32 by 3 with saturation */
75470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (tmpW32>268435455) {
76470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      tmpW32 = WEBRTC_SPL_WORD32_MAX;
77470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    } else if (tmpW32<-268435456) {
78470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      tmpW32 = WEBRTC_SPL_WORD32_MIN;
79470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    } else {
804ab23d0e8f468d9f1e3ce4ffb50df070d8d06c6dbjornv@webrtc.org      tmpW32 <<= 3;
81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
830946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    y[0] = (int16_t)(tmpW32 >> 16);
844ab23d0e8f468d9f1e3ce4ffb50df070d8d06c6dbjornv@webrtc.org    y[1] = (int16_t)((tmpW32 - (y[0] << 16)) >> 1);
85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
86470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return;
88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
89