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 178728d9037c016c01295177fa700fc7927f0bb80bbPeter Kastingstatic void LinearResampler(int16_t* in, 179728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting int16_t* out, 180dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t lenIn, 181dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t lenOut) 182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 183dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t n = (lenIn - 1) * RESAMP_RES; 184dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting int16_t resOut, relativePos, diff; /* */ 185dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t i, j; 1860946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org uint16_t udiff; 187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( lenIn == lenOut ) 189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_SPL_MEMCPY_W16( out, in, lenIn ); 191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 194dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting resOut = WebRtcSpl_DivW32W16ResW16( (int32_t)n, (int16_t)(lenOut-1) ); 195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com out[0] = in[0]; 197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 1, j = 0, relativePos = 0; i < lenOut; i++ ) 198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com relativePos += resOut; 201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while( relativePos > RESAMP_RES ) 202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com j++; 204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com relativePos -= RESAMP_RES; 205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* an overflow may happen and the differce in sample values may 209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * require more than 16 bits. We like to avoid 32 bit arithmatic 210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * as much as possible */ 211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (in[ j ] > 0) && (in[j + 1] < 0) ) 213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2140946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org udiff = (uint16_t)(in[ j ] - in[j + 1]); 2150946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org out[ i ] = in[ j ] - (uint16_t)( ((int32_t)( udiff * relativePos )) >> RESAMP_RES_BIT); 216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (in[j] < 0) && (in[j+1] > 0) ) 220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2210946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org udiff = (uint16_t)( in[j + 1] - in[ j ] ); 2220946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org out[ i ] = in[ j ] + (uint16_t)( ((int32_t)( udiff * relativePos )) >> RESAMP_RES_BIT); 223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com diff = in[ j + 1 ] - in[ j ]; 227f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker out[i] = in[j] + (int16_t)(diff * relativePos >> RESAMP_RES_BIT); 228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 237728d9037c016c01295177fa700fc7927f0bb80bbPeter Kastingvoid WebRtcIsacfix_DecodePlcImpl(int16_t *signal_out16, 238728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting IsacFixDecoderInstance *ISACdec_obj, 239dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t *current_framesamples ) 240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int subframecnt; 242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2430946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t* Vector_Word16_1; 2440946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t Vector_Word16_Extended_1[FRAMESAMPLES_HALF + NOISE_FILTER_LEN]; 2450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t* Vector_Word16_2; 2460946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t Vector_Word16_Extended_2[FRAMESAMPLES_HALF + NOISE_FILTER_LEN]; 247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2480946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t Vector_Word32_1[FRAMESAMPLES_HALF]; 2490946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t Vector_Word32_2[FRAMESAMPLES_HALF]; 250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2510946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs 2520946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs 253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2540946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t pitchLags_Q7[PITCH_SUBFRAMES]; 2550946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t pitchGains_Q12[PITCH_SUBFRAMES]; 256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2570946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t tmp_1, tmp_2; 2580946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t tmp32a, tmp32b; 2590946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t gainQ13; 260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2610946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t myDecayRate; 262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ---------- PLC variables ------------ */ 264dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t lag0, i, k; 265dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting int16_t noiseIndex; 2660946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t stretchPitchLP[PITCH_MAX_LAG + 10], stretchPitchLP1[PITCH_MAX_LAG + 10]; 267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t gain_lo_hiQ17[2*SUBFRAMES]; 269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 270dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting int16_t nLP, pLP, wNoisyLP, wPriodicLP, tmp16; 271dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t minIdx; 2720946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t nHP, pHP, wNoisyHP, wPriodicHP, corr, minCorr, maxCoeff; 2730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t noise1, rshift; 274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2760946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t ltpGain, pitchGain, myVoiceIndicator, myAbs, maxAbs; 2770946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t varIn, varOut, logVarIn, logVarOut, Q, logMaxAbs; 278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int rightShiftIn, rightShiftOut; 279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------------------------------------- */ 282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myDecayRate = (DECAY_RATE); 285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_1 = &Vector_Word16_Extended_1[NOISE_FILTER_LEN]; 286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_2 = &Vector_Word16_Extended_2[NOISE_FILTER_LEN]; 287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ----- Simply Copy Previous LPC parameters ------ */ 290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( subframecnt = 0; subframecnt < SUBFRAMES; subframecnt++ ) 291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* lower Band */ 293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_SPL_MEMCPY_W16(&lofilt_coefQ15[ subframecnt * ORDERLO ], 294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).lofilt_coefQ15, ORDERLO); 295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain_lo_hiQ17[2*subframecnt] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0]; 296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Upper Band */ 298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_SPL_MEMCPY_W16(&hifilt_coefQ15[ subframecnt * ORDERHI ], 299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).hifilt_coefQ15, ORDERHI); 300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com gain_lo_hiQ17[2*subframecnt + 1] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1]; 301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 306dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting lag0 = (size_t)(((ISACdec_obj->plcstr_obj.lastPitchLag_Q7 + 64) >> 7) + 1); 307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).used != PLC_WAS_USED ) 310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchCycles = 0; 312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).lastPitchLP = 314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &((ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0]); 315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com minCorr = WEBRTC_SPL_WORD32_MAX; 316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 317f045e4da43e671ae511aa1d9b6ef2968256a745dPeter Kasting if ((FRAMESAMPLES_HALF - 10) > 2 * lag0) 318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com minIdx = 11; 320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0; i < 21; i++ ) 321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com corr = 0; 323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k = 0; k < lag0; k++ ) 324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3256e71d17bc98d3b179f55fd4fd42dc5c53b7787dcbjornv@webrtc.org corr = WebRtcSpl_AddSatW32(corr, WEBRTC_SPL_ABS_W32( 3261b21a579028998e717c35e320cd1d6258b2b650dbjornv@webrtc.org WebRtcSpl_SubSatW16( 327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).lastPitchLP[k], 328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).prevPitchInvIn[ 329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FRAMESAMPLES_HALF - 2*lag0 - 10 + i + k ] ) ) ); 330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( corr < minCorr ) 332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com minCorr = corr; 334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com minIdx = i; 335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).prevPitchLP = 338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &( (ISACdec_obj->plcstr_obj).prevPitchInvIn[ 339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FRAMESAMPLES_HALF - lag0*2 - 10 + minIdx] ); 340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).prevPitchLP = 344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).lastPitchLP; 345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pitchGain = (ISACdec_obj->plcstr_obj).lastPitchGain_Q12; 347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_AutoCorrelation( 349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0], 350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lag0, 0, &varIn, &rightShiftIn); 351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_AutoCorrelation( 352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &(ISACdec_obj->plcstr_obj).prevPitchInvOut[PITCH_MAX_LAG + 10 - lag0], 353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lag0, 0, &varOut, &rightShiftOut); 354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com maxAbs = 0; 356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0; i< lag0; i++) 357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myAbs = WEBRTC_SPL_ABS_W16( 359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).prevPitchInvOut[ 360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PITCH_MAX_LAG + 10 - lag0 + i] ); 361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com maxAbs = (myAbs > maxAbs)? myAbs:maxAbs; 362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3630946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org logVarIn = log2_Q8_T( (uint32_t)( varIn ) ) + 3640946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)(rightShiftIn << 8); 3650946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org logVarOut = log2_Q8_T( (uint32_t)( varOut ) ) + 3660946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)(rightShiftOut << 8); 3670946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org logMaxAbs = log2_Q8_T( (uint32_t)( maxAbs ) ); 368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org ltpGain = (int16_t)(logVarOut - logVarIn); 370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Q = 2 * logMaxAbs - ( logVarOut - 1512 ); 371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* 373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * --- 374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * We are computing sqrt( (VarIn/lag0) / var( noise ) ) 375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * var( noise ) is almost 256. we have already computed log2( VarIn ) in Q8 376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * so we actually compute 2^( 0.5*(log2( VarIn ) - log2( lag0 ) - log2( var(noise ) ) ). 377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Note that put log function is in Q8 but the exponential function is in Q10. 378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * -- 379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3810946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org logVarIn -= log2_Q8_T( (uint32_t)( lag0 ) ); 3820946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org tmp16 = (int16_t)((logVarIn<<1) - (4<<10) ); 383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rightShiftIn = 0; 384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( tmp16 > 4096 ) 385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16 -= 4096; 387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16 = exp2_Q10_T( tmp16 ); 388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16 >>= 6; 389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp16 = exp2_Q10_T( tmp16 )>>10; 392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).std = tmp16 - 4; 394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ltpGain < 110) || (ltpGain > 230) ) 396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( ltpGain < 100 && (pitchGain < 1800) ) 398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).A = WEBRTC_SPL_WORD16_MAX; 400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).A = ((ltpGain < 110) && (Q < 800) 404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com )? WEBRTC_SPL_WORD16_MAX:0; 405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX - 407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).A; 408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (pitchGain < 450) || (pitchGain > 1600) ) 412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).A = ((pitchGain < 450) 414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com )? WEBRTC_SPL_WORD16_MAX:0; 415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX - 416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).A; 417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myVoiceIndicator = ltpGain * 2 + pitchGain; 421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com MemshipValQ15( myVoiceIndicator, 422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B ); 423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myVoiceIndicator = ltpGain * 16 + pitchGain * 2 + (pitchGain >> 8); 429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com MemshipValQ15( myVoiceIndicator, 430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B ); 431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = lag0; 435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex = 0; 436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myDecayRate = (DECAY_RATE<<2); 441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).B < 1000 ) 444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myDecayRate += (DECAY_RATE<<3); 446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------------ reconstructing the residual signal ------------------ */ 449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP, 451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* inverse pitch filter */ 453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pitchLags_Q7[0] = pitchLags_Q7[1] = pitchLags_Q7[2] = pitchLags_Q7[3] = 455b7e5054414ff524f9db81dab7917729b8c4c8bcbPeter Kasting (int16_t)((ISACdec_obj->plcstr_obj).stretchLag<<7); 456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com pitchGains_Q12[3] = ( (ISACdec_obj->plcstr_obj).lastPitchGain_Q12); 457f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker pitchGains_Q12[2] = (int16_t)(pitchGains_Q12[3] * 1010 >> 10); 458f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker pitchGains_Q12[1] = (int16_t)(pitchGains_Q12[2] * 1010 >> 10); 459f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker pitchGains_Q12[0] = (int16_t)(pitchGains_Q12[1] * 1010 >> 10); 460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* most of the time either B or A are zero so seperating */ 463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).B == 0 ) 464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0; i < FRAMESAMPLES_HALF; i++ ) 466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Low Pass */ 468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed ); 470f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org Vector_Word16_1[i] = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Highpass */ 473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed ); 475f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org Vector_Word16_2[i] = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 1; i < NOISE_FILTER_LEN; i++ ) 479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed ); 482f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org Vector_Word16_Extended_1[i] = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed ); 486f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org Vector_Word16_Extended_2[i] = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com plc_filterma_Fast(Vector_Word16_1, Vector_Word16_Extended_1, 489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - 4900946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org NOISE_FILTER_LEN], (int16_t) NOISE_FILTER_LEN, 4910946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int16_t) FRAMESAMPLES_HALF, (int16_t)(5), 4920946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (ISACdec_obj->plcstr_obj).decayCoeffNoise, (int16_t)(6)); 493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com maxCoeff = WebRtcSpl_MaxAbsValueW32( 495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &(ISACdec_obj->plcstr_obj).prevHP[ 496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN], NOISE_FILTER_LEN ); 497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rshift = 0; 499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com while( maxCoeff > WEBRTC_SPL_WORD16_MAX ) 500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 501a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org maxCoeff >>= 1; 502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rshift++; 503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0; i < NOISE_FILTER_LEN; i++ ) { 505a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org Vector_Word16_1[FRAMESAMPLES_HALF - NOISE_FILTER_LEN + i] =(int16_t)( 506a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org ISACdec_obj->plcstr_obj.prevHP[PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN + 507a296725d0eea443b6cb181262069433866e2849fbjornv@webrtc.org i] >> rshift); 508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffNoise = plc_filterma_Fast( 510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_2, 511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_Extended_2, 512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &Vector_Word16_1[FRAMESAMPLES_HALF - NOISE_FILTER_LEN], 5130946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int16_t) NOISE_FILTER_LEN, 5140946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int16_t) FRAMESAMPLES_HALF, 5150946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int16_t) (5), 516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffNoise, 5170946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int16_t) (7) ); 518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0; i < FRAMESAMPLES_HALF; i++ ) 520d4e75016a3836c3aab992afff6bfd8d5e3862aacBjorn Volcker Vector_Word32_2[i] = Vector_Word16_Extended_2[i] << rshift; 521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_1 = Vector_Word16_Extended_1; 523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).A == 0 ) 527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------ Periodic Vector --- */ 529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ ) 530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Lowpass */ 532f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker pLP = (int16_t)(stretchPitchLP[ISACdec_obj->plcstr_obj.pitchIndex] * 533f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker ISACdec_obj->plcstr_obj.decayCoeffPriodic >> 15); 534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Highpass */ 5360946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org pHP = (int32_t)WEBRTC_SPL_MUL_16_32_RSFT15( 537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 - 539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag + 540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex] ); 541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- lower the muliplier (more decay at next sample) --- */ 543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate); 544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 ) 545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0; 546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex++; 548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).pitchIndex == 550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag ) 551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex = 0; 553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchCycles++; 554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) ) 556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1; 558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = lag0; 562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = ( 565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG 566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com )? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag; 567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP, 569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LinearResampler( (ISACdec_obj->plcstr_obj).prevPitchLP, 572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch( (ISACdec_obj->plcstr_obj).pitchCycles ) 575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 1: 577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5800946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org stretchPitchLP[k] = (int16_t)(( 5810946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP[k]* 3 + 5820946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP1[k])>>2); 583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 2: 587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5900946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org stretchPitchLP[k] = (int16_t)(( 5910946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP[k] + 5920946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP1[k] )>>1); 593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 3: 597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6000946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org stretchPitchLP[k] = (int16_t)((stretchPitchLP[k] + 6010946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP1[k]*3 )>>2); 602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 ) 608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myDecayRate += 35; //(myDecayRate>>1); 610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchCycles = 0; 611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------ Sum the noisy and periodic signals ------ */ 616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_1[i] = pLP; 617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word32_2[i] = pHP; 618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ ) 623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed ); 627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 628f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org noise1 = (ISACdec_obj->plcstr_obj.seed >> 10) - 16; 629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 630f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker nLP = (int16_t)((int16_t)(noise1 * ISACdec_obj->plcstr_obj.std) * 631f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker ISACdec_obj->plcstr_obj.decayCoeffNoise >> 15); 632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Highpass */ 634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND( 635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).seed ); 636f71785cd3b282ad7d584d746ba5b19833a11692bbjornv@webrtc.org noise1 = (ISACdec_obj->plcstr_obj.seed >> 11) - 8; 637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6380946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org nHP = (int32_t)WEBRTC_SPL_MUL_16_32_RSFT15( 639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffNoise, 6400946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)(noise1*(ISACdec_obj->plcstr_obj).std) ); 641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- lower the muliplier (more decay at next sample) --- */ 643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffNoise -= (myDecayRate); 644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).decayCoeffNoise < 0 ) 645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffNoise = 0; 646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------ Periodic Vector --- */ 648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Lowpass */ 649f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker pLP = (int16_t)(stretchPitchLP[ISACdec_obj->plcstr_obj.pitchIndex] * 650f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker ISACdec_obj->plcstr_obj.decayCoeffPriodic >> 15); 651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Highpass */ 6530946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org pHP = (int32_t)WEBRTC_SPL_MUL_16_32_RSFT15( 654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 - 656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag + 657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex] ); 658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- lower the muliplier (more decay at next sample) --- */ 660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate); 661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 ) 662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0; 664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------ Weighting the noisy and periodic vectors ------- */ 667f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker wNoisyLP = (int16_t)(ISACdec_obj->plcstr_obj.A * nLP >> 15); 6680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org wNoisyHP = (int32_t)(WEBRTC_SPL_MUL_16_32_RSFT15( 669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).A, (nHP) ) ); 670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 671f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker wPriodicLP = (int16_t)(ISACdec_obj->plcstr_obj.B * pLP >> 15); 6720946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org wPriodicHP = (int32_t)(WEBRTC_SPL_MUL_16_32_RSFT15( 673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).B, pHP)); 674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex++; 676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if((ISACdec_obj->plcstr_obj).pitchIndex == 678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag) 679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchIndex = 0; 681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchCycles++; 682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) ) 684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1; 685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = lag0; 687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag = ( 689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG 690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com )? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag; 691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LinearResampler( 692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).lastPitchLP, 693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com LinearResampler((ISACdec_obj->plcstr_obj).prevPitchLP, 696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag ); 697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch((ISACdec_obj->plcstr_obj).pitchCycles) 699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 1: 701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 7040946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org stretchPitchLP[k] = (int16_t)(( 7050946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP[k]* 3 + 7060946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP1[k] )>>2); 707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 2: 711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 7140946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org stretchPitchLP[k] = (int16_t)(( 7150946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP[k] + 7160946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP1[k])>>1); 717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case 3: 721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ ) 723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 7240946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org stretchPitchLP[k] = (int16_t)( 725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (stretchPitchLP[k] + 7260946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org (int32_t)stretchPitchLP1[k]*3 )>>2); 727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 ) 733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com myDecayRate += 55; //(myDecayRate>>1); 735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).pitchCycles = 0; 736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ------ Sum the noisy and periodic signals ------ */ 7406e71d17bc98d3b179f55fd4fd42dc5c53b7787dcbjornv@webrtc.org Vector_Word16_1[i] = WebRtcSpl_AddSatW16(wNoisyLP, wPriodicLP); 7416e71d17bc98d3b179f55fd4fd42dc5c53b7787dcbjornv@webrtc.org Vector_Word32_2[i] = WebRtcSpl_AddSatW32(wNoisyHP, wPriodicHP); 742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* ----------------- residual signal is reconstructed ------------------ */ 746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com k = (ISACdec_obj->plcstr_obj).pitchIndex; 748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Write one pitch cycle for recovery block --- */ 749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for( i = 0; i < RECOVERY_OVERLAP; i++ ) 751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 752f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker ISACdec_obj->plcstr_obj.overlapLP[i] = (int16_t)( 753f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker stretchPitchLP[k] * ISACdec_obj->plcstr_obj.decayCoeffPriodic >> 15); 754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com k = ( k < ((ISACdec_obj->plcstr_obj).stretchLag - 1) )? (k+1):0; 755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 757b7e5054414ff524f9db81dab7917729b8c4c8bcbPeter Kasting (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = 758b7e5054414ff524f9db81dab7917729b8c4c8bcbPeter Kasting (int16_t)((ISACdec_obj->plcstr_obj).stretchLag << 7); 759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* --- Inverse Pitch Filter --- */ 762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2, 763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &ISACdec_obj->pitchfiltstr_obj, pitchLags_Q7, pitchGains_Q12, 4); 764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* reduce gain to compensate for pitch enhancer */ 766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* gain = 1.0f - 0.45f * AvgPitchGain; */ 767f2822edf611ff187eab61abccd9edb2edac4ba64Bjorn Volcker tmp32a = ISACdec_obj->plcstr_obj.AvgPitchGain_Q12 * 29; // Q18 768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tmp32b = 262144 - tmp32a; // Q18 7690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org gainQ13 = (int16_t) (tmp32b >> 5); // Q13 770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* perceptual post-filtering (using normalized lattice filter) */ 772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k = 0; k < FRAMESAMPLES_HALF; k++) 773bc2bb34419021fb3be4f87eb062cf0a9ed52675abjornv@webrtc.org Vector_Word32_1[k] = (Vector_Word16_2[k] * gainQ13) << 3; // Q25 774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIsacfix_NormLatticeFilterAr(ORDERLO, 777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0, 778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1); 779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIsacfix_NormLatticeFilterAr(ORDERHI, 781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0, 782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word32_2, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2); 783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* recombine the 2 bands */ 785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Form the polyphase signals, and compensate for DC offset */ 787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (k=0;k<FRAMESAMPLES_HALF;k++) 788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Construct a new upper channel signal*/ 7900946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org tmp_1 = (int16_t)WebRtcSpl_SatW32ToW16( 7910946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org ((int32_t)Vector_Word16_1[k]+Vector_Word16_2[k] + 1)); 792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Construct a new lower channel signal*/ 7930946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org tmp_2 = (int16_t)WebRtcSpl_SatW32ToW16( 7940946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org ((int32_t)Vector_Word16_1[k]-Vector_Word16_2[k])); 795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_1[k] = tmp_1; 796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_2[k] = tmp_2; 797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1, 801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Vector_Word16_2, signal_out16, &ISACdec_obj->postfiltbankstr_obj); 802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ISACdec_obj->plcstr_obj).used = PLC_WAS_USED; 804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *current_framesamples = 480; 805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 806