1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * filterbanks.c 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This file contains function 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsacfix_SplitAndFilter, and WebRtcIsacfix_FilterAndCombine 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * which implement filterbanks that produce decimated lowpass and 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * highpass versions of a signal, and performs reconstruction. 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "filterbank_internal.h" 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 23d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org#include <assert.h> 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 25d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org#include "codec.h" 26d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org#include "filterbank_tables.h" 27d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org#include "settings.h" 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 29a9902801d5b79ccbbf117cae2676dadeb6686308kma@webrtc.org// Declare a function pointer. 30a9902801d5b79ccbbf117cae2676dadeb6686308kma@webrtc.orgAllpassFilter2FixDec16 WebRtcIsacfix_AllpassFilter2FixDec16; 31a9902801d5b79ccbbf117cae2676dadeb6686308kma@webrtc.org 32d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.orgvoid WebRtcIsacfix_AllpassFilter2FixDec16C( 33d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org int16_t *data_ch1, // Input and output in channel 1, in Q0 34d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org int16_t *data_ch2, // Input and output in channel 2, in Q0 35d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org const int16_t *factor_ch1, // Scaling factor for channel 1, in Q15 36d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org const int16_t *factor_ch2, // Scaling factor for channel 2, in Q15 37d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org const int length, // Length of the data buffers 38d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org int32_t *filter_state_ch1, // Filter state for channel 1, in Q16 39d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org int32_t *filter_state_ch2) { // Filter state for channel 2, in Q16 40d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org int n = 0; 41d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org int32_t state0_ch1 = filter_state_ch1[0], state1_ch1 = filter_state_ch1[1]; 42d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org int32_t state0_ch2 = filter_state_ch2[0], state1_ch2 = filter_state_ch2[1]; 43d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org int16_t in_out = 0; 44d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org int32_t a = 0, b = 0; 45d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org 46d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org // Assembly file assumption. 47d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org assert(length % 2 == 0); 48d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org 49d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org for (n = 0; n < length; n++) { 50d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org // Process channel 1: 51d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org in_out = data_ch1[n]; 52d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org a = WEBRTC_SPL_MUL_16_16(factor_ch1[0], in_out); // Q15 * Q0 = Q15 53d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org a <<= 1; // Q15 -> Q16 54347671c843ed5c93d25bf1a23f9295d35ce3df4abjornv@webrtc.org b = WebRtcSpl_AddSatW32(a, state0_ch1); 55d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org a = WEBRTC_SPL_MUL_16_16(-factor_ch1[0], (int16_t) (b >> 16)); // Q15 56347671c843ed5c93d25bf1a23f9295d35ce3df4abjornv@webrtc.org state0_ch1 = WebRtcSpl_AddSatW32(a << 1, (uint32_t)in_out << 16); // Q16 57d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org in_out = (int16_t) (b >> 16); // Save as Q0 58d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org 59d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org a = WEBRTC_SPL_MUL_16_16(factor_ch1[1], in_out); // Q15 * Q0 = Q15 60d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org a <<= 1; // Q15 -> Q16 61347671c843ed5c93d25bf1a23f9295d35ce3df4abjornv@webrtc.org b = WebRtcSpl_AddSatW32(a, state1_ch1); // Q16 62d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org a = WEBRTC_SPL_MUL_16_16(-factor_ch1[1], (int16_t) (b >> 16)); // Q15 63347671c843ed5c93d25bf1a23f9295d35ce3df4abjornv@webrtc.org state1_ch1 = WebRtcSpl_AddSatW32(a << 1, (uint32_t)in_out << 16); // Q16 64d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org data_ch1[n] = (int16_t) (b >> 16); // Save as Q0 65d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org 66d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org // Process channel 2: 67d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org in_out = data_ch2[n]; 68d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org a = WEBRTC_SPL_MUL_16_16(factor_ch2[0], in_out); // Q15 * Q0 = Q15 69d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org a <<= 1; // Q15 -> Q16 70347671c843ed5c93d25bf1a23f9295d35ce3df4abjornv@webrtc.org b = WebRtcSpl_AddSatW32(a, state0_ch2); // Q16 71d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org a = WEBRTC_SPL_MUL_16_16(-factor_ch2[0], (int16_t) (b >> 16)); // Q15 72347671c843ed5c93d25bf1a23f9295d35ce3df4abjornv@webrtc.org state0_ch2 = WebRtcSpl_AddSatW32(a << 1, (uint32_t)in_out << 16); // Q16 73d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org in_out = (int16_t) (b >> 16); // Save as Q0 74d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org 75d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org a = WEBRTC_SPL_MUL_16_16(factor_ch2[1], in_out); // Q15 * Q0 = Q15 76d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org a <<= 1; // Q15 -> Q16 77347671c843ed5c93d25bf1a23f9295d35ce3df4abjornv@webrtc.org b = WebRtcSpl_AddSatW32(a, state1_ch2); // Q16 78d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org a = WEBRTC_SPL_MUL_16_16(-factor_ch2[1], (int16_t) (b >> 16)); // Q15 79347671c843ed5c93d25bf1a23f9295d35ce3df4abjornv@webrtc.org state1_ch2 = WebRtcSpl_AddSatW32(a << 1, (uint32_t)in_out << 16); // Q16 80d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org data_ch2[n] = (int16_t) (b >> 16); // Save as Q0 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 83d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org filter_state_ch1[0] = state0_ch1; 84d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org filter_state_ch1[1] = state1_ch1; 85d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org filter_state_ch2[0] = state0_ch2; 86d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org filter_state_ch2[1] = state1_ch2; 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 89e4834e042a794dbf042bfd0934e335598d7ce4b8andrew@webrtc.org// Declare a function pointer. 90e4834e042a794dbf042bfd0934e335598d7ce4b8andrew@webrtc.orgHighpassFilterFixDec32 WebRtcIsacfix_HighpassFilterFixDec32; 91e4834e042a794dbf042bfd0934e335598d7ce4b8andrew@webrtc.org 92e4834e042a794dbf042bfd0934e335598d7ce4b8andrew@webrtc.orgvoid WebRtcIsacfix_HighpassFilterFixDec32C(int16_t *io, 93e4834e042a794dbf042bfd0934e335598d7ce4b8andrew@webrtc.org int16_t len, 94e4834e042a794dbf042bfd0934e335598d7ce4b8andrew@webrtc.org const int16_t *coefficient, 95e4834e042a794dbf042bfd0934e335598d7ce4b8andrew@webrtc.org int32_t *state) 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 98fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t a1 = 0, b1 = 0, c = 0, in = 0; 99fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t a2 = 0, b2 = 0; 100fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t state0 = state[0]; 101fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t state1 = state[1]; 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<len; k++) { 104fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org in = (int32_t)io[k]; 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef WEBRTC_ARCH_ARM_V7 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 10839dec2c6b1537a46bb35fecc0dd2ffca28bb58a8bjornv@webrtc.org register int tmp_coeff0; 10939dec2c6b1537a46bb35fecc0dd2ffca28bb58a8bjornv@webrtc.org register int tmp_coeff1; 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org __asm __volatile( 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "ldr %[tmp_coeff0], [%[coeff]]\n\t" 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "ldr %[tmp_coeff1], [%[coeff], #4]\n\t" 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "smmulr %[a2], %[tmp_coeff0], %[state0]\n\t" 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "smmulr %[b2], %[tmp_coeff1], %[state1]\n\t" 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "ldr %[tmp_coeff0], [%[coeff], #8]\n\t" 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "ldr %[tmp_coeff1], [%[coeff], #12]\n\t" 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "smmulr %[a1], %[tmp_coeff0], %[state0]\n\t" 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "smmulr %[b1], %[tmp_coeff1], %[state1]\n\t" 11939dec2c6b1537a46bb35fecc0dd2ffca28bb58a8bjornv@webrtc.org :[a2]"=&r"(a2), 12039dec2c6b1537a46bb35fecc0dd2ffca28bb58a8bjornv@webrtc.org [b2]"=&r"(b2), 12139dec2c6b1537a46bb35fecc0dd2ffca28bb58a8bjornv@webrtc.org [a1]"=&r"(a1), 12239dec2c6b1537a46bb35fecc0dd2ffca28bb58a8bjornv@webrtc.org [b1]"=r"(b1), 12339dec2c6b1537a46bb35fecc0dd2ffca28bb58a8bjornv@webrtc.org [tmp_coeff0]"=&r"(tmp_coeff0), 12439dec2c6b1537a46bb35fecc0dd2ffca28bb58a8bjornv@webrtc.org [tmp_coeff1]"=&r"(tmp_coeff1) 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org :[coeff]"r"(coefficient), 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [state0]"r"(state0), 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [state1]"r"(state1) 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ); 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Q35 * Q4 = Q39 ; shift 32 bit => Q7 */ 132b5cd1aa773e4e5bc6ab84ded200ff3a618086032bjornv@webrtc.org a1 = WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[5], state0) + 133b5cd1aa773e4e5bc6ab84ded200ff3a618086032bjornv@webrtc.org (WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[4], state0) >> 16); 134b5cd1aa773e4e5bc6ab84ded200ff3a618086032bjornv@webrtc.org b1 = WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[7], state1) + 135b5cd1aa773e4e5bc6ab84ded200ff3a618086032bjornv@webrtc.org (WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[6], state1) >> 16); 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Q30 * Q4 = Q34 ; shift 32 bit => Q2 */ 138b5cd1aa773e4e5bc6ab84ded200ff3a618086032bjornv@webrtc.org a2 = WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[1], state0) + 139b5cd1aa773e4e5bc6ab84ded200ff3a618086032bjornv@webrtc.org (WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[0], state0) >> 16); 140b5cd1aa773e4e5bc6ab84ded200ff3a618086032bjornv@webrtc.org b2 = WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[3], state1) + 141b5cd1aa773e4e5bc6ab84ded200ff3a618086032bjornv@webrtc.org (WEBRTC_SPL_MUL_16_32_RSFT16(coefficient[2], state1) >> 16); 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 144fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org c = ((int32_t)in) + WEBRTC_SPL_RSHIFT_W32(a1+b1, 7); // Q0 145fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org io[k] = (int16_t)WebRtcSpl_SatW32ToW16(c); // Write output as Q0. 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 147fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org c = WEBRTC_SPL_LSHIFT_W32((int32_t)in, 2) - a2 - b2; // In Q2. 148fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org c = (int32_t)WEBRTC_SPL_SAT(536870911, c, -536870912); 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org state1 = state0; 151d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org state0 = WEBRTC_SPL_LSHIFT_W32(c, 2); // Write state as Q4 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org state[0] = state0; 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org state[1] = state1; 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 158fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgvoid WebRtcIsacfix_SplitAndFilter1(int16_t *pin, 159fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *LP16, 160fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *HP16, 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PreFiltBankstr *prefiltdata) 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Function WebRtcIsacfix_SplitAndFilter */ 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* This function creates low-pass and high-pass decimated versions of part of 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org the input signal, and part of the signal in the input 'lookahead buffer'. */ 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 169fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t tempin_ch1[FRAMESAMPLES/2 + QLOOKAHEAD]; 170fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t tempin_ch2[FRAMESAMPLES/2 + QLOOKAHEAD]; 171fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpState_ch1[2 * (QORDER-1)]; /* 4 */ 172fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmpState_ch2[2 * (QORDER-1)]; /* 4 */ 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* High pass filter */ 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix); 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* First Channel */ 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0;k<FRAMESAMPLES/2;k++) { 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempin_ch1[QLOOKAHEAD + k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)]; 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0;k<QLOOKAHEAD;k++) { 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempin_ch1[k]=prefiltdata->INLABUF1_fix[k]; 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org prefiltdata->INLABUF1_fix[k]=pin[FRAMESAMPLES+1-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)]; 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Second Channel. This is exactly like the first channel, except that the 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org even samples are now filtered instead (lower channel). */ 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0;k<FRAMESAMPLES/2;k++) { 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempin_ch2[QLOOKAHEAD+k] = pin[WEBRTC_SPL_MUL_16_16(2, k)]; 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0;k<QLOOKAHEAD;k++) { 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempin_ch2[k]=prefiltdata->INLABUF2_fix[k]; 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org prefiltdata->INLABUF2_fix[k]=pin[FRAMESAMPLES-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)]; 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /*obtain polyphase components by forward all-pass filtering through each channel */ 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* The all pass filtering automatically updates the filter states which are exported in the 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org prefiltdata structure */ 201d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1, 202d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org tempin_ch2, 203d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_kUpperApFactorsQ15, 204d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_kLowerApFactorsQ15, 205d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org FRAMESAMPLES/2, 206d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org prefiltdata->INSTAT1_fix, 207d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org prefiltdata->INSTAT2_fix); 208d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org 209d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++) { 210d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org tmpState_ch1[k] = prefiltdata->INSTAT1_fix[k]; 211d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org tmpState_ch2[k] = prefiltdata->INSTAT2_fix[k]; 212d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org } 213d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1 + FRAMESAMPLES/2, 214d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org tempin_ch2 + FRAMESAMPLES/2, 215d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_kUpperApFactorsQ15, 216d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_kLowerApFactorsQ15, 217d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org QLOOKAHEAD, 218d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org tmpState_ch1, 219d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org tmpState_ch2); 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Now Construct low-pass and high-pass signals as combinations of polyphase components */ 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<FRAMESAMPLES/2 + QLOOKAHEAD; k++) { 223fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmp1, tmp2, tmp3; 224fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp1 = (int32_t)tempin_ch1[k]; // Q0 -> Q0 225fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp2 = (int32_t)tempin_ch2[k]; // Q0 -> Q0 226fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/ 227fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */ 228fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/ 229fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */ 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}/*end of WebRtcIsacfix_SplitAndFilter */ 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Without lookahead */ 238fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgvoid WebRtcIsacfix_SplitAndFilter2(int16_t *pin, 239fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *LP16, 240fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *HP16, 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PreFiltBankstr *prefiltdata) 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Function WebRtcIsacfix_SplitAndFilter2 */ 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* This function creates low-pass and high-pass decimated versions of part of 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org the input signal. */ 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 249fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t tempin_ch1[FRAMESAMPLES/2]; 250fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t tempin_ch2[FRAMESAMPLES/2]; 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* High pass filter */ 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix); 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* First Channel */ 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0;k<FRAMESAMPLES/2;k++) { 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempin_ch1[k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)]; 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Second Channel. This is exactly like the first channel, except that the 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org even samples are now filtered instead (lower channel). */ 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0;k<FRAMESAMPLES/2;k++) { 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempin_ch2[k] = pin[WEBRTC_SPL_MUL_16_16(2, k)]; 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /*obtain polyphase components by forward all-pass filtering through each channel */ 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* The all pass filtering automatically updates the filter states which are exported in the 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org prefiltdata structure */ 272d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1, 273d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org tempin_ch2, 274d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_kUpperApFactorsQ15, 275d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_kLowerApFactorsQ15, 276d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org FRAMESAMPLES/2, 277d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org prefiltdata->INSTAT1_fix, 278d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org prefiltdata->INSTAT2_fix); 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Now Construct low-pass and high-pass signals as combinations of polyphase components */ 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0; k<FRAMESAMPLES/2; k++) { 282fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t tmp1, tmp2, tmp3; 283fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp1 = (int32_t)tempin_ch1[k]; // Q0 -> Q0 284fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp2 = (int32_t)tempin_ch2[k]; // Q0 -> Q0 285fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/ 286fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org LP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */ 287fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org tmp3 = (int32_t)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/ 288fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org HP16[k] = (int16_t)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */ 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}/*end of WebRtcIsacfix_SplitAndFilter */ 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org////////////////////////////////////////////////////////// 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org////////// Combining 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Function WebRtcIsacfix_FilterAndCombine */ 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* This is a decoder function that takes the decimated 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org length FRAMESAMPLES/2 input low-pass and 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org high-pass signals and creates a reconstructed fullband 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org output signal of length FRAMESAMPLES. WebRtcIsacfix_FilterAndCombine 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org is the sibling function of WebRtcIsacfix_SplitAndFilter */ 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* INPUTS: 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inLP: a length FRAMESAMPLES/2 array of input low-pass 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org samples. 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inHP: a length FRAMESAMPLES/2 array of input high-pass 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org samples. 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org postfiltdata: input data structure containing the filterbank 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org states from the previous decoding iteration. 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org OUTPUTS: 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Out: a length FRAMESAMPLES array of output reconstructed 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org samples (fullband) based on the input low-pass and 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org high-pass signals. 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org postfiltdata: the input data structure containing the filterbank 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org states is updated for the next decoding iteration */ 318fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgvoid WebRtcIsacfix_FilterAndCombine1(int16_t *tempin_ch1, 319fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *tempin_ch2, 320fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *out16, 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PostFiltBankstr *postfiltdata) 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 324fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t in[FRAMESAMPLES]; 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 326d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org /* all-pass filter the new upper and lower channel signal. 327d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org For upper channel, use the all-pass filter factors that were used as a 328d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org lower channel at the encoding side. So at the decoder, the corresponding 329d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org all-pass filter factors for each channel are swapped. 330d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org For lower channel signal, since all-pass filter factors at the decoder are 331d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org swapped from the ones at the encoder, the 'upper' channel all-pass filter 332d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org factors (kUpperApFactors) are used to filter this new lower channel signal. 333d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org */ 334d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1, 335d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org tempin_ch2, 336d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_kLowerApFactorsQ15, 337d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_kUpperApFactorsQ15, 338d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org FRAMESAMPLES/2, 339d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org postfiltdata->STATE_0_UPPER_fix, 340d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org postfiltdata->STATE_0_LOWER_fix); 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Merge outputs to form the full length output signal.*/ 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0;k<FRAMESAMPLES/2;k++) { 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k]; 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k]; 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* High pass filter */ 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix); 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix); 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0;k<FRAMESAMPLES;k++) { 353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org out16[k] = in[k]; 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Function WebRtcIsacfix_FilterAndCombine */ 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* This is a decoder function that takes the decimated 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org length len/2 input low-pass and 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org high-pass signals and creates a reconstructed fullband 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org output signal of length len. WebRtcIsacfix_FilterAndCombine 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org is the sibling function of WebRtcIsacfix_SplitAndFilter */ 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* INPUTS: 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inLP: a length len/2 array of input low-pass 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org samples. 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inHP: a length len/2 array of input high-pass 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org samples. 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org postfiltdata: input data structure containing the filterbank 371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org states from the previous decoding iteration. 372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org OUTPUTS: 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Out: a length len array of output reconstructed 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org samples (fullband) based on the input low-pass and 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org high-pass signals. 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org postfiltdata: the input data structure containing the filterbank 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org states is updated for the next decoding iteration */ 378fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgvoid WebRtcIsacfix_FilterAndCombine2(int16_t *tempin_ch1, 379fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *tempin_ch2, 380fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *out16, 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PostFiltBankstr *postfiltdata, 382fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t len) 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 385fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t in[FRAMESAMPLES]; 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 387d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org /* all-pass filter the new upper and lower channel signal. 388d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org For upper channel, use the all-pass filter factors that were used as a 389d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org lower channel at the encoding side. So at the decoder, the corresponding 390d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org all-pass filter factors for each channel are swapped. 391d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org For lower channel signal, since all-pass filter factors at the decoder are 392d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org swapped from the ones at the encoder, the 'upper' channel all-pass filter 393d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org factors (kUpperApFactors) are used to filter this new lower channel signal. 394d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org */ 395d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_AllpassFilter2FixDec16(tempin_ch1, 396d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org tempin_ch2, 397d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_kLowerApFactorsQ15, 398d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org WebRtcIsacfix_kUpperApFactorsQ15, 399d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org len / 2, 400d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org postfiltdata->STATE_0_UPPER_fix, 401d0ea5f0cdd6bee478e94877a564fedefa84cadd7kma@webrtc.org postfiltdata->STATE_0_LOWER_fix); 402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Merge outputs to form the full length output signal.*/ 404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0;k<len/2;k++) { 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k]; 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k]; 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* High pass filter */ 410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix); 411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix); 412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k=0;k<len;k++) { 414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org out16[k] = in[k]; 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 419