1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This file contains the function WebRtcSpl_AutoCorrToReflCoef().
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * The description header can be found in signal_processing_library.h
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
18f24ac5923cbe5e806fac59a0d15e32567553ce8epbos@webrtc.org#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
2045a3434299d78b2084a2d765c51c76c165b410cepbos@webrtc.orgvoid WebRtcSpl_AutoCorrToReflCoef(const int32_t *R, int use_order, int16_t *K)
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int i, n;
23c49ec1327c1d956c6c889cf1f32a7f9920d76149pbos@webrtc.org    int16_t tmp;
2445a3434299d78b2084a2d765c51c76c165b410cepbos@webrtc.org    const int32_t *rptr;
25c49ec1327c1d956c6c889cf1f32a7f9920d76149pbos@webrtc.org    int32_t L_num, L_den;
26c49ec1327c1d956c6c889cf1f32a7f9920d76149pbos@webrtc.org    int16_t *acfptr, *pptr, *wptr, *p1ptr, *w1ptr, ACF[WEBRTC_SPL_MAX_LPC_ORDER],
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            P[WEBRTC_SPL_MAX_LPC_ORDER], W[WEBRTC_SPL_MAX_LPC_ORDER];
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Initialize loop and pointers.
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    acfptr = ACF;
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    rptr = R;
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    pptr = P;
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    p1ptr = &P[1];
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    w1ptr = &W[1];
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    wptr = w1ptr;
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // First loop; n=0. Determine shifting.
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    tmp = WebRtcSpl_NormW32(*R);
39c49ec1327c1d956c6c889cf1f32a7f9920d76149pbos@webrtc.org    *acfptr = (int16_t)((*rptr++ << tmp) >> 16);
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    *pptr++ = *acfptr++;
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Initialize ACF, P and W.
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (i = 1; i <= use_order; i++)
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
45c49ec1327c1d956c6c889cf1f32a7f9920d76149pbos@webrtc.org        *acfptr = (int16_t)((*rptr++ << tmp) >> 16);
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        *wptr++ = *acfptr;
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        *pptr++ = *acfptr++;
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Compute reflection coefficients.
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (n = 1; n <= use_order; n++, K++)
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        tmp = WEBRTC_SPL_ABS_W16(*p1ptr);
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (*P < tmp)
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            for (i = n; i <= use_order; i++)
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                *K++ = 0;
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return;
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Division: WebRtcSpl_div(tmp, *P)
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        *K = 0;
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (tmp != 0)
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            L_num = tmp;
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            L_den = *P;
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            i = 15;
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            while (i--)
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                (*K) <<= 1;
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                L_num <<= 1;
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                if (L_num >= L_den)
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                {
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    L_num -= L_den;
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    (*K)++;
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                }
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if (*p1ptr > 0)
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                *K = -*K;
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Last iteration; don't do Schur recursion.
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (n == use_order)
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return;
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Schur recursion.
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        pptr = P;
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        wptr = w1ptr;
90c49ec1327c1d956c6c889cf1f32a7f9920d76149pbos@webrtc.org        tmp = (int16_t)(((int32_t)*p1ptr * (int32_t)*K + 16384) >> 15);
91347671c843ed5c93d25bf1a23f9295d35ce3df4abjornv@webrtc.org        *pptr = WebRtcSpl_AddSatW16(*pptr, tmp);
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        pptr++;
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        for (i = 1; i <= use_order - n; i++)
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
95c49ec1327c1d956c6c889cf1f32a7f9920d76149pbos@webrtc.org            tmp = (int16_t)(((int32_t)*wptr * (int32_t)*K + 16384) >> 15);
96347671c843ed5c93d25bf1a23f9295d35ce3df4abjornv@webrtc.org            *pptr = WebRtcSpl_AddSatW16(*(pptr + 1), tmp);
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            pptr++;
98c49ec1327c1d956c6c889cf1f32a7f9920d76149pbos@webrtc.org            tmp = (int16_t)(((int32_t)*pptr * (int32_t)*K + 16384) >> 15);
99347671c843ed5c93d25bf1a23f9295d35ce3df4abjornv@webrtc.org            *wptr = WebRtcSpl_AddSatW16(*wptr, tmp);
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            wptr++;
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
104