Home | History | Annotate | Download | only in ilbc
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 /******************************************************************
     12 
     13  iLBC Speech Coder ANSI-C Source Code
     14 
     15  WebRtcIlbcfix_Chebyshev.c
     16 
     17 ******************************************************************/
     18 
     19 #include "defines.h"
     20 #include "constants.h"
     21 
     22 /*------------------------------------------------------------------*
     23  *  Calculate the Chevyshev polynomial series
     24  *  F(w) = 2*exp(-j5w)*C(x)
     25  *   C(x) = (T_0(x) + f(1)T_1(x) + ... + f(4)T_1(x) + f(5)/2)
     26  *   T_i(x) is the i:th order Chebyshev polynomial
     27  *------------------------------------------------------------------*/
     28 
     29 int16_t WebRtcIlbcfix_Chebyshev(
     30     /* (o) Result of C(x) */
     31     int16_t x,  /* (i) Value to the Chevyshev polynomial */
     32     int16_t *f  /* (i) The coefficients in the polynomial */
     33                                       ) {
     34   int16_t b1_high, b1_low; /* Use the high, low format to increase the accuracy */
     35   int32_t b2;
     36   int32_t tmp1W32;
     37   int32_t tmp2W32;
     38   int i;
     39 
     40   b2 = (int32_t)0x1000000; /* b2 = 1.0 (Q23) */
     41   /* Calculate b1 = 2*x + f[1] */
     42   tmp1W32 = (x << 10) + (f[1] << 14);
     43 
     44   for (i = 2; i < 5; i++) {
     45     tmp2W32 = tmp1W32;
     46 
     47     /* Split b1 (in tmp1W32) into a high and low part */
     48     b1_high = (int16_t)(tmp1W32 >> 16);
     49     b1_low = (int16_t)((tmp1W32 - ((int32_t)b1_high << 16)) >> 1);
     50 
     51     /* Calculate 2*x*b1-b2+f[i] */
     52     tmp1W32 = ((b1_high * x + ((b1_low * x) >> 15)) << 2) - b2 + (f[i] << 14);
     53 
     54     /* Update b2 for next round */
     55     b2 = tmp2W32;
     56   }
     57 
     58   /* Split b1 (in tmp1W32) into a high and low part */
     59   b1_high = (int16_t)(tmp1W32 >> 16);
     60   b1_low = (int16_t)((tmp1W32 - ((int32_t)b1_high << 16)) >> 1);
     61 
     62   /* tmp1W32 = x*b1 - b2 + f[i]/2 */
     63   tmp1W32 = ((b1_high * x) << 1) + (((b1_low * x) >> 15) << 1) -
     64       b2 + (f[i] << 13);
     65 
     66   /* Handle overflows and set to maximum or minimum int16_t instead */
     67   if (tmp1W32>((int32_t)33553408)) {
     68     return(WEBRTC_SPL_WORD16_MAX);
     69   } else if (tmp1W32<((int32_t)-33554432)) {
     70     return(WEBRTC_SPL_WORD16_MIN);
     71   } else {
     72     return (int16_t)(tmp1W32 >> 10);
     73   }
     74 }
     75