From c155873e53275e8902616623339fbe589ad2e24f Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 25 Aug 2011 17:30:25 -0500 Subject: [PATCH] Silk part two... doh --- .../silk/src/SKP_Silk_apply_sine_window_new.c | 101 ++++++ .../src/SKP_Silk_control_audio_bandwidth.c | 137 ++++++++ libs/silk/src/SKP_Silk_decode_pitch.c | 57 ++++ libs/silk/src/SKP_Silk_resampler.c | 323 ++++++++++++++++++ libs/silk/src/SKP_Silk_resampler_down2.c | 77 +++++ libs/silk/src/SKP_Silk_resampler_down2_3.c | 102 ++++++ libs/silk/src/SKP_Silk_resampler_down3.c | 93 +++++ libs/silk/src/SKP_Silk_resampler_private.h | 131 +++++++ .../silk/src/SKP_Silk_resampler_private_AR2.c | 58 ++++ .../src/SKP_Silk_resampler_private_ARMA4.c | 77 +++++ .../src/SKP_Silk_resampler_private_IIR_FIR.c | 105 ++++++ .../src/SKP_Silk_resampler_private_copy.c | 49 +++ .../src/SKP_Silk_resampler_private_down4.c | 77 +++++ .../src/SKP_Silk_resampler_private_down_FIR.c | 160 +++++++++ .../src/SKP_Silk_resampler_private_up2_HQ.c | 118 +++++++ .../silk/src/SKP_Silk_resampler_private_up4.c | 81 +++++ libs/silk/src/SKP_Silk_resampler_rom.c | 269 +++++++++++++++ libs/silk/src/SKP_Silk_resampler_rom.h | 91 +++++ libs/silk/src/SKP_Silk_resampler_structs.h | 80 +++++ libs/silk/src/SKP_Silk_resampler_up2.c | 75 ++++ libs/silk/src/SKP_Silk_setup_complexity.h | 99 ++++++ libs/silk/src/SKP_Silk_tuning_parameters.h | 183 ++++++++++ .../src/SKP_Silk_warped_autocorrelation_FIX.c | 86 +++++ .../How to use the test vectors.txt | 24 ++ libs/silk/test_vectors/test_decoder.bat | 143 ++++++++ libs/silk/test_vectors/test_decoder.sh | 142 ++++++++ libs/silk/test_vectors/test_encoder.bat | 111 ++++++ libs/silk/test_vectors/test_encoder.sh | 109 ++++++ src/mod/codecs/mod_silk/mod_silk.c | 16 +- 29 files changed, 3167 insertions(+), 7 deletions(-) create mode 100644 libs/silk/src/SKP_Silk_apply_sine_window_new.c create mode 100644 libs/silk/src/SKP_Silk_control_audio_bandwidth.c create mode 100644 libs/silk/src/SKP_Silk_decode_pitch.c create mode 100644 libs/silk/src/SKP_Silk_resampler.c create mode 100644 libs/silk/src/SKP_Silk_resampler_down2.c create mode 100644 libs/silk/src/SKP_Silk_resampler_down2_3.c create mode 100644 libs/silk/src/SKP_Silk_resampler_down3.c create mode 100644 libs/silk/src/SKP_Silk_resampler_private.h create mode 100644 libs/silk/src/SKP_Silk_resampler_private_AR2.c create mode 100644 libs/silk/src/SKP_Silk_resampler_private_ARMA4.c create mode 100644 libs/silk/src/SKP_Silk_resampler_private_IIR_FIR.c create mode 100644 libs/silk/src/SKP_Silk_resampler_private_copy.c create mode 100644 libs/silk/src/SKP_Silk_resampler_private_down4.c create mode 100644 libs/silk/src/SKP_Silk_resampler_private_down_FIR.c create mode 100644 libs/silk/src/SKP_Silk_resampler_private_up2_HQ.c create mode 100644 libs/silk/src/SKP_Silk_resampler_private_up4.c create mode 100644 libs/silk/src/SKP_Silk_resampler_rom.c create mode 100644 libs/silk/src/SKP_Silk_resampler_rom.h create mode 100644 libs/silk/src/SKP_Silk_resampler_structs.h create mode 100644 libs/silk/src/SKP_Silk_resampler_up2.c create mode 100644 libs/silk/src/SKP_Silk_setup_complexity.h create mode 100644 libs/silk/src/SKP_Silk_tuning_parameters.h create mode 100644 libs/silk/src/SKP_Silk_warped_autocorrelation_FIX.c create mode 100644 libs/silk/test_vectors/How to use the test vectors.txt create mode 100644 libs/silk/test_vectors/test_decoder.bat create mode 100644 libs/silk/test_vectors/test_decoder.sh create mode 100644 libs/silk/test_vectors/test_encoder.bat create mode 100644 libs/silk/test_vectors/test_encoder.sh diff --git a/libs/silk/src/SKP_Silk_apply_sine_window_new.c b/libs/silk/src/SKP_Silk_apply_sine_window_new.c new file mode 100644 index 0000000000..b4db18e655 --- /dev/null +++ b/libs/silk/src/SKP_Silk_apply_sine_window_new.c @@ -0,0 +1,101 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#include "SKP_Silk_SigProc_FIX.h" + +/* Apply sine window to signal vector. */ +/* Window types: */ +/* 1 -> sine window from 0 to pi/2 */ +/* 2 -> sine window from pi/2 to pi */ +/* Every other sample is linearly interpolated, for speed. */ +/* Window length must be between 16 and 120 (incl) and a multiple of 4. */ + +/* Matlab code for table: + for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end +*/ +static SKP_int16 freq_table_Q16[ 27 ] = { + 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202, + 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422, + 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702, +}; + + +void SKP_Silk_apply_sine_window_new( + SKP_int16 px_win[], /* O Pointer to windowed signal */ + const SKP_int16 px[], /* I Pointer to input signal */ + const SKP_int win_type, /* I Selects a window type */ + const SKP_int length /* I Window length, multiple of 4 */ +) +{ + SKP_int k, f_Q16, c_Q16; + SKP_int32 S0_Q16, S1_Q16; + SKP_assert( win_type == 1 || win_type == 2 ); + + /* Length must be in a range from 16 to 120 and a multiple of 4 */ + SKP_assert( length >= 16 && length <= 120 ); + SKP_assert( ( length & 3 ) == 0 ); + + /* Input pointer must be 4-byte aligned */ + SKP_assert( ( ( SKP_int64 )( ( SKP_int8* )px - ( SKP_int8* )0 ) & 3 ) == 0 ); + + /* Frequency */ + k = ( length >> 2 ) - 4; + SKP_assert( k >= 0 && k <= 26 ); + f_Q16 = (SKP_int)freq_table_Q16[ k ]; + + /* Factor used for cosine approximation */ + c_Q16 = SKP_SMULWB( f_Q16, -f_Q16 ); + SKP_assert( c_Q16 >= -32768 ); + + /* initialize state */ + if( win_type == 1 ) { + /* start from 0 */ + S0_Q16 = 0; + /* approximation of sin(f) */ + S1_Q16 = f_Q16 + SKP_RSHIFT( length, 3 ); + } else { + /* start from 1 */ + S0_Q16 = ( 1 << 16 ); + /* approximation of cos(f) */ + S1_Q16 = ( 1 << 16 ) + SKP_RSHIFT( c_Q16, 1 ) + SKP_RSHIFT( length, 4 ); + } + + /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ + /* 4 samples at a time */ + for( k = 0; k < length; k += 4 ) { + px_win[ k ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] ); + px_win[ k + 1 ] = (SKP_int16)SKP_SMULWB( S1_Q16, px[ k + 1] ); + S0_Q16 = SKP_SMULWB( S1_Q16, c_Q16 ) + SKP_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1; + S0_Q16 = SKP_min( S0_Q16, ( 1 << 16 ) ); + + px_win[ k + 2 ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] ); + px_win[ k + 3 ] = (SKP_int16)SKP_SMULWB( S0_Q16, px[ k + 3 ] ); + S1_Q16 = SKP_SMULWB( S0_Q16, c_Q16 ) + SKP_LSHIFT( S0_Q16, 1 ) - S1_Q16; + S1_Q16 = SKP_min( S1_Q16, ( 1 << 16 ) ); + } +} + diff --git a/libs/silk/src/SKP_Silk_control_audio_bandwidth.c b/libs/silk/src/SKP_Silk_control_audio_bandwidth.c new file mode 100644 index 0000000000..bf8b318098 --- /dev/null +++ b/libs/silk/src/SKP_Silk_control_audio_bandwidth.c @@ -0,0 +1,137 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#include "SKP_Silk_main.h" + +/* Control internal sampling rate */ +SKP_int SKP_Silk_control_audio_bandwidth( + SKP_Silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ + const SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */ +) +{ + SKP_int fs_kHz; + + fs_kHz = psEncC->fs_kHz; + if( fs_kHz == 0 ) { + /* Encoder has just been initialized */ + if( TargetRate_bps >= SWB2WB_BITRATE_BPS ) { + fs_kHz = 24; + } else if( TargetRate_bps >= WB2MB_BITRATE_BPS ) { + fs_kHz = 16; + } else if( TargetRate_bps >= MB2NB_BITRATE_BPS ) { + fs_kHz = 12; + } else { + fs_kHz = 8; + } + /* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */ + fs_kHz = SKP_min( fs_kHz, SKP_DIV32_16( psEncC->API_fs_Hz, 1000 ) ); + fs_kHz = SKP_min( fs_kHz, psEncC->maxInternal_fs_kHz ); + } else if( SKP_SMULBB( fs_kHz, 1000 ) > psEncC->API_fs_Hz || fs_kHz > psEncC->maxInternal_fs_kHz ) { + /* Make sure internal rate is not higher than external rate or maximum allowed */ + fs_kHz = SKP_DIV32_16( psEncC->API_fs_Hz, 1000 ); + fs_kHz = SKP_min( fs_kHz, psEncC->maxInternal_fs_kHz ); + } else { + /* State machine for the internal sampling rate switching */ + if( psEncC->API_fs_Hz > 8000 ) { + /* Accumulate the difference between the target rate and limit for switching down */ + psEncC->bitrateDiff += SKP_MUL( psEncC->PacketSize_ms, psEncC->TargetRate_bps - psEncC->bitrate_threshold_down ); + psEncC->bitrateDiff = SKP_min( psEncC->bitrateDiff, 0 ); + + if( psEncC->vadFlag == NO_VOICE_ACTIVITY ) { /* Low speech activity */ + /* Check if we should switch down */ +#if SWITCH_TRANSITION_FILTERING + if( ( psEncC->sLP.transition_frame_no == 0 ) && /* Transition phase not active */ + ( psEncC->bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || /* Bitrate threshold is met */ + ( psEncC->sSWBdetect.WB_detected * psEncC->fs_kHz == 24 ) ) ) { /* Forced down-switching due to WB input */ + psEncC->sLP.transition_frame_no = 1; /* Begin transition phase */ + psEncC->sLP.mode = 0; /* Switch down */ + } else if( + ( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && /* Transition phase complete */ + ( psEncC->sLP.mode == 0 ) ) { /* Ready to switch down */ + psEncC->sLP.transition_frame_no = 0; /* Ready for new transition phase */ +#else + if( psEncC->bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) { /* Bitrate threshold is met */ +#endif + psEncC->bitrateDiff = 0; + + /* Switch to a lower sample frequency */ + if( psEncC->fs_kHz == 24 ) { + fs_kHz = 16; + } else if( psEncC->fs_kHz == 16 ) { + fs_kHz = 12; + } else { + SKP_assert( psEncC->fs_kHz == 12 ); + fs_kHz = 8; + } + } + + /* Check if we should switch up */ + if( ( ( psEncC->fs_kHz * 1000 < psEncC->API_fs_Hz ) && + ( psEncC->TargetRate_bps >= psEncC->bitrate_threshold_up ) && + ( psEncC->sSWBdetect.WB_detected * psEncC->fs_kHz < 16 ) ) && + ( ( ( psEncC->fs_kHz == 16 ) && ( psEncC->maxInternal_fs_kHz >= 24 ) ) || + ( ( psEncC->fs_kHz == 12 ) && ( psEncC->maxInternal_fs_kHz >= 16 ) ) || + ( ( psEncC->fs_kHz == 8 ) && ( psEncC->maxInternal_fs_kHz >= 12 ) ) ) +#if SWITCH_TRANSITION_FILTERING + && ( psEncC->sLP.transition_frame_no == 0 ) ) { /* No transition phase running, ready to switch */ + psEncC->sLP.mode = 1; /* Switch up */ +#else + ) { +#endif + psEncC->bitrateDiff = 0; + + /* Switch to a higher sample frequency */ + if( psEncC->fs_kHz == 8 ) { + fs_kHz = 12; + } else if( psEncC->fs_kHz == 12 ) { + fs_kHz = 16; + } else { + SKP_assert( psEncC->fs_kHz == 16 ); + fs_kHz = 24; + } + } + } + } + +#if SWITCH_TRANSITION_FILTERING + /* After switching up, stop transition filter during speech inactivity */ + if( ( psEncC->sLP.mode == 1 ) && + ( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES_UP ) && + ( psEncC->vadFlag == NO_VOICE_ACTIVITY ) ) { + + psEncC->sLP.transition_frame_no = 0; + + /* Reset transition filter state */ + SKP_memset( psEncC->sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) ); + } +#endif + } + + + + return fs_kHz; +} diff --git a/libs/silk/src/SKP_Silk_decode_pitch.c b/libs/silk/src/SKP_Silk_decode_pitch.c new file mode 100644 index 0000000000..d625996c14 --- /dev/null +++ b/libs/silk/src/SKP_Silk_decode_pitch.c @@ -0,0 +1,57 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/*********************************************************** +* Pitch analyser function +********************************************************** */ +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_common_pitch_est_defines.h" + +void SKP_Silk_decode_pitch( + SKP_int lagIndex, /* I */ + SKP_int contourIndex, /* O */ + SKP_int pitch_lags[], /* O 4 pitch values */ + SKP_int Fs_kHz /* I sampling frequency (kHz) */ +) +{ + SKP_int lag, i, min_lag; + + min_lag = SKP_SMULBB( PITCH_EST_MIN_LAG_MS, Fs_kHz ); + + /* Only for 24 / 16 kHz version for now */ + lag = min_lag + lagIndex; + if( Fs_kHz == 8 ) { + /* Only a small codebook for 8 khz */ + for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) { + pitch_lags[ i ] = lag + SKP_Silk_CB_lags_stage2[ i ][ contourIndex ]; + } + } else { + for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) { + pitch_lags[ i ] = lag + SKP_Silk_CB_lags_stage3[ i ][ contourIndex ]; + } + } +} diff --git a/libs/silk/src/SKP_Silk_resampler.c b/libs/silk/src/SKP_Silk_resampler.c new file mode 100644 index 0000000000..980f81fefc --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler.c @@ -0,0 +1,323 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * File Name: SKP_Silk_resampler.c * + * * + * Description: Interface to collection of resamplers * + * * + * Copyright 2010 (c), Skype Limited * + * All rights reserved. * + * */ + +/* Matrix of resampling methods used: + * Fs_out (kHz) + * 8 12 16 24 32 44.1 48 + * + * 8 C UF U UF UF UF UF + * 12 AF C UF U UF UF UF + * 16 D AF C UF U UF UF + * Fs_in (kHz) 24 AIF D AF C UF UF U + * 32 UF AF D AF C UF UF + * 44.1 AMI AMI AMI AMI AMI C UF + * 48 DAF DAF AF D AF UF C + * + * default method: UF + * + * C -> Copy (no resampling) + * D -> Allpass-based 2x downsampling + * U -> Allpass-based 2x upsampling + * DAF -> Allpass-based 2x downsampling followed by AR2 filter followed by FIR interpolation + * UF -> Allpass-based 2x upsampling followed by FIR interpolation + * AMI -> ARMA4 filter followed by FIR interpolation + * AF -> AR2 filter followed by FIR interpolation + * + * Input signals sampled above 48 kHz are first downsampled to at most 48 kHz. + * Output signals sampled above 48 kHz are upsampled from at most 48 kHz. + */ + +#include "SKP_Silk_resampler_private.h" + +/* Greatest common divisor */ +static SKP_int32 gcd( + SKP_int32 a, + SKP_int32 b +) +{ + SKP_int32 tmp; + while( b > 0 ) { + tmp = a - b * SKP_DIV32( a, b ); + a = b; + b = tmp; + } + return a; +} + +/* Initialize/reset the resampler state for a given pair of input/output sampling rates */ +SKP_int SKP_Silk_resampler_init( + SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */ + SKP_int32 Fs_Hz_in, /* I: Input sampling rate (Hz) */ + SKP_int32 Fs_Hz_out /* I: Output sampling rate (Hz) */ +) +{ + SKP_int32 cycleLen, cyclesPerBatch, up2 = 0, down2 = 0; + + /* Clear state */ + SKP_memset( S, 0, sizeof( SKP_Silk_resampler_state_struct ) ); + + /* Input checking */ +#if RESAMPLER_SUPPORT_ABOVE_48KHZ + if( Fs_Hz_in < 8000 || Fs_Hz_in > 192000 || Fs_Hz_out < 8000 || Fs_Hz_out > 192000 ) { +#else + if( Fs_Hz_in < 8000 || Fs_Hz_in > 48000 || Fs_Hz_out < 8000 || Fs_Hz_out > 48000 ) { +#endif + SKP_assert( 0 ); + return -1; + } + +#if RESAMPLER_SUPPORT_ABOVE_48KHZ + /* Determine pre downsampling and post upsampling */ + if( Fs_Hz_in > 96000 ) { + S->nPreDownsamplers = 2; + S->down_pre_function = SKP_Silk_resampler_private_down4; + } else if( Fs_Hz_in > 48000 ) { + S->nPreDownsamplers = 1; + S->down_pre_function = SKP_Silk_resampler_down2; + } else { + S->nPreDownsamplers = 0; + S->down_pre_function = NULL; + } + + if( Fs_Hz_out > 96000 ) { + S->nPostUpsamplers = 2; + S->up_post_function = SKP_Silk_resampler_private_up4; + } else if( Fs_Hz_out > 48000 ) { + S->nPostUpsamplers = 1; + S->up_post_function = SKP_Silk_resampler_up2; + } else { + S->nPostUpsamplers = 0; + S->up_post_function = NULL; + } + + if( S->nPreDownsamplers + S->nPostUpsamplers > 0 ) { + /* Ratio of output/input samples */ + S->ratio_Q16 = SKP_LSHIFT32( SKP_DIV32( SKP_LSHIFT32( Fs_Hz_out, 13 ), Fs_Hz_in ), 3 ); + /* Make sure the ratio is rounded up */ + while( SKP_SMULWW( S->ratio_Q16, Fs_Hz_in ) < Fs_Hz_out ) S->ratio_Q16++; + + /* Batch size is 10 ms */ + S->batchSizePrePost = SKP_DIV32_16( Fs_Hz_in, 100 ); + + /* Convert sampling rate to those after pre-downsampling and before post-upsampling */ + Fs_Hz_in = SKP_RSHIFT( Fs_Hz_in, S->nPreDownsamplers ); + Fs_Hz_out = SKP_RSHIFT( Fs_Hz_out, S->nPostUpsamplers ); + } +#endif + + /* Number of samples processed per batch */ + /* First, try 10 ms frames */ + S->batchSize = SKP_DIV32_16( Fs_Hz_in, 100 ); + if( ( SKP_MUL( S->batchSize, 100 ) != Fs_Hz_in ) || ( Fs_Hz_in % 100 != 0 ) ) { + /* No integer number of input or output samples with 10 ms frames, use greatest common divisor */ + cycleLen = SKP_DIV32( Fs_Hz_in, gcd( Fs_Hz_in, Fs_Hz_out ) ); + cyclesPerBatch = SKP_DIV32( RESAMPLER_MAX_BATCH_SIZE_IN, cycleLen ); + if( cyclesPerBatch == 0 ) { + /* cycleLen too big, let's just use the maximum batch size. Some distortion will result. */ + S->batchSize = RESAMPLER_MAX_BATCH_SIZE_IN; + SKP_assert( 0 ); + } else { + S->batchSize = SKP_MUL( cyclesPerBatch, cycleLen ); + } + } + + + /* Find resampler with the right sampling ratio */ + if( Fs_Hz_out > Fs_Hz_in ) { + /* Upsample */ + if( Fs_Hz_out == SKP_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 1 */ + /* Special case: directly use 2x upsampler */ + S->resampler_function = SKP_Silk_resampler_private_up2_HQ_wrapper; + } else { + /* Default resampler */ + S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; + up2 = 1; + if( Fs_Hz_in > 24000 ) { + /* Low-quality all-pass upsampler */ + S->up2_function = SKP_Silk_resampler_up2; + } else { + /* High-quality all-pass upsampler */ + S->up2_function = SKP_Silk_resampler_private_up2_HQ; + } + } + } else if ( Fs_Hz_out < Fs_Hz_in ) { + /* Downsample */ + if( SKP_MUL( Fs_Hz_out, 4 ) == SKP_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 4 */ + S->FIR_Fracs = 3; + S->Coefs = SKP_Silk_Resampler_3_4_COEFS; + S->resampler_function = SKP_Silk_resampler_private_down_FIR; + } else if( SKP_MUL( Fs_Hz_out, 3 ) == SKP_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 3 */ + S->FIR_Fracs = 2; + S->Coefs = SKP_Silk_Resampler_2_3_COEFS; + S->resampler_function = SKP_Silk_resampler_private_down_FIR; + } else if( SKP_MUL( Fs_Hz_out, 2 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 2 */ + S->FIR_Fracs = 1; + S->Coefs = SKP_Silk_Resampler_1_2_COEFS; + S->resampler_function = SKP_Silk_resampler_private_down_FIR; + } else if( SKP_MUL( Fs_Hz_out, 8 ) == SKP_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 8 */ + S->FIR_Fracs = 3; + S->Coefs = SKP_Silk_Resampler_3_8_COEFS; + S->resampler_function = SKP_Silk_resampler_private_down_FIR; + } else if( SKP_MUL( Fs_Hz_out, 3 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 3 */ + S->FIR_Fracs = 1; + S->Coefs = SKP_Silk_Resampler_1_3_COEFS; + S->resampler_function = SKP_Silk_resampler_private_down_FIR; + } else if( SKP_MUL( Fs_Hz_out, 4 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 4 */ + S->FIR_Fracs = 1; + down2 = 1; + S->Coefs = SKP_Silk_Resampler_1_2_COEFS; + S->resampler_function = SKP_Silk_resampler_private_down_FIR; + } else if( SKP_MUL( Fs_Hz_out, 6 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 6 */ + S->FIR_Fracs = 1; + down2 = 1; + S->Coefs = SKP_Silk_Resampler_1_3_COEFS; + S->resampler_function = SKP_Silk_resampler_private_down_FIR; + } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 80 ) ) { /* Fs_out : Fs_in = 80 : 441 */ + S->Coefs = SKP_Silk_Resampler_80_441_ARMA4_COEFS; + S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; + } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 120 ) ) { /* Fs_out : Fs_in = 120 : 441 */ + S->Coefs = SKP_Silk_Resampler_120_441_ARMA4_COEFS; + S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; + } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 160 ) ) { /* Fs_out : Fs_in = 160 : 441 */ + S->Coefs = SKP_Silk_Resampler_160_441_ARMA4_COEFS; + S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; + } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 240 ) ) { /* Fs_out : Fs_in = 240 : 441 */ + S->Coefs = SKP_Silk_Resampler_240_441_ARMA4_COEFS; + S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; + } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 320 ) ) { /* Fs_out : Fs_in = 320 : 441 */ + S->Coefs = SKP_Silk_Resampler_320_441_ARMA4_COEFS; + S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; + } else { + /* Default resampler */ + S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; + up2 = 1; + if( Fs_Hz_in > 24000 ) { + /* Low-quality all-pass upsampler */ + S->up2_function = SKP_Silk_resampler_up2; + } else { + /* High-quality all-pass upsampler */ + S->up2_function = SKP_Silk_resampler_private_up2_HQ; + } + } + } else { + /* Input and output sampling rates are equal: copy */ + S->resampler_function = SKP_Silk_resampler_private_copy; + } + + S->input2x = up2 | down2; + + /* Ratio of input/output samples */ + S->invRatio_Q16 = SKP_LSHIFT32( SKP_DIV32( SKP_LSHIFT32( Fs_Hz_in, 14 + up2 - down2 ), Fs_Hz_out ), 2 ); + /* Make sure the ratio is rounded up */ + while( SKP_SMULWW( S->invRatio_Q16, SKP_LSHIFT32( Fs_Hz_out, down2 ) ) < SKP_LSHIFT32( Fs_Hz_in, up2 ) ) { + S->invRatio_Q16++; + } + + S->magic_number = 123456789; + + return 0; +} + +/* Clear the states of all resampling filters, without resetting sampling rate ratio */ +SKP_int SKP_Silk_resampler_clear( + SKP_Silk_resampler_state_struct *S /* I/O: Resampler state */ +) +{ + /* Clear state */ + SKP_memset( S->sDown2, 0, sizeof( S->sDown2 ) ); + SKP_memset( S->sIIR, 0, sizeof( S->sIIR ) ); + SKP_memset( S->sFIR, 0, sizeof( S->sFIR ) ); +#if RESAMPLER_SUPPORT_ABOVE_48KHZ + SKP_memset( S->sDownPre, 0, sizeof( S->sDownPre ) ); + SKP_memset( S->sUpPost, 0, sizeof( S->sUpPost ) ); +#endif + return 0; +} + +/* Resampler: convert from one sampling rate to another */ +SKP_int SKP_Silk_resampler( + SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */ + SKP_int16 out[], /* O: Output signal */ + const SKP_int16 in[], /* I: Input signal */ + SKP_int32 inLen /* I: Number of input samples */ +) +{ + /* Verify that state was initialized and has not been corrupted */ + if( S->magic_number != 123456789 ) { + SKP_assert( 0 ); + return -1; + } + +#if RESAMPLER_SUPPORT_ABOVE_48KHZ + if( S->nPreDownsamplers + S->nPostUpsamplers > 0 ) { + /* The input and/or output sampling rate is above 48000 Hz */ + SKP_int32 nSamplesIn, nSamplesOut; + SKP_int16 in_buf[ 480 ], out_buf[ 480 ]; + + while( inLen > 0 ) { + /* Number of input and output samples to process */ + nSamplesIn = SKP_min( inLen, S->batchSizePrePost ); + nSamplesOut = SKP_SMULWB( S->ratio_Q16, nSamplesIn ); + + SKP_assert( SKP_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) <= 480 ); + SKP_assert( SKP_RSHIFT32( nSamplesOut, S->nPostUpsamplers ) <= 480 ); + + if( S->nPreDownsamplers > 0 ) { + S->down_pre_function( S->sDownPre, in_buf, in, nSamplesIn ); + if( S->nPostUpsamplers > 0 ) { + S->resampler_function( S, out_buf, in_buf, SKP_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) ); + S->up_post_function( S->sUpPost, out, out_buf, SKP_RSHIFT32( nSamplesOut, S->nPostUpsamplers ) ); + } else { + S->resampler_function( S, out, in_buf, SKP_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) ); + } + } else { + S->resampler_function( S, out_buf, in, SKP_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) ); + S->up_post_function( S->sUpPost, out, out_buf, SKP_RSHIFT32( nSamplesOut, S->nPostUpsamplers ) ); + } + + in += nSamplesIn; + out += nSamplesOut; + inLen -= nSamplesIn; + } + } else +#endif + { + /* Input and output sampling rate are at most 48000 Hz */ + S->resampler_function( S, out, in, inLen ); + } + + return 0; +} diff --git a/libs/silk/src/SKP_Silk_resampler_down2.c b/libs/silk/src/SKP_Silk_resampler_down2.c new file mode 100644 index 0000000000..619442c0df --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_down2.c @@ -0,0 +1,77 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * SKP_Silk_resampler_down2.c * + * * + * Downsample by a factor 2, mediocre quality * + * * + * Copyright 2010 (c), Skype Limited * + * */ + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_rom.h" + +/* Downsample by a factor 2, mediocre quality */ +void SKP_Silk_resampler_down2( + SKP_int32 *S, /* I/O: State vector [ 2 ] */ + SKP_int16 *out, /* O: Output signal [ len ] */ + const SKP_int16 *in, /* I: Input signal [ floor(len/2) ] */ + SKP_int32 inLen /* I: Number of input samples */ +) +{ + SKP_int32 k, len2 = SKP_RSHIFT32( inLen, 1 ); + SKP_int32 in32, out32, Y, X; + + SKP_assert( SKP_Silk_resampler_down2_0 > 0 ); + SKP_assert( SKP_Silk_resampler_down2_1 < 0 ); + + /* Internal variables and state are in Q10 format */ + for( k = 0; k < len2; k++ ) { + /* Convert to Q10 */ + in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k ], 10 ); + + /* All-pass section for even input sample */ + Y = SKP_SUB32( in32, S[ 0 ] ); + X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_down2_1 ); + out32 = SKP_ADD32( S[ 0 ], X ); + S[ 0 ] = SKP_ADD32( in32, X ); + + /* Convert to Q10 */ + in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k + 1 ], 10 ); + + /* All-pass section for odd input sample, and add to output of previous section */ + Y = SKP_SUB32( in32, S[ 1 ] ); + X = SKP_SMULWB( Y, SKP_Silk_resampler_down2_0 ); + out32 = SKP_ADD32( out32, S[ 1 ] ); + out32 = SKP_ADD32( out32, X ); + S[ 1 ] = SKP_ADD32( in32, X ); + + /* Add, convert back to int16 and store to output */ + out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 11 ) ); + } +} diff --git a/libs/silk/src/SKP_Silk_resampler_down2_3.c b/libs/silk/src/SKP_Silk_resampler_down2_3.c new file mode 100644 index 0000000000..31089f909a --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_down2_3.c @@ -0,0 +1,102 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * SKP_Silk_resampler_down2_3.c * + * * + * Downsample by a factor 2/3, low quality * + * * + * Copyright 2010 (c), Skype Limited * + * */ + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_private.h" + +#define ORDER_FIR 4 + +/* Downsample by a factor 2/3, low quality */ +void SKP_Silk_resampler_down2_3( + SKP_int32 *S, /* I/O: State vector [ 6 ] */ + SKP_int16 *out, /* O: Output signal [ floor(2*inLen/3) ] */ + const SKP_int16 *in, /* I: Input signal [ inLen ] */ + SKP_int32 inLen /* I: Number of input samples */ +) +{ + SKP_int32 nSamplesIn, counter, res_Q6; + SKP_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR ]; + SKP_int32 *buf_ptr; + + /* Copy buffered samples to start of buffer */ + SKP_memcpy( buf, S, ORDER_FIR * sizeof( SKP_int32 ) ); + + /* Iterate over blocks of frameSizeIn input samples */ + while( 1 ) { + nSamplesIn = SKP_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN ); + + /* Second-order AR filter (output in Q8) */ + SKP_Silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in, + SKP_Silk_Resampler_2_3_COEFS_LQ, nSamplesIn ); + + /* Interpolate filtered signal */ + buf_ptr = buf; + counter = nSamplesIn; + while( counter > 2 ) { + /* Inner product */ + res_Q6 = SKP_SMULWB( buf_ptr[ 0 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 1 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 3 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 2 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 5 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 3 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 4 ] ); + + /* Scale down, saturate and store in output array */ + *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) ); + + res_Q6 = SKP_SMULWB( buf_ptr[ 1 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 4 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 2 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 5 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 3 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 3 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 4 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 ] ); + + /* Scale down, saturate and store in output array */ + *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) ); + + buf_ptr += 3; + counter -= 3; + } + + in += nSamplesIn; + inLen -= nSamplesIn; + + if( inLen > 0 ) { + /* More iterations to do; copy last part of filtered signal to beginning of buffer */ + SKP_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( SKP_int32 ) ); + } else { + break; + } + } + + /* Copy last part of filtered signal to the state for the next call */ + SKP_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( SKP_int32 ) ); +} diff --git a/libs/silk/src/SKP_Silk_resampler_down3.c b/libs/silk/src/SKP_Silk_resampler_down3.c new file mode 100644 index 0000000000..70c86f6698 --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_down3.c @@ -0,0 +1,93 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * SKP_Silk_resampler_down3.c * + * * + * Downsample by a factor 3, low quality * + * * + * Copyright 2010 (c), Skype Limited * + * */ + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_private.h" + +#define ORDER_FIR 6 + +/* Downsample by a factor 3, low quality */ +void SKP_Silk_resampler_down3( + SKP_int32 *S, /* I/O: State vector [ 8 ] */ + SKP_int16 *out, /* O: Output signal [ floor(inLen/3) ] */ + const SKP_int16 *in, /* I: Input signal [ inLen ] */ + SKP_int32 inLen /* I: Number of input samples */ +) +{ + SKP_int32 nSamplesIn, counter, res_Q6; + SKP_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR ]; + SKP_int32 *buf_ptr; + + /* Copy buffered samples to start of buffer */ + SKP_memcpy( buf, S, ORDER_FIR * sizeof( SKP_int32 ) ); + + /* Iterate over blocks of frameSizeIn input samples */ + while( 1 ) { + nSamplesIn = SKP_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN ); + + /* Second-order AR filter (output in Q8) */ + SKP_Silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in, + SKP_Silk_Resampler_1_3_COEFS_LQ, nSamplesIn ); + + /* Interpolate filtered signal */ + buf_ptr = buf; + counter = nSamplesIn; + while( counter > 2 ) { + /* Inner product */ + res_Q6 = SKP_SMULWB( SKP_ADD32( buf_ptr[ 0 ], buf_ptr[ 5 ] ), SKP_Silk_Resampler_1_3_COEFS_LQ[ 2 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 1 ], buf_ptr[ 4 ] ), SKP_Silk_Resampler_1_3_COEFS_LQ[ 3 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 2 ], buf_ptr[ 3 ] ), SKP_Silk_Resampler_1_3_COEFS_LQ[ 4 ] ); + + /* Scale down, saturate and store in output array */ + *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) ); + + buf_ptr += 3; + counter -= 3; + } + + in += nSamplesIn; + inLen -= nSamplesIn; + + if( inLen > 0 ) { + /* More iterations to do; copy last part of filtered signal to beginning of buffer */ + SKP_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( SKP_int32 ) ); + } else { + break; + } + } + + /* Copy last part of filtered signal to the state for the next call */ + SKP_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( SKP_int32 ) ); +} diff --git a/libs/silk/src/SKP_Silk_resampler_private.h b/libs/silk/src/SKP_Silk_resampler_private.h new file mode 100644 index 0000000000..0402b484aa --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_private.h @@ -0,0 +1,131 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * File Name: SKP_Silk_resampler_structs.h * + * * + * Description: Structs for IIR/FIR resamplers * + * * + * Copyright 2010 (c), Skype Limited * + * All rights reserved. * + * * + * */ + +#ifndef SKP_Silk_RESAMPLER_H +#define SKP_Silk_RESAMPLER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_structs.h" +#include "SKP_Silk_resampler_rom.h" + +/* Number of input samples to process in the inner loop */ +#define RESAMPLER_MAX_BATCH_SIZE_IN 480 + +/* Description: Hybrid IIR/FIR polyphase implementation of resampling */ +void SKP_Silk_resampler_private_IIR_FIR( + void *SS, /* I/O: Resampler state */ + SKP_int16 out[], /* O: Output signal */ + const SKP_int16 in[], /* I: Input signal */ + SKP_int32 inLen /* I: Number of input samples */ +); + +/* Description: Hybrid IIR/FIR polyphase implementation of resampling */ +void SKP_Silk_resampler_private_down_FIR( + void *SS, /* I/O: Resampler state */ + SKP_int16 out[], /* O: Output signal */ + const SKP_int16 in[], /* I: Input signal */ + SKP_int32 inLen /* I: Number of input samples */ +); + +/* Copy */ +void SKP_Silk_resampler_private_copy( + void *SS, /* I/O: Resampler state (unused) */ + SKP_int16 out[], /* O: Output signal */ + const SKP_int16 in[], /* I: Input signal */ + SKP_int32 inLen /* I: Number of input samples */ +); + +/* Upsample by a factor 2, high quality */ +void SKP_Silk_resampler_private_up2_HQ_wrapper( + void *SS, /* I/O: Resampler state (unused) */ + SKP_int16 *out, /* O: Output signal [ 2 * len ] */ + const SKP_int16 *in, /* I: Input signal [ len ] */ + SKP_int32 len /* I: Number of input samples */ +); + +/* Upsample by a factor 2, high quality */ +void SKP_Silk_resampler_private_up2_HQ( + SKP_int32 *S, /* I/O: Resampler state [ 6 ] */ + SKP_int16 *out, /* O: Output signal [ 2 * len ] */ + const SKP_int16 *in, /* I: Input signal [ len ] */ + SKP_int32 len /* I: Number of input samples */ +); + +/* Upsample 4x, low quality */ +void SKP_Silk_resampler_private_up4( + SKP_int32 *S, /* I/O: State vector [ 2 ] */ + SKP_int16 *out, /* O: Output signal [ 4 * len ] */ + const SKP_int16 *in, /* I: Input signal [ len ] */ + SKP_int32 len /* I: Number of input samples */ +); + +/* Downsample 4x, low quality */ +void SKP_Silk_resampler_private_down4( + SKP_int32 *S, /* I/O: State vector [ 2 ] */ + SKP_int16 *out, /* O: Output signal [ floor(len/2) ] */ + const SKP_int16 *in, /* I: Input signal [ len ] */ + SKP_int32 inLen /* I: Number of input samples */ +); + +/* Second order AR filter */ +void SKP_Silk_resampler_private_AR2( + SKP_int32 S[], /* I/O: State vector [ 2 ] */ + SKP_int32 out_Q8[], /* O: Output signal */ + const SKP_int16 in[], /* I: Input signal */ + const SKP_int16 A_Q14[], /* I: AR coefficients, Q14 */ + SKP_int32 len /* I: Signal length */ +); + +/* Fourth order ARMA filter */ +void SKP_Silk_resampler_private_ARMA4( + SKP_int32 S[], /* I/O: State vector [ 4 ] */ + SKP_int16 out[], /* O: Output signal */ + const SKP_int16 in[], /* I: Input signal */ + const SKP_int16 Coef[], /* I: ARMA coefficients [ 7 ] */ + SKP_int32 len /* I: Signal length */ +); + + +#ifdef __cplusplus +} +#endif +#endif // SKP_Silk_RESAMPLER_H + diff --git a/libs/silk/src/SKP_Silk_resampler_private_AR2.c b/libs/silk/src/SKP_Silk_resampler_private_AR2.c new file mode 100644 index 0000000000..69f5043172 --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_private_AR2.c @@ -0,0 +1,58 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * SKP_Silk_resampler_private_AR2. c * + * * + * Second order AR filter with single delay elements * + * * + * Copyright 2010 (c), Skype Limited * + * */ + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_private.h" + +/* Second order AR filter with single delay elements */ +void SKP_Silk_resampler_private_AR2( + SKP_int32 S[], /* I/O: State vector [ 2 ] */ + SKP_int32 out_Q8[], /* O: Output signal */ + const SKP_int16 in[], /* I: Input signal */ + const SKP_int16 A_Q14[], /* I: AR coefficients, Q14 */ + SKP_int32 len /* I: Signal length */ +) +{ + SKP_int32 k; + SKP_int32 out32; + + for( k = 0; k < len; k++ ) { + out32 = SKP_ADD_LSHIFT32( S[ 0 ], (SKP_int32)in[ k ], 8 ); + out_Q8[ k ] = out32; + out32 = SKP_LSHIFT( out32, 2 ); + S[ 0 ] = SKP_SMLAWB( S[ 1 ], out32, A_Q14[ 0 ] ); + S[ 1 ] = SKP_SMULWB( out32, A_Q14[ 1 ] ); + } +} diff --git a/libs/silk/src/SKP_Silk_resampler_private_ARMA4.c b/libs/silk/src/SKP_Silk_resampler_private_ARMA4.c new file mode 100644 index 0000000000..d0ca3a69fd --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_private_ARMA4.c @@ -0,0 +1,77 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * SKP_Silk_resampler_private_ARMA4.c * + * * + * Fourth order ARMA filter, applies 64x gain * + * * + * Copyright 2010 (c), Skype Limited * + * */ + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_private.h" + +/* Fourth order ARMA filter */ +/* Internally operates as two biquad filters in sequence. */ + +/* Coeffients are stored in a packed format: */ +/* { B1_Q14[1], B2_Q14[1], -A1_Q14[1], -A1_Q14[2], -A2_Q14[1], -A2_Q14[2], gain_Q16 } */ +/* where it is assumed that B*_Q14[0], B*_Q14[2], A*_Q14[0] are all 16384 */ +void SKP_Silk_resampler_private_ARMA4( + SKP_int32 S[], /* I/O: State vector [ 4 ] */ + SKP_int16 out[], /* O: Output signal */ + const SKP_int16 in[], /* I: Input signal */ + const SKP_int16 Coef[], /* I: ARMA coefficients [ 7 ] */ + SKP_int32 len /* I: Signal length */ +) +{ + SKP_int32 k; + SKP_int32 in_Q8, out1_Q8, out2_Q8, X; + + for( k = 0; k < len; k++ ) { + in_Q8 = SKP_LSHIFT32( (SKP_int32)in[ k ], 8 ); + + /* Outputs of first and second biquad */ + out1_Q8 = SKP_ADD_LSHIFT32( in_Q8, S[ 0 ], 2 ); + out2_Q8 = SKP_ADD_LSHIFT32( out1_Q8, S[ 2 ], 2 ); + + /* Update states, which are stored in Q6. Coefficients are in Q14 here */ + X = SKP_SMLAWB( S[ 1 ], in_Q8, Coef[ 0 ] ); + S[ 0 ] = SKP_SMLAWB( X, out1_Q8, Coef[ 2 ] ); + + X = SKP_SMLAWB( S[ 3 ], out1_Q8, Coef[ 1 ] ); + S[ 2 ] = SKP_SMLAWB( X, out2_Q8, Coef[ 4 ] ); + + S[ 1 ] = SKP_SMLAWB( SKP_RSHIFT32( in_Q8, 2 ), out1_Q8, Coef[ 3 ] ); + S[ 3 ] = SKP_SMLAWB( SKP_RSHIFT32( out1_Q8, 2 ), out2_Q8, Coef[ 5 ] ); + + /* Apply gain and store to output. The coefficient is in Q16 */ + out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT32( SKP_SMLAWB( 128, out2_Q8, Coef[ 6 ] ), 8 ) ); + } +} + diff --git a/libs/silk/src/SKP_Silk_resampler_private_IIR_FIR.c b/libs/silk/src/SKP_Silk_resampler_private_IIR_FIR.c new file mode 100644 index 0000000000..df9a031dc8 --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_private_IIR_FIR.c @@ -0,0 +1,105 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * File Name: SKP_Silk_resampler_private_IIR_FIR.c * + * * + * Description: Hybrid IIR/FIR polyphase implementation of resampling * + * * + * Copyright 2010 (c), Skype Limited * + * All rights reserved. * + * */ + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_private.h" +SKP_INLINE SKP_int16 *SKP_Silk_resampler_private_IIR_FIR_INTERPOL( + SKP_int16 * out, SKP_int16 * buf, SKP_int32 max_index_Q16 , SKP_int32 index_increment_Q16 ){ + SKP_int32 index_Q16, res_Q15; + SKP_int16 *buf_ptr; + SKP_int32 table_index; + /* Interpolate upsampled signal and store in output array */ + for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { + table_index = SKP_SMULWB( index_Q16 & 0xFFFF, 144 ); + buf_ptr = &buf[ index_Q16 >> 16 ]; + + res_Q15 = SKP_SMULBB( buf_ptr[ 0 ], SKP_Silk_resampler_frac_FIR_144[ table_index ][ 0 ] ); + res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 1 ], SKP_Silk_resampler_frac_FIR_144[ table_index ][ 1 ] ); + res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 2 ], SKP_Silk_resampler_frac_FIR_144[ table_index ][ 2 ] ); + res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 3 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 2 ] ); + res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 4 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 1 ] ); + res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 5 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 0 ] ); + *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q15, 15 ) ); + } + return out; +} +/* Upsample using a combination of allpass-based 2x upsampling and FIR interpolation */ +void SKP_Silk_resampler_private_IIR_FIR( + void *SS, /* I/O: Resampler state */ + SKP_int16 out[], /* O: Output signal */ + const SKP_int16 in[], /* I: Input signal */ + SKP_int32 inLen /* I: Number of input samples */ +) +{ + SKP_Silk_resampler_state_struct *S = (SKP_Silk_resampler_state_struct *)SS; + SKP_int32 nSamplesIn; + SKP_int32 max_index_Q16, index_increment_Q16; + SKP_int16 buf[ 2 * RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_144 ]; + + + /* Copy buffered samples to start of buffer */ + SKP_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) ); + + /* Iterate over blocks of frameSizeIn input samples */ + index_increment_Q16 = S->invRatio_Q16; + while( 1 ) { + nSamplesIn = SKP_min( inLen, S->batchSize ); + + if( S->input2x == 1 ) { + /* Upsample 2x */ + S->up2_function( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_144 ], in, nSamplesIn ); + } else { + /* Fourth-order ARMA filter */ + SKP_Silk_resampler_private_ARMA4( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_144 ], in, S->Coefs, nSamplesIn ); + } + + max_index_Q16 = SKP_LSHIFT32( nSamplesIn, 16 + S->input2x ); /* +1 if 2x upsampling */ + out = SKP_Silk_resampler_private_IIR_FIR_INTERPOL(out, buf, max_index_Q16, index_increment_Q16); + in += nSamplesIn; + inLen -= nSamplesIn; + + if( inLen > 0 ) { + /* More iterations to do; copy last part of filtered signal to beginning of buffer */ + SKP_memcpy( buf, &buf[ nSamplesIn << S->input2x ], RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) ); + } else { + break; + } + } + + /* Copy last part of filtered signal to the state for the next call */ + SKP_memcpy( S->sFIR, &buf[nSamplesIn << S->input2x ], RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) ); +} + diff --git a/libs/silk/src/SKP_Silk_resampler_private_copy.c b/libs/silk/src/SKP_Silk_resampler_private_copy.c new file mode 100644 index 0000000000..7c5b03197a --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_private_copy.c @@ -0,0 +1,49 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * File Name: SKP_Silk_resampler_private_copy.c * + * * + * Description: Copy. * + * * + * Copyright 2010 (c), Skype Limited * + * All rights reserved. * + * */ + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_private.h" + +/* Copy */ +void SKP_Silk_resampler_private_copy( + void *SS, /* I/O: Resampler state (unused) */ + SKP_int16 out[], /* O: Output signal */ + const SKP_int16 in[], /* I: Input signal */ + SKP_int32 inLen /* I: Number of input samples */ +) +{ + SKP_memcpy( out, in, inLen * sizeof( SKP_int16 ) ); +} diff --git a/libs/silk/src/SKP_Silk_resampler_private_down4.c b/libs/silk/src/SKP_Silk_resampler_private_down4.c new file mode 100644 index 0000000000..0d327c728f --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_private_down4.c @@ -0,0 +1,77 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * SKP_Silk_resampler_private_down4.c * + * * + * Downsample by a factor 4 * + * * + * Copyright 2010 (c), Skype Limited * + * */ + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_private.h" + +/* Downsample by a factor 4. Note: very low quality, only use with input sampling rates above 96 kHz. */ +void SKP_Silk_resampler_private_down4( + SKP_int32 *S, /* I/O: State vector [ 2 ] */ + SKP_int16 *out, /* O: Output signal [ floor(len/2) ] */ + const SKP_int16 *in, /* I: Input signal [ len ] */ + SKP_int32 inLen /* I: Number of input samples */ +) +{ + SKP_int32 k, len4 = SKP_RSHIFT32( inLen, 2 ); + SKP_int32 in32, out32, Y, X; + + SKP_assert( SKP_Silk_resampler_down2_0 > 0 ); + SKP_assert( SKP_Silk_resampler_down2_1 < 0 ); + + /* Internal variables and state are in Q10 format */ + for( k = 0; k < len4; k++ ) { + /* Add two input samples and convert to Q10 */ + in32 = SKP_LSHIFT( SKP_ADD32( (SKP_int32)in[ 4 * k ], (SKP_int32)in[ 4 * k + 1 ] ), 9 ); + + /* All-pass section for even input sample */ + Y = SKP_SUB32( in32, S[ 0 ] ); + X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_down2_1 ); + out32 = SKP_ADD32( S[ 0 ], X ); + S[ 0 ] = SKP_ADD32( in32, X ); + + /* Add two input samples and convert to Q10 */ + in32 = SKP_LSHIFT( SKP_ADD32( (SKP_int32)in[ 4 * k + 2 ], (SKP_int32)in[ 4 * k + 3 ] ), 9 ); + + /* All-pass section for odd input sample */ + Y = SKP_SUB32( in32, S[ 1 ] ); + X = SKP_SMULWB( Y, SKP_Silk_resampler_down2_0 ); + out32 = SKP_ADD32( out32, S[ 1 ] ); + out32 = SKP_ADD32( out32, X ); + S[ 1 ] = SKP_ADD32( in32, X ); + + /* Add, convert back to int16 and store to output */ + out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 11 ) ); + } +} diff --git a/libs/silk/src/SKP_Silk_resampler_private_down_FIR.c b/libs/silk/src/SKP_Silk_resampler_private_down_FIR.c new file mode 100644 index 0000000000..f84357beb1 --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_private_down_FIR.c @@ -0,0 +1,160 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * File Name: SKP_Silk_resampler_private_down_FIR.c * + * * + * Description: Hybrid IIR/FIR polyphase implementation of resampling * + * * + * Copyright 2010 (c), Skype Limited * + * All rights reserved. * + * */ + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_private.h" +SKP_INLINE SKP_int16 *SKP_Silk_resampler_private_down_FIR_INTERPOL0( + SKP_int16 *out, SKP_int32 *buf2, const SKP_int16 *FIR_Coefs, SKP_int32 max_index_Q16, SKP_int32 index_increment_Q16){ + + SKP_int32 index_Q16, res_Q6; + SKP_int32 *buf_ptr; + for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { + /* Integer part gives pointer to buffered input */ + buf_ptr = buf2 + SKP_RSHIFT( index_Q16, 16 ); + + /* Inner product */ + res_Q6 = SKP_SMULWB( SKP_ADD32( buf_ptr[ 0 ], buf_ptr[ 11 ] ), FIR_Coefs[ 0 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 1 ], buf_ptr[ 10 ] ), FIR_Coefs[ 1 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 2 ], buf_ptr[ 9 ] ), FIR_Coefs[ 2 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 3 ], buf_ptr[ 8 ] ), FIR_Coefs[ 3 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 4 ], buf_ptr[ 7 ] ), FIR_Coefs[ 4 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 5 ], buf_ptr[ 6 ] ), FIR_Coefs[ 5 ] ); + + /* Scale down, saturate and store in output array */ + *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) ); + } + return out; +} + +SKP_INLINE SKP_int16 *SKP_Silk_resampler_private_down_FIR_INTERPOL1( + SKP_int16 *out, SKP_int32 *buf2, const SKP_int16 *FIR_Coefs, SKP_int32 max_index_Q16, SKP_int32 index_increment_Q16, SKP_int32 FIR_Fracs){ + + SKP_int32 index_Q16, res_Q6; + SKP_int32 *buf_ptr; + SKP_int32 interpol_ind; + const SKP_int16 *interpol_ptr; + for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { + /* Integer part gives pointer to buffered input */ + buf_ptr = buf2 + SKP_RSHIFT( index_Q16, 16 ); + + /* Fractional part gives interpolation coefficients */ + interpol_ind = SKP_SMULWB( index_Q16 & 0xFFFF, FIR_Fracs ); + + /* Inner product */ + interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR / 2 * interpol_ind ]; + res_Q6 = SKP_SMULWB( buf_ptr[ 0 ], interpol_ptr[ 0 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 1 ], interpol_ptr[ 1 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 2 ], interpol_ptr[ 2 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 3 ], interpol_ptr[ 3 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 4 ], interpol_ptr[ 4 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 5 ], interpol_ptr[ 5 ] ); + interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR / 2 * ( FIR_Fracs - 1 - interpol_ind ) ]; + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 11 ], interpol_ptr[ 0 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 10 ], interpol_ptr[ 1 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 9 ], interpol_ptr[ 2 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 8 ], interpol_ptr[ 3 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 7 ], interpol_ptr[ 4 ] ); + res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 6 ], interpol_ptr[ 5 ] ); + + /* Scale down, saturate and store in output array */ + *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) ); + } + return out; +} + + +/* Resample with a 2x downsampler (optional), a 2nd order AR filter followed by FIR interpolation */ +void SKP_Silk_resampler_private_down_FIR( + void *SS, /* I/O: Resampler state */ + SKP_int16 out[], /* O: Output signal */ + const SKP_int16 in[], /* I: Input signal */ + SKP_int32 inLen /* I: Number of input samples */ +) +{ + SKP_Silk_resampler_state_struct *S = (SKP_Silk_resampler_state_struct *)SS; + SKP_int32 nSamplesIn; + SKP_int32 max_index_Q16, index_increment_Q16; + SKP_int16 buf1[ RESAMPLER_MAX_BATCH_SIZE_IN / 2 ]; + SKP_int32 buf2[ RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_DOWN_ORDER_FIR ]; + const SKP_int16 *FIR_Coefs; + + /* Copy buffered samples to start of buffer */ + SKP_memcpy( buf2, S->sFIR, RESAMPLER_DOWN_ORDER_FIR * sizeof( SKP_int32 ) ); + + FIR_Coefs = &S->Coefs[ 2 ]; + + /* Iterate over blocks of frameSizeIn input samples */ + index_increment_Q16 = S->invRatio_Q16; + while( 1 ) { + nSamplesIn = SKP_min( inLen, S->batchSize ); + + if( S->input2x == 1 ) { + /* Downsample 2x */ + SKP_Silk_resampler_down2( S->sDown2, buf1, in, nSamplesIn ); + + nSamplesIn = SKP_RSHIFT32( nSamplesIn, 1 ); + + /* Second-order AR filter (output in Q8) */ + SKP_Silk_resampler_private_AR2( S->sIIR, &buf2[ RESAMPLER_DOWN_ORDER_FIR ], buf1, S->Coefs, nSamplesIn ); + } else { + /* Second-order AR filter (output in Q8) */ + SKP_Silk_resampler_private_AR2( S->sIIR, &buf2[ RESAMPLER_DOWN_ORDER_FIR ], in, S->Coefs, nSamplesIn ); + } + + max_index_Q16 = SKP_LSHIFT32( nSamplesIn, 16 ); + + /* Interpolate filtered signal */ + if( S->FIR_Fracs == 1 ) { + out = SKP_Silk_resampler_private_down_FIR_INTERPOL0(out, buf2, FIR_Coefs, max_index_Q16, index_increment_Q16); + } else { + out = SKP_Silk_resampler_private_down_FIR_INTERPOL1(out, buf2, FIR_Coefs, max_index_Q16, index_increment_Q16, S->FIR_Fracs); + } + + in += nSamplesIn << S->input2x; + inLen -= nSamplesIn << S->input2x; + + if( inLen > S->input2x ) { + /* More iterations to do; copy last part of filtered signal to beginning of buffer */ + SKP_memcpy( buf2, &buf2[ nSamplesIn ], RESAMPLER_DOWN_ORDER_FIR * sizeof( SKP_int32 ) ); + } else { + break; + } + } + + /* Copy last part of filtered signal to the state for the next call */ + SKP_memcpy( S->sFIR, &buf2[ nSamplesIn ], RESAMPLER_DOWN_ORDER_FIR * sizeof( SKP_int32 ) ); +} + diff --git a/libs/silk/src/SKP_Silk_resampler_private_up2_HQ.c b/libs/silk/src/SKP_Silk_resampler_private_up2_HQ.c new file mode 100644 index 0000000000..8ae2548e36 --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_private_up2_HQ.c @@ -0,0 +1,118 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * SKP_Silk_resampler_private_up2_HQ.c * + * * + * Upsample by a factor 2, high quality * + * * + * Copyright 2010 (c), Skype Limited * + * */ + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_private.h" + +/* Upsample by a factor 2, high quality */ +/* Uses 2nd order allpass filters for the 2x upsampling, followed by a */ +/* notch filter just above Nyquist. */ +void SKP_Silk_resampler_private_up2_HQ( + SKP_int32 *S, /* I/O: Resampler state [ 6 ] */ + SKP_int16 *out, /* O: Output signal [ 2 * len ] */ + const SKP_int16 *in, /* I: Input signal [ len ] */ + SKP_int32 len /* I: Number of INPUT samples */ +) +{ + SKP_int32 k; + SKP_int32 in32, out32_1, out32_2, Y, X; + + SKP_assert( SKP_Silk_resampler_up2_hq_0[ 0 ] > 0 ); + SKP_assert( SKP_Silk_resampler_up2_hq_0[ 1 ] < 0 ); + SKP_assert( SKP_Silk_resampler_up2_hq_1[ 0 ] > 0 ); + SKP_assert( SKP_Silk_resampler_up2_hq_1[ 1 ] < 0 ); + + /* Internal variables and state are in Q10 format */ + for( k = 0; k < len; k++ ) { + /* Convert to Q10 */ + in32 = SKP_LSHIFT( (SKP_int32)in[ k ], 10 ); + + /* First all-pass section for even output sample */ + Y = SKP_SUB32( in32, S[ 0 ] ); + X = SKP_SMULWB( Y, SKP_Silk_resampler_up2_hq_0[ 0 ] ); + out32_1 = SKP_ADD32( S[ 0 ], X ); + S[ 0 ] = SKP_ADD32( in32, X ); + + /* Second all-pass section for even output sample */ + Y = SKP_SUB32( out32_1, S[ 1 ] ); + X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_hq_0[ 1 ] ); + out32_2 = SKP_ADD32( S[ 1 ], X ); + S[ 1 ] = SKP_ADD32( out32_1, X ); + + /* Biquad notch filter */ + out32_2 = SKP_SMLAWB( out32_2, S[ 5 ], SKP_Silk_resampler_up2_hq_notch[ 2 ] ); + out32_2 = SKP_SMLAWB( out32_2, S[ 4 ], SKP_Silk_resampler_up2_hq_notch[ 1 ] ); + out32_1 = SKP_SMLAWB( out32_2, S[ 4 ], SKP_Silk_resampler_up2_hq_notch[ 0 ] ); + S[ 5 ] = SKP_SUB32( out32_2, S[ 5 ] ); + + /* Apply gain in Q15, convert back to int16 and store to output */ + out[ 2 * k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT32( + SKP_SMLAWB( 256, out32_1, SKP_Silk_resampler_up2_hq_notch[ 3 ] ), 9 ) ); + + /* First all-pass section for odd output sample */ + Y = SKP_SUB32( in32, S[ 2 ] ); + X = SKP_SMULWB( Y, SKP_Silk_resampler_up2_hq_1[ 0 ] ); + out32_1 = SKP_ADD32( S[ 2 ], X ); + S[ 2 ] = SKP_ADD32( in32, X ); + + /* Second all-pass section for odd output sample */ + Y = SKP_SUB32( out32_1, S[ 3 ] ); + X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_hq_1[ 1 ] ); + out32_2 = SKP_ADD32( S[ 3 ], X ); + S[ 3 ] = SKP_ADD32( out32_1, X ); + + /* Biquad notch filter */ + out32_2 = SKP_SMLAWB( out32_2, S[ 4 ], SKP_Silk_resampler_up2_hq_notch[ 2 ] ); + out32_2 = SKP_SMLAWB( out32_2, S[ 5 ], SKP_Silk_resampler_up2_hq_notch[ 1 ] ); + out32_1 = SKP_SMLAWB( out32_2, S[ 5 ], SKP_Silk_resampler_up2_hq_notch[ 0 ] ); + S[ 4 ] = SKP_SUB32( out32_2, S[ 4 ] ); + + /* Apply gain in Q15, convert back to int16 and store to output */ + out[ 2 * k + 1 ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT32( + SKP_SMLAWB( 256, out32_1, SKP_Silk_resampler_up2_hq_notch[ 3 ] ), 9 ) ); + } +} + + +void SKP_Silk_resampler_private_up2_HQ_wrapper( + void *SS, /* I/O: Resampler state (unused) */ + SKP_int16 *out, /* O: Output signal [ 2 * len ] */ + const SKP_int16 *in, /* I: Input signal [ len ] */ + SKP_int32 len /* I: Number of input samples */ +) +{ + SKP_Silk_resampler_state_struct *S = (SKP_Silk_resampler_state_struct *)SS; + SKP_Silk_resampler_private_up2_HQ( S->sIIR, out, in, len ); +} diff --git a/libs/silk/src/SKP_Silk_resampler_private_up4.c b/libs/silk/src/SKP_Silk_resampler_private_up4.c new file mode 100644 index 0000000000..9c63d400e2 --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_private_up4.c @@ -0,0 +1,81 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * SKP_Silk_resampler_private_up4.c * + * * + * Upsample by a factor 4, low quality * + * * + * Copyright 2010 (c), Skype Limited * + * */ + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_private.h" + +/* Upsample by a factor 4, Note: very low quality, only use with output sampling rates above 96 kHz. */ +void SKP_Silk_resampler_private_up4( + SKP_int32 *S, /* I/O: State vector [ 2 ] */ + SKP_int16 *out, /* O: Output signal [ 4 * len ] */ + const SKP_int16 *in, /* I: Input signal [ len ] */ + SKP_int32 len /* I: Number of INPUT samples */ +) +{ + SKP_int32 k; + SKP_int32 in32, out32, Y, X; + SKP_int16 out16; + + SKP_assert( SKP_Silk_resampler_up2_lq_0 > 0 ); + SKP_assert( SKP_Silk_resampler_up2_lq_1 < 0 ); + + /* Internal variables and state are in Q10 format */ + for( k = 0; k < len; k++ ) { + /* Convert to Q10 */ + in32 = SKP_LSHIFT( (SKP_int32)in[ k ], 10 ); + + /* All-pass section for even output sample */ + Y = SKP_SUB32( in32, S[ 0 ] ); + X = SKP_SMULWB( Y, SKP_Silk_resampler_up2_lq_0 ); + out32 = SKP_ADD32( S[ 0 ], X ); + S[ 0 ] = SKP_ADD32( in32, X ); + + /* Convert back to int16 and store to output */ + out16 = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) ); + out[ 4 * k ] = out16; + out[ 4 * k + 1 ] = out16; + + /* All-pass section for odd output sample */ + Y = SKP_SUB32( in32, S[ 1 ] ); + X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_lq_1 ); + out32 = SKP_ADD32( S[ 1 ], X ); + S[ 1 ] = SKP_ADD32( in32, X ); + + /* Convert back to int16 and store to output */ + out16 = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) ); + out[ 4 * k + 2 ] = out16; + out[ 4 * k + 3 ] = out16; + } +} diff --git a/libs/silk/src/SKP_Silk_resampler_rom.c b/libs/silk/src/SKP_Silk_resampler_rom.c new file mode 100644 index 0000000000..96ecde3659 --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_rom.c @@ -0,0 +1,269 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * File Name: SKP_Silk_resampler_rom.c * + * * + * Description: Filter coefficients for IIR/FIR polyphase resampling * + * Total size: 550 Words (1.1 kB) * + * * + * Copyright 2010 (c), Skype Limited * + * All rights reserved. * + * */ + +#include "SKP_Silk_resampler_private.h" + +/* Tables for 2x downsampler */ +const SKP_int16 SKP_Silk_resampler_down2_0 = 9872; +const SKP_int16 SKP_Silk_resampler_down2_1 = 39809 - 65536; + +/* Tables for 2x upsampler, low quality */ +const SKP_int16 SKP_Silk_resampler_up2_lq_0 = 8102; +const SKP_int16 SKP_Silk_resampler_up2_lq_1 = 36783 - 65536; + +/* Tables for 2x upsampler, high quality */ +const SKP_int16 SKP_Silk_resampler_up2_hq_0[ 2 ] = { 4280, 33727 - 65536 }; +const SKP_int16 SKP_Silk_resampler_up2_hq_1[ 2 ] = { 16295, 54015 - 65536 }; +/* Matlab code for the notch filter coefficients: */ +/* B = [1, 0.12, 1]; A = [1, 0.055, 0.8]; G = 0.87; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]); */ +/* fprintf('\t%6d, %6d, %6d, %6d\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */ +const SKP_int16 SKP_Silk_resampler_up2_hq_notch[ 4 ] = { 7864, -3604, 13107, 28508 }; + + +/* Tables with IIR and FIR coefficients for fractional downsamplers (70 Words) */ +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ] = { + -18249, -12532, + -97, 284, -495, 309, 10268, 20317, + -94, 156, -48, -720, 5984, 18278, + -45, -4, 237, -847, 2540, 14662, +}; + +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR / 2 ] = { + -11891, -12486, + 20, 211, -657, 688, 8423, 15911, + -44, 197, -152, -653, 3855, 13015, +}; + +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ] = { + 2415, -13101, + 158, -295, -400, 1265, 4832, 7968, +}; + +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_3_8_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ] = { + 13270, -13738, + -294, -123, 747, 2043, 3339, 3995, + -151, -311, 414, 1583, 2947, 3877, + -33, -389, 143, 1141, 2503, 3653, +}; + +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ] = { + 16643, -14000, + -331, 19, 581, 1421, 2290, 2845, +}; + +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = { + -2797, -6507, + 4697, 10739, + 1567, 8276, +}; + +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_1_3_COEFS_LQ[ 2 + 3 ] = { + 16777, -9792, + 890, 1614, 2148, +}; + + +/* Tables with coefficients for 4th order ARMA filter (35 Words), in a packed format: */ +/* { B1_Q14[1], B2_Q14[1], -A1_Q14[1], -A1_Q14[2], -A2_Q14[1], -A2_Q14[2], gain_Q16 } */ +/* where it is assumed that B*_Q14[0], B*_Q14[2], A*_Q14[0] are all 16384 */ +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_320_441_ARMA4_COEFS[ 7 ] = { + 31454, 24746, -9706, -3386, -17911, -13243, 24797 +}; + +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_240_441_ARMA4_COEFS[ 7 ] = { + 28721, 11254, 3189, -2546, -1495, -12618, 11562 +}; + +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_160_441_ARMA4_COEFS[ 7 ] = { + 23492, -6457, 14358, -4856, 14654, -13008, 4456 +}; + +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_120_441_ARMA4_COEFS[ 7 ] = { + 19311, -15569, 19489, -6950, 21441, -13559, 2370 +}; + +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_80_441_ARMA4_COEFS[ 7 ] = { + 13248, -23849, 24126, -9486, 26806, -14286, 1065 +}; + +/* Table with interplation fractions of 1/288 : 2/288 : 287/288 (432 Words) */ +SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_resampler_frac_FIR_144[ 144 ][ RESAMPLER_ORDER_FIR_144 / 2 ] = { + { -647, 1884, 30078}, + { -625, 1736, 30044}, + { -603, 1591, 30005}, + { -581, 1448, 29963}, + { -559, 1308, 29917}, + { -537, 1169, 29867}, + { -515, 1032, 29813}, + { -494, 898, 29755}, + { -473, 766, 29693}, + { -452, 636, 29627}, + { -431, 508, 29558}, + { -410, 383, 29484}, + { -390, 260, 29407}, + { -369, 139, 29327}, + { -349, 20, 29242}, + { -330, -97, 29154}, + { -310, -211, 29062}, + { -291, -324, 28967}, + { -271, -434, 28868}, + { -253, -542, 28765}, + { -234, -647, 28659}, + { -215, -751, 28550}, + { -197, -852, 28436}, + { -179, -951, 28320}, + { -162, -1048, 28200}, + { -144, -1143, 28077}, + { -127, -1235, 27950}, + { -110, -1326, 27820}, + { -94, -1414, 27687}, + { -77, -1500, 27550}, + { -61, -1584, 27410}, + { -45, -1665, 27268}, + { -30, -1745, 27122}, + { -15, -1822, 26972}, + { 0, -1897, 26820}, + { 15, -1970, 26665}, + { 29, -2041, 26507}, + { 44, -2110, 26346}, + { 57, -2177, 26182}, + { 71, -2242, 26015}, + { 84, -2305, 25845}, + { 97, -2365, 25673}, + { 110, -2424, 25498}, + { 122, -2480, 25320}, + { 134, -2534, 25140}, + { 146, -2587, 24956}, + { 157, -2637, 24771}, + { 168, -2685, 24583}, + { 179, -2732, 24392}, + { 190, -2776, 24199}, + { 200, -2819, 24003}, + { 210, -2859, 23805}, + { 220, -2898, 23605}, + { 229, -2934, 23403}, + { 238, -2969, 23198}, + { 247, -3002, 22992}, + { 255, -3033, 22783}, + { 263, -3062, 22572}, + { 271, -3089, 22359}, + { 279, -3114, 22144}, + { 286, -3138, 21927}, + { 293, -3160, 21709}, + { 300, -3180, 21488}, + { 306, -3198, 21266}, + { 312, -3215, 21042}, + { 318, -3229, 20816}, + { 323, -3242, 20589}, + { 328, -3254, 20360}, + { 333, -3263, 20130}, + { 338, -3272, 19898}, + { 342, -3278, 19665}, + { 346, -3283, 19430}, + { 350, -3286, 19194}, + { 353, -3288, 18957}, + { 356, -3288, 18718}, + { 359, -3286, 18478}, + { 362, -3283, 18238}, + { 364, -3279, 17996}, + { 366, -3273, 17753}, + { 368, -3266, 17509}, + { 369, -3257, 17264}, + { 371, -3247, 17018}, + { 372, -3235, 16772}, + { 372, -3222, 16525}, + { 373, -3208, 16277}, + { 373, -3192, 16028}, + { 373, -3175, 15779}, + { 373, -3157, 15529}, + { 372, -3138, 15279}, + { 371, -3117, 15028}, + { 370, -3095, 14777}, + { 369, -3072, 14526}, + { 368, -3048, 14274}, + { 366, -3022, 14022}, + { 364, -2996, 13770}, + { 362, -2968, 13517}, + { 359, -2940, 13265}, + { 357, -2910, 13012}, + { 354, -2880, 12760}, + { 351, -2848, 12508}, + { 348, -2815, 12255}, + { 344, -2782, 12003}, + { 341, -2747, 11751}, + { 337, -2712, 11500}, + { 333, -2676, 11248}, + { 328, -2639, 10997}, + { 324, -2601, 10747}, + { 320, -2562, 10497}, + { 315, -2523, 10247}, + { 310, -2482, 9998}, + { 305, -2442, 9750}, + { 300, -2400, 9502}, + { 294, -2358, 9255}, + { 289, -2315, 9009}, + { 283, -2271, 8763}, + { 277, -2227, 8519}, + { 271, -2182, 8275}, + { 265, -2137, 8032}, + { 259, -2091, 7791}, + { 252, -2045, 7550}, + { 246, -1998, 7311}, + { 239, -1951, 7072}, + { 232, -1904, 6835}, + { 226, -1856, 6599}, + { 219, -1807, 6364}, + { 212, -1758, 6131}, + { 204, -1709, 5899}, + { 197, -1660, 5668}, + { 190, -1611, 5439}, + { 183, -1561, 5212}, + { 175, -1511, 4986}, + { 168, -1460, 4761}, + { 160, -1410, 4538}, + { 152, -1359, 4317}, + { 145, -1309, 4098}, + { 137, -1258, 3880}, + { 129, -1207, 3664}, + { 121, -1156, 3450}, + { 113, -1105, 3238}, + { 105, -1054, 3028}, + { 97, -1003, 2820}, + { 89, -952, 2614}, + { 81, -901, 2409}, + { 73, -851, 2207}, +}; diff --git a/libs/silk/src/SKP_Silk_resampler_rom.h b/libs/silk/src/SKP_Silk_resampler_rom.h new file mode 100644 index 0000000000..3369cb736d --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_rom.h @@ -0,0 +1,91 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * File Name: SKP_Silk_resample_rom.h * + * * + * Description: Header file for FIR resampling of * + * 32 and 44 kHz input * + * * + * Copyright 2007 (c), Skype Limited * + * All rights reserved. * + * * + * Date: 070807 * + * */ + +#ifndef _SKP_SILK_FIX_RESAMPLER_ROM_H_ +#define _SKP_SILK_FIX_RESAMPLER_ROM_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "SKP_Silk_typedef.h" +#include "SKP_Silk_resampler_structs.h" + +#define RESAMPLER_DOWN_ORDER_FIR 12 +#define RESAMPLER_ORDER_FIR_144 6 + + +/* Tables for 2x downsampler. Values above 32767 intentionally wrap to a negative value. */ +extern const SKP_int16 SKP_Silk_resampler_down2_0; +extern const SKP_int16 SKP_Silk_resampler_down2_1; + +/* Tables for 2x upsampler, low quality. Values above 32767 intentionally wrap to a negative value. */ +extern const SKP_int16 SKP_Silk_resampler_up2_lq_0; +extern const SKP_int16 SKP_Silk_resampler_up2_lq_1; + +/* Tables for 2x upsampler, high quality. Values above 32767 intentionally wrap to a negative value. */ +extern const SKP_int16 SKP_Silk_resampler_up2_hq_0[ 2 ]; +extern const SKP_int16 SKP_Silk_resampler_up2_hq_1[ 2 ]; +extern const SKP_int16 SKP_Silk_resampler_up2_hq_notch[ 4 ]; + +/* Tables with IIR and FIR coefficients for fractional downsamplers */ +extern const SKP_int16 SKP_Silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ]; +extern const SKP_int16 SKP_Silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR / 2 ]; +extern const SKP_int16 SKP_Silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ]; +extern const SKP_int16 SKP_Silk_Resampler_3_8_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ]; +extern const SKP_int16 SKP_Silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ]; +extern const SKP_int16 SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ]; +extern const SKP_int16 SKP_Silk_Resampler_1_3_COEFS_LQ[ 2 + 3 ]; + +/* Tables with coefficients for 4th order ARMA filter */ +extern const SKP_int16 SKP_Silk_Resampler_320_441_ARMA4_COEFS[ 7 ]; +extern const SKP_int16 SKP_Silk_Resampler_240_441_ARMA4_COEFS[ 7 ]; +extern const SKP_int16 SKP_Silk_Resampler_160_441_ARMA4_COEFS[ 7 ]; +extern const SKP_int16 SKP_Silk_Resampler_120_441_ARMA4_COEFS[ 7 ]; +extern const SKP_int16 SKP_Silk_Resampler_80_441_ARMA4_COEFS[ 7 ]; + +/* Table with interplation fractions of 1/288 : 2/288 : 287/288 (432 Words) */ +extern const SKP_int16 SKP_Silk_resampler_frac_FIR_144[ 144 ][ RESAMPLER_ORDER_FIR_144 / 2 ]; + +#ifdef __cplusplus +} +#endif + +#endif // _SKP_SILK_FIX_RESAMPLER_ROM_H_ diff --git a/libs/silk/src/SKP_Silk_resampler_structs.h b/libs/silk/src/SKP_Silk_resampler_structs.h new file mode 100644 index 0000000000..48c326946c --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_structs.h @@ -0,0 +1,80 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * File Name: SKP_Silk_resampler_structs.h * + * * + * Description: Structs for IIR/FIR resamplers * + * * + * Copyright 2010 (c), Skype Limited * + * All rights reserved. * + * * + * */ + +#ifndef SKP_Silk_RESAMPLER_STRUCTS_H +#define SKP_Silk_RESAMPLER_STRUCTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Flag to enable support for input/output sampling rates above 48 kHz. Turn off for embedded devices */ +#define RESAMPLER_SUPPORT_ABOVE_48KHZ 1 + +#define SKP_Silk_RESAMPLER_MAX_FIR_ORDER 16 +#define SKP_Silk_RESAMPLER_MAX_IIR_ORDER 6 + + +typedef struct _SKP_Silk_resampler_state_struct{ + SKP_int32 sIIR[ SKP_Silk_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */ + SKP_int32 sFIR[ SKP_Silk_RESAMPLER_MAX_FIR_ORDER ]; + SKP_int32 sDown2[ 2 ]; + void (*resampler_function)( void *, SKP_int16 *, const SKP_int16 *, SKP_int32 ); + void (*up2_function)( SKP_int32 *, SKP_int16 *, const SKP_int16 *, SKP_int32 ); + SKP_int32 batchSize; + SKP_int32 invRatio_Q16; + SKP_int32 FIR_Fracs; + SKP_int32 input2x; + const SKP_int16 *Coefs; +#if RESAMPLER_SUPPORT_ABOVE_48KHZ + SKP_int32 sDownPre[ 2 ]; + SKP_int32 sUpPost[ 2 ]; + void (*down_pre_function)( SKP_int32 *, SKP_int16 *, const SKP_int16 *, SKP_int32 ); + void (*up_post_function)( SKP_int32 *, SKP_int16 *, const SKP_int16 *, SKP_int32 ); + SKP_int32 batchSizePrePost; + SKP_int32 ratio_Q16; + SKP_int32 nPreDownsamplers; + SKP_int32 nPostUpsamplers; +#endif + SKP_int32 magic_number; +} SKP_Silk_resampler_state_struct; + +#ifdef __cplusplus +} +#endif +#endif /* SKP_Silk_RESAMPLER_STRUCTS_H */ + diff --git a/libs/silk/src/SKP_Silk_resampler_up2.c b/libs/silk/src/SKP_Silk_resampler_up2.c new file mode 100644 index 0000000000..718b2740d0 --- /dev/null +++ b/libs/silk/src/SKP_Silk_resampler_up2.c @@ -0,0 +1,75 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * SKP_Silk_resampler_up2.c * + * * + * Upsample by a factor 2, low quality * + * * + * Copyright 2010 (c), Skype Limited * + * */ + +#include "SKP_Silk_SigProc_FIX.h" +#include "SKP_Silk_resampler_rom.h" + +/* Upsample by a factor 2, low quality */ +void SKP_Silk_resampler_up2( + SKP_int32 *S, /* I/O: State vector [ 2 ] */ + SKP_int16 *out, /* O: Output signal [ 2 * len ] */ + const SKP_int16 *in, /* I: Input signal [ len ] */ + SKP_int32 len /* I: Number of input samples */ +) +{ + SKP_int32 k; + SKP_int32 in32, out32, Y, X; + + SKP_assert( SKP_Silk_resampler_up2_lq_0 > 0 ); + SKP_assert( SKP_Silk_resampler_up2_lq_1 < 0 ); + /* Internal variables and state are in Q10 format */ + for( k = 0; k < len; k++ ) { + /* Convert to Q10 */ + in32 = SKP_LSHIFT( (SKP_int32)in[ k ], 10 ); + + /* All-pass section for even output sample */ + Y = SKP_SUB32( in32, S[ 0 ] ); + X = SKP_SMULWB( Y, SKP_Silk_resampler_up2_lq_0 ); + out32 = SKP_ADD32( S[ 0 ], X ); + S[ 0 ] = SKP_ADD32( in32, X ); + + /* Convert back to int16 and store to output */ + out[ 2 * k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) ); + + /* All-pass section for odd output sample */ + Y = SKP_SUB32( in32, S[ 1 ] ); + X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_lq_1 ); + out32 = SKP_ADD32( S[ 1 ], X ); + S[ 1 ] = SKP_ADD32( in32, X ); + + /* Convert back to int16 and store to output */ + out[ 2 * k + 1 ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) ); + } +} diff --git a/libs/silk/src/SKP_Silk_setup_complexity.h b/libs/silk/src/SKP_Silk_setup_complexity.h new file mode 100644 index 0000000000..b6933ae5a3 --- /dev/null +++ b/libs/silk/src/SKP_Silk_setup_complexity.h @@ -0,0 +1,99 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#include "SKP_Silk_main.h" +#include "SKP_Silk_tuning_parameters.h" + +SKP_INLINE SKP_int SKP_Silk_setup_complexity( + SKP_Silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ + SKP_int Complexity /* I Complexity (0->low; 1->medium; 2->high) */ +) +{ + SKP_int ret = SKP_SILK_NO_ERROR; + + /* Check that settings are valid */ + if( LOW_COMPLEXITY_ONLY && Complexity != 0 ) { + ret = SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING; + } + + /* Set encoding complexity */ + if( Complexity == 0 || LOW_COMPLEXITY_ONLY ) { + /* Low complexity */ + psEncC->Complexity = 0; + psEncC->pitchEstimationComplexity = PITCH_EST_COMPLEXITY_LC_MODE; + psEncC->pitchEstimationThreshold_Q16 = SKP_FIX_CONST( FIND_PITCH_CORRELATION_THRESHOLD_LC_MODE, 16 ); + psEncC->pitchEstimationLPCOrder = 6; + psEncC->shapingLPCOrder = 8; + psEncC->la_shape = 3 * psEncC->fs_kHz; + psEncC->nStatesDelayedDecision = 1; + psEncC->useInterpolatedNLSFs = 0; + psEncC->LTPQuantLowComplexity = 1; + psEncC->NLSF_MSVQ_Survivors = MAX_NLSF_MSVQ_SURVIVORS_LC_MODE; + psEncC->warping_Q16 = 0; + } else if( Complexity == 1 ) { + /* Medium complexity */ + psEncC->Complexity = 1; + psEncC->pitchEstimationComplexity = PITCH_EST_COMPLEXITY_MC_MODE; + psEncC->pitchEstimationThreshold_Q16 = SKP_FIX_CONST( FIND_PITCH_CORRELATION_THRESHOLD_MC_MODE, 16 ); + psEncC->pitchEstimationLPCOrder = 12; + psEncC->shapingLPCOrder = 12; + psEncC->la_shape = 5 * psEncC->fs_kHz; + psEncC->nStatesDelayedDecision = 2; + psEncC->useInterpolatedNLSFs = 0; + psEncC->LTPQuantLowComplexity = 0; + psEncC->NLSF_MSVQ_Survivors = MAX_NLSF_MSVQ_SURVIVORS_MC_MODE; + psEncC->warping_Q16 = psEncC->fs_kHz * SKP_FIX_CONST( WARPING_MULTIPLIER, 16 ); + } else if( Complexity == 2 ) { + /* High complexity */ + psEncC->Complexity = 2; + psEncC->pitchEstimationComplexity = PITCH_EST_COMPLEXITY_HC_MODE; + psEncC->pitchEstimationThreshold_Q16 = SKP_FIX_CONST( FIND_PITCH_CORRELATION_THRESHOLD_HC_MODE, 16 ); + psEncC->pitchEstimationLPCOrder = 16; + psEncC->shapingLPCOrder = 16; + psEncC->la_shape = 5 * psEncC->fs_kHz; + psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES; + psEncC->useInterpolatedNLSFs = 1; + psEncC->LTPQuantLowComplexity = 0; + psEncC->NLSF_MSVQ_Survivors = MAX_NLSF_MSVQ_SURVIVORS; + psEncC->warping_Q16 = psEncC->fs_kHz * SKP_FIX_CONST( WARPING_MULTIPLIER, 16 ); + } else { + ret = SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING; + } + + /* Do not allow higher pitch estimation LPC order than predict LPC order */ + psEncC->pitchEstimationLPCOrder = SKP_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder ); + psEncC->shapeWinLength = 5 * psEncC->fs_kHz + 2 * psEncC->la_shape; + + SKP_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER ); + SKP_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER ); + SKP_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES ); + SKP_assert( psEncC->warping_Q16 <= 32767 ); + SKP_assert( psEncC->la_shape <= LA_SHAPE_MAX ); + SKP_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX ); + + return( ret ); +} diff --git a/libs/silk/src/SKP_Silk_tuning_parameters.h b/libs/silk/src/SKP_Silk_tuning_parameters.h new file mode 100644 index 0000000000..e98272d1b1 --- /dev/null +++ b/libs/silk/src/SKP_Silk_tuning_parameters.h @@ -0,0 +1,183 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SKP_SILK_TUNING_PARAMETERS_H +#define SKP_SILK_TUNING_PARAMETERS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*******************/ +/* Pitch estimator */ +/*******************/ + +/* Level of noise floor for whitening filter LPC analysis in pitch analysis */ +#define FIND_PITCH_WHITE_NOISE_FRACTION 1e-3f + +/* Bandwidth expansion for whitening filter in pitch analysis */ +#define FIND_PITCH_BANDWITH_EXPANSION 0.99f + +/* Threshold used by pitch estimator for early escape */ +#define FIND_PITCH_CORRELATION_THRESHOLD_HC_MODE 0.7f +#define FIND_PITCH_CORRELATION_THRESHOLD_MC_MODE 0.75f +#define FIND_PITCH_CORRELATION_THRESHOLD_LC_MODE 0.8f + +/*********************/ +/* Linear prediction */ +/*********************/ + +/* LPC analysis defines: regularization and bandwidth expansion */ +#define FIND_LPC_COND_FAC 2.5e-5f +#define FIND_LPC_CHIRP 0.99995f + +/* LTP analysis defines */ +#define FIND_LTP_COND_FAC 1e-5f +#define LTP_DAMPING 0.01f +#define LTP_SMOOTHING 0.1f + +/* LTP quantization settings */ +#define MU_LTP_QUANT_NB 0.03f +#define MU_LTP_QUANT_MB 0.025f +#define MU_LTP_QUANT_WB 0.02f +#define MU_LTP_QUANT_SWB 0.016f + +/***********************/ +/* High pass filtering */ +/***********************/ + +/* Smoothing parameters for low end of pitch frequency range estimation */ +#define VARIABLE_HP_SMTH_COEF1 0.1f +#define VARIABLE_HP_SMTH_COEF2 0.015f + +/* Min and max values for low end of pitch frequency range estimation */ +#define VARIABLE_HP_MIN_FREQ 80.0f +#define VARIABLE_HP_MAX_FREQ 150.0f + +/* Max absolute difference between log2 of pitch frequency and smoother state, to enter the smoother */ +#define VARIABLE_HP_MAX_DELTA_FREQ 0.4f + +/***********/ +/* Various */ +/***********/ + +/* Required speech activity for counting frame as active */ +#define WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES 0.7f + +#define SPEECH_ACTIVITY_DTX_THRES 0.1f + +/* Speech Activity LBRR enable threshold (needs tuning) */ +#define LBRR_SPEECH_ACTIVITY_THRES 0.5f + +/*************************/ +/* Perceptual parameters */ +/*************************/ + +/* reduction in coding SNR during low speech activity */ +#define BG_SNR_DECR_dB 4.0f + +/* factor for reducing quantization noise during voiced speech */ +#define HARM_SNR_INCR_dB 2.0f + +/* factor for reducing quantization noise for unvoiced sparse signals */ +#define SPARSE_SNR_INCR_dB 2.0f + +/* threshold for sparseness measure above which to use lower quantization offset during unvoiced */ +#define SPARSENESS_THRESHOLD_QNT_OFFSET 0.75f + +/* warping control */ +#define WARPING_MULTIPLIER 0.015f + +/* fraction added to first autocorrelation value */ +#define SHAPE_WHITE_NOISE_FRACTION 1e-5f + +/* noise shaping filter chirp factor */ +#define BANDWIDTH_EXPANSION 0.95f + +/* difference between chirp factors for analysis and synthesis noise shaping filters at low bitrates */ +#define LOW_RATE_BANDWIDTH_EXPANSION_DELTA 0.01f + +/* gain reduction for fricatives */ +#define DE_ESSER_COEF_SWB_dB 2.0f +#define DE_ESSER_COEF_WB_dB 1.0f + +/* extra harmonic boosting (signal shaping) at low bitrates */ +#define LOW_RATE_HARMONIC_BOOST 0.1f + +/* extra harmonic boosting (signal shaping) for noisy input signals */ +#define LOW_INPUT_QUALITY_HARMONIC_BOOST 0.1f + +/* harmonic noise shaping */ +#define HARMONIC_SHAPING 0.3f + +/* extra harmonic noise shaping for high bitrates or noisy input */ +#define HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING 0.2f + +/* parameter for shaping noise towards higher frequencies */ +#define HP_NOISE_COEF 0.3f + +/* parameter for shaping noise even more towards higher frequencies during voiced speech */ +#define HARM_HP_NOISE_COEF 0.35f + +/* parameter for applying a high-pass tilt to the input signal */ +#define INPUT_TILT 0.05f + +/* parameter for extra high-pass tilt to the input signal at high rates */ +#define HIGH_RATE_INPUT_TILT 0.1f + +/* parameter for reducing noise at the very low frequencies */ +#define LOW_FREQ_SHAPING 3.0f + +/* less reduction of noise at the very low frequencies for signals with low SNR at low frequencies */ +#define LOW_QUALITY_LOW_FREQ_SHAPING_DECR 0.5f + +/* noise floor to put a lower limit on the quantization step size */ +#define NOISE_FLOOR_dB 4.0f + +/* noise floor relative to active speech gain level */ +#define RELATIVE_MIN_GAIN_dB -50.0f + +/* subframe smoothing coefficient for determining active speech gain level (lower -> more smoothing) */ +#define GAIN_SMOOTHING_COEF 1e-3f + +/* subframe smoothing coefficient for HarmBoost, HarmShapeGain, Tilt (lower -> more smoothing) */ +#define SUBFR_SMTH_COEF 0.4f + +/* parameters defining the R/D tradeoff in the residual quantizer */ +#define LAMBDA_OFFSET 1.2f +#define LAMBDA_SPEECH_ACT -0.3f +#define LAMBDA_DELAYED_DECISIONS -0.05f +#define LAMBDA_INPUT_QUALITY -0.2f +#define LAMBDA_CODING_QUALITY -0.1f +#define LAMBDA_QUANT_OFFSET 1.5f + +#ifdef __cplusplus +} +#endif + +#endif // SKP_SILK_TUNING_PARAMETERS_H diff --git a/libs/silk/src/SKP_Silk_warped_autocorrelation_FIX.c b/libs/silk/src/SKP_Silk_warped_autocorrelation_FIX.c new file mode 100644 index 0000000000..9a8d80db2b --- /dev/null +++ b/libs/silk/src/SKP_Silk_warped_autocorrelation_FIX.c @@ -0,0 +1,86 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, (subject to the limitations in the disclaimer below) +are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Skype Limited, nor the names of specific +contributors, may be used to endorse or promote products derived from +this software without specific prior written permission. +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED +BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#include "SKP_Silk_main_FIX.h" + +#define QC 10 +#define QS 14 + + +/* Autocorrelations for a warped frequency axis */ +void SKP_Silk_warped_autocorrelation_FIX( + SKP_int32 *corr, /* O Result [order + 1] */ + SKP_int *scale, /* O Scaling of the correlation vector */ + const SKP_int16 *input, /* I Input data to correlate */ + const SKP_int16 warping_Q16, /* I Warping coefficient */ + const SKP_int length, /* I Length of input */ + const SKP_int order /* I Correlation order (even) */ +) +{ + SKP_int n, i, lsh; + SKP_int32 tmp1_QS, tmp2_QS; + SKP_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; + SKP_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; + + /* Order must be even */ + SKP_assert( ( order & 1 ) == 0 ); + SKP_assert( 2 * QS - QC >= 0 ); + + /* Loop over samples */ + for( n = 0; n < length; n++ ) { + tmp1_QS = SKP_LSHIFT32( ( SKP_int32 )input[ n ], QS ); + /* Loop over allpass sections */ + for( i = 0; i < order; i += 2 ) { + /* Output of allpass section */ + tmp2_QS = SKP_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 ); + state_QS[ i ] = tmp1_QS; + corr_QC[ i ] += SKP_RSHIFT64( SKP_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); + /* Output of allpass section */ + tmp1_QS = SKP_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 ); + state_QS[ i + 1 ] = tmp2_QS; + corr_QC[ i + 1 ] += SKP_RSHIFT64( SKP_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC ); + } + state_QS[ order ] = tmp1_QS; + corr_QC[ order ] += SKP_RSHIFT64( SKP_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); + } + + lsh = SKP_Silk_CLZ64( corr_QC[ 0 ] ) - 35; + lsh = SKP_LIMIT( lsh, -12 - QC, 30 - QC ); + *scale = -( QC + lsh ); + SKP_assert( *scale >= -30 && *scale <= 12 ); + if( lsh >= 0 ) { + for( i = 0; i < order + 1; i++ ) { + corr[ i ] = ( SKP_int32 )SKP_CHECK_FIT32( SKP_LSHIFT64( corr_QC[ i ], lsh ) ); + } + } else { + for( i = 0; i < order + 1; i++ ) { + corr[ i ] = ( SKP_int32 )SKP_CHECK_FIT32( SKP_RSHIFT64( corr_QC[ i ], -lsh ) ); + } + } + SKP_assert( corr_QC[ 0 ] >= 0 ); // If breaking, decrease QC +} + diff --git a/libs/silk/test_vectors/How to use the test vectors.txt b/libs/silk/test_vectors/How to use the test vectors.txt new file mode 100644 index 0000000000..8abf1ca7f0 --- /dev/null +++ b/libs/silk/test_vectors/How to use the test vectors.txt @@ -0,0 +1,24 @@ +Use the following scripts to verify the decoder implementation: + +o test_encoder.bat / test_encoder.sh + + Make sure the encoder executable to be tested exists in the parent directory, and run + test_encoder.bat (win) or test_encoder.sh (linux/mac). This will run the encoder + and compare the output bitstream with the reference bitstream files. The result is + written to test_encoder_report.txt. + For each file, the bitstreams are either bit-exact or they differ. The compatibility + test is passed if each file is reported as "PASS". + +o test_decoder.bat / test_decoder.sh + + Make sure the decoder executable to be tested exists in the parent directory, and run + test_decoder.bat (win) or test_decoder.sh (linux/mac). This will run the decoder + and compare the output audio file with the reference audio files. The result is + written to test_decoder_report.txt. + For each file, the bitstreams are either bit-exact or they match up to a certain + average weighted SNR. The compatibility test is passed if each file is reported as + "PASS". + + +NOTE: When using the shell script, make sure it is marked as executable. + This can be done by: chmod +x *.sh diff --git a/libs/silk/test_vectors/test_decoder.bat b/libs/silk/test_vectors/test_decoder.bat new file mode 100644 index 0000000000..ff10c9e33f --- /dev/null +++ b/libs/silk/test_vectors/test_decoder.bat @@ -0,0 +1,143 @@ +@echo off + +SET BITSTREAMPATH=./test_vectors/bitstream/ +SET OUTPUTPATH=./test_vectors/output/ +SET DEC=Decoder.exe +SET COMP=SignalCompare.exe + +cd .. + +:: 8 kHz + +:: 8 kHz, 60 ms, 8 kbps, complexity 0 +SET PARAMS=8_kHz_60_ms_8_kbps +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm -fs 24000 > test_decoder_report.txt + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -Fs_API 8000 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%_8_kHz_out.pcm tmp.pcm -fs 8000 >> test_decoder_report.txt + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -Fs_API 12000 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%_12_kHz_out.pcm tmp.pcm -fs 12000 >> test_decoder_report.txt + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -Fs_API 16000 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%_16_kHz_out.pcm tmp.pcm -fs 16000 >> test_decoder_report.txt + +:: 8 kHz, 40 ms, 12 kbps, complexity 1 +SET PARAMS=8_kHz_40_ms_12_kbps +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + +:: 8 kHz, 20 ms, 20 kbps, 10% packet loss, FEC +SET PARAMS=8_kHz_20_ms_20_kbps_10_loss_FEC +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -loss 10 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + + +:: 12 kHz + +:: 12 kHz, 60 ms, 10 kbps, complexity 0 +SET PARAMS=12_kHz_60_ms_10_kbps +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -Fs_API 12000 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%_12_kHz_out.pcm tmp.pcm -fs 12000 >> test_decoder_report.txt + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -Fs_API 16000 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%_16_kHz_out.pcm tmp.pcm -fs 16000 >> test_decoder_report.txt + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -Fs_API 32000 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%_32_kHz_out.pcm tmp.pcm -fs 32000 >> test_decoder_report.txt + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -Fs_API 44100 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%_44100_Hz_out.pcm tmp.pcm -fs 44100 >> test_decoder_report.txt + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -Fs_API 48000 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%_48_kHz_out.pcm tmp.pcm -fs 48000 >> test_decoder_report.txt + +:: 12 kHz, 40 ms, 16 kbps, complexity 1 +SET PARAMS=12_kHz_40_ms_16_kbps +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + +:: 12 kHz, 20 ms, 24 kbps, 10% packet loss, FEC +SET PARAMS=12_kHz_20_ms_24_kbps_10_loss_FEC +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -loss 10 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + + +:: 16 kHz + +:: 16 kHz, 60 ms, 12 kbps, complexity 0 +SET PARAMS=16_kHz_60_ms_12_kbps +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -Fs_API 16000 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%_16_kHz_out.pcm tmp.pcm -fs 16000 >> test_decoder_report.txt + +:: 16 kHz, 40 ms, 20 kbps, complexity 1 +SET PARAMS=16_kHz_40_ms_20_kbps +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + +:: 16 kHz, 20 ms, 32 kbps, 10% packet loss, FEC +SET PARAMS=16_kHz_20_ms_32_kbps_10_loss_FEC +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -loss 10 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + + +:: 24 kHz + +:: 24 kHz, 60 ms, 16 kbps, complexity 0 +SET PARAMS=24_kHz_60_ms_16_kbps +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + +:: 24 kHz, 40 ms, 24 kbps, complexity 1 +SET PARAMS=24_kHz_40_ms_24_kbps +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + +:: 24 kHz, 20 ms, 40 kbps, 10% packet loss, FEC +SET PARAMS=24_kHz_20_ms_40_kbps_10_loss_FEC +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -loss 10 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + + +:: 32 kHz + +:: 32 kHz, 20 ms, 8 kbps, maxInternal 8kHz +SET PARAMS=32_kHz_max_8_kHz_20_ms_8_kbps + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -Fs_API 32000 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%_32_kHz_out.pcm tmp.pcm -fs 32000 >> test_decoder_report.txt + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -Fs_API 44100 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%_44100_Hz_out.pcm tmp.pcm -fs 44100 >> test_decoder_report.txt + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm -Fs_API 48000 +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%_48_kHz_out.pcm tmp.pcm -fs 48000 >> test_decoder_report.txt + + +:: 44100 Hz + +:: 44100 Hz, 20 ms, 40 kbps +SET PARAMS=44100_Hz_20_ms_7_kbps + +%DEC% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.pcm +%COMP% %OUTPUTPATH%testvector_output_%PARAMS%.pcm tmp.pcm >> test_decoder_report.txt + + +del tmp.pcm +move test_decoder_report.txt ./test_vectors/test_decoder_report.txt + +echo. +echo The results have been saved as test_decoder_report.txt +echo. + +pause diff --git a/libs/silk/test_vectors/test_decoder.sh b/libs/silk/test_vectors/test_decoder.sh new file mode 100644 index 0000000000..08e61fa15a --- /dev/null +++ b/libs/silk/test_vectors/test_decoder.sh @@ -0,0 +1,142 @@ +#!/bin/bash + +BITSTREAMPATH=./test_vectors/bitstream/ +OUTPUTPATH=./test_vectors/output/ +DEC=decoder +COMP=signalcompare + +cd .. + + +# 8 kHz + +# 8 kHz, 60 ms, 8 kbps, complexity 0 +PARAMS=8_kHz_60_ms_8_kbps +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm -fs 24000 > test_decoder_report.txt + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -Fs_API 8000 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}_8_kHz_out.pcm tmp.pcm -fs 8000 >> test_decoder_report.txt + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -Fs_API 12000 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}_12_kHz_out.pcm tmp.pcm -fs 12000 >> test_decoder_report.txt + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -Fs_API 16000 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}_16_kHz_out.pcm tmp.pcm -fs 16000 >> test_decoder_report.txt + +# 8 kHz, 40 ms, 12 kbps, complexity 1 +PARAMS=8_kHz_40_ms_12_kbps +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + +# 8 kHz, 20 ms, 20 kbps, 10% packet loss, FEC +PARAMS=8_kHz_20_ms_20_kbps_10_loss_FEC +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -loss 10 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + + +# 12 kHz + +# 12 kHz, 60 ms, 10 kbps, complexity 0 +PARAMS=12_kHz_60_ms_10_kbps +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -Fs_API 12000 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}_12_kHz_out.pcm tmp.pcm -fs 12000 >> test_decoder_report.txt + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -Fs_API 16000 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}_16_kHz_out.pcm tmp.pcm -fs 16000 >> test_decoder_report.txt + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -Fs_API 32000 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}_32_kHz_out.pcm tmp.pcm -fs 32000 >> test_decoder_report.txt + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -Fs_API 44100 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}_44100_Hz_out.pcm tmp.pcm -fs 44100 >> test_decoder_report.txt + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -Fs_API 48000 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}_48_kHz_out.pcm tmp.pcm -fs 48000 >> test_decoder_report.txt + +# 12 kHz, 40 ms, 16 kbps, complexity 1 +PARAMS=12_kHz_40_ms_16_kbps +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + +# 12 kHz, 20 ms, 24 kbps, 10% packet loss, FEC +PARAMS=12_kHz_20_ms_24_kbps_10_loss_FEC +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -loss 10 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + + +# 16 kHz + +# 16 kHz, 60 ms, 12 kbps, complexity 0 +PARAMS=16_kHz_60_ms_12_kbps +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -Fs_API 16000 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}_16_kHz_out.pcm tmp.pcm -fs 16000 >> test_decoder_report.txt + +# 16 kHz, 40 ms, 20 kbps, complexity 1 +PARAMS=16_kHz_40_ms_20_kbps +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + +# 16 kHz, 20 ms, 32 kbps, 10% packet loss, FEC +PARAMS=16_kHz_20_ms_32_kbps_10_loss_FEC +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -loss 10 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + + +# 24 kHz + +# 24 kHz, 60 ms, 16 kbps, complexity 0 +PARAMS=24_kHz_60_ms_16_kbps +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + +# 24 kHz, 40 ms, 24 kbps, complexity 1 +PARAMS=24_kHz_40_ms_24_kbps +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + +# 24 kHz, 20 ms, 40 kbps, 10% packet loss, FEC +PARAMS=24_kHz_20_ms_40_kbps_10_loss_FEC +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -loss 10 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + + +# 32 kHz + +# 32 kHz, 20 ms, 8 kbps, maxInternal 8kHz +PARAMS=32_kHz_max_8_kHz_20_ms_8_kbps + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -Fs_API 32000 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}_32_kHz_out.pcm tmp.pcm -fs 32000 >> test_decoder_report.txt + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -Fs_API 44100 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}_44100_Hz_out.pcm tmp.pcm -fs 44100 >> test_decoder_report.txt + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm -Fs_API 48000 +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}_48_kHz_out.pcm tmp.pcm -fs 48000 >> test_decoder_report.txt + + +# 44100 Hz + +# 44100 Hz, 20 ms, 40 kbps +PARAMS=44100_Hz_20_ms_7_kbps + +./${DEC} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.pcm +./${COMP} ${OUTPUTPATH}testvector_output_${PARAMS}.pcm tmp.pcm >> test_decoder_report.txt + + +rm tmp.pcm +mv test_decoder_report.txt ./test_vectors/test_decoder_report.txt + +echo "" +echo "The results have been saved as test_decoder_report.txt" +echo "" \ No newline at end of file diff --git a/libs/silk/test_vectors/test_encoder.bat b/libs/silk/test_vectors/test_encoder.bat new file mode 100644 index 0000000000..27996966ba --- /dev/null +++ b/libs/silk/test_vectors/test_encoder.bat @@ -0,0 +1,111 @@ +@echo off + +SET INPUTPATH=./test_vectors/input/ +SET BITSTREAMPATH=./test_vectors/bitstream/ +SET ENC=Encoder.exe +SET COMP=SignalCompare.exe + +cd .. + +:: 8 kHz +SET INPUTFILE=testvector_input_8_kHz.pcm + +:: 8 kHz, 60 ms, 8 kbps, complexity 0 +SET PARAMS=8_kHz_60_ms_8_kbps +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 8000 -packetlength 60 -rate 8000 -complexity 0 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff > test_encoder_report.txt + +:: 8 kHz, 40 ms, 12 kbps, complexity 1 +SET PARAMS=8_kHz_40_ms_12_kbps +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 8000 -packetlength 40 -rate 12000 -complexity 1 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + +:: 8 kHz, 20 ms, 20 kbps, 10% packet loss, FEC +SET PARAMS=8_kHz_20_ms_20_kbps_10_loss_FEC +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 8000 -packetlength 20 -rate 20000 -loss 10 -inbandFEC 1 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + + +:: 12 kHz +SET INPUTFILE=testvector_input_12_kHz.pcm + +:: 12 kHz, 60 ms, 10 kbps, complexity 0 +SET PARAMS=12_kHz_60_ms_10_kbps +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 12000 -packetlength 60 -rate 10000 -complexity 0 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + +:: 12 kHz, 40 ms, 16 kbps, complexity 1 +SET PARAMS=12_kHz_40_ms_16_kbps +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 12000 -packetlength 40 -rate 16000 -complexity 1 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + +:: 12 kHz, 20 ms, 24 kbps, 10% packet loss, FEC +SET PARAMS=12_kHz_20_ms_24_kbps_10_loss_FEC +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 12000 -packetlength 20 -rate 24000 -loss 10 -inbandFEC 1 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + + +:: 16 kHz +SET INPUTFILE=testvector_input_16_kHz.pcm + +:: 16 kHz, 60 ms, 12 kbps, complexity 0 +SET PARAMS=16_kHz_60_ms_12_kbps +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 16000 -packetlength 60 -rate 12000 -complexity 0 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + +:: 16 kHz, 40 ms, 20 kbps, complexity 1 +SET PARAMS=16_kHz_40_ms_20_kbps +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 16000 -packetlength 40 -rate 20000 -complexity 1 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + +:: 16 kHz, 20 ms, 32 kbps, 10% packet loss, FEC +SET PARAMS=16_kHz_20_ms_32_kbps_10_loss_FEC +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 16000 -packetlength 20 -rate 32000 -loss 10 -inbandFEC 1 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + + +:: 24 kHz +SET INPUTFILE=testvector_input_24_kHz.pcm + +:: 24 kHz, 60 ms, 16 kbps, complexity 0 +SET PARAMS=24_kHz_60_ms_16_kbps +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 24000 -packetlength 60 -rate 16000 -complexity 0 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + +:: 24 kHz, 40 ms, 24 kbps, complexity 1 +SET PARAMS=24_kHz_40_ms_24_kbps +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 24000 -packetlength 40 -rate 24000 -complexity 1 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + +:: 24 kHz, 20 ms, 40 kbps, 10% packet loss, FEC +SET PARAMS=24_kHz_20_ms_40_kbps_10_loss_FEC +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 24000 -packetlength 20 -rate 40000 -loss 10 -inbandFEC 1 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + + +:: 32 kHz +SET INPUTFILE=testvector_input_32_kHz.pcm + +:: 32 kHz, 20 ms, 8 kbps, maxInternal 8kHz +SET PARAMS=32_kHz_max_8_kHz_20_ms_8_kbps +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 32000 -Fs_maxInternal 8000 -packetlength 20 -rate 8000 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + + +:: 44100 Hz +SET INPUTFILE=testvector_input_44100_Hz.pcm + +:: 44100 Hz, 20 ms, 40 kbps +SET PARAMS=44100_Hz_20_ms_7_kbps +%ENC% %INPUTPATH%%INPUTFILE% tmp.bit -Fs_API 44100 -packetlength 20 -rate 7000 +%COMP% %BITSTREAMPATH%payload_%PARAMS%.bit tmp.bit -diff >> test_encoder_report.txt + + +del tmp.bit +move test_encoder_report.txt ./test_vectors/test_encoder_report.txt + +echo. +echo The results have been saved as test_encoder_report.txt +echo. + +pause diff --git a/libs/silk/test_vectors/test_encoder.sh b/libs/silk/test_vectors/test_encoder.sh new file mode 100644 index 0000000000..b25e3a50c4 --- /dev/null +++ b/libs/silk/test_vectors/test_encoder.sh @@ -0,0 +1,109 @@ +#!/bin/bash + +INPUTPATH=./test_vectors/input/ +BITSTREAMPATH=./test_vectors/bitstream/ +ENC=encoder +COMP=signalcompare + +cd .. + +# 8 kHz +INPUTFILE=testvector_input_8_kHz.pcm + +# 8 kHz, 60 ms, 8 kbps, complexity 0 +PARAMS=8_kHz_60_ms_8_kbps +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 8000 -packetlength 60 -rate 8000 -complexity 0 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff > test_encoder_report.txt + +# 8 kHz, 40 ms, 12 kbps, complexity 1 +PARAMS=8_kHz_40_ms_12_kbps +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 8000 -packetlength 40 -rate 12000 -complexity 1 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + +# 8 kHz, 20 ms, 20 kbps, 10% packet loss, FEC +PARAMS=8_kHz_20_ms_20_kbps_10_loss_FEC +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 8000 -packetlength 20 -rate 20000 -loss 10 -inbandFEC 1 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + + +# 12 kHz +INPUTFILE=testvector_input_12_kHz.pcm + +# 12 kHz, 60 ms, 10 kbps, complexity 0 +PARAMS=12_kHz_60_ms_10_kbps +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 12000 -packetlength 60 -rate 10000 -complexity 0 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + +# 12 kHz, 40 ms, 16 kbps, complexity 1 +PARAMS=12_kHz_40_ms_16_kbps +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 12000 -packetlength 40 -rate 16000 -complexity 1 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + +# 12 kHz, 20 ms, 24 kbps, 10% packet loss, FEC +PARAMS=12_kHz_20_ms_24_kbps_10_loss_FEC +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 12000 -packetlength 20 -rate 24000 -loss 10 -inbandFEC 1 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + + +# 16 kHz +INPUTFILE=testvector_input_16_kHz.pcm + +# 16 kHz, 60 ms, 12 kbps, complexity 0 +PARAMS=16_kHz_60_ms_12_kbps +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 16000 -packetlength 60 -rate 12000 -complexity 0 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + +# 16 kHz, 40 ms, 20 kbps, complexity 1 +PARAMS=16_kHz_40_ms_20_kbps +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 16000 -packetlength 40 -rate 20000 -complexity 1 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + +# 16 kHz, 20 ms, 32 kbps, 10% packet loss, FEC +PARAMS=16_kHz_20_ms_32_kbps_10_loss_FEC +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 16000 -packetlength 20 -rate 32000 -loss 10 -inbandFEC 1 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + + +# 24 kHz +INPUTFILE=testvector_input_24_kHz.pcm + +# 24 kHz, 60 ms, 16 kbps, complexity 0 +PARAMS=24_kHz_60_ms_16_kbps +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 24000 -packetlength 60 -rate 16000 -complexity 0 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + +# 24 kHz, 40 ms, 24 kbps, complexity 1 +PARAMS=24_kHz_40_ms_24_kbps +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 24000 -packetlength 40 -rate 24000 -complexity 1 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + +# 24 kHz, 20 ms, 40 kbps, 10% packet loss, FEC +PARAMS=24_kHz_20_ms_40_kbps_10_loss_FEC +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 24000 -packetlength 20 -rate 40000 -loss 10 -inbandFEC 1 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + + +# 32 kHz +INPUTFILE=testvector_input_32_kHz.pcm + +# 32 kHz, 20 ms, 8 kbps, maxInternal 8kHz +PARAMS=32_kHz_max_8_kHz_20_ms_8_kbps +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 32000 -Fs_maxInternal 8000 -packetlength 20 -rate 8000 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + + +# 44100 Hz +INPUTFILE=testvector_input_44100_Hz.pcm + +# 44100 Hz, 20 ms, 40 kbps +PARAMS=44100_Hz_20_ms_7_kbps +./${ENC} ${INPUTPATH}${INPUTFILE} tmp.bit -Fs_API 44100 -packetlength 20 -rate 7000 +./${COMP} ${BITSTREAMPATH}payload_${PARAMS}.bit tmp.bit -diff >> test_encoder_report.txt + + +rm tmp.bit +mv test_encoder_report.txt ./test_vectors/test_encoder_report.txt + +echo "" +echo "The results have been saved as test_encoder_report.txt" +echo "" \ No newline at end of file diff --git a/src/mod/codecs/mod_silk/mod_silk.c b/src/mod/codecs/mod_silk/mod_silk.c index 934c9ebe32..7e2ba0afd3 100644 --- a/src/mod/codecs/mod_silk/mod_silk.c +++ b/src/mod/codecs/mod_silk/mod_silk.c @@ -192,7 +192,9 @@ static switch_status_t switch_silk_init(switch_codec_t *codec, return SWITCH_STATUS_FALSE; } - context->encoder_object.sampleRate = codec->implementation->actual_samples_per_second; + + context->encoder_object.API_sampleRate = codec->implementation->actual_samples_per_second; + context->encoder_object.maxInternalSampleRate = codec->implementation->actual_samples_per_second; context->encoder_object.packetSize = codec->implementation->samples_per_packet; context->encoder_object.useInBandFEC = silk_codec_settings.useinbandfec; context->encoder_object.complexity = 0; @@ -210,7 +212,7 @@ static switch_status_t switch_silk_init(switch_codec_t *codec, if (SKP_Silk_SDK_InitDecoder(context->dec_state)) { return SWITCH_STATUS_FALSE; } - context->decoder_object.sampleRate = codec->implementation->actual_samples_per_second; + context->decoder_object.API_sampleRate = codec->implementation->actual_samples_per_second; } codec->private_info = context; @@ -241,22 +243,22 @@ void printSilkError(SKP_int16 ret){ case SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT: message = "Allocated payload buffer too short"; break; - case SKP_SILK_ENC_WRONG_LOSS_RATE: + case SKP_SILK_ENC_INVALID_LOSS_RATE: message = " Loss rate not between 0 and 100 % "; break; - case SKP_SILK_ENC_WRONG_COMPLEXITY_SETTING: + case SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING: message = "Complexity setting not valid, use 0 ,1 or 2"; break; - case SKP_SILK_ENC_WRONG_INBAND_FEC_SETTING: + case SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING: message = "Inband FEC setting not valid, use 0 or 1 "; break; - case SKP_SILK_ENC_WRONG_DTX_SETTING: + case SKP_SILK_ENC_INVALID_DTX_SETTING: message = "DTX setting not valid, use 0 or 1"; break; case SKP_SILK_ENC_INTERNAL_ERROR: message = "Internal Encoder Error "; break; - case SKP_SILK_DEC_WRONG_SAMPLING_FREQUENCY: + case SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY: message = "Output sampling frequency lower than internal decoded sampling frequency"; break; case SKP_SILK_DEC_PAYLOAD_TOO_LARGE: