From b57996eeb844f747392a0c6f372453764d2b87c0 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Fri, 29 Apr 2011 15:27:43 -0400 Subject: Moving the SILK fixed-point and float files to silk/fixed and silk/float, respectively --- silk/SKP_Silk_LPC_analysis_filter_FLP.c | 279 -------------- silk/SKP_Silk_LTP_analysis_filter_FIX.c | 81 ---- silk/SKP_Silk_LTP_analysis_filter_FLP.c | 71 ---- silk/SKP_Silk_LTP_scale_ctrl_FIX.c | 52 --- silk/SKP_Silk_LTP_scale_ctrl_FLP.c | 52 --- silk/SKP_Silk_apply_sine_window_FLP.c | 77 ---- silk/SKP_Silk_corrMatrix_FIX.c | 152 -------- silk/SKP_Silk_corrMatrix_FLP.c | 89 ----- silk/SKP_Silk_encode_frame_FIX.c | 301 --------------- silk/SKP_Silk_encode_frame_FLP.c | 277 -------------- silk/SKP_Silk_find_LPC_FIX.c | 157 -------- silk/SKP_Silk_find_LPC_FLP.c | 109 ------ silk/SKP_Silk_find_LTP_FIX.c | 241 ------------ silk/SKP_Silk_find_LTP_FLP.c | 128 ------- silk/SKP_Silk_find_pitch_lags_FIX.c | 133 ------- silk/SKP_Silk_find_pitch_lags_FLP.c | 127 ------- silk/SKP_Silk_find_pred_coefs_FIX.c | 127 ------- silk/SKP_Silk_find_pred_coefs_FLP.c | 114 ------ silk/SKP_Silk_noise_shape_analysis_FIX.c | 433 ---------------------- silk/SKP_Silk_noise_shape_analysis_FLP.c | 359 ------------------ silk/SKP_Silk_prefilter_FIX.c | 201 ---------- silk/SKP_Silk_prefilter_FLP.c | 202 ---------- silk/SKP_Silk_process_gains_FIX.c | 108 ------ silk/SKP_Silk_process_gains_FLP.c | 94 ----- silk/SKP_Silk_regularize_correlations_FIX.c | 43 --- silk/SKP_Silk_regularize_correlations_FLP.c | 43 --- silk/SKP_Silk_residual_energy16_FIX.c | 99 ----- silk/SKP_Silk_residual_energy_FIX.c | 87 ----- silk/SKP_Silk_residual_energy_FLP.c | 113 ------ silk/SKP_Silk_solve_LS_FIX.c | 241 ------------ silk/SKP_Silk_solve_LS_FLP.c | 203 ---------- silk/SKP_Silk_warped_autocorrelation_FIX.c | 84 ----- silk/SKP_Silk_warped_autocorrelation_FLP.c | 69 ---- silk/SKP_Silk_wrappers_FLP.c | 194 ---------- silk/fixed/SKP_Silk_LTP_analysis_filter_FIX.c | 81 ++++ silk/fixed/SKP_Silk_LTP_scale_ctrl_FIX.c | 52 +++ silk/fixed/SKP_Silk_corrMatrix_FIX.c | 152 ++++++++ silk/fixed/SKP_Silk_encode_frame_FIX.c | 301 +++++++++++++++ silk/fixed/SKP_Silk_find_LPC_FIX.c | 157 ++++++++ silk/fixed/SKP_Silk_find_LTP_FIX.c | 241 ++++++++++++ silk/fixed/SKP_Silk_find_pitch_lags_FIX.c | 133 +++++++ silk/fixed/SKP_Silk_find_pred_coefs_FIX.c | 127 +++++++ silk/fixed/SKP_Silk_noise_shape_analysis_FIX.c | 433 ++++++++++++++++++++++ silk/fixed/SKP_Silk_prefilter_FIX.c | 201 ++++++++++ silk/fixed/SKP_Silk_process_gains_FIX.c | 108 ++++++ silk/fixed/SKP_Silk_regularize_correlations_FIX.c | 43 +++ silk/fixed/SKP_Silk_residual_energy16_FIX.c | 99 +++++ silk/fixed/SKP_Silk_residual_energy_FIX.c | 87 +++++ silk/fixed/SKP_Silk_solve_LS_FIX.c | 241 ++++++++++++ silk/fixed/SKP_Silk_warped_autocorrelation_FIX.c | 84 +++++ silk/float/SKP_Silk_LPC_analysis_filter_FLP.c | 279 ++++++++++++++ silk/float/SKP_Silk_LTP_analysis_filter_FLP.c | 71 ++++ silk/float/SKP_Silk_LTP_scale_ctrl_FLP.c | 52 +++ silk/float/SKP_Silk_apply_sine_window_FLP.c | 77 ++++ silk/float/SKP_Silk_corrMatrix_FLP.c | 89 +++++ silk/float/SKP_Silk_encode_frame_FLP.c | 277 ++++++++++++++ silk/float/SKP_Silk_find_LPC_FLP.c | 109 ++++++ silk/float/SKP_Silk_find_LTP_FLP.c | 128 +++++++ silk/float/SKP_Silk_find_pitch_lags_FLP.c | 127 +++++++ silk/float/SKP_Silk_find_pred_coefs_FLP.c | 114 ++++++ silk/float/SKP_Silk_noise_shape_analysis_FLP.c | 359 ++++++++++++++++++ silk/float/SKP_Silk_prefilter_FLP.c | 202 ++++++++++ silk/float/SKP_Silk_process_gains_FLP.c | 94 +++++ silk/float/SKP_Silk_regularize_correlations_FLP.c | 43 +++ silk/float/SKP_Silk_residual_energy_FLP.c | 113 ++++++ silk/float/SKP_Silk_solve_LS_FLP.c | 203 ++++++++++ silk/float/SKP_Silk_warped_autocorrelation_FLP.c | 69 ++++ silk/float/SKP_Silk_wrappers_FLP.c | 194 ++++++++++ silk_sources.mk | 68 ++-- 69 files changed, 5174 insertions(+), 5174 deletions(-) delete mode 100644 silk/SKP_Silk_LPC_analysis_filter_FLP.c delete mode 100644 silk/SKP_Silk_LTP_analysis_filter_FIX.c delete mode 100644 silk/SKP_Silk_LTP_analysis_filter_FLP.c delete mode 100644 silk/SKP_Silk_LTP_scale_ctrl_FIX.c delete mode 100644 silk/SKP_Silk_LTP_scale_ctrl_FLP.c delete mode 100644 silk/SKP_Silk_apply_sine_window_FLP.c delete mode 100644 silk/SKP_Silk_corrMatrix_FIX.c delete mode 100644 silk/SKP_Silk_corrMatrix_FLP.c delete mode 100644 silk/SKP_Silk_encode_frame_FIX.c delete mode 100644 silk/SKP_Silk_encode_frame_FLP.c delete mode 100644 silk/SKP_Silk_find_LPC_FIX.c delete mode 100644 silk/SKP_Silk_find_LPC_FLP.c delete mode 100644 silk/SKP_Silk_find_LTP_FIX.c delete mode 100644 silk/SKP_Silk_find_LTP_FLP.c delete mode 100644 silk/SKP_Silk_find_pitch_lags_FIX.c delete mode 100644 silk/SKP_Silk_find_pitch_lags_FLP.c delete mode 100644 silk/SKP_Silk_find_pred_coefs_FIX.c delete mode 100644 silk/SKP_Silk_find_pred_coefs_FLP.c delete mode 100644 silk/SKP_Silk_noise_shape_analysis_FIX.c delete mode 100644 silk/SKP_Silk_noise_shape_analysis_FLP.c delete mode 100644 silk/SKP_Silk_prefilter_FIX.c delete mode 100644 silk/SKP_Silk_prefilter_FLP.c delete mode 100644 silk/SKP_Silk_process_gains_FIX.c delete mode 100644 silk/SKP_Silk_process_gains_FLP.c delete mode 100644 silk/SKP_Silk_regularize_correlations_FIX.c delete mode 100644 silk/SKP_Silk_regularize_correlations_FLP.c delete mode 100644 silk/SKP_Silk_residual_energy16_FIX.c delete mode 100644 silk/SKP_Silk_residual_energy_FIX.c delete mode 100644 silk/SKP_Silk_residual_energy_FLP.c delete mode 100644 silk/SKP_Silk_solve_LS_FIX.c delete mode 100644 silk/SKP_Silk_solve_LS_FLP.c delete mode 100644 silk/SKP_Silk_warped_autocorrelation_FIX.c delete mode 100644 silk/SKP_Silk_warped_autocorrelation_FLP.c delete mode 100644 silk/SKP_Silk_wrappers_FLP.c create mode 100644 silk/fixed/SKP_Silk_LTP_analysis_filter_FIX.c create mode 100644 silk/fixed/SKP_Silk_LTP_scale_ctrl_FIX.c create mode 100644 silk/fixed/SKP_Silk_corrMatrix_FIX.c create mode 100644 silk/fixed/SKP_Silk_encode_frame_FIX.c create mode 100644 silk/fixed/SKP_Silk_find_LPC_FIX.c create mode 100644 silk/fixed/SKP_Silk_find_LTP_FIX.c create mode 100644 silk/fixed/SKP_Silk_find_pitch_lags_FIX.c create mode 100644 silk/fixed/SKP_Silk_find_pred_coefs_FIX.c create mode 100644 silk/fixed/SKP_Silk_noise_shape_analysis_FIX.c create mode 100644 silk/fixed/SKP_Silk_prefilter_FIX.c create mode 100644 silk/fixed/SKP_Silk_process_gains_FIX.c create mode 100644 silk/fixed/SKP_Silk_regularize_correlations_FIX.c create mode 100644 silk/fixed/SKP_Silk_residual_energy16_FIX.c create mode 100644 silk/fixed/SKP_Silk_residual_energy_FIX.c create mode 100644 silk/fixed/SKP_Silk_solve_LS_FIX.c create mode 100644 silk/fixed/SKP_Silk_warped_autocorrelation_FIX.c create mode 100644 silk/float/SKP_Silk_LPC_analysis_filter_FLP.c create mode 100644 silk/float/SKP_Silk_LTP_analysis_filter_FLP.c create mode 100644 silk/float/SKP_Silk_LTP_scale_ctrl_FLP.c create mode 100644 silk/float/SKP_Silk_apply_sine_window_FLP.c create mode 100644 silk/float/SKP_Silk_corrMatrix_FLP.c create mode 100644 silk/float/SKP_Silk_encode_frame_FLP.c create mode 100644 silk/float/SKP_Silk_find_LPC_FLP.c create mode 100644 silk/float/SKP_Silk_find_LTP_FLP.c create mode 100644 silk/float/SKP_Silk_find_pitch_lags_FLP.c create mode 100644 silk/float/SKP_Silk_find_pred_coefs_FLP.c create mode 100644 silk/float/SKP_Silk_noise_shape_analysis_FLP.c create mode 100644 silk/float/SKP_Silk_prefilter_FLP.c create mode 100644 silk/float/SKP_Silk_process_gains_FLP.c create mode 100644 silk/float/SKP_Silk_regularize_correlations_FLP.c create mode 100644 silk/float/SKP_Silk_residual_energy_FLP.c create mode 100644 silk/float/SKP_Silk_solve_LS_FLP.c create mode 100644 silk/float/SKP_Silk_warped_autocorrelation_FLP.c create mode 100644 silk/float/SKP_Silk_wrappers_FLP.c diff --git a/silk/SKP_Silk_LPC_analysis_filter_FLP.c b/silk/SKP_Silk_LPC_analysis_filter_FLP.c deleted file mode 100644 index b340f559..00000000 --- a/silk/SKP_Silk_LPC_analysis_filter_FLP.c +++ /dev/null @@ -1,279 +0,0 @@ -/*********************************************************************** -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 -#include "SKP_Silk_main_FLP.h" - -/*******************************************/ -/* LPC analysis filter */ -/* NB! State is kept internally and the */ -/* filter always starts with zero state */ -/* first Order output samples are not set */ -/*******************************************/ - -/* 16th order LPC analysis filter, does not write first 16 samples */ -void SKP_Silk_LPC_analysis_filter16_FLP( - SKP_float r_LPC[], /* O LPC residual signal */ - const SKP_float PredCoef[], /* I LPC coefficients */ - const SKP_float s[], /* I Input signal */ - const SKP_int length /* I Length of input signal */ -) -{ - SKP_int ix; - SKP_float LPC_pred; - const SKP_float *s_ptr; - - for ( ix = 16; ix < length; ix++) { - s_ptr = &s[ix - 1]; - - /* short-term prediction */ - LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + - s_ptr[ -1 ] * PredCoef[ 1 ] + - s_ptr[ -2 ] * PredCoef[ 2 ] + - s_ptr[ -3 ] * PredCoef[ 3 ] + - s_ptr[ -4 ] * PredCoef[ 4 ] + - s_ptr[ -5 ] * PredCoef[ 5 ] + - s_ptr[ -6 ] * PredCoef[ 6 ] + - s_ptr[ -7 ] * PredCoef[ 7 ] + - s_ptr[ -8 ] * PredCoef[ 8 ] + - s_ptr[ -9 ] * PredCoef[ 9 ] + - s_ptr[ -10 ] * PredCoef[ 10 ] + - s_ptr[ -11 ] * PredCoef[ 11 ] + - s_ptr[ -12 ] * PredCoef[ 12 ] + - s_ptr[ -13 ] * PredCoef[ 13 ] + - s_ptr[ -14 ] * PredCoef[ 14 ] + - s_ptr[ -15 ] * PredCoef[ 15 ]; - - /* prediction error */ - r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; - } -} - -/* 14th order LPC analysis filter, does not write first 14 samples */ -void SKP_Silk_LPC_analysis_filter14_FLP( - SKP_float r_LPC[], /* O LPC residual signal */ - const SKP_float PredCoef[], /* I LPC coefficients */ - const SKP_float s[], /* I Input signal */ - const SKP_int length /* I Length of input signal */ -) -{ - SKP_int ix; - SKP_float LPC_pred; - const SKP_float *s_ptr; - - for ( ix = 14; ix < length; ix++) { - s_ptr = &s[ix - 1]; - - /* short-term prediction */ - LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + - s_ptr[ -1 ] * PredCoef[ 1 ] + - s_ptr[ -2 ] * PredCoef[ 2 ] + - s_ptr[ -3 ] * PredCoef[ 3 ] + - s_ptr[ -4 ] * PredCoef[ 4 ] + - s_ptr[ -5 ] * PredCoef[ 5 ] + - s_ptr[ -6 ] * PredCoef[ 6 ] + - s_ptr[ -7 ] * PredCoef[ 7 ] + - s_ptr[ -8 ] * PredCoef[ 8 ] + - s_ptr[ -9 ] * PredCoef[ 9 ] + - s_ptr[ -10 ] * PredCoef[ 10 ] + - s_ptr[ -11 ] * PredCoef[ 11 ] + - s_ptr[ -12 ] * PredCoef[ 12 ] + - s_ptr[ -13 ] * PredCoef[ 13 ]; - - /* prediction error */ - r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; - } -} - -/* 12th order LPC analysis filter, does not write first 12 samples */ -void SKP_Silk_LPC_analysis_filter12_FLP( - SKP_float r_LPC[], /* O LPC residual signal */ - const SKP_float PredCoef[], /* I LPC coefficients */ - const SKP_float s[], /* I Input signal */ - const SKP_int length /* I Length of input signal */ -) -{ - SKP_int ix; - SKP_float LPC_pred; - const SKP_float *s_ptr; - - for ( ix = 12; ix < length; ix++) { - s_ptr = &s[ix - 1]; - - /* short-term prediction */ - LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + - s_ptr[ -1 ] * PredCoef[ 1 ] + - s_ptr[ -2 ] * PredCoef[ 2 ] + - s_ptr[ -3 ] * PredCoef[ 3 ] + - s_ptr[ -4 ] * PredCoef[ 4 ] + - s_ptr[ -5 ] * PredCoef[ 5 ] + - s_ptr[ -6 ] * PredCoef[ 6 ] + - s_ptr[ -7 ] * PredCoef[ 7 ] + - s_ptr[ -8 ] * PredCoef[ 8 ] + - s_ptr[ -9 ] * PredCoef[ 9 ] + - s_ptr[ -10 ] * PredCoef[ 10 ] + - s_ptr[ -11 ] * PredCoef[ 11 ]; - - /* prediction error */ - r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; - } -} - -/* 10th order LPC analysis filter, does not write first 10 samples */ -void SKP_Silk_LPC_analysis_filter10_FLP( - SKP_float r_LPC[], /* O LPC residual signal */ - const SKP_float PredCoef[], /* I LPC coefficients */ - const SKP_float s[], /* I Input signal */ - const SKP_int length /* I Length of input signal */ -) -{ - SKP_int ix; - SKP_float LPC_pred; - const SKP_float *s_ptr; - - for ( ix = 10; ix < length; ix++) { - s_ptr = &s[ix - 1]; - - /* short-term prediction */ - LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + - s_ptr[ -1 ] * PredCoef[ 1 ] + - s_ptr[ -2 ] * PredCoef[ 2 ] + - s_ptr[ -3 ] * PredCoef[ 3 ] + - s_ptr[ -4 ] * PredCoef[ 4 ] + - s_ptr[ -5 ] * PredCoef[ 5 ] + - s_ptr[ -6 ] * PredCoef[ 6 ] + - s_ptr[ -7 ] * PredCoef[ 7 ] + - s_ptr[ -8 ] * PredCoef[ 8 ] + - s_ptr[ -9 ] * PredCoef[ 9 ]; - - /* prediction error */ - r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; - } -} - -/* 8th order LPC analysis filter, does not write first 8 samples */ -void SKP_Silk_LPC_analysis_filter8_FLP( - SKP_float r_LPC[], /* O LPC residual signal */ - const SKP_float PredCoef[], /* I LPC coefficients */ - const SKP_float s[], /* I Input signal */ - const SKP_int length /* I Length of input signal */ -) -{ - SKP_int ix; - SKP_float LPC_pred; - const SKP_float *s_ptr; - - for ( ix = 8; ix < length; ix++) { - s_ptr = &s[ix - 1]; - - /* short-term prediction */ - LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + - s_ptr[ -1 ] * PredCoef[ 1 ] + - s_ptr[ -2 ] * PredCoef[ 2 ] + - s_ptr[ -3 ] * PredCoef[ 3 ] + - s_ptr[ -4 ] * PredCoef[ 4 ] + - s_ptr[ -5 ] * PredCoef[ 5 ] + - s_ptr[ -6 ] * PredCoef[ 6 ] + - s_ptr[ -7 ] * PredCoef[ 7 ]; - - /* prediction error */ - r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; - } -} - -/* 6th order LPC analysis filter, does not write first 6 samples */ -void SKP_Silk_LPC_analysis_filter6_FLP( - SKP_float r_LPC[], /* O LPC residual signal */ - const SKP_float PredCoef[], /* I LPC coefficients */ - const SKP_float s[], /* I Input signal */ - const SKP_int length /* I Length of input signal */ -) -{ - SKP_int ix; - SKP_float LPC_pred; - const SKP_float *s_ptr; - - for ( ix = 6; ix < length; ix++) { - s_ptr = &s[ix - 1]; - - /* short-term prediction */ - LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + - s_ptr[ -1 ] * PredCoef[ 1 ] + - s_ptr[ -2 ] * PredCoef[ 2 ] + - s_ptr[ -3 ] * PredCoef[ 3 ] + - s_ptr[ -4 ] * PredCoef[ 4 ] + - s_ptr[ -5 ] * PredCoef[ 5 ]; - - /* prediction error */ - r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; - } -} - -void SKP_Silk_LPC_analysis_filter_FLP( - SKP_float r_LPC[], /* O LPC residual signal */ - const SKP_float PredCoef[], /* I LPC coefficients */ - const SKP_float s[], /* I Input signal */ - const SKP_int length, /* I Length of input signal */ - const SKP_int Order /* I LPC order */ -) -{ - SKP_assert( Order <= length ); - - switch( Order ) { - case 6: - SKP_Silk_LPC_analysis_filter6_FLP( r_LPC, PredCoef, s, length ); - break; - - case 8: - SKP_Silk_LPC_analysis_filter8_FLP( r_LPC, PredCoef, s, length ); - break; - - case 10: - SKP_Silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, length ); - break; - - case 12: - SKP_Silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, length ); - break; - - case 14: - SKP_Silk_LPC_analysis_filter14_FLP( r_LPC, PredCoef, s, length ); - break; - - case 16: - SKP_Silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, length ); - break; - - default: - SKP_assert( 0 ); - break; - } - - /* Set first LPC Order samples to zero instead of undefined */ - SKP_memset( r_LPC, 0, Order * sizeof( SKP_float ) ); -} - diff --git a/silk/SKP_Silk_LTP_analysis_filter_FIX.c b/silk/SKP_Silk_LTP_analysis_filter_FIX.c deleted file mode 100644 index 4e21d65e..00000000 --- a/silk/SKP_Silk_LTP_analysis_filter_FIX.c +++ /dev/null @@ -1,81 +0,0 @@ -/*********************************************************************** -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" - -void SKP_Silk_LTP_analysis_filter_FIX( - SKP_int16 *LTP_res, /* O: LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */ - const SKP_int16 *x, /* I: Pointer to input signal with at least max( pitchL ) preceeding samples */ - const SKP_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I: LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */ - const SKP_int pitchL[ MAX_NB_SUBFR ], /* I: Pitch lag, one for each subframe */ - const SKP_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I: Inverse quantization gains, one for each subframe */ - const SKP_int subfr_length, /* I: Length of each subframe */ - const SKP_int nb_subfr, /* I: Number of subframes */ - const SKP_int pre_length /* I: Length of the preceeding samples starting at &x[0] for each subframe */ -) -{ - const SKP_int16 *x_ptr, *x_lag_ptr; - SKP_int16 Btmp_Q14[ LTP_ORDER ]; - SKP_int16 *LTP_res_ptr; - SKP_int k, i, j; - SKP_int32 LTP_est; - - x_ptr = x; - LTP_res_ptr = LTP_res; - for( k = 0; k < nb_subfr; k++ ) { - - x_lag_ptr = x_ptr - pitchL[ k ]; - for( i = 0; i < LTP_ORDER; i++ ) { - Btmp_Q14[ i ] = LTPCoef_Q14[ k * LTP_ORDER + i ]; - } - - /* LTP analysis FIR filter */ - for( i = 0; i < subfr_length + pre_length; i++ ) { - LTP_res_ptr[ i ] = x_ptr[ i ]; - - /* Long-term prediction */ - LTP_est = SKP_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] ); - for( j = 1; j < LTP_ORDER; j++ ) { - LTP_est = SKP_SMLABB_ovflw( LTP_est, x_lag_ptr[ LTP_ORDER / 2 - j ], Btmp_Q14[ j ] ); - } - LTP_est = SKP_RSHIFT_ROUND( LTP_est, 14 ); // round and -> Q0 - - /* Subtract long-term prediction */ - LTP_res_ptr[ i ] = ( SKP_int16 )SKP_SAT16( ( SKP_int32 )x_ptr[ i ] - LTP_est ); - - /* Scale residual */ - LTP_res_ptr[ i ] = SKP_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] ); - - x_lag_ptr++; - } - - /* Update pointers */ - LTP_res_ptr += subfr_length + pre_length; - x_ptr += subfr_length; - } -} - diff --git a/silk/SKP_Silk_LTP_analysis_filter_FLP.c b/silk/SKP_Silk_LTP_analysis_filter_FLP.c deleted file mode 100644 index b27b08d4..00000000 --- a/silk/SKP_Silk_LTP_analysis_filter_FLP.c +++ /dev/null @@ -1,71 +0,0 @@ -/*********************************************************************** -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_FLP.h" - -void SKP_Silk_LTP_analysis_filter_FLP( - SKP_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */ - const SKP_float *x, /* I Input signal, with preceeding samples */ - const SKP_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */ - const SKP_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const SKP_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */ - const SKP_int subfr_length, /* I Length of each subframe */ - const SKP_int nb_subfr, /* I number of subframes */ - const SKP_int pre_length /* I Preceeding samples for each subframe */ -) -{ - const SKP_float *x_ptr, *x_lag_ptr; - SKP_float Btmp[ LTP_ORDER ]; - SKP_float *LTP_res_ptr; - SKP_float inv_gain; - SKP_int k, i, j; - - x_ptr = x; - LTP_res_ptr = LTP_res; - for( k = 0; k < nb_subfr; k++ ) { - x_lag_ptr = x_ptr - pitchL[ k ]; - inv_gain = invGains[ k ]; - for( i = 0; i < LTP_ORDER; i++ ) { - Btmp[ i ] = B[ k * LTP_ORDER + i ]; - } - - /* LTP analysis FIR filter */ - for( i = 0; i < subfr_length + pre_length; i++ ) { - LTP_res_ptr[ i ] = x_ptr[ i ]; - /* Subtract long-term prediction */ - for( j = 0; j < LTP_ORDER; j++ ) { - LTP_res_ptr[ i ] -= Btmp[ j ] * x_lag_ptr[ LTP_ORDER / 2 - j ]; - } - LTP_res_ptr[ i ] *= inv_gain; - x_lag_ptr++; - } - - /* Update pointers */ - LTP_res_ptr += subfr_length + pre_length; - x_ptr += subfr_length; - } -} diff --git a/silk/SKP_Silk_LTP_scale_ctrl_FIX.c b/silk/SKP_Silk_LTP_scale_ctrl_FIX.c deleted file mode 100644 index 08516050..00000000 --- a/silk/SKP_Silk_LTP_scale_ctrl_FIX.c +++ /dev/null @@ -1,52 +0,0 @@ -/*********************************************************************** -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" - -void SKP_Silk_LTP_scale_ctrl_FIX( - SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state FIX */ - SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O encoder control FIX */ -) -{ - SKP_int round_loss; - - /* 1st order high-pass filter */ - psEnc->HPLTPredCodGain_Q7 = SKP_max_int( psEncCtrl->LTPredCodGain_Q7 - SKP_RSHIFT( psEnc->prevLTPredCodGain_Q7, 1 ), 0 ) - + SKP_RSHIFT( psEnc->HPLTPredCodGain_Q7, 1 ); - psEnc->prevLTPredCodGain_Q7 = psEncCtrl->LTPredCodGain_Q7; - - /* Only scale if first frame in packet */ - if( psEnc->sCmn.nFramesAnalyzed == 0 ) { - round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket - 1; - psEnc->sCmn.indices.LTP_scaleIndex = (SKP_int8)SKP_LIMIT( - SKP_SMULWB( SKP_SMULBB( round_loss, psEnc->HPLTPredCodGain_Q7 ), SKP_FIX_CONST( 0.1, 9 ) ), 0, 2 ); - } else { - /* Default is minimum scaling */ - psEnc->sCmn.indices.LTP_scaleIndex = 0; - } - psEncCtrl->LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ]; -} diff --git a/silk/SKP_Silk_LTP_scale_ctrl_FLP.c b/silk/SKP_Silk_LTP_scale_ctrl_FLP.c deleted file mode 100644 index 4d9345d9..00000000 --- a/silk/SKP_Silk_LTP_scale_ctrl_FLP.c +++ /dev/null @@ -1,52 +0,0 @@ -/*********************************************************************** -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_FLP.h" - -void SKP_Silk_LTP_scale_ctrl_FLP( - SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP *psEncCtrl /* I/O Encoder control FLP */ -) -{ - SKP_int round_loss; - - /* 1st order high-pass filter */ - //g_HP(n) = g(n) - 0.5 * g(n-1) + 0.5 * g_HP(n-1); - psEnc->HPLTPredCodGain = SKP_max_float( psEncCtrl->LTPredCodGain - 0.5 * psEnc->prevLTPredCodGain, 0.0f ) - + 0.5f * psEnc->HPLTPredCodGain; - psEnc->prevLTPredCodGain = psEncCtrl->LTPredCodGain; - - /* Only scale if first frame in packet */ - if( psEnc->sCmn.nFramesAnalyzed == 0 ) { - round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; - psEnc->sCmn.indices.LTP_scaleIndex = (SKP_int8)SKP_LIMIT( round_loss * psEnc->HPLTPredCodGain * 0.1f, 0.0f, 2.0f ); - } else { - /* Default is minimum scaling */ - psEnc->sCmn.indices.LTP_scaleIndex = 0; - } - psEncCtrl->LTP_scale = (SKP_float)SKP_Silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f; -} diff --git a/silk/SKP_Silk_apply_sine_window_FLP.c b/silk/SKP_Silk_apply_sine_window_FLP.c deleted file mode 100644 index 1db6b147..00000000 --- a/silk/SKP_Silk_apply_sine_window_FLP.c +++ /dev/null @@ -1,77 +0,0 @@ -/*********************************************************************** -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_FLP.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 */ -void SKP_Silk_apply_sine_window_FLP( - SKP_float px_win[], /* O Pointer to windowed signal */ - const SKP_float 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; - SKP_float freq, c, S0, S1; - - SKP_assert( win_type == 1 || win_type == 2 ); - - /* Length must be multiple of 4 */ - SKP_assert( ( length & 3 ) == 0 ); - - freq = PI / ( length + 1 ); - - /* Approximation of 2 * cos(f) */ - c = 2.0f - freq * freq; - - /* Initialize state */ - if( win_type < 2 ) { - /* Start from 0 */ - S0 = 0.0f; - /* Approximation of sin(f) */ - S1 = freq; - } else { - /* Start from 1 */ - S0 = 1.0f; - /* Approximation of cos(f) */ - S1 = 0.5f * c; - } - - /* 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 + 0 ] = px[ k + 0 ] * 0.5f * ( S0 + S1 ); - px_win[ k + 1 ] = px[ k + 1 ] * S1; - S0 = c * S1 - S0; - px_win[ k + 2 ] = px[ k + 2 ] * 0.5f * ( S1 + S0 ); - px_win[ k + 3 ] = px[ k + 3 ] * S0; - S1 = c * S0 - S1; - } -} diff --git a/silk/SKP_Silk_corrMatrix_FIX.c b/silk/SKP_Silk_corrMatrix_FIX.c deleted file mode 100644 index 1ac1b195..00000000 --- a/silk/SKP_Silk_corrMatrix_FIX.c +++ /dev/null @@ -1,152 +0,0 @@ -/*********************************************************************** -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. -***********************************************************************/ - -/********************************************************************** - * Correlation Matrix Computations for LS estimate. - **********************************************************************/ - -#include "SKP_Silk_main_FIX.h" - -/* Calculates correlation vector X'*t */ -void SKP_Silk_corrVector_FIX( - const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ - const SKP_int16 *t, /* I target vector [L] */ - const SKP_int L, /* I Length of vectors */ - const SKP_int order, /* I Max lag for correlation */ - SKP_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */ - const SKP_int rshifts /* I Right shifts of correlations */ -) -{ - SKP_int lag, i; - const SKP_int16 *ptr1, *ptr2; - SKP_int32 inner_prod; - - ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ - ptr2 = t; - /* Calculate X'*t */ - if( rshifts > 0 ) { - /* Right shifting used */ - for( lag = 0; lag < order; lag++ ) { - inner_prod = 0; - for( i = 0; i < L; i++ ) { - inner_prod += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts ); - } - Xt[ lag ] = inner_prod; /* X[:,lag]'*t */ - ptr1--; /* Go to next column of X */ - } - } else { - SKP_assert( rshifts == 0 ); - for( lag = 0; lag < order; lag++ ) { - Xt[ lag ] = SKP_Silk_inner_prod_aligned( ptr1, ptr2, L ); /* X[:,lag]'*t */ - ptr1--; /* Go to next column of X */ - } - } -} - -/* Calculates correlation matrix X'*X */ -void SKP_Silk_corrMatrix_FIX( - const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ - const SKP_int L, /* I Length of vectors */ - const SKP_int order, /* I Max lag for correlation */ - const SKP_int head_room, /* I Desired headroom */ - SKP_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ]*/ - SKP_int *rshifts /* I/O Right shifts of correlations */ -) -{ - SKP_int i, j, lag, rshifts_local, head_room_rshifts; - SKP_int32 energy; - const SKP_int16 *ptr1, *ptr2; - - /* Calculate energy to find shift used to fit in 32 bits */ - SKP_Silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 ); - /* Add shifts to get the desired head room */ - head_room_rshifts = SKP_max( head_room - SKP_Silk_CLZ32( energy ), 0 ); - - energy = SKP_RSHIFT32( energy, head_room_rshifts ); - rshifts_local += head_room_rshifts; - - /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */ - /* Remove contribution of first order - 1 samples */ - for( i = 0; i < order - 1; i++ ) { - energy -= SKP_RSHIFT32( SKP_SMULBB( x[ i ], x[ i ] ), rshifts_local ); - } - if( rshifts_local < *rshifts ) { - /* Adjust energy */ - energy = SKP_RSHIFT32( energy, *rshifts - rshifts_local ); - rshifts_local = *rshifts; - } - - /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */ - /* Fill out the diagonal of the correlation matrix */ - matrix_ptr( XX, 0, 0, order ) = energy; - ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */ - for( j = 1; j < order; j++ ) { - energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) ); - energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) ); - matrix_ptr( XX, j, j, order ) = energy; - } - - ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */ - /* Calculate the remaining elements of the correlation matrix */ - if( rshifts_local > 0 ) { - /* Right shifting used */ - for( lag = 1; lag < order; lag++ ) { - /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ - energy = 0; - for( i = 0; i < L; i++ ) { - energy += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local ); - } - /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ - matrix_ptr( XX, lag, 0, order ) = energy; - matrix_ptr( XX, 0, lag, order ) = energy; - for( j = 1; j < ( order - lag ); j++ ) { - energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) ); - energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) ); - matrix_ptr( XX, lag + j, j, order ) = energy; - matrix_ptr( XX, j, lag + j, order ) = energy; - } - ptr2--; /* Update pointer to first sample of next column (lag) in X */ - } - } else { - for( lag = 1; lag < order; lag++ ) { - /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ - energy = SKP_Silk_inner_prod_aligned( ptr1, ptr2, L ); - matrix_ptr( XX, lag, 0, order ) = energy; - matrix_ptr( XX, 0, lag, order ) = energy; - /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ - for( j = 1; j < ( order - lag ); j++ ) { - energy = SKP_SUB32( energy, SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) ); - energy = SKP_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] ); - matrix_ptr( XX, lag + j, j, order ) = energy; - matrix_ptr( XX, j, lag + j, order ) = energy; - } - ptr2--;/* Update pointer to first sample of next column (lag) in X */ - } - } - *rshifts = rshifts_local; -} - diff --git a/silk/SKP_Silk_corrMatrix_FLP.c b/silk/SKP_Silk_corrMatrix_FLP.c deleted file mode 100644 index 0fdaabd0..00000000 --- a/silk/SKP_Silk_corrMatrix_FLP.c +++ /dev/null @@ -1,89 +0,0 @@ -/*********************************************************************** -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. -***********************************************************************/ - -/********************************************************************** - * Correlation matrix computations for LS estimate. - **********************************************************************/ - -#include "SKP_Silk_main_FLP.h" - -/* Calculates correlation vector X'*t */ -void SKP_Silk_corrVector_FLP( - const SKP_float *x, /* I x vector [L+order-1] used to create X */ - const SKP_float *t, /* I Target vector [L] */ - const SKP_int L, /* I Length of vecors */ - const SKP_int Order, /* I Max lag for correlation */ - SKP_float *Xt /* O X'*t correlation vector [order] */ -) -{ - SKP_int lag; - const SKP_float *ptr1; - - ptr1 = &x[ Order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ - for( lag = 0; lag < Order; lag++ ) { - /* Calculate X[:,lag]'*t */ - Xt[ lag ] = (SKP_float)SKP_Silk_inner_product_FLP( ptr1, t, L ); - ptr1--; /* Next column of X */ - } -} - -/* Calculates correlation matrix X'*X */ -void SKP_Silk_corrMatrix_FLP( - const SKP_float *x, /* I x vector [ L+order-1 ] used to create X */ - const SKP_int L, /* I Length of vectors */ - const SKP_int Order, /* I Max lag for correlation */ - SKP_float *XX /* O X'*X correlation matrix [order x order] */ -) -{ - SKP_int j, lag; - double energy; - const SKP_float *ptr1, *ptr2; - - ptr1 = &x[ Order - 1 ]; /* First sample of column 0 of X */ - energy = SKP_Silk_energy_FLP( ptr1, L ); /* X[:,0]'*X[:,0] */ - matrix_ptr( XX, 0, 0, Order ) = ( SKP_float )energy; - for( j = 1; j < Order; j++ ) { - /* Calculate X[:,j]'*X[:,j] */ - energy += ptr1[ -j ] * ptr1[ -j ] - ptr1[ L - j ] * ptr1[ L - j ]; - matrix_ptr( XX, j, j, Order ) = ( SKP_float )energy; - } - - ptr2 = &x[ Order - 2 ]; /* First sample of column 1 of X */ - for( lag = 1; lag < Order; lag++ ) { - /* Calculate X[:,0]'*X[:,lag] */ - energy = SKP_Silk_inner_product_FLP( ptr1, ptr2, L ); - matrix_ptr( XX, lag, 0, Order ) = ( SKP_float )energy; - matrix_ptr( XX, 0, lag, Order ) = ( SKP_float )energy; - /* Calculate X[:,j]'*X[:,j + lag] */ - for( j = 1; j < ( Order - lag ); j++ ) { - energy += ptr1[ -j ] * ptr2[ -j ] - ptr1[ L - j ] * ptr2[ L - j ]; - matrix_ptr( XX, lag + j, j, Order ) = ( SKP_float )energy; - matrix_ptr( XX, j, lag + j, Order ) = ( SKP_float )energy; - } - ptr2--; /* Next column of X */ - } -} diff --git a/silk/SKP_Silk_encode_frame_FIX.c b/silk/SKP_Silk_encode_frame_FIX.c deleted file mode 100644 index e9003fcf..00000000 --- a/silk/SKP_Silk_encode_frame_FIX.c +++ /dev/null @@ -1,301 +0,0 @@ -/*********************************************************************** -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" -#include "SKP_Silk_tuning_parameters.h" - -/****************/ -/* Encode frame */ -/****************/ -SKP_int SKP_Silk_encode_frame_FIX( - SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ - SKP_int32 *pnBytesOut, /* O Number of payload bytes */ - ec_enc *psRangeEnc /* I/O compressor data structure */ -) -{ - SKP_Silk_encoder_control_FIX sEncCtrl; - SKP_int ret = 0; - SKP_int16 *x_frame, *res_pitch_frame; - SKP_int16 xfw[ MAX_FRAME_LENGTH ]; - SKP_int16 res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ]; - -TIC(ENCODE_FRAME) - - psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; - - /**************************************************************/ - /* Setup Input Pointers, and insert frame in input buffer */ - /*************************************************************/ - /* pointers aligned with start of frame to encode */ - x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */ - res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */ - - /****************************/ - /* Voice Activity Detection */ - /****************************/ -TIC(VAD) - ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf ); -TOC(VAD) - - /**************************************************/ - /* Convert speech activity into VAD and DTX flags */ - /**************************************************/ - if( psEnc->sCmn.nFramesAnalyzed == 0 ) { - psEnc->sCmn.inDTX = psEnc->sCmn.useDTX; - } - if( psEnc->sCmn.speech_activity_Q8 < SKP_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) { - psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; - psEnc->sCmn.noSpeechCounter++; - if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) { - psEnc->sCmn.inDTX = 0; - } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { - psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; - psEnc->sCmn.inDTX = 0; - } - psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesAnalyzed ] = 0; - } else { - psEnc->sCmn.noSpeechCounter = 0; - psEnc->sCmn.inDTX = 0; - psEnc->sCmn.indices.signalType = TYPE_UNVOICED; - psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesAnalyzed ] = 1; - } - - /*******************************************/ - /* High-pass filtering of the input signal */ - /*******************************************/ -TIC(HP_IN) - SKP_Silk_HP_variable_cutoff( &psEnc->sCmn, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf, psEnc->sCmn.frame_length ); -TOC(HP_IN) - - /* Ensure smooth bandwidth transitions */ - SKP_Silk_LP_variable_cutoff( &psEnc->sCmn.sLP, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length ); - - /*****************************************/ - /* Find pitch lags, initial LPC analysis */ - /*****************************************/ -TIC(FIND_PITCH) - SKP_Silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame ); -TOC(FIND_PITCH) - - /************************/ - /* Noise shape analysis */ - /************************/ -TIC(NOISE_SHAPE_ANALYSIS) - SKP_Silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame ); -TOC(NOISE_SHAPE_ANALYSIS) - - /*****************************************/ - /* Prefiltering for noise shaper */ - /*****************************************/ -TIC(PREFILTER) - SKP_Silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame ); -TOC(PREFILTER) - - /***************************************************/ - /* Find linear prediction coefficients (LPC + LTP) */ - /***************************************************/ -TIC(FIND_PRED_COEF) - SKP_Silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame ); -TOC(FIND_PRED_COEF) - - /****************************************/ - /* Process gains */ - /****************************************/ -TIC(PROCESS_GAINS) - SKP_Silk_process_gains_FIX( psEnc, &sEncCtrl ); -TOC(PROCESS_GAINS) - - /****************************************/ - /* Low Bitrate Redundant Encoding */ - /****************************************/ -TIC(LBRR) - SKP_Silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw ); -TOC(LBRR) - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ -TIC(NSQ) - if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { - SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses, - sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, - sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); - } else { - SKP_Silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses, - sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, - sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); - } -TOC(NSQ) - - /* Update input buffer */ - SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], - ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_int16 ) ); - - /* Parameters needed for next frame */ - psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; - psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; - - /* Exit without entropy coding */ - if( psEnc->sCmn.prefillFlag ) { - /* No payload */ - *pnBytesOut = 0; - return ret; - } - - /****************************************/ - /* Encode Parameters */ - /****************************************/ -TIC(ENCODE_PARAMS) - SKP_Silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesAnalyzed, 0 ); -TOC(ENCODE_PARAMS) - - /****************************************/ - /* Encode Excitation Signal */ - /****************************************/ -TIC(ENCODE_PULSES) - SKP_Silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, - psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); -TOC(ENCODE_PULSES) - - /****************************************/ - /* Finalize payload */ - /****************************************/ - psEnc->sCmn.first_frame_after_reset = 0; - if( ++psEnc->sCmn.nFramesAnalyzed >= psEnc->sCmn.nFramesPerPacket ) { - /* Payload size */ - *pnBytesOut = SKP_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); - - /* Reset the number of frames in payload buffer */ - psEnc->sCmn.nFramesAnalyzed = 0; - } else { - /* No payload this time */ - *pnBytesOut = 0; - } -TOC(ENCODE_FRAME) - -#ifdef SAVE_ALL_INTERNAL_DATA - { - SKP_float tmp[ MAX_NB_SUBFR * LTP_ORDER ]; - int i; - DEBUG_STORE_DATA( xf.dat, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) ); - DEBUG_STORE_DATA( xfw.dat, xfw, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) ); - DEBUG_STORE_DATA( pitchL.dat, sEncCtrl.pitchL, psEnc->sCmn.nb_subfr * sizeof( SKP_int ) ); - for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) { - tmp[ i ] = (SKP_float)sEncCtrl.LTPCoef_Q14[ i ] / 16384.0f; - } - DEBUG_STORE_DATA( pitchG_quantized.dat, tmp, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) ); - for( i = 0; i sCmn.predictLPCOrder; i++ ) { - tmp[ i ] = (SKP_float)sEncCtrl.PredCoef_Q12[ 1 ][ i ] / 4096.0f; - } - DEBUG_STORE_DATA( PredCoef.dat, tmp, psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) ); - - tmp[ 0 ] = (SKP_float)sEncCtrl.LTPredCodGain_Q7 / 128.0f; - DEBUG_STORE_DATA( LTPredCodGain.dat, tmp, sizeof( SKP_float ) ); - tmp[ 0 ] = (SKP_float)psEnc->LTPCorr_Q15 / 32768.0f; - DEBUG_STORE_DATA( LTPcorr.dat, tmp, sizeof( SKP_float ) ); - tmp[ 0 ] = (SKP_float)psEnc->sCmn.input_tilt_Q15 / 32768.0f; - DEBUG_STORE_DATA( tilt.dat, tmp, sizeof( SKP_float ) ); - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - tmp[ i ] = (SKP_float)sEncCtrl.Gains_Q16[ i ] / 65536.0f; - } - DEBUG_STORE_DATA( gains.dat, tmp, psEnc->sCmn.nb_subfr * sizeof( SKP_float ) ); - DEBUG_STORE_DATA( gains_indices.dat, &psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr * sizeof( SKP_int ) ); - tmp[ 0 ] = (SKP_float)sEncCtrl.current_SNR_dB_Q7 / 128.0f; - DEBUG_STORE_DATA( current_SNR_db.dat, tmp, sizeof( SKP_float ) ); - DEBUG_STORE_DATA( quantOffsetType.dat, &psEnc->sCmn.indices.quantOffsetType, sizeof( SKP_int ) ); - tmp[ 0 ] = (SKP_float)psEnc->sCmn.speech_activity_Q8 / 256.0f; - DEBUG_STORE_DATA( speech_activity.dat, tmp, sizeof( SKP_float ) ); - for( i = 0; i < VAD_N_BANDS; i++ ) { - tmp[ i ] = (SKP_float)psEnc->sCmn.input_quality_bands_Q15[ i ] / 32768.0f; - } - DEBUG_STORE_DATA( input_quality_bands.dat, tmp, VAD_N_BANDS * sizeof( SKP_float ) ); - DEBUG_STORE_DATA( signalType.dat, &psEnc->sCmn.indices.signalType, sizeof( SKP_int8) ); - DEBUG_STORE_DATA( lag_index.dat, &psEnc->sCmn.indices.lagIndex, sizeof( SKP_int16 ) ); - DEBUG_STORE_DATA( contour_index.dat, &psEnc->sCmn.indices.contourIndex, sizeof( SKP_int8 ) ); - DEBUG_STORE_DATA( per_index.dat, &psEnc->sCmn.indices.PERIndex, sizeof( SKP_int8) ); - } -#endif - return ret; -} - -/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ -void SKP_Silk_LBRR_encode_FIX( - SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ - SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ - const SKP_int16 xfw[] /* I Input signal */ -) -{ - SKP_int32 TempGains_Q16[ MAX_NB_SUBFR ]; - SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesAnalyzed ]; - SKP_Silk_nsq_state sNSQ_LBRR; - - /*******************************************/ - /* Control use of inband LBRR */ - /*******************************************/ - if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SKP_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { - psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesAnalyzed ] = 1; - - /* Copy noise shaping quantizer state and quantization indices from regular encoding */ - SKP_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( SKP_Silk_nsq_state ) ); - SKP_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); - - /* Save original gains */ - SKP_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( SKP_int32 ) ); - - if( psEnc->sCmn.nFramesAnalyzed == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesAnalyzed - 1 ] == 0 ) { - /* First frame in packet or previous frame not LBRR coded */ - psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; - - /* Increase Gains to get target LBRR rate */ - psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases; - psIndices_LBRR->GainsIndices[ 0 ] = SKP_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); - } - - /* Decode to get gains in sync with decoder */ - /* Overwrite unquantized gains with quantized gains */ - SKP_Silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices, - &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesAnalyzed, psEnc->sCmn.nb_subfr ); - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ - if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { - SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw, - psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesAnalyzed ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, - psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, - psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); - } else { - SKP_Silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw, - psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesAnalyzed ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, - psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, - psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); - } - - /* Restore original gains */ - SKP_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( SKP_int32 ) ); - } -} diff --git a/silk/SKP_Silk_encode_frame_FLP.c b/silk/SKP_Silk_encode_frame_FLP.c deleted file mode 100644 index 43b5283b..00000000 --- a/silk/SKP_Silk_encode_frame_FLP.c +++ /dev/null @@ -1,277 +0,0 @@ -/*********************************************************************** -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_FLP.h" -#include "SKP_Silk_tuning_parameters.h" - -/****************/ -/* Encode frame */ -/****************/ -SKP_int SKP_Silk_encode_frame_FLP( - SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - SKP_int32 *pnBytesOut, /* O Number of payload bytes */ - ec_enc *psRangeEnc /* I/O compressor data structure */ -) -{ - SKP_Silk_encoder_control_FLP sEncCtrl; - SKP_int i, ret = 0; - SKP_float *x_frame, *res_pitch_frame; - SKP_int16 pIn_HP[ MAX_FRAME_LENGTH ]; - SKP_float xfw[ MAX_FRAME_LENGTH ]; - SKP_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ]; - -TIC(ENCODE_FRAME) - - psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; - - /**************************************************************/ - /* Setup Input Pointers, and insert frame in input buffer */ - /*************************************************************/ - /* pointers aligned with start of frame to encode */ - x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */ - res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */ - - /****************************/ - /* Voice Activity Detection */ - /****************************/ -TIC(VAD) - ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf ); -TOC(VAD) - - /**************************************************/ - /* Convert speech activity into VAD and DTX flags */ - /**************************************************/ - if( psEnc->sCmn.nFramesAnalyzed == 0 ) { - psEnc->sCmn.inDTX = psEnc->sCmn.useDTX; - } - if( psEnc->sCmn.speech_activity_Q8 < SKP_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) { - psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; - psEnc->sCmn.noSpeechCounter++; - if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) { - psEnc->sCmn.inDTX = 0; - } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { - psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; - psEnc->sCmn.inDTX = 0; - } - psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesAnalyzed ] = 0; - } else { - psEnc->sCmn.noSpeechCounter = 0; - psEnc->sCmn.inDTX = 0; - psEnc->sCmn.indices.signalType = TYPE_UNVOICED; - psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesAnalyzed ] = 1; - } - - /*******************************************/ - /* High-pass filtering of the input signal */ - /*******************************************/ -TIC(HP_IN) - SKP_Silk_HP_variable_cutoff( &psEnc->sCmn, pIn_HP, psEnc->sCmn.inputBuf, psEnc->sCmn.frame_length ); -TOC(HP_IN) - - /* Ensure smooth bandwidth transitions */ - SKP_Silk_LP_variable_cutoff( &psEnc->sCmn.sLP, pIn_HP, psEnc->sCmn.frame_length ); - - /*******************************************/ - /* Copy new frame to front of input buffer */ - /*******************************************/ - SKP_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP, psEnc->sCmn.frame_length ); - - /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */ - for( i = 0; i < 8; i++ ) { - x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f; - } - - /*****************************************/ - /* Find pitch lags, initial LPC analysis */ - /*****************************************/ -TIC(FIND_PITCH) - SKP_Silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame ); -TOC(FIND_PITCH) - - /************************/ - /* Noise shape analysis */ - /************************/ -TIC(NOISE_SHAPE_ANALYSIS) - SKP_Silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame ); -TOC(NOISE_SHAPE_ANALYSIS) - - /*****************************************/ - /* Prefiltering for noise shaper */ - /*****************************************/ -TIC(PREFILTER) - SKP_Silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame ); -TOC(PREFILTER) - - /***************************************************/ - /* Find linear prediction coefficients (LPC + LTP) */ - /***************************************************/ -TIC(FIND_PRED_COEF) - SKP_Silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch, x_frame ); -TOC(FIND_PRED_COEF) - - /****************************************/ - /* Process gains */ - /****************************************/ -TIC(PROCESS_GAINS) - SKP_Silk_process_gains_FLP( psEnc, &sEncCtrl ); -TOC(PROCESS_GAINS) - - /****************************************/ - /* Low Bitrate Redundant Encoding */ - /****************************************/ -TIC(LBRR) - SKP_Silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw ); -TOC(LBRR) - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ -TIC(NSQ) - SKP_Silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw ); -TOC(NSQ) - - /* Update input buffer */ - SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], - ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_float ) ); - - /* Parameters needed for next frame */ - psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; - psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; - - /* Exit without entropy coding */ - if( psEnc->sCmn.prefillFlag ) { - /* No payload */ - *pnBytesOut = 0; - return ret; - } - - /****************************************/ - /* Encode Parameters */ - /****************************************/ -TIC(ENCODE_PARAMS) - SKP_Silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesAnalyzed, 0 ); -TOC(ENCODE_PARAMS) - - /****************************************/ - /* Encode Excitation Signal */ - /****************************************/ -TIC(ENCODE_PULSES) - SKP_Silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, - psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); -TOC(ENCODE_PULSES) - - /****************************************/ - /* Finalize payload */ - /****************************************/ - psEnc->sCmn.first_frame_after_reset = 0; - if( ++psEnc->sCmn.nFramesAnalyzed >= psEnc->sCmn.nFramesPerPacket ) { - /* Payload size */ - *pnBytesOut = SKP_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); - - /* Reset the number of frames in payload buffer */ - psEnc->sCmn.nFramesAnalyzed = 0; - } else { - /* No payload this time */ - *pnBytesOut = 0; - } -TOC(ENCODE_FRAME) - -#ifdef SAVE_ALL_INTERNAL_DATA - //DEBUG_STORE_DATA( xf.dat, pIn_HP_LP, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) ); - //DEBUG_STORE_DATA( xfw.dat, xfw, psEnc->sCmn.frame_length * sizeof( SKP_float ) ); - DEBUG_STORE_DATA( pitchL.dat, sEncCtrl.pitchL, MAX_NB_SUBFR * sizeof( SKP_int ) ); - DEBUG_STORE_DATA( pitchG_quantized.dat, sEncCtrl.LTPCoef, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) ); - DEBUG_STORE_DATA( LTPcorr.dat, &psEnc->LTPCorr, sizeof( SKP_float ) ); - DEBUG_STORE_DATA( gains.dat, sEncCtrl.Gains, psEnc->sCmn.nb_subfr * sizeof( SKP_float ) ); - DEBUG_STORE_DATA( gains_indices.dat, &psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr * sizeof( SKP_int8 ) ); - DEBUG_STORE_DATA( quantOffsetType.dat, &psEnc->sCmn.indices.quantOffsetType, sizeof( SKP_int8 ) ); - DEBUG_STORE_DATA( speech_activity_q8.dat, &psEnc->sCmn.speech_activity_Q8, sizeof( SKP_int ) ); - DEBUG_STORE_DATA( signalType.dat, &psEnc->sCmn.indices.signalType, sizeof( SKP_int8 ) ); - DEBUG_STORE_DATA( lag_index.dat, &psEnc->sCmn.indices.lagIndex, sizeof( SKP_int16 ) ); - DEBUG_STORE_DATA( contour_index.dat, &psEnc->sCmn.indices.contourIndex, sizeof( SKP_int8 ) ); - DEBUG_STORE_DATA( per_index.dat, &psEnc->sCmn.indices.PERIndex, sizeof( SKP_int8 ) ); - DEBUG_STORE_DATA( PredCoef.dat, &sEncCtrl.PredCoef[ 1 ], psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) ); - DEBUG_STORE_DATA( ltp_scale_idx.dat, &psEnc->sCmn.indices.LTP_scaleIndex, sizeof( SKP_int8 ) ); -// DEBUG_STORE_DATA( xq.dat, psEnc->sCmn.sNSQ.xqBuf, psEnc->sCmn.frame_length * sizeof( SKP_float ) ); -#endif - return ret; -} - -/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ -void SKP_Silk_LBRR_encode_FLP( - SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - const SKP_float xfw[] /* I Input signal */ -) -{ - SKP_int k; - SKP_int32 Gains_Q16[ MAX_NB_SUBFR ]; - SKP_float TempGains[ MAX_NB_SUBFR ]; - SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesAnalyzed ]; - SKP_Silk_nsq_state sNSQ_LBRR; - - /*******************************************/ - /* Control use of inband LBRR */ - /*******************************************/ - if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SKP_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { - psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesAnalyzed ] = 1; - - /* Copy noise shaping quantizer state and quantization indices from regular encoding */ - SKP_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( SKP_Silk_nsq_state ) ); - SKP_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); - - /* Save original gains */ - SKP_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( SKP_float ) ); - - if( psEnc->sCmn.nFramesAnalyzed == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesAnalyzed - 1 ] == 0 ) { - /* First frame in packet or previous frame not LBRR coded */ - psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; - - /* Increase Gains to get target LBRR rate */ - psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases; - psIndices_LBRR->GainsIndices[ 0 ] = SKP_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); - } - - /* Decode to get gains in sync with decoder */ - SKP_Silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices, - &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesAnalyzed, psEnc->sCmn.nb_subfr ); - - /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains[ k ] = Gains_Q16[ k ] / 65536.0f; - } - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ - SKP_Silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR, - psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesAnalyzed ], xfw ); - - /* Restore original gains */ - SKP_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( SKP_float ) ); - } -} diff --git a/silk/SKP_Silk_find_LPC_FIX.c b/silk/SKP_Silk_find_LPC_FIX.c deleted file mode 100644 index bf065db1..00000000 --- a/silk/SKP_Silk_find_LPC_FIX.c +++ /dev/null @@ -1,157 +0,0 @@ -/*********************************************************************** -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" -#include "SKP_Silk_tuning_parameters.h" - -/* Finds LPC vector from correlations, and converts to NLSF */ -void SKP_Silk_find_LPC_FIX( - SKP_int16 NLSF_Q15[], /* O NLSFs */ - SKP_int8 *interpIndex, /* O NLSF interpolation index, only used for NLSF interpolation */ - const SKP_int16 prev_NLSFq_Q15[], /* I previous NLSFs, only used for NLSF interpolation */ - const SKP_int useInterpNLSFs, /* I Flag */ - const SKP_int firstFrameAfterReset, /* I Flag */ - const SKP_int LPC_order, /* I LPC order */ - const SKP_int16 x[], /* I Input signal */ - const SKP_int subfr_length, /* I Input signal subframe length including preceeding samples */ - const SKP_int nb_subfr /* I: Number of subframes */ -) -{ - SKP_int k; - SKP_int32 a_Q16[ MAX_LPC_ORDER ]; - SKP_int isInterpLower, shift; - SKP_int32 res_nrg0, res_nrg1; - SKP_int rshift0, rshift1; - - /* Used only for LSF interpolation */ - SKP_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg, res_nrg_2nd; - SKP_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q, res_nrg_2nd_Q; - SKP_int16 a_tmp_Q12[ MAX_LPC_ORDER ]; - SKP_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; - SKP_int16 LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; - - /* Default: no interpolation */ - *interpIndex = 4; - - /* Burg AR analysis for the full frame */ - SKP_Silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, subfr_length, nb_subfr, SKP_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order ); - - if( firstFrameAfterReset ) { - SKP_Silk_bwexpander_32( a_Q16, LPC_order, SKP_FIX_CONST( FIND_LPC_CHIRP_FIRST_FRAME, 16 ) ); - } else { - SKP_Silk_bwexpander_32( a_Q16, LPC_order, SKP_FIX_CONST( FIND_LPC_CHIRP, 16 ) ); - } - - if( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) { - - /* Optimal solution for last 10 ms */ - SKP_Silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + ( MAX_NB_SUBFR >> 1 ) * subfr_length, - subfr_length, ( MAX_NB_SUBFR >> 1 ), SKP_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order ); - - SKP_Silk_bwexpander_32( a_tmp_Q16, LPC_order, SKP_FIX_CONST( FIND_LPC_CHIRP, 16 ) ); - - /* subtract residual energy here, as that's easier than adding it to the */ - /* residual energy of the first 10 ms in each iteration of the search below */ - shift = res_tmp_nrg_Q - res_nrg_Q; - if( shift >= 0 ) { - if( shift < 32 ) { - res_nrg = res_nrg - SKP_RSHIFT( res_tmp_nrg, shift ); - } - } else { - SKP_assert( shift > -32 ); - res_nrg = SKP_RSHIFT( res_nrg, -shift ) - res_tmp_nrg; - res_nrg_Q = res_tmp_nrg_Q; - } - - /* Convert to NLSFs */ - SKP_Silk_A2NLSF( NLSF_Q15, a_tmp_Q16, LPC_order ); - - /* Search over interpolation indices to find the one with lowest residual energy */ - res_nrg_2nd = SKP_int32_MAX; - for( k = 3; k >= 0; k-- ) { - /* Interpolate NLSFs for first half */ - SKP_Silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order ); - - /* Convert to LPC for residual energy evaluation */ - SKP_Silk_NLSF2A_stable( a_tmp_Q12, NLSF0_Q15, LPC_order ); - - /* Calculate residual energy with NLSF interpolation */ - SKP_Silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, LPC_order ); - - SKP_Silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + LPC_order, subfr_length - LPC_order ); - SKP_Silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + LPC_order + subfr_length, subfr_length - LPC_order ); - - /* Add subframe energies from first half frame */ - shift = rshift0 - rshift1; - if( shift >= 0 ) { - res_nrg1 = SKP_RSHIFT( res_nrg1, shift ); - res_nrg_interp_Q = -rshift0; - } else { - res_nrg0 = SKP_RSHIFT( res_nrg0, -shift ); - res_nrg_interp_Q = -rshift1; - } - res_nrg_interp = SKP_ADD32( res_nrg0, res_nrg1 ); - - /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */ - shift = res_nrg_interp_Q - res_nrg_Q; - if( shift >= 0 ) { - if( SKP_RSHIFT( res_nrg_interp, shift ) < res_nrg ) { - isInterpLower = SKP_TRUE; - } else { - isInterpLower = SKP_FALSE; - } - } else { - if( -shift < 32 ) { - if( res_nrg_interp < SKP_RSHIFT( res_nrg, -shift ) ) { - isInterpLower = SKP_TRUE; - } else { - isInterpLower = SKP_FALSE; - } - } else { - isInterpLower = SKP_FALSE; - } - } - - /* Determine whether current interpolated NLSFs are best so far */ - if( isInterpLower == SKP_TRUE ) { - /* Interpolation has lower residual energy */ - res_nrg = res_nrg_interp; - res_nrg_Q = res_nrg_interp_Q; - *interpIndex = (SKP_int8)k; - } - res_nrg_2nd = res_nrg_interp; - res_nrg_2nd_Q = res_nrg_interp_Q; - } - } - - if( *interpIndex == 4 ) { - /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ - SKP_Silk_A2NLSF( NLSF_Q15, a_Q16, LPC_order ); - } - - SKP_assert( *interpIndex == 4 || ( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) ); -} diff --git a/silk/SKP_Silk_find_LPC_FLP.c b/silk/SKP_Silk_find_LPC_FLP.c deleted file mode 100644 index 88392f39..00000000 --- a/silk/SKP_Silk_find_LPC_FLP.c +++ /dev/null @@ -1,109 +0,0 @@ -/*********************************************************************** -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_FLP.h" -#include "SKP_Silk_tuning_parameters.h" - -void SKP_Silk_find_LPC_FLP( - SKP_int16 NLSF_Q15[], /* O NLSFs */ - SKP_int8 *interpIndex, /* O NLSF interp. index for NLSF interp. */ - const SKP_int16 prev_NLSFq_Q15[], /* I Previous NLSFs, for NLSF interpolation */ - const SKP_int useInterpNLSFs, /* I Flag */ - const SKP_int firstFrameAfterReset, /* I Flag */ - const SKP_int LPC_order, /* I LPC order */ - const SKP_float x[], /* I Input signal */ - const SKP_int subfr_length, /* I Subframe length incl preceeding samples */ - const SKP_int nb_subfr /* I: Number of subframes */ -) -{ - SKP_int k; - SKP_float a[ MAX_LPC_ORDER ]; - - /* Used only for NLSF interpolation */ - double res_nrg, res_nrg_2nd, res_nrg_interp; - SKP_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; - SKP_float a_tmp[ MAX_LPC_ORDER ]; - SKP_float LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; - - /* Default: No interpolation */ - *interpIndex = 4; - - /* Burg AR analysis for the full frame */ - res_nrg = SKP_Silk_burg_modified_FLP( a, x, subfr_length, nb_subfr, FIND_LPC_COND_FAC, LPC_order ); - - if( firstFrameAfterReset ) { - SKP_Silk_bwexpander_FLP( a, LPC_order, FIND_LPC_CHIRP_FIRST_FRAME ); - } else { - SKP_Silk_bwexpander_FLP( a_tmp, LPC_order, FIND_LPC_CHIRP ); - } - - if( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) { - /* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */ - /* adding it to the residual energy of the first 10 ms in each iteration of the search below */ - res_nrg -= SKP_Silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length, - subfr_length, MAX_NB_SUBFR / 2, FIND_LPC_COND_FAC, LPC_order ); - - SKP_Silk_bwexpander_FLP( a_tmp, LPC_order, FIND_LPC_CHIRP ); - - /* Convert to NLSFs */ - SKP_Silk_A2NLSF_FLP( NLSF_Q15, a_tmp, LPC_order ); - - /* Search over interpolation indices to find the one with lowest residual energy */ - res_nrg_2nd = SKP_float_MAX; - for( k = 3; k >= 0; k-- ) { - /* Interpolate NLSFs for first half */ - SKP_Silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order ); - - /* Convert to LPC for residual energy evaluation */ - SKP_Silk_NLSF2A_stable_FLP( a_tmp, NLSF0_Q15, LPC_order ); - - /* Calculate residual energy with LSF interpolation */ - SKP_Silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, LPC_order ); - res_nrg_interp = - SKP_Silk_energy_FLP( LPC_res + LPC_order, subfr_length - LPC_order ) + - SKP_Silk_energy_FLP( LPC_res + LPC_order + subfr_length, subfr_length - LPC_order ); - - /* Determine whether current interpolated NLSFs are best so far */ - if( res_nrg_interp < res_nrg ) { - /* Interpolation has lower residual energy */ - res_nrg = res_nrg_interp; - *interpIndex = (SKP_int8)k; - } else if( res_nrg_interp > res_nrg_2nd ) { - /* No reason to continue iterating - residual energies will continue to climb */ - break; - } - res_nrg_2nd = res_nrg_interp; - } - } - - if( *interpIndex == 4 ) { - /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ - SKP_Silk_A2NLSF_FLP( NLSF_Q15, a, LPC_order ); - } - - SKP_assert( *interpIndex == 4 || ( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) ); -} diff --git a/silk/SKP_Silk_find_LTP_FIX.c b/silk/SKP_Silk_find_LTP_FIX.c deleted file mode 100644 index 50aeb562..00000000 --- a/silk/SKP_Silk_find_LTP_FIX.c +++ /dev/null @@ -1,241 +0,0 @@ -/*********************************************************************** -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" -#include "SKP_Silk_tuning_parameters.h" - -/* Head room for correlations */ -#define LTP_CORRS_HEAD_ROOM 2 - -void SKP_Silk_fit_LTP( - SKP_int32 LTP_coefs_Q16[ LTP_ORDER ], - SKP_int16 LTP_coefs_Q14[ LTP_ORDER ] -); - -void SKP_Silk_find_LTP_FIX( - SKP_int16 b_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ - SKP_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ - SKP_int *LTPredCodGain_Q7, /* O LTP coding gain */ - const SKP_int16 r_lpc[] , /* I residual signal after LPC signal + state for first 10 ms */ - const SKP_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ - const SKP_int32 Wght_Q15[ MAX_NB_SUBFR ], /* I weights */ - const SKP_int subfr_length, /* I subframe length */ - const SKP_int nb_subfr, /* I number of subframes */ - const SKP_int mem_offset, /* I number of samples in LTP memory */ - SKP_int corr_rshifts[ MAX_NB_SUBFR ] /* O right shifts applied to correlations */ -) -{ - SKP_int i, k, lshift; - const SKP_int16 *r_ptr, *lag_ptr; - SKP_int16 *b_Q14_ptr; - - SKP_int32 regu; - SKP_int32 *WLTP_ptr; - SKP_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], g_Q26; - SKP_int32 w[ MAX_NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits; - - SKP_int32 temp32, denom32; - SKP_int extra_shifts; - SKP_int rr_shifts, maxRshifts, maxRshifts_wxtra, LZs; - SKP_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16; - SKP_int32 Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ]; - SKP_int32 wd, m_Q12; - - b_Q14_ptr = b_Q14; - WLTP_ptr = WLTP; - r_ptr = &r_lpc[ mem_offset ]; - for( k = 0; k < nb_subfr; k++ ) { - lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); - - SKP_Silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */ - - /* Assure headroom */ - LZs = SKP_Silk_CLZ32( rr[k] ); - if( LZs < LTP_CORRS_HEAD_ROOM ) { - rr[ k ] = SKP_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs ); - rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs ); - } - corr_rshifts[ k ] = rr_shifts; - SKP_Silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ] ); /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */ - - /* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */ - SKP_Silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ] ); /* Rr_fix_ptr in Q( -corr_rshifts[ k ] ) */ - if( corr_rshifts[ k ] > rr_shifts ) { - rr[ k ] = SKP_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */ - } - SKP_assert( rr[ k ] >= 0 ); - - regu = 1; - regu = SKP_SMLAWB( regu, rr[ k ], SKP_FIX_CONST( LTP_DAMPING/3, 16 ) ); - regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SKP_FIX_CONST( LTP_DAMPING/3, 16 ) ); - regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SKP_FIX_CONST( LTP_DAMPING/3, 16 ) ); - SKP_Silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER ); - - SKP_Silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */ - - /* Limit and store in Q14 */ - SKP_Silk_fit_LTP( b_Q16, b_Q14_ptr ); - - /* Calculate residual energy */ - nrg[ k ] = SKP_Silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */ - - /* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */ - extra_shifts = SKP_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM ); - denom32 = SKP_LSHIFT_SAT32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */ - SKP_RSHIFT( SKP_SMULWB( subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */ - denom32 = SKP_max( denom32, 1 ); - SKP_assert( ((SKP_int64)Wght_Q15[ k ] << 16 ) < SKP_int32_MAX ); /* Wght always < 0.5 in Q0 */ - temp32 = SKP_DIV32( SKP_LSHIFT( ( SKP_int32 )Wght_Q15[ k ], 16 ), denom32 ); /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */ - temp32 = SKP_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 ); /* Q26 */ - - /* Limit temp such that the below scaling never wraps around */ - WLTP_max = 0; - for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) { - WLTP_max = SKP_max( WLTP_ptr[ i ], WLTP_max ); - } - lshift = SKP_Silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */ - SKP_assert( 26 - 18 + lshift >= 0 ); - if( 26 - 18 + lshift < 31 ) { - temp32 = SKP_min_32( temp32, SKP_LSHIFT( ( SKP_int32 )1, 26 - 18 + lshift ) ); - } - - SKP_Silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */ - - w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER/2, LTP_ORDER/2, LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */ - SKP_assert( w[k] >= 0 ); - - r_ptr += subfr_length; - b_Q14_ptr += LTP_ORDER; - WLTP_ptr += LTP_ORDER * LTP_ORDER; - } - - maxRshifts = 0; - for( k = 0; k < nb_subfr; k++ ) { - maxRshifts = SKP_max_int( corr_rshifts[ k ], maxRshifts ); - } - - /* Compute LTP coding gain */ - if( LTPredCodGain_Q7 != NULL ) { - LPC_LTP_res_nrg = 0; - LPC_res_nrg = 0; - SKP_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */ - for( k = 0; k < nb_subfr; k++ ) { - LPC_res_nrg = SKP_ADD32( LPC_res_nrg, SKP_RSHIFT( SKP_ADD32( SKP_SMULWB( rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */ - LPC_LTP_res_nrg = SKP_ADD32( LPC_LTP_res_nrg, SKP_RSHIFT( SKP_ADD32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */ - } - LPC_LTP_res_nrg = SKP_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */ - - div_Q16 = SKP_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 ); - *LTPredCodGain_Q7 = ( SKP_int )SKP_SMULBB( 3, SKP_Silk_lin2log( div_Q16 ) - ( 16 << 7 ) ); - - SKP_assert( *LTPredCodGain_Q7 == ( SKP_int )SKP_SAT16( SKP_MUL( 3, SKP_Silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) ); - } - - /* smoothing */ - /* d = sum( B, 1 ); */ - b_Q14_ptr = b_Q14; - for( k = 0; k < nb_subfr; k++ ) { - d_Q14[ k ] = 0; - for( i = 0; i < LTP_ORDER; i++ ) { - d_Q14[ k ] += b_Q14_ptr[ i ]; - } - b_Q14_ptr += LTP_ORDER; - } - - /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */ - - /* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */ - max_abs_d_Q14 = 0; - max_w_bits = 0; - for( k = 0; k < nb_subfr; k++ ) { - max_abs_d_Q14 = SKP_max_32( max_abs_d_Q14, SKP_abs( d_Q14[ k ] ) ); - /* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */ - /* Find bits needed in Q( 18 - maxRshifts ) */ - max_w_bits = SKP_max_32( max_w_bits, 32 - SKP_Silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts ); - } - - /* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -SKP_int16_MIN */ - SKP_assert( max_abs_d_Q14 <= ( 5 << 15 ) ); - - /* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */ - extra_shifts = max_w_bits + 32 - SKP_Silk_CLZ32( max_abs_d_Q14 ) - 14; - - /* Subtract what we got available; bits in output var plus maxRshifts */ - extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */ - extra_shifts = SKP_max_int( extra_shifts, 0 ); - - maxRshifts_wxtra = maxRshifts + extra_shifts; - - temp32 = SKP_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */ - wd = 0; - for( k = 0; k < nb_subfr; k++ ) { - /* w has at least 2 bits of headroom so no overflow should happen */ - temp32 = SKP_ADD32( temp32, SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) ); /* Q( 18 - maxRshifts_wxtra ) */ - wd = SKP_ADD32( wd, SKP_LSHIFT( SKP_SMULWW( SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */ - } - m_Q12 = SKP_DIV32_varQ( wd, temp32, 12 ); - - b_Q14_ptr = b_Q14; - for( k = 0; k < nb_subfr; k++ ) { - /* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */ - if( 2 - corr_rshifts[k] > 0 ) { - temp32 = SKP_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] ); - } else { - temp32 = SKP_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 ); - } - - g_Q26 = SKP_MUL( - SKP_DIV32( - SKP_FIX_CONST( LTP_SMOOTHING, 26 ), - SKP_RSHIFT( SKP_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ), /* Q10 */ - SKP_LSHIFT_SAT32( SKP_SUB_SAT32( ( SKP_int32 )m_Q12, SKP_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) ); /* Q16 */ - - temp32 = 0; - for( i = 0; i < LTP_ORDER; i++ ) { - delta_b_Q14[ i ] = SKP_max_16( b_Q14_ptr[ i ], 1638 ); /* 1638_Q14 = 0.1_Q0 */ - temp32 += delta_b_Q14[ i ]; /* Q14 */ - } - temp32 = SKP_DIV32( g_Q26, temp32 ); /* Q14->Q12 */ - for( i = 0; i < LTP_ORDER; i++ ) { - b_Q14_ptr[ i ] = SKP_LIMIT_32( ( SKP_int32 )b_Q14_ptr[ i ] + SKP_SMULWB( SKP_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 ); - } - b_Q14_ptr += LTP_ORDER; - } -TOC(find_LTP_FIX) -} - -void SKP_Silk_fit_LTP( - SKP_int32 LTP_coefs_Q16[ LTP_ORDER ], - SKP_int16 LTP_coefs_Q14[ LTP_ORDER ] -) -{ - SKP_int i; - - for( i = 0; i < LTP_ORDER; i++ ) { - LTP_coefs_Q14[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) ); - } -} diff --git a/silk/SKP_Silk_find_LTP_FLP.c b/silk/SKP_Silk_find_LTP_FLP.c deleted file mode 100644 index 7daf5fbb..00000000 --- a/silk/SKP_Silk_find_LTP_FLP.c +++ /dev/null @@ -1,128 +0,0 @@ -/*********************************************************************** -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_FLP.h" -#include "SKP_Silk_tuning_parameters.h" - -void SKP_Silk_find_LTP_FLP( - SKP_float b[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ - SKP_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ - SKP_float *LTPredCodGain, /* O LTP coding gain */ - const SKP_float r_lpc[], /* I LPC residual */ - const SKP_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ - const SKP_float Wght[ MAX_NB_SUBFR ], /* I Weights */ - const SKP_int subfr_length, /* I Subframe length */ - const SKP_int nb_subfr, /* I number of subframes */ - const SKP_int mem_offset /* I Number of samples in LTP memory */ -) -{ - SKP_int i, k; - SKP_float *b_ptr, temp, *WLTP_ptr; - SKP_float LPC_res_nrg, LPC_LTP_res_nrg; - SKP_float d[ MAX_NB_SUBFR ], m, g, delta_b[ LTP_ORDER ]; - SKP_float w[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], regu; - SKP_float Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ]; - const SKP_float *r_ptr, *lag_ptr; - - b_ptr = b; - WLTP_ptr = WLTP; - r_ptr = &r_lpc[ mem_offset ]; - for( k = 0; k < nb_subfr; k++ ) { - lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); - - SKP_Silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, WLTP_ptr ); - SKP_Silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr ); - - rr[ k ] = ( SKP_float )SKP_Silk_energy_FLP( r_ptr, subfr_length ); - regu = 1.0f + rr[ k ] + - matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ) + - matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ); - regu *= LTP_DAMPING / 3; - SKP_Silk_regularize_correlations_FLP( WLTP_ptr, &rr[ k ], regu, LTP_ORDER ); - SKP_Silk_solve_LDL_FLP( WLTP_ptr, LTP_ORDER, Rr, b_ptr ); - - /* Calculate residual energy */ - nrg[ k ] = SKP_Silk_residual_energy_covar_FLP( b_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER ); - - temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); - SKP_Silk_scale_vector_FLP( WLTP_ptr, temp, LTP_ORDER * LTP_ORDER ); - w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER / 2, LTP_ORDER / 2, LTP_ORDER ); - - r_ptr += subfr_length; - b_ptr += LTP_ORDER; - WLTP_ptr += LTP_ORDER * LTP_ORDER; - } - - /* Compute LTP coding gain */ - if( LTPredCodGain != NULL ) { - LPC_LTP_res_nrg = 1e-6f; - LPC_res_nrg = 0.0f; - for( k = 0; k < nb_subfr; k++ ) { - LPC_res_nrg += rr[ k ] * Wght[ k ]; - LPC_LTP_res_nrg += nrg[ k ] * Wght[ k ]; - } - - SKP_assert( LPC_LTP_res_nrg > 0 ); - *LTPredCodGain = 3.0f * SKP_Silk_log2( LPC_res_nrg / LPC_LTP_res_nrg ); - } - - /* Smoothing */ - /* d = sum( B, 1 ); */ - b_ptr = b; - for( k = 0; k < nb_subfr; k++ ) { - d[ k ] = 0; - for( i = 0; i < LTP_ORDER; i++ ) { - d[ k ] += b_ptr[ i ]; - } - b_ptr += LTP_ORDER; - } - /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */ - temp = 1e-3f; - for( k = 0; k < nb_subfr; k++ ) { - temp += w[ k ]; - } - m = 0; - for( k = 0; k < nb_subfr; k++ ) { - m += d[ k ] * w[ k ]; - } - m = m / temp; - - b_ptr = b; - for( k = 0; k < nb_subfr; k++ ) { - g = LTP_SMOOTHING / ( LTP_SMOOTHING + w[ k ] ) * ( m - d[ k ] ); - temp = 0; - for( i = 0; i < LTP_ORDER; i++ ) { - delta_b[ i ] = SKP_max_float( b_ptr[ i ], 0.1f ); - temp += delta_b[ i ]; - } - temp = g / temp; - for( i = 0; i < LTP_ORDER; i++ ) { - b_ptr[ i ] = b_ptr[ i ] + delta_b[ i ] * temp; - } - b_ptr += LTP_ORDER; - } -} diff --git a/silk/SKP_Silk_find_pitch_lags_FIX.c b/silk/SKP_Silk_find_pitch_lags_FIX.c deleted file mode 100644 index bfc3e36b..00000000 --- a/silk/SKP_Silk_find_pitch_lags_FIX.c +++ /dev/null @@ -1,133 +0,0 @@ -/*********************************************************************** -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" -#include "SKP_Silk_tuning_parameters.h" - -/* Find pitch lags */ -void SKP_Silk_find_pitch_lags_FIX( - SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */ - SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ - SKP_int16 res[], /* O residual */ - const SKP_int16 x[] /* I Speech signal */ -) -{ - SKP_int buf_len, i, scale; - SKP_int32 thrhld_Q15, res_nrg; - const SKP_int16 *x_buf, *x_buf_ptr; - SKP_int16 Wsig[ FIND_PITCH_LPC_WIN_MAX ], *Wsig_ptr; - SKP_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; - SKP_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ]; - SKP_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ]; - SKP_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ]; - - /******************************************/ - /* Setup buffer lengths etc based on Fs */ - /******************************************/ - buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; - - /* Safty check */ - SKP_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); - - x_buf = x - psEnc->sCmn.ltp_mem_length; - - /*************************************/ - /* Estimate LPC AR coefficients */ - /*************************************/ - - /* Calculate windowed signal */ - - /* First LA_LTP samples */ - x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length; - Wsig_ptr = Wsig; - SKP_Silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch ); - - /* Middle un - windowed samples */ - Wsig_ptr += psEnc->sCmn.la_pitch; - x_buf_ptr += psEnc->sCmn.la_pitch; - SKP_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( SKP_int16 ) ); - - /* Last LA_LTP samples */ - Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ); - x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ); - SKP_Silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch ); - - /* Calculate autocorrelation sequence */ - SKP_Silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 ); - - /* Add white noise, as fraction of energy */ - auto_corr[ 0 ] = SKP_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SKP_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1; - - /* Calculate the reflection coefficients using schur */ - res_nrg = SKP_Silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); - - /* Prediction gain */ - psEncCtrl->predGain_Q16 = SKP_DIV32_varQ( auto_corr[ 0 ], SKP_max_int( res_nrg, 1 ), 16 ); - - /* Convert reflection coefficients to prediction coefficients */ - SKP_Silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder ); - - /* Convert From 32 bit Q24 to 16 bit Q12 coefs */ - for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) { - A_Q12[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT( A_Q24[ i ], 12 ) ); - } - - /* Do BWE */ - SKP_Silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SKP_FIX_CONST( FIND_PITCH_BANDWITH_EXPANSION, 16 ) ); - - /*****************************************/ - /* LPC analysis filtering */ - /*****************************************/ - SKP_Silk_LPC_analysis_filter( res, x_buf, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder ); - - if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { - /* Threshold for pitch estimator */ - thrhld_Q15 = SKP_FIX_CONST( 0.6, 15 ); - thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( -0.004, 15 ), psEnc->sCmn.pitchEstimationLPCOrder ); - thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( -0.1, 7 ), psEnc->sCmn.speech_activity_Q8 ); - thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( -0.15, 15 ), SKP_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) ); - thrhld_Q15 = SKP_SMLAWB( thrhld_Q15, SKP_FIX_CONST( -0.1, 16 ), psEnc->sCmn.input_tilt_Q15 ); - thrhld_Q15 = SKP_SAT16( thrhld_Q15 ); - - /*****************************************/ - /* Call pitch estimator */ - /*****************************************/ - if( SKP_Silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex, - &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16, - ( SKP_int16 )thrhld_Q15, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 ) - { - psEnc->sCmn.indices.signalType = TYPE_VOICED; - } else { - psEnc->sCmn.indices.signalType = TYPE_UNVOICED; - } - } else { - SKP_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); - psEnc->sCmn.indices.lagIndex = 0; - psEnc->sCmn.indices.contourIndex = 0; - psEnc->LTPCorr_Q15 = 0; - } -} diff --git a/silk/SKP_Silk_find_pitch_lags_FLP.c b/silk/SKP_Silk_find_pitch_lags_FLP.c deleted file mode 100644 index c8de0e26..00000000 --- a/silk/SKP_Silk_find_pitch_lags_FLP.c +++ /dev/null @@ -1,127 +0,0 @@ -/*********************************************************************** -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 -#include "SKP_Silk_main_FLP.h" -#include "SKP_Silk_tuning_parameters.h" - -void SKP_Silk_find_pitch_lags_FLP( - SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - SKP_float res[], /* O Residual */ - const SKP_float x[] /* I Speech signal */ -) -{ - SKP_int buf_len; - SKP_float thrhld, res_nrg; - const SKP_float *x_buf_ptr, *x_buf; - SKP_float auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; - SKP_float A[ MAX_FIND_PITCH_LPC_ORDER ]; - SKP_float refl_coef[ MAX_FIND_PITCH_LPC_ORDER ]; - SKP_float Wsig[ FIND_PITCH_LPC_WIN_MAX ]; - SKP_float *Wsig_ptr; - - /******************************************/ - /* Setup buffer lengths etc based on Fs */ - /******************************************/ - buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; - - /* Safty check */ - SKP_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); - - x_buf = x - psEnc->sCmn.ltp_mem_length; - - /******************************************/ - /* Estimate LPC AR coeficients */ - /******************************************/ - - /* Calculate windowed signal */ - - /* First LA_LTP samples */ - x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length; - Wsig_ptr = Wsig; - SKP_Silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch ); - - /* Middle non-windowed samples */ - Wsig_ptr += psEnc->sCmn.la_pitch; - x_buf_ptr += psEnc->sCmn.la_pitch; - SKP_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ) ) * sizeof( SKP_float ) ); - - /* Last LA_LTP samples */ - Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ); - x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ); - SKP_Silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch ); - - /* Calculate autocorrelation sequence */ - SKP_Silk_autocorrelation_FLP( auto_corr, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 ); - - /* Add white noise, as a fraction of the energy */ - auto_corr[ 0 ] += auto_corr[ 0 ] * FIND_PITCH_WHITE_NOISE_FRACTION + 1; - - /* Calculate the reflection coefficients using Schur */ - res_nrg = SKP_Silk_schur_FLP( refl_coef, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); - - /* Prediction gain */ - psEncCtrl->predGain = auto_corr[ 0 ] / SKP_max_float( res_nrg, 1.0f ); - - /* Convert reflection coefficients to prediction coefficients */ - SKP_Silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder ); - - /* Bandwidth expansion */ - SKP_Silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWITH_EXPANSION ); - - /*****************************************/ - /* LPC analysis filtering */ - /*****************************************/ - SKP_Silk_LPC_analysis_filter_FLP( res, A, x_buf, buf_len, psEnc->sCmn.pitchEstimationLPCOrder ); - - if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { - /* Threshold for pitch estimator */ - thrhld = 0.6f; - thrhld -= 0.004f * psEnc->sCmn.pitchEstimationLPCOrder; - thrhld -= 0.1f * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); - thrhld -= 0.15f * (psEnc->sCmn.prevSignalType >> 1); - thrhld -= 0.1f * psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ); - - /*****************************************/ - /* Call Pitch estimator */ - /*****************************************/ - if( SKP_Silk_pitch_analysis_core_FLP( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, - &psEnc->sCmn.indices.contourIndex, &psEnc->LTPCorr, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16 / 65536.0f, - thrhld, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 ) - { - psEnc->sCmn.indices.signalType = TYPE_VOICED; - } else { - psEnc->sCmn.indices.signalType = TYPE_UNVOICED; - } - } else { - SKP_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); - psEnc->sCmn.indices.lagIndex = 0; - psEnc->sCmn.indices.contourIndex = 0; - psEnc->LTPCorr = 0; - } -} diff --git a/silk/SKP_Silk_find_pred_coefs_FIX.c b/silk/SKP_Silk_find_pred_coefs_FIX.c deleted file mode 100644 index 532a695b..00000000 --- a/silk/SKP_Silk_find_pred_coefs_FIX.c +++ /dev/null @@ -1,127 +0,0 @@ -/*********************************************************************** -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" - -void SKP_Silk_find_pred_coefs_FIX( - SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */ - SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ - const SKP_int16 res_pitch[], /* I Residual from pitch analysis */ - const SKP_int16 x[] /* I Speech signal */ -) -{ - SKP_int i; - SKP_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; - SKP_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ]; - SKP_int16 NLSF_Q15[ MAX_LPC_ORDER ]; - const SKP_int16 *x_ptr; - SKP_int16 *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; - SKP_int32 tmp, min_gain_Q16; - SKP_int LTP_corrs_rshift[ MAX_NB_SUBFR ]; - - /* weighting for weighted least squares */ - min_gain_Q16 = SKP_int32_MAX >> 6; - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - min_gain_Q16 = SKP_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] ); - } - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - /* Divide to Q16 */ - SKP_assert( psEncCtrl->Gains_Q16[ i ] > 0 ); - /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */ - invGains_Q16[ i ] = SKP_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 ); - - /* Ensure Wght_Q15 a minimum value 1 */ - invGains_Q16[ i ] = SKP_max( invGains_Q16[ i ], 363 ); - - /* Square the inverted gains */ - SKP_assert( invGains_Q16[ i ] == SKP_SAT16( invGains_Q16[ i ] ) ); - tmp = SKP_SMULWB( invGains_Q16[ i ], invGains_Q16[ i ] ); - Wght_Q15[ i ] = SKP_RSHIFT( tmp, 1 ); - - /* Invert the inverted and normalized gains */ - local_gains[ i ] = SKP_DIV32( ( 1 << 16 ), invGains_Q16[ i ] ); - } - - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /**********/ - /* VOICED */ - /**********/ - SKP_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); - - /* LTP analysis */ - SKP_Silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7, - res_pitch, psEncCtrl->pitchL, Wght_Q15, psEnc->sCmn.subfr_length, - psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length, LTP_corrs_rshift ); - - /* Quantize LTP gain parameters */ - SKP_Silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, - WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr); - - /* Control LTP scaling */ - SKP_Silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl ); - - /* Create LTP residual */ - SKP_Silk_LTP_analysis_filter_FIX( LPC_in_pre, psEnc->x_buf + psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder, - psEncCtrl->LTPCoef_Q14, psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); - - } else { - /************/ - /* UNVOICED */ - /************/ - /* Create signal with prepended subframes, scaled by inverse gains */ - x_ptr = x - psEnc->sCmn.predictLPCOrder; - x_pre_ptr = LPC_in_pre; - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - SKP_Silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ], - psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); - x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; - x_ptr += psEnc->sCmn.subfr_length; - } - - SKP_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_int16 ) ); - psEncCtrl->LTPredCodGain_Q7 = 0; - } - - /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ - TIC(FIND_LPC) - SKP_Silk_find_LPC_FIX( NLSF_Q15, &psEnc->sCmn.indices.NLSFInterpCoef_Q2, psEnc->sCmn.prev_NLSFq_Q15, - psEnc->sCmn.useInterpolatedNLSFs, psEnc->sCmn.first_frame_after_reset, psEnc->sCmn.predictLPCOrder, - LPC_in_pre, psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder, psEnc->sCmn.nb_subfr ); - TOC(FIND_LPC) - - /* Quantize LSFs */ - TIC(PROCESS_LSFS) - SKP_Silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); - TOC(PROCESS_LSFS) - - /* Calculate residual energy using quantized LPC coefficients */ - SKP_Silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains, - psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); - - /* Copy to prediction struct for use in next frame for fluctuation reduction */ - SKP_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); -} diff --git a/silk/SKP_Silk_find_pred_coefs_FLP.c b/silk/SKP_Silk_find_pred_coefs_FLP.c deleted file mode 100644 index 00b1cead..00000000 --- a/silk/SKP_Silk_find_pred_coefs_FLP.c +++ /dev/null @@ -1,114 +0,0 @@ -/*********************************************************************** -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_FLP.h" - - -void SKP_Silk_find_pred_coefs_FLP( - SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - const SKP_float res_pitch[], /* I Residual from pitch analysis */ - const SKP_float x[] /* I Speech signal */ -) -{ - SKP_int i; - SKP_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; - SKP_float invGains[ MAX_NB_SUBFR ], Wght[ MAX_NB_SUBFR ]; - SKP_int16 NLSF_Q15[ MAX_LPC_ORDER ]; - const SKP_float *x_ptr; - SKP_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; - - /* Weighting for weighted least squares */ - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - SKP_assert( psEncCtrl->Gains[ i ] > 0.0f ); - invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ]; - Wght[ i ] = invGains[ i ] * invGains[ i ]; - } - - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /**********/ - /* VOICED */ - /**********/ - SKP_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); - - /* LTP analysis */ - SKP_Silk_find_LTP_FLP( psEncCtrl->LTPCoef, WLTP, &psEncCtrl->LTPredCodGain, res_pitch, - psEncCtrl->pitchL, Wght, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length ); - -#ifdef SAVE_ALL_INTERNAL_DATA - DEBUG_STORE_DATA( ltp_gains.dat, psEncCtrl->LTPCoef, sizeof( psEncCtrl->LTPCoef ) ); - DEBUG_STORE_DATA( ltp_weights.dat, WLTP, sizeof( WLTP ) ); -#endif - - /* Quantize LTP gain parameters */ - SKP_Silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, - WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity , psEnc->sCmn.nb_subfr ); - - /* Control LTP scaling */ - SKP_Silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl ); - - /* Create LTP residual */ - SKP_Silk_LTP_analysis_filter_FLP( LPC_in_pre, psEnc->x_buf + psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder, - psEncCtrl->LTPCoef, psEncCtrl->pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); - - } else { - /************/ - /* UNVOICED */ - /************/ - /* Create signal with prepended subframes, scaled by inverse gains */ - x_ptr = x - psEnc->sCmn.predictLPCOrder; - x_pre_ptr = LPC_in_pre; - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - SKP_Silk_scale_copy_vector_FLP( x_pre_ptr, x_ptr, invGains[ i ], - psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); - x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; - x_ptr += psEnc->sCmn.subfr_length; - } - - SKP_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) ); - psEncCtrl->LTPredCodGain = 0.0f; - } - - /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ - SKP_Silk_find_LPC_FLP( NLSF_Q15, &psEnc->sCmn.indices.NLSFInterpCoef_Q2, psEnc->sCmn.prev_NLSFq_Q15, - psEnc->sCmn.useInterpolatedNLSFs, psEnc->sCmn.first_frame_after_reset, psEnc->sCmn.predictLPCOrder, - LPC_in_pre, psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder, psEnc->sCmn.nb_subfr ); - - - /* Quantize LSFs */ -TIC(LSF_quant); - SKP_Silk_process_NLSFs_FLP( &psEnc->sCmn, psEncCtrl->PredCoef, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); -TOC(LSF_quant); - - /* Calculate residual energy using quantized LPC coefficients */ - SKP_Silk_residual_energy_FLP( psEncCtrl->ResNrg, LPC_in_pre, psEncCtrl->PredCoef, psEncCtrl->Gains, - psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); - - /* Copy to prediction struct for use in next frame for fluctuation reduction */ - SKP_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); -} - diff --git a/silk/SKP_Silk_noise_shape_analysis_FIX.c b/silk/SKP_Silk_noise_shape_analysis_FIX.c deleted file mode 100644 index b8d804c9..00000000 --- a/silk/SKP_Silk_noise_shape_analysis_FIX.c +++ /dev/null @@ -1,433 +0,0 @@ -/*********************************************************************** -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" -#include "SKP_Silk_tuning_parameters.h" - -/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ -/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ -SKP_INLINE SKP_int32 warped_gain( // gain in Q16 - const SKP_int32 *coefs_Q24, - SKP_int lambda_Q16, - SKP_int order -) { - SKP_int i; - SKP_int32 gain_Q24; - - lambda_Q16 = -lambda_Q16; - gain_Q24 = coefs_Q24[ order - 1 ]; - for( i = order - 2; i >= 0; i-- ) { - gain_Q24 = SKP_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 ); - } - gain_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 ); - return SKP_INVERSE32_varQ( gain_Q24, 40 ); -} - -/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ -/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ -SKP_INLINE void limit_warped_coefs( - SKP_int32 *coefs_syn_Q24, - SKP_int32 *coefs_ana_Q24, - SKP_int lambda_Q16, - SKP_int32 limit_Q24, - SKP_int order -) { - SKP_int i, iter, ind = 0; - SKP_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16; - SKP_int32 nom_Q16, den_Q24; - - /* Convert to monic coefficients */ - lambda_Q16 = -lambda_Q16; - for( i = order - 1; i > 0; i-- ) { - coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); - coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); - } - lambda_Q16 = -lambda_Q16; - nom_Q16 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 16 ), -lambda_Q16, lambda_Q16 ); - den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); - gain_syn_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); - den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); - gain_ana_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); - for( i = 0; i < order; i++ ) { - coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); - coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); - } - - for( iter = 0; iter < 10; iter++ ) { - /* Find maximum absolute value */ - maxabs_Q24 = -1; - for( i = 0; i < order; i++ ) { - tmp = SKP_max( SKP_abs_int32( coefs_syn_Q24[ i ] ), SKP_abs_int32( coefs_ana_Q24[ i ] ) ); - if( tmp > maxabs_Q24 ) { - maxabs_Q24 = tmp; - ind = i; - } - } - if( maxabs_Q24 <= limit_Q24 ) { - /* Coefficients are within range - done */ - return; - } - - /* Convert back to true warped coefficients */ - for( i = 1; i < order; i++ ) { - coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); - coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); - } - gain_syn_Q16 = SKP_INVERSE32_varQ( gain_syn_Q16, 32 ); - gain_ana_Q16 = SKP_INVERSE32_varQ( gain_ana_Q16, 32 ); - for( i = 0; i < order; i++ ) { - coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); - coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); - } - - /* Apply bandwidth expansion */ - chirp_Q16 = SKP_FIX_CONST( 0.99, 16 ) - SKP_DIV32_varQ( - SKP_SMULWB( maxabs_Q24 - limit_Q24, SKP_SMLABB( SKP_FIX_CONST( 0.8, 10 ), SKP_FIX_CONST( 0.1, 10 ), iter ) ), - SKP_MUL( maxabs_Q24, ind + 1 ), 22 ); - SKP_Silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 ); - SKP_Silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 ); - - /* Convert to monic warped coefficients */ - lambda_Q16 = -lambda_Q16; - for( i = order - 1; i > 0; i-- ) { - coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); - coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); - } - lambda_Q16 = -lambda_Q16; - nom_Q16 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 16 ), -lambda_Q16, lambda_Q16 ); - den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); - gain_syn_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); - den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); - gain_ana_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); - for( i = 0; i < order; i++ ) { - coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); - coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); - } - } - SKP_assert( 0 ); -} - -/**************************************************************/ -/* Compute noise shaping coefficients and initial gain values */ -/**************************************************************/ -void SKP_Silk_noise_shape_analysis_FIX( - SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ - SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ - const SKP_int16 *pitch_res, /* I LPC residual from pitch analysis */ - const SKP_int16 *x /* I Input signal [ frame_length + la_shape ] */ -) -{ - SKP_Silk_shape_state_FIX *psShapeSt = &psEnc->sShape; - SKP_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0; - SKP_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32; - SKP_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7; - SKP_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8; - SKP_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; - SKP_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ]; - SKP_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ]; - SKP_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ]; - SKP_int16 x_windowed[ SHAPE_LPC_WIN_MAX ]; - SKP_int32 sqrt_nrg[ MAX_NB_SUBFR ], Qnrg_vec[ MAX_NB_SUBFR ]; - const SKP_int16 *x_ptr, *pitch_res_ptr; - - /* Point to start of first LPC analysis block */ - x_ptr = x - psEnc->sCmn.la_shape; - - /****************/ - /* GAIN CONTROL */ - /****************/ - SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7; - - /* Input quality is the average of the quality in the lowest two VAD bands */ - psEncCtrl->input_quality_Q14 = ( SKP_int )SKP_RSHIFT( ( SKP_int32 )psEnc->sCmn.input_quality_bands_Q15[ 0 ] - + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 ); - - /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */ - psEncCtrl->coding_quality_Q14 = SKP_RSHIFT( SKP_Silk_sigm_Q15( SKP_RSHIFT_ROUND( SNR_adj_dB_Q7 - - SKP_FIX_CONST( 18.0, 7 ), 4 ) ), 1 ); - - /* Reduce coding SNR during low speech activity */ - if( psEnc->sCmn.useCBR == 0 ) { - b_Q8 = SKP_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8; - b_Q8 = SKP_SMULWB( SKP_LSHIFT( b_Q8, 8 ), b_Q8 ); - SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, - SKP_SMULBB( SKP_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), // Q11 - SKP_SMULWB( SKP_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); // Q12 - } - - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Reduce gains for periodic signals */ - SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SKP_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 ); - } else { - /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ - SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, - SKP_SMLAWB( SKP_FIX_CONST( 6.0, 9 ), -SKP_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ), - SKP_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 ); - } - - /*************************/ - /* SPARSENESS PROCESSING */ - /*************************/ - /* Set quantizer offset */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Initally set to 0; may be overruled in process_gains(..) */ - psEnc->sCmn.indices.quantOffsetType = 0; - psEncCtrl->sparseness_Q8 = 0; - } else { - /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ - nSamples = SKP_LSHIFT( psEnc->sCmn.fs_kHz, 1 ); - energy_variation_Q7 = 0; - log_energy_prev_Q7 = 0; - pitch_res_ptr = pitch_res; - for( k = 0; k < SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) { - SKP_Silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples ); - nrg += SKP_RSHIFT( nSamples, scale ); // Q(-scale) - - log_energy_Q7 = SKP_Silk_lin2log( nrg ); - if( k > 0 ) { - energy_variation_Q7 += SKP_abs( log_energy_Q7 - log_energy_prev_Q7 ); - } - log_energy_prev_Q7 = log_energy_Q7; - pitch_res_ptr += nSamples; - } - - psEncCtrl->sparseness_Q8 = SKP_RSHIFT( SKP_Silk_sigm_Q15( SKP_SMULWB( energy_variation_Q7 - - SKP_FIX_CONST( 5.0, 7 ), SKP_FIX_CONST( 0.1, 16 ) ) ), 7 ); - - /* Set quantization offset depending on sparseness measure */ - if( psEncCtrl->sparseness_Q8 > SKP_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) { - psEnc->sCmn.indices.quantOffsetType = 0; - } else { - psEnc->sCmn.indices.quantOffsetType = 1; - } - - /* Increase coding SNR for sparse signals */ - SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SKP_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SKP_FIX_CONST( 0.5, 8 ) ); - } - - /*******************************/ - /* Control bandwidth expansion */ - /*******************************/ - /* More BWE for signals with high prediction gain */ - strength_Q16 = SKP_SMULWB( psEncCtrl->predGain_Q16, SKP_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ); - BWExp1_Q16 = BWExp2_Q16 = SKP_DIV32_varQ( SKP_FIX_CONST( BANDWIDTH_EXPANSION, 16 ), - SKP_SMLAWW( SKP_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 ); - delta_Q16 = SKP_SMULWB( SKP_FIX_CONST( 1.0, 16 ) - SKP_SMULBB( 3, psEncCtrl->coding_quality_Q14 ), - SKP_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) ); - BWExp1_Q16 = SKP_SUB32( BWExp1_Q16, delta_Q16 ); - BWExp2_Q16 = SKP_ADD32( BWExp2_Q16, delta_Q16 ); - /* BWExp1 will be applied after BWExp2, so make it relative */ - BWExp1_Q16 = SKP_DIV32_16( SKP_LSHIFT( BWExp1_Q16, 14 ), SKP_RSHIFT( BWExp2_Q16, 2 ) ); - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ - warping_Q16 = SKP_SMLAWB( psEnc->sCmn.warping_Q16, psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( 0.01, 18 ) ); - } else { - warping_Q16 = 0; - } - - /********************************************/ - /* Compute noise shaping AR coefs and gains */ - /********************************************/ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Apply window: sine slope followed by flat part followed by cosine slope */ - SKP_int shift, slope_part, flat_part; - flat_part = psEnc->sCmn.fs_kHz * 3; - slope_part = SKP_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 ); - - SKP_Silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part ); - shift = slope_part; - SKP_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(SKP_int16) ); - shift += flat_part; - SKP_Silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part ); - - /* Update pointer: next LPC analysis block */ - x_ptr += psEnc->sCmn.subfr_length; - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Calculate warped auto correlation */ - SKP_Silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); - } else { - /* Calculate regular auto correlation */ - SKP_Silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 ); - } - - /* Add white noise, as a fraction of energy */ - auto_corr[0] = SKP_ADD32( auto_corr[0], SKP_max_32( SKP_SMULWB( SKP_RSHIFT( auto_corr[ 0 ], 4 ), - SKP_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) ); - - /* Calculate the reflection coefficients using schur */ - nrg = SKP_Silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder ); - SKP_assert( nrg >= 0 ); - - /* Convert reflection coefficients to prediction coefficients */ - SKP_Silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder ); - - Qnrg = -scale; // range: -12...30 - SKP_assert( Qnrg >= -12 ); - SKP_assert( Qnrg <= 30 ); - - /* Make sure that Qnrg is an even number */ - if( Qnrg & 1 ) { - Qnrg -= 1; - nrg >>= 1; - } - - tmp32 = SKP_Silk_SQRT_APPROX( nrg ); - Qnrg >>= 1; // range: -6...15 - - sqrt_nrg[ k ] = tmp32; - Qnrg_vec[ k ] = Qnrg; - - psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( tmp32, 16 - Qnrg ); - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Adjust gain for warping */ - gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder ); - psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); - } - - /* Bandwidth expansion for synthesis filter shaping */ - SKP_Silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 ); - - /* Compute noise shaping filter coefficients */ - SKP_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( SKP_int32 ) ); - - /* Bandwidth expansion for analysis filter shaping */ - SKP_assert( BWExp1_Q16 <= SKP_FIX_CONST( 1.0, 16 ) ); - SKP_Silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 ); - - /* Ratio of prediction gains, in energy domain */ - SKP_Silk_LPC_inverse_pred_gain_Q24( &pre_nrg_Q30, AR2_Q24, psEnc->sCmn.shapingLPCOrder ); - SKP_Silk_LPC_inverse_pred_gain_Q24( &nrg, AR1_Q24, psEnc->sCmn.shapingLPCOrder ); - - //psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg; - pre_nrg_Q30 = SKP_LSHIFT32( SKP_SMULWB( pre_nrg_Q30, SKP_FIX_CONST( 0.7, 15 ) ), 1 ); - psEncCtrl->GainsPre_Q14[ k ] = ( SKP_int ) SKP_FIX_CONST( 0.3, 14 ) + SKP_DIV32_varQ( pre_nrg_Q30, nrg, 14 ); - - /* Convert to monic warped prediction coefficients and limit absolute values */ - limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SKP_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder ); - - /* Convert from Q24 to Q13 and store in int16 */ - for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) { - psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) ); - psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) ); - } - } - - /*****************/ - /* Gain tweaking */ - /*****************/ - /* Increase gains during low speech activity and put lower limit on gains */ - gain_mult_Q16 = SKP_Silk_log2lin( -SKP_SMLAWB( -SKP_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SKP_FIX_CONST( 0.16, 16 ) ) ); - gain_add_Q16 = SKP_Silk_log2lin( SKP_SMLAWB( SKP_FIX_CONST( 16.0, 7 ), SKP_FIX_CONST( MIN_QGAIN_DB, 7 ), SKP_FIX_CONST( 0.16, 16 ) ) ); - SKP_assert( gain_mult_Q16 > 0 ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); - SKP_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); - psEncCtrl->Gains_Q16[ k ] = SKP_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 ); - } - - gain_mult_Q16 = SKP_FIX_CONST( 1.0, 16 ) + SKP_RSHIFT_ROUND( SKP_MLA( SKP_FIX_CONST( INPUT_TILT, 26 ), - psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->GainsPre_Q14[ k ] = SKP_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] ); - } - - /************************************************/ - /* Control low-frequency shaping and noise tilt */ - /************************************************/ - /* Less low frequency shaping for noisy inputs */ - strength_Q16 = SKP_MUL( SKP_FIX_CONST( LOW_FREQ_SHAPING, 4 ), SKP_SMLAWB( SKP_FIX_CONST( 1.0, 12 ), - SKP_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SKP_FIX_CONST( 1.0, 15 ) ) ); - strength_Q16 = SKP_RSHIFT( SKP_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 ); - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ - /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ - SKP_int fs_kHz_inv = SKP_DIV32_16( SKP_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - b_Q14 = fs_kHz_inv + SKP_DIV32_16( SKP_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] ); - /* Pack two coefficients in one int32 */ - psEncCtrl->LF_shp_Q14[ k ] = SKP_LSHIFT( SKP_FIX_CONST( 1.0, 14 ) - b_Q14 - SKP_SMULWB( strength_Q16, b_Q14 ), 16 ); - psEncCtrl->LF_shp_Q14[ k ] |= (SKP_uint16)( b_Q14 - SKP_FIX_CONST( 1.0, 14 ) ); - } - SKP_assert( SKP_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SKP_FIX_CONST( 0.5, 24 ) ); // Guarantees that second argument to SMULWB() is within range of an SKP_int16 - Tilt_Q16 = - SKP_FIX_CONST( HP_NOISE_COEF, 16 ) - - SKP_SMULWB( SKP_FIX_CONST( 1.0, 16 ) - SKP_FIX_CONST( HP_NOISE_COEF, 16 ), - SKP_SMULWB( SKP_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) ); - } else { - b_Q14 = SKP_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); // 1.3_Q0 = 21299_Q14 - /* Pack two coefficients in one int32 */ - psEncCtrl->LF_shp_Q14[ 0 ] = SKP_LSHIFT( SKP_FIX_CONST( 1.0, 14 ) - b_Q14 - - SKP_SMULWB( strength_Q16, SKP_SMULWB( SKP_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 ); - psEncCtrl->LF_shp_Q14[ 0 ] |= (SKP_uint16)( b_Q14 - SKP_FIX_CONST( 1.0, 14 ) ); - for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ]; - } - Tilt_Q16 = -SKP_FIX_CONST( HP_NOISE_COEF, 16 ); - } - - /****************************/ - /* HARMONIC SHAPING CONTROL */ - /****************************/ - /* Control boosting of harmonic frequencies */ - HarmBoost_Q16 = SKP_SMULWB( SKP_SMULWB( SKP_FIX_CONST( 1.0, 17 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ), - psEnc->LTPCorr_Q15 ), SKP_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) ); - - /* More harmonic boost for noisy input signals */ - HarmBoost_Q16 = SKP_SMLAWB( HarmBoost_Q16, - SKP_FIX_CONST( 1.0, 16 ) - SKP_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SKP_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) ); - - if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* More harmonic noise shaping for high bitrates or noisy input */ - HarmShapeGain_Q16 = SKP_SMLAWB( SKP_FIX_CONST( HARMONIC_SHAPING, 16 ), - SKP_FIX_CONST( 1.0, 16 ) - SKP_SMULWB( SKP_FIX_CONST( 1.0, 18 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ), - psEncCtrl->input_quality_Q14 ), SKP_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) ); - - /* Less harmonic noise shaping for less periodic signals */ - HarmShapeGain_Q16 = SKP_SMULWB( SKP_LSHIFT( HarmShapeGain_Q16, 1 ), - SKP_Silk_SQRT_APPROX( SKP_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) ); - } else { - HarmShapeGain_Q16 = 0; - } - - /*************************/ - /* Smooth over subframes */ - /*************************/ - for( k = 0; k < MAX_NB_SUBFR; k++ ) { - psShapeSt->HarmBoost_smth_Q16 = - SKP_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SKP_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); - psShapeSt->HarmShapeGain_smth_Q16 = - SKP_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SKP_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); - psShapeSt->Tilt_smth_Q16 = - SKP_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SKP_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); - - psEncCtrl->HarmBoost_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 ); - psEncCtrl->HarmShapeGain_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 ); - psEncCtrl->Tilt_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 ); - } -} diff --git a/silk/SKP_Silk_noise_shape_analysis_FLP.c b/silk/SKP_Silk_noise_shape_analysis_FLP.c deleted file mode 100644 index 05f98fa8..00000000 --- a/silk/SKP_Silk_noise_shape_analysis_FLP.c +++ /dev/null @@ -1,359 +0,0 @@ -/*********************************************************************** -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_FLP.h" -#include "SKP_Silk_tuning_parameters.h" - -/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ -/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ -SKP_INLINE SKP_float warped_gain( - const SKP_float *coefs, - SKP_float lambda, - SKP_int order -) { - SKP_int i; - SKP_float gain; - - lambda = -lambda; - gain = coefs[ order - 1 ]; - for( i = order - 2; i >= 0; i-- ) { - gain = lambda * gain + coefs[ i ]; - } - return (SKP_float)( 1.0f / ( 1.0f - lambda * gain ) ); -} - -/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ -/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ -SKP_INLINE void warped_true2monic_coefs( - SKP_float *coefs_syn, - SKP_float *coefs_ana, - SKP_float lambda, - SKP_float limit, - SKP_int order -) { - SKP_int i, iter, ind = 0; - SKP_float tmp, maxabs, chirp, gain_syn, gain_ana; - - /* Convert to monic coefficients */ - for( i = order - 1; i > 0; i-- ) { - coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ]; - coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ]; - } - gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] ); - gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] ); - for( i = 0; i < order; i++ ) { - coefs_syn[ i ] *= gain_syn; - coefs_ana[ i ] *= gain_ana; - } - - /* Limit */ - for( iter = 0; iter < 10; iter++ ) { - /* Find maximum absolute value */ - maxabs = -1.0f; - for( i = 0; i < order; i++ ) { - tmp = SKP_max( SKP_abs_float( coefs_syn[ i ] ), SKP_abs_float( coefs_ana[ i ] ) ); - if( tmp > maxabs ) { - maxabs = tmp; - ind = i; - } - } - if( maxabs <= limit ) { - /* Coefficients are within range - done */ - return; - } - - /* Convert back to true warped coefficients */ - for( i = 1; i < order; i++ ) { - coefs_syn[ i - 1 ] += lambda * coefs_syn[ i ]; - coefs_ana[ i - 1 ] += lambda * coefs_ana[ i ]; - } - gain_syn = 1.0f / gain_syn; - gain_ana = 1.0f / gain_ana; - for( i = 0; i < order; i++ ) { - coefs_syn[ i ] *= gain_syn; - coefs_ana[ i ] *= gain_ana; - } - - /* Apply bandwidth expansion */ - chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) ); - SKP_Silk_bwexpander_FLP( coefs_syn, order, chirp ); - SKP_Silk_bwexpander_FLP( coefs_ana, order, chirp ); - - /* Convert to monic warped coefficients */ - for( i = order - 1; i > 0; i-- ) { - coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ]; - coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ]; - } - gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] ); - gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] ); - for( i = 0; i < order; i++ ) { - coefs_syn[ i ] *= gain_syn; - coefs_ana[ i ] *= gain_ana; - } - } - SKP_assert( 0 ); -} - -/* Compute noise shaping coefficients and initial gain values */ -void SKP_Silk_noise_shape_analysis_FLP( - SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - const SKP_float *pitch_res, /* I LPC residual from pitch analysis */ - const SKP_float *x /* I Input signal [frame_length + la_shape] */ -) -{ - SKP_Silk_shape_state_FLP *psShapeSt = &psEnc->sShape; - SKP_int k, nSamples; - SKP_float SNR_adj_dB, HarmBoost, HarmShapeGain, Tilt; - SKP_float nrg, pre_nrg, log_energy, log_energy_prev, energy_variation; - SKP_float delta, BWExp1, BWExp2, gain_mult, gain_add, strength, b, warping; - SKP_float x_windowed[ SHAPE_LPC_WIN_MAX ]; - SKP_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; - const SKP_float *x_ptr, *pitch_res_ptr; - - /* Point to start of first LPC analysis block */ - x_ptr = x - psEnc->sCmn.la_shape; - - /****************/ - /* GAIN CONTROL */ - /****************/ - SNR_adj_dB = psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ); - - /* Input quality is the average of the quality in the lowest two VAD bands */ - psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f ); - - /* Coding quality level, between 0.0 and 1.0 */ - psEncCtrl->coding_quality = SKP_sigmoid( 0.25f * ( SNR_adj_dB - 18.0f ) ); - - if( psEnc->sCmn.useCBR == 0 ) { - /* Reduce coding SNR during low speech activity */ - b = 1.0f - psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); - SNR_adj_dB -= BG_SNR_DECR_dB * psEncCtrl->coding_quality * ( 0.5f + 0.5f * psEncCtrl->input_quality ) * b * b; - } - - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Reduce gains for periodic signals */ - SNR_adj_dB += HARM_SNR_INCR_dB * psEnc->LTPCorr; - } else { - /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ - SNR_adj_dB += ( -0.4f * psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) + 6.0f ) * ( 1.0f - psEncCtrl->input_quality ); - } - - /*************************/ - /* SPARSENESS PROCESSING */ - /*************************/ - /* Set quantizer offset */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Initally set to 0; may be overruled in process_gains(..) */ - psEnc->sCmn.indices.quantOffsetType = 0; - psEncCtrl->sparseness = 0.0f; - } else { - /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ - nSamples = 2 * psEnc->sCmn.fs_kHz; - energy_variation = 0.0f; - log_energy_prev = 0.0f; - pitch_res_ptr = pitch_res; - for( k = 0; k < SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) { - nrg = ( SKP_float )nSamples + ( SKP_float )SKP_Silk_energy_FLP( pitch_res_ptr, nSamples ); - log_energy = SKP_Silk_log2( nrg ); - if( k > 0 ) { - energy_variation += SKP_abs_float( log_energy - log_energy_prev ); - } - log_energy_prev = log_energy; - pitch_res_ptr += nSamples; - } - psEncCtrl->sparseness = SKP_sigmoid( 0.4f * ( energy_variation - 5.0f ) ); - - /* Set quantization offset depending on sparseness measure */ - if( psEncCtrl->sparseness > SPARSENESS_THRESHOLD_QNT_OFFSET ) { - psEnc->sCmn.indices.quantOffsetType = 0; - } else { - psEnc->sCmn.indices.quantOffsetType = 1; - } - - /* Increase coding SNR for sparse signals */ - SNR_adj_dB += SPARSE_SNR_INCR_dB * ( psEncCtrl->sparseness - 0.5f ); - } - - /*******************************/ - /* Control bandwidth expansion */ - /*******************************/ - /* More BWE for signals with high prediction gain */ - strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */ - BWExp1 = BWExp2 = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength ); - delta = LOW_RATE_BANDWIDTH_EXPANSION_DELTA * ( 1.0f - 0.75f * psEncCtrl->coding_quality ); - BWExp1 -= delta; - BWExp2 += delta; - /* BWExp1 will be applied after BWExp2, so make it relative */ - BWExp1 /= BWExp2; - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ - warping = (SKP_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality; - } else { - warping = 0.0f; - } - - /********************************************/ - /* Compute noise shaping AR coefs and gains */ - /********************************************/ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Apply window: sine slope followed by flat part followed by cosine slope */ - SKP_int shift, slope_part, flat_part; - flat_part = psEnc->sCmn.fs_kHz * 3; - slope_part = ( psEnc->sCmn.shapeWinLength - flat_part ) / 2; - - SKP_Silk_apply_sine_window_FLP( x_windowed, x_ptr, 1, slope_part ); - shift = slope_part; - SKP_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(SKP_float) ); - shift += flat_part; - SKP_Silk_apply_sine_window_FLP( x_windowed + shift, x_ptr + shift, 2, slope_part ); - - /* Update pointer: next LPC analysis block */ - x_ptr += psEnc->sCmn.subfr_length; - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Calculate warped auto correlation */ - SKP_Silk_warped_autocorrelation_FLP( auto_corr, x_windowed, warping, - psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); - } else { - /* Calculate regular auto correlation */ - SKP_Silk_autocorrelation_FLP( auto_corr, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 ); - } - - /* Add white noise, as a fraction of energy */ - auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION; - - /* Convert correlations to prediction coefficients, and compute residual energy */ - nrg = SKP_Silk_levinsondurbin_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], auto_corr, psEnc->sCmn.shapingLPCOrder ); - psEncCtrl->Gains[ k ] = ( SKP_float )sqrt( nrg ); - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Adjust gain for warping */ - psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder ); - } - - /* Bandwidth expansion for synthesis filter shaping */ - SKP_Silk_bwexpander_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp2 ); - - /* Compute noise shaping filter coefficients */ - SKP_memcpy( - &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], - &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], - psEnc->sCmn.shapingLPCOrder * sizeof( SKP_float ) ); - - /* Bandwidth expansion for analysis filter shaping */ - SKP_Silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 ); - - /* Ratio of prediction gains, in energy domain */ - SKP_Silk_LPC_inverse_pred_gain_FLP( &pre_nrg, &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder ); - SKP_Silk_LPC_inverse_pred_gain_FLP( &nrg, &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder ); - psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ); - - /* Convert to monic warped prediction coefficients and limit absolute values */ - warped_true2monic_coefs( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], - warping, 3.999f, psEnc->sCmn.shapingLPCOrder ); - } - - /*****************/ - /* Gain tweaking */ - /*****************/ - /* Increase gains during low speech activity */ - gain_mult = (SKP_float)pow( 2.0f, -0.16f * SNR_adj_dB ); - gain_add = (SKP_float)pow( 2.0f, 0.16f * MIN_QGAIN_DB ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains[ k ] *= gain_mult; - psEncCtrl->Gains[ k ] += gain_add; - } - - gain_mult = 1.0f + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT; - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->GainsPre[ k ] *= gain_mult; - } - - /************************************************/ - /* Control low-frequency shaping and noise tilt */ - /************************************************/ - /* Less low frequency shaping for noisy inputs */ - strength = LOW_FREQ_SHAPING * ( 1.0f + LOW_QUALITY_LOW_FREQ_SHAPING_DECR * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] * ( 1.0f / 32768.0f ) - 1.0f ) ); - strength *= psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ - /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - b = 0.2f / psEnc->sCmn.fs_kHz + 3.0f / psEncCtrl->pitchL[ k ]; - psEncCtrl->LF_MA_shp[ k ] = -1.0f + b; - psEncCtrl->LF_AR_shp[ k ] = 1.0f - b - b * strength; - } - Tilt = - HP_NOISE_COEF - - (1 - HP_NOISE_COEF) * HARM_HP_NOISE_COEF * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); - } else { - b = 1.3f / psEnc->sCmn.fs_kHz; - psEncCtrl->LF_MA_shp[ 0 ] = -1.0f + b; - psEncCtrl->LF_AR_shp[ 0 ] = 1.0f - b - b * strength * 0.6f; - for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->LF_MA_shp[ k ] = psEncCtrl->LF_MA_shp[ 0 ]; - psEncCtrl->LF_AR_shp[ k ] = psEncCtrl->LF_AR_shp[ 0 ]; - } - Tilt = -HP_NOISE_COEF; - } - - /****************************/ - /* HARMONIC SHAPING CONTROL */ - /****************************/ - /* Control boosting of harmonic frequencies */ - HarmBoost = LOW_RATE_HARMONIC_BOOST * ( 1.0f - psEncCtrl->coding_quality ) * psEnc->LTPCorr; - - /* More harmonic boost for noisy input signals */ - HarmBoost += LOW_INPUT_QUALITY_HARMONIC_BOOST * ( 1.0f - psEncCtrl->input_quality ); - - if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Harmonic noise shaping */ - HarmShapeGain = HARMONIC_SHAPING; - - /* More harmonic noise shaping for high bitrates or noisy input */ - HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING * - ( 1.0f - ( 1.0f - psEncCtrl->coding_quality ) * psEncCtrl->input_quality ); - - /* Less harmonic noise shaping for less periodic signals */ - HarmShapeGain *= ( SKP_float )sqrt( psEnc->LTPCorr ); - } else { - HarmShapeGain = 0.0f; - } - - /*************************/ - /* Smooth over subframes */ - /*************************/ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psShapeSt->HarmBoost_smth += SUBFR_SMTH_COEF * ( HarmBoost - psShapeSt->HarmBoost_smth ); - psEncCtrl->HarmBoost[ k ] = psShapeSt->HarmBoost_smth; - psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth ); - psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth; - psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth ); - psEncCtrl->Tilt[ k ] = psShapeSt->Tilt_smth; - } -} diff --git a/silk/SKP_Silk_prefilter_FIX.c b/silk/SKP_Silk_prefilter_FIX.c deleted file mode 100644 index 58be293f..00000000 --- a/silk/SKP_Silk_prefilter_FIX.c +++ /dev/null @@ -1,201 +0,0 @@ -/*********************************************************************** -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" -#include "SKP_Silk_tuning_parameters.h" - -/* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal */ -SKP_INLINE void SKP_Silk_prefilt_FIX( - SKP_Silk_prefilter_state_FIX *P, /* I/O state */ - SKP_int32 st_res_Q12[], /* I short term residual signal */ - SKP_int16 xw[], /* O prefiltered signal */ - SKP_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */ - SKP_int Tilt_Q14, /* I Tilt shaping coeficient */ - SKP_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients*/ - SKP_int lag, /* I Lag for harmonic shaping */ - SKP_int length /* I Length of signals */ -); - -void SKP_Silk_warped_LPC_analysis_filter_FIX( - SKP_int32 state[], /* I/O State [order + 1] */ - SKP_int16 res[], /* O Residual signal [length] */ - const SKP_int16 coef_Q13[], /* I Coefficients [order] */ - const SKP_int16 input[], /* I Input signal [length] */ - const SKP_int16 lambda_Q16, /* I Warping factor */ - const SKP_int length, /* I Length of input signal */ - const SKP_int order /* I Filter order (even) */ -) -{ - SKP_int n, i; - SKP_int32 acc_Q11, tmp1, tmp2; - - /* Order must be even */ - SKP_assert( ( order & 1 ) == 0 ); - - for( n = 0; n < length; n++ ) { - /* Output of lowpass section */ - tmp2 = SKP_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 ); - state[ 0 ] = SKP_LSHIFT( input[ n ], 14 ); - /* Output of allpass section */ - tmp1 = SKP_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 ); - state[ 1 ] = tmp2; - acc_Q11 = SKP_SMULWB( tmp2, coef_Q13[ 0 ] ); - /* Loop over allpass sections */ - for( i = 2; i < order; i += 2 ) { - /* Output of allpass section */ - tmp2 = SKP_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 ); - state[ i ] = tmp1; - acc_Q11 = SKP_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] ); - /* Output of allpass section */ - tmp1 = SKP_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 ); - state[ i + 1 ] = tmp2; - acc_Q11 = SKP_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] ); - } - state[ order ] = tmp1; - acc_Q11 = SKP_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] ); - res[ n ] = ( SKP_int16 )SKP_SAT16( ( SKP_int32 )input[ n ] - SKP_RSHIFT_ROUND( acc_Q11, 11 ) ); - } -} - -void SKP_Silk_prefilter_FIX( - SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ - const SKP_Silk_encoder_control_FIX *psEncCtrl, /* I Encoder control FIX */ - SKP_int16 xw[], /* O Weighted signal */ - const SKP_int16 x[] /* I Speech signal */ -) -{ - SKP_Silk_prefilter_state_FIX *P = &psEnc->sPrefilt; - SKP_int j, k, lag; - SKP_int32 tmp_32; - const SKP_int16 *AR1_shp_Q13; - const SKP_int16 *px; - SKP_int16 *pxw; - SKP_int HarmShapeGain_Q12, Tilt_Q14; - SKP_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14; - SKP_int32 x_filt_Q12[ MAX_FRAME_LENGTH / MAX_NB_SUBFR ]; - SKP_int16 st_res[ ( MAX_FRAME_LENGTH / MAX_NB_SUBFR ) + MAX_LPC_ORDER ]; - SKP_int16 B_Q12[ 2 ]; - - /* Setup pointers */ - px = x; - pxw = xw; - lag = P->lagPrev; - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Update Variables that change per sub frame */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - lag = psEncCtrl->pitchL[ k ]; - } - - /* Noise shape parameters */ - HarmShapeGain_Q12 = SKP_SMULWB( psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] ); - SKP_assert( HarmShapeGain_Q12 >= 0 ); - HarmShapeFIRPacked_Q12 = SKP_RSHIFT( HarmShapeGain_Q12, 2 ); - HarmShapeFIRPacked_Q12 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q12, 1 ), 16 ); - Tilt_Q14 = psEncCtrl->Tilt_Q14[ k ]; - LF_shp_Q14 = psEncCtrl->LF_shp_Q14[ k ]; - AR1_shp_Q13 = &psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER ]; - - /* Short term FIR filtering*/ - SKP_Silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res, AR1_shp_Q13, px, - psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder ); - - /* reduce (mainly) low frequencies during harmonic emphasis */ - B_Q12[ 0 ] = SKP_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 2 ); - tmp_32 = SKP_SMLABB( SKP_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 ); /* Q26 */ - tmp_32 = SKP_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ); /* Q26 */ - tmp_32 = SKP_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */ - tmp_32 = SKP_RSHIFT_ROUND( tmp_32, 12 ); /* Q12 */ - B_Q12[ 1 ]= SKP_SAT16( tmp_32 ); - - x_filt_Q12[ 0 ] = SKP_SMLABB( SKP_SMULBB( st_res[ 0 ], B_Q12[ 0 ] ), P->sHarmHP, B_Q12[ 1 ] ); - for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) { - x_filt_Q12[ j ] = SKP_SMLABB( SKP_SMULBB( st_res[ j ], B_Q12[ 0 ] ), st_res[ j - 1 ], B_Q12[ 1 ] ); - } - P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ]; - - SKP_Silk_prefilt_FIX( P, x_filt_Q12, pxw, HarmShapeFIRPacked_Q12, Tilt_Q14, - LF_shp_Q14, lag, psEnc->sCmn.subfr_length ); - - px += psEnc->sCmn.subfr_length; - pxw += psEnc->sCmn.subfr_length; - } - - P->lagPrev = psEncCtrl->pitchL[ MAX_NB_SUBFR - 1 ]; -} - -/* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal */ -SKP_INLINE void SKP_Silk_prefilt_FIX( - SKP_Silk_prefilter_state_FIX *P, /* I/O state */ - SKP_int32 st_res_Q12[], /* I short term residual signal */ - SKP_int16 xw[], /* O prefiltered signal */ - SKP_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */ - SKP_int Tilt_Q14, /* I Tilt shaping coeficient */ - SKP_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients*/ - SKP_int lag, /* I Lag for harmonic shaping */ - SKP_int length /* I Length of signals */ -) -{ - SKP_int i, idx, LTP_shp_buf_idx; - SKP_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10; - SKP_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12; - SKP_int16 *LTP_shp_buf; - - /* To speed up use temp variables instead of using the struct */ - LTP_shp_buf = P->sLTP_shp; - LTP_shp_buf_idx = P->sLTP_shp_buf_idx; - sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12; - sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12; - - for( i = 0; i < length; i++ ) { - if( lag > 0 ) { - /* unrolled loop */ - SKP_assert( HARM_SHAPE_FIR_TAPS == 3 ); - idx = lag + LTP_shp_buf_idx; - n_LTP_Q12 = SKP_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); - n_LTP_Q12 = SKP_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); - n_LTP_Q12 = SKP_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); - } else { - n_LTP_Q12 = 0; - } - - n_Tilt_Q10 = SKP_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 ); - n_LF_Q10 = SKP_SMLAWB( SKP_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 ); - - sLF_AR_shp_Q12 = SKP_SUB32( st_res_Q12[ i ], SKP_LSHIFT( n_Tilt_Q10, 2 ) ); - sLF_MA_shp_Q12 = SKP_SUB32( sLF_AR_shp_Q12, SKP_LSHIFT( n_LF_Q10, 2 ) ); - - LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK; - LTP_shp_buf[ LTP_shp_buf_idx ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) ); - - xw[i] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 12 ) ); - } - - /* Copy temp variable back to state */ - P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12; - P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12; - P->sLTP_shp_buf_idx = LTP_shp_buf_idx; -} diff --git a/silk/SKP_Silk_prefilter_FLP.c b/silk/SKP_Silk_prefilter_FLP.c deleted file mode 100644 index c3a23d15..00000000 --- a/silk/SKP_Silk_prefilter_FLP.c +++ /dev/null @@ -1,202 +0,0 @@ -/*********************************************************************** -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_FLP.h" -#include "SKP_Silk_tuning_parameters.h" - -/* -* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal -*/ -SKP_INLINE void SKP_Silk_prefilt_FLP( - SKP_Silk_prefilter_state_FLP *P,/* I/O state */ - SKP_float st_res[], /* I */ - SKP_float xw[], /* O */ - SKP_float *HarmShapeFIR, /* I */ - SKP_float Tilt, /* I */ - SKP_float LF_MA_shp, /* I */ - SKP_float LF_AR_shp, /* I */ - SKP_int lag, /* I */ - SKP_int length /* I */ -); - -void SKP_Silk_warped_LPC_analysis_filter_FLP( - SKP_float state[], /* I/O State [order + 1] */ - SKP_float res[], /* O Residual signal [length] */ - const SKP_float coef[], /* I Coefficients [order] */ - const SKP_float input[], /* I Input signal [length] */ - const SKP_float lambda, /* I Warping factor */ - const SKP_int length, /* I Length of input signal */ - const SKP_int order /* I Filter order (even) */ -) -{ - SKP_int n, i; - SKP_float acc, tmp1, tmp2; - - /* Order must be even */ - SKP_assert( ( order & 1 ) == 0 ); - - for( n = 0; n < length; n++ ) { - /* Output of lowpass section */ - tmp2 = state[ 0 ] + lambda * state[ 1 ]; - state[ 0 ] = input[ n ]; - /* Output of allpass section */ - tmp1 = state[ 1 ] + lambda * ( state[ 2 ] - tmp2 ); - state[ 1 ] = tmp2; - acc = coef[ 0 ] * tmp2; - /* Loop over allpass sections */ - for( i = 2; i < order; i += 2 ) { - /* Output of allpass section */ - tmp2 = state[ i ] + lambda * ( state[ i + 1 ] - tmp1 ); - state[ i ] = tmp1; - acc += coef[ i - 1 ] * tmp1; - /* Output of allpass section */ - tmp1 = state[ i + 1 ] + lambda * ( state[ i + 2 ] - tmp2 ); - state[ i + 1 ] = tmp2; - acc += coef[ i ] * tmp2; - } - state[ order ] = tmp1; - acc += coef[ order - 1 ] * tmp1; - res[ n ] = input[ n ] - acc; - } -} - -/* -* SKP_Silk_prefilter. Main prefilter function -*/ -void SKP_Silk_prefilter_FLP( - SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - const SKP_Silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */ - SKP_float xw[], /* O Weighted signal */ - const SKP_float x[] /* I Speech signal */ -) -{ - SKP_Silk_prefilter_state_FLP *P = &psEnc->sPrefilt; - SKP_int j, k, lag; - SKP_float HarmShapeGain, Tilt, LF_MA_shp, LF_AR_shp; - SKP_float B[ 2 ]; - const SKP_float *AR1_shp; - const SKP_float *px; - SKP_float *pxw; - SKP_float HarmShapeFIR[ 3 ]; - SKP_float st_res[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ]; - - /* Setup pointers */ - px = x; - pxw = xw; - lag = P->lagPrev; - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Update Variables that change per sub frame */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - lag = psEncCtrl->pitchL[ k ]; - } - - /* Noise shape parameters */ - HarmShapeGain = psEncCtrl->HarmShapeGain[ k ] * ( 1.0f - psEncCtrl->HarmBoost[ k ] ); - HarmShapeFIR[ 0 ] = 0.25f * HarmShapeGain; - HarmShapeFIR[ 1 ] = 32767.0f / 65536.0f * HarmShapeGain; - HarmShapeFIR[ 2 ] = 0.25f * HarmShapeGain; - Tilt = psEncCtrl->Tilt[ k ]; - LF_MA_shp = psEncCtrl->LF_MA_shp[ k ]; - LF_AR_shp = psEncCtrl->LF_AR_shp[ k ]; - AR1_shp = &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ]; - - /* Short term FIR filtering */ - SKP_Silk_warped_LPC_analysis_filter_FLP( P->sAR_shp, st_res, AR1_shp, px, - (SKP_float)psEnc->sCmn.warping_Q16 / 65536.0f, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder ); - - /* Reduce (mainly) low frequencies during harmonic emphasis */ - B[ 0 ] = psEncCtrl->GainsPre[ k ]; - B[ 1 ] = -psEncCtrl->GainsPre[ k ] * - ( psEncCtrl->HarmBoost[ k ] * HarmShapeGain + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT ); - pxw[ 0 ] = B[ 0 ] * st_res[ 0 ] + B[ 1 ] * P->sHarmHP; - for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) { - pxw[ j ] = B[ 0 ] * st_res[ j ] + B[ 1 ] * st_res[ j - 1 ]; - } - P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ]; - - SKP_Silk_prefilt_FLP( P, pxw, pxw, HarmShapeFIR, Tilt, LF_MA_shp, LF_AR_shp, lag, psEnc->sCmn.subfr_length ); - - px += psEnc->sCmn.subfr_length; - pxw += psEnc->sCmn.subfr_length; - } - P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ]; -} - -/* -* Prefilter for finding Quantizer input signal -*/ -SKP_INLINE void SKP_Silk_prefilt_FLP( - SKP_Silk_prefilter_state_FLP *P,/* I/O state */ - SKP_float st_res[], /* I */ - SKP_float xw[], /* O */ - SKP_float *HarmShapeFIR, /* I */ - SKP_float Tilt, /* I */ - SKP_float LF_MA_shp, /* I */ - SKP_float LF_AR_shp, /* I */ - SKP_int lag, /* I */ - SKP_int length /* I */ -) -{ - SKP_int i; - SKP_int idx, LTP_shp_buf_idx; - SKP_float n_Tilt, n_LF, n_LTP; - SKP_float sLF_AR_shp, sLF_MA_shp; - SKP_float *LTP_shp_buf; - - /* To speed up use temp variables instead of using the struct */ - LTP_shp_buf = P->sLTP_shp; - LTP_shp_buf_idx = P->sLTP_shp_buf_idx; - sLF_AR_shp = P->sLF_AR_shp; - sLF_MA_shp = P->sLF_MA_shp; - - for( i = 0; i < length; i++ ) { - if( lag > 0 ) { - SKP_assert( HARM_SHAPE_FIR_TAPS == 3 ); - idx = lag + LTP_shp_buf_idx; - n_LTP = LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ] * HarmShapeFIR[ 0 ]; - n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ] * HarmShapeFIR[ 1 ]; - n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ] * HarmShapeFIR[ 2 ]; - } else { - n_LTP = 0; - } - - n_Tilt = sLF_AR_shp * Tilt; - n_LF = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp; - - sLF_AR_shp = st_res[ i ] - n_Tilt; - sLF_MA_shp = sLF_AR_shp - n_LF; - - LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK; - LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp; - - xw[ i ] = sLF_MA_shp - n_LTP; - } - /* Copy temp variable back to state */ - P->sLF_AR_shp = sLF_AR_shp; - P->sLF_MA_shp = sLF_MA_shp; - P->sLTP_shp_buf_idx = LTP_shp_buf_idx; -} diff --git a/silk/SKP_Silk_process_gains_FIX.c b/silk/SKP_Silk_process_gains_FIX.c deleted file mode 100644 index c11502b0..00000000 --- a/silk/SKP_Silk_process_gains_FIX.c +++ /dev/null @@ -1,108 +0,0 @@ -/*********************************************************************** -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" -#include "SKP_Silk_tuning_parameters.h" - -/* Processing of gains */ -void SKP_Silk_process_gains_FIX( - SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state_FIX */ - SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O Encoder control_FIX */ -) -{ - SKP_Silk_shape_state_FIX *psShapeSt = &psEnc->sShape; - SKP_int k; - SKP_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10; - - /* Gain reduction when LTP coding gain is high */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /*s = -0.5f * SKP_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */ - s_Q16 = -SKP_Silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SKP_FIX_CONST( 12.0, 7 ), 4 ) ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains_Q16[ k ] = SKP_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 ); - } - } - - /* Limit the quantized signal */ - /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */ - InvMaxSqrVal_Q16 = SKP_DIV32_16( SKP_Silk_log2lin( - SKP_SMULWB( SKP_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SKP_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length ); - - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Soft limit on ratio residual energy and squared gains */ - ResNrg = psEncCtrl->ResNrg[ k ]; - ResNrgPart = SKP_SMULWW( ResNrg, InvMaxSqrVal_Q16 ); - if( psEncCtrl->ResNrgQ[ k ] > 0 ) { - ResNrgPart = SKP_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] ); - } else { - if( ResNrgPart >= SKP_RSHIFT( SKP_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) { - ResNrgPart = SKP_int32_MAX; - } else { - ResNrgPart = SKP_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] ); - } - } - gain = psEncCtrl->Gains_Q16[ k ]; - gain_squared = SKP_ADD_SAT32( ResNrgPart, SKP_SMMUL( gain, gain ) ); - if( gain_squared < SKP_int16_MAX ) { - /* recalculate with higher precision */ - gain_squared = SKP_SMLAWW( SKP_LSHIFT( ResNrgPart, 16 ), gain, gain ); - SKP_assert( gain_squared > 0 ); - gain = SKP_Silk_SQRT_APPROX( gain_squared ); /* Q8 */ - gain = SKP_min( gain, SKP_int32_MAX >> 8 ); - psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 8 ); /* Q16 */ - } else { - gain = SKP_Silk_SQRT_APPROX( gain_squared ); /* Q0 */ - gain = SKP_min( gain, SKP_int32_MAX >> 16 ); - psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 16 ); /* Q16 */ - } - } - - /* Noise shaping quantization */ - SKP_Silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16, - &psShapeSt->LastGainIndex, psEnc->sCmn.nFramesAnalyzed, psEnc->sCmn.nb_subfr ); - - /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - if( psEncCtrl->LTPredCodGain_Q7 + SKP_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SKP_FIX_CONST( 1.0, 7 ) ) { - psEnc->sCmn.indices.quantOffsetType = 0; - } else { - psEnc->sCmn.indices.quantOffsetType = 1; - } - } - - /* Quantizer boundary adjustment */ - quant_offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ]; - psEncCtrl->Lambda_Q10 = SKP_FIX_CONST( LAMBDA_OFFSET, 10 ) - + SKP_SMULBB( SKP_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision ) - + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_SPEECH_ACT, 18 ), psEnc->sCmn.speech_activity_Q8 ) - + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_INPUT_QUALITY, 12 ), psEncCtrl->input_quality_Q14 ) - + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_CODING_QUALITY, 12 ), psEncCtrl->coding_quality_Q14 ) - + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_QUANT_OFFSET, 16 ), quant_offset_Q10 ); - - SKP_assert( psEncCtrl->Lambda_Q10 > 0 ); - SKP_assert( psEncCtrl->Lambda_Q10 < SKP_FIX_CONST( 2, 10 ) ); -} diff --git a/silk/SKP_Silk_process_gains_FLP.c b/silk/SKP_Silk_process_gains_FLP.c deleted file mode 100644 index 4f0a2089..00000000 --- a/silk/SKP_Silk_process_gains_FLP.c +++ /dev/null @@ -1,94 +0,0 @@ -/*********************************************************************** -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_FLP.h" -#include "SKP_Silk_tuning_parameters.h" - -/* Processing of gains */ -void SKP_Silk_process_gains_FLP( - SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP *psEncCtrl /* I/O Encoder control FLP */ -) -{ - SKP_Silk_shape_state_FLP *psShapeSt = &psEnc->sShape; - SKP_int k; - SKP_int32 pGains_Q16[ MAX_NB_SUBFR ]; - SKP_float s, InvMaxSqrVal, gain, quant_offset; - - /* Gain reduction when LTP coding gain is high */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - s = 1.0f - 0.5f * SKP_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains[ k ] *= s; - } - } - - /* Limit the quantized signal */ - InvMaxSqrVal = ( SKP_float )( pow( 2.0f, 0.33f * ( 21.0f - psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) ) ) / psEnc->sCmn.subfr_length ); - - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Soft limit on ratio residual energy and squared gains */ - gain = psEncCtrl->Gains[ k ]; - gain = ( SKP_float )sqrt( gain * gain + psEncCtrl->ResNrg[ k ] * InvMaxSqrVal ); - psEncCtrl->Gains[ k ] = SKP_min_float( gain, 32767.0f ); - } - - /* Prepare gains for noise shaping quantization */ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - pGains_Q16[ k ] = ( SKP_int32 ) ( psEncCtrl->Gains[ k ] * 65536.0f ); - } - - /* Noise shaping quantization */ - SKP_Silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, - &psShapeSt->LastGainIndex, psEnc->sCmn.nFramesAnalyzed, psEnc->sCmn.nb_subfr ); - - /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains[ k ] = pGains_Q16[ k ] / 65536.0f; - } - - /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - if( psEncCtrl->LTPredCodGain + psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ) > 1.0f ) { - psEnc->sCmn.indices.quantOffsetType = 0; - } else { - psEnc->sCmn.indices.quantOffsetType = 1; - } - } - - /* Quantizer boundary adjustment */ - quant_offset = SKP_Silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ] / 1024.0f; - psEncCtrl->Lambda = LAMBDA_OFFSET - + LAMBDA_DELAYED_DECISIONS * psEnc->sCmn.nStatesDelayedDecision - + LAMBDA_SPEECH_ACT * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ) - + LAMBDA_INPUT_QUALITY * psEncCtrl->input_quality - + LAMBDA_CODING_QUALITY * psEncCtrl->coding_quality - + LAMBDA_QUANT_OFFSET * quant_offset; - - SKP_assert( psEncCtrl->Lambda > 0.0f ); - SKP_assert( psEncCtrl->Lambda < 2.0f ); -} diff --git a/silk/SKP_Silk_regularize_correlations_FIX.c b/silk/SKP_Silk_regularize_correlations_FIX.c deleted file mode 100644 index f30f631c..00000000 --- a/silk/SKP_Silk_regularize_correlations_FIX.c +++ /dev/null @@ -1,43 +0,0 @@ -/*********************************************************************** -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" - -/* Add noise to matrix diagonal */ -void SKP_Silk_regularize_correlations_FIX( - SKP_int32 *XX, /* I/O Correlation matrices */ - SKP_int32 *xx, /* I/O Correlation values */ - SKP_int32 noise, /* I Noise to add */ - SKP_int D /* I Dimension of XX */ -) -{ - SKP_int i; - for( i = 0; i < D; i++ ) { - matrix_ptr( &XX[ 0 ], i, i, D ) = SKP_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise ); - } - xx[ 0 ] += noise; -} diff --git a/silk/SKP_Silk_regularize_correlations_FLP.c b/silk/SKP_Silk_regularize_correlations_FLP.c deleted file mode 100644 index 3acb944d..00000000 --- a/silk/SKP_Silk_regularize_correlations_FLP.c +++ /dev/null @@ -1,43 +0,0 @@ -/*********************************************************************** -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_FLP.h" - -void SKP_Silk_regularize_correlations_FLP( - SKP_float *XX, /* I/O Correlation matrices */ - SKP_float *xx, /* I/O Correlation values */ - const SKP_float noise, /* I Noise energy to add */ - const SKP_int D /* I Dimension of XX */ -) -{ - SKP_int i; - - for( i = 0; i < D; i++ ) { - matrix_ptr( &XX[ 0 ], i, i, D ) += noise; - } - xx[ 0 ] += noise; -} diff --git a/silk/SKP_Silk_residual_energy16_FIX.c b/silk/SKP_Silk_residual_energy16_FIX.c deleted file mode 100644 index b559ce61..00000000 --- a/silk/SKP_Silk_residual_energy16_FIX.c +++ /dev/null @@ -1,99 +0,0 @@ -/*********************************************************************** -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" - -/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ -SKP_int32 SKP_Silk_residual_energy16_covar_FIX( - const SKP_int16 *c, /* I Prediction vector */ - const SKP_int32 *wXX, /* I Correlation matrix */ - const SKP_int32 *wXx, /* I Correlation vector */ - SKP_int32 wxx, /* I Signal energy */ - SKP_int D, /* I Dimension */ - SKP_int cQ /* I Q value for c vector 0 - 15 */ -) -{ - SKP_int i, j, lshifts, Qxtra; - SKP_int32 c_max, w_max, tmp, tmp2, nrg; - SKP_int cn[ MAX_MATRIX_SIZE ]; - const SKP_int32 *pRow; - - /* Safety checks */ - SKP_assert( D >= 0 ); - SKP_assert( D <= 16 ); - SKP_assert( cQ > 0 ); - SKP_assert( cQ < 16 ); - - lshifts = 16 - cQ; - Qxtra = lshifts; - - c_max = 0; - for( i = 0; i < D; i++ ) { - c_max = SKP_max_32( c_max, SKP_abs( ( SKP_int32 )c[ i ] ) ); - } - Qxtra = SKP_min_int( Qxtra, SKP_Silk_CLZ32( c_max ) - 17 ); - - w_max = SKP_max_32( wXX[ 0 ], wXX[ D * D - 1 ] ); - Qxtra = SKP_min_int( Qxtra, SKP_Silk_CLZ32( SKP_MUL( D, SKP_RSHIFT( SKP_SMULWB( w_max, c_max ), 4 ) ) ) - 5 ); - Qxtra = SKP_max_int( Qxtra, 0 ); - for( i = 0; i < D; i++ ) { - cn[ i ] = SKP_LSHIFT( ( SKP_int )c[ i ], Qxtra ); - SKP_assert( SKP_abs(cn[i]) <= ( SKP_int16_MAX + 1 ) ); /* Check that SKP_SMLAWB can be used */ - } - lshifts -= Qxtra; - - /* Compute wxx - 2 * wXx * c */ - tmp = 0; - for( i = 0; i < D; i++ ) { - tmp = SKP_SMLAWB( tmp, wXx[ i ], cn[ i ] ); - } - nrg = SKP_RSHIFT( wxx, 1 + lshifts ) - tmp; /* Q: -lshifts - 1 */ - - /* Add c' * wXX * c, assuming wXX is symmetric */ - tmp2 = 0; - for( i = 0; i < D; i++ ) { - tmp = 0; - pRow = &wXX[ i * D ]; - for( j = i + 1; j < D; j++ ) { - tmp = SKP_SMLAWB( tmp, pRow[ j ], cn[ j ] ); - } - tmp = SKP_SMLAWB( tmp, SKP_RSHIFT( pRow[ i ], 1 ), cn[ i ] ); - tmp2 = SKP_SMLAWB( tmp2, tmp, cn[ i ] ); - } - nrg = SKP_ADD_LSHIFT32( nrg, tmp2, lshifts ); /* Q: -lshifts - 1 */ - - /* Keep one bit free always, because we add them for LSF interpolation */ - if( nrg < 1 ) { - nrg = 1; - } else if( nrg > SKP_RSHIFT( SKP_int32_MAX, lshifts + 2 ) ) { - nrg = SKP_int32_MAX >> 1; - } else { - nrg = SKP_LSHIFT( nrg, lshifts + 1 ); /* Q0 */ - } - return nrg; - -} diff --git a/silk/SKP_Silk_residual_energy_FIX.c b/silk/SKP_Silk_residual_energy_FIX.c deleted file mode 100644 index 2fb531ca..00000000 --- a/silk/SKP_Silk_residual_energy_FIX.c +++ /dev/null @@ -1,87 +0,0 @@ -/*********************************************************************** -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" - -/* Calculates residual energies of input subframes where all subframes have LPC_order */ -/* of preceeding samples */ -void SKP_Silk_residual_energy_FIX( - SKP_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ - SKP_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */ - const SKP_int16 x[], /* I Input signal */ - const SKP_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ - const SKP_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */ - const SKP_int subfr_length, /* I Subframe length */ - const SKP_int nb_subfr, /* I Number of subframes */ - const SKP_int LPC_order /* I LPC order */ -) -{ - SKP_int offset, i, j, rshift, lz1, lz2; - SKP_int16 *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; - const SKP_int16 *x_ptr; - SKP_int32 tmp32; - - x_ptr = x; - offset = LPC_order + subfr_length; - - /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ - for( i = 0; i < nb_subfr >> 1; i++ ) { - /* Calculate half frame LPC residual signal including preceeding samples */ - SKP_Silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order ); - - /* Point to first subframe of the just calculated LPC residual signal */ - LPC_res_ptr = LPC_res + LPC_order; - for( j = 0; j < ( MAX_NB_SUBFR >> 1 ); j++ ) { - /* Measure subframe energy */ - SKP_Silk_sum_sqr_shift( &nrgs[ i * ( MAX_NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length ); - - /* Set Q values for the measured energy */ - nrgsQ[ i * ( MAX_NB_SUBFR >> 1 ) + j ] = -rshift; - - /* Move to next subframe */ - LPC_res_ptr += offset; - } - /* Move to next frame half */ - x_ptr += ( MAX_NB_SUBFR >> 1 ) * offset; - } - - /* Apply the squared subframe gains */ - for( i = 0; i < nb_subfr; i++ ) { - /* Fully upscale gains and energies */ - lz1 = SKP_Silk_CLZ32( nrgs[ i ] ) - 1; - lz2 = SKP_Silk_CLZ32( gains[ i ] ) - 1; - - tmp32 = SKP_LSHIFT32( gains[ i ], lz2 ); - - /* Find squared gains */ - tmp32 = SKP_SMMUL( tmp32, tmp32 ); // Q( 2 * lz2 - 32 ) - - /* Scale energies */ - nrgs[ i ] = SKP_SMMUL( tmp32, SKP_LSHIFT32( nrgs[ i ], lz1 ) ); // Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 ) - nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32; - } -} diff --git a/silk/SKP_Silk_residual_energy_FLP.c b/silk/SKP_Silk_residual_energy_FLP.c deleted file mode 100644 index 1d11b4ec..00000000 --- a/silk/SKP_Silk_residual_energy_FLP.c +++ /dev/null @@ -1,113 +0,0 @@ -/*********************************************************************** -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_FLP.h" - -#define MAX_ITERATIONS_RESIDUAL_NRG 10 -#define REGULARIZATION_FACTOR 1e-8f - -/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ -SKP_float SKP_Silk_residual_energy_covar_FLP( /* O Weighted residual energy */ - const SKP_float *c, /* I Filter coefficients */ - SKP_float *wXX, /* I/O Weighted correlation matrix, reg. out */ - const SKP_float *wXx, /* I Weighted correlation vector */ - const SKP_float wxx, /* I Weighted correlation value */ - const SKP_int D /* I Dimension */ -) -{ - SKP_int i, j, k; - SKP_float tmp, nrg, regularization; - - /* Safety checks */ - SKP_assert( D >= 0 ); - - regularization = REGULARIZATION_FACTOR * ( wXX[ 0 ] + wXX[ D * D - 1 ] ); - for( k = 0; k < MAX_ITERATIONS_RESIDUAL_NRG; k++ ) { - nrg = wxx; - - tmp = 0.0f; - for( i = 0; i < D; i++ ) { - tmp += wXx[ i ] * c[ i ]; - } - nrg -= 2.0f * tmp; - - /* compute c' * wXX * c, assuming wXX is symmetric */ - for( i = 0; i < D; i++ ) { - tmp = 0.0f; - for( j = i + 1; j < D; j++ ) { - tmp += matrix_c_ptr( wXX, i, j, D ) * c[ j ]; - } - nrg += c[ i ] * ( 2.0f * tmp + matrix_c_ptr( wXX, i, i, D ) * c[ i ] ); - } - if( nrg > 0 ) { - break; - } else { - /* Add white noise */ - for( i = 0; i < D; i++ ) { - matrix_c_ptr( wXX, i, i, D ) += regularization; - } - /* Increase noise for next run */ - regularization *= 2.0f; - } - } - if( k == MAX_ITERATIONS_RESIDUAL_NRG ) { - SKP_assert( nrg == 0 ); - nrg = 1.0f; - } - - return nrg; -} - -/* Calculates residual energies of input subframes where all subframes have LPC_order */ -/* of preceeding samples */ -void SKP_Silk_residual_energy_FLP( - SKP_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ - const SKP_float x[], /* I Input signal */ - const SKP_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ - const SKP_float gains[], /* I Quantization gains */ - const SKP_int subfr_length, /* I Subframe length */ - const SKP_int nb_subfr, /* I number of subframes */ - const SKP_int LPC_order /* I LPC order */ -) -{ - SKP_int shift; - SKP_float *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; - - LPC_res_ptr = LPC_res + LPC_order; - shift = LPC_order + subfr_length; - - /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ - SKP_Silk_LPC_analysis_filter_FLP( LPC_res, a[ 0 ], x + 0 * shift, 2 * shift, LPC_order ); - nrgs[ 0 ] = ( SKP_float )( gains[ 0 ] * gains[ 0 ] * SKP_Silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) ); - nrgs[ 1 ] = ( SKP_float )( gains[ 1 ] * gains[ 1 ] * SKP_Silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) ); - - if( nb_subfr == MAX_NB_SUBFR ) { - SKP_Silk_LPC_analysis_filter_FLP( LPC_res, a[ 1 ], x + 2 * shift, 2 * shift, LPC_order ); - nrgs[ 2 ] = ( SKP_float )( gains[ 2 ] * gains[ 2 ] * SKP_Silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) ); - nrgs[ 3 ] = ( SKP_float )( gains[ 3 ] * gains[ 3 ] * SKP_Silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) ); - } -} diff --git a/silk/SKP_Silk_solve_LS_FIX.c b/silk/SKP_Silk_solve_LS_FIX.c deleted file mode 100644 index 25684185..00000000 --- a/silk/SKP_Silk_solve_LS_FIX.c +++ /dev/null @@ -1,241 +0,0 @@ -/*********************************************************************** -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" -#include "SKP_Silk_tuning_parameters.h" - -/*****************************/ -/* Internal function headers */ -/*****************************/ - -typedef struct { - SKP_int32 Q36_part; - SKP_int32 Q48_part; -} inv_D_t; - -/* Factorize square matrix A into LDL form */ -SKP_INLINE void SKP_Silk_LDL_factorize_FIX( - SKP_int32 *A, /* I/O Pointer to Symetric Square Matrix */ - SKP_int M, /* I Size of Matrix */ - SKP_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */ - inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */ -); - -/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */ -SKP_INLINE void SKP_Silk_LS_SolveFirst_FIX( - const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ - SKP_int M, /* I Dim of Matrix equation */ - const SKP_int32 *b, /* I b Vector */ - SKP_int32 *x_Q16 /* O x Vector */ -); - -/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */ -SKP_INLINE void SKP_Silk_LS_SolveLast_FIX( - const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ - const SKP_int M, /* I Dim of Matrix equation */ - const SKP_int32 *b, /* I b Vector */ - SKP_int32 *x_Q16 /* O x Vector */ -); - -SKP_INLINE void SKP_Silk_LS_divide_Q16_FIX( - SKP_int32 T[], /* I/O Numenator vector */ - inv_D_t *inv_D, /* I 1 / D vector */ - SKP_int M /* I dimension */ -); - -/* Solves Ax = b, assuming A is symmetric */ -void SKP_Silk_solve_LDL_FIX( - SKP_int32 *A, /* I Pointer to symetric square matrix A */ - SKP_int M, /* I Size of matrix */ - const SKP_int32 *b, /* I Pointer to b vector */ - SKP_int32 *x_Q16 /* O Pointer to x solution vector */ -) -{ - SKP_int32 L_Q16[ MAX_MATRIX_SIZE * MAX_MATRIX_SIZE ]; - SKP_int32 Y[ MAX_MATRIX_SIZE ]; - inv_D_t inv_D[ MAX_MATRIX_SIZE ]; - - SKP_assert( M <= MAX_MATRIX_SIZE ); - - /*************************************************** - Factorize A by LDL such that A = L*D*L', - where L is lower triangular with ones on diagonal - ****************************************************/ - SKP_Silk_LDL_factorize_FIX( A, M, L_Q16, inv_D ); - - /**************************************************** - * substitute D*L'*x = Y. ie: - L*D*L'*x = b => L*Y = b <=> Y = inv(L)*b - ******************************************************/ - SKP_Silk_LS_SolveFirst_FIX( L_Q16, M, b, Y ); - - /**************************************************** - D*L'*x = Y <=> L'*x = inv(D)*Y, because D is - diagonal just multiply with 1/d_i - ****************************************************/ - SKP_Silk_LS_divide_Q16_FIX( Y, inv_D, M ); - - /**************************************************** - x = inv(L') * inv(D) * Y - *****************************************************/ - SKP_Silk_LS_SolveLast_FIX( L_Q16, M, Y, x_Q16 ); -} - -SKP_INLINE void SKP_Silk_LDL_factorize_FIX( - SKP_int32 *A, /* I Pointer to Symetric Square Matrix */ - SKP_int M, /* I Size of Matrix */ - SKP_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */ - inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */ -) -{ - SKP_int i, j, k, status, loop_count; - const SKP_int32 *ptr1, *ptr2; - SKP_int32 diag_min_value, tmp_32, err; - SKP_int32 v_Q0[ MAX_MATRIX_SIZE ], D_Q0[ MAX_MATRIX_SIZE ]; - SKP_int32 one_div_diag_Q36, one_div_diag_Q40, one_div_diag_Q48; - - SKP_assert( M <= MAX_MATRIX_SIZE ); - - status = 1; - diag_min_value = SKP_max_32( SKP_SMMUL( SKP_ADD_SAT32( A[ 0 ], A[ SKP_SMULBB( M, M ) - 1 ] ), SKP_FIX_CONST( FIND_LTP_COND_FAC, 31 ) ), 1 << 9 ); - for( loop_count = 0; loop_count < M && status == 1; loop_count++ ) { - status = 0; - for( j = 0; j < M; j++ ) { - ptr1 = matrix_adr( L_Q16, j, 0, M ); - tmp_32 = 0; - for( i = 0; i < j; i++ ) { - v_Q0[ i ] = SKP_SMULWW( D_Q0[ i ], ptr1[ i ] ); /* Q0 */ - tmp_32 = SKP_SMLAWW( tmp_32, v_Q0[ i ], ptr1[ i ] ); /* Q0 */ - } - tmp_32 = SKP_SUB32( matrix_ptr( A, j, j, M ), tmp_32 ); - - if( tmp_32 < diag_min_value ) { - tmp_32 = SKP_SUB32( SKP_SMULBB( loop_count + 1, diag_min_value ), tmp_32 ); - /* Matrix not positive semi-definite, or ill conditioned */ - for( i = 0; i < M; i++ ) { - matrix_ptr( A, i, i, M ) = SKP_ADD32( matrix_ptr( A, i, i, M ), tmp_32 ); - } - status = 1; - break; - } - D_Q0[ j ] = tmp_32; /* always < max(Correlation) */ - - /* two-step division */ - one_div_diag_Q36 = SKP_INVERSE32_varQ( tmp_32, 36 ); /* Q36 */ - one_div_diag_Q40 = SKP_LSHIFT( one_div_diag_Q36, 4 ); /* Q40 */ - err = SKP_SUB32( 1 << 24, SKP_SMULWW( tmp_32, one_div_diag_Q40 ) ); /* Q24 */ - one_div_diag_Q48 = SKP_SMULWW( err, one_div_diag_Q40 ); /* Q48 */ - - /* Save 1/Ds */ - inv_D[ j ].Q36_part = one_div_diag_Q36; - inv_D[ j ].Q48_part = one_div_diag_Q48; - - matrix_ptr( L_Q16, j, j, M ) = 65536; /* 1.0 in Q16 */ - ptr1 = matrix_adr( A, j, 0, M ); - ptr2 = matrix_adr( L_Q16, j + 1, 0, M ); - for( i = j + 1; i < M; i++ ) { - tmp_32 = 0; - for( k = 0; k < j; k++ ) { - tmp_32 = SKP_SMLAWW( tmp_32, v_Q0[ k ], ptr2[ k ] ); /* Q0 */ - } - tmp_32 = SKP_SUB32( ptr1[ i ], tmp_32 ); /* always < max(Correlation) */ - - /* tmp_32 / D_Q0[j] : Divide to Q16 */ - matrix_ptr( L_Q16, i, j, M ) = SKP_ADD32( SKP_SMMUL( tmp_32, one_div_diag_Q48 ), - SKP_RSHIFT( SKP_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) ); - - /* go to next column */ - ptr2 += M; - } - } - } - - SKP_assert( status == 0 ); -} - -SKP_INLINE void SKP_Silk_LS_divide_Q16_FIX( - SKP_int32 T[], /* I/O Numenator vector */ - inv_D_t *inv_D, /* I 1 / D vector */ - SKP_int M /* I Order */ -) -{ - SKP_int i; - SKP_int32 tmp_32; - SKP_int32 one_div_diag_Q36, one_div_diag_Q48; - - for( i = 0; i < M; i++ ) { - one_div_diag_Q36 = inv_D[ i ].Q36_part; - one_div_diag_Q48 = inv_D[ i ].Q48_part; - - tmp_32 = T[ i ]; - T[ i ] = SKP_ADD32( SKP_SMMUL( tmp_32, one_div_diag_Q48 ), SKP_RSHIFT( SKP_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) ); - } -} - -/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */ -SKP_INLINE void SKP_Silk_LS_SolveFirst_FIX( - const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ - SKP_int M, /* I Dim of Matrix equation */ - const SKP_int32 *b, /* I b Vector */ - SKP_int32 *x_Q16 /* O x Vector */ -) -{ - SKP_int i, j; - const SKP_int32 *ptr32; - SKP_int32 tmp_32; - - for( i = 0; i < M; i++ ) { - ptr32 = matrix_adr( L_Q16, i, 0, M ); - tmp_32 = 0; - for( j = 0; j < i; j++ ) { - tmp_32 = SKP_SMLAWW( tmp_32, ptr32[ j ], x_Q16[ j ] ); - } - x_Q16[ i ] = SKP_SUB32( b[ i ], tmp_32 ); - } -} - -/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */ -SKP_INLINE void SKP_Silk_LS_SolveLast_FIX( - const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ - const SKP_int M, /* I Dim of Matrix equation */ - const SKP_int32 *b, /* I b Vector */ - SKP_int32 *x_Q16 /* O x Vector */ -) -{ - SKP_int i, j; - const SKP_int32 *ptr32; - SKP_int32 tmp_32; - - for( i = M - 1; i >= 0; i-- ) { - ptr32 = matrix_adr( L_Q16, 0, i, M ); - tmp_32 = 0; - for( j = M - 1; j > i; j-- ) { - tmp_32 = SKP_SMLAWW( tmp_32, ptr32[ SKP_SMULBB( j, M ) ], x_Q16[ j ] ); - } - x_Q16[ i ] = SKP_SUB32( b[ i ], tmp_32 ); - } -} diff --git a/silk/SKP_Silk_solve_LS_FLP.c b/silk/SKP_Silk_solve_LS_FLP.c deleted file mode 100644 index e6c02c4d..00000000 --- a/silk/SKP_Silk_solve_LS_FLP.c +++ /dev/null @@ -1,203 +0,0 @@ -/*********************************************************************** -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_FLP.h" -#include "SKP_Silk_tuning_parameters.h" - -/********************************************************************** - * LDL Factorisation. Finds the upper triangular matrix L and the diagonal - * Matrix D (only the diagonal elements returned in a vector)such that - * the symmetric matric A is given by A = L*D*L'. - **********************************************************************/ -void SKP_Silk_LDL_FLP( - SKP_float *A, /* (I/O) Pointer to Symetric Square Matrix */ - SKP_int M, /* (I) Size of Matrix */ - SKP_float *L, /* (I/O) Pointer to Square Upper triangular Matrix */ - SKP_float *Dinv /* (I/O) Pointer to vector holding the inverse diagonal elements of D */ -); - -/********************************************************************** - * Function to solve linear equation Ax = b, when A is a MxM lower - * triangular matrix, with ones on the diagonal. - **********************************************************************/ -void SKP_Silk_SolveWithLowerTriangularWdiagOnes_FLP( - const SKP_float *L, /* (I) Pointer to Lower Triangular Matrix */ - SKP_int M, /* (I) Dim of Matrix equation */ - const SKP_float *b, /* (I) b Vector */ - SKP_float *x /* (O) x Vector */ -); - -/********************************************************************** - * Function to solve linear equation (A^T)x = b, when A is a MxM lower - * triangular, with ones on the diagonal. (ie then A^T is upper triangular) - **********************************************************************/ -void SKP_Silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( - const SKP_float *L, /* (I) Pointer to Lower Triangular Matrix */ - SKP_int M, /* (I) Dim of Matrix equation */ - const SKP_float *b, /* (I) b Vector */ - SKP_float *x /* (O) x Vector */ -); - -/********************************************************************** - * Function to solve linear equation Ax = b, when A is a MxM - * symmetric square matrix - using LDL factorisation - **********************************************************************/ -void SKP_Silk_solve_LDL_FLP( - SKP_float *A, /* I/O Symmetric square matrix, out: reg. */ - const SKP_int M, /* I Size of matrix */ - const SKP_float *b, /* I Pointer to b vector */ - SKP_float *x /* O Pointer to x solution vector */ -) -{ - SKP_int i; - SKP_float L[ MAX_MATRIX_SIZE ][ MAX_MATRIX_SIZE ]; - SKP_float T[ MAX_MATRIX_SIZE ]; - SKP_float Dinv[ MAX_MATRIX_SIZE ]; // inverse diagonal elements of D - - SKP_assert( M <= MAX_MATRIX_SIZE ); - - /*************************************************** - Factorize A by LDL such that A = L*D*(L^T), - where L is lower triangular with ones on diagonal - ****************************************************/ - SKP_Silk_LDL_FLP( A, M, &L[ 0 ][ 0 ], Dinv ); - - /**************************************************** - * substitute D*(L^T) = T. ie: - L*D*(L^T)*x = b => L*T = b <=> T = inv(L)*b - ******************************************************/ - SKP_Silk_SolveWithLowerTriangularWdiagOnes_FLP( &L[ 0 ][ 0 ], M, b, T ); - - /**************************************************** - D*(L^T)*x = T <=> (L^T)*x = inv(D)*T, because D is - diagonal just multiply with 1/d_i - ****************************************************/ - for( i = 0; i < M; i++ ) { - T[ i ] = T[ i ] * Dinv[ i ]; - } - /**************************************************** - x = inv(L') * inv(D) * T - *****************************************************/ - SKP_Silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( &L[ 0 ][ 0 ], M, T, x ); -} - -void SKP_Silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( - const SKP_float *L, /* (I) Pointer to Lower Triangular Matrix */ - SKP_int M, /* (I) Dim of Matrix equation */ - const SKP_float *b, /* (I) b Vector */ - SKP_float *x /* (O) x Vector */ -) -{ - SKP_int i, j; - SKP_float temp; - const SKP_float *ptr1; - - for( i = M - 1; i >= 0; i-- ) { - ptr1 = matrix_adr( L, 0, i, M ); - temp = 0; - for( j = M - 1; j > i ; j-- ) { - temp += ptr1[ j * M ] * x[ j ]; - } - temp = b[ i ] - temp; - x[ i ] = temp; - } -} - -void SKP_Silk_SolveWithLowerTriangularWdiagOnes_FLP( - const SKP_float *L, /* (I) Pointer to Lower Triangular Matrix */ - SKP_int M, /* (I) Dim of Matrix equation */ - const SKP_float *b, /* (I) b Vector */ - SKP_float *x /* (O) x Vector */ -) -{ - SKP_int i, j; - SKP_float temp; - const SKP_float *ptr1; - - for( i = 0; i < M; i++ ) { - ptr1 = matrix_adr( L, i, 0, M ); - temp = 0; - for( j = 0; j < i; j++ ) { - temp += ptr1[ j ] * x[ j ]; - } - temp = b[ i ] - temp; - x[ i ] = temp; - } -} - -void SKP_Silk_LDL_FLP( - SKP_float *A, /* (I/O) Pointer to Symetric Square Matrix */ - SKP_int M, /* (I) Size of Matrix */ - SKP_float *L, /* (I/O) Pointer to Square Upper triangular Matrix */ - SKP_float *Dinv /* (I/O) Pointer to vector holding the inverse diagonal elements of D */ -) -{ - SKP_int i, j, k, loop_count, err = 1; - SKP_float *ptr1, *ptr2; - double temp, diag_min_value; - SKP_float v[ MAX_MATRIX_SIZE ], D[ MAX_MATRIX_SIZE ]; // temp arrays - - SKP_assert( M <= MAX_MATRIX_SIZE ); - - diag_min_value = FIND_LTP_COND_FAC * 0.5f * ( A[ 0 ] + A[ M * M - 1 ] ); - for( loop_count = 0; loop_count < M && err == 1; loop_count++ ) { - err = 0; - for( j = 0; j < M; j++ ) { - ptr1 = matrix_adr( L, j, 0, M ); - temp = matrix_ptr( A, j, j, M ); // element in row j column j - for( i = 0; i < j; i++ ) { - v[ i ] = ptr1[ i ] * D[ i ]; - temp -= ptr1[ i ] * v[ i ]; - } - if( temp < diag_min_value ) { - /* Badly conditioned matrix: add white noise and run again */ - temp = ( loop_count + 1 ) * diag_min_value - temp; - for( i = 0; i < M; i++ ) { - matrix_ptr( A, i, i, M ) += ( SKP_float )temp; - } - err = 1; - break; - } - D[ j ] = ( SKP_float )temp; - Dinv[ j ] = ( SKP_float )( 1.0f / temp ); - matrix_ptr( L, j, j, M ) = 1.0f; - - ptr1 = matrix_adr( A, j, 0, M ); - ptr2 = matrix_adr( L, j + 1, 0, M); - for( i = j + 1; i < M; i++ ) { - temp = 0.0; - for( k = 0; k < j; k++ ) { - temp += ptr2[ k ] * v[ k ]; - } - matrix_ptr( L, i, j, M ) = ( SKP_float )( ( ptr1[ i ] - temp ) * Dinv[ j ] ); - ptr2 += M; // go to next column - } - } - } - SKP_assert( err == 0 ); -} - diff --git a/silk/SKP_Silk_warped_autocorrelation_FIX.c b/silk/SKP_Silk_warped_autocorrelation_FIX.c deleted file mode 100644 index 380104ff..00000000 --- a/silk/SKP_Silk_warped_autocorrelation_FIX.c +++ /dev/null @@ -1,84 +0,0 @@ -/*********************************************************************** -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_int 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/silk/SKP_Silk_warped_autocorrelation_FLP.c b/silk/SKP_Silk_warped_autocorrelation_FLP.c deleted file mode 100644 index 355d7e49..00000000 --- a/silk/SKP_Silk_warped_autocorrelation_FLP.c +++ /dev/null @@ -1,69 +0,0 @@ -/*********************************************************************** -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_FLP.h" - -/* Autocorrelations for a warped frequency axis */ -void SKP_Silk_warped_autocorrelation_FLP( - SKP_float *corr, /* O Result [order + 1] */ - const SKP_float *input, /* I Input data to correlate */ - const SKP_float warping, /* I Warping coefficient */ - const SKP_int length, /* I Length of input */ - const SKP_int order /* I Correlation order (even) */ -) -{ - SKP_int n, i; - double tmp1, tmp2; - double state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; - double C[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; - - /* Order must be even */ - SKP_assert( ( order & 1 ) == 0 ); - - /* Loop over samples */ - for( n = 0; n < length; n++ ) { - tmp1 = input[ n ]; - /* Loop over allpass sections */ - for( i = 0; i < order; i += 2 ) { - /* Output of allpass section */ - tmp2 = state[ i ] + warping * ( state[ i + 1 ] - tmp1 ); - state[ i ] = tmp1; - C[ i ] += state[ 0 ] * tmp1; - /* Output of allpass section */ - tmp1 = state[ i + 1 ] + warping * ( state[ i + 2 ] - tmp2 ); - state[ i + 1 ] = tmp2; - C[ i + 1 ] += state[ 0 ] * tmp2; - } - state[ order ] = tmp1; - C[ order ] += state[ 0 ] * tmp1; - } - - /* Copy correlations in SKP_float output format */ - for( i = 0; i < order + 1; i++ ) { - corr[ i ] = ( SKP_float )C[ i ]; - } -} diff --git a/silk/SKP_Silk_wrappers_FLP.c b/silk/SKP_Silk_wrappers_FLP.c deleted file mode 100644 index 9e5b7650..00000000 --- a/silk/SKP_Silk_wrappers_FLP.c +++ /dev/null @@ -1,194 +0,0 @@ -/*********************************************************************** -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_FLP.h" - -/* Wrappers. Calls flp / fix code */ - -/* Convert AR filter coefficients to NLSF parameters */ -void SKP_Silk_A2NLSF_FLP( - SKP_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */ - const SKP_float *pAR, /* I LPC coefficients [ LPC_order ] */ - const SKP_int LPC_order /* I LPC order */ -) -{ - SKP_int i; - SKP_int32 a_fix_Q16[ MAX_LPC_ORDER ]; - - for( i = 0; i < LPC_order; i++ ) { - a_fix_Q16[ i ] = SKP_float2int( pAR[ i ] * 65536.0f ); - } - - SKP_Silk_A2NLSF( NLSF_Q15, a_fix_Q16, LPC_order ); -} - -/* Convert LSF parameters to AR prediction filter coefficients */ -void SKP_Silk_NLSF2A_stable_FLP( - SKP_float *pAR, /* O LPC coefficients [ LPC_order ] */ - const SKP_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */ - const SKP_int LPC_order /* I LPC order */ -) -{ - SKP_int i; - SKP_int16 a_fix_Q12[ MAX_LPC_ORDER ]; - - SKP_Silk_NLSF2A_stable( a_fix_Q12, NLSF_Q15, LPC_order ); - - for( i = 0; i < LPC_order; i++ ) { - pAR[ i ] = ( SKP_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f ); - } -} - -/******************************************/ -/* Floating-point NLSF processing wrapper */ -/******************************************/ -void SKP_Silk_process_NLSFs_FLP( - SKP_Silk_encoder_state *psEncC, /* I/O Encoder state */ - SKP_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ - SKP_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ - const SKP_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ -) -{ - SKP_int i, j; - SKP_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; - - SKP_Silk_process_NLSFs( psEncC, PredCoef_Q12, NLSF_Q15, prev_NLSF_Q15); - - for( j = 0; j < 2; j++ ) { - for( i = 0; i < psEncC->predictLPCOrder; i++ ) { - PredCoef[ j ][ i ] = ( SKP_float )PredCoef_Q12[ j ][ i ] * ( 1.0f / 4096.0f ); - } - } -} - -/****************************************/ -/* Floating-point Silk NSQ wrapper */ -/****************************************/ -void SKP_Silk_NSQ_wrapper_FLP( - SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - SideInfoIndices *psIndices, /* I/O Quantization indices */ - SKP_Silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */ - SKP_int8 pulses[], /* O Quantized pulse signal */ - const SKP_float x[] /* I Prefiltered input signal */ -) -{ - SKP_int i, j; - SKP_int16 x_16[ MAX_FRAME_LENGTH ]; - SKP_int32 Gains_Q16[ MAX_NB_SUBFR ]; - SKP_DWORD_ALIGN SKP_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; - SKP_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; - SKP_int LTP_scale_Q14; - - /* Noise shaping parameters */ - SKP_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; - SKP_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ - SKP_int Lambda_Q10; - SKP_int Tilt_Q14[ MAX_NB_SUBFR ]; - SKP_int HarmShapeGain_Q14[ MAX_NB_SUBFR ]; - - /* Convert control struct to fix control struct */ - /* Noise shape parameters */ - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) { - AR2_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = SKP_float2int( psEncCtrl->AR2[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f ); - } - } - - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - LF_shp_Q14[ i ] = SKP_LSHIFT32( SKP_float2int( psEncCtrl->LF_AR_shp[ i ] * 16384.0f ), 16 ) | - (SKP_uint16)SKP_float2int( psEncCtrl->LF_MA_shp[ i ] * 16384.0f ); - Tilt_Q14[ i ] = (SKP_int)SKP_float2int( psEncCtrl->Tilt[ i ] * 16384.0f ); - HarmShapeGain_Q14[ i ] = (SKP_int)SKP_float2int( psEncCtrl->HarmShapeGain[ i ] * 16384.0f ); - } - Lambda_Q10 = ( SKP_int )SKP_float2int( psEncCtrl->Lambda * 1024.0f ); - - /* prediction and coding parameters */ - for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) { - LTPCoef_Q14[ i ] = ( SKP_int16 )SKP_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f ); - } - - for( j = 0; j < 2; j++ ) { - for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) { - PredCoef_Q12[ j ][ i ] = ( SKP_int16 )SKP_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f ); - } - } - - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - Gains_Q16[ i ] = SKP_float2int( psEncCtrl->Gains[ i ] * 65536.0f ); - SKP_assert( Gains_Q16[ i ] > 0 ); - } - - if( psIndices->signalType == TYPE_VOICED ) { - LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ psIndices->LTP_scaleIndex ]; - } else { - LTP_scale_Q14 = 0; - } - - /* Convert input to fix */ - SKP_float2short_array( x_16, x, psEnc->sCmn.frame_length ); - - /* Call NSQ */ - if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { - SKP_Silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x_16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, - AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 ); - } else { - SKP_Silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x_16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, - AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 ); - } -} - -/***********************************************/ -/* Floating-point Silk LTP quantiation wrapper */ -/***********************************************/ -void SKP_Silk_quant_LTP_gains_FLP( - SKP_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */ - SKP_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */ - SKP_int8 *periodicity_index, /* O Periodicity index */ - const SKP_float W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Error weights */ - const SKP_int mu_Q10, /* I Mu value (R/D tradeoff) */ - const SKP_int lowComplexity, /* I Flag for low complexity */ - const SKP_int nb_subfr /* I number of subframes */ -) -{ - SKP_int i; - SKP_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ]; - SKP_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ]; - - for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { - B_Q14[ i ] = (SKP_int16)SKP_float2int( B[ i ] * 16384.0f ); - } - for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) { - W_Q18[ i ] = (SKP_int32)SKP_float2int( W[ i ] * 262144.0f ); - } - - SKP_Silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, W_Q18, mu_Q10, lowComplexity, nb_subfr ); - - for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { - B[ i ] = (SKP_float)B_Q14[ i ] * ( 1.0f / 16384.0f ); - } -} diff --git a/silk/fixed/SKP_Silk_LTP_analysis_filter_FIX.c b/silk/fixed/SKP_Silk_LTP_analysis_filter_FIX.c new file mode 100644 index 00000000..4e21d65e --- /dev/null +++ b/silk/fixed/SKP_Silk_LTP_analysis_filter_FIX.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. +***********************************************************************/ + +#include "SKP_Silk_main_FIX.h" + +void SKP_Silk_LTP_analysis_filter_FIX( + SKP_int16 *LTP_res, /* O: LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */ + const SKP_int16 *x, /* I: Pointer to input signal with at least max( pitchL ) preceeding samples */ + const SKP_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I: LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */ + const SKP_int pitchL[ MAX_NB_SUBFR ], /* I: Pitch lag, one for each subframe */ + const SKP_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I: Inverse quantization gains, one for each subframe */ + const SKP_int subfr_length, /* I: Length of each subframe */ + const SKP_int nb_subfr, /* I: Number of subframes */ + const SKP_int pre_length /* I: Length of the preceeding samples starting at &x[0] for each subframe */ +) +{ + const SKP_int16 *x_ptr, *x_lag_ptr; + SKP_int16 Btmp_Q14[ LTP_ORDER ]; + SKP_int16 *LTP_res_ptr; + SKP_int k, i, j; + SKP_int32 LTP_est; + + x_ptr = x; + LTP_res_ptr = LTP_res; + for( k = 0; k < nb_subfr; k++ ) { + + x_lag_ptr = x_ptr - pitchL[ k ]; + for( i = 0; i < LTP_ORDER; i++ ) { + Btmp_Q14[ i ] = LTPCoef_Q14[ k * LTP_ORDER + i ]; + } + + /* LTP analysis FIR filter */ + for( i = 0; i < subfr_length + pre_length; i++ ) { + LTP_res_ptr[ i ] = x_ptr[ i ]; + + /* Long-term prediction */ + LTP_est = SKP_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] ); + for( j = 1; j < LTP_ORDER; j++ ) { + LTP_est = SKP_SMLABB_ovflw( LTP_est, x_lag_ptr[ LTP_ORDER / 2 - j ], Btmp_Q14[ j ] ); + } + LTP_est = SKP_RSHIFT_ROUND( LTP_est, 14 ); // round and -> Q0 + + /* Subtract long-term prediction */ + LTP_res_ptr[ i ] = ( SKP_int16 )SKP_SAT16( ( SKP_int32 )x_ptr[ i ] - LTP_est ); + + /* Scale residual */ + LTP_res_ptr[ i ] = SKP_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] ); + + x_lag_ptr++; + } + + /* Update pointers */ + LTP_res_ptr += subfr_length + pre_length; + x_ptr += subfr_length; + } +} + diff --git a/silk/fixed/SKP_Silk_LTP_scale_ctrl_FIX.c b/silk/fixed/SKP_Silk_LTP_scale_ctrl_FIX.c new file mode 100644 index 00000000..08516050 --- /dev/null +++ b/silk/fixed/SKP_Silk_LTP_scale_ctrl_FIX.c @@ -0,0 +1,52 @@ +/*********************************************************************** +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" + +void SKP_Silk_LTP_scale_ctrl_FIX( + SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state FIX */ + SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O encoder control FIX */ +) +{ + SKP_int round_loss; + + /* 1st order high-pass filter */ + psEnc->HPLTPredCodGain_Q7 = SKP_max_int( psEncCtrl->LTPredCodGain_Q7 - SKP_RSHIFT( psEnc->prevLTPredCodGain_Q7, 1 ), 0 ) + + SKP_RSHIFT( psEnc->HPLTPredCodGain_Q7, 1 ); + psEnc->prevLTPredCodGain_Q7 = psEncCtrl->LTPredCodGain_Q7; + + /* Only scale if first frame in packet */ + if( psEnc->sCmn.nFramesAnalyzed == 0 ) { + round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket - 1; + psEnc->sCmn.indices.LTP_scaleIndex = (SKP_int8)SKP_LIMIT( + SKP_SMULWB( SKP_SMULBB( round_loss, psEnc->HPLTPredCodGain_Q7 ), SKP_FIX_CONST( 0.1, 9 ) ), 0, 2 ); + } else { + /* Default is minimum scaling */ + psEnc->sCmn.indices.LTP_scaleIndex = 0; + } + psEncCtrl->LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ]; +} diff --git a/silk/fixed/SKP_Silk_corrMatrix_FIX.c b/silk/fixed/SKP_Silk_corrMatrix_FIX.c new file mode 100644 index 00000000..1ac1b195 --- /dev/null +++ b/silk/fixed/SKP_Silk_corrMatrix_FIX.c @@ -0,0 +1,152 @@ +/*********************************************************************** +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. +***********************************************************************/ + +/********************************************************************** + * Correlation Matrix Computations for LS estimate. + **********************************************************************/ + +#include "SKP_Silk_main_FIX.h" + +/* Calculates correlation vector X'*t */ +void SKP_Silk_corrVector_FIX( + const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ + const SKP_int16 *t, /* I target vector [L] */ + const SKP_int L, /* I Length of vectors */ + const SKP_int order, /* I Max lag for correlation */ + SKP_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */ + const SKP_int rshifts /* I Right shifts of correlations */ +) +{ + SKP_int lag, i; + const SKP_int16 *ptr1, *ptr2; + SKP_int32 inner_prod; + + ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ + ptr2 = t; + /* Calculate X'*t */ + if( rshifts > 0 ) { + /* Right shifting used */ + for( lag = 0; lag < order; lag++ ) { + inner_prod = 0; + for( i = 0; i < L; i++ ) { + inner_prod += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts ); + } + Xt[ lag ] = inner_prod; /* X[:,lag]'*t */ + ptr1--; /* Go to next column of X */ + } + } else { + SKP_assert( rshifts == 0 ); + for( lag = 0; lag < order; lag++ ) { + Xt[ lag ] = SKP_Silk_inner_prod_aligned( ptr1, ptr2, L ); /* X[:,lag]'*t */ + ptr1--; /* Go to next column of X */ + } + } +} + +/* Calculates correlation matrix X'*X */ +void SKP_Silk_corrMatrix_FIX( + const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ + const SKP_int L, /* I Length of vectors */ + const SKP_int order, /* I Max lag for correlation */ + const SKP_int head_room, /* I Desired headroom */ + SKP_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ]*/ + SKP_int *rshifts /* I/O Right shifts of correlations */ +) +{ + SKP_int i, j, lag, rshifts_local, head_room_rshifts; + SKP_int32 energy; + const SKP_int16 *ptr1, *ptr2; + + /* Calculate energy to find shift used to fit in 32 bits */ + SKP_Silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 ); + /* Add shifts to get the desired head room */ + head_room_rshifts = SKP_max( head_room - SKP_Silk_CLZ32( energy ), 0 ); + + energy = SKP_RSHIFT32( energy, head_room_rshifts ); + rshifts_local += head_room_rshifts; + + /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */ + /* Remove contribution of first order - 1 samples */ + for( i = 0; i < order - 1; i++ ) { + energy -= SKP_RSHIFT32( SKP_SMULBB( x[ i ], x[ i ] ), rshifts_local ); + } + if( rshifts_local < *rshifts ) { + /* Adjust energy */ + energy = SKP_RSHIFT32( energy, *rshifts - rshifts_local ); + rshifts_local = *rshifts; + } + + /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */ + /* Fill out the diagonal of the correlation matrix */ + matrix_ptr( XX, 0, 0, order ) = energy; + ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */ + for( j = 1; j < order; j++ ) { + energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) ); + energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) ); + matrix_ptr( XX, j, j, order ) = energy; + } + + ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */ + /* Calculate the remaining elements of the correlation matrix */ + if( rshifts_local > 0 ) { + /* Right shifting used */ + for( lag = 1; lag < order; lag++ ) { + /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ + energy = 0; + for( i = 0; i < L; i++ ) { + energy += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local ); + } + /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ + matrix_ptr( XX, lag, 0, order ) = energy; + matrix_ptr( XX, 0, lag, order ) = energy; + for( j = 1; j < ( order - lag ); j++ ) { + energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) ); + energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) ); + matrix_ptr( XX, lag + j, j, order ) = energy; + matrix_ptr( XX, j, lag + j, order ) = energy; + } + ptr2--; /* Update pointer to first sample of next column (lag) in X */ + } + } else { + for( lag = 1; lag < order; lag++ ) { + /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ + energy = SKP_Silk_inner_prod_aligned( ptr1, ptr2, L ); + matrix_ptr( XX, lag, 0, order ) = energy; + matrix_ptr( XX, 0, lag, order ) = energy; + /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ + for( j = 1; j < ( order - lag ); j++ ) { + energy = SKP_SUB32( energy, SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) ); + energy = SKP_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] ); + matrix_ptr( XX, lag + j, j, order ) = energy; + matrix_ptr( XX, j, lag + j, order ) = energy; + } + ptr2--;/* Update pointer to first sample of next column (lag) in X */ + } + } + *rshifts = rshifts_local; +} + diff --git a/silk/fixed/SKP_Silk_encode_frame_FIX.c b/silk/fixed/SKP_Silk_encode_frame_FIX.c new file mode 100644 index 00000000..e9003fcf --- /dev/null +++ b/silk/fixed/SKP_Silk_encode_frame_FIX.c @@ -0,0 +1,301 @@ +/*********************************************************************** +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" +#include "SKP_Silk_tuning_parameters.h" + +/****************/ +/* Encode frame */ +/****************/ +SKP_int SKP_Silk_encode_frame_FIX( + SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ + SKP_int32 *pnBytesOut, /* O Number of payload bytes */ + ec_enc *psRangeEnc /* I/O compressor data structure */ +) +{ + SKP_Silk_encoder_control_FIX sEncCtrl; + SKP_int ret = 0; + SKP_int16 *x_frame, *res_pitch_frame; + SKP_int16 xfw[ MAX_FRAME_LENGTH ]; + SKP_int16 res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ]; + +TIC(ENCODE_FRAME) + + psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; + + /**************************************************************/ + /* Setup Input Pointers, and insert frame in input buffer */ + /*************************************************************/ + /* pointers aligned with start of frame to encode */ + x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */ + res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */ + + /****************************/ + /* Voice Activity Detection */ + /****************************/ +TIC(VAD) + ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf ); +TOC(VAD) + + /**************************************************/ + /* Convert speech activity into VAD and DTX flags */ + /**************************************************/ + if( psEnc->sCmn.nFramesAnalyzed == 0 ) { + psEnc->sCmn.inDTX = psEnc->sCmn.useDTX; + } + if( psEnc->sCmn.speech_activity_Q8 < SKP_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) { + psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; + psEnc->sCmn.noSpeechCounter++; + if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) { + psEnc->sCmn.inDTX = 0; + } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { + psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; + psEnc->sCmn.inDTX = 0; + } + psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesAnalyzed ] = 0; + } else { + psEnc->sCmn.noSpeechCounter = 0; + psEnc->sCmn.inDTX = 0; + psEnc->sCmn.indices.signalType = TYPE_UNVOICED; + psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesAnalyzed ] = 1; + } + + /*******************************************/ + /* High-pass filtering of the input signal */ + /*******************************************/ +TIC(HP_IN) + SKP_Silk_HP_variable_cutoff( &psEnc->sCmn, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf, psEnc->sCmn.frame_length ); +TOC(HP_IN) + + /* Ensure smooth bandwidth transitions */ + SKP_Silk_LP_variable_cutoff( &psEnc->sCmn.sLP, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length ); + + /*****************************************/ + /* Find pitch lags, initial LPC analysis */ + /*****************************************/ +TIC(FIND_PITCH) + SKP_Silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame ); +TOC(FIND_PITCH) + + /************************/ + /* Noise shape analysis */ + /************************/ +TIC(NOISE_SHAPE_ANALYSIS) + SKP_Silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame ); +TOC(NOISE_SHAPE_ANALYSIS) + + /*****************************************/ + /* Prefiltering for noise shaper */ + /*****************************************/ +TIC(PREFILTER) + SKP_Silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame ); +TOC(PREFILTER) + + /***************************************************/ + /* Find linear prediction coefficients (LPC + LTP) */ + /***************************************************/ +TIC(FIND_PRED_COEF) + SKP_Silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame ); +TOC(FIND_PRED_COEF) + + /****************************************/ + /* Process gains */ + /****************************************/ +TIC(PROCESS_GAINS) + SKP_Silk_process_gains_FIX( psEnc, &sEncCtrl ); +TOC(PROCESS_GAINS) + + /****************************************/ + /* Low Bitrate Redundant Encoding */ + /****************************************/ +TIC(LBRR) + SKP_Silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw ); +TOC(LBRR) + + /*****************************************/ + /* Noise shaping quantization */ + /*****************************************/ +TIC(NSQ) + if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { + SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses, + sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, + sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); + } else { + SKP_Silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses, + sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, + sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); + } +TOC(NSQ) + + /* Update input buffer */ + SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], + ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_int16 ) ); + + /* Parameters needed for next frame */ + psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; + psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; + + /* Exit without entropy coding */ + if( psEnc->sCmn.prefillFlag ) { + /* No payload */ + *pnBytesOut = 0; + return ret; + } + + /****************************************/ + /* Encode Parameters */ + /****************************************/ +TIC(ENCODE_PARAMS) + SKP_Silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesAnalyzed, 0 ); +TOC(ENCODE_PARAMS) + + /****************************************/ + /* Encode Excitation Signal */ + /****************************************/ +TIC(ENCODE_PULSES) + SKP_Silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, + psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); +TOC(ENCODE_PULSES) + + /****************************************/ + /* Finalize payload */ + /****************************************/ + psEnc->sCmn.first_frame_after_reset = 0; + if( ++psEnc->sCmn.nFramesAnalyzed >= psEnc->sCmn.nFramesPerPacket ) { + /* Payload size */ + *pnBytesOut = SKP_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); + + /* Reset the number of frames in payload buffer */ + psEnc->sCmn.nFramesAnalyzed = 0; + } else { + /* No payload this time */ + *pnBytesOut = 0; + } +TOC(ENCODE_FRAME) + +#ifdef SAVE_ALL_INTERNAL_DATA + { + SKP_float tmp[ MAX_NB_SUBFR * LTP_ORDER ]; + int i; + DEBUG_STORE_DATA( xf.dat, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) ); + DEBUG_STORE_DATA( xfw.dat, xfw, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) ); + DEBUG_STORE_DATA( pitchL.dat, sEncCtrl.pitchL, psEnc->sCmn.nb_subfr * sizeof( SKP_int ) ); + for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) { + tmp[ i ] = (SKP_float)sEncCtrl.LTPCoef_Q14[ i ] / 16384.0f; + } + DEBUG_STORE_DATA( pitchG_quantized.dat, tmp, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) ); + for( i = 0; i sCmn.predictLPCOrder; i++ ) { + tmp[ i ] = (SKP_float)sEncCtrl.PredCoef_Q12[ 1 ][ i ] / 4096.0f; + } + DEBUG_STORE_DATA( PredCoef.dat, tmp, psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) ); + + tmp[ 0 ] = (SKP_float)sEncCtrl.LTPredCodGain_Q7 / 128.0f; + DEBUG_STORE_DATA( LTPredCodGain.dat, tmp, sizeof( SKP_float ) ); + tmp[ 0 ] = (SKP_float)psEnc->LTPCorr_Q15 / 32768.0f; + DEBUG_STORE_DATA( LTPcorr.dat, tmp, sizeof( SKP_float ) ); + tmp[ 0 ] = (SKP_float)psEnc->sCmn.input_tilt_Q15 / 32768.0f; + DEBUG_STORE_DATA( tilt.dat, tmp, sizeof( SKP_float ) ); + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + tmp[ i ] = (SKP_float)sEncCtrl.Gains_Q16[ i ] / 65536.0f; + } + DEBUG_STORE_DATA( gains.dat, tmp, psEnc->sCmn.nb_subfr * sizeof( SKP_float ) ); + DEBUG_STORE_DATA( gains_indices.dat, &psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr * sizeof( SKP_int ) ); + tmp[ 0 ] = (SKP_float)sEncCtrl.current_SNR_dB_Q7 / 128.0f; + DEBUG_STORE_DATA( current_SNR_db.dat, tmp, sizeof( SKP_float ) ); + DEBUG_STORE_DATA( quantOffsetType.dat, &psEnc->sCmn.indices.quantOffsetType, sizeof( SKP_int ) ); + tmp[ 0 ] = (SKP_float)psEnc->sCmn.speech_activity_Q8 / 256.0f; + DEBUG_STORE_DATA( speech_activity.dat, tmp, sizeof( SKP_float ) ); + for( i = 0; i < VAD_N_BANDS; i++ ) { + tmp[ i ] = (SKP_float)psEnc->sCmn.input_quality_bands_Q15[ i ] / 32768.0f; + } + DEBUG_STORE_DATA( input_quality_bands.dat, tmp, VAD_N_BANDS * sizeof( SKP_float ) ); + DEBUG_STORE_DATA( signalType.dat, &psEnc->sCmn.indices.signalType, sizeof( SKP_int8) ); + DEBUG_STORE_DATA( lag_index.dat, &psEnc->sCmn.indices.lagIndex, sizeof( SKP_int16 ) ); + DEBUG_STORE_DATA( contour_index.dat, &psEnc->sCmn.indices.contourIndex, sizeof( SKP_int8 ) ); + DEBUG_STORE_DATA( per_index.dat, &psEnc->sCmn.indices.PERIndex, sizeof( SKP_int8) ); + } +#endif + return ret; +} + +/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ +void SKP_Silk_LBRR_encode_FIX( + SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ + SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ + const SKP_int16 xfw[] /* I Input signal */ +) +{ + SKP_int32 TempGains_Q16[ MAX_NB_SUBFR ]; + SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesAnalyzed ]; + SKP_Silk_nsq_state sNSQ_LBRR; + + /*******************************************/ + /* Control use of inband LBRR */ + /*******************************************/ + if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SKP_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { + psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesAnalyzed ] = 1; + + /* Copy noise shaping quantizer state and quantization indices from regular encoding */ + SKP_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( SKP_Silk_nsq_state ) ); + SKP_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); + + /* Save original gains */ + SKP_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( SKP_int32 ) ); + + if( psEnc->sCmn.nFramesAnalyzed == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesAnalyzed - 1 ] == 0 ) { + /* First frame in packet or previous frame not LBRR coded */ + psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; + + /* Increase Gains to get target LBRR rate */ + psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases; + psIndices_LBRR->GainsIndices[ 0 ] = SKP_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); + } + + /* Decode to get gains in sync with decoder */ + /* Overwrite unquantized gains with quantized gains */ + SKP_Silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices, + &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesAnalyzed, psEnc->sCmn.nb_subfr ); + + /*****************************************/ + /* Noise shaping quantization */ + /*****************************************/ + if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { + SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw, + psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesAnalyzed ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, + psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, + psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); + } else { + SKP_Silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw, + psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesAnalyzed ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, + psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, + psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); + } + + /* Restore original gains */ + SKP_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( SKP_int32 ) ); + } +} diff --git a/silk/fixed/SKP_Silk_find_LPC_FIX.c b/silk/fixed/SKP_Silk_find_LPC_FIX.c new file mode 100644 index 00000000..bf065db1 --- /dev/null +++ b/silk/fixed/SKP_Silk_find_LPC_FIX.c @@ -0,0 +1,157 @@ +/*********************************************************************** +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" +#include "SKP_Silk_tuning_parameters.h" + +/* Finds LPC vector from correlations, and converts to NLSF */ +void SKP_Silk_find_LPC_FIX( + SKP_int16 NLSF_Q15[], /* O NLSFs */ + SKP_int8 *interpIndex, /* O NLSF interpolation index, only used for NLSF interpolation */ + const SKP_int16 prev_NLSFq_Q15[], /* I previous NLSFs, only used for NLSF interpolation */ + const SKP_int useInterpNLSFs, /* I Flag */ + const SKP_int firstFrameAfterReset, /* I Flag */ + const SKP_int LPC_order, /* I LPC order */ + const SKP_int16 x[], /* I Input signal */ + const SKP_int subfr_length, /* I Input signal subframe length including preceeding samples */ + const SKP_int nb_subfr /* I: Number of subframes */ +) +{ + SKP_int k; + SKP_int32 a_Q16[ MAX_LPC_ORDER ]; + SKP_int isInterpLower, shift; + SKP_int32 res_nrg0, res_nrg1; + SKP_int rshift0, rshift1; + + /* Used only for LSF interpolation */ + SKP_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg, res_nrg_2nd; + SKP_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q, res_nrg_2nd_Q; + SKP_int16 a_tmp_Q12[ MAX_LPC_ORDER ]; + SKP_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; + SKP_int16 LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; + + /* Default: no interpolation */ + *interpIndex = 4; + + /* Burg AR analysis for the full frame */ + SKP_Silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, subfr_length, nb_subfr, SKP_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order ); + + if( firstFrameAfterReset ) { + SKP_Silk_bwexpander_32( a_Q16, LPC_order, SKP_FIX_CONST( FIND_LPC_CHIRP_FIRST_FRAME, 16 ) ); + } else { + SKP_Silk_bwexpander_32( a_Q16, LPC_order, SKP_FIX_CONST( FIND_LPC_CHIRP, 16 ) ); + } + + if( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) { + + /* Optimal solution for last 10 ms */ + SKP_Silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + ( MAX_NB_SUBFR >> 1 ) * subfr_length, + subfr_length, ( MAX_NB_SUBFR >> 1 ), SKP_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order ); + + SKP_Silk_bwexpander_32( a_tmp_Q16, LPC_order, SKP_FIX_CONST( FIND_LPC_CHIRP, 16 ) ); + + /* subtract residual energy here, as that's easier than adding it to the */ + /* residual energy of the first 10 ms in each iteration of the search below */ + shift = res_tmp_nrg_Q - res_nrg_Q; + if( shift >= 0 ) { + if( shift < 32 ) { + res_nrg = res_nrg - SKP_RSHIFT( res_tmp_nrg, shift ); + } + } else { + SKP_assert( shift > -32 ); + res_nrg = SKP_RSHIFT( res_nrg, -shift ) - res_tmp_nrg; + res_nrg_Q = res_tmp_nrg_Q; + } + + /* Convert to NLSFs */ + SKP_Silk_A2NLSF( NLSF_Q15, a_tmp_Q16, LPC_order ); + + /* Search over interpolation indices to find the one with lowest residual energy */ + res_nrg_2nd = SKP_int32_MAX; + for( k = 3; k >= 0; k-- ) { + /* Interpolate NLSFs for first half */ + SKP_Silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order ); + + /* Convert to LPC for residual energy evaluation */ + SKP_Silk_NLSF2A_stable( a_tmp_Q12, NLSF0_Q15, LPC_order ); + + /* Calculate residual energy with NLSF interpolation */ + SKP_Silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, LPC_order ); + + SKP_Silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + LPC_order, subfr_length - LPC_order ); + SKP_Silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + LPC_order + subfr_length, subfr_length - LPC_order ); + + /* Add subframe energies from first half frame */ + shift = rshift0 - rshift1; + if( shift >= 0 ) { + res_nrg1 = SKP_RSHIFT( res_nrg1, shift ); + res_nrg_interp_Q = -rshift0; + } else { + res_nrg0 = SKP_RSHIFT( res_nrg0, -shift ); + res_nrg_interp_Q = -rshift1; + } + res_nrg_interp = SKP_ADD32( res_nrg0, res_nrg1 ); + + /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */ + shift = res_nrg_interp_Q - res_nrg_Q; + if( shift >= 0 ) { + if( SKP_RSHIFT( res_nrg_interp, shift ) < res_nrg ) { + isInterpLower = SKP_TRUE; + } else { + isInterpLower = SKP_FALSE; + } + } else { + if( -shift < 32 ) { + if( res_nrg_interp < SKP_RSHIFT( res_nrg, -shift ) ) { + isInterpLower = SKP_TRUE; + } else { + isInterpLower = SKP_FALSE; + } + } else { + isInterpLower = SKP_FALSE; + } + } + + /* Determine whether current interpolated NLSFs are best so far */ + if( isInterpLower == SKP_TRUE ) { + /* Interpolation has lower residual energy */ + res_nrg = res_nrg_interp; + res_nrg_Q = res_nrg_interp_Q; + *interpIndex = (SKP_int8)k; + } + res_nrg_2nd = res_nrg_interp; + res_nrg_2nd_Q = res_nrg_interp_Q; + } + } + + if( *interpIndex == 4 ) { + /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ + SKP_Silk_A2NLSF( NLSF_Q15, a_Q16, LPC_order ); + } + + SKP_assert( *interpIndex == 4 || ( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) ); +} diff --git a/silk/fixed/SKP_Silk_find_LTP_FIX.c b/silk/fixed/SKP_Silk_find_LTP_FIX.c new file mode 100644 index 00000000..50aeb562 --- /dev/null +++ b/silk/fixed/SKP_Silk_find_LTP_FIX.c @@ -0,0 +1,241 @@ +/*********************************************************************** +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" +#include "SKP_Silk_tuning_parameters.h" + +/* Head room for correlations */ +#define LTP_CORRS_HEAD_ROOM 2 + +void SKP_Silk_fit_LTP( + SKP_int32 LTP_coefs_Q16[ LTP_ORDER ], + SKP_int16 LTP_coefs_Q14[ LTP_ORDER ] +); + +void SKP_Silk_find_LTP_FIX( + SKP_int16 b_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ + SKP_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ + SKP_int *LTPredCodGain_Q7, /* O LTP coding gain */ + const SKP_int16 r_lpc[] , /* I residual signal after LPC signal + state for first 10 ms */ + const SKP_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ + const SKP_int32 Wght_Q15[ MAX_NB_SUBFR ], /* I weights */ + const SKP_int subfr_length, /* I subframe length */ + const SKP_int nb_subfr, /* I number of subframes */ + const SKP_int mem_offset, /* I number of samples in LTP memory */ + SKP_int corr_rshifts[ MAX_NB_SUBFR ] /* O right shifts applied to correlations */ +) +{ + SKP_int i, k, lshift; + const SKP_int16 *r_ptr, *lag_ptr; + SKP_int16 *b_Q14_ptr; + + SKP_int32 regu; + SKP_int32 *WLTP_ptr; + SKP_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], g_Q26; + SKP_int32 w[ MAX_NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits; + + SKP_int32 temp32, denom32; + SKP_int extra_shifts; + SKP_int rr_shifts, maxRshifts, maxRshifts_wxtra, LZs; + SKP_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16; + SKP_int32 Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ]; + SKP_int32 wd, m_Q12; + + b_Q14_ptr = b_Q14; + WLTP_ptr = WLTP; + r_ptr = &r_lpc[ mem_offset ]; + for( k = 0; k < nb_subfr; k++ ) { + lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); + + SKP_Silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */ + + /* Assure headroom */ + LZs = SKP_Silk_CLZ32( rr[k] ); + if( LZs < LTP_CORRS_HEAD_ROOM ) { + rr[ k ] = SKP_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs ); + rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs ); + } + corr_rshifts[ k ] = rr_shifts; + SKP_Silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ] ); /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */ + + /* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */ + SKP_Silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ] ); /* Rr_fix_ptr in Q( -corr_rshifts[ k ] ) */ + if( corr_rshifts[ k ] > rr_shifts ) { + rr[ k ] = SKP_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */ + } + SKP_assert( rr[ k ] >= 0 ); + + regu = 1; + regu = SKP_SMLAWB( regu, rr[ k ], SKP_FIX_CONST( LTP_DAMPING/3, 16 ) ); + regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SKP_FIX_CONST( LTP_DAMPING/3, 16 ) ); + regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SKP_FIX_CONST( LTP_DAMPING/3, 16 ) ); + SKP_Silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER ); + + SKP_Silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */ + + /* Limit and store in Q14 */ + SKP_Silk_fit_LTP( b_Q16, b_Q14_ptr ); + + /* Calculate residual energy */ + nrg[ k ] = SKP_Silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */ + + /* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */ + extra_shifts = SKP_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM ); + denom32 = SKP_LSHIFT_SAT32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */ + SKP_RSHIFT( SKP_SMULWB( subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */ + denom32 = SKP_max( denom32, 1 ); + SKP_assert( ((SKP_int64)Wght_Q15[ k ] << 16 ) < SKP_int32_MAX ); /* Wght always < 0.5 in Q0 */ + temp32 = SKP_DIV32( SKP_LSHIFT( ( SKP_int32 )Wght_Q15[ k ], 16 ), denom32 ); /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */ + temp32 = SKP_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 ); /* Q26 */ + + /* Limit temp such that the below scaling never wraps around */ + WLTP_max = 0; + for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) { + WLTP_max = SKP_max( WLTP_ptr[ i ], WLTP_max ); + } + lshift = SKP_Silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */ + SKP_assert( 26 - 18 + lshift >= 0 ); + if( 26 - 18 + lshift < 31 ) { + temp32 = SKP_min_32( temp32, SKP_LSHIFT( ( SKP_int32 )1, 26 - 18 + lshift ) ); + } + + SKP_Silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */ + + w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER/2, LTP_ORDER/2, LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */ + SKP_assert( w[k] >= 0 ); + + r_ptr += subfr_length; + b_Q14_ptr += LTP_ORDER; + WLTP_ptr += LTP_ORDER * LTP_ORDER; + } + + maxRshifts = 0; + for( k = 0; k < nb_subfr; k++ ) { + maxRshifts = SKP_max_int( corr_rshifts[ k ], maxRshifts ); + } + + /* Compute LTP coding gain */ + if( LTPredCodGain_Q7 != NULL ) { + LPC_LTP_res_nrg = 0; + LPC_res_nrg = 0; + SKP_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */ + for( k = 0; k < nb_subfr; k++ ) { + LPC_res_nrg = SKP_ADD32( LPC_res_nrg, SKP_RSHIFT( SKP_ADD32( SKP_SMULWB( rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */ + LPC_LTP_res_nrg = SKP_ADD32( LPC_LTP_res_nrg, SKP_RSHIFT( SKP_ADD32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */ + } + LPC_LTP_res_nrg = SKP_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */ + + div_Q16 = SKP_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 ); + *LTPredCodGain_Q7 = ( SKP_int )SKP_SMULBB( 3, SKP_Silk_lin2log( div_Q16 ) - ( 16 << 7 ) ); + + SKP_assert( *LTPredCodGain_Q7 == ( SKP_int )SKP_SAT16( SKP_MUL( 3, SKP_Silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) ); + } + + /* smoothing */ + /* d = sum( B, 1 ); */ + b_Q14_ptr = b_Q14; + for( k = 0; k < nb_subfr; k++ ) { + d_Q14[ k ] = 0; + for( i = 0; i < LTP_ORDER; i++ ) { + d_Q14[ k ] += b_Q14_ptr[ i ]; + } + b_Q14_ptr += LTP_ORDER; + } + + /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */ + + /* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */ + max_abs_d_Q14 = 0; + max_w_bits = 0; + for( k = 0; k < nb_subfr; k++ ) { + max_abs_d_Q14 = SKP_max_32( max_abs_d_Q14, SKP_abs( d_Q14[ k ] ) ); + /* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */ + /* Find bits needed in Q( 18 - maxRshifts ) */ + max_w_bits = SKP_max_32( max_w_bits, 32 - SKP_Silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts ); + } + + /* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -SKP_int16_MIN */ + SKP_assert( max_abs_d_Q14 <= ( 5 << 15 ) ); + + /* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */ + extra_shifts = max_w_bits + 32 - SKP_Silk_CLZ32( max_abs_d_Q14 ) - 14; + + /* Subtract what we got available; bits in output var plus maxRshifts */ + extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */ + extra_shifts = SKP_max_int( extra_shifts, 0 ); + + maxRshifts_wxtra = maxRshifts + extra_shifts; + + temp32 = SKP_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */ + wd = 0; + for( k = 0; k < nb_subfr; k++ ) { + /* w has at least 2 bits of headroom so no overflow should happen */ + temp32 = SKP_ADD32( temp32, SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) ); /* Q( 18 - maxRshifts_wxtra ) */ + wd = SKP_ADD32( wd, SKP_LSHIFT( SKP_SMULWW( SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */ + } + m_Q12 = SKP_DIV32_varQ( wd, temp32, 12 ); + + b_Q14_ptr = b_Q14; + for( k = 0; k < nb_subfr; k++ ) { + /* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */ + if( 2 - corr_rshifts[k] > 0 ) { + temp32 = SKP_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] ); + } else { + temp32 = SKP_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 ); + } + + g_Q26 = SKP_MUL( + SKP_DIV32( + SKP_FIX_CONST( LTP_SMOOTHING, 26 ), + SKP_RSHIFT( SKP_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ), /* Q10 */ + SKP_LSHIFT_SAT32( SKP_SUB_SAT32( ( SKP_int32 )m_Q12, SKP_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) ); /* Q16 */ + + temp32 = 0; + for( i = 0; i < LTP_ORDER; i++ ) { + delta_b_Q14[ i ] = SKP_max_16( b_Q14_ptr[ i ], 1638 ); /* 1638_Q14 = 0.1_Q0 */ + temp32 += delta_b_Q14[ i ]; /* Q14 */ + } + temp32 = SKP_DIV32( g_Q26, temp32 ); /* Q14->Q12 */ + for( i = 0; i < LTP_ORDER; i++ ) { + b_Q14_ptr[ i ] = SKP_LIMIT_32( ( SKP_int32 )b_Q14_ptr[ i ] + SKP_SMULWB( SKP_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 ); + } + b_Q14_ptr += LTP_ORDER; + } +TOC(find_LTP_FIX) +} + +void SKP_Silk_fit_LTP( + SKP_int32 LTP_coefs_Q16[ LTP_ORDER ], + SKP_int16 LTP_coefs_Q14[ LTP_ORDER ] +) +{ + SKP_int i; + + for( i = 0; i < LTP_ORDER; i++ ) { + LTP_coefs_Q14[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) ); + } +} diff --git a/silk/fixed/SKP_Silk_find_pitch_lags_FIX.c b/silk/fixed/SKP_Silk_find_pitch_lags_FIX.c new file mode 100644 index 00000000..bfc3e36b --- /dev/null +++ b/silk/fixed/SKP_Silk_find_pitch_lags_FIX.c @@ -0,0 +1,133 @@ +/*********************************************************************** +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" +#include "SKP_Silk_tuning_parameters.h" + +/* Find pitch lags */ +void SKP_Silk_find_pitch_lags_FIX( + SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */ + SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ + SKP_int16 res[], /* O residual */ + const SKP_int16 x[] /* I Speech signal */ +) +{ + SKP_int buf_len, i, scale; + SKP_int32 thrhld_Q15, res_nrg; + const SKP_int16 *x_buf, *x_buf_ptr; + SKP_int16 Wsig[ FIND_PITCH_LPC_WIN_MAX ], *Wsig_ptr; + SKP_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; + SKP_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ]; + SKP_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ]; + SKP_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ]; + + /******************************************/ + /* Setup buffer lengths etc based on Fs */ + /******************************************/ + buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; + + /* Safty check */ + SKP_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); + + x_buf = x - psEnc->sCmn.ltp_mem_length; + + /*************************************/ + /* Estimate LPC AR coefficients */ + /*************************************/ + + /* Calculate windowed signal */ + + /* First LA_LTP samples */ + x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length; + Wsig_ptr = Wsig; + SKP_Silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch ); + + /* Middle un - windowed samples */ + Wsig_ptr += psEnc->sCmn.la_pitch; + x_buf_ptr += psEnc->sCmn.la_pitch; + SKP_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( SKP_int16 ) ); + + /* Last LA_LTP samples */ + Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ); + x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ); + SKP_Silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch ); + + /* Calculate autocorrelation sequence */ + SKP_Silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 ); + + /* Add white noise, as fraction of energy */ + auto_corr[ 0 ] = SKP_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SKP_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1; + + /* Calculate the reflection coefficients using schur */ + res_nrg = SKP_Silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); + + /* Prediction gain */ + psEncCtrl->predGain_Q16 = SKP_DIV32_varQ( auto_corr[ 0 ], SKP_max_int( res_nrg, 1 ), 16 ); + + /* Convert reflection coefficients to prediction coefficients */ + SKP_Silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder ); + + /* Convert From 32 bit Q24 to 16 bit Q12 coefs */ + for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) { + A_Q12[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT( A_Q24[ i ], 12 ) ); + } + + /* Do BWE */ + SKP_Silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SKP_FIX_CONST( FIND_PITCH_BANDWITH_EXPANSION, 16 ) ); + + /*****************************************/ + /* LPC analysis filtering */ + /*****************************************/ + SKP_Silk_LPC_analysis_filter( res, x_buf, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder ); + + if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { + /* Threshold for pitch estimator */ + thrhld_Q15 = SKP_FIX_CONST( 0.6, 15 ); + thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( -0.004, 15 ), psEnc->sCmn.pitchEstimationLPCOrder ); + thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( -0.1, 7 ), psEnc->sCmn.speech_activity_Q8 ); + thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( -0.15, 15 ), SKP_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) ); + thrhld_Q15 = SKP_SMLAWB( thrhld_Q15, SKP_FIX_CONST( -0.1, 16 ), psEnc->sCmn.input_tilt_Q15 ); + thrhld_Q15 = SKP_SAT16( thrhld_Q15 ); + + /*****************************************/ + /* Call pitch estimator */ + /*****************************************/ + if( SKP_Silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex, + &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16, + ( SKP_int16 )thrhld_Q15, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 ) + { + psEnc->sCmn.indices.signalType = TYPE_VOICED; + } else { + psEnc->sCmn.indices.signalType = TYPE_UNVOICED; + } + } else { + SKP_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); + psEnc->sCmn.indices.lagIndex = 0; + psEnc->sCmn.indices.contourIndex = 0; + psEnc->LTPCorr_Q15 = 0; + } +} diff --git a/silk/fixed/SKP_Silk_find_pred_coefs_FIX.c b/silk/fixed/SKP_Silk_find_pred_coefs_FIX.c new file mode 100644 index 00000000..532a695b --- /dev/null +++ b/silk/fixed/SKP_Silk_find_pred_coefs_FIX.c @@ -0,0 +1,127 @@ +/*********************************************************************** +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" + +void SKP_Silk_find_pred_coefs_FIX( + SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */ + SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ + const SKP_int16 res_pitch[], /* I Residual from pitch analysis */ + const SKP_int16 x[] /* I Speech signal */ +) +{ + SKP_int i; + SKP_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; + SKP_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ]; + SKP_int16 NLSF_Q15[ MAX_LPC_ORDER ]; + const SKP_int16 *x_ptr; + SKP_int16 *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; + SKP_int32 tmp, min_gain_Q16; + SKP_int LTP_corrs_rshift[ MAX_NB_SUBFR ]; + + /* weighting for weighted least squares */ + min_gain_Q16 = SKP_int32_MAX >> 6; + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + min_gain_Q16 = SKP_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] ); + } + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + /* Divide to Q16 */ + SKP_assert( psEncCtrl->Gains_Q16[ i ] > 0 ); + /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */ + invGains_Q16[ i ] = SKP_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 ); + + /* Ensure Wght_Q15 a minimum value 1 */ + invGains_Q16[ i ] = SKP_max( invGains_Q16[ i ], 363 ); + + /* Square the inverted gains */ + SKP_assert( invGains_Q16[ i ] == SKP_SAT16( invGains_Q16[ i ] ) ); + tmp = SKP_SMULWB( invGains_Q16[ i ], invGains_Q16[ i ] ); + Wght_Q15[ i ] = SKP_RSHIFT( tmp, 1 ); + + /* Invert the inverted and normalized gains */ + local_gains[ i ] = SKP_DIV32( ( 1 << 16 ), invGains_Q16[ i ] ); + } + + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /**********/ + /* VOICED */ + /**********/ + SKP_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); + + /* LTP analysis */ + SKP_Silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7, + res_pitch, psEncCtrl->pitchL, Wght_Q15, psEnc->sCmn.subfr_length, + psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length, LTP_corrs_rshift ); + + /* Quantize LTP gain parameters */ + SKP_Silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, + WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr); + + /* Control LTP scaling */ + SKP_Silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl ); + + /* Create LTP residual */ + SKP_Silk_LTP_analysis_filter_FIX( LPC_in_pre, psEnc->x_buf + psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder, + psEncCtrl->LTPCoef_Q14, psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); + + } else { + /************/ + /* UNVOICED */ + /************/ + /* Create signal with prepended subframes, scaled by inverse gains */ + x_ptr = x - psEnc->sCmn.predictLPCOrder; + x_pre_ptr = LPC_in_pre; + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + SKP_Silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ], + psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); + x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; + x_ptr += psEnc->sCmn.subfr_length; + } + + SKP_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_int16 ) ); + psEncCtrl->LTPredCodGain_Q7 = 0; + } + + /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ + TIC(FIND_LPC) + SKP_Silk_find_LPC_FIX( NLSF_Q15, &psEnc->sCmn.indices.NLSFInterpCoef_Q2, psEnc->sCmn.prev_NLSFq_Q15, + psEnc->sCmn.useInterpolatedNLSFs, psEnc->sCmn.first_frame_after_reset, psEnc->sCmn.predictLPCOrder, + LPC_in_pre, psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder, psEnc->sCmn.nb_subfr ); + TOC(FIND_LPC) + + /* Quantize LSFs */ + TIC(PROCESS_LSFS) + SKP_Silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); + TOC(PROCESS_LSFS) + + /* Calculate residual energy using quantized LPC coefficients */ + SKP_Silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains, + psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); + + /* Copy to prediction struct for use in next frame for fluctuation reduction */ + SKP_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); +} diff --git a/silk/fixed/SKP_Silk_noise_shape_analysis_FIX.c b/silk/fixed/SKP_Silk_noise_shape_analysis_FIX.c new file mode 100644 index 00000000..b8d804c9 --- /dev/null +++ b/silk/fixed/SKP_Silk_noise_shape_analysis_FIX.c @@ -0,0 +1,433 @@ +/*********************************************************************** +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" +#include "SKP_Silk_tuning_parameters.h" + +/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ +/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ +SKP_INLINE SKP_int32 warped_gain( // gain in Q16 + const SKP_int32 *coefs_Q24, + SKP_int lambda_Q16, + SKP_int order +) { + SKP_int i; + SKP_int32 gain_Q24; + + lambda_Q16 = -lambda_Q16; + gain_Q24 = coefs_Q24[ order - 1 ]; + for( i = order - 2; i >= 0; i-- ) { + gain_Q24 = SKP_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 ); + } + gain_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 ); + return SKP_INVERSE32_varQ( gain_Q24, 40 ); +} + +/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ +/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ +SKP_INLINE void limit_warped_coefs( + SKP_int32 *coefs_syn_Q24, + SKP_int32 *coefs_ana_Q24, + SKP_int lambda_Q16, + SKP_int32 limit_Q24, + SKP_int order +) { + SKP_int i, iter, ind = 0; + SKP_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16; + SKP_int32 nom_Q16, den_Q24; + + /* Convert to monic coefficients */ + lambda_Q16 = -lambda_Q16; + for( i = order - 1; i > 0; i-- ) { + coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); + coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); + } + lambda_Q16 = -lambda_Q16; + nom_Q16 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 16 ), -lambda_Q16, lambda_Q16 ); + den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); + gain_syn_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); + den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); + gain_ana_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); + for( i = 0; i < order; i++ ) { + coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); + coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); + } + + for( iter = 0; iter < 10; iter++ ) { + /* Find maximum absolute value */ + maxabs_Q24 = -1; + for( i = 0; i < order; i++ ) { + tmp = SKP_max( SKP_abs_int32( coefs_syn_Q24[ i ] ), SKP_abs_int32( coefs_ana_Q24[ i ] ) ); + if( tmp > maxabs_Q24 ) { + maxabs_Q24 = tmp; + ind = i; + } + } + if( maxabs_Q24 <= limit_Q24 ) { + /* Coefficients are within range - done */ + return; + } + + /* Convert back to true warped coefficients */ + for( i = 1; i < order; i++ ) { + coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); + coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); + } + gain_syn_Q16 = SKP_INVERSE32_varQ( gain_syn_Q16, 32 ); + gain_ana_Q16 = SKP_INVERSE32_varQ( gain_ana_Q16, 32 ); + for( i = 0; i < order; i++ ) { + coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); + coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); + } + + /* Apply bandwidth expansion */ + chirp_Q16 = SKP_FIX_CONST( 0.99, 16 ) - SKP_DIV32_varQ( + SKP_SMULWB( maxabs_Q24 - limit_Q24, SKP_SMLABB( SKP_FIX_CONST( 0.8, 10 ), SKP_FIX_CONST( 0.1, 10 ), iter ) ), + SKP_MUL( maxabs_Q24, ind + 1 ), 22 ); + SKP_Silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 ); + SKP_Silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 ); + + /* Convert to monic warped coefficients */ + lambda_Q16 = -lambda_Q16; + for( i = order - 1; i > 0; i-- ) { + coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); + coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); + } + lambda_Q16 = -lambda_Q16; + nom_Q16 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 16 ), -lambda_Q16, lambda_Q16 ); + den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); + gain_syn_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); + den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); + gain_ana_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); + for( i = 0; i < order; i++ ) { + coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); + coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); + } + } + SKP_assert( 0 ); +} + +/**************************************************************/ +/* Compute noise shaping coefficients and initial gain values */ +/**************************************************************/ +void SKP_Silk_noise_shape_analysis_FIX( + SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ + SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ + const SKP_int16 *pitch_res, /* I LPC residual from pitch analysis */ + const SKP_int16 *x /* I Input signal [ frame_length + la_shape ] */ +) +{ + SKP_Silk_shape_state_FIX *psShapeSt = &psEnc->sShape; + SKP_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0; + SKP_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32; + SKP_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7; + SKP_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8; + SKP_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; + SKP_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ]; + SKP_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ]; + SKP_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ]; + SKP_int16 x_windowed[ SHAPE_LPC_WIN_MAX ]; + SKP_int32 sqrt_nrg[ MAX_NB_SUBFR ], Qnrg_vec[ MAX_NB_SUBFR ]; + const SKP_int16 *x_ptr, *pitch_res_ptr; + + /* Point to start of first LPC analysis block */ + x_ptr = x - psEnc->sCmn.la_shape; + + /****************/ + /* GAIN CONTROL */ + /****************/ + SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7; + + /* Input quality is the average of the quality in the lowest two VAD bands */ + psEncCtrl->input_quality_Q14 = ( SKP_int )SKP_RSHIFT( ( SKP_int32 )psEnc->sCmn.input_quality_bands_Q15[ 0 ] + + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 ); + + /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */ + psEncCtrl->coding_quality_Q14 = SKP_RSHIFT( SKP_Silk_sigm_Q15( SKP_RSHIFT_ROUND( SNR_adj_dB_Q7 - + SKP_FIX_CONST( 18.0, 7 ), 4 ) ), 1 ); + + /* Reduce coding SNR during low speech activity */ + if( psEnc->sCmn.useCBR == 0 ) { + b_Q8 = SKP_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8; + b_Q8 = SKP_SMULWB( SKP_LSHIFT( b_Q8, 8 ), b_Q8 ); + SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, + SKP_SMULBB( SKP_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), // Q11 + SKP_SMULWB( SKP_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); // Q12 + } + + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Reduce gains for periodic signals */ + SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SKP_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 ); + } else { + /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ + SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, + SKP_SMLAWB( SKP_FIX_CONST( 6.0, 9 ), -SKP_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ), + SKP_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 ); + } + + /*************************/ + /* SPARSENESS PROCESSING */ + /*************************/ + /* Set quantizer offset */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Initally set to 0; may be overruled in process_gains(..) */ + psEnc->sCmn.indices.quantOffsetType = 0; + psEncCtrl->sparseness_Q8 = 0; + } else { + /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ + nSamples = SKP_LSHIFT( psEnc->sCmn.fs_kHz, 1 ); + energy_variation_Q7 = 0; + log_energy_prev_Q7 = 0; + pitch_res_ptr = pitch_res; + for( k = 0; k < SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) { + SKP_Silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples ); + nrg += SKP_RSHIFT( nSamples, scale ); // Q(-scale) + + log_energy_Q7 = SKP_Silk_lin2log( nrg ); + if( k > 0 ) { + energy_variation_Q7 += SKP_abs( log_energy_Q7 - log_energy_prev_Q7 ); + } + log_energy_prev_Q7 = log_energy_Q7; + pitch_res_ptr += nSamples; + } + + psEncCtrl->sparseness_Q8 = SKP_RSHIFT( SKP_Silk_sigm_Q15( SKP_SMULWB( energy_variation_Q7 - + SKP_FIX_CONST( 5.0, 7 ), SKP_FIX_CONST( 0.1, 16 ) ) ), 7 ); + + /* Set quantization offset depending on sparseness measure */ + if( psEncCtrl->sparseness_Q8 > SKP_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) { + psEnc->sCmn.indices.quantOffsetType = 0; + } else { + psEnc->sCmn.indices.quantOffsetType = 1; + } + + /* Increase coding SNR for sparse signals */ + SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SKP_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SKP_FIX_CONST( 0.5, 8 ) ); + } + + /*******************************/ + /* Control bandwidth expansion */ + /*******************************/ + /* More BWE for signals with high prediction gain */ + strength_Q16 = SKP_SMULWB( psEncCtrl->predGain_Q16, SKP_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ); + BWExp1_Q16 = BWExp2_Q16 = SKP_DIV32_varQ( SKP_FIX_CONST( BANDWIDTH_EXPANSION, 16 ), + SKP_SMLAWW( SKP_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 ); + delta_Q16 = SKP_SMULWB( SKP_FIX_CONST( 1.0, 16 ) - SKP_SMULBB( 3, psEncCtrl->coding_quality_Q14 ), + SKP_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) ); + BWExp1_Q16 = SKP_SUB32( BWExp1_Q16, delta_Q16 ); + BWExp2_Q16 = SKP_ADD32( BWExp2_Q16, delta_Q16 ); + /* BWExp1 will be applied after BWExp2, so make it relative */ + BWExp1_Q16 = SKP_DIV32_16( SKP_LSHIFT( BWExp1_Q16, 14 ), SKP_RSHIFT( BWExp2_Q16, 2 ) ); + + if( psEnc->sCmn.warping_Q16 > 0 ) { + /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ + warping_Q16 = SKP_SMLAWB( psEnc->sCmn.warping_Q16, psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( 0.01, 18 ) ); + } else { + warping_Q16 = 0; + } + + /********************************************/ + /* Compute noise shaping AR coefs and gains */ + /********************************************/ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + /* Apply window: sine slope followed by flat part followed by cosine slope */ + SKP_int shift, slope_part, flat_part; + flat_part = psEnc->sCmn.fs_kHz * 3; + slope_part = SKP_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 ); + + SKP_Silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part ); + shift = slope_part; + SKP_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(SKP_int16) ); + shift += flat_part; + SKP_Silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part ); + + /* Update pointer: next LPC analysis block */ + x_ptr += psEnc->sCmn.subfr_length; + + if( psEnc->sCmn.warping_Q16 > 0 ) { + /* Calculate warped auto correlation */ + SKP_Silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); + } else { + /* Calculate regular auto correlation */ + SKP_Silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 ); + } + + /* Add white noise, as a fraction of energy */ + auto_corr[0] = SKP_ADD32( auto_corr[0], SKP_max_32( SKP_SMULWB( SKP_RSHIFT( auto_corr[ 0 ], 4 ), + SKP_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) ); + + /* Calculate the reflection coefficients using schur */ + nrg = SKP_Silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder ); + SKP_assert( nrg >= 0 ); + + /* Convert reflection coefficients to prediction coefficients */ + SKP_Silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder ); + + Qnrg = -scale; // range: -12...30 + SKP_assert( Qnrg >= -12 ); + SKP_assert( Qnrg <= 30 ); + + /* Make sure that Qnrg is an even number */ + if( Qnrg & 1 ) { + Qnrg -= 1; + nrg >>= 1; + } + + tmp32 = SKP_Silk_SQRT_APPROX( nrg ); + Qnrg >>= 1; // range: -6...15 + + sqrt_nrg[ k ] = tmp32; + Qnrg_vec[ k ] = Qnrg; + + psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( tmp32, 16 - Qnrg ); + + if( psEnc->sCmn.warping_Q16 > 0 ) { + /* Adjust gain for warping */ + gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder ); + psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); + } + + /* Bandwidth expansion for synthesis filter shaping */ + SKP_Silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 ); + + /* Compute noise shaping filter coefficients */ + SKP_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( SKP_int32 ) ); + + /* Bandwidth expansion for analysis filter shaping */ + SKP_assert( BWExp1_Q16 <= SKP_FIX_CONST( 1.0, 16 ) ); + SKP_Silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 ); + + /* Ratio of prediction gains, in energy domain */ + SKP_Silk_LPC_inverse_pred_gain_Q24( &pre_nrg_Q30, AR2_Q24, psEnc->sCmn.shapingLPCOrder ); + SKP_Silk_LPC_inverse_pred_gain_Q24( &nrg, AR1_Q24, psEnc->sCmn.shapingLPCOrder ); + + //psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg; + pre_nrg_Q30 = SKP_LSHIFT32( SKP_SMULWB( pre_nrg_Q30, SKP_FIX_CONST( 0.7, 15 ) ), 1 ); + psEncCtrl->GainsPre_Q14[ k ] = ( SKP_int ) SKP_FIX_CONST( 0.3, 14 ) + SKP_DIV32_varQ( pre_nrg_Q30, nrg, 14 ); + + /* Convert to monic warped prediction coefficients and limit absolute values */ + limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SKP_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder ); + + /* Convert from Q24 to Q13 and store in int16 */ + for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) { + psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) ); + psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) ); + } + } + + /*****************/ + /* Gain tweaking */ + /*****************/ + /* Increase gains during low speech activity and put lower limit on gains */ + gain_mult_Q16 = SKP_Silk_log2lin( -SKP_SMLAWB( -SKP_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SKP_FIX_CONST( 0.16, 16 ) ) ); + gain_add_Q16 = SKP_Silk_log2lin( SKP_SMLAWB( SKP_FIX_CONST( 16.0, 7 ), SKP_FIX_CONST( MIN_QGAIN_DB, 7 ), SKP_FIX_CONST( 0.16, 16 ) ) ); + SKP_assert( gain_mult_Q16 > 0 ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); + SKP_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); + psEncCtrl->Gains_Q16[ k ] = SKP_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 ); + } + + gain_mult_Q16 = SKP_FIX_CONST( 1.0, 16 ) + SKP_RSHIFT_ROUND( SKP_MLA( SKP_FIX_CONST( INPUT_TILT, 26 ), + psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->GainsPre_Q14[ k ] = SKP_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] ); + } + + /************************************************/ + /* Control low-frequency shaping and noise tilt */ + /************************************************/ + /* Less low frequency shaping for noisy inputs */ + strength_Q16 = SKP_MUL( SKP_FIX_CONST( LOW_FREQ_SHAPING, 4 ), SKP_SMLAWB( SKP_FIX_CONST( 1.0, 12 ), + SKP_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SKP_FIX_CONST( 1.0, 15 ) ) ); + strength_Q16 = SKP_RSHIFT( SKP_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 ); + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ + /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ + SKP_int fs_kHz_inv = SKP_DIV32_16( SKP_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + b_Q14 = fs_kHz_inv + SKP_DIV32_16( SKP_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] ); + /* Pack two coefficients in one int32 */ + psEncCtrl->LF_shp_Q14[ k ] = SKP_LSHIFT( SKP_FIX_CONST( 1.0, 14 ) - b_Q14 - SKP_SMULWB( strength_Q16, b_Q14 ), 16 ); + psEncCtrl->LF_shp_Q14[ k ] |= (SKP_uint16)( b_Q14 - SKP_FIX_CONST( 1.0, 14 ) ); + } + SKP_assert( SKP_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SKP_FIX_CONST( 0.5, 24 ) ); // Guarantees that second argument to SMULWB() is within range of an SKP_int16 + Tilt_Q16 = - SKP_FIX_CONST( HP_NOISE_COEF, 16 ) - + SKP_SMULWB( SKP_FIX_CONST( 1.0, 16 ) - SKP_FIX_CONST( HP_NOISE_COEF, 16 ), + SKP_SMULWB( SKP_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) ); + } else { + b_Q14 = SKP_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); // 1.3_Q0 = 21299_Q14 + /* Pack two coefficients in one int32 */ + psEncCtrl->LF_shp_Q14[ 0 ] = SKP_LSHIFT( SKP_FIX_CONST( 1.0, 14 ) - b_Q14 - + SKP_SMULWB( strength_Q16, SKP_SMULWB( SKP_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 ); + psEncCtrl->LF_shp_Q14[ 0 ] |= (SKP_uint16)( b_Q14 - SKP_FIX_CONST( 1.0, 14 ) ); + for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ]; + } + Tilt_Q16 = -SKP_FIX_CONST( HP_NOISE_COEF, 16 ); + } + + /****************************/ + /* HARMONIC SHAPING CONTROL */ + /****************************/ + /* Control boosting of harmonic frequencies */ + HarmBoost_Q16 = SKP_SMULWB( SKP_SMULWB( SKP_FIX_CONST( 1.0, 17 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ), + psEnc->LTPCorr_Q15 ), SKP_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) ); + + /* More harmonic boost for noisy input signals */ + HarmBoost_Q16 = SKP_SMLAWB( HarmBoost_Q16, + SKP_FIX_CONST( 1.0, 16 ) - SKP_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SKP_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) ); + + if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* More harmonic noise shaping for high bitrates or noisy input */ + HarmShapeGain_Q16 = SKP_SMLAWB( SKP_FIX_CONST( HARMONIC_SHAPING, 16 ), + SKP_FIX_CONST( 1.0, 16 ) - SKP_SMULWB( SKP_FIX_CONST( 1.0, 18 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ), + psEncCtrl->input_quality_Q14 ), SKP_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) ); + + /* Less harmonic noise shaping for less periodic signals */ + HarmShapeGain_Q16 = SKP_SMULWB( SKP_LSHIFT( HarmShapeGain_Q16, 1 ), + SKP_Silk_SQRT_APPROX( SKP_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) ); + } else { + HarmShapeGain_Q16 = 0; + } + + /*************************/ + /* Smooth over subframes */ + /*************************/ + for( k = 0; k < MAX_NB_SUBFR; k++ ) { + psShapeSt->HarmBoost_smth_Q16 = + SKP_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SKP_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); + psShapeSt->HarmShapeGain_smth_Q16 = + SKP_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SKP_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); + psShapeSt->Tilt_smth_Q16 = + SKP_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SKP_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); + + psEncCtrl->HarmBoost_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 ); + psEncCtrl->HarmShapeGain_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 ); + psEncCtrl->Tilt_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 ); + } +} diff --git a/silk/fixed/SKP_Silk_prefilter_FIX.c b/silk/fixed/SKP_Silk_prefilter_FIX.c new file mode 100644 index 00000000..58be293f --- /dev/null +++ b/silk/fixed/SKP_Silk_prefilter_FIX.c @@ -0,0 +1,201 @@ +/*********************************************************************** +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" +#include "SKP_Silk_tuning_parameters.h" + +/* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal */ +SKP_INLINE void SKP_Silk_prefilt_FIX( + SKP_Silk_prefilter_state_FIX *P, /* I/O state */ + SKP_int32 st_res_Q12[], /* I short term residual signal */ + SKP_int16 xw[], /* O prefiltered signal */ + SKP_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */ + SKP_int Tilt_Q14, /* I Tilt shaping coeficient */ + SKP_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients*/ + SKP_int lag, /* I Lag for harmonic shaping */ + SKP_int length /* I Length of signals */ +); + +void SKP_Silk_warped_LPC_analysis_filter_FIX( + SKP_int32 state[], /* I/O State [order + 1] */ + SKP_int16 res[], /* O Residual signal [length] */ + const SKP_int16 coef_Q13[], /* I Coefficients [order] */ + const SKP_int16 input[], /* I Input signal [length] */ + const SKP_int16 lambda_Q16, /* I Warping factor */ + const SKP_int length, /* I Length of input signal */ + const SKP_int order /* I Filter order (even) */ +) +{ + SKP_int n, i; + SKP_int32 acc_Q11, tmp1, tmp2; + + /* Order must be even */ + SKP_assert( ( order & 1 ) == 0 ); + + for( n = 0; n < length; n++ ) { + /* Output of lowpass section */ + tmp2 = SKP_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 ); + state[ 0 ] = SKP_LSHIFT( input[ n ], 14 ); + /* Output of allpass section */ + tmp1 = SKP_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 ); + state[ 1 ] = tmp2; + acc_Q11 = SKP_SMULWB( tmp2, coef_Q13[ 0 ] ); + /* Loop over allpass sections */ + for( i = 2; i < order; i += 2 ) { + /* Output of allpass section */ + tmp2 = SKP_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 ); + state[ i ] = tmp1; + acc_Q11 = SKP_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] ); + /* Output of allpass section */ + tmp1 = SKP_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 ); + state[ i + 1 ] = tmp2; + acc_Q11 = SKP_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] ); + } + state[ order ] = tmp1; + acc_Q11 = SKP_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] ); + res[ n ] = ( SKP_int16 )SKP_SAT16( ( SKP_int32 )input[ n ] - SKP_RSHIFT_ROUND( acc_Q11, 11 ) ); + } +} + +void SKP_Silk_prefilter_FIX( + SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ + const SKP_Silk_encoder_control_FIX *psEncCtrl, /* I Encoder control FIX */ + SKP_int16 xw[], /* O Weighted signal */ + const SKP_int16 x[] /* I Speech signal */ +) +{ + SKP_Silk_prefilter_state_FIX *P = &psEnc->sPrefilt; + SKP_int j, k, lag; + SKP_int32 tmp_32; + const SKP_int16 *AR1_shp_Q13; + const SKP_int16 *px; + SKP_int16 *pxw; + SKP_int HarmShapeGain_Q12, Tilt_Q14; + SKP_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14; + SKP_int32 x_filt_Q12[ MAX_FRAME_LENGTH / MAX_NB_SUBFR ]; + SKP_int16 st_res[ ( MAX_FRAME_LENGTH / MAX_NB_SUBFR ) + MAX_LPC_ORDER ]; + SKP_int16 B_Q12[ 2 ]; + + /* Setup pointers */ + px = x; + pxw = xw; + lag = P->lagPrev; + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + /* Update Variables that change per sub frame */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + lag = psEncCtrl->pitchL[ k ]; + } + + /* Noise shape parameters */ + HarmShapeGain_Q12 = SKP_SMULWB( psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] ); + SKP_assert( HarmShapeGain_Q12 >= 0 ); + HarmShapeFIRPacked_Q12 = SKP_RSHIFT( HarmShapeGain_Q12, 2 ); + HarmShapeFIRPacked_Q12 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q12, 1 ), 16 ); + Tilt_Q14 = psEncCtrl->Tilt_Q14[ k ]; + LF_shp_Q14 = psEncCtrl->LF_shp_Q14[ k ]; + AR1_shp_Q13 = &psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER ]; + + /* Short term FIR filtering*/ + SKP_Silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res, AR1_shp_Q13, px, + psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder ); + + /* reduce (mainly) low frequencies during harmonic emphasis */ + B_Q12[ 0 ] = SKP_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 2 ); + tmp_32 = SKP_SMLABB( SKP_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 ); /* Q26 */ + tmp_32 = SKP_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ); /* Q26 */ + tmp_32 = SKP_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */ + tmp_32 = SKP_RSHIFT_ROUND( tmp_32, 12 ); /* Q12 */ + B_Q12[ 1 ]= SKP_SAT16( tmp_32 ); + + x_filt_Q12[ 0 ] = SKP_SMLABB( SKP_SMULBB( st_res[ 0 ], B_Q12[ 0 ] ), P->sHarmHP, B_Q12[ 1 ] ); + for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) { + x_filt_Q12[ j ] = SKP_SMLABB( SKP_SMULBB( st_res[ j ], B_Q12[ 0 ] ), st_res[ j - 1 ], B_Q12[ 1 ] ); + } + P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ]; + + SKP_Silk_prefilt_FIX( P, x_filt_Q12, pxw, HarmShapeFIRPacked_Q12, Tilt_Q14, + LF_shp_Q14, lag, psEnc->sCmn.subfr_length ); + + px += psEnc->sCmn.subfr_length; + pxw += psEnc->sCmn.subfr_length; + } + + P->lagPrev = psEncCtrl->pitchL[ MAX_NB_SUBFR - 1 ]; +} + +/* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal */ +SKP_INLINE void SKP_Silk_prefilt_FIX( + SKP_Silk_prefilter_state_FIX *P, /* I/O state */ + SKP_int32 st_res_Q12[], /* I short term residual signal */ + SKP_int16 xw[], /* O prefiltered signal */ + SKP_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */ + SKP_int Tilt_Q14, /* I Tilt shaping coeficient */ + SKP_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients*/ + SKP_int lag, /* I Lag for harmonic shaping */ + SKP_int length /* I Length of signals */ +) +{ + SKP_int i, idx, LTP_shp_buf_idx; + SKP_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10; + SKP_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12; + SKP_int16 *LTP_shp_buf; + + /* To speed up use temp variables instead of using the struct */ + LTP_shp_buf = P->sLTP_shp; + LTP_shp_buf_idx = P->sLTP_shp_buf_idx; + sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12; + sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12; + + for( i = 0; i < length; i++ ) { + if( lag > 0 ) { + /* unrolled loop */ + SKP_assert( HARM_SHAPE_FIR_TAPS == 3 ); + idx = lag + LTP_shp_buf_idx; + n_LTP_Q12 = SKP_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); + n_LTP_Q12 = SKP_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); + n_LTP_Q12 = SKP_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); + } else { + n_LTP_Q12 = 0; + } + + n_Tilt_Q10 = SKP_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 ); + n_LF_Q10 = SKP_SMLAWB( SKP_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 ); + + sLF_AR_shp_Q12 = SKP_SUB32( st_res_Q12[ i ], SKP_LSHIFT( n_Tilt_Q10, 2 ) ); + sLF_MA_shp_Q12 = SKP_SUB32( sLF_AR_shp_Q12, SKP_LSHIFT( n_LF_Q10, 2 ) ); + + LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK; + LTP_shp_buf[ LTP_shp_buf_idx ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) ); + + xw[i] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 12 ) ); + } + + /* Copy temp variable back to state */ + P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12; + P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12; + P->sLTP_shp_buf_idx = LTP_shp_buf_idx; +} diff --git a/silk/fixed/SKP_Silk_process_gains_FIX.c b/silk/fixed/SKP_Silk_process_gains_FIX.c new file mode 100644 index 00000000..c11502b0 --- /dev/null +++ b/silk/fixed/SKP_Silk_process_gains_FIX.c @@ -0,0 +1,108 @@ +/*********************************************************************** +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" +#include "SKP_Silk_tuning_parameters.h" + +/* Processing of gains */ +void SKP_Silk_process_gains_FIX( + SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state_FIX */ + SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O Encoder control_FIX */ +) +{ + SKP_Silk_shape_state_FIX *psShapeSt = &psEnc->sShape; + SKP_int k; + SKP_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10; + + /* Gain reduction when LTP coding gain is high */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /*s = -0.5f * SKP_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */ + s_Q16 = -SKP_Silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SKP_FIX_CONST( 12.0, 7 ), 4 ) ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->Gains_Q16[ k ] = SKP_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 ); + } + } + + /* Limit the quantized signal */ + /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */ + InvMaxSqrVal_Q16 = SKP_DIV32_16( SKP_Silk_log2lin( + SKP_SMULWB( SKP_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SKP_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length ); + + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + /* Soft limit on ratio residual energy and squared gains */ + ResNrg = psEncCtrl->ResNrg[ k ]; + ResNrgPart = SKP_SMULWW( ResNrg, InvMaxSqrVal_Q16 ); + if( psEncCtrl->ResNrgQ[ k ] > 0 ) { + ResNrgPart = SKP_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] ); + } else { + if( ResNrgPart >= SKP_RSHIFT( SKP_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) { + ResNrgPart = SKP_int32_MAX; + } else { + ResNrgPart = SKP_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] ); + } + } + gain = psEncCtrl->Gains_Q16[ k ]; + gain_squared = SKP_ADD_SAT32( ResNrgPart, SKP_SMMUL( gain, gain ) ); + if( gain_squared < SKP_int16_MAX ) { + /* recalculate with higher precision */ + gain_squared = SKP_SMLAWW( SKP_LSHIFT( ResNrgPart, 16 ), gain, gain ); + SKP_assert( gain_squared > 0 ); + gain = SKP_Silk_SQRT_APPROX( gain_squared ); /* Q8 */ + gain = SKP_min( gain, SKP_int32_MAX >> 8 ); + psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 8 ); /* Q16 */ + } else { + gain = SKP_Silk_SQRT_APPROX( gain_squared ); /* Q0 */ + gain = SKP_min( gain, SKP_int32_MAX >> 16 ); + psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 16 ); /* Q16 */ + } + } + + /* Noise shaping quantization */ + SKP_Silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16, + &psShapeSt->LastGainIndex, psEnc->sCmn.nFramesAnalyzed, psEnc->sCmn.nb_subfr ); + + /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + if( psEncCtrl->LTPredCodGain_Q7 + SKP_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SKP_FIX_CONST( 1.0, 7 ) ) { + psEnc->sCmn.indices.quantOffsetType = 0; + } else { + psEnc->sCmn.indices.quantOffsetType = 1; + } + } + + /* Quantizer boundary adjustment */ + quant_offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ]; + psEncCtrl->Lambda_Q10 = SKP_FIX_CONST( LAMBDA_OFFSET, 10 ) + + SKP_SMULBB( SKP_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision ) + + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_SPEECH_ACT, 18 ), psEnc->sCmn.speech_activity_Q8 ) + + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_INPUT_QUALITY, 12 ), psEncCtrl->input_quality_Q14 ) + + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_CODING_QUALITY, 12 ), psEncCtrl->coding_quality_Q14 ) + + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_QUANT_OFFSET, 16 ), quant_offset_Q10 ); + + SKP_assert( psEncCtrl->Lambda_Q10 > 0 ); + SKP_assert( psEncCtrl->Lambda_Q10 < SKP_FIX_CONST( 2, 10 ) ); +} diff --git a/silk/fixed/SKP_Silk_regularize_correlations_FIX.c b/silk/fixed/SKP_Silk_regularize_correlations_FIX.c new file mode 100644 index 00000000..f30f631c --- /dev/null +++ b/silk/fixed/SKP_Silk_regularize_correlations_FIX.c @@ -0,0 +1,43 @@ +/*********************************************************************** +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" + +/* Add noise to matrix diagonal */ +void SKP_Silk_regularize_correlations_FIX( + SKP_int32 *XX, /* I/O Correlation matrices */ + SKP_int32 *xx, /* I/O Correlation values */ + SKP_int32 noise, /* I Noise to add */ + SKP_int D /* I Dimension of XX */ +) +{ + SKP_int i; + for( i = 0; i < D; i++ ) { + matrix_ptr( &XX[ 0 ], i, i, D ) = SKP_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise ); + } + xx[ 0 ] += noise; +} diff --git a/silk/fixed/SKP_Silk_residual_energy16_FIX.c b/silk/fixed/SKP_Silk_residual_energy16_FIX.c new file mode 100644 index 00000000..b559ce61 --- /dev/null +++ b/silk/fixed/SKP_Silk_residual_energy16_FIX.c @@ -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_FIX.h" + +/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ +SKP_int32 SKP_Silk_residual_energy16_covar_FIX( + const SKP_int16 *c, /* I Prediction vector */ + const SKP_int32 *wXX, /* I Correlation matrix */ + const SKP_int32 *wXx, /* I Correlation vector */ + SKP_int32 wxx, /* I Signal energy */ + SKP_int D, /* I Dimension */ + SKP_int cQ /* I Q value for c vector 0 - 15 */ +) +{ + SKP_int i, j, lshifts, Qxtra; + SKP_int32 c_max, w_max, tmp, tmp2, nrg; + SKP_int cn[ MAX_MATRIX_SIZE ]; + const SKP_int32 *pRow; + + /* Safety checks */ + SKP_assert( D >= 0 ); + SKP_assert( D <= 16 ); + SKP_assert( cQ > 0 ); + SKP_assert( cQ < 16 ); + + lshifts = 16 - cQ; + Qxtra = lshifts; + + c_max = 0; + for( i = 0; i < D; i++ ) { + c_max = SKP_max_32( c_max, SKP_abs( ( SKP_int32 )c[ i ] ) ); + } + Qxtra = SKP_min_int( Qxtra, SKP_Silk_CLZ32( c_max ) - 17 ); + + w_max = SKP_max_32( wXX[ 0 ], wXX[ D * D - 1 ] ); + Qxtra = SKP_min_int( Qxtra, SKP_Silk_CLZ32( SKP_MUL( D, SKP_RSHIFT( SKP_SMULWB( w_max, c_max ), 4 ) ) ) - 5 ); + Qxtra = SKP_max_int( Qxtra, 0 ); + for( i = 0; i < D; i++ ) { + cn[ i ] = SKP_LSHIFT( ( SKP_int )c[ i ], Qxtra ); + SKP_assert( SKP_abs(cn[i]) <= ( SKP_int16_MAX + 1 ) ); /* Check that SKP_SMLAWB can be used */ + } + lshifts -= Qxtra; + + /* Compute wxx - 2 * wXx * c */ + tmp = 0; + for( i = 0; i < D; i++ ) { + tmp = SKP_SMLAWB( tmp, wXx[ i ], cn[ i ] ); + } + nrg = SKP_RSHIFT( wxx, 1 + lshifts ) - tmp; /* Q: -lshifts - 1 */ + + /* Add c' * wXX * c, assuming wXX is symmetric */ + tmp2 = 0; + for( i = 0; i < D; i++ ) { + tmp = 0; + pRow = &wXX[ i * D ]; + for( j = i + 1; j < D; j++ ) { + tmp = SKP_SMLAWB( tmp, pRow[ j ], cn[ j ] ); + } + tmp = SKP_SMLAWB( tmp, SKP_RSHIFT( pRow[ i ], 1 ), cn[ i ] ); + tmp2 = SKP_SMLAWB( tmp2, tmp, cn[ i ] ); + } + nrg = SKP_ADD_LSHIFT32( nrg, tmp2, lshifts ); /* Q: -lshifts - 1 */ + + /* Keep one bit free always, because we add them for LSF interpolation */ + if( nrg < 1 ) { + nrg = 1; + } else if( nrg > SKP_RSHIFT( SKP_int32_MAX, lshifts + 2 ) ) { + nrg = SKP_int32_MAX >> 1; + } else { + nrg = SKP_LSHIFT( nrg, lshifts + 1 ); /* Q0 */ + } + return nrg; + +} diff --git a/silk/fixed/SKP_Silk_residual_energy_FIX.c b/silk/fixed/SKP_Silk_residual_energy_FIX.c new file mode 100644 index 00000000..2fb531ca --- /dev/null +++ b/silk/fixed/SKP_Silk_residual_energy_FIX.c @@ -0,0 +1,87 @@ +/*********************************************************************** +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" + +/* Calculates residual energies of input subframes where all subframes have LPC_order */ +/* of preceeding samples */ +void SKP_Silk_residual_energy_FIX( + SKP_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ + SKP_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */ + const SKP_int16 x[], /* I Input signal */ + const SKP_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ + const SKP_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */ + const SKP_int subfr_length, /* I Subframe length */ + const SKP_int nb_subfr, /* I Number of subframes */ + const SKP_int LPC_order /* I LPC order */ +) +{ + SKP_int offset, i, j, rshift, lz1, lz2; + SKP_int16 *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; + const SKP_int16 *x_ptr; + SKP_int32 tmp32; + + x_ptr = x; + offset = LPC_order + subfr_length; + + /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ + for( i = 0; i < nb_subfr >> 1; i++ ) { + /* Calculate half frame LPC residual signal including preceeding samples */ + SKP_Silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order ); + + /* Point to first subframe of the just calculated LPC residual signal */ + LPC_res_ptr = LPC_res + LPC_order; + for( j = 0; j < ( MAX_NB_SUBFR >> 1 ); j++ ) { + /* Measure subframe energy */ + SKP_Silk_sum_sqr_shift( &nrgs[ i * ( MAX_NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length ); + + /* Set Q values for the measured energy */ + nrgsQ[ i * ( MAX_NB_SUBFR >> 1 ) + j ] = -rshift; + + /* Move to next subframe */ + LPC_res_ptr += offset; + } + /* Move to next frame half */ + x_ptr += ( MAX_NB_SUBFR >> 1 ) * offset; + } + + /* Apply the squared subframe gains */ + for( i = 0; i < nb_subfr; i++ ) { + /* Fully upscale gains and energies */ + lz1 = SKP_Silk_CLZ32( nrgs[ i ] ) - 1; + lz2 = SKP_Silk_CLZ32( gains[ i ] ) - 1; + + tmp32 = SKP_LSHIFT32( gains[ i ], lz2 ); + + /* Find squared gains */ + tmp32 = SKP_SMMUL( tmp32, tmp32 ); // Q( 2 * lz2 - 32 ) + + /* Scale energies */ + nrgs[ i ] = SKP_SMMUL( tmp32, SKP_LSHIFT32( nrgs[ i ], lz1 ) ); // Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 ) + nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32; + } +} diff --git a/silk/fixed/SKP_Silk_solve_LS_FIX.c b/silk/fixed/SKP_Silk_solve_LS_FIX.c new file mode 100644 index 00000000..25684185 --- /dev/null +++ b/silk/fixed/SKP_Silk_solve_LS_FIX.c @@ -0,0 +1,241 @@ +/*********************************************************************** +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" +#include "SKP_Silk_tuning_parameters.h" + +/*****************************/ +/* Internal function headers */ +/*****************************/ + +typedef struct { + SKP_int32 Q36_part; + SKP_int32 Q48_part; +} inv_D_t; + +/* Factorize square matrix A into LDL form */ +SKP_INLINE void SKP_Silk_LDL_factorize_FIX( + SKP_int32 *A, /* I/O Pointer to Symetric Square Matrix */ + SKP_int M, /* I Size of Matrix */ + SKP_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */ + inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */ +); + +/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */ +SKP_INLINE void SKP_Silk_LS_SolveFirst_FIX( + const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ + SKP_int M, /* I Dim of Matrix equation */ + const SKP_int32 *b, /* I b Vector */ + SKP_int32 *x_Q16 /* O x Vector */ +); + +/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */ +SKP_INLINE void SKP_Silk_LS_SolveLast_FIX( + const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ + const SKP_int M, /* I Dim of Matrix equation */ + const SKP_int32 *b, /* I b Vector */ + SKP_int32 *x_Q16 /* O x Vector */ +); + +SKP_INLINE void SKP_Silk_LS_divide_Q16_FIX( + SKP_int32 T[], /* I/O Numenator vector */ + inv_D_t *inv_D, /* I 1 / D vector */ + SKP_int M /* I dimension */ +); + +/* Solves Ax = b, assuming A is symmetric */ +void SKP_Silk_solve_LDL_FIX( + SKP_int32 *A, /* I Pointer to symetric square matrix A */ + SKP_int M, /* I Size of matrix */ + const SKP_int32 *b, /* I Pointer to b vector */ + SKP_int32 *x_Q16 /* O Pointer to x solution vector */ +) +{ + SKP_int32 L_Q16[ MAX_MATRIX_SIZE * MAX_MATRIX_SIZE ]; + SKP_int32 Y[ MAX_MATRIX_SIZE ]; + inv_D_t inv_D[ MAX_MATRIX_SIZE ]; + + SKP_assert( M <= MAX_MATRIX_SIZE ); + + /*************************************************** + Factorize A by LDL such that A = L*D*L', + where L is lower triangular with ones on diagonal + ****************************************************/ + SKP_Silk_LDL_factorize_FIX( A, M, L_Q16, inv_D ); + + /**************************************************** + * substitute D*L'*x = Y. ie: + L*D*L'*x = b => L*Y = b <=> Y = inv(L)*b + ******************************************************/ + SKP_Silk_LS_SolveFirst_FIX( L_Q16, M, b, Y ); + + /**************************************************** + D*L'*x = Y <=> L'*x = inv(D)*Y, because D is + diagonal just multiply with 1/d_i + ****************************************************/ + SKP_Silk_LS_divide_Q16_FIX( Y, inv_D, M ); + + /**************************************************** + x = inv(L') * inv(D) * Y + *****************************************************/ + SKP_Silk_LS_SolveLast_FIX( L_Q16, M, Y, x_Q16 ); +} + +SKP_INLINE void SKP_Silk_LDL_factorize_FIX( + SKP_int32 *A, /* I Pointer to Symetric Square Matrix */ + SKP_int M, /* I Size of Matrix */ + SKP_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */ + inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */ +) +{ + SKP_int i, j, k, status, loop_count; + const SKP_int32 *ptr1, *ptr2; + SKP_int32 diag_min_value, tmp_32, err; + SKP_int32 v_Q0[ MAX_MATRIX_SIZE ], D_Q0[ MAX_MATRIX_SIZE ]; + SKP_int32 one_div_diag_Q36, one_div_diag_Q40, one_div_diag_Q48; + + SKP_assert( M <= MAX_MATRIX_SIZE ); + + status = 1; + diag_min_value = SKP_max_32( SKP_SMMUL( SKP_ADD_SAT32( A[ 0 ], A[ SKP_SMULBB( M, M ) - 1 ] ), SKP_FIX_CONST( FIND_LTP_COND_FAC, 31 ) ), 1 << 9 ); + for( loop_count = 0; loop_count < M && status == 1; loop_count++ ) { + status = 0; + for( j = 0; j < M; j++ ) { + ptr1 = matrix_adr( L_Q16, j, 0, M ); + tmp_32 = 0; + for( i = 0; i < j; i++ ) { + v_Q0[ i ] = SKP_SMULWW( D_Q0[ i ], ptr1[ i ] ); /* Q0 */ + tmp_32 = SKP_SMLAWW( tmp_32, v_Q0[ i ], ptr1[ i ] ); /* Q0 */ + } + tmp_32 = SKP_SUB32( matrix_ptr( A, j, j, M ), tmp_32 ); + + if( tmp_32 < diag_min_value ) { + tmp_32 = SKP_SUB32( SKP_SMULBB( loop_count + 1, diag_min_value ), tmp_32 ); + /* Matrix not positive semi-definite, or ill conditioned */ + for( i = 0; i < M; i++ ) { + matrix_ptr( A, i, i, M ) = SKP_ADD32( matrix_ptr( A, i, i, M ), tmp_32 ); + } + status = 1; + break; + } + D_Q0[ j ] = tmp_32; /* always < max(Correlation) */ + + /* two-step division */ + one_div_diag_Q36 = SKP_INVERSE32_varQ( tmp_32, 36 ); /* Q36 */ + one_div_diag_Q40 = SKP_LSHIFT( one_div_diag_Q36, 4 ); /* Q40 */ + err = SKP_SUB32( 1 << 24, SKP_SMULWW( tmp_32, one_div_diag_Q40 ) ); /* Q24 */ + one_div_diag_Q48 = SKP_SMULWW( err, one_div_diag_Q40 ); /* Q48 */ + + /* Save 1/Ds */ + inv_D[ j ].Q36_part = one_div_diag_Q36; + inv_D[ j ].Q48_part = one_div_diag_Q48; + + matrix_ptr( L_Q16, j, j, M ) = 65536; /* 1.0 in Q16 */ + ptr1 = matrix_adr( A, j, 0, M ); + ptr2 = matrix_adr( L_Q16, j + 1, 0, M ); + for( i = j + 1; i < M; i++ ) { + tmp_32 = 0; + for( k = 0; k < j; k++ ) { + tmp_32 = SKP_SMLAWW( tmp_32, v_Q0[ k ], ptr2[ k ] ); /* Q0 */ + } + tmp_32 = SKP_SUB32( ptr1[ i ], tmp_32 ); /* always < max(Correlation) */ + + /* tmp_32 / D_Q0[j] : Divide to Q16 */ + matrix_ptr( L_Q16, i, j, M ) = SKP_ADD32( SKP_SMMUL( tmp_32, one_div_diag_Q48 ), + SKP_RSHIFT( SKP_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) ); + + /* go to next column */ + ptr2 += M; + } + } + } + + SKP_assert( status == 0 ); +} + +SKP_INLINE void SKP_Silk_LS_divide_Q16_FIX( + SKP_int32 T[], /* I/O Numenator vector */ + inv_D_t *inv_D, /* I 1 / D vector */ + SKP_int M /* I Order */ +) +{ + SKP_int i; + SKP_int32 tmp_32; + SKP_int32 one_div_diag_Q36, one_div_diag_Q48; + + for( i = 0; i < M; i++ ) { + one_div_diag_Q36 = inv_D[ i ].Q36_part; + one_div_diag_Q48 = inv_D[ i ].Q48_part; + + tmp_32 = T[ i ]; + T[ i ] = SKP_ADD32( SKP_SMMUL( tmp_32, one_div_diag_Q48 ), SKP_RSHIFT( SKP_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) ); + } +} + +/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */ +SKP_INLINE void SKP_Silk_LS_SolveFirst_FIX( + const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ + SKP_int M, /* I Dim of Matrix equation */ + const SKP_int32 *b, /* I b Vector */ + SKP_int32 *x_Q16 /* O x Vector */ +) +{ + SKP_int i, j; + const SKP_int32 *ptr32; + SKP_int32 tmp_32; + + for( i = 0; i < M; i++ ) { + ptr32 = matrix_adr( L_Q16, i, 0, M ); + tmp_32 = 0; + for( j = 0; j < i; j++ ) { + tmp_32 = SKP_SMLAWW( tmp_32, ptr32[ j ], x_Q16[ j ] ); + } + x_Q16[ i ] = SKP_SUB32( b[ i ], tmp_32 ); + } +} + +/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */ +SKP_INLINE void SKP_Silk_LS_SolveLast_FIX( + const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ + const SKP_int M, /* I Dim of Matrix equation */ + const SKP_int32 *b, /* I b Vector */ + SKP_int32 *x_Q16 /* O x Vector */ +) +{ + SKP_int i, j; + const SKP_int32 *ptr32; + SKP_int32 tmp_32; + + for( i = M - 1; i >= 0; i-- ) { + ptr32 = matrix_adr( L_Q16, 0, i, M ); + tmp_32 = 0; + for( j = M - 1; j > i; j-- ) { + tmp_32 = SKP_SMLAWW( tmp_32, ptr32[ SKP_SMULBB( j, M ) ], x_Q16[ j ] ); + } + x_Q16[ i ] = SKP_SUB32( b[ i ], tmp_32 ); + } +} diff --git a/silk/fixed/SKP_Silk_warped_autocorrelation_FIX.c b/silk/fixed/SKP_Silk_warped_autocorrelation_FIX.c new file mode 100644 index 00000000..380104ff --- /dev/null +++ b/silk/fixed/SKP_Silk_warped_autocorrelation_FIX.c @@ -0,0 +1,84 @@ +/*********************************************************************** +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_int 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/silk/float/SKP_Silk_LPC_analysis_filter_FLP.c b/silk/float/SKP_Silk_LPC_analysis_filter_FLP.c new file mode 100644 index 00000000..b340f559 --- /dev/null +++ b/silk/float/SKP_Silk_LPC_analysis_filter_FLP.c @@ -0,0 +1,279 @@ +/*********************************************************************** +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 +#include "SKP_Silk_main_FLP.h" + +/*******************************************/ +/* LPC analysis filter */ +/* NB! State is kept internally and the */ +/* filter always starts with zero state */ +/* first Order output samples are not set */ +/*******************************************/ + +/* 16th order LPC analysis filter, does not write first 16 samples */ +void SKP_Silk_LPC_analysis_filter16_FLP( + SKP_float r_LPC[], /* O LPC residual signal */ + const SKP_float PredCoef[], /* I LPC coefficients */ + const SKP_float s[], /* I Input signal */ + const SKP_int length /* I Length of input signal */ +) +{ + SKP_int ix; + SKP_float LPC_pred; + const SKP_float *s_ptr; + + for ( ix = 16; ix < length; ix++) { + s_ptr = &s[ix - 1]; + + /* short-term prediction */ + LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + + s_ptr[ -1 ] * PredCoef[ 1 ] + + s_ptr[ -2 ] * PredCoef[ 2 ] + + s_ptr[ -3 ] * PredCoef[ 3 ] + + s_ptr[ -4 ] * PredCoef[ 4 ] + + s_ptr[ -5 ] * PredCoef[ 5 ] + + s_ptr[ -6 ] * PredCoef[ 6 ] + + s_ptr[ -7 ] * PredCoef[ 7 ] + + s_ptr[ -8 ] * PredCoef[ 8 ] + + s_ptr[ -9 ] * PredCoef[ 9 ] + + s_ptr[ -10 ] * PredCoef[ 10 ] + + s_ptr[ -11 ] * PredCoef[ 11 ] + + s_ptr[ -12 ] * PredCoef[ 12 ] + + s_ptr[ -13 ] * PredCoef[ 13 ] + + s_ptr[ -14 ] * PredCoef[ 14 ] + + s_ptr[ -15 ] * PredCoef[ 15 ]; + + /* prediction error */ + r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; + } +} + +/* 14th order LPC analysis filter, does not write first 14 samples */ +void SKP_Silk_LPC_analysis_filter14_FLP( + SKP_float r_LPC[], /* O LPC residual signal */ + const SKP_float PredCoef[], /* I LPC coefficients */ + const SKP_float s[], /* I Input signal */ + const SKP_int length /* I Length of input signal */ +) +{ + SKP_int ix; + SKP_float LPC_pred; + const SKP_float *s_ptr; + + for ( ix = 14; ix < length; ix++) { + s_ptr = &s[ix - 1]; + + /* short-term prediction */ + LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + + s_ptr[ -1 ] * PredCoef[ 1 ] + + s_ptr[ -2 ] * PredCoef[ 2 ] + + s_ptr[ -3 ] * PredCoef[ 3 ] + + s_ptr[ -4 ] * PredCoef[ 4 ] + + s_ptr[ -5 ] * PredCoef[ 5 ] + + s_ptr[ -6 ] * PredCoef[ 6 ] + + s_ptr[ -7 ] * PredCoef[ 7 ] + + s_ptr[ -8 ] * PredCoef[ 8 ] + + s_ptr[ -9 ] * PredCoef[ 9 ] + + s_ptr[ -10 ] * PredCoef[ 10 ] + + s_ptr[ -11 ] * PredCoef[ 11 ] + + s_ptr[ -12 ] * PredCoef[ 12 ] + + s_ptr[ -13 ] * PredCoef[ 13 ]; + + /* prediction error */ + r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; + } +} + +/* 12th order LPC analysis filter, does not write first 12 samples */ +void SKP_Silk_LPC_analysis_filter12_FLP( + SKP_float r_LPC[], /* O LPC residual signal */ + const SKP_float PredCoef[], /* I LPC coefficients */ + const SKP_float s[], /* I Input signal */ + const SKP_int length /* I Length of input signal */ +) +{ + SKP_int ix; + SKP_float LPC_pred; + const SKP_float *s_ptr; + + for ( ix = 12; ix < length; ix++) { + s_ptr = &s[ix - 1]; + + /* short-term prediction */ + LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + + s_ptr[ -1 ] * PredCoef[ 1 ] + + s_ptr[ -2 ] * PredCoef[ 2 ] + + s_ptr[ -3 ] * PredCoef[ 3 ] + + s_ptr[ -4 ] * PredCoef[ 4 ] + + s_ptr[ -5 ] * PredCoef[ 5 ] + + s_ptr[ -6 ] * PredCoef[ 6 ] + + s_ptr[ -7 ] * PredCoef[ 7 ] + + s_ptr[ -8 ] * PredCoef[ 8 ] + + s_ptr[ -9 ] * PredCoef[ 9 ] + + s_ptr[ -10 ] * PredCoef[ 10 ] + + s_ptr[ -11 ] * PredCoef[ 11 ]; + + /* prediction error */ + r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; + } +} + +/* 10th order LPC analysis filter, does not write first 10 samples */ +void SKP_Silk_LPC_analysis_filter10_FLP( + SKP_float r_LPC[], /* O LPC residual signal */ + const SKP_float PredCoef[], /* I LPC coefficients */ + const SKP_float s[], /* I Input signal */ + const SKP_int length /* I Length of input signal */ +) +{ + SKP_int ix; + SKP_float LPC_pred; + const SKP_float *s_ptr; + + for ( ix = 10; ix < length; ix++) { + s_ptr = &s[ix - 1]; + + /* short-term prediction */ + LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + + s_ptr[ -1 ] * PredCoef[ 1 ] + + s_ptr[ -2 ] * PredCoef[ 2 ] + + s_ptr[ -3 ] * PredCoef[ 3 ] + + s_ptr[ -4 ] * PredCoef[ 4 ] + + s_ptr[ -5 ] * PredCoef[ 5 ] + + s_ptr[ -6 ] * PredCoef[ 6 ] + + s_ptr[ -7 ] * PredCoef[ 7 ] + + s_ptr[ -8 ] * PredCoef[ 8 ] + + s_ptr[ -9 ] * PredCoef[ 9 ]; + + /* prediction error */ + r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; + } +} + +/* 8th order LPC analysis filter, does not write first 8 samples */ +void SKP_Silk_LPC_analysis_filter8_FLP( + SKP_float r_LPC[], /* O LPC residual signal */ + const SKP_float PredCoef[], /* I LPC coefficients */ + const SKP_float s[], /* I Input signal */ + const SKP_int length /* I Length of input signal */ +) +{ + SKP_int ix; + SKP_float LPC_pred; + const SKP_float *s_ptr; + + for ( ix = 8; ix < length; ix++) { + s_ptr = &s[ix - 1]; + + /* short-term prediction */ + LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + + s_ptr[ -1 ] * PredCoef[ 1 ] + + s_ptr[ -2 ] * PredCoef[ 2 ] + + s_ptr[ -3 ] * PredCoef[ 3 ] + + s_ptr[ -4 ] * PredCoef[ 4 ] + + s_ptr[ -5 ] * PredCoef[ 5 ] + + s_ptr[ -6 ] * PredCoef[ 6 ] + + s_ptr[ -7 ] * PredCoef[ 7 ]; + + /* prediction error */ + r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; + } +} + +/* 6th order LPC analysis filter, does not write first 6 samples */ +void SKP_Silk_LPC_analysis_filter6_FLP( + SKP_float r_LPC[], /* O LPC residual signal */ + const SKP_float PredCoef[], /* I LPC coefficients */ + const SKP_float s[], /* I Input signal */ + const SKP_int length /* I Length of input signal */ +) +{ + SKP_int ix; + SKP_float LPC_pred; + const SKP_float *s_ptr; + + for ( ix = 6; ix < length; ix++) { + s_ptr = &s[ix - 1]; + + /* short-term prediction */ + LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + + s_ptr[ -1 ] * PredCoef[ 1 ] + + s_ptr[ -2 ] * PredCoef[ 2 ] + + s_ptr[ -3 ] * PredCoef[ 3 ] + + s_ptr[ -4 ] * PredCoef[ 4 ] + + s_ptr[ -5 ] * PredCoef[ 5 ]; + + /* prediction error */ + r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; + } +} + +void SKP_Silk_LPC_analysis_filter_FLP( + SKP_float r_LPC[], /* O LPC residual signal */ + const SKP_float PredCoef[], /* I LPC coefficients */ + const SKP_float s[], /* I Input signal */ + const SKP_int length, /* I Length of input signal */ + const SKP_int Order /* I LPC order */ +) +{ + SKP_assert( Order <= length ); + + switch( Order ) { + case 6: + SKP_Silk_LPC_analysis_filter6_FLP( r_LPC, PredCoef, s, length ); + break; + + case 8: + SKP_Silk_LPC_analysis_filter8_FLP( r_LPC, PredCoef, s, length ); + break; + + case 10: + SKP_Silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, length ); + break; + + case 12: + SKP_Silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, length ); + break; + + case 14: + SKP_Silk_LPC_analysis_filter14_FLP( r_LPC, PredCoef, s, length ); + break; + + case 16: + SKP_Silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, length ); + break; + + default: + SKP_assert( 0 ); + break; + } + + /* Set first LPC Order samples to zero instead of undefined */ + SKP_memset( r_LPC, 0, Order * sizeof( SKP_float ) ); +} + diff --git a/silk/float/SKP_Silk_LTP_analysis_filter_FLP.c b/silk/float/SKP_Silk_LTP_analysis_filter_FLP.c new file mode 100644 index 00000000..b27b08d4 --- /dev/null +++ b/silk/float/SKP_Silk_LTP_analysis_filter_FLP.c @@ -0,0 +1,71 @@ +/*********************************************************************** +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_FLP.h" + +void SKP_Silk_LTP_analysis_filter_FLP( + SKP_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */ + const SKP_float *x, /* I Input signal, with preceeding samples */ + const SKP_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */ + const SKP_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const SKP_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */ + const SKP_int subfr_length, /* I Length of each subframe */ + const SKP_int nb_subfr, /* I number of subframes */ + const SKP_int pre_length /* I Preceeding samples for each subframe */ +) +{ + const SKP_float *x_ptr, *x_lag_ptr; + SKP_float Btmp[ LTP_ORDER ]; + SKP_float *LTP_res_ptr; + SKP_float inv_gain; + SKP_int k, i, j; + + x_ptr = x; + LTP_res_ptr = LTP_res; + for( k = 0; k < nb_subfr; k++ ) { + x_lag_ptr = x_ptr - pitchL[ k ]; + inv_gain = invGains[ k ]; + for( i = 0; i < LTP_ORDER; i++ ) { + Btmp[ i ] = B[ k * LTP_ORDER + i ]; + } + + /* LTP analysis FIR filter */ + for( i = 0; i < subfr_length + pre_length; i++ ) { + LTP_res_ptr[ i ] = x_ptr[ i ]; + /* Subtract long-term prediction */ + for( j = 0; j < LTP_ORDER; j++ ) { + LTP_res_ptr[ i ] -= Btmp[ j ] * x_lag_ptr[ LTP_ORDER / 2 - j ]; + } + LTP_res_ptr[ i ] *= inv_gain; + x_lag_ptr++; + } + + /* Update pointers */ + LTP_res_ptr += subfr_length + pre_length; + x_ptr += subfr_length; + } +} diff --git a/silk/float/SKP_Silk_LTP_scale_ctrl_FLP.c b/silk/float/SKP_Silk_LTP_scale_ctrl_FLP.c new file mode 100644 index 00000000..4d9345d9 --- /dev/null +++ b/silk/float/SKP_Silk_LTP_scale_ctrl_FLP.c @@ -0,0 +1,52 @@ +/*********************************************************************** +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_FLP.h" + +void SKP_Silk_LTP_scale_ctrl_FLP( + SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + SKP_Silk_encoder_control_FLP *psEncCtrl /* I/O Encoder control FLP */ +) +{ + SKP_int round_loss; + + /* 1st order high-pass filter */ + //g_HP(n) = g(n) - 0.5 * g(n-1) + 0.5 * g_HP(n-1); + psEnc->HPLTPredCodGain = SKP_max_float( psEncCtrl->LTPredCodGain - 0.5 * psEnc->prevLTPredCodGain, 0.0f ) + + 0.5f * psEnc->HPLTPredCodGain; + psEnc->prevLTPredCodGain = psEncCtrl->LTPredCodGain; + + /* Only scale if first frame in packet */ + if( psEnc->sCmn.nFramesAnalyzed == 0 ) { + round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; + psEnc->sCmn.indices.LTP_scaleIndex = (SKP_int8)SKP_LIMIT( round_loss * psEnc->HPLTPredCodGain * 0.1f, 0.0f, 2.0f ); + } else { + /* Default is minimum scaling */ + psEnc->sCmn.indices.LTP_scaleIndex = 0; + } + psEncCtrl->LTP_scale = (SKP_float)SKP_Silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f; +} diff --git a/silk/float/SKP_Silk_apply_sine_window_FLP.c b/silk/float/SKP_Silk_apply_sine_window_FLP.c new file mode 100644 index 00000000..1db6b147 --- /dev/null +++ b/silk/float/SKP_Silk_apply_sine_window_FLP.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. +***********************************************************************/ + +#include "SKP_Silk_main_FLP.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 */ +void SKP_Silk_apply_sine_window_FLP( + SKP_float px_win[], /* O Pointer to windowed signal */ + const SKP_float 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; + SKP_float freq, c, S0, S1; + + SKP_assert( win_type == 1 || win_type == 2 ); + + /* Length must be multiple of 4 */ + SKP_assert( ( length & 3 ) == 0 ); + + freq = PI / ( length + 1 ); + + /* Approximation of 2 * cos(f) */ + c = 2.0f - freq * freq; + + /* Initialize state */ + if( win_type < 2 ) { + /* Start from 0 */ + S0 = 0.0f; + /* Approximation of sin(f) */ + S1 = freq; + } else { + /* Start from 1 */ + S0 = 1.0f; + /* Approximation of cos(f) */ + S1 = 0.5f * c; + } + + /* 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 + 0 ] = px[ k + 0 ] * 0.5f * ( S0 + S1 ); + px_win[ k + 1 ] = px[ k + 1 ] * S1; + S0 = c * S1 - S0; + px_win[ k + 2 ] = px[ k + 2 ] * 0.5f * ( S1 + S0 ); + px_win[ k + 3 ] = px[ k + 3 ] * S0; + S1 = c * S0 - S1; + } +} diff --git a/silk/float/SKP_Silk_corrMatrix_FLP.c b/silk/float/SKP_Silk_corrMatrix_FLP.c new file mode 100644 index 00000000..0fdaabd0 --- /dev/null +++ b/silk/float/SKP_Silk_corrMatrix_FLP.c @@ -0,0 +1,89 @@ +/*********************************************************************** +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. +***********************************************************************/ + +/********************************************************************** + * Correlation matrix computations for LS estimate. + **********************************************************************/ + +#include "SKP_Silk_main_FLP.h" + +/* Calculates correlation vector X'*t */ +void SKP_Silk_corrVector_FLP( + const SKP_float *x, /* I x vector [L+order-1] used to create X */ + const SKP_float *t, /* I Target vector [L] */ + const SKP_int L, /* I Length of vecors */ + const SKP_int Order, /* I Max lag for correlation */ + SKP_float *Xt /* O X'*t correlation vector [order] */ +) +{ + SKP_int lag; + const SKP_float *ptr1; + + ptr1 = &x[ Order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ + for( lag = 0; lag < Order; lag++ ) { + /* Calculate X[:,lag]'*t */ + Xt[ lag ] = (SKP_float)SKP_Silk_inner_product_FLP( ptr1, t, L ); + ptr1--; /* Next column of X */ + } +} + +/* Calculates correlation matrix X'*X */ +void SKP_Silk_corrMatrix_FLP( + const SKP_float *x, /* I x vector [ L+order-1 ] used to create X */ + const SKP_int L, /* I Length of vectors */ + const SKP_int Order, /* I Max lag for correlation */ + SKP_float *XX /* O X'*X correlation matrix [order x order] */ +) +{ + SKP_int j, lag; + double energy; + const SKP_float *ptr1, *ptr2; + + ptr1 = &x[ Order - 1 ]; /* First sample of column 0 of X */ + energy = SKP_Silk_energy_FLP( ptr1, L ); /* X[:,0]'*X[:,0] */ + matrix_ptr( XX, 0, 0, Order ) = ( SKP_float )energy; + for( j = 1; j < Order; j++ ) { + /* Calculate X[:,j]'*X[:,j] */ + energy += ptr1[ -j ] * ptr1[ -j ] - ptr1[ L - j ] * ptr1[ L - j ]; + matrix_ptr( XX, j, j, Order ) = ( SKP_float )energy; + } + + ptr2 = &x[ Order - 2 ]; /* First sample of column 1 of X */ + for( lag = 1; lag < Order; lag++ ) { + /* Calculate X[:,0]'*X[:,lag] */ + energy = SKP_Silk_inner_product_FLP( ptr1, ptr2, L ); + matrix_ptr( XX, lag, 0, Order ) = ( SKP_float )energy; + matrix_ptr( XX, 0, lag, Order ) = ( SKP_float )energy; + /* Calculate X[:,j]'*X[:,j + lag] */ + for( j = 1; j < ( Order - lag ); j++ ) { + energy += ptr1[ -j ] * ptr2[ -j ] - ptr1[ L - j ] * ptr2[ L - j ]; + matrix_ptr( XX, lag + j, j, Order ) = ( SKP_float )energy; + matrix_ptr( XX, j, lag + j, Order ) = ( SKP_float )energy; + } + ptr2--; /* Next column of X */ + } +} diff --git a/silk/float/SKP_Silk_encode_frame_FLP.c b/silk/float/SKP_Silk_encode_frame_FLP.c new file mode 100644 index 00000000..43b5283b --- /dev/null +++ b/silk/float/SKP_Silk_encode_frame_FLP.c @@ -0,0 +1,277 @@ +/*********************************************************************** +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_FLP.h" +#include "SKP_Silk_tuning_parameters.h" + +/****************/ +/* Encode frame */ +/****************/ +SKP_int SKP_Silk_encode_frame_FLP( + SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + SKP_int32 *pnBytesOut, /* O Number of payload bytes */ + ec_enc *psRangeEnc /* I/O compressor data structure */ +) +{ + SKP_Silk_encoder_control_FLP sEncCtrl; + SKP_int i, ret = 0; + SKP_float *x_frame, *res_pitch_frame; + SKP_int16 pIn_HP[ MAX_FRAME_LENGTH ]; + SKP_float xfw[ MAX_FRAME_LENGTH ]; + SKP_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ]; + +TIC(ENCODE_FRAME) + + psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; + + /**************************************************************/ + /* Setup Input Pointers, and insert frame in input buffer */ + /*************************************************************/ + /* pointers aligned with start of frame to encode */ + x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */ + res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */ + + /****************************/ + /* Voice Activity Detection */ + /****************************/ +TIC(VAD) + ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf ); +TOC(VAD) + + /**************************************************/ + /* Convert speech activity into VAD and DTX flags */ + /**************************************************/ + if( psEnc->sCmn.nFramesAnalyzed == 0 ) { + psEnc->sCmn.inDTX = psEnc->sCmn.useDTX; + } + if( psEnc->sCmn.speech_activity_Q8 < SKP_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) { + psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; + psEnc->sCmn.noSpeechCounter++; + if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) { + psEnc->sCmn.inDTX = 0; + } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { + psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; + psEnc->sCmn.inDTX = 0; + } + psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesAnalyzed ] = 0; + } else { + psEnc->sCmn.noSpeechCounter = 0; + psEnc->sCmn.inDTX = 0; + psEnc->sCmn.indices.signalType = TYPE_UNVOICED; + psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesAnalyzed ] = 1; + } + + /*******************************************/ + /* High-pass filtering of the input signal */ + /*******************************************/ +TIC(HP_IN) + SKP_Silk_HP_variable_cutoff( &psEnc->sCmn, pIn_HP, psEnc->sCmn.inputBuf, psEnc->sCmn.frame_length ); +TOC(HP_IN) + + /* Ensure smooth bandwidth transitions */ + SKP_Silk_LP_variable_cutoff( &psEnc->sCmn.sLP, pIn_HP, psEnc->sCmn.frame_length ); + + /*******************************************/ + /* Copy new frame to front of input buffer */ + /*******************************************/ + SKP_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP, psEnc->sCmn.frame_length ); + + /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */ + for( i = 0; i < 8; i++ ) { + x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f; + } + + /*****************************************/ + /* Find pitch lags, initial LPC analysis */ + /*****************************************/ +TIC(FIND_PITCH) + SKP_Silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame ); +TOC(FIND_PITCH) + + /************************/ + /* Noise shape analysis */ + /************************/ +TIC(NOISE_SHAPE_ANALYSIS) + SKP_Silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame ); +TOC(NOISE_SHAPE_ANALYSIS) + + /*****************************************/ + /* Prefiltering for noise shaper */ + /*****************************************/ +TIC(PREFILTER) + SKP_Silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame ); +TOC(PREFILTER) + + /***************************************************/ + /* Find linear prediction coefficients (LPC + LTP) */ + /***************************************************/ +TIC(FIND_PRED_COEF) + SKP_Silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch, x_frame ); +TOC(FIND_PRED_COEF) + + /****************************************/ + /* Process gains */ + /****************************************/ +TIC(PROCESS_GAINS) + SKP_Silk_process_gains_FLP( psEnc, &sEncCtrl ); +TOC(PROCESS_GAINS) + + /****************************************/ + /* Low Bitrate Redundant Encoding */ + /****************************************/ +TIC(LBRR) + SKP_Silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw ); +TOC(LBRR) + + /*****************************************/ + /* Noise shaping quantization */ + /*****************************************/ +TIC(NSQ) + SKP_Silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw ); +TOC(NSQ) + + /* Update input buffer */ + SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], + ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_float ) ); + + /* Parameters needed for next frame */ + psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; + psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; + + /* Exit without entropy coding */ + if( psEnc->sCmn.prefillFlag ) { + /* No payload */ + *pnBytesOut = 0; + return ret; + } + + /****************************************/ + /* Encode Parameters */ + /****************************************/ +TIC(ENCODE_PARAMS) + SKP_Silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesAnalyzed, 0 ); +TOC(ENCODE_PARAMS) + + /****************************************/ + /* Encode Excitation Signal */ + /****************************************/ +TIC(ENCODE_PULSES) + SKP_Silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, + psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); +TOC(ENCODE_PULSES) + + /****************************************/ + /* Finalize payload */ + /****************************************/ + psEnc->sCmn.first_frame_after_reset = 0; + if( ++psEnc->sCmn.nFramesAnalyzed >= psEnc->sCmn.nFramesPerPacket ) { + /* Payload size */ + *pnBytesOut = SKP_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); + + /* Reset the number of frames in payload buffer */ + psEnc->sCmn.nFramesAnalyzed = 0; + } else { + /* No payload this time */ + *pnBytesOut = 0; + } +TOC(ENCODE_FRAME) + +#ifdef SAVE_ALL_INTERNAL_DATA + //DEBUG_STORE_DATA( xf.dat, pIn_HP_LP, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) ); + //DEBUG_STORE_DATA( xfw.dat, xfw, psEnc->sCmn.frame_length * sizeof( SKP_float ) ); + DEBUG_STORE_DATA( pitchL.dat, sEncCtrl.pitchL, MAX_NB_SUBFR * sizeof( SKP_int ) ); + DEBUG_STORE_DATA( pitchG_quantized.dat, sEncCtrl.LTPCoef, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) ); + DEBUG_STORE_DATA( LTPcorr.dat, &psEnc->LTPCorr, sizeof( SKP_float ) ); + DEBUG_STORE_DATA( gains.dat, sEncCtrl.Gains, psEnc->sCmn.nb_subfr * sizeof( SKP_float ) ); + DEBUG_STORE_DATA( gains_indices.dat, &psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr * sizeof( SKP_int8 ) ); + DEBUG_STORE_DATA( quantOffsetType.dat, &psEnc->sCmn.indices.quantOffsetType, sizeof( SKP_int8 ) ); + DEBUG_STORE_DATA( speech_activity_q8.dat, &psEnc->sCmn.speech_activity_Q8, sizeof( SKP_int ) ); + DEBUG_STORE_DATA( signalType.dat, &psEnc->sCmn.indices.signalType, sizeof( SKP_int8 ) ); + DEBUG_STORE_DATA( lag_index.dat, &psEnc->sCmn.indices.lagIndex, sizeof( SKP_int16 ) ); + DEBUG_STORE_DATA( contour_index.dat, &psEnc->sCmn.indices.contourIndex, sizeof( SKP_int8 ) ); + DEBUG_STORE_DATA( per_index.dat, &psEnc->sCmn.indices.PERIndex, sizeof( SKP_int8 ) ); + DEBUG_STORE_DATA( PredCoef.dat, &sEncCtrl.PredCoef[ 1 ], psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) ); + DEBUG_STORE_DATA( ltp_scale_idx.dat, &psEnc->sCmn.indices.LTP_scaleIndex, sizeof( SKP_int8 ) ); +// DEBUG_STORE_DATA( xq.dat, psEnc->sCmn.sNSQ.xqBuf, psEnc->sCmn.frame_length * sizeof( SKP_float ) ); +#endif + return ret; +} + +/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ +void SKP_Silk_LBRR_encode_FLP( + SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + const SKP_float xfw[] /* I Input signal */ +) +{ + SKP_int k; + SKP_int32 Gains_Q16[ MAX_NB_SUBFR ]; + SKP_float TempGains[ MAX_NB_SUBFR ]; + SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesAnalyzed ]; + SKP_Silk_nsq_state sNSQ_LBRR; + + /*******************************************/ + /* Control use of inband LBRR */ + /*******************************************/ + if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SKP_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { + psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesAnalyzed ] = 1; + + /* Copy noise shaping quantizer state and quantization indices from regular encoding */ + SKP_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( SKP_Silk_nsq_state ) ); + SKP_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); + + /* Save original gains */ + SKP_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( SKP_float ) ); + + if( psEnc->sCmn.nFramesAnalyzed == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesAnalyzed - 1 ] == 0 ) { + /* First frame in packet or previous frame not LBRR coded */ + psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; + + /* Increase Gains to get target LBRR rate */ + psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases; + psIndices_LBRR->GainsIndices[ 0 ] = SKP_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); + } + + /* Decode to get gains in sync with decoder */ + SKP_Silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices, + &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesAnalyzed, psEnc->sCmn.nb_subfr ); + + /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->Gains[ k ] = Gains_Q16[ k ] / 65536.0f; + } + + /*****************************************/ + /* Noise shaping quantization */ + /*****************************************/ + SKP_Silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR, + psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesAnalyzed ], xfw ); + + /* Restore original gains */ + SKP_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( SKP_float ) ); + } +} diff --git a/silk/float/SKP_Silk_find_LPC_FLP.c b/silk/float/SKP_Silk_find_LPC_FLP.c new file mode 100644 index 00000000..88392f39 --- /dev/null +++ b/silk/float/SKP_Silk_find_LPC_FLP.c @@ -0,0 +1,109 @@ +/*********************************************************************** +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_FLP.h" +#include "SKP_Silk_tuning_parameters.h" + +void SKP_Silk_find_LPC_FLP( + SKP_int16 NLSF_Q15[], /* O NLSFs */ + SKP_int8 *interpIndex, /* O NLSF interp. index for NLSF interp. */ + const SKP_int16 prev_NLSFq_Q15[], /* I Previous NLSFs, for NLSF interpolation */ + const SKP_int useInterpNLSFs, /* I Flag */ + const SKP_int firstFrameAfterReset, /* I Flag */ + const SKP_int LPC_order, /* I LPC order */ + const SKP_float x[], /* I Input signal */ + const SKP_int subfr_length, /* I Subframe length incl preceeding samples */ + const SKP_int nb_subfr /* I: Number of subframes */ +) +{ + SKP_int k; + SKP_float a[ MAX_LPC_ORDER ]; + + /* Used only for NLSF interpolation */ + double res_nrg, res_nrg_2nd, res_nrg_interp; + SKP_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; + SKP_float a_tmp[ MAX_LPC_ORDER ]; + SKP_float LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; + + /* Default: No interpolation */ + *interpIndex = 4; + + /* Burg AR analysis for the full frame */ + res_nrg = SKP_Silk_burg_modified_FLP( a, x, subfr_length, nb_subfr, FIND_LPC_COND_FAC, LPC_order ); + + if( firstFrameAfterReset ) { + SKP_Silk_bwexpander_FLP( a, LPC_order, FIND_LPC_CHIRP_FIRST_FRAME ); + } else { + SKP_Silk_bwexpander_FLP( a_tmp, LPC_order, FIND_LPC_CHIRP ); + } + + if( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) { + /* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */ + /* adding it to the residual energy of the first 10 ms in each iteration of the search below */ + res_nrg -= SKP_Silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length, + subfr_length, MAX_NB_SUBFR / 2, FIND_LPC_COND_FAC, LPC_order ); + + SKP_Silk_bwexpander_FLP( a_tmp, LPC_order, FIND_LPC_CHIRP ); + + /* Convert to NLSFs */ + SKP_Silk_A2NLSF_FLP( NLSF_Q15, a_tmp, LPC_order ); + + /* Search over interpolation indices to find the one with lowest residual energy */ + res_nrg_2nd = SKP_float_MAX; + for( k = 3; k >= 0; k-- ) { + /* Interpolate NLSFs for first half */ + SKP_Silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order ); + + /* Convert to LPC for residual energy evaluation */ + SKP_Silk_NLSF2A_stable_FLP( a_tmp, NLSF0_Q15, LPC_order ); + + /* Calculate residual energy with LSF interpolation */ + SKP_Silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, LPC_order ); + res_nrg_interp = + SKP_Silk_energy_FLP( LPC_res + LPC_order, subfr_length - LPC_order ) + + SKP_Silk_energy_FLP( LPC_res + LPC_order + subfr_length, subfr_length - LPC_order ); + + /* Determine whether current interpolated NLSFs are best so far */ + if( res_nrg_interp < res_nrg ) { + /* Interpolation has lower residual energy */ + res_nrg = res_nrg_interp; + *interpIndex = (SKP_int8)k; + } else if( res_nrg_interp > res_nrg_2nd ) { + /* No reason to continue iterating - residual energies will continue to climb */ + break; + } + res_nrg_2nd = res_nrg_interp; + } + } + + if( *interpIndex == 4 ) { + /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ + SKP_Silk_A2NLSF_FLP( NLSF_Q15, a, LPC_order ); + } + + SKP_assert( *interpIndex == 4 || ( useInterpNLSFs && !firstFrameAfterReset && nb_subfr == MAX_NB_SUBFR ) ); +} diff --git a/silk/float/SKP_Silk_find_LTP_FLP.c b/silk/float/SKP_Silk_find_LTP_FLP.c new file mode 100644 index 00000000..7daf5fbb --- /dev/null +++ b/silk/float/SKP_Silk_find_LTP_FLP.c @@ -0,0 +1,128 @@ +/*********************************************************************** +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_FLP.h" +#include "SKP_Silk_tuning_parameters.h" + +void SKP_Silk_find_LTP_FLP( + SKP_float b[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ + SKP_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ + SKP_float *LTPredCodGain, /* O LTP coding gain */ + const SKP_float r_lpc[], /* I LPC residual */ + const SKP_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ + const SKP_float Wght[ MAX_NB_SUBFR ], /* I Weights */ + const SKP_int subfr_length, /* I Subframe length */ + const SKP_int nb_subfr, /* I number of subframes */ + const SKP_int mem_offset /* I Number of samples in LTP memory */ +) +{ + SKP_int i, k; + SKP_float *b_ptr, temp, *WLTP_ptr; + SKP_float LPC_res_nrg, LPC_LTP_res_nrg; + SKP_float d[ MAX_NB_SUBFR ], m, g, delta_b[ LTP_ORDER ]; + SKP_float w[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], regu; + SKP_float Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ]; + const SKP_float *r_ptr, *lag_ptr; + + b_ptr = b; + WLTP_ptr = WLTP; + r_ptr = &r_lpc[ mem_offset ]; + for( k = 0; k < nb_subfr; k++ ) { + lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); + + SKP_Silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, WLTP_ptr ); + SKP_Silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr ); + + rr[ k ] = ( SKP_float )SKP_Silk_energy_FLP( r_ptr, subfr_length ); + regu = 1.0f + rr[ k ] + + matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ) + + matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ); + regu *= LTP_DAMPING / 3; + SKP_Silk_regularize_correlations_FLP( WLTP_ptr, &rr[ k ], regu, LTP_ORDER ); + SKP_Silk_solve_LDL_FLP( WLTP_ptr, LTP_ORDER, Rr, b_ptr ); + + /* Calculate residual energy */ + nrg[ k ] = SKP_Silk_residual_energy_covar_FLP( b_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER ); + + temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); + SKP_Silk_scale_vector_FLP( WLTP_ptr, temp, LTP_ORDER * LTP_ORDER ); + w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER / 2, LTP_ORDER / 2, LTP_ORDER ); + + r_ptr += subfr_length; + b_ptr += LTP_ORDER; + WLTP_ptr += LTP_ORDER * LTP_ORDER; + } + + /* Compute LTP coding gain */ + if( LTPredCodGain != NULL ) { + LPC_LTP_res_nrg = 1e-6f; + LPC_res_nrg = 0.0f; + for( k = 0; k < nb_subfr; k++ ) { + LPC_res_nrg += rr[ k ] * Wght[ k ]; + LPC_LTP_res_nrg += nrg[ k ] * Wght[ k ]; + } + + SKP_assert( LPC_LTP_res_nrg > 0 ); + *LTPredCodGain = 3.0f * SKP_Silk_log2( LPC_res_nrg / LPC_LTP_res_nrg ); + } + + /* Smoothing */ + /* d = sum( B, 1 ); */ + b_ptr = b; + for( k = 0; k < nb_subfr; k++ ) { + d[ k ] = 0; + for( i = 0; i < LTP_ORDER; i++ ) { + d[ k ] += b_ptr[ i ]; + } + b_ptr += LTP_ORDER; + } + /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */ + temp = 1e-3f; + for( k = 0; k < nb_subfr; k++ ) { + temp += w[ k ]; + } + m = 0; + for( k = 0; k < nb_subfr; k++ ) { + m += d[ k ] * w[ k ]; + } + m = m / temp; + + b_ptr = b; + for( k = 0; k < nb_subfr; k++ ) { + g = LTP_SMOOTHING / ( LTP_SMOOTHING + w[ k ] ) * ( m - d[ k ] ); + temp = 0; + for( i = 0; i < LTP_ORDER; i++ ) { + delta_b[ i ] = SKP_max_float( b_ptr[ i ], 0.1f ); + temp += delta_b[ i ]; + } + temp = g / temp; + for( i = 0; i < LTP_ORDER; i++ ) { + b_ptr[ i ] = b_ptr[ i ] + delta_b[ i ] * temp; + } + b_ptr += LTP_ORDER; + } +} diff --git a/silk/float/SKP_Silk_find_pitch_lags_FLP.c b/silk/float/SKP_Silk_find_pitch_lags_FLP.c new file mode 100644 index 00000000..c8de0e26 --- /dev/null +++ b/silk/float/SKP_Silk_find_pitch_lags_FLP.c @@ -0,0 +1,127 @@ +/*********************************************************************** +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 +#include "SKP_Silk_main_FLP.h" +#include "SKP_Silk_tuning_parameters.h" + +void SKP_Silk_find_pitch_lags_FLP( + SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + SKP_float res[], /* O Residual */ + const SKP_float x[] /* I Speech signal */ +) +{ + SKP_int buf_len; + SKP_float thrhld, res_nrg; + const SKP_float *x_buf_ptr, *x_buf; + SKP_float auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; + SKP_float A[ MAX_FIND_PITCH_LPC_ORDER ]; + SKP_float refl_coef[ MAX_FIND_PITCH_LPC_ORDER ]; + SKP_float Wsig[ FIND_PITCH_LPC_WIN_MAX ]; + SKP_float *Wsig_ptr; + + /******************************************/ + /* Setup buffer lengths etc based on Fs */ + /******************************************/ + buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; + + /* Safty check */ + SKP_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); + + x_buf = x - psEnc->sCmn.ltp_mem_length; + + /******************************************/ + /* Estimate LPC AR coeficients */ + /******************************************/ + + /* Calculate windowed signal */ + + /* First LA_LTP samples */ + x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length; + Wsig_ptr = Wsig; + SKP_Silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch ); + + /* Middle non-windowed samples */ + Wsig_ptr += psEnc->sCmn.la_pitch; + x_buf_ptr += psEnc->sCmn.la_pitch; + SKP_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ) ) * sizeof( SKP_float ) ); + + /* Last LA_LTP samples */ + Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ); + x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ); + SKP_Silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch ); + + /* Calculate autocorrelation sequence */ + SKP_Silk_autocorrelation_FLP( auto_corr, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 ); + + /* Add white noise, as a fraction of the energy */ + auto_corr[ 0 ] += auto_corr[ 0 ] * FIND_PITCH_WHITE_NOISE_FRACTION + 1; + + /* Calculate the reflection coefficients using Schur */ + res_nrg = SKP_Silk_schur_FLP( refl_coef, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); + + /* Prediction gain */ + psEncCtrl->predGain = auto_corr[ 0 ] / SKP_max_float( res_nrg, 1.0f ); + + /* Convert reflection coefficients to prediction coefficients */ + SKP_Silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder ); + + /* Bandwidth expansion */ + SKP_Silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWITH_EXPANSION ); + + /*****************************************/ + /* LPC analysis filtering */ + /*****************************************/ + SKP_Silk_LPC_analysis_filter_FLP( res, A, x_buf, buf_len, psEnc->sCmn.pitchEstimationLPCOrder ); + + if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { + /* Threshold for pitch estimator */ + thrhld = 0.6f; + thrhld -= 0.004f * psEnc->sCmn.pitchEstimationLPCOrder; + thrhld -= 0.1f * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); + thrhld -= 0.15f * (psEnc->sCmn.prevSignalType >> 1); + thrhld -= 0.1f * psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ); + + /*****************************************/ + /* Call Pitch estimator */ + /*****************************************/ + if( SKP_Silk_pitch_analysis_core_FLP( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, + &psEnc->sCmn.indices.contourIndex, &psEnc->LTPCorr, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16 / 65536.0f, + thrhld, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 ) + { + psEnc->sCmn.indices.signalType = TYPE_VOICED; + } else { + psEnc->sCmn.indices.signalType = TYPE_UNVOICED; + } + } else { + SKP_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); + psEnc->sCmn.indices.lagIndex = 0; + psEnc->sCmn.indices.contourIndex = 0; + psEnc->LTPCorr = 0; + } +} diff --git a/silk/float/SKP_Silk_find_pred_coefs_FLP.c b/silk/float/SKP_Silk_find_pred_coefs_FLP.c new file mode 100644 index 00000000..00b1cead --- /dev/null +++ b/silk/float/SKP_Silk_find_pred_coefs_FLP.c @@ -0,0 +1,114 @@ +/*********************************************************************** +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_FLP.h" + + +void SKP_Silk_find_pred_coefs_FLP( + SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + const SKP_float res_pitch[], /* I Residual from pitch analysis */ + const SKP_float x[] /* I Speech signal */ +) +{ + SKP_int i; + SKP_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; + SKP_float invGains[ MAX_NB_SUBFR ], Wght[ MAX_NB_SUBFR ]; + SKP_int16 NLSF_Q15[ MAX_LPC_ORDER ]; + const SKP_float *x_ptr; + SKP_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; + + /* Weighting for weighted least squares */ + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + SKP_assert( psEncCtrl->Gains[ i ] > 0.0f ); + invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ]; + Wght[ i ] = invGains[ i ] * invGains[ i ]; + } + + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /**********/ + /* VOICED */ + /**********/ + SKP_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); + + /* LTP analysis */ + SKP_Silk_find_LTP_FLP( psEncCtrl->LTPCoef, WLTP, &psEncCtrl->LTPredCodGain, res_pitch, + psEncCtrl->pitchL, Wght, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length ); + +#ifdef SAVE_ALL_INTERNAL_DATA + DEBUG_STORE_DATA( ltp_gains.dat, psEncCtrl->LTPCoef, sizeof( psEncCtrl->LTPCoef ) ); + DEBUG_STORE_DATA( ltp_weights.dat, WLTP, sizeof( WLTP ) ); +#endif + + /* Quantize LTP gain parameters */ + SKP_Silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, + WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity , psEnc->sCmn.nb_subfr ); + + /* Control LTP scaling */ + SKP_Silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl ); + + /* Create LTP residual */ + SKP_Silk_LTP_analysis_filter_FLP( LPC_in_pre, psEnc->x_buf + psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder, + psEncCtrl->LTPCoef, psEncCtrl->pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); + + } else { + /************/ + /* UNVOICED */ + /************/ + /* Create signal with prepended subframes, scaled by inverse gains */ + x_ptr = x - psEnc->sCmn.predictLPCOrder; + x_pre_ptr = LPC_in_pre; + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + SKP_Silk_scale_copy_vector_FLP( x_pre_ptr, x_ptr, invGains[ i ], + psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); + x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; + x_ptr += psEnc->sCmn.subfr_length; + } + + SKP_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) ); + psEncCtrl->LTPredCodGain = 0.0f; + } + + /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ + SKP_Silk_find_LPC_FLP( NLSF_Q15, &psEnc->sCmn.indices.NLSFInterpCoef_Q2, psEnc->sCmn.prev_NLSFq_Q15, + psEnc->sCmn.useInterpolatedNLSFs, psEnc->sCmn.first_frame_after_reset, psEnc->sCmn.predictLPCOrder, + LPC_in_pre, psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder, psEnc->sCmn.nb_subfr ); + + + /* Quantize LSFs */ +TIC(LSF_quant); + SKP_Silk_process_NLSFs_FLP( &psEnc->sCmn, psEncCtrl->PredCoef, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); +TOC(LSF_quant); + + /* Calculate residual energy using quantized LPC coefficients */ + SKP_Silk_residual_energy_FLP( psEncCtrl->ResNrg, LPC_in_pre, psEncCtrl->PredCoef, psEncCtrl->Gains, + psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); + + /* Copy to prediction struct for use in next frame for fluctuation reduction */ + SKP_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); +} + diff --git a/silk/float/SKP_Silk_noise_shape_analysis_FLP.c b/silk/float/SKP_Silk_noise_shape_analysis_FLP.c new file mode 100644 index 00000000..05f98fa8 --- /dev/null +++ b/silk/float/SKP_Silk_noise_shape_analysis_FLP.c @@ -0,0 +1,359 @@ +/*********************************************************************** +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_FLP.h" +#include "SKP_Silk_tuning_parameters.h" + +/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ +/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ +SKP_INLINE SKP_float warped_gain( + const SKP_float *coefs, + SKP_float lambda, + SKP_int order +) { + SKP_int i; + SKP_float gain; + + lambda = -lambda; + gain = coefs[ order - 1 ]; + for( i = order - 2; i >= 0; i-- ) { + gain = lambda * gain + coefs[ i ]; + } + return (SKP_float)( 1.0f / ( 1.0f - lambda * gain ) ); +} + +/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ +/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ +SKP_INLINE void warped_true2monic_coefs( + SKP_float *coefs_syn, + SKP_float *coefs_ana, + SKP_float lambda, + SKP_float limit, + SKP_int order +) { + SKP_int i, iter, ind = 0; + SKP_float tmp, maxabs, chirp, gain_syn, gain_ana; + + /* Convert to monic coefficients */ + for( i = order - 1; i > 0; i-- ) { + coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ]; + coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ]; + } + gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] ); + gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] ); + for( i = 0; i < order; i++ ) { + coefs_syn[ i ] *= gain_syn; + coefs_ana[ i ] *= gain_ana; + } + + /* Limit */ + for( iter = 0; iter < 10; iter++ ) { + /* Find maximum absolute value */ + maxabs = -1.0f; + for( i = 0; i < order; i++ ) { + tmp = SKP_max( SKP_abs_float( coefs_syn[ i ] ), SKP_abs_float( coefs_ana[ i ] ) ); + if( tmp > maxabs ) { + maxabs = tmp; + ind = i; + } + } + if( maxabs <= limit ) { + /* Coefficients are within range - done */ + return; + } + + /* Convert back to true warped coefficients */ + for( i = 1; i < order; i++ ) { + coefs_syn[ i - 1 ] += lambda * coefs_syn[ i ]; + coefs_ana[ i - 1 ] += lambda * coefs_ana[ i ]; + } + gain_syn = 1.0f / gain_syn; + gain_ana = 1.0f / gain_ana; + for( i = 0; i < order; i++ ) { + coefs_syn[ i ] *= gain_syn; + coefs_ana[ i ] *= gain_ana; + } + + /* Apply bandwidth expansion */ + chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) ); + SKP_Silk_bwexpander_FLP( coefs_syn, order, chirp ); + SKP_Silk_bwexpander_FLP( coefs_ana, order, chirp ); + + /* Convert to monic warped coefficients */ + for( i = order - 1; i > 0; i-- ) { + coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ]; + coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ]; + } + gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] ); + gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] ); + for( i = 0; i < order; i++ ) { + coefs_syn[ i ] *= gain_syn; + coefs_ana[ i ] *= gain_ana; + } + } + SKP_assert( 0 ); +} + +/* Compute noise shaping coefficients and initial gain values */ +void SKP_Silk_noise_shape_analysis_FLP( + SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + const SKP_float *pitch_res, /* I LPC residual from pitch analysis */ + const SKP_float *x /* I Input signal [frame_length + la_shape] */ +) +{ + SKP_Silk_shape_state_FLP *psShapeSt = &psEnc->sShape; + SKP_int k, nSamples; + SKP_float SNR_adj_dB, HarmBoost, HarmShapeGain, Tilt; + SKP_float nrg, pre_nrg, log_energy, log_energy_prev, energy_variation; + SKP_float delta, BWExp1, BWExp2, gain_mult, gain_add, strength, b, warping; + SKP_float x_windowed[ SHAPE_LPC_WIN_MAX ]; + SKP_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; + const SKP_float *x_ptr, *pitch_res_ptr; + + /* Point to start of first LPC analysis block */ + x_ptr = x - psEnc->sCmn.la_shape; + + /****************/ + /* GAIN CONTROL */ + /****************/ + SNR_adj_dB = psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ); + + /* Input quality is the average of the quality in the lowest two VAD bands */ + psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f ); + + /* Coding quality level, between 0.0 and 1.0 */ + psEncCtrl->coding_quality = SKP_sigmoid( 0.25f * ( SNR_adj_dB - 18.0f ) ); + + if( psEnc->sCmn.useCBR == 0 ) { + /* Reduce coding SNR during low speech activity */ + b = 1.0f - psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); + SNR_adj_dB -= BG_SNR_DECR_dB * psEncCtrl->coding_quality * ( 0.5f + 0.5f * psEncCtrl->input_quality ) * b * b; + } + + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Reduce gains for periodic signals */ + SNR_adj_dB += HARM_SNR_INCR_dB * psEnc->LTPCorr; + } else { + /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ + SNR_adj_dB += ( -0.4f * psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) + 6.0f ) * ( 1.0f - psEncCtrl->input_quality ); + } + + /*************************/ + /* SPARSENESS PROCESSING */ + /*************************/ + /* Set quantizer offset */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Initally set to 0; may be overruled in process_gains(..) */ + psEnc->sCmn.indices.quantOffsetType = 0; + psEncCtrl->sparseness = 0.0f; + } else { + /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ + nSamples = 2 * psEnc->sCmn.fs_kHz; + energy_variation = 0.0f; + log_energy_prev = 0.0f; + pitch_res_ptr = pitch_res; + for( k = 0; k < SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) { + nrg = ( SKP_float )nSamples + ( SKP_float )SKP_Silk_energy_FLP( pitch_res_ptr, nSamples ); + log_energy = SKP_Silk_log2( nrg ); + if( k > 0 ) { + energy_variation += SKP_abs_float( log_energy - log_energy_prev ); + } + log_energy_prev = log_energy; + pitch_res_ptr += nSamples; + } + psEncCtrl->sparseness = SKP_sigmoid( 0.4f * ( energy_variation - 5.0f ) ); + + /* Set quantization offset depending on sparseness measure */ + if( psEncCtrl->sparseness > SPARSENESS_THRESHOLD_QNT_OFFSET ) { + psEnc->sCmn.indices.quantOffsetType = 0; + } else { + psEnc->sCmn.indices.quantOffsetType = 1; + } + + /* Increase coding SNR for sparse signals */ + SNR_adj_dB += SPARSE_SNR_INCR_dB * ( psEncCtrl->sparseness - 0.5f ); + } + + /*******************************/ + /* Control bandwidth expansion */ + /*******************************/ + /* More BWE for signals with high prediction gain */ + strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */ + BWExp1 = BWExp2 = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength ); + delta = LOW_RATE_BANDWIDTH_EXPANSION_DELTA * ( 1.0f - 0.75f * psEncCtrl->coding_quality ); + BWExp1 -= delta; + BWExp2 += delta; + /* BWExp1 will be applied after BWExp2, so make it relative */ + BWExp1 /= BWExp2; + + if( psEnc->sCmn.warping_Q16 > 0 ) { + /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ + warping = (SKP_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality; + } else { + warping = 0.0f; + } + + /********************************************/ + /* Compute noise shaping AR coefs and gains */ + /********************************************/ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + /* Apply window: sine slope followed by flat part followed by cosine slope */ + SKP_int shift, slope_part, flat_part; + flat_part = psEnc->sCmn.fs_kHz * 3; + slope_part = ( psEnc->sCmn.shapeWinLength - flat_part ) / 2; + + SKP_Silk_apply_sine_window_FLP( x_windowed, x_ptr, 1, slope_part ); + shift = slope_part; + SKP_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(SKP_float) ); + shift += flat_part; + SKP_Silk_apply_sine_window_FLP( x_windowed + shift, x_ptr + shift, 2, slope_part ); + + /* Update pointer: next LPC analysis block */ + x_ptr += psEnc->sCmn.subfr_length; + + if( psEnc->sCmn.warping_Q16 > 0 ) { + /* Calculate warped auto correlation */ + SKP_Silk_warped_autocorrelation_FLP( auto_corr, x_windowed, warping, + psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); + } else { + /* Calculate regular auto correlation */ + SKP_Silk_autocorrelation_FLP( auto_corr, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 ); + } + + /* Add white noise, as a fraction of energy */ + auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION; + + /* Convert correlations to prediction coefficients, and compute residual energy */ + nrg = SKP_Silk_levinsondurbin_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], auto_corr, psEnc->sCmn.shapingLPCOrder ); + psEncCtrl->Gains[ k ] = ( SKP_float )sqrt( nrg ); + + if( psEnc->sCmn.warping_Q16 > 0 ) { + /* Adjust gain for warping */ + psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder ); + } + + /* Bandwidth expansion for synthesis filter shaping */ + SKP_Silk_bwexpander_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp2 ); + + /* Compute noise shaping filter coefficients */ + SKP_memcpy( + &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], + &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], + psEnc->sCmn.shapingLPCOrder * sizeof( SKP_float ) ); + + /* Bandwidth expansion for analysis filter shaping */ + SKP_Silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 ); + + /* Ratio of prediction gains, in energy domain */ + SKP_Silk_LPC_inverse_pred_gain_FLP( &pre_nrg, &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder ); + SKP_Silk_LPC_inverse_pred_gain_FLP( &nrg, &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder ); + psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ); + + /* Convert to monic warped prediction coefficients and limit absolute values */ + warped_true2monic_coefs( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], + warping, 3.999f, psEnc->sCmn.shapingLPCOrder ); + } + + /*****************/ + /* Gain tweaking */ + /*****************/ + /* Increase gains during low speech activity */ + gain_mult = (SKP_float)pow( 2.0f, -0.16f * SNR_adj_dB ); + gain_add = (SKP_float)pow( 2.0f, 0.16f * MIN_QGAIN_DB ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->Gains[ k ] *= gain_mult; + psEncCtrl->Gains[ k ] += gain_add; + } + + gain_mult = 1.0f + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT; + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->GainsPre[ k ] *= gain_mult; + } + + /************************************************/ + /* Control low-frequency shaping and noise tilt */ + /************************************************/ + /* Less low frequency shaping for noisy inputs */ + strength = LOW_FREQ_SHAPING * ( 1.0f + LOW_QUALITY_LOW_FREQ_SHAPING_DECR * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] * ( 1.0f / 32768.0f ) - 1.0f ) ); + strength *= psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ + /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + b = 0.2f / psEnc->sCmn.fs_kHz + 3.0f / psEncCtrl->pitchL[ k ]; + psEncCtrl->LF_MA_shp[ k ] = -1.0f + b; + psEncCtrl->LF_AR_shp[ k ] = 1.0f - b - b * strength; + } + Tilt = - HP_NOISE_COEF - + (1 - HP_NOISE_COEF) * HARM_HP_NOISE_COEF * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); + } else { + b = 1.3f / psEnc->sCmn.fs_kHz; + psEncCtrl->LF_MA_shp[ 0 ] = -1.0f + b; + psEncCtrl->LF_AR_shp[ 0 ] = 1.0f - b - b * strength * 0.6f; + for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->LF_MA_shp[ k ] = psEncCtrl->LF_MA_shp[ 0 ]; + psEncCtrl->LF_AR_shp[ k ] = psEncCtrl->LF_AR_shp[ 0 ]; + } + Tilt = -HP_NOISE_COEF; + } + + /****************************/ + /* HARMONIC SHAPING CONTROL */ + /****************************/ + /* Control boosting of harmonic frequencies */ + HarmBoost = LOW_RATE_HARMONIC_BOOST * ( 1.0f - psEncCtrl->coding_quality ) * psEnc->LTPCorr; + + /* More harmonic boost for noisy input signals */ + HarmBoost += LOW_INPUT_QUALITY_HARMONIC_BOOST * ( 1.0f - psEncCtrl->input_quality ); + + if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Harmonic noise shaping */ + HarmShapeGain = HARMONIC_SHAPING; + + /* More harmonic noise shaping for high bitrates or noisy input */ + HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING * + ( 1.0f - ( 1.0f - psEncCtrl->coding_quality ) * psEncCtrl->input_quality ); + + /* Less harmonic noise shaping for less periodic signals */ + HarmShapeGain *= ( SKP_float )sqrt( psEnc->LTPCorr ); + } else { + HarmShapeGain = 0.0f; + } + + /*************************/ + /* Smooth over subframes */ + /*************************/ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psShapeSt->HarmBoost_smth += SUBFR_SMTH_COEF * ( HarmBoost - psShapeSt->HarmBoost_smth ); + psEncCtrl->HarmBoost[ k ] = psShapeSt->HarmBoost_smth; + psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth ); + psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth; + psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth ); + psEncCtrl->Tilt[ k ] = psShapeSt->Tilt_smth; + } +} diff --git a/silk/float/SKP_Silk_prefilter_FLP.c b/silk/float/SKP_Silk_prefilter_FLP.c new file mode 100644 index 00000000..c3a23d15 --- /dev/null +++ b/silk/float/SKP_Silk_prefilter_FLP.c @@ -0,0 +1,202 @@ +/*********************************************************************** +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_FLP.h" +#include "SKP_Silk_tuning_parameters.h" + +/* +* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal +*/ +SKP_INLINE void SKP_Silk_prefilt_FLP( + SKP_Silk_prefilter_state_FLP *P,/* I/O state */ + SKP_float st_res[], /* I */ + SKP_float xw[], /* O */ + SKP_float *HarmShapeFIR, /* I */ + SKP_float Tilt, /* I */ + SKP_float LF_MA_shp, /* I */ + SKP_float LF_AR_shp, /* I */ + SKP_int lag, /* I */ + SKP_int length /* I */ +); + +void SKP_Silk_warped_LPC_analysis_filter_FLP( + SKP_float state[], /* I/O State [order + 1] */ + SKP_float res[], /* O Residual signal [length] */ + const SKP_float coef[], /* I Coefficients [order] */ + const SKP_float input[], /* I Input signal [length] */ + const SKP_float lambda, /* I Warping factor */ + const SKP_int length, /* I Length of input signal */ + const SKP_int order /* I Filter order (even) */ +) +{ + SKP_int n, i; + SKP_float acc, tmp1, tmp2; + + /* Order must be even */ + SKP_assert( ( order & 1 ) == 0 ); + + for( n = 0; n < length; n++ ) { + /* Output of lowpass section */ + tmp2 = state[ 0 ] + lambda * state[ 1 ]; + state[ 0 ] = input[ n ]; + /* Output of allpass section */ + tmp1 = state[ 1 ] + lambda * ( state[ 2 ] - tmp2 ); + state[ 1 ] = tmp2; + acc = coef[ 0 ] * tmp2; + /* Loop over allpass sections */ + for( i = 2; i < order; i += 2 ) { + /* Output of allpass section */ + tmp2 = state[ i ] + lambda * ( state[ i + 1 ] - tmp1 ); + state[ i ] = tmp1; + acc += coef[ i - 1 ] * tmp1; + /* Output of allpass section */ + tmp1 = state[ i + 1 ] + lambda * ( state[ i + 2 ] - tmp2 ); + state[ i + 1 ] = tmp2; + acc += coef[ i ] * tmp2; + } + state[ order ] = tmp1; + acc += coef[ order - 1 ] * tmp1; + res[ n ] = input[ n ] - acc; + } +} + +/* +* SKP_Silk_prefilter. Main prefilter function +*/ +void SKP_Silk_prefilter_FLP( + SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + const SKP_Silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */ + SKP_float xw[], /* O Weighted signal */ + const SKP_float x[] /* I Speech signal */ +) +{ + SKP_Silk_prefilter_state_FLP *P = &psEnc->sPrefilt; + SKP_int j, k, lag; + SKP_float HarmShapeGain, Tilt, LF_MA_shp, LF_AR_shp; + SKP_float B[ 2 ]; + const SKP_float *AR1_shp; + const SKP_float *px; + SKP_float *pxw; + SKP_float HarmShapeFIR[ 3 ]; + SKP_float st_res[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ]; + + /* Setup pointers */ + px = x; + pxw = xw; + lag = P->lagPrev; + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + /* Update Variables that change per sub frame */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + lag = psEncCtrl->pitchL[ k ]; + } + + /* Noise shape parameters */ + HarmShapeGain = psEncCtrl->HarmShapeGain[ k ] * ( 1.0f - psEncCtrl->HarmBoost[ k ] ); + HarmShapeFIR[ 0 ] = 0.25f * HarmShapeGain; + HarmShapeFIR[ 1 ] = 32767.0f / 65536.0f * HarmShapeGain; + HarmShapeFIR[ 2 ] = 0.25f * HarmShapeGain; + Tilt = psEncCtrl->Tilt[ k ]; + LF_MA_shp = psEncCtrl->LF_MA_shp[ k ]; + LF_AR_shp = psEncCtrl->LF_AR_shp[ k ]; + AR1_shp = &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ]; + + /* Short term FIR filtering */ + SKP_Silk_warped_LPC_analysis_filter_FLP( P->sAR_shp, st_res, AR1_shp, px, + (SKP_float)psEnc->sCmn.warping_Q16 / 65536.0f, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder ); + + /* Reduce (mainly) low frequencies during harmonic emphasis */ + B[ 0 ] = psEncCtrl->GainsPre[ k ]; + B[ 1 ] = -psEncCtrl->GainsPre[ k ] * + ( psEncCtrl->HarmBoost[ k ] * HarmShapeGain + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT ); + pxw[ 0 ] = B[ 0 ] * st_res[ 0 ] + B[ 1 ] * P->sHarmHP; + for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) { + pxw[ j ] = B[ 0 ] * st_res[ j ] + B[ 1 ] * st_res[ j - 1 ]; + } + P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ]; + + SKP_Silk_prefilt_FLP( P, pxw, pxw, HarmShapeFIR, Tilt, LF_MA_shp, LF_AR_shp, lag, psEnc->sCmn.subfr_length ); + + px += psEnc->sCmn.subfr_length; + pxw += psEnc->sCmn.subfr_length; + } + P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ]; +} + +/* +* Prefilter for finding Quantizer input signal +*/ +SKP_INLINE void SKP_Silk_prefilt_FLP( + SKP_Silk_prefilter_state_FLP *P,/* I/O state */ + SKP_float st_res[], /* I */ + SKP_float xw[], /* O */ + SKP_float *HarmShapeFIR, /* I */ + SKP_float Tilt, /* I */ + SKP_float LF_MA_shp, /* I */ + SKP_float LF_AR_shp, /* I */ + SKP_int lag, /* I */ + SKP_int length /* I */ +) +{ + SKP_int i; + SKP_int idx, LTP_shp_buf_idx; + SKP_float n_Tilt, n_LF, n_LTP; + SKP_float sLF_AR_shp, sLF_MA_shp; + SKP_float *LTP_shp_buf; + + /* To speed up use temp variables instead of using the struct */ + LTP_shp_buf = P->sLTP_shp; + LTP_shp_buf_idx = P->sLTP_shp_buf_idx; + sLF_AR_shp = P->sLF_AR_shp; + sLF_MA_shp = P->sLF_MA_shp; + + for( i = 0; i < length; i++ ) { + if( lag > 0 ) { + SKP_assert( HARM_SHAPE_FIR_TAPS == 3 ); + idx = lag + LTP_shp_buf_idx; + n_LTP = LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ] * HarmShapeFIR[ 0 ]; + n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ] * HarmShapeFIR[ 1 ]; + n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ] * HarmShapeFIR[ 2 ]; + } else { + n_LTP = 0; + } + + n_Tilt = sLF_AR_shp * Tilt; + n_LF = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp; + + sLF_AR_shp = st_res[ i ] - n_Tilt; + sLF_MA_shp = sLF_AR_shp - n_LF; + + LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK; + LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp; + + xw[ i ] = sLF_MA_shp - n_LTP; + } + /* Copy temp variable back to state */ + P->sLF_AR_shp = sLF_AR_shp; + P->sLF_MA_shp = sLF_MA_shp; + P->sLTP_shp_buf_idx = LTP_shp_buf_idx; +} diff --git a/silk/float/SKP_Silk_process_gains_FLP.c b/silk/float/SKP_Silk_process_gains_FLP.c new file mode 100644 index 00000000..4f0a2089 --- /dev/null +++ b/silk/float/SKP_Silk_process_gains_FLP.c @@ -0,0 +1,94 @@ +/*********************************************************************** +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_FLP.h" +#include "SKP_Silk_tuning_parameters.h" + +/* Processing of gains */ +void SKP_Silk_process_gains_FLP( + SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + SKP_Silk_encoder_control_FLP *psEncCtrl /* I/O Encoder control FLP */ +) +{ + SKP_Silk_shape_state_FLP *psShapeSt = &psEnc->sShape; + SKP_int k; + SKP_int32 pGains_Q16[ MAX_NB_SUBFR ]; + SKP_float s, InvMaxSqrVal, gain, quant_offset; + + /* Gain reduction when LTP coding gain is high */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + s = 1.0f - 0.5f * SKP_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->Gains[ k ] *= s; + } + } + + /* Limit the quantized signal */ + InvMaxSqrVal = ( SKP_float )( pow( 2.0f, 0.33f * ( 21.0f - psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) ) ) / psEnc->sCmn.subfr_length ); + + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + /* Soft limit on ratio residual energy and squared gains */ + gain = psEncCtrl->Gains[ k ]; + gain = ( SKP_float )sqrt( gain * gain + psEncCtrl->ResNrg[ k ] * InvMaxSqrVal ); + psEncCtrl->Gains[ k ] = SKP_min_float( gain, 32767.0f ); + } + + /* Prepare gains for noise shaping quantization */ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + pGains_Q16[ k ] = ( SKP_int32 ) ( psEncCtrl->Gains[ k ] * 65536.0f ); + } + + /* Noise shaping quantization */ + SKP_Silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, + &psShapeSt->LastGainIndex, psEnc->sCmn.nFramesAnalyzed, psEnc->sCmn.nb_subfr ); + + /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->Gains[ k ] = pGains_Q16[ k ] / 65536.0f; + } + + /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + if( psEncCtrl->LTPredCodGain + psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ) > 1.0f ) { + psEnc->sCmn.indices.quantOffsetType = 0; + } else { + psEnc->sCmn.indices.quantOffsetType = 1; + } + } + + /* Quantizer boundary adjustment */ + quant_offset = SKP_Silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ] / 1024.0f; + psEncCtrl->Lambda = LAMBDA_OFFSET + + LAMBDA_DELAYED_DECISIONS * psEnc->sCmn.nStatesDelayedDecision + + LAMBDA_SPEECH_ACT * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ) + + LAMBDA_INPUT_QUALITY * psEncCtrl->input_quality + + LAMBDA_CODING_QUALITY * psEncCtrl->coding_quality + + LAMBDA_QUANT_OFFSET * quant_offset; + + SKP_assert( psEncCtrl->Lambda > 0.0f ); + SKP_assert( psEncCtrl->Lambda < 2.0f ); +} diff --git a/silk/float/SKP_Silk_regularize_correlations_FLP.c b/silk/float/SKP_Silk_regularize_correlations_FLP.c new file mode 100644 index 00000000..3acb944d --- /dev/null +++ b/silk/float/SKP_Silk_regularize_correlations_FLP.c @@ -0,0 +1,43 @@ +/*********************************************************************** +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_FLP.h" + +void SKP_Silk_regularize_correlations_FLP( + SKP_float *XX, /* I/O Correlation matrices */ + SKP_float *xx, /* I/O Correlation values */ + const SKP_float noise, /* I Noise energy to add */ + const SKP_int D /* I Dimension of XX */ +) +{ + SKP_int i; + + for( i = 0; i < D; i++ ) { + matrix_ptr( &XX[ 0 ], i, i, D ) += noise; + } + xx[ 0 ] += noise; +} diff --git a/silk/float/SKP_Silk_residual_energy_FLP.c b/silk/float/SKP_Silk_residual_energy_FLP.c new file mode 100644 index 00000000..1d11b4ec --- /dev/null +++ b/silk/float/SKP_Silk_residual_energy_FLP.c @@ -0,0 +1,113 @@ +/*********************************************************************** +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_FLP.h" + +#define MAX_ITERATIONS_RESIDUAL_NRG 10 +#define REGULARIZATION_FACTOR 1e-8f + +/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ +SKP_float SKP_Silk_residual_energy_covar_FLP( /* O Weighted residual energy */ + const SKP_float *c, /* I Filter coefficients */ + SKP_float *wXX, /* I/O Weighted correlation matrix, reg. out */ + const SKP_float *wXx, /* I Weighted correlation vector */ + const SKP_float wxx, /* I Weighted correlation value */ + const SKP_int D /* I Dimension */ +) +{ + SKP_int i, j, k; + SKP_float tmp, nrg, regularization; + + /* Safety checks */ + SKP_assert( D >= 0 ); + + regularization = REGULARIZATION_FACTOR * ( wXX[ 0 ] + wXX[ D * D - 1 ] ); + for( k = 0; k < MAX_ITERATIONS_RESIDUAL_NRG; k++ ) { + nrg = wxx; + + tmp = 0.0f; + for( i = 0; i < D; i++ ) { + tmp += wXx[ i ] * c[ i ]; + } + nrg -= 2.0f * tmp; + + /* compute c' * wXX * c, assuming wXX is symmetric */ + for( i = 0; i < D; i++ ) { + tmp = 0.0f; + for( j = i + 1; j < D; j++ ) { + tmp += matrix_c_ptr( wXX, i, j, D ) * c[ j ]; + } + nrg += c[ i ] * ( 2.0f * tmp + matrix_c_ptr( wXX, i, i, D ) * c[ i ] ); + } + if( nrg > 0 ) { + break; + } else { + /* Add white noise */ + for( i = 0; i < D; i++ ) { + matrix_c_ptr( wXX, i, i, D ) += regularization; + } + /* Increase noise for next run */ + regularization *= 2.0f; + } + } + if( k == MAX_ITERATIONS_RESIDUAL_NRG ) { + SKP_assert( nrg == 0 ); + nrg = 1.0f; + } + + return nrg; +} + +/* Calculates residual energies of input subframes where all subframes have LPC_order */ +/* of preceeding samples */ +void SKP_Silk_residual_energy_FLP( + SKP_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ + const SKP_float x[], /* I Input signal */ + const SKP_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ + const SKP_float gains[], /* I Quantization gains */ + const SKP_int subfr_length, /* I Subframe length */ + const SKP_int nb_subfr, /* I number of subframes */ + const SKP_int LPC_order /* I LPC order */ +) +{ + SKP_int shift; + SKP_float *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; + + LPC_res_ptr = LPC_res + LPC_order; + shift = LPC_order + subfr_length; + + /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ + SKP_Silk_LPC_analysis_filter_FLP( LPC_res, a[ 0 ], x + 0 * shift, 2 * shift, LPC_order ); + nrgs[ 0 ] = ( SKP_float )( gains[ 0 ] * gains[ 0 ] * SKP_Silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) ); + nrgs[ 1 ] = ( SKP_float )( gains[ 1 ] * gains[ 1 ] * SKP_Silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) ); + + if( nb_subfr == MAX_NB_SUBFR ) { + SKP_Silk_LPC_analysis_filter_FLP( LPC_res, a[ 1 ], x + 2 * shift, 2 * shift, LPC_order ); + nrgs[ 2 ] = ( SKP_float )( gains[ 2 ] * gains[ 2 ] * SKP_Silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) ); + nrgs[ 3 ] = ( SKP_float )( gains[ 3 ] * gains[ 3 ] * SKP_Silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) ); + } +} diff --git a/silk/float/SKP_Silk_solve_LS_FLP.c b/silk/float/SKP_Silk_solve_LS_FLP.c new file mode 100644 index 00000000..e6c02c4d --- /dev/null +++ b/silk/float/SKP_Silk_solve_LS_FLP.c @@ -0,0 +1,203 @@ +/*********************************************************************** +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_FLP.h" +#include "SKP_Silk_tuning_parameters.h" + +/********************************************************************** + * LDL Factorisation. Finds the upper triangular matrix L and the diagonal + * Matrix D (only the diagonal elements returned in a vector)such that + * the symmetric matric A is given by A = L*D*L'. + **********************************************************************/ +void SKP_Silk_LDL_FLP( + SKP_float *A, /* (I/O) Pointer to Symetric Square Matrix */ + SKP_int M, /* (I) Size of Matrix */ + SKP_float *L, /* (I/O) Pointer to Square Upper triangular Matrix */ + SKP_float *Dinv /* (I/O) Pointer to vector holding the inverse diagonal elements of D */ +); + +/********************************************************************** + * Function to solve linear equation Ax = b, when A is a MxM lower + * triangular matrix, with ones on the diagonal. + **********************************************************************/ +void SKP_Silk_SolveWithLowerTriangularWdiagOnes_FLP( + const SKP_float *L, /* (I) Pointer to Lower Triangular Matrix */ + SKP_int M, /* (I) Dim of Matrix equation */ + const SKP_float *b, /* (I) b Vector */ + SKP_float *x /* (O) x Vector */ +); + +/********************************************************************** + * Function to solve linear equation (A^T)x = b, when A is a MxM lower + * triangular, with ones on the diagonal. (ie then A^T is upper triangular) + **********************************************************************/ +void SKP_Silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( + const SKP_float *L, /* (I) Pointer to Lower Triangular Matrix */ + SKP_int M, /* (I) Dim of Matrix equation */ + const SKP_float *b, /* (I) b Vector */ + SKP_float *x /* (O) x Vector */ +); + +/********************************************************************** + * Function to solve linear equation Ax = b, when A is a MxM + * symmetric square matrix - using LDL factorisation + **********************************************************************/ +void SKP_Silk_solve_LDL_FLP( + SKP_float *A, /* I/O Symmetric square matrix, out: reg. */ + const SKP_int M, /* I Size of matrix */ + const SKP_float *b, /* I Pointer to b vector */ + SKP_float *x /* O Pointer to x solution vector */ +) +{ + SKP_int i; + SKP_float L[ MAX_MATRIX_SIZE ][ MAX_MATRIX_SIZE ]; + SKP_float T[ MAX_MATRIX_SIZE ]; + SKP_float Dinv[ MAX_MATRIX_SIZE ]; // inverse diagonal elements of D + + SKP_assert( M <= MAX_MATRIX_SIZE ); + + /*************************************************** + Factorize A by LDL such that A = L*D*(L^T), + where L is lower triangular with ones on diagonal + ****************************************************/ + SKP_Silk_LDL_FLP( A, M, &L[ 0 ][ 0 ], Dinv ); + + /**************************************************** + * substitute D*(L^T) = T. ie: + L*D*(L^T)*x = b => L*T = b <=> T = inv(L)*b + ******************************************************/ + SKP_Silk_SolveWithLowerTriangularWdiagOnes_FLP( &L[ 0 ][ 0 ], M, b, T ); + + /**************************************************** + D*(L^T)*x = T <=> (L^T)*x = inv(D)*T, because D is + diagonal just multiply with 1/d_i + ****************************************************/ + for( i = 0; i < M; i++ ) { + T[ i ] = T[ i ] * Dinv[ i ]; + } + /**************************************************** + x = inv(L') * inv(D) * T + *****************************************************/ + SKP_Silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( &L[ 0 ][ 0 ], M, T, x ); +} + +void SKP_Silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( + const SKP_float *L, /* (I) Pointer to Lower Triangular Matrix */ + SKP_int M, /* (I) Dim of Matrix equation */ + const SKP_float *b, /* (I) b Vector */ + SKP_float *x /* (O) x Vector */ +) +{ + SKP_int i, j; + SKP_float temp; + const SKP_float *ptr1; + + for( i = M - 1; i >= 0; i-- ) { + ptr1 = matrix_adr( L, 0, i, M ); + temp = 0; + for( j = M - 1; j > i ; j-- ) { + temp += ptr1[ j * M ] * x[ j ]; + } + temp = b[ i ] - temp; + x[ i ] = temp; + } +} + +void SKP_Silk_SolveWithLowerTriangularWdiagOnes_FLP( + const SKP_float *L, /* (I) Pointer to Lower Triangular Matrix */ + SKP_int M, /* (I) Dim of Matrix equation */ + const SKP_float *b, /* (I) b Vector */ + SKP_float *x /* (O) x Vector */ +) +{ + SKP_int i, j; + SKP_float temp; + const SKP_float *ptr1; + + for( i = 0; i < M; i++ ) { + ptr1 = matrix_adr( L, i, 0, M ); + temp = 0; + for( j = 0; j < i; j++ ) { + temp += ptr1[ j ] * x[ j ]; + } + temp = b[ i ] - temp; + x[ i ] = temp; + } +} + +void SKP_Silk_LDL_FLP( + SKP_float *A, /* (I/O) Pointer to Symetric Square Matrix */ + SKP_int M, /* (I) Size of Matrix */ + SKP_float *L, /* (I/O) Pointer to Square Upper triangular Matrix */ + SKP_float *Dinv /* (I/O) Pointer to vector holding the inverse diagonal elements of D */ +) +{ + SKP_int i, j, k, loop_count, err = 1; + SKP_float *ptr1, *ptr2; + double temp, diag_min_value; + SKP_float v[ MAX_MATRIX_SIZE ], D[ MAX_MATRIX_SIZE ]; // temp arrays + + SKP_assert( M <= MAX_MATRIX_SIZE ); + + diag_min_value = FIND_LTP_COND_FAC * 0.5f * ( A[ 0 ] + A[ M * M - 1 ] ); + for( loop_count = 0; loop_count < M && err == 1; loop_count++ ) { + err = 0; + for( j = 0; j < M; j++ ) { + ptr1 = matrix_adr( L, j, 0, M ); + temp = matrix_ptr( A, j, j, M ); // element in row j column j + for( i = 0; i < j; i++ ) { + v[ i ] = ptr1[ i ] * D[ i ]; + temp -= ptr1[ i ] * v[ i ]; + } + if( temp < diag_min_value ) { + /* Badly conditioned matrix: add white noise and run again */ + temp = ( loop_count + 1 ) * diag_min_value - temp; + for( i = 0; i < M; i++ ) { + matrix_ptr( A, i, i, M ) += ( SKP_float )temp; + } + err = 1; + break; + } + D[ j ] = ( SKP_float )temp; + Dinv[ j ] = ( SKP_float )( 1.0f / temp ); + matrix_ptr( L, j, j, M ) = 1.0f; + + ptr1 = matrix_adr( A, j, 0, M ); + ptr2 = matrix_adr( L, j + 1, 0, M); + for( i = j + 1; i < M; i++ ) { + temp = 0.0; + for( k = 0; k < j; k++ ) { + temp += ptr2[ k ] * v[ k ]; + } + matrix_ptr( L, i, j, M ) = ( SKP_float )( ( ptr1[ i ] - temp ) * Dinv[ j ] ); + ptr2 += M; // go to next column + } + } + } + SKP_assert( err == 0 ); +} + diff --git a/silk/float/SKP_Silk_warped_autocorrelation_FLP.c b/silk/float/SKP_Silk_warped_autocorrelation_FLP.c new file mode 100644 index 00000000..355d7e49 --- /dev/null +++ b/silk/float/SKP_Silk_warped_autocorrelation_FLP.c @@ -0,0 +1,69 @@ +/*********************************************************************** +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_FLP.h" + +/* Autocorrelations for a warped frequency axis */ +void SKP_Silk_warped_autocorrelation_FLP( + SKP_float *corr, /* O Result [order + 1] */ + const SKP_float *input, /* I Input data to correlate */ + const SKP_float warping, /* I Warping coefficient */ + const SKP_int length, /* I Length of input */ + const SKP_int order /* I Correlation order (even) */ +) +{ + SKP_int n, i; + double tmp1, tmp2; + double state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; + double C[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; + + /* Order must be even */ + SKP_assert( ( order & 1 ) == 0 ); + + /* Loop over samples */ + for( n = 0; n < length; n++ ) { + tmp1 = input[ n ]; + /* Loop over allpass sections */ + for( i = 0; i < order; i += 2 ) { + /* Output of allpass section */ + tmp2 = state[ i ] + warping * ( state[ i + 1 ] - tmp1 ); + state[ i ] = tmp1; + C[ i ] += state[ 0 ] * tmp1; + /* Output of allpass section */ + tmp1 = state[ i + 1 ] + warping * ( state[ i + 2 ] - tmp2 ); + state[ i + 1 ] = tmp2; + C[ i + 1 ] += state[ 0 ] * tmp2; + } + state[ order ] = tmp1; + C[ order ] += state[ 0 ] * tmp1; + } + + /* Copy correlations in SKP_float output format */ + for( i = 0; i < order + 1; i++ ) { + corr[ i ] = ( SKP_float )C[ i ]; + } +} diff --git a/silk/float/SKP_Silk_wrappers_FLP.c b/silk/float/SKP_Silk_wrappers_FLP.c new file mode 100644 index 00000000..9e5b7650 --- /dev/null +++ b/silk/float/SKP_Silk_wrappers_FLP.c @@ -0,0 +1,194 @@ +/*********************************************************************** +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_FLP.h" + +/* Wrappers. Calls flp / fix code */ + +/* Convert AR filter coefficients to NLSF parameters */ +void SKP_Silk_A2NLSF_FLP( + SKP_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */ + const SKP_float *pAR, /* I LPC coefficients [ LPC_order ] */ + const SKP_int LPC_order /* I LPC order */ +) +{ + SKP_int i; + SKP_int32 a_fix_Q16[ MAX_LPC_ORDER ]; + + for( i = 0; i < LPC_order; i++ ) { + a_fix_Q16[ i ] = SKP_float2int( pAR[ i ] * 65536.0f ); + } + + SKP_Silk_A2NLSF( NLSF_Q15, a_fix_Q16, LPC_order ); +} + +/* Convert LSF parameters to AR prediction filter coefficients */ +void SKP_Silk_NLSF2A_stable_FLP( + SKP_float *pAR, /* O LPC coefficients [ LPC_order ] */ + const SKP_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */ + const SKP_int LPC_order /* I LPC order */ +) +{ + SKP_int i; + SKP_int16 a_fix_Q12[ MAX_LPC_ORDER ]; + + SKP_Silk_NLSF2A_stable( a_fix_Q12, NLSF_Q15, LPC_order ); + + for( i = 0; i < LPC_order; i++ ) { + pAR[ i ] = ( SKP_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f ); + } +} + +/******************************************/ +/* Floating-point NLSF processing wrapper */ +/******************************************/ +void SKP_Silk_process_NLSFs_FLP( + SKP_Silk_encoder_state *psEncC, /* I/O Encoder state */ + SKP_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ + SKP_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ + const SKP_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ +) +{ + SKP_int i, j; + SKP_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; + + SKP_Silk_process_NLSFs( psEncC, PredCoef_Q12, NLSF_Q15, prev_NLSF_Q15); + + for( j = 0; j < 2; j++ ) { + for( i = 0; i < psEncC->predictLPCOrder; i++ ) { + PredCoef[ j ][ i ] = ( SKP_float )PredCoef_Q12[ j ][ i ] * ( 1.0f / 4096.0f ); + } + } +} + +/****************************************/ +/* Floating-point Silk NSQ wrapper */ +/****************************************/ +void SKP_Silk_NSQ_wrapper_FLP( + SKP_Silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + SKP_Silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + SideInfoIndices *psIndices, /* I/O Quantization indices */ + SKP_Silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */ + SKP_int8 pulses[], /* O Quantized pulse signal */ + const SKP_float x[] /* I Prefiltered input signal */ +) +{ + SKP_int i, j; + SKP_int16 x_16[ MAX_FRAME_LENGTH ]; + SKP_int32 Gains_Q16[ MAX_NB_SUBFR ]; + SKP_DWORD_ALIGN SKP_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; + SKP_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; + SKP_int LTP_scale_Q14; + + /* Noise shaping parameters */ + SKP_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; + SKP_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ + SKP_int Lambda_Q10; + SKP_int Tilt_Q14[ MAX_NB_SUBFR ]; + SKP_int HarmShapeGain_Q14[ MAX_NB_SUBFR ]; + + /* Convert control struct to fix control struct */ + /* Noise shape parameters */ + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) { + AR2_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = SKP_float2int( psEncCtrl->AR2[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f ); + } + } + + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + LF_shp_Q14[ i ] = SKP_LSHIFT32( SKP_float2int( psEncCtrl->LF_AR_shp[ i ] * 16384.0f ), 16 ) | + (SKP_uint16)SKP_float2int( psEncCtrl->LF_MA_shp[ i ] * 16384.0f ); + Tilt_Q14[ i ] = (SKP_int)SKP_float2int( psEncCtrl->Tilt[ i ] * 16384.0f ); + HarmShapeGain_Q14[ i ] = (SKP_int)SKP_float2int( psEncCtrl->HarmShapeGain[ i ] * 16384.0f ); + } + Lambda_Q10 = ( SKP_int )SKP_float2int( psEncCtrl->Lambda * 1024.0f ); + + /* prediction and coding parameters */ + for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) { + LTPCoef_Q14[ i ] = ( SKP_int16 )SKP_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f ); + } + + for( j = 0; j < 2; j++ ) { + for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) { + PredCoef_Q12[ j ][ i ] = ( SKP_int16 )SKP_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f ); + } + } + + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + Gains_Q16[ i ] = SKP_float2int( psEncCtrl->Gains[ i ] * 65536.0f ); + SKP_assert( Gains_Q16[ i ] > 0 ); + } + + if( psIndices->signalType == TYPE_VOICED ) { + LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ psIndices->LTP_scaleIndex ]; + } else { + LTP_scale_Q14 = 0; + } + + /* Convert input to fix */ + SKP_float2short_array( x_16, x, psEnc->sCmn.frame_length ); + + /* Call NSQ */ + if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { + SKP_Silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x_16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, + AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 ); + } else { + SKP_Silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x_16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, + AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 ); + } +} + +/***********************************************/ +/* Floating-point Silk LTP quantiation wrapper */ +/***********************************************/ +void SKP_Silk_quant_LTP_gains_FLP( + SKP_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */ + SKP_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */ + SKP_int8 *periodicity_index, /* O Periodicity index */ + const SKP_float W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Error weights */ + const SKP_int mu_Q10, /* I Mu value (R/D tradeoff) */ + const SKP_int lowComplexity, /* I Flag for low complexity */ + const SKP_int nb_subfr /* I number of subframes */ +) +{ + SKP_int i; + SKP_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ]; + SKP_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ]; + + for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { + B_Q14[ i ] = (SKP_int16)SKP_float2int( B[ i ] * 16384.0f ); + } + for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) { + W_Q18[ i ] = (SKP_int32)SKP_float2int( W[ i ] * 262144.0f ); + } + + SKP_Silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, W_Q18, mu_Q10, lowComplexity, nb_subfr ); + + for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { + B[ i ] = (SKP_float)B_Q14[ i ] * ( 1.0f / 16384.0f ); + } +} diff --git a/silk_sources.mk b/silk_sources.mk index 7a8e0942..feb2d631 100644 --- a/silk_sources.mk +++ b/silk_sources.mk @@ -108,40 +108,40 @@ silk/SKP_Silk_sort_FLP.c ifdef FIXED_POINT SILK_SOURCES += \ -silk/SKP_Silk_LTP_analysis_filter_FIX.c \ -silk/SKP_Silk_LTP_scale_ctrl_FIX.c \ -silk/SKP_Silk_corrMatrix_FIX.c \ -silk/SKP_Silk_encode_frame_FIX.c \ -silk/SKP_Silk_find_LPC_FIX.c \ -silk/SKP_Silk_find_LTP_FIX.c \ -silk/SKP_Silk_find_pitch_lags_FIX.c \ -silk/SKP_Silk_find_pred_coefs_FIX.c \ -silk/SKP_Silk_noise_shape_analysis_FIX.c \ -silk/SKP_Silk_prefilter_FIX.c \ -silk/SKP_Silk_process_gains_FIX.c \ -silk/SKP_Silk_regularize_correlations_FIX.c \ -silk/SKP_Silk_residual_energy16_FIX.c \ -silk/SKP_Silk_residual_energy_FIX.c \ -silk/SKP_Silk_solve_LS_FIX.c \ -silk/SKP_Silk_warped_autocorrelation_FIX.c +silk/fixed/SKP_Silk_LTP_analysis_filter_FIX.c \ +silk/fixed/SKP_Silk_LTP_scale_ctrl_FIX.c \ +silk/fixed/SKP_Silk_corrMatrix_FIX.c \ +silk/fixed/SKP_Silk_encode_frame_FIX.c \ +silk/fixed/SKP_Silk_find_LPC_FIX.c \ +silk/fixed/SKP_Silk_find_LTP_FIX.c \ +silk/fixed/SKP_Silk_find_pitch_lags_FIX.c \ +silk/fixed/SKP_Silk_find_pred_coefs_FIX.c \ +silk/fixed/SKP_Silk_noise_shape_analysis_FIX.c \ +silk/fixed/SKP_Silk_prefilter_FIX.c \ +silk/fixed/SKP_Silk_process_gains_FIX.c \ +silk/fixed/SKP_Silk_regularize_correlations_FIX.c \ +silk/fixed/SKP_Silk_residual_energy16_FIX.c \ +silk/fixed/SKP_Silk_residual_energy_FIX.c \ +silk/fixed/SKP_Silk_solve_LS_FIX.c \ +silk/fixed/SKP_Silk_warped_autocorrelation_FIX.c else SILK_SOURCES += \ -silk/SKP_Silk_apply_sine_window_FLP.c \ -silk/SKP_Silk_corrMatrix_FLP.c \ -silk/SKP_Silk_encode_frame_FLP.c \ -silk/SKP_Silk_find_LPC_FLP.c \ -silk/SKP_Silk_find_LTP_FLP.c \ -silk/SKP_Silk_find_pitch_lags_FLP.c \ -silk/SKP_Silk_find_pred_coefs_FLP.c \ -silk/SKP_Silk_LPC_analysis_filter_FLP.c \ -silk/SKP_Silk_LTP_analysis_filter_FLP.c \ -silk/SKP_Silk_LTP_scale_ctrl_FLP.c \ -silk/SKP_Silk_noise_shape_analysis_FLP.c \ -silk/SKP_Silk_prefilter_FLP.c \ -silk/SKP_Silk_process_gains_FLP.c \ -silk/SKP_Silk_regularize_correlations_FLP.c \ -silk/SKP_Silk_residual_energy_FLP.c \ -silk/SKP_Silk_solve_LS_FLP.c \ -silk/SKP_Silk_warped_autocorrelation_FLP.c \ -silk/SKP_Silk_wrappers_FLP.c +silk/float/SKP_Silk_apply_sine_window_FLP.c \ +silk/float/SKP_Silk_corrMatrix_FLP.c \ +silk/float/SKP_Silk_encode_frame_FLP.c \ +silk/float/SKP_Silk_find_LPC_FLP.c \ +silk/float/SKP_Silk_find_LTP_FLP.c \ +silk/float/SKP_Silk_find_pitch_lags_FLP.c \ +silk/float/SKP_Silk_find_pred_coefs_FLP.c \ +silk/float/SKP_Silk_LPC_analysis_filter_FLP.c \ +silk/float/SKP_Silk_LTP_analysis_filter_FLP.c \ +silk/float/SKP_Silk_LTP_scale_ctrl_FLP.c \ +silk/float/SKP_Silk_noise_shape_analysis_FLP.c \ +silk/float/SKP_Silk_prefilter_FLP.c \ +silk/float/SKP_Silk_process_gains_FLP.c \ +silk/float/SKP_Silk_regularize_correlations_FLP.c \ +silk/float/SKP_Silk_residual_energy_FLP.c \ +silk/float/SKP_Silk_solve_LS_FLP.c \ +silk/float/SKP_Silk_warped_autocorrelation_FLP.c \ +silk/float/SKP_Silk_wrappers_FLP.c endif -- cgit v1.2.3