/* decodeAdaptativeCodeVector.c Copyright (C) 2011 Belledonne Communications, Grenoble, France Author : Johan Pascal This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "typedef.h" #include "codecParameters.h" #include "basicOperationsMacros.h" #include "codebooks.h" #include "decodeAdaptativeCodeVector.h" /* init function */ void initDecodeAdaptativeCodeVector(bcg729DecoderChannelContextStruct *decoderChannelContext) { decoderChannelContext->previousIntPitchDelay = 60; } /*****************************************************************************/ /* computeAdaptativeCodeVector : as in spec 4.1.3 */ /* parameters: */ /* -(i/o) excitationVector : in Q0 excitation accessed from */ /* [-MAXIMUM_INT_PITCH_DELAY(143), -1] as input */ /* and [0, L_SUBFRAME[ as output to store the adaptative */ /* codebook vector */ /* -(i/o) fracPitchDelay : the fractionnal part of Pitch Delay. */ /* -(i/o) intPitchDelay : the integer part of Pitch Delay. */ /* */ /*****************************************************************************/ void computeAdaptativeCodebookVector(word16_t *excitationVector, int16_t fracPitchDelay, int16_t intPitchDelay) { word16_t *excitationVectorMinusK; /* pointer to u(-k) */ int n; /* compute the adaptative codebook vector using the pitch delay and the past excitation vector */ /* from spec 4.1.3 and 3.7.1 */ /* shall compute v(n ) = ∑ u (n - k + i )b30 (t + 3i ) + ∑ u (n - k + 1 + i )b30 (3 - t + 3i ) for i=0,...,9 and n = 0,...,39 (t in 0, 1, 2) */ /* with k = intPitchDelay and t = fracPitchDelay wich must be converted from range -1,0,1 to 0,1,2 */ /* u the past excitation vector */ /* v the adaptative codebook vector */ /* b30 an interpolation filter */ /* scale fracPichDelay from -1,0.1 to 0,1,2 */ if (fracPitchDelay==1) { excitationVectorMinusK = &(excitationVector[-(intPitchDelay+1)]); /* fracPitchDelay being positive -> increase by one the integer part and set to 2 the fractional part : -(k+1/3) -> -(k+1)+2/3 */ fracPitchDelay = 2; } else { fracPitchDelay = -fracPitchDelay; /* 0 unchanged, -1 -> +1 */ excitationVectorMinusK = &(excitationVector[-intPitchDelay]); /* -(k-1/3) -> -k+1/3 or -(k) -> -k*/ } for (n=0; npreviousIntPitchDelay; /* set the integer part of Pitch Delay to the last second subframe Pitch Delay computed spec: 4.1.2 */ /* Note: unable to find anything regarding this part in the spec, just copied it from the ITU source code */ fracPitchDelay = 0; decoderChannelContext->previousIntPitchDelay++; if (decoderChannelContext->previousIntPitchDelay>MAXIMUM_INT_PITCH_DELAY) decoderChannelContext->previousIntPitchDelay=MAXIMUM_INT_PITCH_DELAY; } else { /* parity and frameErasure flags are off, do the normal computation (doc 4.1.3) */ if (adaptativeCodebookIndex<197) { /* *intPitchDelay = (P1 + 2 )/ 3 + 19 */ *intPitchDelay = ADD16(MULT16_16_Q15(ADD16(adaptativeCodebookIndex,2), 10923), 19); /* MULT in Q15: 1/3 in Q15: 10923 */ /* fracPitchDelay = P1 − 3*intPitchDelay + 58 : fracPitchDelay in -1, 0, 1 */ fracPitchDelay = ADD16(SUB16(adaptativeCodebookIndex, MULT16_16(*intPitchDelay, 3)), 58); } else {/* adaptativeCodebookIndex>= 197 */ *intPitchDelay = SUB16(adaptativeCodebookIndex, 112); fracPitchDelay = 0; } /* backup the intPitchDelay */ decoderChannelContext->previousIntPitchDelay = *intPitchDelay; } } else { /* second subframe */ if (frameErasureFlag) { /* there is an error : frame erased, in case of parity error, it has been taken in account at first subframe */ /* unable to find anything regarding this part in the spec, just copied it from the ITU source code */ *intPitchDelay = decoderChannelContext->previousIntPitchDelay; fracPitchDelay = 0; decoderChannelContext->previousIntPitchDelay++; if (decoderChannelContext->previousIntPitchDelay>MAXIMUM_INT_PITCH_DELAY) decoderChannelContext->previousIntPitchDelay=MAXIMUM_INT_PITCH_DELAY; } else { /* frameErasure flags are off, do the normal computation (doc 4.1.3) */ int16_t tMin = SUB16(*intPitchDelay,5); /* intPitchDelay contains the intPitch computed for subframe one */ if (tMin<20) { tMin = 20; } if (tMin>134) { tMin = 134; } /* intPitchDelay = (P2 + 2 )/ 3 − 1 */ *intPitchDelay = SUB16(MULT16_16_Q15(ADD16(adaptativeCodebookIndex, 2), 10923), 1); /* fracPitchDelay = P2 − 2 − 3((P 2 + 2 )/ 3 − 1) */ fracPitchDelay = SUB16(SUB16(adaptativeCodebookIndex, MULT16_16(*intPitchDelay, 3)), 2); /* *intPitchDelay = (P2 + 2 )/ 3 − 1 + tMin */ *intPitchDelay = ADD16(*intPitchDelay,tMin); /* backup the intPitchDelay */ decoderChannelContext->previousIntPitchDelay = *intPitchDelay; } } /* compute the adaptative codebook vector using the pitch delay we just get and the past excitation vector */ computeAdaptativeCodebookVector(excitationVector, fracPitchDelay, *intPitchDelay); return; }