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