Refactored the pitch filter function in iSAC-fix. One important purpose is to prepare the function for assembly optimization in ARM platforms.
Note that, (1) The main change is a new function PitchFilter() replacing a couple of common code blocks. Next step will be the assembly coding of this function in ARM. (2) Resulted code is not bit exact with the original. The only reason is replacing two saturation blocks (lines 197 and 208) for the case of "type == 2" with the general case (line 147 and 159). The change makes the code more consistent, and I think the original code might just be a bug. I raised the issue in an email to Turaj and Bjorn last week. Listening test might be needed. I will send the resulted files to Turaj for this purpose. (3) I used Astyle to make the code more stylish, but didn't try extra effort to correct all the code style details. Local code style consistency was considered for new code. So this is not a full and final refactor project (will leave that to future refactoring). Review URL: https://webrtc-codereview.appspot.com/573009 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2344 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
5b4f36db88
commit
c3b2683bf4
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 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
|
||||
@ -9,25 +9,30 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* pitch_estimatorfilter.c
|
||||
* pitch_filter.c
|
||||
*
|
||||
* Pitch filter functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "common_audio/signal_processing/include/signal_processing_library.h"
|
||||
#include "modules/audio_coding/codecs/iSAC/fix/source/pitch_estimator.h"
|
||||
#include "modules/audio_coding/codecs/iSAC/fix/source/settings.h"
|
||||
#include "modules/audio_coding/codecs/iSAC/fix/source/structs.h"
|
||||
|
||||
#include "pitch_estimator.h"
|
||||
// Number of segments in a pitch subframe.
|
||||
static const int kSegments = 5;
|
||||
|
||||
// A division factor of 1/5 in Q15.
|
||||
static const WebRtc_Word16 kDivFactor = 6553;
|
||||
|
||||
/* Filter coefficicients in Q15 */
|
||||
// Filter coefficicients in Q15.
|
||||
static const WebRtc_Word16 kDampFilter[PITCH_DAMPORDER] = {
|
||||
-2294, 8192, 20972, 8192, -2294
|
||||
};
|
||||
|
||||
/* Interpolation coefficients; generated by design_pitch_filter.m.
|
||||
* Coefficients are stored in Q14.
|
||||
*/
|
||||
// Interpolation coefficients; generated by design_pitch_filter.m.
|
||||
// Coefficients are stored in Q14.
|
||||
static const WebRtc_Word16 kIntrpCoef[PITCH_FRACS][PITCH_FRACORDER] = {
|
||||
{-367, 1090, -2706, 9945, 10596, -3318, 1626, -781, 287},
|
||||
{-325, 953, -2292, 7301, 12963, -3320, 1570, -743, 271},
|
||||
@ -39,293 +44,277 @@ static const WebRtc_Word16 kIntrpCoef[PITCH_FRACS][PITCH_FRACORDER] = {
|
||||
{ 271, -743, 1570, -3320, 12963, 7301, -2292, 953, -325}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static __inline WebRtc_Word32 CalcLrIntQ(WebRtc_Word32 fixVal, WebRtc_Word16 qDomain) {
|
||||
static __inline WebRtc_Word32 CalcLrIntQ(WebRtc_Word32 fixVal,
|
||||
WebRtc_Word16 qDomain) {
|
||||
WebRtc_Word32 intgr;
|
||||
WebRtc_Word32 roundVal;
|
||||
|
||||
roundVal = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, qDomain-1);
|
||||
intgr = WEBRTC_SPL_RSHIFT_W32(fixVal+roundVal, qDomain);
|
||||
roundVal = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, qDomain - 1);
|
||||
intgr = WEBRTC_SPL_RSHIFT_W32(fixVal + roundVal, qDomain);
|
||||
|
||||
return intgr;
|
||||
}
|
||||
|
||||
void WebRtcIsacfix_PitchFilter(WebRtc_Word16 *indatQQ, /* Q10 if type is 1 or 4, Q0 if type is 2 */
|
||||
WebRtc_Word16 *outdatQQ,
|
||||
PitchFiltstr *pfp,
|
||||
WebRtc_Word16 *lagsQ7,
|
||||
WebRtc_Word16 *gainsQ12,
|
||||
WebRtc_Word16 type)
|
||||
{
|
||||
int k, n, m, ind;
|
||||
// Pitch filtering.
|
||||
// TODO(Turaj): Add descriptions of input and output parameters.
|
||||
static void PitchFilter(int loopNumber,
|
||||
WebRtc_Word16 gain,
|
||||
int index,
|
||||
WebRtc_Word16 sign,
|
||||
WebRtc_Word16* inputState,
|
||||
WebRtc_Word16* outputBuf2,
|
||||
const WebRtc_Word16* coefficient,
|
||||
WebRtc_Word16* inputBuf,
|
||||
WebRtc_Word16* outputBuf,
|
||||
int* index2) {
|
||||
int i = 0, j = 0; // Loop counters.
|
||||
WebRtc_Word16* ubufQQpos2 = &outputBuf2[PITCH_BUFFSIZE - (index + 2)];
|
||||
WebRtc_Word16 tmpW16 = 0;
|
||||
|
||||
for (i = 0; i < loopNumber; i++) {
|
||||
WebRtc_Word32 tmpW32 = 0;
|
||||
|
||||
// Filter to get fractional pitch.
|
||||
for (j = 0; j < PITCH_FRACORDER; j++) {
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQpos2[*index2 + j], coefficient[j]);
|
||||
}
|
||||
|
||||
// Saturate to avoid overflow in tmpW16.
|
||||
tmpW32 = WEBRTC_SPL_SAT(536862719, tmpW32, -536879104);
|
||||
tmpW32 += 8192;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 14);
|
||||
|
||||
// Shift low pass filter state.
|
||||
memmove(&inputState[1], &inputState[0],
|
||||
(PITCH_DAMPORDER - 1) * sizeof(WebRtc_Word16));
|
||||
inputState[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
|
||||
gain, tmpW16, 12);
|
||||
|
||||
// Low pass filter.
|
||||
tmpW32 = 0;
|
||||
// TODO(kma): Define a static inline function WebRtcSpl_DotProduct()
|
||||
// in spl_inl.h to replace this and other similar loops.
|
||||
for (j = 0; j < PITCH_DAMPORDER; j++) {
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(inputState[j], kDampFilter[j]);
|
||||
}
|
||||
|
||||
// Saturate to avoid overflow in tmpW16.
|
||||
tmpW32 = WEBRTC_SPL_SAT(1073725439, tmpW32, -1073758208);
|
||||
tmpW32 += 16384;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 15);
|
||||
|
||||
// Subtract from input and update buffer.
|
||||
tmpW32 = inputBuf[*index2] - WEBRTC_SPL_MUL_16_16(sign, tmpW16);
|
||||
outputBuf[*index2] = WebRtcSpl_SatW32ToW16(tmpW32);
|
||||
tmpW32 = inputBuf[*index2] + outputBuf[*index2];
|
||||
outputBuf2[*index2 + PITCH_BUFFSIZE] = WebRtcSpl_SatW32ToW16(tmpW32);
|
||||
|
||||
(*index2)++;
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcIsacfix_PitchFilter(WebRtc_Word16* indatQQ, // Q10 if type is 1 or 4,
|
||||
// Q0 if type is 2.
|
||||
WebRtc_Word16* outdatQQ,
|
||||
PitchFiltstr* pfp,
|
||||
WebRtc_Word16* lagsQ7,
|
||||
WebRtc_Word16* gainsQ12,
|
||||
WebRtc_Word16 type) {
|
||||
int k, ind, cnt;
|
||||
WebRtc_Word16 sign = 1;
|
||||
WebRtc_Word16 inystateQQ[PITCH_DAMPORDER];
|
||||
WebRtc_Word16 ubufQQ[PITCH_INTBUFFSIZE+QLOOKAHEAD];
|
||||
WebRtc_Word16 Gain = 21299; /* 1.3 in Q14 */
|
||||
WebRtc_Word16 DivFactor = 6553; /* 0.2 in Q15 */
|
||||
WebRtc_Word16 oldLagQ7, oldGainQ12,
|
||||
lagdeltaQ7, curLagQ7,
|
||||
gaindeltaQ12, curGainQ12;
|
||||
WebRtc_Word16 tmpW16, indW16=0, frcQQ, cnt=0, pos, pos2;
|
||||
const WebRtc_Word16 *fracoeffQQ=NULL;
|
||||
WebRtc_Word16 ubufQQ[PITCH_INTBUFFSIZE + QLOOKAHEAD];
|
||||
const WebRtc_Word16 Gain = 21299; // 1.3 in Q14
|
||||
WebRtc_Word16 oldLagQ7;
|
||||
WebRtc_Word16 oldGainQ12, lagdeltaQ7, curLagQ7, gaindeltaQ12, curGainQ12;
|
||||
int indW32 = 0, frcQQ = 0;
|
||||
WebRtc_Word32 tmpW32;
|
||||
const WebRtc_Word16* fracoeffQQ = NULL;
|
||||
|
||||
if (type==4)
|
||||
sign = -1;
|
||||
// Set up buffer and states.
|
||||
memcpy(ubufQQ, pfp->ubufQQ, sizeof(pfp->ubufQQ));
|
||||
memcpy(inystateQQ, pfp->ystateQQ, sizeof(inystateQQ));
|
||||
|
||||
/* Set up buffer and states */
|
||||
memcpy(ubufQQ, pfp->ubufQQ, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_BUFFSIZE));
|
||||
memcpy(inystateQQ, pfp->ystateQQ, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_DAMPORDER));
|
||||
|
||||
/* Get old lag and gain value from memory */
|
||||
// Get old lag and gain value from memory.
|
||||
oldLagQ7 = pfp->oldlagQ7;
|
||||
oldGainQ12 = pfp->oldgainQ12;
|
||||
|
||||
if (type==4) {
|
||||
/* make output more periodic */
|
||||
/* Fixed 1.3 = 21299 in Q14 */
|
||||
for (k=0;k<PITCH_SUBFRAMES;k++)
|
||||
gainsQ12[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gainsQ12[k], Gain, 14);
|
||||
if (type == 4) {
|
||||
sign = -1;
|
||||
|
||||
// Make output more periodic.
|
||||
for (k = 0; k < PITCH_SUBFRAMES; k++) {
|
||||
gainsQ12[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
|
||||
gainsQ12[k], Gain, 14);
|
||||
}
|
||||
}
|
||||
|
||||
/* No interpolation if pitch lag step is big */
|
||||
if ((WEBRTC_SPL_RSHIFT_W16(WEBRTC_SPL_MUL_16_16(lagsQ7[0], 3), 1) < oldLagQ7) ||
|
||||
(lagsQ7[0] > WEBRTC_SPL_RSHIFT_W16(WEBRTC_SPL_MUL_16_16(oldLagQ7, 3), 1))) {
|
||||
// No interpolation if pitch lag step is big.
|
||||
if ((WEBRTC_SPL_MUL_16_16_RSFT(lagsQ7[0], 3, 1) < oldLagQ7) ||
|
||||
(lagsQ7[0] > WEBRTC_SPL_MUL_16_16_RSFT(oldLagQ7, 3, 1))) {
|
||||
oldLagQ7 = lagsQ7[0];
|
||||
oldGainQ12 = gainsQ12[0];
|
||||
}
|
||||
|
||||
ind=0;
|
||||
for (k=0;k<PITCH_SUBFRAMES;k++) {
|
||||
ind = 0;
|
||||
|
||||
/* Calculate interpolation steps */
|
||||
lagdeltaQ7 = lagsQ7[k]-oldLagQ7;
|
||||
lagdeltaQ7 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(lagdeltaQ7,DivFactor,15);
|
||||
for (k = 0; k < PITCH_SUBFRAMES; k++) {
|
||||
// Calculate interpolation steps.
|
||||
lagdeltaQ7 = lagsQ7[k] - oldLagQ7;
|
||||
lagdeltaQ7 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
|
||||
lagdeltaQ7, kDivFactor, 15);
|
||||
curLagQ7 = oldLagQ7;
|
||||
gaindeltaQ12 = gainsQ12[k]-oldGainQ12;
|
||||
gaindeltaQ12 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(gaindeltaQ12,DivFactor,15);
|
||||
gaindeltaQ12 = gainsQ12[k] - oldGainQ12;
|
||||
gaindeltaQ12 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
|
||||
gaindeltaQ12, kDivFactor, 15);
|
||||
|
||||
curGainQ12 = oldGainQ12;
|
||||
oldLagQ7 = lagsQ7[k];
|
||||
oldGainQ12 = gainsQ12[k];
|
||||
|
||||
// Each frame has 4 60-sample pitch subframes, and each subframe has 5
|
||||
// 12-sample segments. Each segment need to be processed with
|
||||
// newly-updated parameters, so we break the pitch filtering into
|
||||
// two for-loops (5 x 12) below. It's also why kDivFactor = 0.2 (in Q15).
|
||||
for (cnt = 0; cnt < kSegments; cnt++) {
|
||||
// Update parameters for each segment.
|
||||
curGainQ12 += gaindeltaQ12;
|
||||
curLagQ7 += lagdeltaQ7;
|
||||
indW32 = CalcLrIntQ(curLagQ7, 7);
|
||||
tmpW32 = WEBRTC_SPL_LSHIFT_W32(indW32, 7);
|
||||
tmpW32 -= curLagQ7;
|
||||
frcQQ = WEBRTC_SPL_RSHIFT_W32(tmpW32, 4);
|
||||
frcQQ += 4;
|
||||
|
||||
for (n=0;n<PITCH_SUBFRAME_LEN;n++) {
|
||||
|
||||
if (cnt == 0) { /* Update parameters */
|
||||
|
||||
curGainQ12 += gaindeltaQ12;
|
||||
curLagQ7 += lagdeltaQ7;
|
||||
indW16 = (WebRtc_Word16)CalcLrIntQ(curLagQ7,7);
|
||||
tmpW16 = WEBRTC_SPL_LSHIFT_W16(indW16,7);
|
||||
tmpW16 -= curLagQ7;
|
||||
frcQQ = WEBRTC_SPL_RSHIFT_W16(tmpW16,4);
|
||||
frcQQ += 4;
|
||||
|
||||
if(frcQQ==PITCH_FRACS)
|
||||
frcQQ=0;
|
||||
fracoeffQQ = kIntrpCoef[frcQQ];
|
||||
|
||||
cnt=12;
|
||||
if (frcQQ == PITCH_FRACS) {
|
||||
frcQQ = 0;
|
||||
}
|
||||
fracoeffQQ = kIntrpCoef[frcQQ];
|
||||
|
||||
/* shift low pass filter state */
|
||||
for (m=PITCH_DAMPORDER-1;m>0;m--)
|
||||
inystateQQ[m] = inystateQQ[m-1];
|
||||
|
||||
/* Filter to get fractional pitch */
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
pos2 = pos - (indW16 + 2);
|
||||
|
||||
tmpW32=0;
|
||||
for (m=0;m<PITCH_FRACORDER;m++)
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQ[pos2+m], fracoeffQQ[m]);
|
||||
|
||||
/* Saturate to avoid overflow in tmpW16 */
|
||||
tmpW32 = WEBRTC_SPL_SAT(536862719, tmpW32, -536879104);
|
||||
tmpW32 += 8192;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,14);
|
||||
|
||||
inystateQQ[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(curGainQ12, tmpW16,12); /* Multiply with gain */
|
||||
|
||||
/* Low pass filter */
|
||||
tmpW32=0;
|
||||
for (m=0;m<PITCH_DAMPORDER;m++)
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(inystateQQ[m], kDampFilter[m]);
|
||||
|
||||
/* Saturate to avoid overflow in tmpW16 */
|
||||
tmpW32 = WEBRTC_SPL_SAT(1073725439, tmpW32, -1073758208);
|
||||
tmpW32 += 16384;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,15);
|
||||
|
||||
/* Subtract from input and update buffer */
|
||||
tmpW32 = indatQQ[ind] - WEBRTC_SPL_MUL_16_16(sign, tmpW16);
|
||||
outdatQQ[ind] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmpW32);
|
||||
tmpW32 = indatQQ[ind] + (WebRtc_Word32)outdatQQ[ind];
|
||||
ubufQQ[pos] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmpW32);
|
||||
|
||||
ind++;
|
||||
cnt--;
|
||||
// Pitch filtering.
|
||||
PitchFilter(PITCH_SUBFRAME_LEN / kSegments, curGainQ12, indW32, sign,
|
||||
inystateQQ, ubufQQ, fracoeffQQ, indatQQ, outdatQQ, &ind);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Export buffer and states */
|
||||
memcpy(pfp->ubufQQ, ubufQQ+PITCH_FRAME_LEN, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_BUFFSIZE));
|
||||
memcpy(pfp->ystateQQ, inystateQQ, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_DAMPORDER));
|
||||
// Export buffer and states.
|
||||
memcpy(pfp->ubufQQ, ubufQQ + PITCH_FRAME_LEN, sizeof(pfp->ubufQQ));
|
||||
memcpy(pfp->ystateQQ, inystateQQ, sizeof(pfp->ystateQQ));
|
||||
|
||||
pfp->oldlagQ7 = oldLagQ7;
|
||||
pfp->oldgainQ12 = oldGainQ12;
|
||||
|
||||
if (type==2) {
|
||||
/* Filter look-ahead segment */
|
||||
for (n=0;n<QLOOKAHEAD;n++) {
|
||||
/* shift low pass filter state */
|
||||
for (m=PITCH_DAMPORDER-1;m>0;m--)
|
||||
inystateQQ[m] = inystateQQ[m-1];
|
||||
|
||||
/* Filter to get fractional pitch */
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
pos2= pos - (indW16 + 2);
|
||||
|
||||
tmpW32=0;
|
||||
for (m=0;m<PITCH_FRACORDER;m++)
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQ[pos2+m], fracoeffQQ[m]);
|
||||
|
||||
if (tmpW32<536862720) {//536870912)
|
||||
tmpW32 += 8192;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,14);
|
||||
} else
|
||||
tmpW16= 32767;
|
||||
inystateQQ[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(curGainQ12, tmpW16,12); /* Multiply with gain */
|
||||
|
||||
/* Low pass filter */
|
||||
tmpW32=0;
|
||||
for (m=0;m<PITCH_DAMPORDER;m++)
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(inystateQQ[m], kDampFilter[m]);
|
||||
if (tmpW32<1073725440) { //1073741824)
|
||||
tmpW32 += 16384;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,15);
|
||||
} else
|
||||
tmpW16 = 32767;
|
||||
|
||||
/* Subtract from input and update buffer */
|
||||
tmpW32 = indatQQ[ind] - (WebRtc_Word32)tmpW16;
|
||||
outdatQQ[ind] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmpW32);
|
||||
tmpW32 = indatQQ[ind] + (WebRtc_Word32)outdatQQ[ind];
|
||||
ubufQQ[pos] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmpW32);
|
||||
|
||||
ind++;
|
||||
}
|
||||
|
||||
if (type == 2) {
|
||||
// Filter look-ahead segment.
|
||||
PitchFilter(QLOOKAHEAD, curGainQ12, indW32, 1, inystateQQ,
|
||||
ubufQQ, fracoeffQQ, indatQQ, outdatQQ, &ind);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsacfix_PitchFilterGains(const WebRtc_Word16 *indatQ0,
|
||||
PitchFiltstr *pfp,
|
||||
WebRtc_Word16 *lagsQ7,
|
||||
WebRtc_Word16 *gainsQ12)
|
||||
{
|
||||
int k, n, m, ind;
|
||||
void WebRtcIsacfix_PitchFilterGains(const WebRtc_Word16* indatQ0,
|
||||
PitchFiltstr* pfp,
|
||||
WebRtc_Word16* lagsQ7,
|
||||
WebRtc_Word16* gainsQ12) {
|
||||
int k, n, m, ind, pos, pos3QQ;
|
||||
|
||||
WebRtc_Word16 ubufQQ[PITCH_INTBUFFSIZE];
|
||||
WebRtc_Word16 oldLagQ7,lagdeltaQ7, curLagQ7;
|
||||
WebRtc_Word16 DivFactor = 6553;
|
||||
const WebRtc_Word16 *fracoeffQQ = NULL;
|
||||
WebRtc_Word16 oldLagQ7, lagdeltaQ7, curLagQ7;
|
||||
const WebRtc_Word16* fracoeffQQ = NULL;
|
||||
WebRtc_Word16 scale;
|
||||
WebRtc_Word16 cnt=0, pos, pos3QQ, frcQQ, indW16 = 0, tmpW16;
|
||||
WebRtc_Word16 cnt = 0, frcQQ, indW16 = 0, tmpW16;
|
||||
WebRtc_Word32 tmpW32, tmp2W32, csum1QQ, esumxQQ;
|
||||
|
||||
/* Set up buffer and states */
|
||||
memcpy(ubufQQ, pfp->ubufQQ, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_BUFFSIZE));
|
||||
// Set up buffer and states.
|
||||
memcpy(ubufQQ, pfp->ubufQQ, sizeof(pfp->ubufQQ));
|
||||
oldLagQ7 = pfp->oldlagQ7;
|
||||
|
||||
/* No interpolation if pitch lag step is big */
|
||||
if ((WEBRTC_SPL_RSHIFT_W16(WEBRTC_SPL_MUL_16_16(lagsQ7[0], 3), 1) < oldLagQ7) ||
|
||||
(lagsQ7[0] > WEBRTC_SPL_RSHIFT_W16(WEBRTC_SPL_MUL_16_16(oldLagQ7, 3), 1))) {
|
||||
// No interpolation if pitch lag step is big.
|
||||
if ((WEBRTC_SPL_MUL_16_16_RSFT(lagsQ7[0], 3, 1) < oldLagQ7) ||
|
||||
(lagsQ7[0] > WEBRTC_SPL_MUL_16_16_RSFT(oldLagQ7, 3, 1))) {
|
||||
oldLagQ7 = lagsQ7[0];
|
||||
}
|
||||
|
||||
ind=0;
|
||||
scale=0;
|
||||
for (k=0;k<PITCH_SUBFRAMES;k++) {
|
||||
ind = 0;
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
scale = 0;
|
||||
for (k = 0; k < PITCH_SUBFRAMES; k++) {
|
||||
|
||||
/* Calculate interpolation steps */
|
||||
lagdeltaQ7 = lagsQ7[k]-oldLagQ7;
|
||||
lagdeltaQ7 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(lagdeltaQ7,DivFactor,15);
|
||||
// Calculate interpolation steps.
|
||||
lagdeltaQ7 = lagsQ7[k] - oldLagQ7;
|
||||
lagdeltaQ7 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
|
||||
lagdeltaQ7, kDivFactor, 15);
|
||||
curLagQ7 = oldLagQ7;
|
||||
oldLagQ7 = lagsQ7[k];
|
||||
|
||||
csum1QQ=1;
|
||||
esumxQQ=1;
|
||||
csum1QQ = 1;
|
||||
esumxQQ = 1;
|
||||
|
||||
for (n=0;n<PITCH_SUBFRAME_LEN;n++) {
|
||||
// Same as function WebRtcIsacfix_PitchFilter(), we break the pitch
|
||||
// filtering into two for-loops (5 x 12) below.
|
||||
for (cnt = 0; cnt < kSegments; cnt++) {
|
||||
// Update parameters for each segment.
|
||||
curLagQ7 += lagdeltaQ7;
|
||||
indW16 = (WebRtc_Word16)CalcLrIntQ(curLagQ7, 7);
|
||||
tmpW16 = WEBRTC_SPL_LSHIFT_W16(indW16, 7);
|
||||
tmpW16 -= curLagQ7;
|
||||
frcQQ = WEBRTC_SPL_RSHIFT_W16(tmpW16, 4);
|
||||
frcQQ += 4;
|
||||
|
||||
if (cnt == 0) { /* Update parameters */
|
||||
curLagQ7 += lagdeltaQ7;
|
||||
indW16 = (WebRtc_Word16)CalcLrIntQ(curLagQ7,7);
|
||||
tmpW16 = WEBRTC_SPL_LSHIFT_W16(indW16,7);
|
||||
tmpW16 -= curLagQ7;
|
||||
frcQQ = WEBRTC_SPL_RSHIFT_W16(tmpW16,4);
|
||||
frcQQ += 4;
|
||||
|
||||
if(frcQQ==PITCH_FRACS)
|
||||
frcQQ=0;
|
||||
fracoeffQQ = kIntrpCoef[frcQQ];
|
||||
|
||||
cnt=12;
|
||||
if (frcQQ == PITCH_FRACS) {
|
||||
frcQQ = 0;
|
||||
}
|
||||
fracoeffQQ = kIntrpCoef[frcQQ];
|
||||
|
||||
/* Filter to get fractional pitch */
|
||||
pos = ind + PITCH_BUFFSIZE;
|
||||
pos3QQ = pos - (indW16 + 4);
|
||||
|
||||
tmpW32=0;
|
||||
for (m=0;m<PITCH_FRACORDER;m++){
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQ[pos3QQ+m], fracoeffQQ[m]);
|
||||
for (n = 0; n < PITCH_SUBFRAME_LEN / kSegments; n++) {
|
||||
// Filter to get fractional pitch.
|
||||
|
||||
tmpW32 = 0;
|
||||
for (m = 0; m < PITCH_FRACORDER; m++) {
|
||||
tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQ[pos3QQ + m], fracoeffQQ[m]);
|
||||
}
|
||||
|
||||
// Subtract from input and update buffer.
|
||||
ubufQQ[pos] = indatQ0[ind];
|
||||
|
||||
tmp2W32 = WEBRTC_SPL_MUL_16_32_RSFT14(indatQ0[ind], tmpW32);
|
||||
tmpW32 += 8192;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 14);
|
||||
tmpW32 = WEBRTC_SPL_MUL_16_16(tmpW16, tmpW16);
|
||||
|
||||
if ((tmp2W32 > 1073700000) || (csum1QQ > 1073700000) ||
|
||||
(tmpW32 > 1073700000) || (esumxQQ > 1073700000)) { // 2^30
|
||||
scale++;
|
||||
csum1QQ = WEBRTC_SPL_RSHIFT_W32(csum1QQ, 1);
|
||||
esumxQQ = WEBRTC_SPL_RSHIFT_W32(esumxQQ, 1);
|
||||
}
|
||||
tmp2W32 = WEBRTC_SPL_RSHIFT_W32(tmp2W32, scale);
|
||||
csum1QQ += tmp2W32;
|
||||
tmpW32 = WEBRTC_SPL_RSHIFT_W32(tmpW32, scale);
|
||||
esumxQQ += tmpW32;
|
||||
|
||||
ind++;
|
||||
pos++;
|
||||
pos3QQ++;
|
||||
}
|
||||
|
||||
/* Subtract from input and update buffer */
|
||||
ubufQQ[pos] = indatQ0[ind];
|
||||
|
||||
tmp2W32 = WEBRTC_SPL_MUL_16_32_RSFT14(indatQ0[ind], tmpW32);
|
||||
tmpW32 += 8192;
|
||||
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32,14);
|
||||
tmpW32 = WEBRTC_SPL_MUL_16_16(tmpW16, tmpW16);
|
||||
|
||||
if ((tmp2W32>1073700000) || (csum1QQ>1073700000) || (tmpW32>1073700000) || (esumxQQ>1073700000)) {//2^30
|
||||
scale++;
|
||||
csum1QQ = WEBRTC_SPL_RSHIFT_W32(csum1QQ,1);
|
||||
esumxQQ = WEBRTC_SPL_RSHIFT_W32(esumxQQ,1);
|
||||
}
|
||||
tmp2W32 = WEBRTC_SPL_RSHIFT_W32(tmp2W32,scale);
|
||||
csum1QQ += tmp2W32;
|
||||
tmpW32 = WEBRTC_SPL_RSHIFT_W32(tmpW32,scale);
|
||||
esumxQQ += tmpW32;
|
||||
|
||||
ind++;
|
||||
cnt--;
|
||||
}
|
||||
|
||||
if (csum1QQ<esumxQQ) {
|
||||
tmp2W32=WebRtcSpl_DivResultInQ31(csum1QQ,esumxQQ);
|
||||
|
||||
/* Gain should be half the correlation */
|
||||
tmpW32=WEBRTC_SPL_RSHIFT_W32(tmp2W32,20);
|
||||
} else
|
||||
tmpW32=4096;
|
||||
gainsQ12[k]=(WebRtc_Word16)WEBRTC_SPL_SAT(PITCH_MAX_GAIN_Q12, tmpW32, 0);
|
||||
if (csum1QQ < esumxQQ) {
|
||||
tmp2W32 = WebRtcSpl_DivResultInQ31(csum1QQ, esumxQQ);
|
||||
|
||||
// Gain should be half the correlation.
|
||||
tmpW32 = WEBRTC_SPL_RSHIFT_W32(tmp2W32, 20);
|
||||
} else {
|
||||
tmpW32 = 4096;
|
||||
}
|
||||
gainsQ12[k] = (WebRtc_Word16)WEBRTC_SPL_SAT(PITCH_MAX_GAIN_Q12, tmpW32, 0);
|
||||
}
|
||||
|
||||
/* Export buffer and states */
|
||||
memcpy(pfp->ubufQQ, ubufQQ+PITCH_FRAME_LEN, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), PITCH_BUFFSIZE));
|
||||
pfp->oldlagQ7 = lagsQ7[PITCH_SUBFRAMES-1];
|
||||
pfp->oldgainQ12 = gainsQ12[PITCH_SUBFRAMES-1];
|
||||
// Export buffer and states.
|
||||
memcpy(pfp->ubufQQ, ubufQQ + PITCH_FRAME_LEN, sizeof(pfp->ubufQQ));
|
||||
pfp->oldlagQ7 = lagsQ7[PITCH_SUBFRAMES - 1];
|
||||
pfp->oldgainQ12 = gainsQ12[PITCH_SUBFRAMES - 1];
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user