File: chebyshev.c

package info (click to toggle)
xulrunner 24.8.1esr-2~deb7u1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 796,452 kB
  • sloc: cpp: 3,181,607; ansic: 1,641,175; python: 167,590; java: 128,022; asm: 118,009; xml: 75,870; sh: 70,457; makefile: 50,358; perl: 21,413; objc: 4,014; yacc: 2,066; pascal: 995; lex: 982; exp: 449; php: 244; lisp: 228; awk: 211; sed: 61; csh: 31; ada: 16; ruby: 3
file content (82 lines) | stat: -rw-r--r-- 3,052 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

/******************************************************************

 iLBC Speech Coder ANSI-C Source Code

 WebRtcIlbcfix_Chebyshev.c

******************************************************************/

#include "defines.h"
#include "constants.h"

/*------------------------------------------------------------------*
 *  Calculate the Chevyshev polynomial series
 *  F(w) = 2*exp(-j5w)*C(x)
 *   C(x) = (T_0(x) + f(1)T_1(x) + ... + f(4)T_1(x) + f(5)/2)
 *   T_i(x) is the i:th order Chebyshev polynomial
 *------------------------------------------------------------------*/

WebRtc_Word16 WebRtcIlbcfix_Chebyshev(
    /* (o) Result of C(x) */
    WebRtc_Word16 x,  /* (i) Value to the Chevyshev polynomial */
    WebRtc_Word16 *f  /* (i) The coefficients in the polynomial */
                                      ) {
  WebRtc_Word16 b1_high, b1_low; /* Use the high, low format to increase the accuracy */
  WebRtc_Word32 b2;
  WebRtc_Word32 tmp1W32;
  WebRtc_Word32 tmp2W32;
  int i;

  b2 = (WebRtc_Word32)0x1000000; /* b2 = 1.0 (Q23) */
  /* Calculate b1 = 2*x + f[1] */
  tmp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)x, 10);
  tmp1W32 += WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)f[1], 14);

  for (i = 2; i < 5; i++) {
    tmp2W32 = tmp1W32;

    /* Split b1 (in tmp1W32) into a high and low part */
    b1_high = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp1W32, 16);
    b1_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp1W32-WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)b1_high),16), 1);

    /* Calculate 2*x*b1-b2+f[i] */
    tmp1W32 = WEBRTC_SPL_LSHIFT_W32( (WEBRTC_SPL_MUL_16_16(b1_high, x) +
                                      WEBRTC_SPL_MUL_16_16_RSFT(b1_low, x, 15)), 2);

    tmp1W32 -= b2;
    tmp1W32 += WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)f[i], 14);

    /* Update b2 for next round */
    b2 = tmp2W32;
  }

  /* Split b1 (in tmp1W32) into a high and low part */
  b1_high = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp1W32, 16);
  b1_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp1W32-WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)b1_high),16), 1);

  /* tmp1W32 = x*b1 - b2 + f[i]/2 */
  tmp1W32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(b1_high, x), 1) +
      WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16_RSFT(b1_low, x, 15), 1);

  tmp1W32 -= b2;
  tmp1W32 += WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)f[i], 13);

  /* Handle overflows and set to maximum or minimum WebRtc_Word16 instead */
  if (tmp1W32>((WebRtc_Word32)33553408)) {
    return(WEBRTC_SPL_WORD16_MAX);
  } else if (tmp1W32<((WebRtc_Word32)-33554432)) {
    return(WEBRTC_SPL_WORD16_MIN);
  } else {
    return((WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp1W32, 10));
  }
}