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  * This file contains the function WebRtcSpl_AutoCorrToReflCoef().
14  * The description header can be found in signal_processing_library.h
15  *
16  */
17 
18 #include "signal_processing_library.h"
19 
WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 * R,int use_order,WebRtc_Word16 * K)20 void WebRtcSpl_AutoCorrToReflCoef(G_CONST WebRtc_Word32 *R, int use_order, WebRtc_Word16 *K)
21 {
22     int i, n;
23     WebRtc_Word16 tmp;
24     G_CONST WebRtc_Word32 *rptr;
25     WebRtc_Word32 L_num, L_den;
26     WebRtc_Word16 *acfptr, *pptr, *wptr, *p1ptr, *w1ptr, ACF[WEBRTC_SPL_MAX_LPC_ORDER],
27             P[WEBRTC_SPL_MAX_LPC_ORDER], W[WEBRTC_SPL_MAX_LPC_ORDER];
28 
29     // Initialize loop and pointers.
30     acfptr = ACF;
31     rptr = R;
32     pptr = P;
33     p1ptr = &P[1];
34     w1ptr = &W[1];
35     wptr = w1ptr;
36 
37     // First loop; n=0. Determine shifting.
38     tmp = WebRtcSpl_NormW32(*R);
39     *acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16);
40     *pptr++ = *acfptr++;
41 
42     // Initialize ACF, P and W.
43     for (i = 1; i <= use_order; i++)
44     {
45         *acfptr = (WebRtc_Word16)((*rptr++ << tmp) >> 16);
46         *wptr++ = *acfptr;
47         *pptr++ = *acfptr++;
48     }
49 
50     // Compute reflection coefficients.
51     for (n = 1; n <= use_order; n++, K++)
52     {
53         tmp = WEBRTC_SPL_ABS_W16(*p1ptr);
54         if (*P < tmp)
55         {
56             for (i = n; i <= use_order; i++)
57                 *K++ = 0;
58 
59             return;
60         }
61 
62         // Division: WebRtcSpl_div(tmp, *P)
63         *K = 0;
64         if (tmp != 0)
65         {
66             L_num = tmp;
67             L_den = *P;
68             i = 15;
69             while (i--)
70             {
71                 (*K) <<= 1;
72                 L_num <<= 1;
73                 if (L_num >= L_den)
74                 {
75                     L_num -= L_den;
76                     (*K)++;
77                 }
78             }
79             if (*p1ptr > 0)
80                 *K = -*K;
81         }
82 
83         // Last iteration; don't do Schur recursion.
84         if (n == use_order)
85             return;
86 
87         // Schur recursion.
88         pptr = P;
89         wptr = w1ptr;
90         tmp = (WebRtc_Word16)(((WebRtc_Word32)*p1ptr * (WebRtc_Word32)*K + 16384) >> 15);
91         *pptr = WEBRTC_SPL_ADD_SAT_W16( *pptr, tmp );
92         pptr++;
93         for (i = 1; i <= use_order - n; i++)
94         {
95             tmp = (WebRtc_Word16)(((WebRtc_Word32)*wptr * (WebRtc_Word32)*K + 16384) >> 15);
96             *pptr = WEBRTC_SPL_ADD_SAT_W16( *(pptr+1), tmp );
97             pptr++;
98             tmp = (WebRtc_Word16)(((WebRtc_Word32)*pptr * (WebRtc_Word32)*K + 16384) >> 15);
99             *wptr = WEBRTC_SPL_ADD_SAT_W16( *wptr, tmp );
100             wptr++;
101         }
102     }
103 }
104