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 "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
19 
WebRtcSpl_AutoCorrToReflCoef(const int32_t * R,int use_order,int16_t * K)20 void WebRtcSpl_AutoCorrToReflCoef(const int32_t *R, int use_order, int16_t *K)
21 {
22     int i, n;
23     int16_t tmp;
24     const int32_t *rptr;
25     int32_t L_num, L_den;
26     int16_t *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 = (int16_t)((*rptr++ << tmp) >> 16);
40     *pptr++ = *acfptr++;
41 
42     // Initialize ACF, P and W.
43     for (i = 1; i <= use_order; i++)
44     {
45         *acfptr = (int16_t)((*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 = (int16_t)(((int32_t)*p1ptr * (int32_t)*K + 16384) >> 15);
91         *pptr = WebRtcSpl_AddSatW16(*pptr, tmp);
92         pptr++;
93         for (i = 1; i <= use_order - n; i++)
94         {
95             tmp = (int16_t)(((int32_t)*wptr * (int32_t)*K + 16384) >> 15);
96             *pptr = WebRtcSpl_AddSatW16(*(pptr + 1), tmp);
97             pptr++;
98             tmp = (int16_t)(((int32_t)*pptr * (int32_t)*K + 16384) >> 15);
99             *wptr = WebRtcSpl_AddSatW16(*wptr, tmp);
100             wptr++;
101         }
102     }
103 }
104