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 iLBC Speech Coder ANSI-C Source Code
14
15 WebRtcIlbcfix_SimpleLpcAnalysis.c
16
17******************************************************************/
18
19#include "defines.h"
20#include "window32_w32.h"
21#include "bw_expand.h"
22#include "poly_to_lsf.h"
23#include "constants.h"
24
25/*----------------------------------------------------------------*
26 *  lpc analysis (subrutine to LPCencode)
27 *---------------------------------------------------------------*/
28
29void WebRtcIlbcfix_SimpleLpcAnalysis(
30    int16_t *lsf,   /* (o) lsf coefficients */
31    int16_t *data,   /* (i) new block of speech */
32    iLBC_Enc_Inst_t *iLBCenc_inst
33    /* (i/o) the encoder state structure */
34                                     ) {
35  int k;
36  int scale;
37  int16_t is;
38  int16_t stability;
39  /* Stack based */
40  int16_t A[LPC_FILTERORDER + 1];
41  int32_t R[LPC_FILTERORDER + 1];
42  int16_t windowedData[BLOCKL_MAX];
43  int16_t rc[LPC_FILTERORDER];
44
45  is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
46  WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->lpc_buffer+is,data,iLBCenc_inst->blockl);
47
48  /* No lookahead, last window is asymmetric */
49
50  for (k = 0; k < iLBCenc_inst->lpc_n; k++) {
51
52    is = LPC_LOOKBACK;
53
54    if (k < (iLBCenc_inst->lpc_n - 1)) {
55
56      /* Hanning table WebRtcIlbcfix_kLpcWin[] is in Q15-domain so the output is right-shifted 15 */
57      WebRtcSpl_ElementwiseVectorMult(windowedData, iLBCenc_inst->lpc_buffer, WebRtcIlbcfix_kLpcWin, BLOCKL_MAX, 15);
58    } else {
59
60      /* Hanning table WebRtcIlbcfix_kLpcAsymWin[] is in Q15-domain so the output is right-shifted 15 */
61      WebRtcSpl_ElementwiseVectorMult(windowedData, iLBCenc_inst->lpc_buffer+is, WebRtcIlbcfix_kLpcAsymWin, BLOCKL_MAX, 15);
62    }
63
64    /* Compute autocorrelation */
65    WebRtcSpl_AutoCorrelation(windowedData, BLOCKL_MAX, LPC_FILTERORDER, R, &scale);
66
67    /* Window autocorrelation vector */
68    WebRtcIlbcfix_Window32W32(R, R, WebRtcIlbcfix_kLpcLagWin, LPC_FILTERORDER + 1 );
69
70    /* Calculate the A coefficients from the Autocorrelation using Levinson Durbin algorithm */
71    stability=WebRtcSpl_LevinsonDurbin(R, A, rc, LPC_FILTERORDER);
72
73    /*
74       Set the filter to {1.0, 0.0, 0.0,...} if filter from Levinson Durbin algorithm is unstable
75       This should basically never happen...
76    */
77    if (stability!=1) {
78      A[0]=4096;
79      WebRtcSpl_MemSetW16(&A[1], 0, LPC_FILTERORDER);
80    }
81
82    /* Bandwidth expand the filter coefficients */
83    WebRtcIlbcfix_BwExpand(A, A, (int16_t*)WebRtcIlbcfix_kLpcChirpSyntDenum, LPC_FILTERORDER+1);
84
85    /* Convert from A to LSF representation */
86    WebRtcIlbcfix_Poly2Lsf(lsf + k*LPC_FILTERORDER, A);
87  }
88
89  is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
90  WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->lpc_buffer,
91                        iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is, is);
92
93  return;
94}
95