/*
 *  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.
 */


/*
 * This file contains the function WebRtcSpl_LevinsonDurbin().
 * The description header can be found in signal_processing_library.h
 *
 */

#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/rtc_base/sanitizer.h"

#define SPL_LEVINSON_MAXORDER 20

int16_t RTC_NO_SANITIZE("signed-integer-overflow")  // bugs.webrtc.org/5486
WebRtcSpl_LevinsonDurbin(const int32_t* R, int16_t* A, int16_t* K,
                         size_t order)
{
    size_t i, j;
    // Auto-correlation coefficients in high precision
    int16_t R_hi[SPL_LEVINSON_MAXORDER + 1], R_low[SPL_LEVINSON_MAXORDER + 1];
    // LPC coefficients in high precision
    int16_t A_hi[SPL_LEVINSON_MAXORDER + 1], A_low[SPL_LEVINSON_MAXORDER + 1];
    // LPC coefficients for next iteration
    int16_t A_upd_hi[SPL_LEVINSON_MAXORDER + 1], A_upd_low[SPL_LEVINSON_MAXORDER + 1];
    // Reflection coefficient in high precision
    int16_t K_hi, K_low;
    // Prediction gain Alpha in high precision and with scale factor
    int16_t Alpha_hi, Alpha_low, Alpha_exp;
    int16_t tmp_hi, tmp_low;
    int32_t temp1W32, temp2W32, temp3W32;
    int16_t norm;

    // Normalize the autocorrelation R[0]...R[order+1]

    norm = WebRtcSpl_NormW32(R[0]);

    for (i = 0; i <= order; ++i)
    {
        temp1W32 = R[i] * (1 << norm);
        // UBSan: 12 * 268435456 cannot be represented in type 'int'

        // Put R in hi and low format
        R_hi[i] = (int16_t)(temp1W32 >> 16);
        R_low[i] = (int16_t)((temp1W32 - ((int32_t)R_hi[i] * 65536)) >> 1);
    }

    // K = A[1] = -R[1] / R[0]

    temp2W32 = R[1] * (1 << norm); // R[1] in Q31
    temp3W32 = WEBRTC_SPL_ABS_W32(temp2W32); // abs R[1]
    temp1W32 = WebRtcSpl_DivW32HiLow(temp3W32, R_hi[0], R_low[0]); // abs(R[1])/R[0] in Q31
    // Put back the sign on R[1]
    if (temp2W32 > 0)
    {
        temp1W32 = -temp1W32;
    }

    // Put K in hi and low format
    K_hi = (int16_t)(temp1W32 >> 16);
    K_low = (int16_t)((temp1W32 - ((int32_t)K_hi * 65536)) >> 1);

    // Store first reflection coefficient
    K[0] = K_hi;

    temp1W32 >>= 4;  // A[1] in Q27.

    // Put A[1] in hi and low format
    A_hi[1] = (int16_t)(temp1W32 >> 16);
    A_low[1] = (int16_t)((temp1W32 - ((int32_t)A_hi[1] * 65536)) >> 1);

    // Alpha = R[0] * (1-K^2)

    temp1W32 = ((K_hi * K_low >> 14) + K_hi * K_hi) * 2;  // = k^2 in Q31

    temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0
    temp1W32 = (int32_t)0x7fffffffL - temp1W32; // temp1W32 = (1 - K[0]*K[0]) in Q31

    // Store temp1W32 = 1 - K[0]*K[0] on hi and low format
    tmp_hi = (int16_t)(temp1W32 >> 16);
    tmp_low = (int16_t)((temp1W32 - ((int32_t)tmp_hi << 16)) >> 1);

    // Calculate Alpha in Q31
    temp1W32 = (R_hi[0] * tmp_hi + (R_hi[0] * tmp_low >> 15) +
        (R_low[0] * tmp_hi >> 15)) << 1;

    // Normalize Alpha and put it in hi and low format

    Alpha_exp = WebRtcSpl_NormW32(temp1W32);
    temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp);
    Alpha_hi = (int16_t)(temp1W32 >> 16);
    Alpha_low = (int16_t)((temp1W32 - ((int32_t)Alpha_hi << 16)) >> 1);

    // Perform the iterative calculations in the Levinson-Durbin algorithm

    for (i = 2; i <= order; i++)
    {
        /*                    ----
         temp1W32 =  R[i] + > R[j]*A[i-j]
         /
         ----
         j=1..i-1
         */

        temp1W32 = 0;

        for (j = 1; j < i; j++)
        {
          // temp1W32 is in Q31
          temp1W32 += (R_hi[j] * A_hi[i - j] * 2) +
              (((R_hi[j] * A_low[i - j] >> 15) +
              (R_low[j] * A_hi[i - j] >> 15)) * 2);
        }

        temp1W32 = temp1W32 * 16;
        temp1W32 += ((int32_t)R_hi[i] * 65536)
                + WEBRTC_SPL_LSHIFT_W32((int32_t)R_low[i], 1);

        // K = -temp1W32 / Alpha
        temp2W32 = WEBRTC_SPL_ABS_W32(temp1W32); // abs(temp1W32)
        temp3W32 = WebRtcSpl_DivW32HiLow(temp2W32, Alpha_hi, Alpha_low); // abs(temp1W32)/Alpha

        // Put the sign of temp1W32 back again
        if (temp1W32 > 0)
        {
            temp3W32 = -temp3W32;
        }

        // Use the Alpha shifts from earlier to de-normalize
        norm = WebRtcSpl_NormW32(temp3W32);
        if ((Alpha_exp <= norm) || (temp3W32 == 0))
        {
            temp3W32 = temp3W32 * (1 << Alpha_exp);
        } else
        {
            if (temp3W32 > 0)
            {
                temp3W32 = (int32_t)0x7fffffffL;
            } else
            {
                temp3W32 = (int32_t)0x80000000L;
            }
        }

        // Put K on hi and low format
        K_hi = (int16_t)(temp3W32 >> 16);
        K_low = (int16_t)((temp3W32 - ((int32_t)K_hi * 65536)) >> 1);

        // Store Reflection coefficient in Q15
        K[i - 1] = K_hi;

        // Test for unstable filter.
        // If unstable return 0 and let the user decide what to do in that case

        if ((int32_t)WEBRTC_SPL_ABS_W16(K_hi) > (int32_t)32750)
        {
            return 0; // Unstable filter
        }

        /*
         Compute updated LPC coefficient: Anew[i]
         Anew[j]= A[j] + K*A[i-j]   for j=1..i-1
         Anew[i]= K
         */

        for (j = 1; j < i; j++)
        {
            // temp1W32 = A[j] in Q27
            temp1W32 = (int32_t)A_hi[j] * 65536
                    + WEBRTC_SPL_LSHIFT_W32((int32_t)A_low[j],1);

            // temp1W32 += K*A[i-j] in Q27
            temp1W32 += (K_hi * A_hi[i - j] + (K_hi * A_low[i - j] >> 15) +
                (K_low * A_hi[i - j] >> 15)) * 2;

            // Put Anew in hi and low format
            A_upd_hi[j] = (int16_t)(temp1W32 >> 16);
            A_upd_low[j] = (int16_t)(
                (temp1W32 - ((int32_t)A_upd_hi[j] * 65536)) >> 1);
        }

        // temp3W32 = K in Q27 (Convert from Q31 to Q27)
        temp3W32 >>= 4;

        // Store Anew in hi and low format
        A_upd_hi[i] = (int16_t)(temp3W32 >> 16);
        A_upd_low[i] = (int16_t)(
            (temp3W32 - ((int32_t)A_upd_hi[i] * 65536)) >> 1);

        // Alpha = Alpha * (1-K^2)

        temp1W32 = ((K_hi * K_low >> 14) + K_hi * K_hi) * 2;  // K*K in Q31

        temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0
        temp1W32 = (int32_t)0x7fffffffL - temp1W32; // 1 - K*K  in Q31

        // Convert 1- K^2 in hi and low format
        tmp_hi = (int16_t)(temp1W32 >> 16);
        tmp_low = (int16_t)((temp1W32 - ((int32_t)tmp_hi << 16)) >> 1);

        // Calculate Alpha = Alpha * (1-K^2) in Q31
        temp1W32 = (Alpha_hi * tmp_hi + (Alpha_hi * tmp_low >> 15) +
            (Alpha_low * tmp_hi >> 15)) << 1;

        // Normalize Alpha and store it on hi and low format

        norm = WebRtcSpl_NormW32(temp1W32);
        temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm);

        Alpha_hi = (int16_t)(temp1W32 >> 16);
        Alpha_low = (int16_t)((temp1W32 - ((int32_t)Alpha_hi << 16)) >> 1);

        // Update the total normalization of Alpha
        Alpha_exp = Alpha_exp + norm;

        // Update A[]

        for (j = 1; j <= i; j++)
        {
            A_hi[j] = A_upd_hi[j];
            A_low[j] = A_upd_low[j];
        }
    }

    /*
     Set A[0] to 1.0 and store the A[i] i=1...order in Q12
     (Convert from Q27 and use rounding)
     */

    A[0] = 4096;

    for (i = 1; i <= order; i++)
    {
        // temp1W32 in Q27
        temp1W32 = (int32_t)A_hi[i] * 65536
                + WEBRTC_SPL_LSHIFT_W32((int32_t)A_low[i], 1);
        // Round and store upper word
        A[i] = (int16_t)(((temp1W32 * 2) + 32768) >> 16);
    }
    return 1; // Stable filters
}
