decode_plc.c revision f045e4da43e671ae511aa1d9b6ef2968256a745d
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 * decode_plc.c 13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 14470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Packet Loss Concealment. 15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 17470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include <string.h> 19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 20470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "settings.h" 21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "entropy_coding.h" 22470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "pitch_estimator.h" 23470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "bandwidth_estimator.h" 24470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "structs.h" 25470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "codec.h" 26470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 27470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 28470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#define NO_OF_PRIMES 8 29470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#define NOISE_FILTER_LEN 30 30470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 31470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 32470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * function to decode the bitstream 33470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * returns the total number of bytes in the stream 34470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 35470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 360946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic int16_t plc_filterma_Fast( 370946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *In, /* (i) Vector to be filtered. InOut[-orderCoef+1] 38470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com to InOut[-1] contains state */ 390946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *Out, /* (o) Filtered vector */ 400946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *B, /* (i) The filter coefficients (in Q0) */ 410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t Blen, /* (i) Number of B coefficients */ 420946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t len, /* (i) Number of samples to be filtered */ 430946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t reduceDecay, 440946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t decay, 450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t rshift ) 46470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 47470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int i, j; 480946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t o; 49d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker int32_t lim = (1 << (15 + rshift)) - 1; 50470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 51470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (i = 0; i < len; i++) 52470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 53e4b6064f8e6b0b448f070155b1b6c4b6788107dfpbos@webrtc.org const int16_t *b_ptr = &B[0]; 54e4b6064f8e6b0b448f070155b1b6c4b6788107dfpbos@webrtc.org const int16_t *x_ptr = &In[i]; 55470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 560946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org o = (int32_t)0; 57470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 58470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (j = 0;j < Blen; j++) 59470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 60bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org o = WebRtcSpl_AddSatW32(o, *b_ptr * *x_ptr); 61470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com b_ptr++; 62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com x_ptr--; 63470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 64470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 65470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* to round off correctly */ 666e71d17bc98d3b179f55fd4fd42dc5c53b7787dcbjornv@webrtc.org o = WebRtcSpl_AddSatW32(o, 1 << (rshift - 1)); 67470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 68470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* saturate according to the domain of the filter coefficients */ 690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org o = WEBRTC_SPL_SAT((int32_t)lim, o, (int32_t)-lim); 70470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org /* o should be in the range of int16_t */ 72a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org o >>= rshift; 73470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 74470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* decay the output signal; this is specific to plc */ 75f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker *Out++ = (int16_t)((int16_t)o * decay >> 15); 76470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 77470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* change the decay */ 78470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com decay -= reduceDecay; 79470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( decay < 0 ) 80470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com decay = 0; 81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return( decay ); 83470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 84470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 86470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 90470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 920946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic __inline int32_t log2_Q8_T( uint32_t x ) { 93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 943ea35fdb1b3bc50e98b0fee03d274dce76fbdd55bjornv@webrtc.org int32_t zeros; 950946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t frac; 96470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 97470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com zeros=WebRtcSpl_NormU32(x); 98a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org frac = (int16_t)(((x << zeros) & 0x7FFFFFFF) >> 23); 99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1003ea35fdb1b3bc50e98b0fee03d274dce76fbdd55bjornv@webrtc.org /* log2(magn(i)) */ 1013ea35fdb1b3bc50e98b0fee03d274dce76fbdd55bjornv@webrtc.org return ((31 - zeros) << 8) + frac; 102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1040946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic __inline int16_t exp2_Q10_T(int16_t x) { // Both in and out in Q10 105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1060946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t tmp16_1, tmp16_2; 107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1080946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org tmp16_2=(int16_t)(0x0400|(x&0x03FF)); 109f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org tmp16_1 = -(x >> 10); 110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(tmp16_1>0) 111f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org return tmp16_2 >> tmp16_1; 112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 1133ea35fdb1b3bc50e98b0fee03d274dce76fbdd55bjornv@webrtc.org return tmp16_2 << -tmp16_1; 114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com This is a fixed-point version of the above code with limLow = 700 and limHigh = 5000, 120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com hard-coded. The values 700 and 5000 were experimentally obtained. 121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com The function implements membership values for two sets. The mebership functions are 123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com of second orders corresponding to half-bell-shapped pulses. 124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com*/ 1250946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic void MemshipValQ15( int16_t in, int16_t *A, int16_t *B ) 126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1270946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t x; 128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com in -= 700; /* translate the lowLim to 0, limHigh = 5000 - 700, M = 2150 */ 130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( in <= 2150 ) 132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( in > 0 ) 134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* b = in^2 / (2 * M^2), a = 1 - b in Q0. 136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com We have to compute in Q15 */ 137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* x = in / 2150 {in Q15} = x * 15.2409 {in Q15} = 139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com x*15 + (x*983)/(2^12); note that 983/2^12 = 0.23999 */ 140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org /* we are sure that x is in the range of int16_t */ 142f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker x = (int16_t)(in * 15 + (in * 983 >> 12)); 143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* b = x^2 / 2 {in Q15} so a shift of 16 is required to 144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com be in correct domain and one more for the division by 2 */ 145a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org *B = (int16_t)((x * x + 0x00010000) >> 17); 146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *A = WEBRTC_SPL_WORD16_MAX - *B; 147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *B = 0; 151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *A = WEBRTC_SPL_WORD16_MAX; 152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( in < 4300 ) 157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* This is a mirror case of the above */ 159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com in = 4300 - in; 160f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker x = (int16_t)(in * 15 + (in * 983 >> 12)); 161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* b = x^2 / 2 {in Q15} so a shift of 16 is required to 162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com be in correct domain and one more for the division by 2 */ 163a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org *A = (int16_t)((x * x + 0x00010000) >> 17); 164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *B = WEBRTC_SPL_WORD16_MAX - *A; 165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *A = 0; 170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *B = WEBRTC_SPL_WORD16_MAX; 171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1780946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgstatic void LinearResampler( int16_t *in, int16_t *out, int16_t lenIn, int16_t lenOut ) 179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 180bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org int32_t n = (lenIn - 1) * RESAMP_RES; 1810946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t resOut, i, j, relativePos, diff; /* */ 1820946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint16_t udiff; 183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( lenIn == lenOut ) 185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_SPL_MEMCPY_W16( out, in, lenIn ); 187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1900946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org resOut = WebRtcSpl_DivW32W16ResW16( n, (int16_t)(lenOut-1) ); 191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com out[0] = in[0]; 193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 1, j = 0, relativePos = 0; i < lenOut; i++ ) 194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com relativePos += resOut; 197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while( relativePos > RESAMP_RES ) 198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com j++; 200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com relativePos -= RESAMP_RES; 201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* an overflow may happen and the differce in sample values may 205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * require more than 16 bits. We like to avoid 32 bit arithmatic 206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * as much as possible */ 207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (in[ j ] > 0) && (in[j + 1] < 0) ) 209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2100946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org udiff = (uint16_t)(in[ j ] - in[j + 1]); 2110946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org out[ i ] = in[ j ] - (uint16_t)( ((int32_t)( udiff * relativePos )) >> RESAMP_RES_BIT); 212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (in[j] < 0) && (in[j+1] > 0) ) 216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2170946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org udiff = (uint16_t)( in[j + 1] - in[ j ] ); 2180946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org out[ i ] = in[ j ] + (uint16_t)( ((int32_t)( udiff * relativePos )) >> RESAMP_RES_BIT); 219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diff = in[ j + 1 ] - in[ j ]; 223f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker out[i] = in[j] + (int16_t)(diff * relativePos >> RESAMP_RES_BIT); 224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2330946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_DecodePlcImpl(int16_t *signal_out16, 234eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.org IsacFixDecoderInstance *ISACdec_obj, 2350946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *current_framesamples ) 236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int subframecnt; 2380946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t len = 0; 239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2400946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t* Vector_Word16_1; 2410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t Vector_Word16_Extended_1[FRAMESAMPLES_HALF + NOISE_FILTER_LEN]; 2420946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t* Vector_Word16_2; 2430946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t Vector_Word16_Extended_2[FRAMESAMPLES_HALF + NOISE_FILTER_LEN]; 244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t Vector_Word32_1[FRAMESAMPLES_HALF]; 2460946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t Vector_Word32_2[FRAMESAMPLES_HALF]; 247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2480946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs 2490946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs 250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2510946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t pitchLags_Q7[PITCH_SUBFRAMES]; 2520946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t pitchGains_Q12[PITCH_SUBFRAMES]; 253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2540946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t tmp_1, tmp_2; 2550946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmp32a, tmp32b; 2560946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t gainQ13; 257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2580946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t myDecayRate; 259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ---------- PLC variables ------------ */ 2610946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t lag0, i, k, noiseIndex; 2620946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t stretchPitchLP[PITCH_MAX_LAG + 10], stretchPitchLP1[PITCH_MAX_LAG + 10]; 263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2640946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t gain_lo_hiQ17[2*SUBFRAMES]; 265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2660946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t nLP, pLP, wNoisyLP, wPriodicLP, tmp16, minIdx; 2670946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t nHP, pHP, wNoisyHP, wPriodicHP, corr, minCorr, maxCoeff; 2680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t noise1, rshift; 269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2710946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t ltpGain, pitchGain, myVoiceIndicator, myAbs, maxAbs; 2720946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t varIn, varOut, logVarIn, logVarOut, Q, logMaxAbs; 273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int rightShiftIn, rightShiftOut; 274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------------------------------------- */ 277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myDecayRate = (DECAY_RATE); 280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_1 = &Vector_Word16_Extended_1[NOISE_FILTER_LEN]; 281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_2 = &Vector_Word16_Extended_2[NOISE_FILTER_LEN]; 282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ----- Simply Copy Previous LPC parameters ------ */ 285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( subframecnt = 0; subframecnt < SUBFRAMES; subframecnt++ ) 286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* lower Band */ 288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_SPL_MEMCPY_W16(&lofilt_coefQ15[ subframecnt * ORDERLO ], 289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).lofilt_coefQ15, ORDERLO); 290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain_lo_hiQ17[2*subframecnt] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0]; 291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Upper Band */ 293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_SPL_MEMCPY_W16(&hifilt_coefQ15[ subframecnt * ORDERHI ], 294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).hifilt_coefQ15, ORDERHI); 295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain_lo_hiQ17[2*subframecnt + 1] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1]; 296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 301f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org lag0 = ((ISACdec_obj->plcstr_obj.lastPitchLag_Q7 + 64) >> 7) + 1; 302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).used != PLC_WAS_USED ) 305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchCycles = 0; 307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).lastPitchLP = 309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &((ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0]); 310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com minCorr = WEBRTC_SPL_WORD32_MAX; 311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 312f045e4da43e671ae511aa1d9b6ef2968256a745dPeter Kasting if ((FRAMESAMPLES_HALF - 10) > 2 * lag0) 313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com minIdx = 11; 315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0; i < 21; i++ ) 316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com corr = 0; 318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k = 0; k < lag0; k++ ) 319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3206e71d17bc98d3b179f55fd4fd42dc5c53b7787dcbjornv@webrtc.org corr = WebRtcSpl_AddSatW32(corr, WEBRTC_SPL_ABS_W32( 3211b21a579028998e717c35e320cd1d6258b2b650dbjornv@webrtc.org WebRtcSpl_SubSatW16( 322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).lastPitchLP[k], 323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).prevPitchInvIn[ 324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FRAMESAMPLES_HALF - 2*lag0 - 10 + i + k ] ) ) ); 325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( corr < minCorr ) 327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com minCorr = corr; 329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com minIdx = i; 330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).prevPitchLP = 333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &( (ISACdec_obj->plcstr_obj).prevPitchInvIn[ 334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FRAMESAMPLES_HALF - lag0*2 - 10 + minIdx] ); 335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).prevPitchLP = 339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).lastPitchLP; 340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pitchGain = (ISACdec_obj->plcstr_obj).lastPitchGain_Q12; 342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_AutoCorrelation( 344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0], 345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lag0, 0, &varIn, &rightShiftIn); 346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_AutoCorrelation( 347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &(ISACdec_obj->plcstr_obj).prevPitchInvOut[PITCH_MAX_LAG + 10 - lag0], 348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lag0, 0, &varOut, &rightShiftOut); 349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com maxAbs = 0; 351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0; i< lag0; i++) 352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myAbs = WEBRTC_SPL_ABS_W16( 354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).prevPitchInvOut[ 355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PITCH_MAX_LAG + 10 - lag0 + i] ); 356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com maxAbs = (myAbs > maxAbs)? myAbs:maxAbs; 357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3580946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org logVarIn = log2_Q8_T( (uint32_t)( varIn ) ) + 3590946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)(rightShiftIn << 8); 3600946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org logVarOut = log2_Q8_T( (uint32_t)( varOut ) ) + 3610946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)(rightShiftOut << 8); 3620946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org logMaxAbs = log2_Q8_T( (uint32_t)( maxAbs ) ); 363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3640946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org ltpGain = (int16_t)(logVarOut - logVarIn); 365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Q = 2 * logMaxAbs - ( logVarOut - 1512 ); 366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* 368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * --- 369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * We are computing sqrt( (VarIn/lag0) / var( noise ) ) 370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * var( noise ) is almost 256. we have already computed log2( VarIn ) in Q8 371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * so we actually compute 2^( 0.5*(log2( VarIn ) - log2( lag0 ) - log2( var(noise ) ) ). 372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Note that put log function is in Q8 but the exponential function is in Q10. 373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * -- 374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3760946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org logVarIn -= log2_Q8_T( (uint32_t)( lag0 ) ); 3770946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org tmp16 = (int16_t)((logVarIn<<1) - (4<<10) ); 378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rightShiftIn = 0; 379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( tmp16 > 4096 ) 380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16 -= 4096; 382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16 = exp2_Q10_T( tmp16 ); 383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16 >>= 6; 384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16 = exp2_Q10_T( tmp16 )>>10; 387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).std = tmp16 - 4; 389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ltpGain < 110) || (ltpGain > 230) ) 391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( ltpGain < 100 && (pitchGain < 1800) ) 393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).A = WEBRTC_SPL_WORD16_MAX; 395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).A = ((ltpGain < 110) && (Q < 800) 399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com )? WEBRTC_SPL_WORD16_MAX:0; 400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX - 402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).A; 403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (pitchGain < 450) || (pitchGain > 1600) ) 407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).A = ((pitchGain < 450) 409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com )? WEBRTC_SPL_WORD16_MAX:0; 410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX - 411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).A; 412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myVoiceIndicator = ltpGain * 2 + pitchGain; 416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com MemshipValQ15( myVoiceIndicator, 417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B ); 418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myVoiceIndicator = ltpGain * 16 + pitchGain * 2 + (pitchGain >> 8); 424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com MemshipValQ15( myVoiceIndicator, 425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B ); 426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = lag0; 430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex = 0; 431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myDecayRate = (DECAY_RATE<<2); 436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).B < 1000 ) 439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myDecayRate += (DECAY_RATE<<3); 441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------------ reconstructing the residual signal ------------------ */ 444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP, 446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* inverse pitch filter */ 448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pitchLags_Q7[0] = pitchLags_Q7[1] = pitchLags_Q7[2] = pitchLags_Q7[3] = 450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ((ISACdec_obj->plcstr_obj).stretchLag<<7); 451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pitchGains_Q12[3] = ( (ISACdec_obj->plcstr_obj).lastPitchGain_Q12); 452f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker pitchGains_Q12[2] = (int16_t)(pitchGains_Q12[3] * 1010 >> 10); 453f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker pitchGains_Q12[1] = (int16_t)(pitchGains_Q12[2] * 1010 >> 10); 454f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker pitchGains_Q12[0] = (int16_t)(pitchGains_Q12[1] * 1010 >> 10); 455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* most of the time either B or A are zero so seperating */ 458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).B == 0 ) 459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0; i < FRAMESAMPLES_HALF; i++ ) 461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Low Pass */ 463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed ); 465f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org Vector_Word16_1[i] = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Highpass */ 468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed ); 470f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org Vector_Word16_2[i] = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 1; i < NOISE_FILTER_LEN; i++ ) 474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed ); 477f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org Vector_Word16_Extended_1[i] = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed ); 481f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org Vector_Word16_Extended_2[i] = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com plc_filterma_Fast(Vector_Word16_1, Vector_Word16_Extended_1, 484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - 4850946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org NOISE_FILTER_LEN], (int16_t) NOISE_FILTER_LEN, 4860946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int16_t) FRAMESAMPLES_HALF, (int16_t)(5), 4870946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (ISACdec_obj->plcstr_obj).decayCoeffNoise, (int16_t)(6)); 488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com maxCoeff = WebRtcSpl_MaxAbsValueW32( 490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &(ISACdec_obj->plcstr_obj).prevHP[ 491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN], NOISE_FILTER_LEN ); 492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rshift = 0; 494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while( maxCoeff > WEBRTC_SPL_WORD16_MAX ) 495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 496a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org maxCoeff >>= 1; 497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rshift++; 498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0; i < NOISE_FILTER_LEN; i++ ) { 500a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org Vector_Word16_1[FRAMESAMPLES_HALF - NOISE_FILTER_LEN + i] =(int16_t)( 501a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org ISACdec_obj->plcstr_obj.prevHP[PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN + 502a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org i] >> rshift); 503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffNoise = plc_filterma_Fast( 505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_2, 506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_Extended_2, 507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &Vector_Word16_1[FRAMESAMPLES_HALF - NOISE_FILTER_LEN], 5080946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int16_t) NOISE_FILTER_LEN, 5090946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int16_t) FRAMESAMPLES_HALF, 5100946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int16_t) (5), 511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffNoise, 5120946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int16_t) (7) ); 513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0; i < FRAMESAMPLES_HALF; i++ ) 515d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker Vector_Word32_2[i] = Vector_Word16_Extended_2[i] << rshift; 516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_1 = Vector_Word16_Extended_1; 518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).A == 0 ) 522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------ Periodic Vector --- */ 524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ ) 525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Lowpass */ 527f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker pLP = (int16_t)(stretchPitchLP[ISACdec_obj->plcstr_obj.pitchIndex] * 528f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker ISACdec_obj->plcstr_obj.decayCoeffPriodic >> 15); 529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Highpass */ 5310946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org pHP = (int32_t)WEBRTC_SPL_MUL_16_32_RSFT15( 532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 - 534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag + 535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex] ); 536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- lower the muliplier (more decay at next sample) --- */ 538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate); 539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 ) 540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0; 541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex++; 543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).pitchIndex == 545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag ) 546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex = 0; 548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchCycles++; 549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) ) 551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1; 553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = lag0; 557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = ( 560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG 561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com )? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag; 562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP, 564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LinearResampler( (ISACdec_obj->plcstr_obj).prevPitchLP, 567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch( (ISACdec_obj->plcstr_obj).pitchCycles ) 570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 1: 572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5750946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org stretchPitchLP[k] = (int16_t)(( 5760946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP[k]* 3 + 5770946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP1[k])>>2); 578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 2: 582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5850946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org stretchPitchLP[k] = (int16_t)(( 5860946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP[k] + 5870946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP1[k] )>>1); 588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 3: 592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5950946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org stretchPitchLP[k] = (int16_t)((stretchPitchLP[k] + 5960946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP1[k]*3 )>>2); 597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 ) 603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myDecayRate += 35; //(myDecayRate>>1); 605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchCycles = 0; 606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------ Sum the noisy and periodic signals ------ */ 611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_1[i] = pLP; 612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word32_2[i] = pHP; 613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ ) 618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed ); 622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 623f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org noise1 = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 625f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker nLP = (int16_t)((int16_t)(noise1 * ISACdec_obj->plcstr_obj.std) * 626f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker ISACdec_obj->plcstr_obj.decayCoeffNoise >> 15); 627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Highpass */ 629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed ); 631f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org noise1 = (ISACdec_obj->plcstr_obj.seed >> 11) - 8; 632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6330946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org nHP = (int32_t)WEBRTC_SPL_MUL_16_32_RSFT15( 634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffNoise, 6350946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)(noise1*(ISACdec_obj->plcstr_obj).std) ); 636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- lower the muliplier (more decay at next sample) --- */ 638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffNoise -= (myDecayRate); 639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).decayCoeffNoise < 0 ) 640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffNoise = 0; 641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------ Periodic Vector --- */ 643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Lowpass */ 644f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker pLP = (int16_t)(stretchPitchLP[ISACdec_obj->plcstr_obj.pitchIndex] * 645f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker ISACdec_obj->plcstr_obj.decayCoeffPriodic >> 15); 646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Highpass */ 6480946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org pHP = (int32_t)WEBRTC_SPL_MUL_16_32_RSFT15( 649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 - 651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag + 652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex] ); 653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- lower the muliplier (more decay at next sample) --- */ 655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate); 656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 ) 657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0; 659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------ Weighting the noisy and periodic vectors ------- */ 662f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker wNoisyLP = (int16_t)(ISACdec_obj->plcstr_obj.A * nLP >> 15); 6630946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org wNoisyHP = (int32_t)(WEBRTC_SPL_MUL_16_32_RSFT15( 664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).A, (nHP) ) ); 665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 666f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker wPriodicLP = (int16_t)(ISACdec_obj->plcstr_obj.B * pLP >> 15); 6670946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org wPriodicHP = (int32_t)(WEBRTC_SPL_MUL_16_32_RSFT15( 668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).B, pHP)); 669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex++; 671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if((ISACdec_obj->plcstr_obj).pitchIndex == 673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag) 674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex = 0; 676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchCycles++; 677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) ) 679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1; 680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = lag0; 682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = ( 684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG 685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com )? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag; 686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LinearResampler( 687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).lastPitchLP, 688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LinearResampler((ISACdec_obj->plcstr_obj).prevPitchLP, 691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch((ISACdec_obj->plcstr_obj).pitchCycles) 694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 1: 696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6990946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org stretchPitchLP[k] = (int16_t)(( 7000946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP[k]* 3 + 7010946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP1[k] )>>2); 702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 2: 706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 7090946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org stretchPitchLP[k] = (int16_t)(( 7100946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP[k] + 7110946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP1[k])>>1); 712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 3: 716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 7190946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org stretchPitchLP[k] = (int16_t)( 720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (stretchPitchLP[k] + 7210946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP1[k]*3 )>>2); 722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 ) 728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myDecayRate += 55; //(myDecayRate>>1); 730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchCycles = 0; 731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------ Sum the noisy and periodic signals ------ */ 7356e71d17bc98d3b179f55fd4fd42dc5c53b7787dcbjornv@webrtc.org Vector_Word16_1[i] = WebRtcSpl_AddSatW16(wNoisyLP, wPriodicLP); 7366e71d17bc98d3b179f55fd4fd42dc5c53b7787dcbjornv@webrtc.org Vector_Word32_2[i] = WebRtcSpl_AddSatW32(wNoisyHP, wPriodicHP); 737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ----------------- residual signal is reconstructed ------------------ */ 741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com k = (ISACdec_obj->plcstr_obj).pitchIndex; 743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Write one pitch cycle for recovery block --- */ 744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0; i < RECOVERY_OVERLAP; i++ ) 746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 747f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker ISACdec_obj->plcstr_obj.overlapLP[i] = (int16_t)( 748f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker stretchPitchLP[k] * ISACdec_obj->plcstr_obj.decayCoeffPriodic >> 15); 749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com k = ( k < ((ISACdec_obj->plcstr_obj).stretchLag - 1) )? (k+1):0; 750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = (ISACdec_obj->plcstr_obj).stretchLag << 7; 753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Inverse Pitch Filter --- */ 756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2, 757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &ISACdec_obj->pitchfiltstr_obj, pitchLags_Q7, pitchGains_Q12, 4); 758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* reduce gain to compensate for pitch enhancer */ 760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* gain = 1.0f - 0.45f * AvgPitchGain; */ 761f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker tmp32a = ISACdec_obj->plcstr_obj.AvgPitchGain_Q12 * 29; // Q18 762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32b = 262144 - tmp32a; // Q18 7630946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org gainQ13 = (int16_t) (tmp32b >> 5); // Q13 764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* perceptual post-filtering (using normalized lattice filter) */ 766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < FRAMESAMPLES_HALF; k++) 767bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org Vector_Word32_1[k] = (Vector_Word16_2[k] * gainQ13) << 3; // Q25 768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIsacfix_NormLatticeFilterAr(ORDERLO, 771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0, 772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1); 773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIsacfix_NormLatticeFilterAr(ORDERHI, 775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0, 776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word32_2, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2); 777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* recombine the 2 bands */ 779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Form the polyphase signals, and compensate for DC offset */ 781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0;k<FRAMESAMPLES_HALF;k++) 782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Construct a new upper channel signal*/ 7840946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org tmp_1 = (int16_t)WebRtcSpl_SatW32ToW16( 7850946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org ((int32_t)Vector_Word16_1[k]+Vector_Word16_2[k] + 1)); 786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Construct a new lower channel signal*/ 7870946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org tmp_2 = (int16_t)WebRtcSpl_SatW32ToW16( 7880946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org ((int32_t)Vector_Word16_1[k]-Vector_Word16_2[k])); 789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_1[k] = tmp_1; 790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_2[k] = tmp_2; 791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1, 795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_2, signal_out16, &ISACdec_obj->postfiltbankstr_obj); 796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).used = PLC_WAS_USED; 798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *current_framesamples = 480; 799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return len; 801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 802