blob: 6edf921650bddf7724e8ee477a3f4cd6e755d364 [file] [log] [blame]
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_FrameClassify.c
******************************************************************/
#include "modules/audio_coding/codecs/ilbc/defines.h"
#include "modules/audio_coding/codecs/ilbc/constants.h"
/*----------------------------------------------------------------*
* Classification of subframes to localize start state
*---------------------------------------------------------------*/
size_t WebRtcIlbcfix_FrameClassify(
/* (o) Index to the max-energy sub frame */
IlbcEncoder *iLBCenc_inst,
/* (i/o) the encoder state structure */
int16_t *residualFIX /* (i) lpc residual signal */
){
int16_t max, scale;
int32_t ssqEn[NSUB_MAX-1];
int16_t *ssqPtr;
int32_t *seqEnPtr;
int32_t maxW32;
int16_t scale1;
size_t pos;
size_t n;
/*
Calculate the energy of each of the 80 sample blocks
in the draft the 4 first and last samples are windowed with 1/5...4/5
and 4/5...1/5 respectively. To simplify for the fixpoint we have changed
this to 0 0 1 1 and 1 1 0 0
*/
max = WebRtcSpl_MaxAbsValueW16(residualFIX, iLBCenc_inst->blockl);
scale = WebRtcSpl_GetSizeInBits((uint32_t)(max * max));
/* Scale to maximum 24 bits so that it won't overflow for 76 samples */
scale = scale-24;
scale1 = WEBRTC_SPL_MAX(0, scale);
/* Calculate energies */
ssqPtr=residualFIX + 2;
seqEnPtr=ssqEn;
for (n=(iLBCenc_inst->nsub-1); n>0; n--) {
(*seqEnPtr) = WebRtcSpl_DotProductWithScale(ssqPtr, ssqPtr, 76, scale1);
ssqPtr += 40;
seqEnPtr++;
}
/* Scale to maximum 20 bits in order to allow for the 11 bit window */
maxW32 = WebRtcSpl_MaxValueW32(ssqEn, iLBCenc_inst->nsub - 1);
scale = WebRtcSpl_GetSizeInBits(maxW32) - 20;
scale1 = WEBRTC_SPL_MAX(0, scale);
/* Window each 80 block with the ssqEn_winTbl window to give higher probability for
the blocks in the middle
*/
seqEnPtr=ssqEn;
if (iLBCenc_inst->mode==20) {
ssqPtr=(int16_t*)WebRtcIlbcfix_kStartSequenceEnrgWin+1;
} else {
ssqPtr=(int16_t*)WebRtcIlbcfix_kStartSequenceEnrgWin;
}
for (n=(iLBCenc_inst->nsub-1); n>0; n--) {
(*seqEnPtr)=WEBRTC_SPL_MUL(((*seqEnPtr)>>scale1), (*ssqPtr));
seqEnPtr++;
ssqPtr++;
}
/* Extract the best choise of start state */
pos = WebRtcSpl_MaxIndexW32(ssqEn, iLBCenc_inst->nsub - 1) + 1;
return(pos);
}