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