1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
2470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Use of this source code is governed by a BSD-style license
5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  that can be found in the LICENSE file in the root of the source
6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  tree. An additional intellectual property rights grant can be found
7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  in the file PATENTS.  All contributing project authors may
8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  be found in the AUTHORS file in the root of the source tree.
9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
11470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/******************************************************************
12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com iLBC Speech Coder ANSI-C Source Code
14470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIlbcfix_SimpleLpcAnalysis.c
16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
17470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com******************************************************************/
18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "defines.h"
20470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "window32_w32.h"
21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "bw_expand.h"
22470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "poly_to_lsf.h"
23470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "constants.h"
24470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
25470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*----------------------------------------------------------------*
26470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  lpc analysis (subrutine to LPCencode)
27470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *---------------------------------------------------------------*/
28470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
29470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid WebRtcIlbcfix_SimpleLpcAnalysis(
300946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t *lsf,   /* (o) lsf coefficients */
310946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    int16_t *data,   /* (i) new block of speech */
32eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.org    IlbcEncoder *iLBCenc_inst
33470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* (i/o) the encoder state structure */
34470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                     ) {
35470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  int k;
36470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  int scale;
37dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  size_t is;
380946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t stability;
39470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Stack based */
400946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t A[LPC_FILTERORDER + 1];
410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int32_t R[LPC_FILTERORDER + 1];
420946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t windowedData[BLOCKL_MAX];
430946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t rc[LPC_FILTERORDER];
44470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
45470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
46470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->lpc_buffer+is,data,iLBCenc_inst->blockl);
47470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
48470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* No lookahead, last window is asymmetric */
49470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
50470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (k = 0; k < iLBCenc_inst->lpc_n; k++) {
51470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
52470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    is = LPC_LOOKBACK;
53470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
54470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (k < (iLBCenc_inst->lpc_n - 1)) {
55470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
56470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      /* Hanning table WebRtcIlbcfix_kLpcWin[] is in Q15-domain so the output is right-shifted 15 */
57470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      WebRtcSpl_ElementwiseVectorMult(windowedData, iLBCenc_inst->lpc_buffer, WebRtcIlbcfix_kLpcWin, BLOCKL_MAX, 15);
58470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    } else {
59470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
60470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      /* Hanning table WebRtcIlbcfix_kLpcAsymWin[] is in Q15-domain so the output is right-shifted 15 */
61470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      WebRtcSpl_ElementwiseVectorMult(windowedData, iLBCenc_inst->lpc_buffer+is, WebRtcIlbcfix_kLpcAsymWin, BLOCKL_MAX, 15);
62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
63470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
64470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Compute autocorrelation */
65470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WebRtcSpl_AutoCorrelation(windowedData, BLOCKL_MAX, LPC_FILTERORDER, R, &scale);
66470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
67470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Window autocorrelation vector */
68470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WebRtcIlbcfix_Window32W32(R, R, WebRtcIlbcfix_kLpcLagWin, LPC_FILTERORDER + 1 );
69470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
70470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Calculate the A coefficients from the Autocorrelation using Levinson Durbin algorithm */
71470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    stability=WebRtcSpl_LevinsonDurbin(R, A, rc, LPC_FILTERORDER);
72470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
73470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /*
74470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       Set the filter to {1.0, 0.0, 0.0,...} if filter from Levinson Durbin algorithm is unstable
75470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       This should basically never happen...
76470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    */
77470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (stability!=1) {
78470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      A[0]=4096;
79470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      WebRtcSpl_MemSetW16(&A[1], 0, LPC_FILTERORDER);
80470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Bandwidth expand the filter coefficients */
830946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    WebRtcIlbcfix_BwExpand(A, A, (int16_t*)WebRtcIlbcfix_kLpcChirpSyntDenum, LPC_FILTERORDER+1);
84470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Convert from A to LSF representation */
86470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WebRtcIlbcfix_Poly2Lsf(lsf + k*LPC_FILTERORDER, A);
87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
90470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->lpc_buffer,
91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                        iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is, is);
92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return;
94470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
95