1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libopus/silk/resampler_private_IIR_FIR.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,107 @@ 1.4 +/*********************************************************************** 1.5 +Copyright (c) 2006-2011, Skype Limited. All rights reserved. 1.6 +Redistribution and use in source and binary forms, with or without 1.7 +modification, are permitted provided that the following conditions 1.8 +are met: 1.9 +- Redistributions of source code must retain the above copyright notice, 1.10 +this list of conditions and the following disclaimer. 1.11 +- Redistributions in binary form must reproduce the above copyright 1.12 +notice, this list of conditions and the following disclaimer in the 1.13 +documentation and/or other materials provided with the distribution. 1.14 +- Neither the name of Internet Society, IETF or IETF Trust, nor the 1.15 +names of specific contributors, may be used to endorse or promote 1.16 +products derived from this software without specific prior written 1.17 +permission. 1.18 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1.19 +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.20 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.21 +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 1.22 +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.23 +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.24 +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.25 +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.26 +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.27 +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 1.28 +POSSIBILITY OF SUCH DAMAGE. 1.29 +***********************************************************************/ 1.30 + 1.31 +#ifdef HAVE_CONFIG_H 1.32 +#include "config.h" 1.33 +#endif 1.34 + 1.35 +#include "SigProc_FIX.h" 1.36 +#include "resampler_private.h" 1.37 +#include "stack_alloc.h" 1.38 + 1.39 +static OPUS_INLINE opus_int16 *silk_resampler_private_IIR_FIR_INTERPOL( 1.40 + opus_int16 *out, 1.41 + opus_int16 *buf, 1.42 + opus_int32 max_index_Q16, 1.43 + opus_int32 index_increment_Q16 1.44 +) 1.45 +{ 1.46 + opus_int32 index_Q16, res_Q15; 1.47 + opus_int16 *buf_ptr; 1.48 + opus_int32 table_index; 1.49 + 1.50 + /* Interpolate upsampled signal and store in output array */ 1.51 + for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { 1.52 + table_index = silk_SMULWB( index_Q16 & 0xFFFF, 12 ); 1.53 + buf_ptr = &buf[ index_Q16 >> 16 ]; 1.54 + 1.55 + res_Q15 = silk_SMULBB( buf_ptr[ 0 ], silk_resampler_frac_FIR_12[ table_index ][ 0 ] ); 1.56 + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 1 ], silk_resampler_frac_FIR_12[ table_index ][ 1 ] ); 1.57 + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 2 ], silk_resampler_frac_FIR_12[ table_index ][ 2 ] ); 1.58 + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 3 ], silk_resampler_frac_FIR_12[ table_index ][ 3 ] ); 1.59 + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 4 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 3 ] ); 1.60 + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 5 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 2 ] ); 1.61 + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 6 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 1 ] ); 1.62 + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 7 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 0 ] ); 1.63 + *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q15, 15 ) ); 1.64 + } 1.65 + return out; 1.66 +} 1.67 +/* Upsample using a combination of allpass-based 2x upsampling and FIR interpolation */ 1.68 +void silk_resampler_private_IIR_FIR( 1.69 + void *SS, /* I/O Resampler state */ 1.70 + opus_int16 out[], /* O Output signal */ 1.71 + const opus_int16 in[], /* I Input signal */ 1.72 + opus_int32 inLen /* I Number of input samples */ 1.73 +) 1.74 +{ 1.75 + silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; 1.76 + opus_int32 nSamplesIn; 1.77 + opus_int32 max_index_Q16, index_increment_Q16; 1.78 + VARDECL( opus_int16, buf ); 1.79 + SAVE_STACK; 1.80 + 1.81 + ALLOC( buf, 2 * S->batchSize + RESAMPLER_ORDER_FIR_12, opus_int16 ); 1.82 + 1.83 + /* Copy buffered samples to start of buffer */ 1.84 + silk_memcpy( buf, S->sFIR.i16, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); 1.85 + 1.86 + /* Iterate over blocks of frameSizeIn input samples */ 1.87 + index_increment_Q16 = S->invRatio_Q16; 1.88 + while( 1 ) { 1.89 + nSamplesIn = silk_min( inLen, S->batchSize ); 1.90 + 1.91 + /* Upsample 2x */ 1.92 + silk_resampler_private_up2_HQ( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_12 ], in, nSamplesIn ); 1.93 + 1.94 + max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 + 1 ); /* + 1 because 2x upsampling */ 1.95 + out = silk_resampler_private_IIR_FIR_INTERPOL( out, buf, max_index_Q16, index_increment_Q16 ); 1.96 + in += nSamplesIn; 1.97 + inLen -= nSamplesIn; 1.98 + 1.99 + if( inLen > 0 ) { 1.100 + /* More iterations to do; copy last part of filtered signal to beginning of buffer */ 1.101 + silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); 1.102 + } else { 1.103 + break; 1.104 + } 1.105 + } 1.106 + 1.107 + /* Copy last part of filtered signal to the state for the next call */ 1.108 + silk_memcpy( S->sFIR.i16, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); 1.109 + RESTORE_STACK; 1.110 +}