Initial Skype commit taken from FreeSwitch, which got it from the IETF draft.
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Wed, 30 Jun 2010 03:26:14 +0000 (23:26 -0400)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Wed, 30 Jun 2010 03:26:14 +0000 (23:26 -0400)
157 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
Silk_SDK.sln [new file with mode: 0644]
configure.gnu [new file with mode: 0755]
configure.in [new file with mode: 0644]
interface/SKP_Silk_SDK_API.h [new file with mode: 0644]
interface/SKP_Silk_control.h [new file with mode: 0644]
interface/SKP_Silk_errors.h [new file with mode: 0644]
interface/SKP_Silk_typedef.h [new file with mode: 0644]
readme.txt [new file with mode: 0644]
src/SKP_Silk_A2NLSF.c [new file with mode: 0644]
src/SKP_Silk_CNG.c [new file with mode: 0644]
src/SKP_Silk_HP_variable_cutoff_FIX.c [new file with mode: 0644]
src/SKP_Silk_Inlines.h [new file with mode: 0644]
src/SKP_Silk_LBRR_reset.c [new file with mode: 0644]
src/SKP_Silk_LPC_inv_pred_gain.c [new file with mode: 0644]
src/SKP_Silk_LPC_stabilize.c [new file with mode: 0644]
src/SKP_Silk_LPC_synthesis_filter.c [new file with mode: 0644]
src/SKP_Silk_LPC_synthesis_order16.c [new file with mode: 0644]
src/SKP_Silk_LP_variable_cutoff.c [new file with mode: 0644]
src/SKP_Silk_LSF_cos_table.c [new file with mode: 0644]
src/SKP_Silk_LTP_analysis_filter_FIX.c [new file with mode: 0644]
src/SKP_Silk_LTP_scale_ctrl_FIX.c [new file with mode: 0644]
src/SKP_Silk_MA.c [new file with mode: 0644]
src/SKP_Silk_NLSF2A.c [new file with mode: 0644]
src/SKP_Silk_NLSF2A_stable.c [new file with mode: 0644]
src/SKP_Silk_NLSF_MSVQ_decode.c [new file with mode: 0644]
src/SKP_Silk_NLSF_MSVQ_encode_FIX.c [new file with mode: 0644]
src/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c [new file with mode: 0644]
src/SKP_Silk_NLSF_VQ_sum_error_FIX.c [new file with mode: 0644]
src/SKP_Silk_NLSF_VQ_weights_laroia.c [new file with mode: 0644]
src/SKP_Silk_NLSF_stabilize.c [new file with mode: 0644]
src/SKP_Silk_NSQ.c [new file with mode: 0644]
src/SKP_Silk_NSQ_del_dec.c [new file with mode: 0644]
src/SKP_Silk_PLC.c [new file with mode: 0644]
src/SKP_Silk_PLC.h [new file with mode: 0644]
src/SKP_Silk_SigProc_FIX.h [new file with mode: 0644]
src/SKP_Silk_VAD.c [new file with mode: 0644]
src/SKP_Silk_VQ_nearest_neighbor_FIX.c [new file with mode: 0644]
src/SKP_Silk_allpass_int.c [new file with mode: 0644]
src/SKP_Silk_ana_filt_bank_1.c [new file with mode: 0644]
src/SKP_Silk_apply_sine_window.c [new file with mode: 0644]
src/SKP_Silk_array_maxabs.c [new file with mode: 0644]
src/SKP_Silk_autocorr.c [new file with mode: 0644]
src/SKP_Silk_biquad.c [new file with mode: 0644]
src/SKP_Silk_biquad_alt.c [new file with mode: 0644]
src/SKP_Silk_burg_modified.c [new file with mode: 0644]
src/SKP_Silk_bwexpander.c [new file with mode: 0644]
src/SKP_Silk_bwexpander_32.c [new file with mode: 0644]
src/SKP_Silk_code_signs.c [new file with mode: 0644]
src/SKP_Silk_common_pitch_est_defines.h [new file with mode: 0644]
src/SKP_Silk_control_codec_FIX.c [new file with mode: 0644]
src/SKP_Silk_corrMatrix_FIX.c [new file with mode: 0644]
src/SKP_Silk_create_init_destroy.c [new file with mode: 0644]
src/SKP_Silk_dec_API.c [new file with mode: 0644]
src/SKP_Silk_decode_core.c [new file with mode: 0644]
src/SKP_Silk_decode_frame.c [new file with mode: 0644]
src/SKP_Silk_decode_indices_v4.c [new file with mode: 0644]
src/SKP_Silk_decode_parameters.c [new file with mode: 0644]
src/SKP_Silk_decode_parameters_v4.c [new file with mode: 0644]
src/SKP_Silk_decode_pulses.c [new file with mode: 0644]
src/SKP_Silk_decoder_set_fs.c [new file with mode: 0644]
src/SKP_Silk_define.h [new file with mode: 0644]
src/SKP_Silk_define_FIX.h [new file with mode: 0644]
src/SKP_Silk_detect_SWB_input.c [new file with mode: 0644]
src/SKP_Silk_enc_API.c [new file with mode: 0644]
src/SKP_Silk_encode_frame_FIX.c [new file with mode: 0644]
src/SKP_Silk_encode_parameters.c [new file with mode: 0644]
src/SKP_Silk_encode_parameters_v4.c [new file with mode: 0644]
src/SKP_Silk_encode_pulses.c [new file with mode: 0644]
src/SKP_Silk_find_LPC_FIX.c [new file with mode: 0644]
src/SKP_Silk_find_LTP_FIX.c [new file with mode: 0644]
src/SKP_Silk_find_pitch_lags_FIX.c [new file with mode: 0644]
src/SKP_Silk_find_pred_coefs_FIX.c [new file with mode: 0644]
src/SKP_Silk_gain_quant.c [new file with mode: 0644]
src/SKP_Silk_init_encoder_FIX.c [new file with mode: 0644]
src/SKP_Silk_inner_prod_aligned.c [new file with mode: 0644]
src/SKP_Silk_interpolate.c [new file with mode: 0644]
src/SKP_Silk_k2a.c [new file with mode: 0644]
src/SKP_Silk_k2a_Q16.c [new file with mode: 0644]
src/SKP_Silk_lin2log.c [new file with mode: 0644]
src/SKP_Silk_log2lin.c [new file with mode: 0644]
src/SKP_Silk_lowpass_int.c [new file with mode: 0644]
src/SKP_Silk_lowpass_short.c [new file with mode: 0644]
src/SKP_Silk_macros.h [new file with mode: 0644]
src/SKP_Silk_main.h [new file with mode: 0644]
src/SKP_Silk_main_FIX.h [new file with mode: 0644]
src/SKP_Silk_noise_shape_analysis_FIX.c [new file with mode: 0644]
src/SKP_Silk_perceptual_parameters_FIX.h [new file with mode: 0644]
src/SKP_Silk_pitch_analysis_core.c [new file with mode: 0644]
src/SKP_Silk_pitch_est_defines.h [new file with mode: 0644]
src/SKP_Silk_pitch_est_tables.c [new file with mode: 0644]
src/SKP_Silk_prefilter_FIX.c [new file with mode: 0644]
src/SKP_Silk_process_NLSFs_FIX.c [new file with mode: 0644]
src/SKP_Silk_process_gains_FIX.c [new file with mode: 0644]
src/SKP_Silk_pulses_to_bytes.c [new file with mode: 0644]
src/SKP_Silk_quant_LTP_gains_FIX.c [new file with mode: 0644]
src/SKP_Silk_range_coder.c [new file with mode: 0644]
src/SKP_Silk_regularize_correlations_FIX.c [new file with mode: 0644]
src/SKP_Silk_resample_1_2.c [new file with mode: 0644]
src/SKP_Silk_resample_1_2_coarse.c [new file with mode: 0644]
src/SKP_Silk_resample_1_2_coarsest.c [new file with mode: 0644]
src/SKP_Silk_resample_1_3.c [new file with mode: 0644]
src/SKP_Silk_resample_2_1_coarse.c [new file with mode: 0644]
src/SKP_Silk_resample_2_3.c [new file with mode: 0644]
src/SKP_Silk_resample_2_3_coarse.c [new file with mode: 0644]
src/SKP_Silk_resample_2_3_coarsest.c [new file with mode: 0644]
src/SKP_Silk_resample_2_3_rom.c [new file with mode: 0644]
src/SKP_Silk_resample_3_1.c [new file with mode: 0644]
src/SKP_Silk_resample_3_2.c [new file with mode: 0644]
src/SKP_Silk_resample_3_2_rom.c [new file with mode: 0644]
src/SKP_Silk_resample_3_4.c [new file with mode: 0644]
src/SKP_Silk_resample_4_3.c [new file with mode: 0644]
src/SKP_Silk_resample_rom.h [new file with mode: 0644]
src/SKP_Silk_residual_energy16_FIX.c [new file with mode: 0644]
src/SKP_Silk_residual_energy_FIX.c [new file with mode: 0644]
src/SKP_Silk_scale_copy_vector16.c [new file with mode: 0644]
src/SKP_Silk_scale_vector.c [new file with mode: 0644]
src/SKP_Silk_schur.c [new file with mode: 0644]
src/SKP_Silk_schur64.c [new file with mode: 0644]
src/SKP_Silk_shell_coder.c [new file with mode: 0644]
src/SKP_Silk_sigm_Q15.c [new file with mode: 0644]
src/SKP_Silk_solve_LS_FIX.c [new file with mode: 0644]
src/SKP_Silk_sort.c [new file with mode: 0644]
src/SKP_Silk_structs.h [new file with mode: 0644]
src/SKP_Silk_structs_FIX.h [new file with mode: 0644]
src/SKP_Silk_sum_sqr_shift.c [new file with mode: 0644]
src/SKP_Silk_tables.h [new file with mode: 0644]
src/SKP_Silk_tables_LTP.c [new file with mode: 0644]
src/SKP_Silk_tables_NLSF_CB0_10.c [new file with mode: 0644]
src/SKP_Silk_tables_NLSF_CB0_10.h [new file with mode: 0644]
src/SKP_Silk_tables_NLSF_CB0_16.c [new file with mode: 0644]
src/SKP_Silk_tables_NLSF_CB0_16.h [new file with mode: 0644]
src/SKP_Silk_tables_NLSF_CB1_10.c [new file with mode: 0644]
src/SKP_Silk_tables_NLSF_CB1_10.h [new file with mode: 0644]
src/SKP_Silk_tables_NLSF_CB1_16.c [new file with mode: 0644]
src/SKP_Silk_tables_NLSF_CB1_16.h [new file with mode: 0644]
src/SKP_Silk_tables_gain.c [new file with mode: 0644]
src/SKP_Silk_tables_other.c [new file with mode: 0644]
src/SKP_Silk_tables_pitch_lag.c [new file with mode: 0644]
src/SKP_Silk_tables_pulses_per_block.c [new file with mode: 0644]
src/SKP_Silk_tables_sign.c [new file with mode: 0644]
src/SKP_Silk_tables_type_offset.c [new file with mode: 0644]
src/Silk_FIX.2008.vcproj [new file with mode: 0644]
src/Silk_FIX.2010.vcxproj [new file with mode: 0644]
src/Silk_FIX.vcproj [new file with mode: 0644]
test/Dec_SDK.vcproj [new file with mode: 0644]
test/Decoder.c [new file with mode: 0644]
test/Enc_SDK.vcproj [new file with mode: 0644]
test/Encoder.c [new file with mode: 0644]
test/SignalCompare.vcproj [new file with mode: 0644]
test/signalCompare.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..4ec0218
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,26 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..23e5f25
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,236 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).  Here is a another example:
+
+     /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..2a681e8
--- /dev/null
@@ -0,0 +1,172 @@
+
+AM_CFLAGS = -Isrc -Iinterface -fPIC -Wall -O3 
+AUTOMAKE_OPTS = gnu
+NAME = libSKP_SILK_SDK
+AM_CPPFLAGS = $(AM_CFLAGS)
+
+EXTRA_DIST = Silk_SDK.sln \
+src/Silk_FIX.vcproj \
+test/Encoder.c \
+test/Enc_SDK.vcproj \
+test/Decoder.c \
+test/Dec_SDK.vcproj \
+test/signalCompare.c \
+test/SignalCompare.vcproj 
+
+lib_LTLIBRARIES        = libSKP_SILK_SDK.la
+libSKP_SILK_SDK_la_SOURCES = src/SKP_Silk_A2NLSF.c \
+src/SKP_Silk_allpass_int.c \
+src/SKP_Silk_ana_filt_bank_1.c \
+src/SKP_Silk_apply_sine_window.c \
+src/SKP_Silk_array_maxabs.c \
+src/SKP_Silk_autocorr.c \
+src/SKP_Silk_biquad_alt.c \
+src/SKP_Silk_biquad.c \
+src/SKP_Silk_burg_modified.c \
+src/SKP_Silk_bwexpander_32.c \
+src/SKP_Silk_bwexpander.c \
+src/SKP_Silk_CNG.c \
+src/SKP_Silk_code_signs.c \
+src/SKP_Silk_control_codec_FIX.c \
+src/SKP_Silk_corrMatrix_FIX.c \
+src/SKP_Silk_create_init_destroy.c \
+src/SKP_Silk_dec_API.c \
+src/SKP_Silk_decode_core.c \
+src/SKP_Silk_decode_frame.c \
+src/SKP_Silk_decode_indices_v4.c \
+src/SKP_Silk_decode_parameters.c \
+src/SKP_Silk_decode_parameters_v4.c \
+src/SKP_Silk_decode_pulses.c \
+src/SKP_Silk_decoder_set_fs.c \
+src/SKP_Silk_detect_SWB_input.c \
+src/SKP_Silk_enc_API.c \
+src/SKP_Silk_encode_frame_FIX.c \
+src/SKP_Silk_encode_parameters.c \
+src/SKP_Silk_encode_parameters_v4.c \
+src/SKP_Silk_encode_pulses.c \
+src/SKP_Silk_find_LPC_FIX.c \
+src/SKP_Silk_find_LTP_FIX.c \
+src/SKP_Silk_find_pitch_lags_FIX.c \
+src/SKP_Silk_find_pred_coefs_FIX.c \
+src/SKP_Silk_gain_quant.c \
+src/SKP_Silk_HP_variable_cutoff_FIX.c \
+src/SKP_Silk_init_encoder_FIX.c \
+src/SKP_Silk_inner_prod_aligned.c \
+src/SKP_Silk_interpolate.c \
+src/SKP_Silk_k2a.c \
+src/SKP_Silk_k2a_Q16.c \
+src/SKP_Silk_LBRR_reset.c \
+src/SKP_Silk_lin2log.c \
+src/SKP_Silk_log2lin.c \
+src/SKP_Silk_lowpass_int.c \
+src/SKP_Silk_lowpass_short.c \
+src/SKP_Silk_LPC_inv_pred_gain.c \
+src/SKP_Silk_LPC_stabilize.c \
+src/SKP_Silk_LPC_synthesis_filter.c \
+src/SKP_Silk_LPC_synthesis_order16.c \
+src/SKP_Silk_LP_variable_cutoff.c \
+src/SKP_Silk_LSF_cos_table.c \
+src/SKP_Silk_LTP_analysis_filter_FIX.c \
+src/SKP_Silk_LTP_scale_ctrl_FIX.c \
+src/SKP_Silk_MA.c \
+src/SKP_Silk_NLSF2A.c \
+src/SKP_Silk_NLSF2A_stable.c \
+src/SKP_Silk_NLSF_MSVQ_decode.c \
+src/SKP_Silk_NLSF_MSVQ_encode_FIX.c \
+src/SKP_Silk_NLSF_stabilize.c \
+src/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c \
+src/SKP_Silk_NLSF_VQ_sum_error_FIX.c \
+src/SKP_Silk_NLSF_VQ_weights_laroia.c \
+src/SKP_Silk_noise_shape_analysis_FIX.c \
+src/SKP_Silk_NSQ.c \
+src/SKP_Silk_NSQ_del_dec.c \
+src/SKP_Silk_pitch_analysis_core.c \
+src/SKP_Silk_pitch_est_tables.c \
+src/SKP_Silk_PLC.c \
+src/SKP_Silk_prefilter_FIX.c \
+src/SKP_Silk_process_gains_FIX.c \
+src/SKP_Silk_process_NLSFs_FIX.c \
+src/SKP_Silk_pulses_to_bytes.c \
+src/SKP_Silk_quant_LTP_gains_FIX.c \
+src/SKP_Silk_range_coder.c \
+src/SKP_Silk_regularize_correlations_FIX.c \
+src/SKP_Silk_resample_1_2.c \
+src/SKP_Silk_resample_1_2_coarse.c \
+src/SKP_Silk_resample_1_2_coarsest.c \
+src/SKP_Silk_resample_1_3.c \
+src/SKP_Silk_resample_2_1_coarse.c \
+src/SKP_Silk_resample_2_3.c \
+src/SKP_Silk_resample_2_3_coarse.c \
+src/SKP_Silk_resample_2_3_coarsest.c \
+src/SKP_Silk_resample_2_3_rom.c \
+src/SKP_Silk_resample_3_1.c \
+src/SKP_Silk_resample_3_2.c \
+src/SKP_Silk_resample_3_2_rom.c \
+src/SKP_Silk_resample_3_4.c \
+src/SKP_Silk_resample_4_3.c \
+src/SKP_Silk_residual_energy16_FIX.c \
+src/SKP_Silk_residual_energy_FIX.c \
+src/SKP_Silk_scale_copy_vector16.c \
+src/SKP_Silk_scale_vector.c \
+src/SKP_Silk_schur64.c \
+src/SKP_Silk_schur.c \
+src/SKP_Silk_shell_coder.c \
+src/SKP_Silk_sigm_Q15.c \
+src/SKP_Silk_solve_LS_FIX.c \
+src/SKP_Silk_sort.c \
+src/SKP_Silk_sum_sqr_shift.c \
+src/SKP_Silk_tables_gain.c \
+src/SKP_Silk_tables_LTP.c \
+src/SKP_Silk_tables_NLSF_CB0_10.c \
+src/SKP_Silk_tables_NLSF_CB0_16.c \
+src/SKP_Silk_tables_NLSF_CB1_10.c \
+src/SKP_Silk_tables_NLSF_CB1_16.c \
+src/SKP_Silk_tables_other.c \
+src/SKP_Silk_tables_pitch_lag.c \
+src/SKP_Silk_tables_pulses_per_block.c \
+src/SKP_Silk_tables_sign.c \
+src/SKP_Silk_tables_type_offset.c \
+src/SKP_Silk_VAD.c \
+src/SKP_Silk_VQ_nearest_neighbor_FIX.c 
+
+
+libSKP_SILK_SDK_la_CFLAGS = $(AM_CFLAGS)
+libSKP_SILK_SDK_la_LDFLAGS = $(LIBS)
+
+library_includedir = $(prefix)/include/silk
+library_include_HEADERS        = src/SKP_Silk_common_pitch_est_defines.h \
+src/SKP_Silk_define_FIX.h \
+src/SKP_Silk_define.h \
+src/SKP_Silk_Inlines.h \
+src/SKP_Silk_macros.h \
+src/SKP_Silk_main_FIX.h \
+src/SKP_Silk_main.h \
+src/SKP_Silk_perceptual_parameters_FIX.h \
+src/SKP_Silk_pitch_est_defines.h \
+src/SKP_Silk_PLC.h \
+src/SKP_Silk_resample_rom.h \
+src/SKP_Silk_SigProc_FIX.h \
+src/SKP_Silk_structs_FIX.h \
+src/SKP_Silk_structs.h \
+src/SKP_Silk_tables.h \
+src/SKP_Silk_tables_NLSF_CB0_10.h \
+src/SKP_Silk_tables_NLSF_CB0_16.h \
+src/SKP_Silk_tables_NLSF_CB1_10.h \
+src/SKP_Silk_tables_NLSF_CB1_16.h \
+interface/SKP_Silk_control.h \
+interface/SKP_Silk_errors.h \
+interface/SKP_Silk_SDK_API.h \
+interface/SKP_Silk_typedef.h 
+
+bin_PROGRAMS = Encoder Decoder signalCompare
+Encoder_SOURCES = test/Encoder.c $(top_builddir)/interface/SKP_Silk_SDK_API.h
+Encoder_LDADD = $(lib_LTLIBRARIES) 
+Encoder_LDFLAGS = $(LIBS)
+
+Decoder_SOURCES = test/Decoder.c $(top_builddir)/interface/SKP_Silk_SDK_API.h
+Decoder_LDADD = $(lib_LTLIBRARIES) 
+Decoder_LDFLAGS = $(LIBS)
+
+signalCompare_SOURCES = test/signalCompare.c $(top_builddir)/interface/SKP_Silk_SDK_API.h
+signalCompare_LDADD = $(lib_LTLIBRARIES) 
+signalCompare_LDFLAGS = $(LIBS)
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Silk_SDK.sln b/Silk_SDK.sln
new file mode 100644 (file)
index 0000000..ab0dd8d
--- /dev/null
@@ -0,0 +1,44 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 9.00\r
+# Visual Studio 2005\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Silk_FIX", "src\Silk_FIX.vcproj", "{56B91D01-9150-4BBF-AFA1-5B68AB991B76}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dec_SDK", "test\Dec_SDK.vcproj", "{82685D7F-0589-42BD-877C-31A952D53A8E}"\r
+       ProjectSection(ProjectDependencies) = postProject\r
+               {56B91D01-9150-4BBF-AFA1-5B68AB991B76} = {56B91D01-9150-4BBF-AFA1-5B68AB991B76}\r
+       EndProjectSection\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SignalCompare", "test\SignalCompare.vcproj", "{7FE8F544-9175-40C3-A187-7F15CE9A75D8}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Enc_SDK", "test\Enc_SDK.vcproj", "{6D97A8EF-5724-4D85-8BF4-C583714BBA78}"\r
+       ProjectSection(ProjectDependencies) = postProject\r
+               {56B91D01-9150-4BBF-AFA1-5B68AB991B76} = {56B91D01-9150-4BBF-AFA1-5B68AB991B76}\r
+       EndProjectSection\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Win32 = Debug|Win32\r
+               Release|Win32 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Debug|Win32.Build.0 = Debug|Win32\r
+               {56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Release|Win32.ActiveCfg = Release|Win32\r
+               {56B91D01-9150-4BBF-AFA1-5B68AB991B76}.Release|Win32.Build.0 = Release|Win32\r
+               {82685D7F-0589-42BD-877C-31A952D53A8E}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {82685D7F-0589-42BD-877C-31A952D53A8E}.Debug|Win32.Build.0 = Debug|Win32\r
+               {82685D7F-0589-42BD-877C-31A952D53A8E}.Release|Win32.ActiveCfg = Release|Win32\r
+               {82685D7F-0589-42BD-877C-31A952D53A8E}.Release|Win32.Build.0 = Release|Win32\r
+               {7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Debug|Win32.Build.0 = Debug|Win32\r
+               {7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Release|Win32.ActiveCfg = Release|Win32\r
+               {7FE8F544-9175-40C3-A187-7F15CE9A75D8}.Release|Win32.Build.0 = Release|Win32\r
+               {6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Debug|Win32.Build.0 = Debug|Win32\r
+               {6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Release|Win32.ActiveCfg = Release|Win32\r
+               {6D97A8EF-5724-4D85-8BF4-C583714BBA78}.Release|Win32.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/configure.gnu b/configure.gnu
new file mode 100755 (executable)
index 0000000..c78238d
--- /dev/null
@@ -0,0 +1,4 @@
+#! /bin/sh
+srcpath=$(dirname $0 2>/dev/null )  || srcpath="." 
+$srcpath/configure "$@" --disable-shared --with-pic
+
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..bd71b65
--- /dev/null
@@ -0,0 +1,26 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.59])
+AC_INIT(libSKP_SILK_SDK, 1.0.2, brian@freeswitch.org, libSKP_SILK_SDK)
+AM_INIT_AUTOMAKE(libSKP_SILK_SDK,1.0.2)
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_LIBTOOL
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([float.h stdint.h stdlib.h string.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_CHECK_LIB([m],[pow])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/interface/SKP_Silk_SDK_API.h b/interface/SKP_Silk_SDK_API.h
new file mode 100644 (file)
index 0000000..cb31db2
--- /dev/null
@@ -0,0 +1,154 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#ifndef SKP_SILK_SDK_API_H\r
+#define SKP_SILK_SDK_API_H\r
+\r
+#include "SKP_Silk_control.h"\r
+#include "SKP_Silk_typedef.h"\r
+#include "SKP_Silk_errors.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+#define SILK_MAX_FRAMES_PER_PACKET  5\r
+\r
+/* Struct for TOC (Table Of Contents) */\r
+typedef struct {\r
+    SKP_int     framesInPacket;                             /* Number of 20 ms frames in packet     */\r
+    SKP_int     fs_kHz;                                     /* Sampling frequency in packet         */\r
+    SKP_int     inbandLBRR;                                 /* Does packet contain LBRR information */\r
+    SKP_int     corrupt;                                    /* Packet is corrupt                    */\r
+    SKP_int     vadFlags[     SILK_MAX_FRAMES_PER_PACKET ]; /* VAD flag for each frame in packet    */\r
+    SKP_int     sigtypeFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* Signal type for each frame in packet */\r
+} SKP_Silk_TOC_struct;\r
+\r
+/****************************************/\r
+/* Encoder functions                    */\r
+/****************************************/\r
+\r
+/***********************************************/\r
+/* Get size in bytes of the Silk encoder state */\r
+/***********************************************/\r
+SKP_int SKP_Silk_SDK_Get_Encoder_Size( \r
+    SKP_int32                           *encSizeBytes   /* O:   Number of bytes in SILK encoder state           */\r
+);\r
+\r
+/*************************/\r
+/* Init or reset encoder */\r
+/*************************/\r
+SKP_int SKP_Silk_SDK_InitEncoder(\r
+    void                                *encState,      /* I/O: State                                           */\r
+    SKP_SILK_SDK_EncControlStruct       *encStatus      /* O:   Encoder Status                                  */\r
+);\r
+\r
+/***************************************/\r
+/* Read control structure from encoder */\r
+/***************************************/\r
+SKP_int SKP_Silk_SDK_QueryEncoder(\r
+    const void                          *encState,      /* I:   State                                           */\r
+    SKP_SILK_SDK_EncControlStruct       *encStatus      /* O:   Encoder Status                                  */\r
+);\r
+\r
+/**************************/\r
+/* Encode frame with Silk */\r
+/**************************/\r
+SKP_int SKP_Silk_SDK_Encode( \r
+    void                                *encState,      /* I/O: State                                           */\r
+    const SKP_SILK_SDK_EncControlStruct *encControl,    /* I:   Control status                                  */\r
+    const SKP_int16                     *samplesIn,     /* I:   Speech sample input vector                      */\r
+    SKP_int                             nSamplesIn,     /* I:   Number of samples in input vector               */\r
+    SKP_uint8                           *outData,       /* O:   Encoded output vector                           */\r
+    SKP_int16                           *nBytesOut      /* I/O: Number of Bytes in outData (input: Max Bytes)   */\r
+);\r
+\r
+/****************************************/\r
+/* Decoder functions                    */\r
+/****************************************/\r
+\r
+/***********************************************/\r
+/* Get size in bytes of the Silk decoder state */\r
+/***********************************************/\r
+SKP_int SKP_Silk_SDK_Get_Decoder_Size( \r
+    SKP_int32                           *decSizeBytes   /* O:   Number of bytes in SILK decoder state           */\r
+);\r
+\r
+/*************************/\r
+/* Init or Reset decoder */\r
+/*************************/\r
+SKP_int SKP_Silk_SDK_InitDecoder( \r
+    void                                *decState       /* I/O: State                                           */\r
+);\r
+\r
+/******************/\r
+/* Decode a frame */\r
+/******************/\r
+SKP_int SKP_Silk_SDK_Decode(\r
+    void*                               decState,       /* I/O: State                                           */\r
+    SKP_SILK_SDK_DecControlStruct*      decControl,     /* I/O: Control Structure                               */\r
+    SKP_int                             lostFlag,       /* I:   0: no loss, 1 loss                              */\r
+    const SKP_uint8                     *inData,        /* I:   Encoded input vector                            */\r
+    const SKP_int                       nBytesIn,       /* I:   Number of input Bytes                           */\r
+    SKP_int16                           *samplesOut,    /* O:   Decoded output speech vector                    */\r
+    SKP_int16                           *nSamplesOut    /* I/O: Number of samples (vector/decoded)              */\r
+);\r
+\r
+/***************************************************************/\r
+/* Find Low Bit Rate Redundancy (LBRR) information in a packet */\r
+/***************************************************************/\r
+void SKP_Silk_SDK_search_for_LBRR(\r
+    void                                *decState,      /* I:   Decoder state, to select bitstream version only */\r
+    const SKP_uint8                     *inData,        /* I:   Encoded input vector                            */\r
+    const SKP_int16                     nBytesIn,       /* I:   Number of input Bytes                           */\r
+    SKP_int                             lost_offset,    /* I:   Offset from lost packet                         */\r
+    SKP_uint8                           *LBRRData,      /* O:   LBRR payload                                    */\r
+    SKP_int16                           *nLBRRBytes     /* O:   Number of LBRR Bytes                            */\r
+);\r
+\r
+/************************************/\r
+/* Get type of content for a packet */\r
+/************************************/\r
+void SKP_Silk_SDK_get_TOC(\r
+    void                                       *decState,      /* I:   Decoder state, to select bitstream version only */\r
+    const SKP_uint8                     *inData,        /* I:   Encoded input vector                            */\r
+    const SKP_int16                     nBytesIn,       /* I:   Number of input bytes                           */\r
+    SKP_Silk_TOC_struct                 *Silk_TOC       /* O:   Type of content                                 */\r
+);\r
+\r
+/**************************/\r
+/* Get the version number */\r
+/**************************/\r
+/* Return a pointer to string specifying the version */ \r
+const char *SKP_Silk_SDK_get_version();\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/interface/SKP_Silk_control.h b/interface/SKP_Silk_control.h
new file mode 100644 (file)
index 0000000..2bd056f
--- /dev/null
@@ -0,0 +1,88 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#ifndef SKP_SILK_CONTROL_H\r
+#define SKP_SILK_CONTROL_H\r
+\r
+#include "SKP_Silk_typedef.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+/***********************************************/\r
+/* Structure for controlling encoder operation */\r
+/***********************************************/\r
+typedef struct {\r
+    /* I:   Sampling rate in Hertz; 8000/12000/16000/24000                                  */\r
+    SKP_int32 sampleRate;\r
+\r
+    /* I:   Number of samples per packet; must be equivalent of 20, 40, 60, 80 or 100 ms    */\r
+    SKP_int packetSize;\r
+\r
+    /* I:   Bitrate during active speech in bits/second; internally limited                 */\r
+    SKP_int32 bitRate;                        \r
+\r
+    /* I:   Uplink Packet loss in pct (0...100)                                             */\r
+    SKP_int packetLossPercentage;\r
+    \r
+    /* I:   Complexity mode; 0 is lowest; 1 is medium and 2 is highest complexity           */\r
+    SKP_int complexity;\r
+\r
+    /* I:   Flag to enable in-band Forward Error Correction (FEC); 0/1                      */\r
+    SKP_int useInBandFEC;\r
+\r
+    /* I:   Flag to enable Discontinous Transmission; 0/1                                   */\r
+    SKP_int useDTX;\r
+} SKP_SILK_SDK_EncControlStruct;\r
+\r
+/**************************************************************************/\r
+/* Structure for controlling decoder operation and reading decoder status */\r
+/**************************************************************************/\r
+typedef struct {\r
+    /* I:   Sampling rate in Hertz; 8000/12000/16000/24000                                  */\r
+    SKP_int32 sampleRate;\r
+\r
+    /* O:   Number of samples per frame                                                     */\r
+    SKP_int frameSize;\r
+\r
+    /* O:   Frames per packet 1, 2, 3, 4, 5                                                 */\r
+    SKP_int framesPerPacket;\r
+\r
+    /* O:   Flag to indicate that the decoder has remaining payloads internally             */\r
+    SKP_int moreInternalDecoderFrames;\r
+\r
+    /* O:   Distance between main payload and redundant payload in packets                  */\r
+    SKP_int inBandFECOffset;\r
+} SKP_SILK_SDK_DecControlStruct;\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/interface/SKP_Silk_errors.h b/interface/SKP_Silk_errors.h
new file mode 100644 (file)
index 0000000..99b837c
--- /dev/null
@@ -0,0 +1,93 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#ifndef SKP_SILK_ERRORS_H\r
+#define SKP_SILK_ERRORS_H\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+/******************/\r
+/* Error messages */\r
+/******************/\r
+#define SKP_SILK_NO_ERROR                                 0\r
+\r
+/**************************/\r
+/* Encoder error messages */\r
+/**************************/\r
+\r
+/* Input length is not a multiplum of 10 ms, \r
+   or length is longer than the packet length */\r
+#define SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES         -1\r
+\r
+/* Sampling frequency not 8000, 12000, 16000 \r
+   or 24000 Hertz */\r
+#define SKP_SILK_ENC_FS_NOT_SUPPORTED                    -2\r
+\r
+/* Packet size not 20, 40, 60, 80 or 100 ms */\r
+#define SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED           -3\r
+\r
+/* Allocated payload buffer too short */\r
+#define SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT               -4\r
+\r
+/* Loss rate not between 0 and 100 percent */\r
+#define SKP_SILK_ENC_WRONG_LOSS_RATE                     -5\r
+\r
+/* Complexity setting not valid, use 0, 1 or 2 */\r
+#define SKP_SILK_ENC_WRONG_COMPLEXITY_SETTING            -6\r
+\r
+/* Inband FEC setting not valid, use 0 or 1 */\r
+#define SKP_SILK_ENC_WRONG_INBAND_FEC_SETTING            -7\r
+\r
+/* DTX setting not valid, use 0 or 1 */\r
+#define SKP_SILK_ENC_WRONG_DTX_SETTING                   -8\r
+\r
+/* Internal encoder error */\r
+#define SKP_SILK_ENC_INTERNAL_ERROR                      -9\r
+\r
+/**************************/\r
+/* Decoder error messages */\r
+/**************************/\r
+\r
+/* Output sampling frequency lower than internal \r
+   decoded sampling frequency */\r
+#define SKP_SILK_DEC_WRONG_SAMPLING_FREQUENCY           -10\r
+\r
+/* Payload size exceeded the maximum allowed 1024 bytes */\r
+#define SKP_SILK_DEC_PAYLOAD_TOO_LARGE                  -11\r
+\r
+/* Payload has bit errors */\r
+#define SKP_SILK_DEC_PAYLOAD_ERROR                      -12\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/interface/SKP_Silk_typedef.h b/interface/SKP_Silk_typedef.h
new file mode 100644 (file)
index 0000000..7cb661a
--- /dev/null
@@ -0,0 +1,99 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#ifndef _SKP_SILK_API_TYPDEF_H_\r
+#define _SKP_SILK_API_TYPDEF_H_\r
+\r
+#ifndef SKP_USE_DOUBLE_PRECISION_FLOATS\r
+#define SKP_USE_DOUBLE_PRECISION_FLOATS     0\r
+#endif\r
+\r
+#include <float.h>\r
+#if defined( __GNUC__ )\r
+#include <stdint.h>\r
+#endif\r
+\r
+#define SKP_int         int                     /* used for counters etc; at least 16 bits */\r
+#define SKP_int64       long long\r
+#define SKP_int32       int\r
+#define SKP_int16       short\r
+#define SKP_int8        signed char\r
+\r
+#define SKP_uint        unsigned int            /* used for counters etc; at least 16 bits */\r
+#define SKP_uint64      unsigned long long\r
+#define SKP_uint32      unsigned int\r
+#define SKP_uint16      unsigned short\r
+#define SKP_uint8       unsigned char\r
+\r
+#define SKP_int_ptr_size intptr_t\r
+\r
+#if SKP_USE_DOUBLE_PRECISION_FLOATS\r
+# define SKP_float      double\r
+# define SKP_float_MAX  DBL_MAX\r
+#else\r
+# define SKP_float      float\r
+# define SKP_float_MAX  FLT_MAX\r
+#endif\r
+\r
+#define SKP_INLINE      static __inline\r
+\r
+#ifdef _WIN32\r
+# define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) _stricmp(x, y)\r
+#else\r
+# define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) strcasecmp(x, y)\r
+#endif \r
+\r
+#define SKP_int64_MAX   ((SKP_int64)0x7FFFFFFFFFFFFFFFLL)   //  2^63 - 1  \r
+#define SKP_int64_MIN   ((SKP_int64)0x8000000000000000LL)   // -2^63     \r
+#define SKP_int32_MAX   0x7FFFFFFF                          //  2^31 - 1 =  2147483647\r
+#define SKP_int32_MIN   ((SKP_int32)0x80000000)             // -2^31     = -2147483648\r
+#define SKP_int16_MAX   0x7FFF                              //  2^15 - 1 =  32767\r
+#define SKP_int16_MIN   ((SKP_int16)0x8000)                 // -2^15     = -32768\r
+#define SKP_int8_MAX    0x7F                                //  2^7 - 1  =  127\r
+#define SKP_int8_MIN    ((SKP_int8)0x80)                    // -2^7      = -128\r
+\r
+#define SKP_uint32_MAX  0xFFFFFFFF  // 2^32 - 1 = 4294967295\r
+#define SKP_uint32_MIN  0x00000000\r
+#define SKP_uint16_MAX  0xFFFF      // 2^16 - 1 = 65535\r
+#define SKP_uint16_MIN  0x0000\r
+#define SKP_uint8_MAX   0xFF        //  2^8 - 1 = 255\r
+#define SKP_uint8_MIN   0x00\r
+\r
+#define SKP_TRUE        1\r
+#define SKP_FALSE       0\r
+\r
+/* assertions */\r
+#if (defined _WIN32 && !defined _WINCE && !defined(__GNUC__) && !defined(NO_ASSERTS))\r
+# ifndef SKP_assert\r
+#  include <crtdbg.h>      /* ASSERTE() */\r
+#  define SKP_assert(COND)   _ASSERTE(COND)\r
+# endif\r
+#else\r
+# define SKP_assert(COND)\r
+#endif\r
+\r
+#endif\r
diff --git a/readme.txt b/readme.txt
new file mode 100644 (file)
index 0000000..11cf531
--- /dev/null
@@ -0,0 +1,80 @@
+************************************************************************\r
+Fixed Point SILK SDK 1.0.2 beta source code package\r
+Copyright 2010 (c), Skype Limited\r
+https://developer.skype.com/silk/\r
+************************************************************************\r
+\r
+Date: 09/03/2010 (Format: DD/MM/YYYY)\r
+\r
+I. Description\r
+\r
+This package contains files for compiling and testing the fixed\r
+point SILK SDK library. The following is included in this package:\r
+\r
+    o Source code for the fixed point SILK SDK library\r
+    o Source code for creating encoder and decoder executables\r
+    o Test vectors\r
+    o Comparison tool\r
+    o Microsoft Visual Studio solution and project files\r
+    o Makefile for GNU C-compiler (GCC)\r
+    \r
+II. Files and Folders\r
+\r
+    o doc/          - contains more information about the SILK SDK\r
+    o interface/    - contains API header files\r
+    o src/          - contains all SILK SDK library source files\r
+    o test/         - contains source files for testing the SILK SDK\r
+    o test_vectors/ - contains test vectors   \r
+    o Makefile      - Makefile for compiling with GCC\r
+    o readme.txt    - this file\r
+    o Silk_SDK.sln  - Visual Studio solution for all SILK SDK code\r
+\r
+III. How to use the Makefile\r
+\r
+    1. How to clean and compile the SILK SDK library:\r
+         \r
+       make clean lib\r
\r
+    2. How to compile an encoder executable:\r
+\r
+       make encoder\r
+\r
+    3. How to compile a decoder executable:\r
+\r
+       make decoder\r
+\r
+    4. How to compile the comparison tool:\r
+\r
+       make signalcompare\r
+\r
+    5. How to clean and compile all of the above:\r
+\r
+       make clean all\r
+\r
+    6. How to use the comparison tool:\r
+       \r
+       See 'How to use the test vectors.txt' in the test_vectors folder.       \r
+\r
+IV. History\r
+\r
+    Version 1.0.2 - Updated with various bugfixes and improvements\r
+    Version 1.0.1 - First beta source code release\r
+    \r
+V. Compatibility\r
+\r
+    This package has been tested under the following platforms:\r
+\r
+    Windows XP Home and Professional\r
+    Windows Vista, 32-bit version\r
+    Mac OS X Version 10.5.8\r
+    Ubuntu Linux 9.10, 64-bit version \r
+\r
+VI. Known Issues\r
+\r
+    None\r
+\r
+VII. Additional Resources\r
+\r
+    For more information, visit the SILK SDK web site at:\r
+\r
+    <https://developer.skype.com/silk/>\r
diff --git a/src/SKP_Silk_A2NLSF.c b/src/SKP_Silk_A2NLSF.c
new file mode 100644 (file)
index 0000000..f8e56ca
--- /dev/null
@@ -0,0 +1,280 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+/* Conversion between prediction filter coefficients and NLSFs  */\r
+/* Requires the order to be an even number                      */\r
+/* A piecewise linear approximation maps LSF <-> cos(LSF)       */\r
+/* Therefore the result is not accurate NLSFs, but the two      */\r
+/* function are accurate inverses of each other                 */\r
+\r
+#include "SKP_Silk_SigProc_FIX.h"\r
+\r
+/* Number of binary divisions, when not in low complexity mode */\r
+#define BIN_DIV_STEPS_A2NLSF_FIX      2 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */\r
+#define QPoly                        16\r
+#define MAX_ITERATIONS_A2NLSF_FIX    50\r
+\r
+/* Flag for using 2x as many cosine sampling points, reduces the risk of missing a root */\r
+#define OVERSAMPLE_COSINE_TABLE       0\r
+\r
+/* Helper function for A2NLSF(..)                    */\r
+/* Transforms polynomials from cos(n*f) to cos(f)^n  */\r
+SKP_INLINE void SKP_Silk_A2NLSF_trans_poly(\r
+    SKP_int32        *p,    /* I/O    Polynomial                                */\r
+    const SKP_int    dd     /* I      Polynomial order (= filter order / 2 )    */\r
+)\r
+{\r
+    SKP_int k, n;\r
+    \r
+    for( k = 2; k <= dd; k++ ) {\r
+        for( n = dd; n > k; n-- ) {\r
+            p[ n - 2 ] -= p[ n ];\r
+        }\r
+        p[ k - 2 ] -= SKP_LSHIFT( p[ k ], 1 );\r
+    }\r
+}    \r
+\r
+/* Helper function for A2NLSF(..)                    */\r
+/* Polynomial evaluation                             */\r
+SKP_INLINE SKP_int32 SKP_Silk_A2NLSF_eval_poly(    /* return the polynomial evaluation, in QPoly */\r
+    SKP_int32        *p,    /* I    Polynomial, QPoly        */\r
+    const SKP_int32    x,   /* I    Evaluation point, Q12    */\r
+    const SKP_int    dd     /* I    Order                    */\r
+)\r
+{\r
+    SKP_int   n;\r
+    SKP_int32 x_Q16, y32;\r
+\r
+    y32 = p[ dd ];                                    /* QPoly */\r
+    x_Q16 = SKP_LSHIFT( x, 4 );\r
+    for( n = dd - 1; n >= 0; n-- ) {\r
+        y32 = SKP_SMLAWW( p[ n ], y32, x_Q16 );       /* QPoly */\r
+    }\r
+    return y32;\r
+}\r
+\r
+SKP_INLINE void SKP_Silk_A2NLSF_init(\r
+     const SKP_int32    *a_Q16,\r
+     SKP_int32            *P, \r
+     SKP_int32            *Q, \r
+     const SKP_int        dd\r
+) \r
+{\r
+    SKP_int k;\r
+\r
+    /* Convert filter coefs to even and odd polynomials */\r
+    P[dd] = SKP_LSHIFT( 1, QPoly );\r
+    Q[dd] = SKP_LSHIFT( 1, QPoly );\r
+    for( k = 0; k < dd; k++ ) {\r
+#if( QPoly < 16 )\r
+        P[ k ] = SKP_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */\r
+        Q[ k ] = SKP_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */\r
+#elif( Qpoly == 16 )\r
+        P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; // QPoly\r
+        Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; // QPoly\r
+#else\r
+        P[ k ] = SKP_LSHIFT( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */\r
+        Q[ k ] = SKP_LSHIFT( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */\r
+#endif\r
+    }\r
+\r
+    /* Divide out zeros as we have that for even filter orders, */\r
+    /* z =  1 is always a root in Q, and                        */\r
+    /* z = -1 is always a root in P                             */\r
+    for( k = dd; k > 0; k-- ) {\r
+        P[ k - 1 ] -= P[ k ]; \r
+        Q[ k - 1 ] += Q[ k ]; \r
+    }\r
+\r
+    /* Transform polynomials from cos(n*f) to cos(f)^n */\r
+    SKP_Silk_A2NLSF_trans_poly( P, dd );\r
+    SKP_Silk_A2NLSF_trans_poly( Q, dd );\r
+}\r
+\r
+/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients        */\r
+/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence.    */\r
+void SKP_Silk_A2NLSF(\r
+    SKP_int          *NLSF,                 /* O    Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d]    */\r
+    SKP_int32        *a_Q16,                /* I/O  Monic whitening filter coefficients in Q16 [d]                   */\r
+    const SKP_int    d                      /* I    Filter order (must be even)                                      */\r
+)\r
+{\r
+    SKP_int      i, k, m, dd, root_ix, ffrac;\r
+    SKP_int32 xlo, xhi, xmid;\r
+    SKP_int32 ylo, yhi, ymid;\r
+    SKP_int32 nom, den;\r
+    SKP_int32 P[ SigProc_MAX_ORDER_LPC / 2 + 1 ];\r
+    SKP_int32 Q[ SigProc_MAX_ORDER_LPC / 2 + 1 ];\r
+    SKP_int32 *PQ[ 2 ];\r
+    SKP_int32 *p;\r
+\r
+    /* Store pointers to array */\r
+    PQ[ 0 ] = P;\r
+    PQ[ 1 ] = Q;\r
+\r
+    dd = SKP_RSHIFT( d, 1 );\r
+\r
+    SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd );\r
+\r
+    /* Find roots, alternating between P and Q */\r
+    p = P;    /* Pointer to polynomial */\r
+    \r
+    xlo = SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12\r
+    ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );\r
+\r
+    if( ylo < 0 ) {\r
+        /* Set the first NLSF to zero and move on to the next */\r
+        NLSF[ 0 ] = 0;\r
+        p = Q;                      /* Pointer to polynomial */\r
+        ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );\r
+        root_ix = 1;                /* Index of current root */\r
+    } else {\r
+        root_ix = 0;                /* Index of current root */\r
+    }\r
+    k = 1;                          /* Loop counter */\r
+    i = 0;                          /* Counter for bandwidth expansions applied */\r
+    while( 1 ) {\r
+        /* Evaluate polynomial */\r
+#if OVERSAMPLE_COSINE_TABLE\r
+        xhi = SKP_Silk_LSFCosTab_FIX_Q12[   k       >> 1 ] +\r
+          ( ( SKP_Silk_LSFCosTab_FIX_Q12[ ( k + 1 ) >> 1 ] - \r
+              SKP_Silk_LSFCosTab_FIX_Q12[   k       >> 1 ] ) >> 1 );    /* Q12 */\r
+#else\r
+        xhi = SKP_Silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */\r
+#endif\r
+        yhi = SKP_Silk_A2NLSF_eval_poly( p, xhi, dd );\r
+        \r
+        /* Detect zero crossing */\r
+        if( ( ylo <= 0 && yhi >= 0 ) || ( ylo >= 0 && yhi <= 0 ) ) {\r
+            /* Binary division */\r
+#if OVERSAMPLE_COSINE_TABLE\r
+            ffrac = -128;\r
+#else\r
+            ffrac = -256;\r
+#endif\r
+            for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) {\r
+                /* Evaluate polynomial */\r
+                xmid = SKP_RSHIFT_ROUND( xlo + xhi, 1 );\r
+                ymid = SKP_Silk_A2NLSF_eval_poly( p, xmid, dd );\r
+\r
+                /* Detect zero crossing */\r
+                if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) {\r
+                    /* Reduce frequency */\r
+                    xhi = xmid;\r
+                    yhi = ymid;\r
+                } else {\r
+                    /* Increase frequency */\r
+                    xlo = xmid;\r
+                    ylo = ymid;\r
+#if OVERSAMPLE_COSINE_TABLE\r
+                    ffrac = SKP_ADD_RSHIFT( ffrac,  64, m );\r
+#else\r
+                    ffrac = SKP_ADD_RSHIFT( ffrac, 128, m );\r
+#endif\r
+                }\r
+            }\r
+            \r
+            /* Interpolate */\r
+            if( SKP_abs( ylo ) < 65536 ) {\r
+                /* Avoid dividing by zero */\r
+                den = ylo - yhi;\r
+                nom = SKP_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + SKP_RSHIFT( den, 1 );\r
+                if( den != 0 ) {\r
+                    ffrac += SKP_DIV32( nom, den );\r
+                }\r
+            } else {\r
+                /* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */\r
+                ffrac += SKP_DIV32( ylo, SKP_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) );\r
+            }\r
+#if OVERSAMPLE_COSINE_TABLE\r
+            NLSF[ root_ix ] = (SKP_int)SKP_min_32( SKP_LSHIFT( (SKP_int32)k, 7 ) + ffrac, SKP_int16_MAX ); \r
+#else\r
+            NLSF[ root_ix ] = (SKP_int)SKP_min_32( SKP_LSHIFT( (SKP_int32)k, 8 ) + ffrac, SKP_int16_MAX ); \r
+#endif\r
+\r
+            SKP_assert( NLSF[ root_ix ] >=     0 );\r
+            SKP_assert( NLSF[ root_ix ] <= 32767 );\r
+\r
+            root_ix++;        /* Next root */\r
+            if( root_ix >= d ) {\r
+                /* Found all roots */\r
+                break;\r
+            }\r
+            /* Alternate pointer to polynomial */\r
+            p = PQ[ root_ix & 1 ];\r
+            \r
+            /* Evaluate polynomial */\r
+#if OVERSAMPLE_COSINE_TABLE\r
+            xlo = SKP_Silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] +\r
+              ( ( SKP_Silk_LSFCosTab_FIX_Q12[   k       >> 1 ] - \r
+                  SKP_Silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] ) >> 1 ); // Q12\r
+#else\r
+            xlo = SKP_Silk_LSFCosTab_FIX_Q12[ k - 1 ]; // Q12\r
+#endif\r
+            ylo = SKP_LSHIFT( 1 - ( root_ix & 2 ), 12 );\r
+        } else {\r
+            /* Increment loop counter */\r
+            k++;\r
+            xlo    = xhi;\r
+            ylo    = yhi;\r
+            \r
+#if OVERSAMPLE_COSINE_TABLE\r
+            if( k > 2 * LSF_COS_TAB_SZ_FIX ) {\r
+#else\r
+            if( k > LSF_COS_TAB_SZ_FIX ) {\r
+#endif\r
+                i++;\r
+                if( i > MAX_ITERATIONS_A2NLSF_FIX ) {\r
+                    /* Set NLSFs to white spectrum and exit */\r
+                    NLSF[ 0 ] = SKP_DIV32_16( 1 << 15, d + 1 );\r
+                    for( k = 1; k < d; k++ ) {\r
+                        NLSF[ k ] = SKP_SMULBB( k + 1, NLSF[ 0 ] );\r
+                    }\r
+                    return;\r
+                }\r
+\r
+                /* Error: Apply progressively more bandwidth expansion and run again */\r
+                SKP_Silk_bwexpander_32( a_Q16, d, 65536 - SKP_SMULBB( 66, i ) ); // 66_Q16 = 0.001\r
+\r
+                SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd );\r
+                p = P;                            /* Pointer to polynomial */\r
+                xlo = SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12\r
+                ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );\r
+                if( ylo < 0 ) {\r
+                    /* Set the first NLSF to zero and move on to the next */\r
+                    NLSF[ 0 ] = 0;\r
+                    p = Q;                        /* Pointer to polynomial */\r
+                    ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );\r
+                    root_ix = 1;                /* Index of current root */\r
+                } else {\r
+                    root_ix = 0;                /* Index of current root */\r
+                }\r
+                k = 1;                            /* Reset loop counter */\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/src/SKP_Silk_CNG.c b/src/SKP_Silk_CNG.c
new file mode 100644 (file)
index 0000000..2958fad
--- /dev/null
@@ -0,0 +1,149 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main_FIX.h"\r
+\r
+/* Generates excitation for CNG LPC synthesis */\r
+SKP_INLINE void SKP_Silk_CNG_exc(\r
+    SKP_int16                       residual[],         /* O    CNG residual signal Q0                      */\r
+    SKP_int32                       exc_buf_Q10[],      /* I    Random samples buffer Q10                   */\r
+    SKP_int32                       Gain_Q16,           /* I    Gain to apply                               */\r
+    SKP_int                         length,             /* I    Length                                      */\r
+    SKP_int32                       *rand_seed          /* I/O  Seed to random index generator              */\r
+)\r
+{\r
+    SKP_int32 seed;\r
+    SKP_int   i, idx, exc_mask;\r
+\r
+    exc_mask = CNG_BUF_MASK_MAX;\r
+    while( exc_mask > length ) {\r
+        exc_mask = SKP_RSHIFT( exc_mask, 1 );\r
+    }\r
+\r
+    seed = *rand_seed;\r
+    for( i = 0; i < length; i++ ) {\r
+        seed = SKP_RAND( seed );\r
+        idx = ( SKP_int )( SKP_RSHIFT( seed, 24 ) & exc_mask );\r
+        SKP_assert( idx >= 0 );\r
+        SKP_assert( idx <= CNG_BUF_MASK_MAX );\r
+        residual[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( exc_buf_Q10[ idx ], Gain_Q16 ), 10 ) );\r
+    }\r
+    *rand_seed = seed;\r
+}\r
+\r
+void SKP_Silk_CNG_Reset(\r
+    SKP_Silk_decoder_state      *psDec              /* I/O  Decoder state                               */\r
+)\r
+{\r
+    SKP_int i, NLSF_step_Q15, NLSF_acc_Q15;\r
+\r
+    NLSF_step_Q15 = SKP_DIV32_16( SKP_int16_MAX, psDec->LPC_order + 1 );\r
+    NLSF_acc_Q15 = 0;\r
+    for( i = 0; i < psDec->LPC_order; i++ ) {\r
+        NLSF_acc_Q15 += NLSF_step_Q15;\r
+        psDec->sCNG.CNG_smth_NLSF_Q15[ i ] = NLSF_acc_Q15;\r
+    }\r
+    psDec->sCNG.CNG_smth_Gain_Q16 = 0;\r
+    psDec->sCNG.rand_seed = 3176576;\r
+}\r
+\r
+/* Updates CNG estimate, and applies the CNG when packet was lost   */\r
+void SKP_Silk_CNG(\r
+    SKP_Silk_decoder_state      *psDec,             /* I/O  Decoder state                               */\r
+    SKP_Silk_decoder_control    *psDecCtrl,         /* I/O  Decoder control                             */\r
+    SKP_int16                   signal[],           /* I/O  Signal                                      */\r
+    SKP_int                     length              /* I    Length of residual                          */\r
+)\r
+{\r
+    SKP_int   i, subfr;\r
+    SKP_int32 tmp_32, Gain_Q26, max_Gain_Q16;\r
+    SKP_int16 LPC_buf[ MAX_LPC_ORDER ];\r
+    SKP_int16 CNG_sig[ MAX_FRAME_LENGTH ];\r
+    SKP_Silk_CNG_struct *psCNG;\r
+    psCNG = &psDec->sCNG;\r
+\r
+    if( psDec->fs_kHz != psCNG->fs_kHz ) {\r
+        /* Reset state */\r
+        SKP_Silk_CNG_Reset( psDec );\r
+\r
+        psCNG->fs_kHz = psDec->fs_kHz;\r
+    }\r
+    if( psDec->lossCnt == 0 && psDec->vadFlag == NO_VOICE_ACTIVITY ) {\r
+        /* Update CNG parameters */\r
+\r
+        /* Smoothing of LSF's  */\r
+        for( i = 0; i < psDec->LPC_order; i++ ) {\r
+            psCNG->CNG_smth_NLSF_Q15[ i ] += SKP_SMULWB( psDec->prevNLSF_Q15[ i ] - psCNG->CNG_smth_NLSF_Q15[ i ], CNG_NLSF_SMTH_Q16 );\r
+        }\r
+        /* Find the subframe with the highest gain */\r
+        max_Gain_Q16 = 0;\r
+        subfr        = 0;\r
+        for( i = 0; i < NB_SUBFR; i++ ) {\r
+            if( psDecCtrl->Gains_Q16[ i ] > max_Gain_Q16 ) {\r
+                max_Gain_Q16 = psDecCtrl->Gains_Q16[ i ];\r
+                subfr        = i;\r
+            }\r
+        }\r
+        /* Update CNG excitation buffer with excitation from this subframe */\r
+        SKP_memmove( &psCNG->CNG_exc_buf_Q10[ psDec->subfr_length ], psCNG->CNG_exc_buf_Q10, ( NB_SUBFR - 1 ) * psDec->subfr_length * sizeof( SKP_int32 ) );\r
+        SKP_memcpy(   psCNG->CNG_exc_buf_Q10, &psDec->exc_Q10[ subfr * psDec->subfr_length ], psDec->subfr_length * sizeof( SKP_int32 ) );\r
+\r
+        /* Smooth gains */\r
+        for( i = 0; i < NB_SUBFR; i++ ) {\r
+            psCNG->CNG_smth_Gain_Q16 += SKP_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 );\r
+        }\r
+    }\r
+\r
+    /* Add CNG when packet is lost and / or when low speech activity */\r
+    if( psDec->lossCnt ) {//|| psDec->vadFlag == NO_VOICE_ACTIVITY ) {\r
+\r
+        /* Generate CNG excitation */\r
+        SKP_Silk_CNG_exc( CNG_sig, psCNG->CNG_exc_buf_Q10, \r
+                psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed );\r
+\r
+        /* Convert CNG NLSF to filter representation */\r
+        SKP_Silk_NLSF2A_stable( LPC_buf, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order );\r
+\r
+        Gain_Q26 = ( SKP_int32 )1 << 26; /* 1.0 */\r
+        \r
+        /* Generate CNG signal, by synthesis filtering */\r
+        if( psDec->LPC_order == 16 ) {\r
+            SKP_Silk_LPC_synthesis_order16( CNG_sig, LPC_buf, \r
+                Gain_Q26, psCNG->CNG_synth_state, CNG_sig, length );\r
+        } else {\r
+            SKP_Silk_LPC_synthesis_filter( CNG_sig, LPC_buf, \r
+                Gain_Q26, psCNG->CNG_synth_state, CNG_sig, length, psDec->LPC_order );\r
+        }\r
+        /* Mix with signal */\r
+        for( i = 0; i < length; i++ ) {\r
+            tmp_32 = signal[ i ] + CNG_sig[ i ];\r
+            signal[ i ] = SKP_SAT16( tmp_32 );\r
+        }\r
+    } else {\r
+        SKP_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order *  sizeof( SKP_int32 ) );\r
+    }\r
+}\r
diff --git a/src/SKP_Silk_HP_variable_cutoff_FIX.c b/src/SKP_Silk_HP_variable_cutoff_FIX.c
new file mode 100644 (file)
index 0000000..68356fa
--- /dev/null
@@ -0,0 +1,118 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main_FIX.h"\r
+\r
+#if HIGH_PASS_INPUT\r
+\r
+#define SKP_RADIANS_CONSTANT_Q19            1482    // 0.45f * 2.0f * 3.14159265359 / 1000\r
+#define SKP_LOG2_VARIABLE_HP_MIN_FREQ_Q7    809     // log(80) in Q7\r
+\r
+/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */\r
+void SKP_Silk_HP_variable_cutoff_FIX(\r
+    SKP_Silk_encoder_state_FIX      *psEnc,             /* I/O  Encoder state FIX                           */\r
+    SKP_Silk_encoder_control_FIX    *psEncCtrl,         /* I/O  Encoder control FIX                         */\r
+    SKP_int16                       *out,               /* O    high-pass filtered output signal            */\r
+    const SKP_int16                 *in                 /* I    input signal                                */\r
+)\r
+{\r
+    SKP_int   quality_Q15;\r
+    SKP_int32 B_Q28[ 3 ], A_Q28[ 2 ];\r
+    SKP_int32 Fc_Q19, r_Q28, r_Q22;\r
+    SKP_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7;\r
+\r
+    /*********************************************/\r
+    /* Estimate Low End of Pitch Frequency Range */\r
+    /*********************************************/\r
+    if( psEnc->sCmn.prev_sigtype == SIG_TYPE_VOICED ) {\r
+        /* difference, in log domain */\r
+        pitch_freq_Hz_Q16 = SKP_DIV32_16( SKP_LSHIFT( SKP_MUL( psEnc->sCmn.fs_kHz, 1000 ), 16 ), psEnc->sCmn.prevLag );\r
+        pitch_freq_log_Q7 = SKP_Silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 ); //0x70\r
+\r
+        /* adjustment based on quality */\r
+        quality_Q15 = psEncCtrl->input_quality_bands_Q15[ 0 ];\r
+        pitch_freq_log_Q7 = SKP_SUB32( pitch_freq_log_Q7, SKP_SMULWB( SKP_SMULWB( SKP_LSHIFT( quality_Q15, 2 ), quality_Q15 ), \r
+            pitch_freq_log_Q7 - SKP_LOG2_VARIABLE_HP_MIN_FREQ_Q7 ) );\r
+        pitch_freq_log_Q7 = SKP_ADD32( pitch_freq_log_Q7, SKP_RSHIFT( 19661 - quality_Q15, 9 ) ); // 19661_Q15 = 0.6_Q0\r
+\r
+        //delta_freq = pitch_freq_log - psEnc->variable_HP_smth1;\r
+        delta_freq_Q7 = pitch_freq_log_Q7 - SKP_RSHIFT( psEnc->variable_HP_smth1_Q15, 8 );\r
+        if( delta_freq_Q7 < 0 ) {\r
+            /* less smoothing for decreasing pitch frequency, to track something close to the minimum */\r
+            delta_freq_Q7 = SKP_MUL( delta_freq_Q7, 3 );\r
+        }\r
+\r
+        /* limit delta, to reduce impact of outliers */\r
+        delta_freq_Q7 = SKP_LIMIT( delta_freq_Q7, -VARIABLE_HP_MAX_DELTA_FREQ_Q7, VARIABLE_HP_MAX_DELTA_FREQ_Q7 );\r
+\r
+        /* update smoother */\r
+        psEnc->variable_HP_smth1_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth1_Q15, \r
+            SKP_MUL( SKP_LSHIFT( psEnc->speech_activity_Q8, 1 ), delta_freq_Q7 ), VARIABLE_HP_SMTH_COEF1_Q16 );\r
+    }\r
+    /* second smoother */\r
+    psEnc->variable_HP_smth2_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth2_Q15, \r
+        psEnc->variable_HP_smth1_Q15 - psEnc->variable_HP_smth2_Q15, VARIABLE_HP_SMTH_COEF2_Q16 );\r
+\r
+    /* convert from log scale to Hertz */\r
+    psEncCtrl->pitch_freq_low_Hz = SKP_Silk_log2lin( SKP_RSHIFT( psEnc->variable_HP_smth2_Q15, 8 ) ); //pow( 2.0, psEnc->variable_HP_smth2 );\r
+\r
+    /* limit frequency range */\r
+    psEncCtrl->pitch_freq_low_Hz = SKP_LIMIT( psEncCtrl->pitch_freq_low_Hz, VARIABLE_HP_MIN_FREQ_Q0, VARIABLE_HP_MAX_FREQ_Q0 );\r
+\r
+    /********************************/\r
+    /* Compute Filter Coefficients  */\r
+    /********************************/\r
+    /* compute cut-off frequency, in radians */\r
+    //Fc_num   = (SKP_float)( 0.45f * 2.0f * 3.14159265359 * psEncCtrl->pitch_freq_low_Hz );\r
+    //Fc_denom = (SKP_float)( 1e3f * psEnc->sCmn.fs_kHz );\r
+    SKP_assert( psEncCtrl->pitch_freq_low_Hz <= SKP_int32_MAX / SKP_RADIANS_CONSTANT_Q19 );\r
+    Fc_Q19 = SKP_DIV32_16( SKP_SMULBB( SKP_RADIANS_CONSTANT_Q19, psEncCtrl->pitch_freq_low_Hz ), psEnc->sCmn.fs_kHz ); // range: 3704 - 27787, 11-15 bits\r
+    SKP_assert( Fc_Q19 >=  3704 );\r
+    SKP_assert( Fc_Q19 <= 27787 );\r
+\r
+    r_Q28 = ( 1 << 28 ) - SKP_MUL( 471, Fc_Q19 ); // 471_Q9 = 0.92_Q0, range: 255347779 to 266690872, 27-28 bits\r
+    SKP_assert( r_Q28 >= 255347779 );\r
+    SKP_assert( r_Q28 <= 266690872 );\r
+\r
+    /* b = r * [ 1; -2; 1 ]; */\r
+    /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */\r
+    B_Q28[ 0 ] = r_Q28;\r
+    B_Q28[ 1 ] = SKP_LSHIFT( -r_Q28, 1 );\r
+    B_Q28[ 2 ] = r_Q28;\r
+    \r
+    // -r * ( 2 - Fc * Fc );\r
+    r_Q22  = SKP_RSHIFT( r_Q28, 6 );\r
+    A_Q28[ 0 ] = SKP_SMULWW( r_Q22, SKP_SMULWW( Fc_Q19, Fc_Q19 ) - ( 2 << 22 ) );\r
+    A_Q28[ 1 ] = SKP_SMULWW( r_Q22, r_Q22 );\r
+\r
+    /********************************/\r
+    /* High-Pass Filter             */\r
+    /********************************/\r
+    SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psEnc->sCmn.In_HP_State, out, psEnc->sCmn.frame_length );\r
+}\r
+\r
+#endif // HIGH_PASS_INPUT\r
diff --git a/src/SKP_Silk_Inlines.h b/src/SKP_Silk_Inlines.h
new file mode 100644 (file)
index 0000000..66a09bd
--- /dev/null
@@ -0,0 +1,280 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+/*! \file SKP_Silk_Inlines.h\r
+ *  \brief SigProcFix_Inlines.h defines inline signal processing functions.\r
+ */\r
+\r
+#ifndef _SKP_SILK_FIX_INLINES_H_\r
+#define _SKP_SILK_FIX_INLINES_H_\r
+\r
+#ifdef  __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+/* count leading zeros of SKP_int64 */\r
+SKP_INLINE SKP_int32 SKP_Silk_CLZ64(SKP_int64 in)\r
+{\r
+    SKP_int32 in_upper;\r
+\r
+    in_upper = (SKP_int32)SKP_RSHIFT64(in, 32);\r
+    if (in_upper == 0) {\r
+        /* Search in the lower 32 bits */\r
+        return 32 + SKP_Silk_CLZ32( (SKP_int32) in );\r
+    } else {\r
+        /* Search in the upper 32 bits */\r
+        return SKP_Silk_CLZ32( in_upper );\r
+    }\r
+}\r
+\r
+/* get number of leading zeros and fractional part (the bits right after the leading one */\r
+SKP_INLINE void SKP_Silk_CLZ_FRAC(SKP_int32 in,            /* I: input */\r
+                                    SKP_int32 *lz,           /* O: number of leading zeros */\r
+                                    SKP_int32 *frac_Q7)      /* O: the 7 bits right after the leading one */\r
+{\r
+    SKP_int32 leadingZeros;\r
+\r
+    leadingZeros = SKP_Silk_CLZ32(in);\r
+    *lz = leadingZeros;\r
+    if( leadingZeros < 24 ) { \r
+        *frac_Q7 = SKP_RSHIFT(in, 24 - leadingZeros) & 0x7F;\r
+    } else {\r
+        *frac_Q7 = SKP_LSHIFT(in, leadingZeros - 24) & 0x7F;\r
+    }\r
+}\r
+\r
+/* Approximation of square root                                          */\r
+/* Accuracy: < +/- 10% for output values > 15                            */\r
+/*             < +/- 2.5% for output values > 120                        */\r
+SKP_INLINE SKP_int32 SKP_Silk_SQRT_APPROX(SKP_int32 x)\r
+{\r
+    SKP_int32 y, lz, frac_Q7;\r
+\r
+    if( x <= 0 ) {\r
+        return 0;\r
+    }\r
+\r
+    SKP_Silk_CLZ_FRAC(x, &lz, &frac_Q7);\r
+\r
+    if( lz & 1 ) {\r
+        y = 32768;\r
+    } else {\r
+        y = 46214;        /* 46214 = sqrt(2) * 32768 */\r
+    }\r
+\r
+    /* get scaling right */\r
+    y >>= SKP_RSHIFT(lz, 1);\r
+\r
+    /* increment using fractional part of input */\r
+    y = SKP_SMLAWB(y, y, SKP_SMULBB(213, frac_Q7));\r
+\r
+    return y;\r
+}\r
+\r
+/* returns the number of left shifts before overflow for a 16 bit number (ITU definition with norm(0)=0) */\r
+SKP_INLINE SKP_int32 SKP_Silk_norm16(SKP_int16 a) {\r
+\r
+  SKP_int32 a32;\r
+\r
+  /* if ((a == 0) || (a == SKP_int16_MIN)) return(0); */\r
+  if ((a << 1) == 0) return(0);\r
+\r
+  a32 = a;\r
+  /* if (a32 < 0) a32 = -a32 - 1; */\r
+  a32 ^= SKP_RSHIFT(a32, 31);\r
+\r
+  return SKP_Silk_CLZ32(a32) - 17;\r
+}\r
+\r
+/* returns the number of left shifts before overflow for a 32 bit number (ITU definition with norm(0)=0) */\r
+SKP_INLINE SKP_int32 SKP_Silk_norm32(SKP_int32 a) {\r
+  \r
+  /* if ((a == 0) || (a == SKP_int32_MIN)) return(0); */\r
+  if ((a << 1) == 0) return(0);\r
+\r
+  /* if (a < 0) a = -a - 1; */\r
+  a ^= SKP_RSHIFT(a, 31);\r
+\r
+  return SKP_Silk_CLZ32(a) - 1;\r
+}\r
+\r
+/* Divide two int32 values and return result as int32 in a given Q-domain */\r
+SKP_INLINE SKP_int32 SKP_DIV32_varQ(    /* O    returns a good approximation of "(a32 << Qres) / b32" */\r
+    const SKP_int32        a32,         /* I    numerator (Q0)                  */\r
+    const SKP_int32        b32,         /* I    denominator (Q0)                */\r
+    const SKP_int        Qres           /* I    Q-domain of result (>= 0)       */\r
+)\r
+{\r
+    SKP_int   a_headrm, b_headrm, lshift;\r
+    SKP_int32 b32_inv, a32_nrm, b32_nrm, result;\r
+\r
+    SKP_assert( b32 != 0 );\r
+    SKP_assert( Qres >= 0 );\r
+\r
+    /* Compute number of bits head room and normalize inputs */\r
+    a_headrm = SKP_Silk_CLZ32( SKP_abs(a32) ) - 1;\r
+    a32_nrm = SKP_LSHIFT(a32, a_headrm);                                    /* Q: a_headrm                    */\r
+    b_headrm = SKP_Silk_CLZ32( SKP_abs(b32) ) - 1;\r
+    b32_nrm = SKP_LSHIFT(b32, b_headrm);                                    /* Q: b_headrm                    */\r
+\r
+    /* Inverse of b32, with 14 bits of precision */\r
+    b32_inv = SKP_DIV32_16( SKP_int32_MAX >> 2, SKP_RSHIFT(b32_nrm, 16) );  /* Q: 29 + 16 - b_headrm        */\r
+\r
+    /* First approximation */\r
+    result = SKP_SMULWB(a32_nrm, b32_inv);                                  /* Q: 29 + a_headrm - b_headrm    */\r
+\r
+    /* Compute residual by subtracting product of denominator and first approximation */\r
+    a32_nrm -= SKP_LSHIFT_ovflw( SKP_SMMUL(b32_nrm, result), 3 );           /* Q: a_headrm                    */\r
+\r
+    /* Refinement */\r
+    result = SKP_SMLAWB(result, a32_nrm, b32_inv);                          /* Q: 29 + a_headrm - b_headrm    */\r
+\r
+    /* Convert to Qres domain */\r
+    lshift = 29 + a_headrm - b_headrm - Qres;\r
+    if( lshift <= 0 ) {\r
+        return SKP_LSHIFT_SAT32(result, -lshift);\r
+    } else {\r
+        if( lshift < 32){\r
+            return SKP_RSHIFT(result, lshift);\r
+        } else {\r
+            /* Avoid undefined result */\r
+            return 0;\r
+        }\r
+    }\r
+}\r
+\r
+/* Invert int32 value and return result as int32 in a given Q-domain */\r
+SKP_INLINE SKP_int32 SKP_INVERSE32_varQ(    /* O    returns a good approximation of "(1 << Qres) / b32" */\r
+    const SKP_int32        b32,             /* I    denominator (Q0)                */\r
+    const SKP_int        Qres               /* I    Q-domain of result (> 0)        */\r
+)\r
+{\r
+    SKP_int   b_headrm, lshift;\r
+    SKP_int32 b32_inv, b32_nrm, err_Q32, result;\r
+\r
+    SKP_assert( b32 != 0 );\r
+    SKP_assert( Qres > 0 );\r
+\r
+    /* Compute number of bits head room and normalize input */\r
+    b_headrm = SKP_Silk_CLZ32( SKP_abs(b32) ) - 1;\r
+    b32_nrm = SKP_LSHIFT(b32, b_headrm);                                    /* Q: b_headrm                */\r
+\r
+    /* Inverse of b32, with 14 bits of precision */\r
+    b32_inv = SKP_DIV32_16( SKP_int32_MAX >> 2, SKP_RSHIFT(b32_nrm, 16) );  /* Q: 29 + 16 - b_headrm    */\r
+\r
+    /* First approximation */\r
+    result = SKP_LSHIFT(b32_inv, 16);                                       /* Q: 61 - b_headrm            */\r
+\r
+    /* Compute residual by subtracting product of denominator and first approximation from one */\r
+    err_Q32 = SKP_LSHIFT_ovflw( -SKP_SMULWB(b32_nrm, b32_inv), 3 );         /* Q32                        */\r
+\r
+    /* Refinement */\r
+    result = SKP_SMLAWW(result, err_Q32, b32_inv);                          /* Q: 61 - b_headrm            */\r
+\r
+    /* Convert to Qres domain */\r
+    lshift = 61 - b_headrm - Qres;\r
+    if( lshift <= 0 ) {\r
+        return SKP_LSHIFT_SAT32(result, -lshift);\r
+    } else {\r
+        if( lshift < 32){\r
+            return SKP_RSHIFT(result, lshift);\r
+        }else{\r
+            /* Avoid undefined result */\r
+            return 0;\r
+        }\r
+    }\r
+}\r
+\r
+#define SKP_SIN_APPROX_CONST0       (1073735400)\r
+#define SKP_SIN_APPROX_CONST1        (-82778932)\r
+#define SKP_SIN_APPROX_CONST2          (1059577)\r
+#define SKP_SIN_APPROX_CONST3            (-5013)\r
+\r
+/* Sine approximation; an input of 65536 corresponds to 2 * pi */\r
+/* Uses polynomial expansion of the input to the power 0, 2, 4 and 6 */\r
+/* The relative error is below 1e-5 */\r
+SKP_INLINE SKP_int32 SKP_Silk_SIN_APPROX_Q24(        /* O    returns approximately 2^24 * sin(x * 2 * pi / 65536) */\r
+    SKP_int32        x\r
+)\r
+{\r
+    SKP_int y_Q30;\r
+\r
+    /* Keep only bottom 16 bits (the function repeats itself with period 65536) */\r
+    x &= 65535;\r
+\r
+    /* Split range in four quadrants */\r
+    if( x <= 32768 ) {\r
+        if( x < 16384 ) {\r
+            /* Return cos(pi/2 - x) */\r
+            x = 16384 - x;\r
+        } else {\r
+            /* Return cos(x - pi/2) */\r
+            x -= 16384;\r
+        }\r
+        if( x < 1100 ) {\r
+            /* Special case: high accuracy */\r
+            return SKP_SMLAWB( 1 << 24, SKP_MUL( x, x ), -5053 );\r
+        }\r
+        x = SKP_SMULWB( SKP_LSHIFT( x, 8 ), x );        /* contains x^2 in Q20 */\r
+        y_Q30 = SKP_SMLAWB( SKP_SIN_APPROX_CONST2, x, SKP_SIN_APPROX_CONST3 );\r
+        y_Q30 = SKP_SMLAWW( SKP_SIN_APPROX_CONST1, x, y_Q30 );\r
+        y_Q30 = SKP_SMLAWW( SKP_SIN_APPROX_CONST0 + 66, x, y_Q30 );\r
+    } else {\r
+        if( x < 49152 ) {\r
+            /* Return -cos(3*pi/2 - x) */\r
+            x = 49152 - x;\r
+        } else {\r
+            /* Return -cos(x - 3*pi/2) */\r
+            x -= 49152;\r
+        }\r
+        if( x < 1100 ) {\r
+            /* Special case: high accuracy */\r
+            return SKP_SMLAWB( -1 << 24, SKP_MUL( x, x ), 5053 );\r
+        }\r
+        x = SKP_SMULWB( SKP_LSHIFT( x, 8 ), x );        /* contains x^2 in Q20 */\r
+        y_Q30 = SKP_SMLAWB( -SKP_SIN_APPROX_CONST2, x, -SKP_SIN_APPROX_CONST3 );\r
+        y_Q30 = SKP_SMLAWW( -SKP_SIN_APPROX_CONST1, x, y_Q30 );\r
+        y_Q30 = SKP_SMLAWW( -SKP_SIN_APPROX_CONST0, x, y_Q30 );\r
+    }\r
+    return SKP_RSHIFT_ROUND( y_Q30, 6 );\r
+}\r
+\r
+/* Cosine approximation; an input of 65536 corresponds to 2 * pi */\r
+/* The relative error is below 1e-5 */\r
+SKP_INLINE SKP_int32 SKP_Silk_COS_APPROX_Q24(        /* O    returns approximately 2^24 * cos(x * 2 * pi / 65536) */\r
+    SKP_int32        x\r
+)\r
+{\r
+    return SKP_Silk_SIN_APPROX_Q24( x + 16384 );\r
+}\r
+\r
+#ifdef  __cplusplus\r
+}\r
+#endif\r
+\r
+#endif //_SKP_SILK_FIX_INLINES_H_\r
diff --git a/src/SKP_Silk_LBRR_reset.c b/src/SKP_Silk_LBRR_reset.c
new file mode 100644 (file)
index 0000000..22e6830
--- /dev/null
@@ -0,0 +1,40 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main.h"\r
+\r
+/* Resets LBRR buffer, used if packet size changes */\r
+void SKP_Silk_LBRR_reset( \r
+    SKP_Silk_encoder_state      *psEncC             /* I/O  state                                       */\r
+)\r
+{\r
+    SKP_int i;\r
+\r
+    for( i = 0; i < MAX_LBRR_DELAY; i++ ) {\r
+        psEncC->LBRR_buffer[ i ].usage = SKP_SILK_NO_LBRR;\r
+    }\r
+}\r
diff --git a/src/SKP_Silk_LPC_inv_pred_gain.c b/src/SKP_Silk_LPC_inv_pred_gain.c
new file mode 100644 (file)
index 0000000..a350a6f
--- /dev/null
@@ -0,0 +1,189 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+/*                                                                      *\r
+ * SKP_Silk_LPC_inverse_pred_gain.c                                   *\r
+ *                                                                      *\r
+ * Compute inverse of LPC prediction gain, and                          *\r
+ * test if LPC coefficients are stable (all poles within unit circle)   *\r
+ *                                                                      *\r
+ * Copyright 2008 (c), Skype Limited                                           *\r
+ *                                                                      */\r
+#include "SKP_Silk_SigProc_FIX.h"\r
+#define QA          16\r
+#define A_LIMIT     65520\r
+\r
+/* Compute inverse of LPC prediction gain, and                          */\r
+/* test if LPC coefficients are stable (all poles within unit circle)   */\r
+SKP_int SKP_Silk_LPC_inverse_pred_gain(       /* O:   Returns 1 if unstable, otherwise 0          */\r
+    SKP_int32           *invGain_Q30,           /* O:   Inverse prediction gain, Q30 energy domain  */\r
+    const SKP_int16     *A_Q12,                 /* I:   Prediction coefficients, Q12 [order]        */\r
+    const SKP_int       order                   /* I:   Prediction order                            */\r
+)\r
+{\r
+    SKP_int   k, n, headrm;\r
+    SKP_int32 rc_Q31, rc_mult1_Q30, rc_mult2_Q16;\r
+    SKP_int32 Atmp_QA[ 2 ][ SigProc_MAX_ORDER_LPC ], tmp_QA;\r
+    SKP_int32 *Aold_QA, *Anew_QA;\r
+\r
+    Anew_QA = Atmp_QA[ order & 1 ];\r
+    /* Increase Q domain of the AR coefficients */\r
+    for( k = 0; k < order; k++ ) {\r
+        Anew_QA[ k ] = SKP_LSHIFT( (SKP_int32)A_Q12[ k ], QA - 12 );\r
+    }\r
+\r
+    *invGain_Q30 = ( 1 << 30 );\r
+    for( k = order - 1; k > 0; k-- ) {\r
+        /* Check for stability */\r
+        if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {\r
+            return 1;\r
+        }\r
+\r
+        /* Set RC equal to negated AR coef */\r
+        rc_Q31 = -SKP_LSHIFT( Anew_QA[ k ], 31 - QA );\r
+        \r
+        /* rc_mult1_Q30 range: [ 1 : 2^30-1 ] */\r
+        rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 );\r
+        SKP_assert( rc_mult1_Q30 > ( 1 << 15 ) );                   /* reduce A_LIMIT if fails */\r
+        SKP_assert( rc_mult1_Q30 < ( 1 << 30 ) );\r
+\r
+        /* rc_mult2_Q16 range: [ 2^16 : SKP_int32_MAX ] */\r
+        rc_mult2_Q16 = SKP_INVERSE32_varQ( rc_mult1_Q30, 46 );      /* 16 = 46 - 30 */\r
+\r
+        /* Update inverse gain */\r
+        /* invGain_Q30 range: [ 0 : 2^30 ] */\r
+        *invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );\r
+        SKP_assert( *invGain_Q30 >= 0           );\r
+        SKP_assert( *invGain_Q30 <= ( 1 << 30 ) );\r
+\r
+        /* Swap pointers */\r
+        Aold_QA = Anew_QA;\r
+        Anew_QA = Atmp_QA[ k & 1 ];\r
+        \r
+        /* Update AR coefficient */\r
+        headrm = SKP_Silk_CLZ32( rc_mult2_Q16 ) - 1;\r
+        rc_mult2_Q16 = SKP_LSHIFT( rc_mult2_Q16, headrm );          /* Q: 16 + headrm */\r
+        for( n = 0; n < k; n++ ) {\r
+            tmp_QA = Aold_QA[ n ] - SKP_LSHIFT( SKP_SMMUL( Aold_QA[ k - n - 1 ], rc_Q31 ), 1 );\r
+            Anew_QA[ n ] = SKP_LSHIFT( SKP_SMMUL( tmp_QA, rc_mult2_Q16 ), 16 - headrm );\r
+        }\r
+    }\r
+\r
+    /* Check for stability */\r
+    if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {\r
+        return 1;\r
+    }\r
+\r
+    /* Set RC equal to negated AR coef */\r
+    rc_Q31 = -SKP_LSHIFT( Anew_QA[ 0 ], 31 - QA );\r
+\r
+    /* Range: [ 1 : 2^30 ] */\r
+    rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 );\r
+\r
+    /* Update inverse gain */\r
+    /* Range: [ 0 : 2^30 ] */\r
+    *invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );\r
+    SKP_assert( *invGain_Q30 >= 0     );\r
+    SKP_assert( *invGain_Q30 <= 1<<30 );\r
+\r
+    return 0;\r
+}\r
+\r
+/* For input in Q13 domain */\r
+SKP_int SKP_Silk_LPC_inverse_pred_gain_Q13(   /* O:   Returns 1 if unstable, otherwise 0          */\r
+    SKP_int32           *invGain_Q30,           /* O:   Inverse prediction gain, Q30 energy domain  */\r
+    const SKP_int16     *A_Q13,                 /* I:   Prediction coefficients, Q13 [order]        */\r
+    const SKP_int       order                   /* I:   Prediction order                            */\r
+)\r
+{\r
+    SKP_int   k, n, headrm;\r
+    SKP_int32 rc_Q31, rc_mult1_Q30, rc_mult2_Q16;\r
+    SKP_int32 Atmp_QA[ 2 ][ SigProc_MAX_ORDER_LPC ], tmp_QA;\r
+    SKP_int32 *Aold_QA, *Anew_QA;\r
+\r
+    Anew_QA = Atmp_QA[ order & 1 ];\r
+    /* Increase Q domain of the AR coefficients */\r
+    for( k = 0; k < order; k++ ) {\r
+        Anew_QA[ k ] = SKP_LSHIFT( (SKP_int32)A_Q13[ k ], QA - 13 );\r
+    }\r
+\r
+    *invGain_Q30 = ( 1 << 30 );\r
+    for( k = order - 1; k > 0; k-- ) {\r
+        /* Check for stability */\r
+        if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {\r
+            return 1;\r
+        }\r
+\r
+        /* Set RC equal to negated AR coef */\r
+        rc_Q31 = -SKP_LSHIFT( Anew_QA[ k ], 31 - QA );\r
+        \r
+        /* rc_mult1_Q30 range: [ 1 : 2^30-1 ] */\r
+        rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 );\r
+        SKP_assert( rc_mult1_Q30 > ( 1 << 15 ) );                   /* reduce A_LIMIT if fails */\r
+        SKP_assert( rc_mult1_Q30 < ( 1 << 30 ) );\r
+\r
+        /* rc_mult2_Q16 range: [ 2^16 : SKP_int32_MAX ] */\r
+        rc_mult2_Q16 = SKP_INVERSE32_varQ( rc_mult1_Q30, 46 );      /* 16 = 46 - 30 */\r
+\r
+        /* Update inverse gain */\r
+        /* invGain_Q30 range: [ 0 : 2^30 ] */\r
+        *invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );\r
+        SKP_assert( *invGain_Q30 >= 0     );\r
+        SKP_assert( *invGain_Q30 <= 1<<30 );\r
+\r
+        /* Swap pointers */\r
+        Aold_QA = Anew_QA;\r
+        Anew_QA = Atmp_QA[ k & 1 ];\r
+        \r
+        /* Update AR coefficient */\r
+        headrm = SKP_Silk_CLZ32( rc_mult2_Q16 ) - 1;\r
+        rc_mult2_Q16 = SKP_LSHIFT( rc_mult2_Q16, headrm );          /* Q: 16 + headrm */\r
+        for( n = 0; n < k; n++ ) {\r
+            tmp_QA = Aold_QA[ n ] - SKP_LSHIFT( SKP_SMMUL( Aold_QA[ k - n - 1 ], rc_Q31 ), 1 );\r
+            Anew_QA[ n ] = SKP_LSHIFT( SKP_SMMUL( tmp_QA, rc_mult2_Q16 ), 16 - headrm );\r
+        }\r
+    }\r
+\r
+    /* Check for stability */\r
+    if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {\r
+        return 1;\r
+    }\r
+\r
+    /* Set RC equal to negated AR coef */\r
+    rc_Q31 = -SKP_LSHIFT( Anew_QA[ 0 ], 31 - QA );\r
+\r
+    /* Range: [ 1 : 2^30 ] */\r
+    rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 );\r
+\r
+    /* Update inverse gain */\r
+    /* Range: [ 0 : 2^30 ] */\r
+    *invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );\r
+    SKP_assert( *invGain_Q30 >= 0     );\r
+    SKP_assert( *invGain_Q30 <= 1<<30 );\r
+\r
+    return 0;\r
+}\r
diff --git a/src/SKP_Silk_LPC_stabilize.c b/src/SKP_Silk_LPC_stabilize.c
new file mode 100644 (file)
index 0000000..bd58d10
--- /dev/null
@@ -0,0 +1,132 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_typedef.h"\r
+#include "SKP_Silk_SigProc_FIX.h"\r
+\r
+#define LPC_STABILIZE_LPC_MAX_ABS_VALUE_Q16     ( ( (SKP_int32)SKP_int16_MAX ) << 4 )\r
+\r
+/* LPC stabilizer, for a single input data vector */\r
+void SKP_Silk_LPC_stabilize(\r
+    SKP_int16       *a_Q12,         /* O    stabilized LPC vector [L]                       */\r
+    SKP_int32       *a_Q16,         /* I    LPC vector [L]                                  */\r
+    const SKP_int32  bwe_Q16,       /* I    Bandwidth expansion factor                      */\r
+    const SKP_int    L              /* I    Number of LPC parameters in the input vector    */\r
+)\r
+{\r
+    SKP_int32   maxabs, absval, sc_Q16;\r
+    SKP_int     i, idx = 0;\r
+    SKP_int32   invGain_Q30;\r
+\r
+    SKP_Silk_bwexpander_32( a_Q16, L, bwe_Q16 );\r
+\r
+    /***************************/\r
+    /* Limit range of the LPCs */\r
+    /***************************/\r
+    /* Limit the maximum absolute value of the prediction coefficients */\r
+    while( SKP_TRUE ) {\r
+        /* Find maximum absolute value and its index */\r
+        maxabs = SKP_int32_MIN;\r
+        for( i = 0; i < L; i++ ) {\r
+            absval = SKP_abs( a_Q16[ i ] );\r
+            if( absval > maxabs ) {\r
+                maxabs = absval;\r
+                idx    = i;\r
+            }\r
+        }\r
+    \r
+        if( maxabs >= LPC_STABILIZE_LPC_MAX_ABS_VALUE_Q16 ) {\r
+            /* Reduce magnitude of prediction coefficients */\r
+            sc_Q16 = SKP_DIV32( SKP_int32_MAX, SKP_RSHIFT( maxabs, 4 ) );\r
+            sc_Q16 = 65536 - sc_Q16;\r
+            sc_Q16 = SKP_DIV32( sc_Q16, idx + 1 );\r
+            sc_Q16 = 65536 - sc_Q16;\r
+            sc_Q16 = SKP_LSHIFT( SKP_SMULWB( sc_Q16, 32604 ), 1 ); // 0.995 in Q16\r
+            SKP_Silk_bwexpander_32( a_Q16, L, sc_Q16 );\r
+        } else {\r
+            break;\r
+        }\r
+    }\r
+\r
+    /* Convert to 16 bit Q12 */\r
+    for( i = 0; i < L; i++ ) {\r
+        a_Q12[ i ] = (SKP_int16)SKP_RSHIFT_ROUND( a_Q16[ i ], 4 );\r
+    }\r
+\r
+    /**********************/\r
+    /* Ensure stable LPCs */\r
+    /**********************/\r
+    while( SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, a_Q12, L ) == 1 ) {\r
+        SKP_Silk_bwexpander( a_Q12, L, 65339 ); // 0.997 in Q16\r
+    }\r
+}\r
+\r
+void SKP_Silk_LPC_fit(\r
+    SKP_int16       *a_QQ,          /* O    Stabilized LPC vector, Q(24-rshift) [L]         */\r
+    SKP_int32       *a_Q24,         /* I    LPC vector [L]                                  */\r
+    const SKP_int    QQ,            /* I    Q domain of output LPC vector                   */\r
+    const SKP_int    L              /* I    Number of LPC parameters in the input vector    */\r
+)\r
+{\r
+    SKP_int     i, rshift, idx = 0;\r
+    SKP_int32   maxabs, absval, sc_Q16;\r
+\r
+    rshift = 24 - QQ;\r
+\r
+    /***************************/\r
+    /* Limit range of the LPCs */\r
+    /***************************/\r
+    /* Limit the maximum absolute value of the prediction coefficients */\r
+    while( SKP_TRUE ) {\r
+        /* Find maximum absolute value and its index */\r
+        maxabs = SKP_int32_MIN;\r
+        for( i = 0; i < L; i++ ) {\r
+            absval = SKP_abs( a_Q24[ i ] );\r
+            if( absval > maxabs ) {\r
+                maxabs = absval;\r
+                idx    = i;\r
+            }\r
+        }\r
+    \r
+        maxabs = SKP_RSHIFT( maxabs, rshift );\r
+        if( maxabs >= SKP_int16_MAX ) {\r
+            /* Reduce magnitude of prediction coefficients */\r
+            sc_Q16 = 65470 - SKP_DIV32( SKP_MUL( 65470 >> 2, maxabs - SKP_int16_MAX ), \r
+                                        SKP_RSHIFT32( SKP_MUL( maxabs, idx + 1), 2 ) );\r
+            SKP_Silk_bwexpander_32( a_Q24, L, sc_Q16 );\r
+        } else {\r
+            break;\r
+        }\r
+    }\r
+\r
+    /* Convert to 16 bit Q(24-rshift) */\r
+    SKP_assert( rshift > 0  );\r
+    SKP_assert( rshift < 31 );\r
+    for( i = 0; i < L; i++ ) {\r
+        a_QQ[ i ] = (SKP_int16)SKP_RSHIFT_ROUND( a_Q24[ i ], rshift );\r
+    }\r
+}\r
diff --git a/src/SKP_Silk_LPC_synthesis_filter.c b/src/SKP_Silk_LPC_synthesis_filter.c
new file mode 100644 (file)
index 0000000..fff5e70
--- /dev/null
@@ -0,0 +1,98 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+/*                                                                      *\r
+ * SKP_Silk_LPC_synthesis_filter.c                                    *\r
+ * Coefficients are in Q12                                              *\r
+ *                                                                      *\r
+ * even order AR filter                                                 *\r
+ *                                                                      */\r
+#include "SKP_Silk_SigProc_FIX.h"\r
+\r
+/* even order AR filter */\r
+void SKP_Silk_LPC_synthesis_filter(\r
+    const SKP_int16 *in,        /* I:   excitation signal */\r
+    const SKP_int16 *A_Q12,     /* I:   AR coefficients [Order], between -8_Q0 and 8_Q0 */\r
+    const SKP_int32 Gain_Q26,   /* I:   gain */\r
+    SKP_int32 *S,               /* I/O: state vector [Order] */\r
+    SKP_int16 *out,             /* O:   output signal */\r
+    const SKP_int32 len,        /* I:   signal length */\r
+    const SKP_int Order         /* I:   filter order, must be even */\r
+)\r
+{\r
+    SKP_int   k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );\r
+    SKP_int32 SA, SB, Atmp, A_align_Q12[SigProc_MAX_ORDER_LPC >> 1], out32_Q10, out32;\r
+\r
+    /* Order must be even */\r
+    SKP_assert( 2*Order_half == Order );\r
+\r
+    /* combine two A_Q12 values and ensure 32-bit alignment */\r
+    for( k = 0; k < Order_half; k++ ) {\r
+        idx = SKP_SMULBB( 2, k );\r
+        A_align_Q12[k] = (((SKP_int32)A_Q12[idx]) & 0x0000ffff) | SKP_LSHIFT( (SKP_int32)A_Q12[idx+1], 16 );\r
+    }\r
+\r
+    /* S[] values are in Q14 */\r
+    for( k = 0; k < len; k++ ) {\r
+        SA = S[Order-1];\r
+        out32_Q10 = 0;\r
+        for( j=0;j<(Order_half-1); j++ ) {\r
+            idx = SKP_SMULBB( 2, j ) + 1;\r
+            /* multiply-add two prediction coefficients for each loop */\r
+            /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the   */\r
+            /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be     */\r
+            /* loaded in reverse order and the code will give the wrong result. In that case swapping   */\r
+            /* the SMLAWB and SMLAWT instructions should solve the problem.                             */\r
+            Atmp = A_align_Q12[j];\r
+            SB = S[Order - 1 - idx];\r
+            S[Order - 1 - idx] = SA;\r
+            out32_Q10 = SKP_SMLAWB( out32_Q10, SA, Atmp );\r
+            out32_Q10 = SKP_SMLAWT( out32_Q10, SB, Atmp );\r
+            SA = S[Order - 2 - idx];\r
+            S[Order - 2 - idx] = SB;\r
+        }\r
+\r
+        /* unrolled loop: epilog */\r
+        Atmp = A_align_Q12[Order_half-1];\r
+        SB = S[0];\r
+        S[0] = SA;\r
+        out32_Q10 = SKP_SMLAWB( out32_Q10, SA, Atmp );\r
+        out32_Q10 = SKP_SMLAWT( out32_Q10, SB, Atmp );\r
+\r
+        /* apply gain to excitation signal and add to prediction */\r
+        out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[k] ) );\r
+\r
+        /* scale to Q0 */\r
+        out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );\r
+\r
+        /* saturate output */\r
+        out[k] = (SKP_int16)SKP_SAT16( out32 );\r
+\r
+        /* move result into delay line */\r
+        S[Order - 1] = SKP_LSHIFT_SAT32( out32_Q10, 4 );\r
+    }\r
+}\r
diff --git a/src/SKP_Silk_LPC_synthesis_order16.c b/src/SKP_Silk_LPC_synthesis_order16.c
new file mode 100644 (file)
index 0000000..ec2d358
--- /dev/null
@@ -0,0 +1,141 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+/*                                                                      *\r
+ * SKP_Silk_LPC_synthesis_order16.c                                   *\r
+ * Coefficients are in Q12                                              *\r
+ *                                                                      *\r
+ * 16th order AR filter                                                 *\r
+ *                                                                      */\r
+#include "SKP_Silk_SigProc_FIX.h"\r
+\r
+/* 16th order AR filter */\r
+void SKP_Silk_LPC_synthesis_order16(const SKP_int16 *in,          /* I:   excitation signal */\r
+                                      const SKP_int16 *A_Q12,       /* I:   AR coefficients [16], between -8_Q0 and 8_Q0 */\r
+                                      const SKP_int32 Gain_Q26,     /* I:   gain */\r
+                                      SKP_int32 *S,                 /* I/O: state vector [16] */\r
+                                      SKP_int16 *out,               /* O:   output signal */\r
+                                      const SKP_int32 len           /* I:   signal length, must be multiple of 16 */\r
+)\r
+{\r
+    SKP_int   k;\r
+    SKP_int32 SA, SB, Atmp, A_align_Q12[8], out32_Q10, out32;\r
+\r
+    /* combine two A_Q12 values and ensure 32-bit alignment */\r
+    for( k = 0; k < 8; k++ ) {\r
+        A_align_Q12[k] = (((SKP_int32)A_Q12[ 2*k ]) & 0x0000ffff) | SKP_LSHIFT( (SKP_int32)A_Q12[ 2*k + 1 ], 16 );\r
+    }\r
+\r
+    /* S[] values are in Q14 */\r
+    /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the   */\r
+    /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be     */\r
+    /* loaded in reverse order and the code will give the wrong result. In that case swapping   */\r
+    /* the SMLAWB and SMLAWT instructions should solve the problem.                             */\r
+    for( k = 0; k < len; k++ ) {\r
+        /* unrolled loop: prolog */\r
+        /* multiply-add two prediction coefficients per iteration */\r
+        SA = S[15];\r
+        Atmp = A_align_Q12[0];\r
+        SB = S[14];\r
+        S[14] = SA;\r
+        out32_Q10 = SKP_SMULWB(                  SA, Atmp );\r
+        out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );\r
+        SA = S[13];\r
+        S[13] = SB;\r
+\r
+        /* unrolled loop: main loop */\r
+        Atmp = A_align_Q12[1];\r
+        SB = S[12];\r
+        S[12] = SA;\r
+        out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );\r
+        out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );\r
+        SA = S[11];\r
+        S[11] = SB;\r
+\r
+        Atmp = A_align_Q12[2];\r
+        SB = S[10];\r
+        S[10] = SA;\r
+        out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );\r
+        out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );\r
+        SA = S[9];\r
+        S[9] = SB;\r
+\r
+        Atmp = A_align_Q12[3];\r
+        SB = S[8];\r
+        S[8] = SA;\r
+        out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );\r
+        out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );\r
+        SA = S[7];\r
+        S[7] = SB;\r
+\r
+        Atmp = A_align_Q12[4];\r
+        SB = S[6];\r
+        S[6] = SA;\r
+        out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );\r
+        out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );\r
+        SA = S[5];\r
+        S[5] = SB;\r
+\r
+        Atmp = A_align_Q12[5];\r
+        SB = S[4];\r
+        S[4] = SA;\r
+        out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );\r
+        out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );\r
+        SA = S[3];\r
+        S[3] = SB;\r
+\r
+        Atmp = A_align_Q12[6];\r
+        SB = S[2];\r
+        S[2] = SA;\r
+        out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );\r
+        out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );\r
+        SA = S[1];\r
+        S[1] = SB;\r
+\r
+        /* unrolled loop: epilog */\r
+        Atmp = A_align_Q12[7];\r
+        SB = S[0];\r
+        S[0] = SA;\r
+        out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );\r
+        out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );\r
+\r
+        /* unrolled loop: end */\r
+        /* apply gain to excitation signal and add to prediction */\r
+        out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[k] ) );\r
+\r
+        /* scale to Q0 */\r
+        out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );\r
+\r
+        /* saturate output */\r
+        out[k] = (SKP_int16)SKP_SAT16( out32 );\r
+\r
+        /* move result into delay line */\r
+        S[15] = SKP_LSHIFT_SAT32( out32_Q10, 4 );\r
+    }\r
+}\r
+\r
+\r
diff --git a/src/SKP_Silk_LP_variable_cutoff.c b/src/SKP_Silk_LP_variable_cutoff.c
new file mode 100644 (file)
index 0000000..87feef5
--- /dev/null
@@ -0,0 +1,191 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+/* \r
+\r
+    Elliptic/Cauer filters designed with 0.1 dB passband ripple, \r
+        80 dB minimum stopband attenuation, and\r
+        [0.95 : 0.15 : 0.35] normalized cut off frequencies.\r
+\r
+*/\r
+#include "SKP_Silk_main.h"\r
+\r
+#if SWITCH_TRANSITION_FILTERING\r
+\r
+/* Helper function, that interpolates the filter taps */\r
+SKP_INLINE void SKP_Silk_LP_interpolate_filter_taps( \r
+    SKP_int32           B_Q28[ TRANSITION_NB ], \r
+    SKP_int32           A_Q28[ TRANSITION_NA ],\r
+    const SKP_int       ind,\r
+    const SKP_int32     fac_Q16\r
+)\r
+{\r
+    SKP_int nb, na;\r
+\r
+    if( ind < TRANSITION_INT_NUM - 1 ) {\r
+        if( fac_Q16 > 0 ) {\r
+            if( fac_Q16 == SKP_SAT16( fac_Q16 ) ) { /* fac_Q16 is in range of a 16-bit int */\r
+                /* Piece-wise linear interpolation of B and A */\r
+                for( nb = 0; nb < TRANSITION_NB; nb++ ) {\r
+                    B_Q28[ nb ] = SKP_SMLAWB(\r
+                        SKP_Silk_Transition_LP_B_Q28[ ind     ][ nb ],\r
+                        SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -\r
+                        SKP_Silk_Transition_LP_B_Q28[ ind     ][ nb ],\r
+                        fac_Q16 );\r
+                }\r
+                for( na = 0; na < TRANSITION_NA; na++ ) {\r
+                    A_Q28[ na ] = SKP_SMLAWB(\r
+                        SKP_Silk_Transition_LP_A_Q28[ ind     ][ na ],\r
+                        SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -\r
+                        SKP_Silk_Transition_LP_A_Q28[ ind     ][ na ],\r
+                        fac_Q16 );\r
+                }\r
+            } else if( fac_Q16 == ( 1 << 15 ) ) { /* Neither fac_Q16 nor ( ( 1 << 16 ) - fac_Q16 ) is in range of a 16-bit int */\r
+\r
+                /* Piece-wise linear interpolation of B and A */\r
+                for( nb = 0; nb < TRANSITION_NB; nb++ ) {\r
+                    B_Q28[ nb ] = SKP_RSHIFT( \r
+                        SKP_Silk_Transition_LP_B_Q28[ ind     ][ nb ] +\r
+                        SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],\r
+                        1 );\r
+                }\r
+                for( na = 0; na < TRANSITION_NA; na++ ) {\r
+                    A_Q28[ na ] = SKP_RSHIFT( \r
+                        SKP_Silk_Transition_LP_A_Q28[ ind     ][ na ] + \r
+                        SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ], \r
+                        1 );\r
+                }\r
+            } else { /* ( ( 1 << 16 ) - fac_Q16 ) is in range of a 16-bit int */\r
+                \r
+                SKP_assert( ( ( 1 << 16 ) - fac_Q16 ) == SKP_SAT16( ( ( 1 << 16 ) - fac_Q16) ) );\r
+                /* Piece-wise linear interpolation of B and A */\r
+                for( nb = 0; nb < TRANSITION_NB; nb++ ) {\r
+                    B_Q28[ nb ] = SKP_SMLAWB(\r
+                        SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],\r
+                        SKP_Silk_Transition_LP_B_Q28[ ind     ][ nb ] -\r
+                        SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],\r
+                        ( 1 << 16 ) - fac_Q16 );\r
+                }\r
+                for( na = 0; na < TRANSITION_NA; na++ ) {\r
+                    A_Q28[ na ] = SKP_SMLAWB(\r
+                        SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ],\r
+                        SKP_Silk_Transition_LP_A_Q28[ ind     ][ na ] -\r
+                        SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ],\r
+                        ( 1 << 16 ) - fac_Q16 );\r
+                }\r
+            }\r
+        } else {\r
+            SKP_memcpy( B_Q28, SKP_Silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( SKP_int32 ) );\r
+            SKP_memcpy( A_Q28, SKP_Silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( SKP_int32 ) );\r
+        }\r
+    } else {\r
+        SKP_memcpy( B_Q28, SKP_Silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( SKP_int32 ) );\r
+        SKP_memcpy( A_Q28, SKP_Silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( SKP_int32 ) );\r
+    }\r
+}\r
+\r
+/* Low-pass filter with variable cutoff frequency based on  */\r
+/* piece-wise linear interpolation between elliptic filters */\r
+/* Start by setting psEncC->transition_frame_no = 1;            */\r
+/* Deactivate by setting psEncC->transition_frame_no = 0;   */\r
+void SKP_Silk_LP_variable_cutoff(\r
+    SKP_Silk_LP_state               *psLP,          /* I/O  LP filter state                     */\r
+    SKP_int16                       *out,           /* O    Low-pass filtered output signal     */\r
+    const SKP_int16                 *in,            /* I    Input signal                        */\r
+    const SKP_int                   frame_length    /* I    Frame length                        */\r
+)\r
+{\r
+    SKP_int32   B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ];\r
+    SKP_int     fac_Q16 = 0, ind = 0;\r
+\r
+    SKP_assert( psLP->transition_frame_no >= 0 );\r
+    SKP_assert( ( ( ( psLP->transition_frame_no <= TRANSITION_FRAMES_DOWN ) && ( psLP->mode == 0 ) ) || \r
+                  ( ( psLP->transition_frame_no <= TRANSITION_FRAMES_UP   ) && ( psLP->mode == 1 ) ) ) );\r
+\r
+    /* Interpolate filter coefficients if needed */\r
+    if( psLP->transition_frame_no > 0 ) {\r
+        if( psLP->mode == 0 ) {\r
+            if( psLP->transition_frame_no < TRANSITION_FRAMES_DOWN ) {\r
+                /* Calculate index and interpolation factor for interpolation */\r
+#if( TRANSITION_INT_STEPS_DOWN == 32 )\r
+                fac_Q16 = SKP_LSHIFT( psLP->transition_frame_no, 16 - 5 );\r
+#else\r
+                fac_Q16 = SKP_DIV32_16( SKP_LSHIFT( psLP->transition_frame_no, 16 ), TRANSITION_INT_STEPS_DOWN );\r
+#endif\r
+                ind      = SKP_RSHIFT( fac_Q16, 16 );\r
+                fac_Q16 -= SKP_LSHIFT( ind, 16 );\r
+\r
+                SKP_assert( ind >= 0 );\r
+                SKP_assert( ind < TRANSITION_INT_NUM );\r
+\r
+                /* Interpolate filter coefficients */\r
+                SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );\r
+\r
+                /* Increment transition frame number for next frame */\r
+                psLP->transition_frame_no++;\r
+\r
+            } else if( psLP->transition_frame_no == TRANSITION_FRAMES_DOWN ) {\r
+                /* End of transition phase */\r
+                SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, TRANSITION_INT_NUM - 1, 0 );\r
+            }\r
+        } else if( psLP->mode == 1 ) {\r
+            if( psLP->transition_frame_no < TRANSITION_FRAMES_UP ) {\r
+                /* Calculate index and interpolation factor for interpolation */\r
+#if( TRANSITION_INT_STEPS_UP == 64 )\r
+                fac_Q16 = SKP_LSHIFT( TRANSITION_FRAMES_UP - psLP->transition_frame_no, 16 - 6 );\r
+#else\r
+                fac_Q16 = SKP_DIV32_16( SKP_LSHIFT( TRANSITION_FRAMES_UP - psLP->transition_frame_no, 16 ), TRANSITION_INT_STEPS_UP );\r
+#endif\r
+                ind      = SKP_RSHIFT( fac_Q16, 16 );\r
+                fac_Q16 -= SKP_LSHIFT( ind, 16 );\r
+\r
+                SKP_assert( ind >= 0 );\r
+                SKP_assert( ind < TRANSITION_INT_NUM );\r
+\r
+                /* Interpolate filter coefficients */\r
+                SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );\r
+\r
+                /* Increment transition frame number for next frame */\r
+                psLP->transition_frame_no++;\r
+            \r
+            } else if( psLP->transition_frame_no == TRANSITION_FRAMES_UP ) {\r
+                /* End of transition phase */\r
+                SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, 0, 0 );\r
+            }\r
+        }\r
+    } \r
+    \r
+    if( psLP->transition_frame_no > 0 ) {\r
+        /* ARMA low-pass filtering */\r
+        SKP_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 );\r
+        SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psLP->In_LP_State, out, frame_length );\r
+    } else {\r
+        /* Instead of using the filter, copy input directly to output */\r
+        SKP_memcpy( out, in, frame_length * sizeof( SKP_int16 ) );\r
+    }\r
+}\r
+#endif\r
diff --git a/src/SKP_Silk_LSF_cos_table.c b/src/SKP_Silk_LSF_cos_table.c
new file mode 100644 (file)
index 0000000..099324f
--- /dev/null
@@ -0,0 +1,65 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_SigProc_FIX.h"\r
+\r
+// Q12 values (even)\r
+const SKP_int SKP_Silk_LSFCosTab_FIX_Q12[LSF_COS_TAB_SZ_FIX + 1] = {\r
+            8192,             8190,             8182,             8170,     \r
+            8152,             8130,             8104,             8072,     \r
+            8034,             7994,             7946,             7896,     \r
+            7840,             7778,             7714,             7644,     \r
+            7568,             7490,             7406,             7318,     \r
+            7226,             7128,             7026,             6922,     \r
+            6812,             6698,             6580,             6458,     \r
+            6332,             6204,             6070,             5934,     \r
+            5792,             5648,             5502,             5352,     \r
+            5198,             5040,             4880,             4718,     \r
+            4552,             4382,             4212,             4038,     \r
+            3862,             3684,             3502,             3320,     \r
+            3136,             2948,             2760,             2570,     \r
+            2378,             2186,             1990,             1794,     \r
+            1598,             1400,             1202,             1002,     \r
+             802,              602,              402,              202,     \r
+               0,             -202,             -402,             -602,     \r
+            -802,            -1002,            -1202,            -1400,     \r
+           -1598,            -1794,            -1990,            -2186,     \r
+           -2378,            -2570,            -2760,            -2948,     \r
+           -3136,            -3320,            -3502,            -3684,     \r
+           -3862,            -4038,            -4212,            -4382,     \r
+           -4552,            -4718,            -4880,            -5040,     \r
+           -5198,            -5352,            -5502,            -5648,     \r
+           -5792,            -5934,            -6070,            -6204,     \r
+           -6332,            -6458,            -6580,            -6698,     \r
+           -6812,            -6922,            -7026,            -7128,     \r
+           -7226,            -7318,            -7406,            -7490,     \r
+           -7568,            -7644,            -7714,            -7778,     \r
+           -7840,            -7896,            -7946,            -7994,     \r
+           -8034,            -8072,            -8104,            -8130,     \r
+           -8152,            -8170,            -8182,            -8190,     \r
+           -8192\r
+};\r
diff --git a/src/SKP_Silk_LTP_analysis_filter_FIX.c b/src/SKP_Silk_LTP_analysis_filter_FIX.c
new file mode 100644 (file)
index 0000000..af851c7
--- /dev/null
@@ -0,0 +1,85 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main_FIX.h"\r
+\r
+void SKP_Silk_LTP_analysis_filter_FIX(\r
+    SKP_int16       *LTP_res,                           /* O:   LTP residual signal of length NB_SUBFR * ( pre_length + subfr_length )  */\r
+    const SKP_int16 *x,                                 /* I:   Pointer to input signal with at least max( pitchL ) preceeding samples  */\r
+    const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ],/* I:   LTP_ORDER LTP coefficients for each NB_SUBFR subframe                   */\r
+    const SKP_int   pitchL[ NB_SUBFR ],                 /* I:   Pitch lag, one for each subframe                                        */\r
+    const SKP_int32 invGains_Qxx[ NB_SUBFR ],           /* I:   Inverse quantization gains, one for each subframe                       */\r
+    const SKP_int   Qxx,                                /* I:   Inverse quantization gains Q domain                                     */\r
+    const SKP_int   subfr_length,                       /* I:   Length of each subframe                                                 */\r
+    const SKP_int   pre_length                          /* I:   Length of the preceeding samples starting at &x[0] for each subframe    */\r
+)\r
+{\r
+    const SKP_int16 *x_ptr, *x_lag_ptr;\r
+    SKP_int16   Btmp_Q14[ LTP_ORDER ];\r
+    SKP_int16   *LTP_res_ptr;\r
+    SKP_int     k, i, j;\r
+    SKP_int32   LTP_est;\r
+\r
+    x_ptr = x;\r
+    LTP_res_ptr = LTP_res;\r
+    for( k = 0; k < NB_SUBFR; k++ ) {\r
+\r
+        x_lag_ptr = x_ptr - pitchL[ k ];\r
+        for( i = 0; i < LTP_ORDER; i++ ) {\r
+            Btmp_Q14[ i ] = LTPCoef_Q14[ k * LTP_ORDER + i ];\r
+        }\r
+\r
+        /* LTP analysis FIR filter */\r
+        for( i = 0; i < subfr_length + pre_length; i++ ) {\r
+            LTP_res_ptr[ i ] = x_ptr[ i ];\r
+            \r
+            /* Long-term prediction */\r
+            LTP_est = SKP_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] );\r
+            for( j = 1; j < LTP_ORDER; j++ ) {\r
+                LTP_est = SKP_SMLABB_ovflw( LTP_est, x_lag_ptr[ LTP_ORDER / 2 - j ], Btmp_Q14[ j ] );\r
+            }\r
+            LTP_est = SKP_RSHIFT_ROUND( LTP_est, 14 ); // round and -> Q0\r
+\r
+            /* Subtract long-term prediction */\r
+            LTP_res_ptr[ i ] = ( SKP_int16 )SKP_SAT16( ( SKP_int32 )x_ptr[ i ] - LTP_est );\r
+\r
+            /* Scale residual */\r
+            if( Qxx == 16 ) {\r
+                LTP_res_ptr[ i ] = SKP_SMULWB( invGains_Qxx[ k ], LTP_res_ptr[ i ] );\r
+            } else {\r
+                LTP_res_ptr[ i ] = ( SKP_int16 )SKP_CHECK_FIT16( SKP_RSHIFT64( SKP_SMULL( invGains_Qxx[ k ], LTP_res_ptr[ i ] ), Qxx ) );\r
+            }\r
+\r
+            x_lag_ptr++;\r
+        }\r
+\r
+        /* Update pointers */\r
+        LTP_res_ptr += subfr_length + pre_length; \r
+        x_ptr       += subfr_length;\r
+    }\r
+}\r
+\r
diff --git a/src/SKP_Silk_LTP_scale_ctrl_FIX.c b/src/SKP_Silk_LTP_scale_ctrl_FIX.c
new file mode 100644 (file)
index 0000000..4d69a8a
--- /dev/null
@@ -0,0 +1,81 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main_FIX.h"\r
+\r
+#define NB_THRESHOLDS           11\r
+\r
+/* Table containing trained thresholds for LTP scaling */\r
+static const SKP_int16 LTPScaleThresholds_Q15[ NB_THRESHOLDS ] = \r
+{\r
+    31129, 26214, 16384, 13107, 9830, 6554,\r
+     4915,  3276,  2621,  2458,    0\r
+};\r
+\r
+void SKP_Silk_LTP_scale_ctrl_FIX(\r
+    SKP_Silk_encoder_state_FIX      *psEnc,     /* I/O  encoder state FIX                           */\r
+    SKP_Silk_encoder_control_FIX    *psEncCtrl  /* I/O  encoder control FIX                         */\r
+)\r
+{\r
+    SKP_int round_loss, frames_per_packet;\r
+    SKP_int g_out_Q5, g_limit_Q15, thrld1_Q15, thrld2_Q15;\r
+\r
+    /* 1st order high-pass filter */\r
+    psEnc->HPLTPredCodGain_Q7 = SKP_max_int( psEncCtrl->LTPredCodGain_Q7 - psEnc->prevLTPredCodGain_Q7, 0 ) \r
+        + SKP_RSHIFT_ROUND( psEnc->HPLTPredCodGain_Q7, 1 );\r
+    \r
+    psEnc->prevLTPredCodGain_Q7 = psEncCtrl->LTPredCodGain_Q7;\r
+\r
+    /* combine input and filtered input */\r
+    g_out_Q5    = SKP_RSHIFT_ROUND( SKP_RSHIFT( psEncCtrl->LTPredCodGain_Q7, 1 ) + SKP_RSHIFT( psEnc->HPLTPredCodGain_Q7, 1 ), 3 );\r
+    g_limit_Q15 = SKP_Silk_sigm_Q15( g_out_Q5 - ( 3 << 5 ) ); /* mulitplid with 0.5 */\r
+            \r
+    /* Default is minimum scaling */\r
+    psEncCtrl->sCmn.LTP_scaleIndex = 0;\r
+\r
+    /* Round the loss measure to whole pct */\r
+    round_loss = ( SKP_int )psEnc->sCmn.PacketLoss_perc;\r
+\r
+    /* Only scale if first frame in packet 0% */\r
+    if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
+        \r
+        frames_per_packet = SKP_DIV32_16( psEnc->sCmn.PacketSize_ms, FRAME_LENGTH_MS );\r
+\r
+        round_loss += frames_per_packet - 1;\r
+        thrld1_Q15 = LTPScaleThresholds_Q15[ SKP_min_int( round_loss,     NB_THRESHOLDS - 1 ) ];\r
+        thrld2_Q15 = LTPScaleThresholds_Q15[ SKP_min_int( round_loss + 1, NB_THRESHOLDS - 1 ) ];\r
+    \r
+        if( g_limit_Q15 > thrld1_Q15 ) {\r
+            /* Maximum scaling */\r
+            psEncCtrl->sCmn.LTP_scaleIndex = 2;\r
+        } else if( g_limit_Q15 > thrld2_Q15 ) {\r
+            /* Medium scaling */\r
+            psEncCtrl->sCmn.LTP_scaleIndex = 1;\r
+        }\r
+    }\r
+    psEncCtrl->LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ psEncCtrl->sCmn.LTP_scaleIndex ];\r
+}\r
diff --git a/src/SKP_Silk_MA.c b/src/SKP_Silk_MA.c
new file mode 100644 (file)
index 0000000..cdfaca7
--- /dev/null
@@ -0,0 +1,232 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+/*                                                                      *\r
+ * SKP_Silk_MA.c                                                      *\r
+ *                                                                      *\r
+ * Variable order MA filter                                             *\r
+ *                                                                      *\r
+ * Copyright 2006 (c), Skype Limited                                    *\r
+ * Date: 060221                                                         *\r
+ *                                                                      */\r
+#include "SKP_Silk_SigProc_FIX.h"\r
+\r
+/* Variable order MA filter */\r
+void SKP_Silk_MA(\r
+    const SKP_int16      *in,            /* I:   input signal                                */\r
+    const SKP_int16      *B,             /* I:   MA coefficients, Q13 [order+1]              */\r
+    SKP_int32            *S,             /* I/O: state vector [order]                        */\r
+    SKP_int16            *out,           /* O:   output signal                               */\r
+    const SKP_int32      len,            /* I:   signal length                               */\r
+    const SKP_int32      order           /* I:   filter order                                */\r
+)\r
+{\r
+    SKP_int   k, d, in16;\r
+    SKP_int32 out32;\r
+    \r
+    for( k = 0; k < len; k++ ) {\r
+        in16 = in[ k ];\r
+        out32 = SKP_SMLABB( S[ 0 ], in16, B[ 0 ] );\r
+        out32 = SKP_RSHIFT_ROUND( out32, 13 );\r
+        \r
+        for( d = 1; d < order; d++ ) {\r
+            S[ d - 1 ] = SKP_SMLABB( S[ d ], in16, B[ d ] );\r
+        }\r
+        S[ order - 1 ] = SKP_SMULBB( in16, B[ order ] );\r
+\r
+        /* Limit */\r
+        out[ k ] = (SKP_int16)SKP_SAT16( out32 );\r
+    }\r
+}\r
+/* Variable order MA prediction error filter */\r
+void SKP_Silk_MA_Prediction(\r
+    const SKP_int16      *in,            /* I:   Input signal                                */\r
+    const SKP_int16      *B,             /* I:   MA prediction coefficients, Q12 [order]     */\r
+    SKP_int32            *S,             /* I/O: State vector [order]                        */\r
+    SKP_int16            *out,           /* O:   Output signal                               */\r
+    const SKP_int32      len,            /* I:   Signal length                               */\r
+    const SKP_int32      order           /* I:   Filter order                                */\r
+)\r
+{\r
+    SKP_int   k, d, in16;\r
+    SKP_int32 out32;\r
+    SKP_int32 B32;\r
+\r
+    if( ( order & 1 ) == 0 && (SKP_int32)( (SKP_int_ptr_size)B & 3 ) == 0 ) {\r
+        /* Even order and 4-byte aligned coefficient array */\r
+\r
+        /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the    */\r
+        /* SMLABB and SMLABT instructions. On a big-endian CPU the two int16 variables would be      */\r
+        /* loaded in reverse order and the code will give the wrong result. In that case swapping    */\r
+        /* the SMLABB and SMLABT instructions should solve the problem.                              */\r
+        for( k = 0; k < len; k++ ) {\r
+            in16 = in[ k ];\r
+            out32 = SKP_LSHIFT( in16, 12 ) - S[ 0 ];\r
+            out32 = SKP_RSHIFT_ROUND( out32, 12 );\r
+            \r
+            for( d = 0; d < order - 2; d += 2 ) {\r
+                B32 = *( (SKP_int32*)&B[ d ] );                /* read two coefficients at once */\r
+                S[ d ]     = SKP_SMLABB_ovflw( S[ d + 1 ], in16, B32 );\r
+                S[ d + 1 ] = SKP_SMLABT_ovflw( S[ d + 2 ], in16, B32 );\r
+            }\r
+            B32 = *( (SKP_int32*)&B[ d ] );                    /* read two coefficients at once */\r
+            S[ order - 2 ] = SKP_SMLABB_ovflw( S[ order - 1 ], in16, B32 );\r
+            S[ order - 1 ] = SKP_SMULBT( in16, B32 );\r
+\r
+            /* Limit */\r
+            out[ k ] = (SKP_int16)SKP_SAT16( out32 );\r
+        }\r
+    } else {\r
+        /* Odd order or not 4-byte aligned coefficient array */\r
+        for( k = 0; k < len; k++ ) {\r
+            in16 = in[ k ];\r
+            out32 = SKP_LSHIFT( in16, 12 ) - S[ 0 ];\r
+            out32 = SKP_RSHIFT_ROUND( out32, 12 );\r
+            \r
+            for( d = 0; d < order - 1; d++ ) {\r
+                S[ d ] = SKP_SMLABB_ovflw( S[ d + 1 ], in16, B[ d ] );\r
+            }\r
+            S[ order - 1 ] = SKP_SMULBB( in16, B[ order - 1 ] );\r
+\r
+            /* Limit */\r
+            out[ k ] = (SKP_int16)SKP_SAT16( out32 );\r
+        }\r
+    }\r
+}\r
+\r
+void SKP_Silk_MA_Prediction_Q13(\r
+    const SKP_int16      *in,            /* I:   input signal                                */\r
+    const SKP_int16      *B,             /* I:   MA prediction coefficients, Q13 [order]     */\r
+    SKP_int32            *S,             /* I/O: state vector [order]                        */\r
+    SKP_int16            *out,           /* O:   output signal                               */\r
+    SKP_int32            len,            /* I:   signal length                               */\r
+    SKP_int32            order           /* I:   filter order                                */\r
+)\r
+{\r
+    SKP_int   k, d, in16;\r
+    SKP_int32 out32, B32;\r
+    \r
+    if( ( order & 1 ) == 0 && (SKP_int32)( (SKP_int_ptr_size)B & 3 ) == 0 ) {\r
+        /* Even order and 4-byte aligned coefficient array */\r
+        \r
+        /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the    */\r
+        /* SMLABB and SMLABT instructions. On a big-endian CPU the two int16 variables would be      */\r
+        /* loaded in reverse order and the code will give the wrong result. In that case swapping    */\r
+        /* the SMLABB and SMLABT instructions should solve the problem.                              */\r
+        for( k = 0; k < len; k++ ) {\r
+            in16 = in[ k ];\r
+            out32 = SKP_LSHIFT( in16, 13 ) - S[ 0 ];\r
+            out32 = SKP_RSHIFT_ROUND( out32, 13 );\r
+            \r
+            for( d = 0; d < order - 2; d += 2 ) {\r
+                B32 = *( (SKP_int32*)&B[ d ] );                /* read two coefficients at once */\r
+                S[ d ]     = SKP_SMLABB( S[ d + 1 ], in16, B32 );\r
+                S[ d + 1 ] = SKP_SMLABT( S[ d + 2 ], in16, B32 );\r
+            }\r
+            B32 = *( (SKP_int32*)&B[ d ] );                    /* read two coefficients at once */\r
+            S[ order - 2 ] = SKP_SMLABB( S[ order - 1 ], in16, B32 );\r
+            S[ order - 1 ] = SKP_SMULBT( in16, B32 );\r
+\r
+            /* Limit */\r
+            out[ k ] = (SKP_int16)SKP_SAT16( out32 );\r
+        }\r
+    } else {\r
+        /* Odd order or not 4-byte aligned coefficient array */\r
+        for( k = 0; k < len; k++ ) {\r
+            in16 = in[ k ];\r
+            out32 = SKP_LSHIFT( in16, 13 ) - S[ 0 ];\r
+            out32 = SKP_RSHIFT_ROUND( out32, 13 );\r
+            \r
+            for( d = 0; d < order - 1; d++ ) {\r
+                S[ d ] = SKP_SMLABB( S[ d + 1 ], in16, B[ d ] );\r
+            }\r
+            S[ order - 1 ] = SKP_SMULBB( in16, B[ order - 1 ] );\r
+\r
+            /* Limit */\r
+            out[ k ] = (SKP_int16)SKP_SAT16( out32 );\r
+        }\r
+    }\r
+}\r
+/* Variable order MA prediction error filter. */\r
+/* Inverse filter of SKP_Silk_LPC_synthesis_filter */\r
+void SKP_Silk_LPC_analysis_filter(\r
+    const SKP_int16      *in,            /* I:   Input signal                                */\r
+    const SKP_int16      *B,             /* I:   MA prediction coefficients, Q12 [order]     */\r
+    SKP_int16            *S,             /* I/O: State vector [order]                        */\r
+    SKP_int16            *out,           /* O:   Output signal                               */\r
+    const SKP_int32      len,            /* I:   Signal length                               */\r
+    const SKP_int32      Order           /* I:   Filter order                                */\r
+)\r
+{\r
+    SKP_int   k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );\r
+    SKP_int32 Btmp, B_align_Q12[ SigProc_MAX_ORDER_LPC >> 1 ], out32_Q12, out32;\r
+    SKP_int16 SA, SB;\r
+    /* Order must be even */\r
+    SKP_assert( 2 * Order_half == Order );\r
+\r
+    /* Combine two A_Q12 values and ensure 32-bit alignment */\r
+    for( k = 0; k < Order_half; k++ ) {\r
+        idx = SKP_SMULBB( 2, k );\r
+        B_align_Q12[ k ] = ( ( (SKP_int32)B[ idx ] ) & 0x0000ffff ) | SKP_LSHIFT( (SKP_int32)B[ idx + 1 ], 16 );\r
+    }\r
+\r
+    /* S[] values are in Q0 */\r
+    for( k = 0; k < len; k++ ) {\r
+        SA = S[ 0 ];\r
+        out32_Q12 = 0;\r
+        for( j = 0; j < ( Order_half - 1 ); j++ ) {\r
+            idx = SKP_SMULBB( 2, j ) + 1;\r
+            /* Multiply-add two prediction coefficients for each loop */\r
+            Btmp = B_align_Q12[ j ];\r
+            SB = S[ idx ];\r
+            S[ idx ] = SA;\r
+            out32_Q12 = SKP_SMLABB( out32_Q12, SA, Btmp );\r
+            out32_Q12 = SKP_SMLABT( out32_Q12, SB, Btmp );\r
+            SA = S[ idx + 1 ];\r
+            S[ idx + 1 ] = SB;\r
+        }\r
+\r
+        /* Unrolled loop: epilog */\r
+        Btmp = B_align_Q12[ Order_half - 1 ];\r
+        SB = S[ Order - 1 ];\r
+        S[ Order - 1 ] = SA;\r
+        out32_Q12 = SKP_SMLABB( out32_Q12, SA, Btmp );\r
+        out32_Q12 = SKP_SMLABT( out32_Q12, SB, Btmp );\r
+\r
+        /* Subtract prediction */\r
+        out32_Q12 = SKP_SUB_SAT32( SKP_LSHIFT( (SKP_int32)in[ k ], 12 ), out32_Q12 );\r
+\r
+        /* Scale to Q0 */\r
+        out32 = SKP_RSHIFT_ROUND( out32_Q12, 12 );\r
+\r
+        /* Saturate output */\r
+        out[ k ] = (SKP_int16)SKP_SAT16( out32 );\r
+\r
+        /* Move input line */\r
+        S[ 0 ] = in[ k ];\r
+    }\r
+}\r
diff --git a/src/SKP_Silk_NLSF2A.c b/src/SKP_Silk_NLSF2A.c
new file mode 100644 (file)
index 0000000..262b654
--- /dev/null
@@ -0,0 +1,150 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+/* conversion between prediction filter coefficients and LSFs   */\r
+/* order should be even                                         */\r
+/* a piecewise linear approximation maps LSF <-> cos(LSF)       */\r
+/* therefore the result is not accurate LSFs, but the two       */\r
+/* function are accurate inverses of each other                 */\r
+\r
+#include "SKP_Silk_SigProc_FIX.h"\r
+\r
+/* helper function for NLSF2A(..) */\r
+SKP_INLINE void SKP_Silk_NLSF2A_find_poly(\r
+    SKP_int32        *out,        /* o    intermediate polynomial, Q20            */\r
+    const SKP_int32    *cLSF,     /* i    vector of interleaved 2*cos(LSFs), Q20  */\r
+    SKP_int            dd         /* i    polynomial order (= 1/2 * filter order) */\r
+)\r
+{\r
+    SKP_int        k, n;\r
+    SKP_int32    ftmp;\r
+\r
+    out[0] = SKP_LSHIFT( 1, 20 );\r
+    out[1] = -cLSF[0];\r
+    for( k = 1; k < dd; k++ ) {\r
+        ftmp = cLSF[2*k];            // Q20\r
+        out[k+1] = SKP_LSHIFT( out[k-1], 1 ) - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[k] ), 20 );\r
+        for( n = k; n > 1; n-- ) {\r
+            out[n] += out[n-2] - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[n-1] ), 20 );\r
+        }\r
+        out[1] -= ftmp;\r
+    }\r
+}\r
+\r
+/* compute whitening filter coefficients from normalized line spectral frequencies */\r
+void SKP_Silk_NLSF2A(\r
+    SKP_int16       *a,               /* o    monic whitening filter coefficients in Q12,  [d]    */\r
+    const SKP_int    *NLSF,           /* i    normalized line spectral frequencies in Q15, [d]    */\r
+    const SKP_int    d                /* i    filter order (should be even)                       */\r
+)\r
+{\r
+    SKP_int k, i, dd;\r
+    SKP_int32 cos_LSF_Q20[SigProc_MAX_ORDER_LPC];\r
+    SKP_int32 P[SigProc_MAX_ORDER_LPC/2+1], Q[SigProc_MAX_ORDER_LPC/2+1];\r
+    SKP_int32 Ptmp, Qtmp;\r
+    SKP_int32 f_int;\r
+    SKP_int32 f_frac;\r
+    SKP_int32 cos_val, delta;\r
+    SKP_int32 a_int32[SigProc_MAX_ORDER_LPC];\r
+    SKP_int32 maxabs, absval, idx=0, sc_Q16; \r
+\r
+    SKP_assert(LSF_COS_TAB_SZ_FIX == 128);\r
+\r
+    /* convert LSFs to 2*cos(LSF(i)), using piecewise linear curve from table */\r
+    for( k = 0; k < d; k++ ) {\r
+        SKP_assert(NLSF[k] >= 0 );\r
+        SKP_assert(NLSF[k] <= 32767 );\r
+\r
+        /* f_int on a scale 0-127 (rounded down) */\r
+        f_int = SKP_RSHIFT( NLSF[k], 15 - 7 ); \r
+        \r
+        /* f_frac, range: 0..255 */\r
+        f_frac = NLSF[k] - SKP_LSHIFT( f_int, 15 - 7 ); \r
+\r
+        SKP_assert(f_int >= 0);\r
+        SKP_assert(f_int < LSF_COS_TAB_SZ_FIX );\r
+\r
+        /* Read start and end value from table */\r
+        cos_val = SKP_Silk_LSFCosTab_FIX_Q12[ f_int ];                /* Q12 */\r
+        delta   = SKP_Silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val;  /* Q12, with a range of 0..200 */\r
+\r
+        /* Linear interpolation */\r
+        cos_LSF_Q20[k] = SKP_LSHIFT( cos_val, 8 ) + SKP_MUL( delta, f_frac ); /* Q20 */\r
+    }\r
+    \r
+    dd = SKP_RSHIFT( d, 1 );\r
+\r
+    /* generate even and odd polynomials using convolution */\r
+    SKP_Silk_NLSF2A_find_poly( P, &cos_LSF_Q20[0], dd );\r
+    SKP_Silk_NLSF2A_find_poly( Q, &cos_LSF_Q20[1], dd );\r
+\r
+    /* convert even and odd polynomials to SKP_int32 Q12 filter coefs */\r
+    for( k = 0; k < dd; k++ ) {\r
+        Ptmp = P[k+1] + P[k];\r
+        Qtmp = Q[k+1] - Q[k];\r
+\r
+        /* the Ptmp and Qtmp values at this stage need to fit in int32 */\r
+\r
+        a_int32[k]     = -SKP_RSHIFT_ROUND( Ptmp + Qtmp, 9 ); /* Q20 -> Q12 */\r
+        a_int32[d-k-1] =  SKP_RSHIFT_ROUND( Qtmp - Ptmp, 9 ); /* Q20 -> Q12 */\r
+    }\r
+\r
+    /* Limit the maximum absolute value of the prediction coefficients */\r
+    for( i = 0; i < 10; i++ ) {\r
+        /* Find maximum absolute value and its index */\r
+        maxabs = 0;\r
+        for( k = 0; k < d; k++ ) {\r
+            absval = SKP_abs( a_int32[k] );\r
+            if( absval > maxabs ) {\r
+                maxabs = absval;\r
+                idx       = k;\r
+            }    \r
+        }\r
+    \r
+        if( maxabs > SKP_int16_MAX ) {    \r
+            /* Reduce magnitude of prediction coefficients */\r
+            sc_Q16 = 65470 - SKP_DIV32( SKP_MUL( 65470 >> 2, maxabs - SKP_int16_MAX ), \r
+                                        SKP_RSHIFT32( SKP_MUL( maxabs, idx + 1), 2 ) );\r
+            SKP_Silk_bwexpander_32( a_int32, d, sc_Q16 );\r
+        } else {\r
+            break;\r
+        }\r
+    }    \r
+\r
+    /* Reached the last iteration */\r
+    if( i == 10 ) {\r
+        SKP_assert(0);\r
+        for( k = 0; k < d; k++ ) {\r
+            a_int32[k] = SKP_SAT16( a_int32[k] ); \r
+        }\r
+    }\r
+\r
+    /* Return as SKP_int16 Q12 coefficients */\r
+    for( k = 0; k < d; k++ ) {\r
+        a[k] = (SKP_int16)a_int32[k];\r
+    }\r
+}\r
diff --git a/src/SKP_Silk_NLSF2A_stable.c b/src/SKP_Silk_NLSF2A_stable.c
new file mode 100644 (file)
index 0000000..05be911
--- /dev/null
@@ -0,0 +1,57 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main.h"\r
+\r
+/* Convert NLSF parameters to stable AR prediction filter coefficients */\r
+void SKP_Silk_NLSF2A_stable(\r
+    SKP_int16                       pAR_Q12[ MAX_LPC_ORDER ],   /* O    Stabilized AR coefs [LPC_order]     */ \r
+    const SKP_int                   pNLSF[ MAX_LPC_ORDER ],     /* I    NLSF vector         [LPC_order]     */\r
+    const SKP_int                   LPC_order                   /* I    LPC/LSF order                       */\r
+)\r
+{\r
+    SKP_int   i;\r
+    SKP_int32 invGain_Q30;\r
+\r
+    SKP_Silk_NLSF2A( pAR_Q12, pNLSF, LPC_order );\r
+\r
+    /* Ensure stable LPCs */\r
+    for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {\r
+        if( SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, pAR_Q12, LPC_order ) == 1 ) {\r
+            SKP_Silk_bwexpander( pAR_Q12, LPC_order, 65536 - SKP_SMULBB( 66, i ) ); /* 66_Q16 = 0.001 */\r
+        } else {\r
+            break;\r
+        }\r
+    }\r
+\r
+    /* Reached the last iteration */\r
+    if( i == MAX_LPC_STABILIZE_ITERATIONS ) {\r
+        for( i = 0; i < LPC_order; i++ ) {\r
+            pAR_Q12[ i ] = 0;\r
+        }\r
+    }\r
+}\r
diff --git a/src/SKP_Silk_NLSF_MSVQ_decode.c b/src/SKP_Silk_NLSF_MSVQ_decode.c
new file mode 100644 (file)
index 0000000..d5be46e
--- /dev/null
@@ -0,0 +1,91 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main.h"\r
+\r
+/* NLSF vector decoder */\r
+void SKP_Silk_NLSF_MSVQ_decode(\r
+    SKP_int                         *pNLSF_Q15,     /* O    Pointer to decoded output vector [LPC_ORDER x 1]    */\r
+    const SKP_Silk_NLSF_CB_struct   *psNLSF_CB,     /* I    Pointer to NLSF codebook struct                     */\r
+    const SKP_int                   *NLSFIndices,   /* I    Pointer to NLSF indices          [nStages x 1]      */\r
+    const SKP_int                   LPC_order       /* I    LPC order used                                      */\r
+) \r
+{\r
+    const SKP_int16 *pCB_element;\r
+          SKP_int    s;\r
+          SKP_int    i;\r
+\r
+    /* Check that each index is within valid range */\r
+    SKP_assert( 0 <= NLSFIndices[ 0 ] && NLSFIndices[ 0 ] < psNLSF_CB->CBStages[ 0 ].nVectors );\r
+\r
+    /* Point to the first vector element */\r
+    pCB_element = &psNLSF_CB->CBStages[ 0 ].CB_NLSF_Q15[ SKP_MUL( NLSFIndices[ 0 ], LPC_order ) ];\r
+\r
+    /* Initialize with the codebook vector from stage 0 */\r
+    for( i = 0; i < LPC_order; i++ ) {\r
+        pNLSF_Q15[ i ] = ( SKP_int )pCB_element[ i ];\r
+    }\r
+          \r
+    for( s = 1; s < psNLSF_CB->nStages; s++ ) {\r
+        /* Check that each index is within valid range */\r
+        SKP_assert( 0 <= NLSFIndices[ s ] && NLSFIndices[ s ] < psNLSF_CB->CBStages[ s ].nVectors );\r
+\r
+        if( LPC_order == 16 ) {\r
+            /* Point to the first vector element */\r
+            pCB_element = &psNLSF_CB->CBStages[ s ].CB_NLSF_Q15[ SKP_LSHIFT( NLSFIndices[ s ], 4 ) ];\r
+\r
+            /* Add the codebook vector from the current stage */\r
+            pNLSF_Q15[  0 ] += pCB_element[  0 ];\r
+            pNLSF_Q15[  1 ] += pCB_element[  1 ];\r
+            pNLSF_Q15[  2 ] += pCB_element[  2 ];\r
+            pNLSF_Q15[  3 ] += pCB_element[  3 ];\r
+            pNLSF_Q15[  4 ] += pCB_element[  4 ];\r
+            pNLSF_Q15[  5 ] += pCB_element[  5 ];\r
+            pNLSF_Q15[  6 ] += pCB_element[  6 ];\r
+            pNLSF_Q15[  7 ] += pCB_element[  7 ];\r
+            pNLSF_Q15[  8 ] += pCB_element[  8 ];\r
+            pNLSF_Q15[  9 ] += pCB_element[  9 ];\r
+            pNLSF_Q15[ 10 ] += pCB_element[ 10 ];\r
+            pNLSF_Q15[ 11 ] += pCB_element[ 11 ];\r
+            pNLSF_Q15[ 12 ] += pCB_element[ 12 ];\r
+            pNLSF_Q15[ 13 ] += pCB_element[ 13 ];\r
+            pNLSF_Q15[ 14 ] += pCB_element[ 14 ];\r
+            pNLSF_Q15[ 15 ] += pCB_element[ 15 ];\r
+        } else {\r
+            /* Point to the first vector element */\r
+            pCB_element = &psNLSF_CB->CBStages[ s ].CB_NLSF_Q15[ SKP_SMULBB( NLSFIndices[ s ], LPC_order ) ];\r
+\r
+            /* Add the codebook vector from the current stage */\r
+            for( i = 0; i < LPC_order; i++ ) {\r
+                pNLSF_Q15[ i ] += pCB_element[ i ];\r
+            }\r
+        }\r
+    }\r
+\r
+    /* NLSF stabilization */\r
+    SKP_Silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->NDeltaMin_Q15, LPC_order );\r
+}\r
diff --git a/src/SKP_Silk_NLSF_MSVQ_encode_FIX.c b/src/SKP_Silk_NLSF_MSVQ_encode_FIX.c
new file mode 100644 (file)
index 0000000..ba92556
--- /dev/null
@@ -0,0 +1,231 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main_FIX.h"\r
+\r
+/***********************/\r
+/* NLSF vector encoder */\r
+/***********************/\r
+void SKP_Silk_NLSF_MSVQ_encode_FIX(\r
+          SKP_int                   *NLSFIndices,           /* O    Codebook path vector [ CB_STAGES ]      */\r
+          SKP_int                   *pNLSF_Q15,             /* I/O  Quantized NLSF vector [ LPC_ORDER ]     */\r
+    const SKP_Silk_NLSF_CB_struct   *psNLSF_CB,             /* I    Codebook object                         */\r
+    const SKP_int                   *pNLSF_q_Q15_prev,      /* I    Prev. quantized NLSF vector [LPC_ORDER] */\r
+    const SKP_int                   *pW_Q6,                 /* I    NLSF weight vector [ LPC_ORDER ]        */\r
+    const SKP_int                   NLSF_mu_Q15,            /* I    Rate weight for the RD optimization     */\r
+    const SKP_int                   NLSF_mu_fluc_red_Q16,   /* I    Fluctuation reduction error weight      */\r
+    const SKP_int                   NLSF_MSVQ_Survivors,    /* I    Max survivors from each stage           */\r
+    const SKP_int                   LPC_order,              /* I    LPC order                               */\r
+    const SKP_int                   deactivate_fluc_red     /* I    Deactivate fluctuation reduction        */\r
+)\r
+{\r
+    SKP_int     i, s, k, cur_survivors = 0, prev_survivors, input_index, cb_index, bestIndex;\r
+    SKP_int32   rateDistThreshold_Q18;\r
+    SKP_int     pNLSF_in_Q15[ MAX_LPC_ORDER ];\r
+#if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 1 )\r
+    SKP_int32   se_Q15, wsse_Q20, bestRateDist_Q20;\r
+#endif\r
+\r
+#if( LOW_COMPLEXITY_ONLY == 1 )\r
+    SKP_int32   pRateDist_Q18[  NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE ];\r
+    SKP_int32   pRate_Q5[       MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ];\r
+    SKP_int32   pRate_new_Q5[   MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ];\r
+    SKP_int     pTempIndices[   MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ];\r
+    SKP_int     pPath[          MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_CB_STAGES ];\r
+    SKP_int     pPath_new[      MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_CB_STAGES ];\r
+    SKP_int     pRes_Q15[       MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * MAX_LPC_ORDER ];\r
+    SKP_int     pRes_new_Q15[   MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * MAX_LPC_ORDER ];\r
+#else\r
+    SKP_int32   pRateDist_Q18[  NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED ];\r
+    SKP_int32   pRate_Q5[       MAX_NLSF_MSVQ_SURVIVORS ];\r
+    SKP_int32   pRate_new_Q5[   MAX_NLSF_MSVQ_SURVIVORS ];\r
+    SKP_int     pTempIndices[   MAX_NLSF_MSVQ_SURVIVORS ];\r
+    SKP_int     pPath[          MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_CB_STAGES ];\r
+    SKP_int     pPath_new[      MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_CB_STAGES ];\r
+    SKP_int     pRes_Q15[       MAX_NLSF_MSVQ_SURVIVORS * MAX_LPC_ORDER ];\r
+    SKP_int     pRes_new_Q15[   MAX_NLSF_MSVQ_SURVIVORS * MAX_LPC_ORDER ];\r
+#endif\r
+\r
+    const SKP_int   *pConstInt;\r
+          SKP_int   *pInt;\r
+    const SKP_int16 *pCB_element;\r
+    const SKP_Silk_NLSF_CBS *pCurrentCBStage;\r
+\r
+    SKP_assert( NLSF_MSVQ_Survivors <= MAX_NLSF_MSVQ_SURVIVORS );\r
+    SKP_assert( ( LOW_COMPLEXITY_ONLY == 0 ) || ( NLSF_MSVQ_Survivors <= MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ) );\r
+\r
+\r
+\r
+    /* Copy the input vector */\r
+    SKP_memcpy( pNLSF_in_Q15, pNLSF_Q15, LPC_order * sizeof( SKP_int ) );\r
+\r
+    /****************************************************/\r
+    /* Tree search for the multi-stage vector quantizer */\r
+    /****************************************************/\r
+\r
+    /* Clear accumulated rates */\r
+    SKP_memset( pRate_Q5, 0, NLSF_MSVQ_Survivors * sizeof( SKP_int32 ) );\r
+    \r
+    /* Copy NLSFs into residual signal vector */\r
+    for( i = 0; i < LPC_order; i++ ) {\r
+        pRes_Q15[ i ] = pNLSF_Q15[ i ];\r
+    }\r
+\r
+    /* Set first stage values */\r
+    prev_survivors = 1;\r
+\r
+    /* Loop over all stages */\r
+    for( s = 0; s < psNLSF_CB->nStages; s++ ) {\r
+\r
+        /* Set a pointer to the current stage codebook */\r
+        pCurrentCBStage = &psNLSF_CB->CBStages[ s ];\r
+\r
+        /* Calculate the number of survivors in the current stage */\r
+        cur_survivors = SKP_min_32( NLSF_MSVQ_Survivors, SKP_SMULBB( prev_survivors, pCurrentCBStage->nVectors ) );\r
+\r
+#if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 0 )\r
+        /* Find a single best survivor in the last stage, if we */\r
+        /* do not need candidates for fluctuation reduction     */\r
+        if( s == psNLSF_CB->nStages - 1 ) {\r
+            cur_survivors = 1;\r
+        }\r
+#endif\r
+\r
+        /* Nearest neighbor clustering for multiple input data vectors */\r
+        SKP_Silk_NLSF_VQ_rate_distortion_FIX( pRateDist_Q18, pCurrentCBStage, pRes_Q15, pW_Q6, \r
+            pRate_Q5, NLSF_mu_Q15, prev_survivors, LPC_order );\r
+\r
+        /* Sort the rate-distortion errors */\r
+        SKP_Silk_insertion_sort_increasing( pRateDist_Q18, pTempIndices, \r
+            prev_survivors * pCurrentCBStage->nVectors, cur_survivors );\r
+\r
+        /* Discard survivors with rate-distortion values too far above the best one */\r
+        if( pRateDist_Q18[ 0 ] < SKP_int32_MAX / NLSF_MSVQ_SURV_MAX_REL_RD ) {\r
+            rateDistThreshold_Q18 = SKP_MUL( NLSF_MSVQ_SURV_MAX_REL_RD, pRateDist_Q18[ 0 ] );\r
+            while( pRateDist_Q18[ cur_survivors - 1 ] > rateDistThreshold_Q18 && cur_survivors > 1 ) {\r
+                cur_survivors--;\r
+            }\r
+        }\r
+        /* Update accumulated codebook contributions for the 'cur_survivors' best codebook indices */\r
+        for( k = 0; k < cur_survivors; k++ ) { \r
+            if( s > 0 ) {\r
+                /* Find the indices of the input and the codebook vector */\r
+                if( pCurrentCBStage->nVectors == 8 ) {\r
+                    input_index = SKP_RSHIFT( pTempIndices[ k ], 3 );\r
+                    cb_index    = pTempIndices[ k ] & 7;\r
+                } else {\r
+                    input_index = SKP_DIV32_16( pTempIndices[ k ], pCurrentCBStage->nVectors );  \r
+                    cb_index    = pTempIndices[ k ] - SKP_SMULBB( input_index, pCurrentCBStage->nVectors );\r
+                }\r
+            } else {\r
+                /* Find the indices of the input and the codebook vector */\r
+                input_index = 0;\r
+                cb_index    = pTempIndices[ k ];\r
+            }\r
+\r
+            /* Subtract new contribution from the previous residual vector for each of 'cur_survivors' */\r
+            pConstInt   = &pRes_Q15[ SKP_SMULBB( input_index, LPC_order ) ];\r
+            pCB_element = &pCurrentCBStage->CB_NLSF_Q15[ SKP_SMULBB( cb_index, LPC_order ) ];\r
+            pInt        = &pRes_new_Q15[ SKP_SMULBB( k, LPC_order ) ];\r
+            for( i = 0; i < LPC_order; i++ ) {\r
+                pInt[ i ] = pConstInt[ i ] - ( SKP_int )pCB_element[ i ];\r
+            }\r
+\r
+            /* Update accumulated rate for stage 1 to the current */\r
+            pRate_new_Q5[ k ] = pRate_Q5[ input_index ] + pCurrentCBStage->Rates_Q5[ cb_index ];\r
+\r
+            /* Copy paths from previous matrix, starting with the best path */\r
+            pConstInt = &pPath[ SKP_SMULBB( input_index, psNLSF_CB->nStages ) ];\r
+            pInt      = &pPath_new[ SKP_SMULBB( k, psNLSF_CB->nStages ) ];\r
+            for( i = 0; i < s; i++ ) {\r
+                pInt[ i ] = pConstInt[ i ];\r
+            }\r
+            /* Write the current stage indices for the 'cur_survivors' to the best path matrix */\r
+            pInt[ s ] = cb_index;\r
+        }\r
+\r
+        if( s < psNLSF_CB->nStages - 1 ) {\r
+            /* Copy NLSF residual matrix for next stage */\r
+            SKP_memcpy( pRes_Q15, pRes_new_Q15, SKP_SMULBB( cur_survivors, LPC_order ) * sizeof( SKP_int ) );\r
+\r
+            /* Copy rate vector for next stage */\r
+            SKP_memcpy( pRate_Q5, pRate_new_Q5, cur_survivors * sizeof( SKP_int32 ) );\r
+\r
+            /* Copy best path matrix for next stage */\r
+            SKP_memcpy( pPath, pPath_new, SKP_SMULBB( cur_survivors, psNLSF_CB->nStages ) * sizeof( SKP_int ) );\r
+        }\r
+\r
+        prev_survivors = cur_survivors;\r
+    }\r
+\r
+    /* (Preliminary) index of the best survivor, later to be decoded */\r
+    bestIndex = 0;\r
+\r
+#if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 1 )\r
+    /******************************/\r
+    /* NLSF fluctuation reduction */\r
+    /******************************/\r
+    if( deactivate_fluc_red != 1 ) {\r
+    \r
+        /* Search among all survivors, now taking also weighted fluctuation errors into account */\r
+        bestRateDist_Q20 = SKP_int32_MAX;\r
+        for( s = 0; s < cur_survivors; s++ ) {\r
+            /* Decode survivor to compare with previous quantized NLSF vector */\r
+            SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, &pPath_new[ SKP_SMULBB( s, psNLSF_CB->nStages ) ], LPC_order );\r
+\r
+            /* Compare decoded NLSF vector with the previously quantized vector */ \r
+            wsse_Q20 = 0;\r
+            for( i = 0; i < LPC_order; i += 2 ) {\r
+                /* Compute weighted squared quantization error for index i */\r
+                se_Q15 = pNLSF_Q15[ i ] - pNLSF_q_Q15_prev[ i ]; // range: [ -32767 : 32767 ]\r
+                wsse_Q20 = SKP_SMLAWB( wsse_Q20, SKP_SMULBB( se_Q15, se_Q15 ), pW_Q6[ i ] );\r
+\r
+                /* Compute weighted squared quantization error for index i + 1 */\r
+                se_Q15 = pNLSF_Q15[ i + 1 ] - pNLSF_q_Q15_prev[ i + 1 ]; // range: [ -32767 : 32767 ]\r
+                wsse_Q20 = SKP_SMLAWB( wsse_Q20, SKP_SMULBB( se_Q15, se_Q15 ), pW_Q6[ i + 1 ] );\r
+            }\r
+            SKP_assert( wsse_Q20 >= 0 );\r
+\r
+            /* Add the fluctuation reduction penalty to the rate distortion error */\r
+            wsse_Q20 = SKP_ADD_POS_SAT32( pRateDist_Q18[ s ], SKP_SMULWB( wsse_Q20, NLSF_mu_fluc_red_Q16 ) );\r
+\r
+            /* Keep index of best survivor */\r
+            if( wsse_Q20 < bestRateDist_Q20 ) {\r
+                bestRateDist_Q20 = wsse_Q20;\r
+                bestIndex = s;\r
+            }\r
+        }\r
+    }\r
+#endif\r
+\r
+    /* Copy best path to output argument */\r
+    SKP_memcpy( NLSFIndices, &pPath_new[ SKP_SMULBB( bestIndex, psNLSF_CB->nStages ) ], psNLSF_CB->nStages * sizeof( SKP_int ) );\r
+\r
+    /* Decode and stabilize the best survivor */\r
+    SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, NLSFIndices, LPC_order );\r
+\r
+}\r
diff --git a/src/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c b/src/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c
new file mode 100644 (file)
index 0000000..09e2bc7
--- /dev/null
@@ -0,0 +1,61 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main_FIX.h"\r
+\r
+/* Rate-Distortion calculations for multiple input data vectors */\r
+void SKP_Silk_NLSF_VQ_rate_distortion_FIX(\r
+    SKP_int32                       *pRD_Q20,           /* O    Rate-distortion values [psNLSF_CBS->nVectors*N] */\r
+    const SKP_Silk_NLSF_CBS         *psNLSF_CBS,        /* I    NLSF codebook stage struct                      */\r
+    const SKP_int                   *in_Q15,            /* I    Input vectors to be quantized                   */\r
+    const SKP_int                   *w_Q6,              /* I    Weight vector                                   */\r
+    const SKP_int32                 *rate_acc_Q5,       /* I    Accumulated rates from previous stage           */\r
+    const SKP_int                   mu_Q15,             /* I    Weight between weighted error and rate          */\r
+    const SKP_int                   N,                  /* I    Number of input vectors to be quantized         */\r
+    const SKP_int                   LPC_order           /* I    LPC order                                       */\r
+)\r
+{\r
+    SKP_int   i, n;\r
+    SKP_int32 *pRD_vec_Q20;\r
+\r
+    /* Compute weighted quantization errors for all input vectors over one codebook stage */\r
+    SKP_Silk_NLSF_VQ_sum_error_FIX( pRD_Q20, in_Q15, w_Q6, psNLSF_CBS->CB_NLSF_Q15, \r
+        N, psNLSF_CBS->nVectors, LPC_order );\r
+\r
+    /* Loop over input vectors */\r
+    pRD_vec_Q20 = pRD_Q20;\r
+    for( n = 0; n < N; n++ ) {\r
+        /* Add rate cost to error for each codebook vector */\r
+        for( i = 0; i < psNLSF_CBS->nVectors; i++ ) {\r
+            SKP_assert( rate_acc_Q5[ n ] + psNLSF_CBS->Rates_Q5[ i ] >= 0 );\r
+            SKP_assert( rate_acc_Q5[ n ] + psNLSF_CBS->Rates_Q5[ i ] <= SKP_int16_MAX );\r
+            pRD_vec_Q20[ i ] = SKP_SMLABB( pRD_vec_Q20[ i ], rate_acc_Q5[ n ] + psNLSF_CBS->Rates_Q5[ i ], mu_Q15 );\r
+            SKP_assert( pRD_vec_Q20[ i ] >= 0 );\r
+        }\r
+        pRD_vec_Q20 += psNLSF_CBS->nVectors;\r
+    }\r
+}\r
diff --git a/src/SKP_Silk_NLSF_VQ_sum_error_FIX.c b/src/SKP_Silk_NLSF_VQ_sum_error_FIX.c
new file mode 100644 (file)
index 0000000..7a2171c
--- /dev/null
@@ -0,0 +1,79 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main_FIX.h"\r
+\r
+/* Compute weighted quantization errors for an LPC_order element input vector, over one codebook stage */\r
+void SKP_Silk_NLSF_VQ_sum_error_FIX(\r
+    SKP_int32                       *err_Q20,           /* O    Weighted quantization errors  [N*K]         */\r
+    const SKP_int                   *in_Q15,            /* I    Input vectors to be quantized [N*LPC_order] */\r
+    const SKP_int                   *w_Q6,              /* I    Weighting vectors             [N*LPC_order] */\r
+    const SKP_int16                 *pCB_Q15,           /* I    Codebook vectors              [K*LPC_order] */\r
+    const SKP_int                   N,                  /* I    Number of input vectors                     */\r
+    const SKP_int                   K,                  /* I    Number of codebook vectors                  */\r
+    const SKP_int                   LPC_order           /* I    Number of LPCs                              */\r
+)\r
+{\r
+    SKP_int         i, n, m;\r
+    SKP_int32       diff_Q15, sum_error, Wtmp_Q6;\r
+    SKP_int32       Wcpy_Q6[ MAX_LPC_ORDER / 2 ];\r
+    const SKP_int16 *cb_vec_Q15;\r
+\r
+    SKP_assert( LPC_order <= 16 );\r
+    SKP_assert( ( LPC_order & 1 ) == 0 );\r
+\r
+    /* Copy to local stack and pack two weights per int32 */\r
+    for( m = 0; m < SKP_RSHIFT( LPC_order, 1 ); m++ ) {\r
+        Wcpy_Q6[ m ] = w_Q6[ 2 * m ] | SKP_LSHIFT( ( SKP_int32 )w_Q6[ 2 * m + 1 ], 16 );\r
+    }\r
+\r
+    /* Loop over input vectors */\r
+    for( n = 0; n < N; n++ ) {\r
+        /* Loop over codebook */\r
+        cb_vec_Q15 = pCB_Q15;\r
+        for( i = 0; i < K; i++ ) {\r
+            sum_error = 0;\r
+            for( m = 0; m < LPC_order; m += 2 ) {\r
+                /* Get two weights packed in an int32 */\r
+                Wtmp_Q6 = Wcpy_Q6[ SKP_RSHIFT( m, 1 ) ];\r
+\r
+                /* Compute weighted squared quantization error for index m */\r
+                diff_Q15 = in_Q15[ m ] - *cb_vec_Q15++; // range: [ -32767 : 32767 ]\r
+                sum_error = SKP_SMLAWB( sum_error, SKP_SMULBB( diff_Q15, diff_Q15 ), Wtmp_Q6 );\r
+\r
+                /* Compute weighted squared quantization error for index m + 1 */\r
+                diff_Q15 = in_Q15[m + 1] - *cb_vec_Q15++; // range: [ -32767 : 32767 ]\r
+                sum_error = SKP_SMLAWT( sum_error, SKP_SMULBB( diff_Q15, diff_Q15 ), Wtmp_Q6 );\r
+            }\r
+            SKP_assert( sum_error >= 0 );\r
+            err_Q20[ i ] = sum_error;\r
+        }\r
+        err_Q20 += K;\r
+        in_Q15 += LPC_order;\r
+    }\r
+}\r
+\r
diff --git a/src/SKP_Silk_NLSF_VQ_weights_laroia.c b/src/SKP_Silk_NLSF_VQ_weights_laroia.c
new file mode 100644 (file)
index 0000000..e7f4618
--- /dev/null
@@ -0,0 +1,78 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_SigProc_FIX.h"\r
+\r
+/* \r
+R. Laroia, N. Phamdo and N. Farvardin, "Robust and Efficient Quantization of Speech LSP\r
+Parameters Using Structured Vector Quantization", Proc. IEEE Int. Conf. Acoust., Speech,\r
+Signal Processing, pp. 641-644, 1991.\r
+*/\r
+\r
+#define Q_OUT                       6\r
+\r
+/* Laroia low complexity NLSF weights */\r
+void SKP_Silk_NLSF_VQ_weights_laroia(\r
+    SKP_int             *pNLSFW_Q6,         /* O: Pointer to input vector weights           [D x 1]     */\r
+    const SKP_int       *pNLSF_Q15,         /* I: Pointer to input vector                   [D x 1]     */ \r
+    const SKP_int       D                   /* I: Input vector dimension (even)                         */\r
+)\r
+{\r
+    SKP_int   k;\r
+    SKP_int32 tmp1_int, tmp2_int;\r
+    \r
+    /* Check that we are guaranteed to end up within the required range */\r
+    SKP_assert( D > 0 );\r
+    SKP_assert( ( D & 1 ) == 0 );\r
+    \r
+    /* First value */\r
+    tmp1_int = SKP_max_int( pNLSF_Q15[ 0 ], 1 );\r
+    tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );\r
+    tmp2_int = SKP_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], 1 );\r
+    tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int );\r
+    pNLSFW_Q6[ 0 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );\r
+    SKP_assert( pNLSFW_Q6[ 0 ] > 0 );\r
+    \r
+    /* Main loop */\r
+    for( k = 1; k < D - 1; k += 2 ) {\r
+        tmp1_int = SKP_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], 1 );\r
+        tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );\r
+        pNLSFW_Q6[ k ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );\r
+        SKP_assert( pNLSFW_Q6[ k ] > 0 );\r
+\r
+        tmp2_int = SKP_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], 1 );\r
+        tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int );\r
+        pNLSFW_Q6[ k + 1 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );\r
+        SKP_assert( pNLSFW_Q6[ k + 1 ] > 0 );\r
+    }\r
+    \r
+    /* Last value */\r
+    tmp1_int = SKP_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], 1 );\r
+    tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );\r
+    pNLSFW_Q6[ D - 1 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );\r
+    SKP_assert( pNLSFW_Q6[ D - 1 ] > 0 );\r
+}\r
diff --git a/src/SKP_Silk_NLSF_stabilize.c b/src/SKP_Silk_NLSF_stabilize.c
new file mode 100644 (file)
index 0000000..7932586
--- /dev/null
@@ -0,0 +1,154 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+/* NLSF stabilizer:                                         */\r
+/*                                                          */\r
+/* - Moves NLSFs futher apart if they are too close         */\r
+/* - Moves NLSFs away from borders if they are too close    */\r
+/* - High effort to achieve a modification with minimum     */\r
+/*     Euclidean distance to input vector                   */\r
+/* - Output are sorted NLSF coefficients                    */\r
+/*                                                          */\r
+#include "SKP_Silk_SigProc_FIX.h"\r
+\r
+/* Constant Definitions */\r
+#define MAX_LOOPS        20\r
+\r
+/* NLSF stabilizer, for a single input data vector */\r
+void SKP_Silk_NLSF_stabilize(\r
+          SKP_int    *NLSF_Q15,            /* I/O:  Unstable/stabilized normalized LSF vector in Q15 [L]                    */\r
+    const SKP_int    *NDeltaMin_Q15,       /* I:    Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */\r
+    const SKP_int     L                    /* I:    Number of NLSF parameters in the input vector                           */\r
+)\r
+{\r
+    SKP_int        center_freq_Q15, diff_Q15, min_center_Q15, max_center_Q15;\r
+    SKP_int32    min_diff_Q15;\r
+    SKP_int        loops;\r
+    SKP_int        i, I=0, k;\r
+\r
+    /* This is necessary to ensure an output within range of a SKP_int16 */\r
+    SKP_assert( NDeltaMin_Q15[L] >= 1 );\r
+\r
+    for( loops = 0; loops < MAX_LOOPS; loops++ ) {\r
+        /**************************/\r
+        /* Find smallest distance */\r
+        /**************************/\r
+        /* First element */\r
+        min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0];\r
+        I = 0;\r
+        /* Middle elements */\r
+        for( i = 1; i <= L-1; i++ ) {\r
+            diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] );\r
+            if( diff_Q15 < min_diff_Q15 ) {\r
+                min_diff_Q15 = diff_Q15;\r
+                I = i;\r
+            }\r
+        }\r
+        /* Last element */\r
+        diff_Q15 = (1<<15) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] );\r
+        if( diff_Q15 < min_diff_Q15 ) {\r
+            min_diff_Q15 = diff_Q15;\r
+            I = L;\r
+        }\r
+\r
+        /***************************************************/\r
+        /* Now check if the smallest distance non-negative */\r
+        /***************************************************/\r
+        if (min_diff_Q15 >= 0) {\r
+            return;\r
+        }\r
+\r
+        if( I == 0 ) {\r
+            /* Move away from lower limit */\r
+            NLSF_Q15[0] = NDeltaMin_Q15[0];\r
+        \r
+        } else if( I == L) {\r
+            /* Move away from higher limit */\r
+            NLSF_Q15[L-1] = (1<<15) - NDeltaMin_Q15[L];\r
+        \r
+        } else {\r
+            /* Find the lower extreme for the location of the current center frequency */ \r
+            min_center_Q15 = 0;\r
+            for( k = 0; k < I; k++ ) {\r
+                min_center_Q15 += NDeltaMin_Q15[k];\r
+            }\r
+            min_center_Q15 += SKP_RSHIFT( NDeltaMin_Q15[I], 1 );\r
+\r
+            /* Find the upper extreme for the location of the current center frequency */\r
+            max_center_Q15 = (1<<15);\r
+            for( k = L; k > I; k-- ) {\r
+                max_center_Q15 -= NDeltaMin_Q15[k];\r
+            }\r
+            max_center_Q15 -= ( NDeltaMin_Q15[I] - SKP_RSHIFT( NDeltaMin_Q15[I], 1 ) );\r
+\r
+            /* Move apart, sorted by value, keeping the same center frequency */\r
+            center_freq_Q15 = SKP_LIMIT( SKP_RSHIFT_ROUND( (SKP_int32)NLSF_Q15[I-1] + (SKP_int32)NLSF_Q15[I], 1 ),\r
+                min_center_Q15, max_center_Q15 );\r
+            NLSF_Q15[I-1] = center_freq_Q15 - SKP_RSHIFT( NDeltaMin_Q15[I], 1 );\r
+            NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I];\r
+        }\r
+    }\r
+\r
+    /* Safe and simple fall back method, which is less ideal than the above */\r
+    if( loops == MAX_LOOPS )\r
+    {\r
+        /* Insertion sort (fast for already almost sorted arrays):   */\r
+        /* Best case:  O(n)   for an already sorted array            */\r
+        /* Worst case: O(n^2) for an inversely sorted array          */\r
+        SKP_Silk_insertion_sort_increasing_all_values(&NLSF_Q15[0], L);\r
+            \r
+        /* First NLSF should be no less than NDeltaMin[0] */\r
+        NLSF_Q15[0] = SKP_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] );\r
+        \r
+        /* Keep delta_min distance between the NLSFs */\r
+        for( i = 1; i < L; i++ )\r
+            NLSF_Q15[i] = SKP_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] );\r
+\r
+        /* Last NLSF should be no higher than 1 - NDeltaMin[L] */\r
+        NLSF_Q15[L-1] = SKP_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );\r
+\r
+        /* Keep NDeltaMin distance between the NLSFs */\r
+        for( i = L-2; i >= 0; i-- ) \r
+            NLSF_Q15[i] = SKP_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] );\r
+    }\r
+}\r
+\r
+/* NLSF stabilizer, over multiple input column data vectors */\r
+void SKP_Silk_NLSF_stabilize_multi(\r
+          SKP_int        *NLSF_Q15,        /* I/O:  Unstable/stabilized normalized LSF vectors in Q15 [LxN]                 */\r
+    const SKP_int        *NDeltaMin_Q15,   /* I:    Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */\r
+    const SKP_int         N,               /* I:    Number of input vectors to be stabilized                                */\r
+    const SKP_int         L                /* I:    NLSF vector dimension                                                   */\r
+)\r
+{\r
+    SKP_int n;\r
+    \r
+    /* loop over input data */\r
+    for( n = 0; n < N; n++ ) {\r
+        SKP_Silk_NLSF_stabilize( &NLSF_Q15[n * L], NDeltaMin_Q15, L );\r
+    }\r
+}\r
diff --git a/src/SKP_Silk_NSQ.c b/src/SKP_Silk_NSQ.c
new file mode 100644 (file)
index 0000000..19cb8ea
--- /dev/null
@@ -0,0 +1,446 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main.h"\r
+\r
+SKP_INLINE void SKP_Silk_nsq_scale_states(\r
+    SKP_Silk_nsq_state  *NSQ,               /* I/O NSQ state                        */\r
+    const SKP_int16     x[],                /* I input in Q0                        */\r
+    SKP_int32           x_sc_Q10[],         /* O input scaled with 1/Gain           */\r
+    SKP_int             length,             /* I length of input                    */\r
+    SKP_int16           sLTP[],             /* I re-whitened LTP state in Q0        */\r
+    SKP_int32           sLTP_Q16[],         /* O LTP state matching scaled input    */\r
+    SKP_int             subfr,              /* I subframe number                    */\r
+    const SKP_int       LTP_scale_Q14,      /* I                                    */\r
+    const SKP_int32     Gains_Q16[ NB_SUBFR ], /* I                                 */\r
+    const SKP_int       pitchL[ NB_SUBFR ]  /* I                                    */\r
+);\r
+\r
+SKP_INLINE void SKP_Silk_noise_shape_quantizer(\r
+    SKP_Silk_nsq_state  *NSQ,               /* I/O  NSQ state                       */\r
+    SKP_int             sigtype,            /* I    Signal type                     */\r
+    const SKP_int32     x_sc_Q10[],         /* I                                    */\r
+    SKP_int             q[],                /* O                                    */\r
+    SKP_int16           xq[],               /* O                                    */\r
+    SKP_int32           sLTP_Q16[],         /* I/O  LTP state                       */\r
+    const SKP_int16     a_Q12[],            /* I    Short term prediction coefs     */\r
+    const SKP_int16     b_Q14[],            /* I    Long term prediction coefs      */\r
+    const SKP_int16     AR_shp_Q13[],       /* I    Noise shaping AR coefs          */\r
+    SKP_int             lag,                /* I    Pitch lag                       */\r
+    SKP_int32           HarmShapeFIRPacked_Q14, /* I                                */\r
+    SKP_int             Tilt_Q14,           /* I    Spectral tilt                   */\r
+    SKP_int32           LF_shp_Q14,         /* I                                    */\r
+    SKP_int32           Gain_Q16,           /* I                                    */\r
+    SKP_int             Lambda_Q10,         /* I                                    */\r
+    SKP_int             offset_Q10,         /* I                                    */\r
+    SKP_int             length,             /* I    Input length                    */\r
+    SKP_int             shapingLPCOrder,    /* I    Noise shaping AR filter order   */\r
+    SKP_int             predictLPCOrder     /* I    Prediction filter order         */\r
+);\r
+\r
+void SKP_Silk_NSQ(\r
+    SKP_Silk_encoder_state          *psEncC,                                    /* I/O  Encoder State                       */\r
+    SKP_Silk_encoder_control        *psEncCtrlC,                                /* I    Encoder Control                     */\r
+    SKP_Silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                           */\r
+    const SKP_int16                 x[],                                        /* I    prefiltered input signal            */\r
+    SKP_int                         q[],                                        /* O    quantized qulse signal              */\r
+    const SKP_int                   LSFInterpFactor_Q2,                         /* I    LSF interpolation factor in Q2      */\r
+    const SKP_int16                 PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefficients  */\r
+    const SKP_int16                 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ],        /* I    Long term prediction coefficients   */\r
+    const SKP_int16                 AR2_Q13[ NB_SUBFR * SHAPE_LPC_ORDER_MAX ],  /* I                                        */\r
+    const SKP_int                   HarmShapeGain_Q14[ NB_SUBFR ],              /* I                                        */\r
+    const SKP_int                   Tilt_Q14[ NB_SUBFR ],                       /* I    Spectral tilt                       */\r
+    const SKP_int32                 LF_shp_Q14[ NB_SUBFR ],                     /* I                                        */\r
+    const SKP_int32                 Gains_Q16[ NB_SUBFR ],                      /* I                                        */\r
+    const SKP_int                   Lambda_Q10,                                 /* I                                        */\r
+    const SKP_int                   LTP_scale_Q14                               /* I    LTP state scaling                   */\r
+)\r
+{\r
+    SKP_int     k, lag, start_idx, subfr_length, LSF_interpolation_flag;\r
+    const SKP_int16 *A_Q12, *B_Q14, *AR_shp_Q13;\r
+    SKP_int16   *pxq;\r
+    SKP_int32   sLTP_Q16[ 2 * MAX_FRAME_LENGTH ];\r
+    SKP_int16   sLTP[     2 * MAX_FRAME_LENGTH ];\r
+    SKP_int32   HarmShapeFIRPacked_Q14;\r
+    SKP_int     offset_Q10;\r
+    SKP_int32   FiltState[ MAX_LPC_ORDER ];\r
+    SKP_int32   x_sc_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ];\r
+\r
+    subfr_length = psEncC->frame_length / NB_SUBFR;\r
+\r
+    NSQ->rand_seed  =  psEncCtrlC->Seed;\r
+    /* Set unvoiced lag to the previous one, overwrite later for voiced */\r
+    lag             = NSQ->lagPrev;\r
+\r
+    SKP_assert( NSQ->prev_inv_gain_Q16 != 0 );\r
+\r
+    offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEncCtrlC->sigtype ][ psEncCtrlC->QuantOffsetType ];\r
+\r
+    if( LSFInterpFactor_Q2 == ( 1 << 2 ) ) {\r
+        LSF_interpolation_flag = 0;\r
+    } else {\r
+        LSF_interpolation_flag = 1;\r
+    }\r
+\r
+    /* Setup pointers to start of sub frame */\r
+    NSQ->sLTP_shp_buf_idx = psEncC->frame_length;\r
+    NSQ->sLTP_buf_idx     = psEncC->frame_length;\r
+    pxq                   = &NSQ->xq[ psEncC->frame_length ];\r
+    for( k = 0; k < NB_SUBFR; k++ ) {\r
+        A_Q12      = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];\r
+        B_Q14      = &LTPCoef_Q14[ k * LTP_ORDER ];\r
+        AR_shp_Q13 = &AR2_Q13[     k * SHAPE_LPC_ORDER_MAX ];\r
+\r
+        /* Noise shape parameters */\r
+        SKP_assert( HarmShapeGain_Q14[ k ] >= 0 );\r
+        HarmShapeFIRPacked_Q14  =                        SKP_RSHIFT( HarmShapeGain_Q14[ k ], 2 );\r
+        HarmShapeFIRPacked_Q14 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );\r
+\r
+        if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {\r
+            /* Voiced */\r
+            lag = psEncCtrlC->pitchL[ k ];\r
+\r
+            NSQ->rewhite_flag = 0;\r
+            /* Re-whitening */\r
+            if( ( k & ( 3 - SKP_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {\r
+                /* Rewhiten with new A coefs */\r
+                \r
+                start_idx = psEncC->frame_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;\r
+                start_idx = SKP_LIMIT( start_idx, 0, psEncC->frame_length - psEncC->predictLPCOrder ); /* Limit */\r
+                \r
+                SKP_memset( FiltState, 0, psEncC->predictLPCOrder * sizeof( SKP_int32 ) );\r
+                SKP_Silk_MA_Prediction( &NSQ->xq[ start_idx + k * ( psEncC->frame_length >> 2 ) ], \r
+                    A_Q12, FiltState, sLTP + start_idx, psEncC->frame_length - start_idx, psEncC->predictLPCOrder );\r
+\r
+                NSQ->rewhite_flag = 1;\r
+                NSQ->sLTP_buf_idx = psEncC->frame_length;\r
+            }\r
+        }\r
+        \r
+        SKP_Silk_nsq_scale_states( NSQ, x, x_sc_Q10, psEncC->subfr_length, sLTP, \r
+            sLTP_Q16, k, LTP_scale_Q14, Gains_Q16, psEncCtrlC->pitchL );\r
+\r
+        SKP_Silk_noise_shape_quantizer( NSQ, psEncCtrlC->sigtype, x_sc_Q10, q, pxq, sLTP_Q16, A_Q12, B_Q14, \r
+            AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, \r
+            offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder\r
+        );\r
+\r
+        x          += psEncC->subfr_length;\r
+        q          += psEncC->subfr_length;\r
+        pxq        += psEncC->subfr_length;\r
+    }\r
+\r
+    /* Save scalars for this layer */\r
+    NSQ->sLF_AR_shp_Q12             = NSQ->sLF_AR_shp_Q12;\r
+    NSQ->prev_inv_gain_Q16          = NSQ->prev_inv_gain_Q16;\r
+    NSQ->lagPrev                        = psEncCtrlC->pitchL[ NB_SUBFR - 1 ];\r
+    /* Save quantized speech and noise shaping signals */\r
+    SKP_memcpy( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int16 ) );\r
+    SKP_memcpy( NSQ->sLTP_shp_Q10, &NSQ->sLTP_shp_Q10[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int32 ) );\r
+\r
+}\r
+\r
+/***********************************/\r
+/* SKP_Silk_noise_shape_quantizer  */\r
+/***********************************/\r
+SKP_INLINE void SKP_Silk_noise_shape_quantizer(\r
+    SKP_Silk_nsq_state  *NSQ,               /* I/O  NSQ state                       */\r
+    SKP_int             sigtype,            /* I    Signal type                     */\r
+    const SKP_int32     x_sc_Q10[],         /* I                                    */\r
+    SKP_int             q[],                /* O                                    */\r
+    SKP_int16           xq[],               /* O                                    */\r
+    SKP_int32           sLTP_Q16[],         /* I/O  LTP state                       */\r
+    const SKP_int16     a_Q12[],            /* I    Short term prediction coefs     */\r
+    const SKP_int16     b_Q14[],            /* I    Long term prediction coefs      */\r
+    const SKP_int16     AR_shp_Q13[],       /* I    Noise shaping AR coefs          */\r
+    SKP_int             lag,                /* I    Pitch lag                       */\r
+    SKP_int32           HarmShapeFIRPacked_Q14, /* I                                */\r
+    SKP_int             Tilt_Q14,           /* I    Spectral tilt                   */\r
+    SKP_int32           LF_shp_Q14,         /* I                                    */\r
+    SKP_int32           Gain_Q16,           /* I                                    */\r
+    SKP_int             Lambda_Q10,         /* I                                    */\r
+    SKP_int             offset_Q10,         /* I                                    */\r
+    SKP_int             length,             /* I    Input length                    */\r
+    SKP_int             shapingLPCOrder,    /* I    Noise shaping AR filter order   */\r
+    SKP_int             predictLPCOrder     /* I    Prediction filter order         */\r
+)\r
+{\r
+    SKP_int     i, j;\r
+    SKP_int32   LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14;\r
+    SKP_int32   n_LF_Q10, r_Q10, q_Q0, q_Q10;\r
+    SKP_int32   thr1_Q10, thr2_Q10, thr3_Q10;\r
+    SKP_int32   Atmp, dither;\r
+    SKP_int32   exc_Q10, LPC_exc_Q10, xq_Q10;\r
+    SKP_int32   tmp, sLF_AR_shp_Q10;\r
+    SKP_int32   *psLPC_Q14;\r
+    SKP_int32   *shp_lag_ptr, *pred_lag_ptr;\r
+    SKP_int32   a_Q12_tmp[ MAX_LPC_ORDER / 2 ], AR_shp_Q13_tmp[ MAX_LPC_ORDER / 2 ];\r
+\r
+    shp_lag_ptr  = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];\r
+    pred_lag_ptr = &sLTP_Q16[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];\r
+    \r
+    /* Setup short term AR state */\r
+    psLPC_Q14     = &NSQ->sLPC_Q14[ MAX_LPC_ORDER - 1 ];\r
+\r
+    /* Quantization thresholds */\r
+    thr1_Q10 = SKP_SUB_RSHIFT32( -1536, Lambda_Q10, 1);\r
+    thr2_Q10 = SKP_SUB_RSHIFT32( -512,  Lambda_Q10, 1);\r
+    thr2_Q10 = SKP_ADD_RSHIFT32( thr2_Q10, SKP_SMULBB( offset_Q10, Lambda_Q10 ), 10 );\r
+    thr3_Q10 = SKP_ADD_RSHIFT32(  512,  Lambda_Q10, 1);\r
+    \r
+    /* Preload LPC coeficients to array on stack. Gives small performance gain */\r
+    SKP_memcpy( a_Q12_tmp, a_Q12, predictLPCOrder * sizeof( SKP_int16 ) );\r
+    SKP_memcpy( AR_shp_Q13_tmp, AR_shp_Q13, shapingLPCOrder * sizeof( SKP_int16 ) );\r
+    \r
+    for( i = 0; i < length; i++ ) {\r
+        /* Generate dither */\r
+        NSQ->rand_seed = SKP_RAND( NSQ->rand_seed );\r
+\r
+        /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */\r
+        dither = SKP_RSHIFT( NSQ->rand_seed, 31 );\r
+                \r
+        /* Short-term prediction */\r
+        SKP_assert( ( predictLPCOrder  & 1 ) == 0 );    /* check that order is even */\r
+        SKP_assert( ( (SKP_int64)a_Q12 & 3 ) == 0 );    /* check that array starts at 4-byte aligned address */\r
+        SKP_assert( predictLPCOrder >= 10 );            /* check that unrolling works */\r
+\r
+        /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the   */\r
+        /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be     */\r
+        /* loaded in reverse order and the code will give the wrong result. In that case swapping   */\r
+        /* the SMLAWB and SMLAWT instructions should solve the problem.                             */\r
+        /* Partially unrolled */\r
+        Atmp = a_Q12_tmp[ 0 ];      /* read two coefficients at once */\r
+        LPC_pred_Q10 = SKP_SMULWB(               psLPC_Q14[ 0  ], Atmp );\r
+        LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -1 ], Atmp );\r
+        Atmp = a_Q12_tmp[ 1 ];\r
+        LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], Atmp );\r
+        LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -3 ], Atmp );\r
+        Atmp = a_Q12_tmp[ 2 ];\r
+        LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], Atmp );\r
+        LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -5 ], Atmp );\r
+        Atmp = a_Q12_tmp[ 3 ];\r
+        LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], Atmp );\r
+        LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -7 ], Atmp );\r
+        Atmp = a_Q12_tmp[ 4 ];\r
+        LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], Atmp );\r
+        LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -9 ], Atmp );\r
+        for( j = 10; j < predictLPCOrder; j += 2 ) {\r
+            Atmp = a_Q12_tmp[ j >> 1 ];     /* read two coefficients at once */\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j     ], Atmp );\r
+            LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -j - 1 ], Atmp );\r
+        }\r
+\r
+        /* Long-term prediction */\r
+        if( sigtype == SIG_TYPE_VOICED ) {\r
+            /* Unrolled loop */\r
+            LTP_pred_Q14 = SKP_SMULWB(               pred_lag_ptr[  0 ], b_Q14[ 0 ] );\r
+            LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );\r
+            LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );\r
+            LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );\r
+            LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );\r
+            pred_lag_ptr++;\r
+        } else {\r
+            LTP_pred_Q14 = 0;\r
+        }\r
+\r
+        /* Noise shape feedback */\r
+        SKP_assert( ( shapingLPCOrder       & 1 ) == 0 );   /* check that order is even */\r
+        SKP_assert( ( (SKP_int64)AR_shp_Q13 & 3 ) == 0 );   /* check that array starts at 4-byte aligned address */\r
+        SKP_assert( shapingLPCOrder >= 12 );                /* check that unrolling works */\r
+\r
+        /* Partially unrolled */\r
+        Atmp = AR_shp_Q13_tmp[ 0 ];     /* read two coefficients at once */\r
+        n_AR_Q10 = SKP_SMULWB(           psLPC_Q14[ 0  ], Atmp );\r
+        n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -1 ], Atmp );\r
+        Atmp = AR_shp_Q13_tmp[ 1 ];\r
+        n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ -2 ], Atmp );\r
+        n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -3 ], Atmp );\r
+        Atmp = AR_shp_Q13_tmp[ 2 ];\r
+        n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ -4 ], Atmp );\r
+        n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -5 ], Atmp );\r
+        Atmp = AR_shp_Q13_tmp[ 3 ];\r
+        n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ -6 ], Atmp );\r
+        n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -7 ], Atmp );\r
+        Atmp = AR_shp_Q13_tmp[ 4 ];\r
+        n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ -8 ], Atmp );\r
+        n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -9 ], Atmp );\r
+        Atmp = AR_shp_Q13_tmp[ 5 ];\r
+        n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ -10 ], Atmp );\r
+        n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -11 ], Atmp );\r
+        for( j = 12; j < shapingLPCOrder; j += 2 ) {\r
+            Atmp = AR_shp_Q13_tmp[ j >> 1 ];        /* read two coefficients at once */\r
+            n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ -j     ], Atmp );\r
+            n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -j - 1 ], Atmp );\r
+        }\r
+        n_AR_Q10 = SKP_RSHIFT( n_AR_Q10, 1 );   /* Q11 -> Q10 */\r
+        n_AR_Q10  = SKP_SMLAWB( n_AR_Q10, NSQ->sLF_AR_shp_Q12, Tilt_Q14 );\r
+\r
+        n_LF_Q10   = SKP_LSHIFT( SKP_SMULWB( NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ), 2 ); \r
+        n_LF_Q10   = SKP_SMLAWT( n_LF_Q10, NSQ->sLF_AR_shp_Q12, LF_shp_Q14 );\r
+\r
+        SKP_assert( lag > 0 || sigtype == SIG_TYPE_UNVOICED);\r
+\r
+        /* Long-term shaping */\r
+        if( lag > 0 ) {\r
+            /* Symmetric, packed FIR coefficients */\r
+            n_LTP_Q14 = SKP_SMULWB( SKP_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );\r
+            n_LTP_Q14 = SKP_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ],                     HarmShapeFIRPacked_Q14 );\r
+            shp_lag_ptr++;\r
+            n_LTP_Q14 = SKP_LSHIFT( n_LTP_Q14, 6 );\r
+        } else {\r
+            n_LTP_Q14 = 0;\r
+        }\r
+\r
+        /* Input minus prediction plus noise feedback  */\r
+        //r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP;\r
+        tmp   = SKP_SUB32( LTP_pred_Q14, n_LTP_Q14 );                       /* Add Q14 stuff */\r
+        tmp   = SKP_RSHIFT_ROUND( tmp, 4 );                                 /* round to Q10  */\r
+        tmp   = SKP_ADD32( tmp, LPC_pred_Q10 );                             /* add Q10 stuff */ \r
+        tmp   = SKP_SUB32( tmp, n_AR_Q10 );                                 /* subtract Q10 stuff */ \r
+        tmp   = SKP_SUB32( tmp, n_LF_Q10 );                                 /* subtract Q10 stuff */ \r
+        r_Q10 = SKP_SUB32( x_sc_Q10[ i ], tmp );\r
+\r
+\r
+        /* Flip sign depending on dither */\r
+        r_Q10 = ( r_Q10 ^ dither ) - dither;\r
+        r_Q10 = SKP_SUB32( r_Q10, offset_Q10 );\r
+        r_Q10 = SKP_LIMIT( r_Q10, -64 << 10, 64 << 10 );\r
+\r
+        /* Quantize */\r
+        if( r_Q10 < thr1_Q10 ) {\r
+            q_Q0 = SKP_RSHIFT_ROUND( SKP_ADD_RSHIFT32( r_Q10, Lambda_Q10, 1 ), 10 );\r
+            q_Q10 = SKP_LSHIFT( q_Q0, 10 );\r
+        } else if( r_Q10 < thr2_Q10 ) {\r
+            q_Q0 = -1;\r
+            q_Q10 = -1024;\r
+        } else if( r_Q10 > thr3_Q10 ) {\r
+            q_Q0 = SKP_RSHIFT_ROUND( SKP_SUB_RSHIFT32( r_Q10, Lambda_Q10, 1 ), 10 );\r
+            q_Q10 = SKP_LSHIFT( q_Q0, 10 );\r
+        } else {\r
+            q_Q0 = 0;\r
+            q_Q10 = 0;\r
+        }\r
+        q[ i ] = q_Q0;\r
+\r
+        /* Excitation */\r
+        exc_Q10 = SKP_ADD32( q_Q10, offset_Q10 );\r
+        exc_Q10 = ( exc_Q10 ^ dither ) - dither;\r
+\r
+        /* Add predictions */\r
+        LPC_exc_Q10 = SKP_ADD32( exc_Q10, SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) );\r
+        xq_Q10      = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 );\r
+        \r
+        /* Scale XQ back to normal level before saving */\r
+        xq[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( xq_Q10, Gain_Q16 ), 10 ) );\r
+        \r
+        \r
+        /* Update states */\r
+        psLPC_Q14++;\r
+        *psLPC_Q14 = SKP_LSHIFT( xq_Q10, 4 );\r
+        sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 );\r
+        NSQ->sLF_AR_shp_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 );\r
+\r
+        NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx ] = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 );\r
+        sLTP_Q16[NSQ->sLTP_buf_idx] = SKP_LSHIFT( LPC_exc_Q10, 6 );\r
+        NSQ->sLTP_shp_buf_idx++;\r
+        NSQ->sLTP_buf_idx++;\r
+\r
+        /* Make dither dependent on quantized signal */\r
+        NSQ->rand_seed += q[ i ];\r
+    }\r
+    /* Update LPC synth buffer */\r
+    SKP_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], MAX_LPC_ORDER * sizeof( SKP_int32 ) );\r
+}\r
+\r
+SKP_INLINE void SKP_Silk_nsq_scale_states(\r
+    SKP_Silk_nsq_state  *NSQ,               /* I/O NSQ state                        */\r
+    const SKP_int16     x[],                /* I input in Q0                        */\r
+    SKP_int32           x_sc_Q10[],         /* O input scaled with 1/Gain           */\r
+    SKP_int             length,             /* I length of input                    */\r
+    SKP_int16           sLTP[],             /* I re-whitened LTP state in Q0        */\r
+    SKP_int32           sLTP_Q16[],         /* O LTP state matching scaled input    */\r
+    SKP_int             subfr,              /* I subframe number                    */\r
+    const SKP_int       LTP_scale_Q14,      /* I                                    */\r
+    const SKP_int32     Gains_Q16[ NB_SUBFR ], /* I                                 */\r
+    const SKP_int       pitchL[ NB_SUBFR ]  /* I                                    */\r
+)\r
+{\r
+    SKP_int   i, scale_length, lag;\r
+    SKP_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q32;\r
+\r
+    inv_gain_Q16 = SKP_DIV32( SKP_int32_MAX, SKP_RSHIFT( Gains_Q16[ subfr ], 1) );\r
+    inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX );\r
+    lag          = pitchL[ subfr ];\r
+\r
+    /* After rewhitening the LTP state is un-scaled */\r
+    if( NSQ->rewhite_flag ) {\r
+        inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 );\r
+        if( subfr == 0 ) {\r
+            /* Do LTP downscaling */\r
+            inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, LTP_scale_Q14 ), 2 );\r
+        }\r
+        for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {\r
+            sLTP_Q16[ i ] = SKP_SMULWB( inv_gain_Q32, sLTP[ i ] );\r
+        }\r
+    }\r
+\r
+    /* Prepare for Worst case. Next frame starts with max lag voiced */\r
+    scale_length = length * NB_SUBFR;                                           /* approx max lag */\r
+    scale_length = scale_length - SKP_SMULBB( NB_SUBFR - (subfr + 1), length ); /* subtract samples that will be too old in next frame */\r
+    scale_length = SKP_max_int( scale_length, lag + LTP_ORDER );                /* make sure to scale whole pitch period if voiced */\r
+\r
+    /* Adjust for changing gain */\r
+    if( inv_gain_Q16 != NSQ->prev_inv_gain_Q16 ) {\r
+        gain_adj_Q16 =  SKP_DIV32_varQ( inv_gain_Q16, NSQ->prev_inv_gain_Q16, 16 );\r
+\r
+        for( i = NSQ->sLTP_shp_buf_idx - scale_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {\r
+            NSQ->sLTP_shp_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q10[ i ] );\r
+        }\r
+\r
+        /* Scale LTP predict state */\r
+        if( NSQ->rewhite_flag == 0 ) {\r
+            for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {\r
+                sLTP_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] );\r
+            }\r
+        }\r
+        NSQ->sLF_AR_shp_Q12 = SKP_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q12 );\r
+\r
+        /* scale short term state */\r
+        for( i = 0; i < MAX_LPC_ORDER; i++ ) {\r
+            NSQ->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );\r
+        }\r
+    }\r
+\r
+    /* Scale input */\r
+    for( i = 0; i < length; i++ ) {\r
+        x_sc_Q10[ i ] = SKP_RSHIFT( SKP_SMULBB( x[ i ], ( SKP_int16 )inv_gain_Q16 ), 6 );\r
+    }\r
+\r
+    /* save inv_gain */\r
+    SKP_assert( inv_gain_Q16 != 0 );\r
+    NSQ->prev_inv_gain_Q16 = inv_gain_Q16;\r
+}\r
diff --git a/src/SKP_Silk_NSQ_del_dec.c b/src/SKP_Silk_NSQ_del_dec.c
new file mode 100644 (file)
index 0000000..3601263
--- /dev/null
@@ -0,0 +1,722 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main.h"\r
+\r
+typedef struct {\r
+    SKP_int   RandState[ DECISION_DELAY ];\r
+    SKP_int32 Q_Q10[     DECISION_DELAY ];\r
+    SKP_int32 Xq_Q10[    DECISION_DELAY ];\r
+    SKP_int32 Pred_Q16[  DECISION_DELAY ];\r
+    SKP_int32 Shape_Q10[ DECISION_DELAY ];\r
+    SKP_int32 Gain_Q16[  DECISION_DELAY ];\r
+    SKP_int32 sLPC_Q14[ MAX_FRAME_LENGTH / NB_SUBFR + NSQ_LPC_BUF_LENGTH ];\r
+    SKP_int32 LF_AR_Q12;\r
+    SKP_int32 Seed;\r
+    SKP_int32 SeedInit;\r
+    SKP_int32 RD_Q10;\r
+} NSQ_del_dec_struct;\r
+\r
+typedef struct {\r
+    SKP_int32 Q_Q10;\r
+    SKP_int32 RD_Q10;\r
+    SKP_int32 xq_Q14;\r
+    SKP_int32 LF_AR_Q12;\r
+    SKP_int32 sLTP_shp_Q10;\r
+    SKP_int32 LPC_exc_Q16;\r
+} NSQ_sample_struct;\r
+\r
+SKP_INLINE void SKP_Silk_copy_del_dec_state(\r
+    NSQ_del_dec_struct  *DD_dst,                /* I    Dst del dec state                   */\r
+    NSQ_del_dec_struct  *DD_src,                /* I    Src del dec state                   */\r
+    SKP_int             LPC_state_idx           /* I    Index to LPC buffer                 */\r
+);\r
+\r
+SKP_INLINE void SKP_Silk_nsq_del_dec_scale_states(\r
+    SKP_Silk_nsq_state  *NSQ,                   /* I/O  NSQ state                           */\r
+    NSQ_del_dec_struct  psDelDec[],             /* I/O  Delayed decision states             */\r
+    const SKP_int16     x[],                    /* I    Input in Q0                         */\r
+    SKP_int32           x_sc_Q10[],             /* O    Input scaled with 1/Gain in Q10     */\r
+    SKP_int             length,                 /* I    Length of input                     */\r
+    SKP_int16           sLTP[],                 /* I    Re-whitened LTP state in Q0         */\r
+    SKP_int32           sLTP_Q16[],             /* O    LTP state matching scaled input     */\r
+    SKP_int             subfr,                  /* I    Subframe number                     */\r
+    SKP_int             nStatesDelayedDecision, /* I    Number of del dec states            */\r
+    SKP_int             smpl_buf_idx,           /* I    Index to newest samples in buffers  */\r
+    const SKP_int       LTP_scale_Q14,          /* I    LTP state scaling                   */\r
+    const SKP_int32     Gains_Q16[ NB_SUBFR ],  /* I                                        */\r
+    const SKP_int       pitchL[ NB_SUBFR ]      /* I    Pitch lag                           */\r
+);\r
+\r
+/******************************************/\r
+/* Noise shape quantizer for one subframe */\r
+/******************************************/\r
+SKP_INLINE void SKP_Silk_noise_shape_quantizer_del_dec(\r
+    SKP_Silk_nsq_state  *NSQ,                   /* I/O  NSQ state                           */\r
+    NSQ_del_dec_struct  psDelDec[],             /* I/O  Delayed decision states             */\r
+    SKP_int             sigtype,                /* I    Signal type                         */\r
+    const SKP_int32     x_Q10[],                /* I                                        */\r
+    SKP_int             q[],                    /* O                                        */\r
+    SKP_int16           xq[],                   /* O                                        */\r
+    SKP_int32           sLTP_Q16[],             /* I/O  LTP filter state                    */\r
+    const SKP_int16     a_Q12[],                /* I    Short term prediction coefs         */\r
+    const SKP_int16     b_Q14[],                /* I    Long term prediction coefs          */\r
+    const SKP_int16     AR_shp_Q13[],           /* I    Noise shaping coefs                 */\r
+    SKP_int             lag,                    /* I    Pitch lag                           */\r
+    SKP_int32           HarmShapeFIRPacked_Q14, /* I                                        */\r
+    SKP_int             Tilt_Q14,               /* I    Spectral tilt                       */\r
+    SKP_int32           LF_shp_Q14,             /* I                                        */\r
+    SKP_int32           Gain_Q16,               /* I                                        */\r
+    SKP_int             Lambda_Q10,             /* I                                        */\r
+    SKP_int             offset_Q10,             /* I                                        */\r
+    SKP_int             length,                 /* I    Input length                        */\r
+    SKP_int             subfr,                  /* I    Subframe number                     */\r
+    SKP_int             shapingLPCOrder,        /* I    Shaping LPC filter order            */\r
+    SKP_int             predictLPCOrder,        /* I    Prediction LPC filter order         */\r
+    SKP_int             nStatesDelayedDecision, /* I    Number of states in decision tree   */\r
+    SKP_int             *smpl_buf_idx,          /* I    Index to newest samples in buffers  */\r
+    SKP_int             decisionDelay           /* I                                        */\r
+);\r
+\r
+void SKP_Silk_NSQ_del_dec(\r
+    SKP_Silk_encoder_state          *psEncC,                                    /* I/O  Encoder State                       */\r
+    SKP_Silk_encoder_control        *psEncCtrlC,                                /* I    Encoder Control                     */\r
+    SKP_Silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                           */\r
+    const SKP_int16                 x[],                                        /* I    Prefiltered input signal            */\r
+    SKP_int                         q[],                                        /* O    Quantized pulse signal              */\r
+    const SKP_int                   LSFInterpFactor_Q2,                         /* I    LSF interpolation factor in Q2      */\r
+    const SKP_int16                 PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Prediction coefs                    */\r
+    const SKP_int16                 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ],        /* I    LT prediction coefs                 */\r
+    const SKP_int16                 AR2_Q13[ NB_SUBFR * SHAPE_LPC_ORDER_MAX ],  /* I                                        */\r
+    const SKP_int                   HarmShapeGain_Q14[ NB_SUBFR ],              /* I                                        */\r
+    const SKP_int                   Tilt_Q14[ NB_SUBFR ],                       /* I    Spectral tilt                       */\r
+    const SKP_int32                 LF_shp_Q14[ NB_SUBFR ],                     /* I                                        */\r
+    const SKP_int32                 Gains_Q16[ NB_SUBFR ],                      /* I                                        */\r
+    const SKP_int                   Lambda_Q10,                                 /* I                                        */\r
+    const SKP_int                   LTP_scale_Q14                               /* I    LTP state scaling                   */\r
+)\r
+{\r
+    SKP_int     i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;\r
+    SKP_int     last_smple_idx, smpl_buf_idx, decisionDelay, subfr_length;\r
+    const SKP_int16 *A_Q12, *B_Q14, *AR_shp_Q13;\r
+    SKP_int16   *pxq;\r
+    SKP_int32   sLTP_Q16[ 2 * MAX_FRAME_LENGTH ];\r
+    SKP_int16   sLTP[     2 * MAX_FRAME_LENGTH ];\r
+    SKP_int32   HarmShapeFIRPacked_Q14;\r
+    SKP_int     offset_Q10;\r
+    SKP_int32   FiltState[ MAX_LPC_ORDER ], RDmin_Q10;\r
+    SKP_int32   x_sc_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ];\r
+    NSQ_del_dec_struct psDelDec[ DEL_DEC_STATES_MAX ];\r
+    NSQ_del_dec_struct *psDD;\r
+\r
+    subfr_length = psEncC->frame_length / NB_SUBFR;\r
+\r
+    /* Set unvoiced lag to the previous one, overwrite later for voiced */\r
+    lag = NSQ->lagPrev;\r
+\r
+    SKP_assert( NSQ->prev_inv_gain_Q16 != 0 );\r
+\r
+    /* Initialize delayed decision states */\r
+    SKP_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );\r
+    for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {\r
+        psDD                 = &psDelDec[ k ];\r
+        psDD->Seed           = ( k + psEncCtrlC->Seed ) & 3;\r
+        psDD->SeedInit       = psDD->Seed;\r
+        psDD->RD_Q10         = 0;\r
+        psDD->LF_AR_Q12      = NSQ->sLF_AR_shp_Q12;\r
+        psDD->Shape_Q10[ 0 ] = NSQ->sLTP_shp_Q10[ psEncC->frame_length - 1 ];\r
+        SKP_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );\r
+    }\r
+\r
+    offset_Q10   = SKP_Silk_Quantization_Offsets_Q10[ psEncCtrlC->sigtype ][ psEncCtrlC->QuantOffsetType ];\r
+    smpl_buf_idx = 0; /* index of oldest samples */\r
+\r
+    decisionDelay = SKP_min_int( DECISION_DELAY, subfr_length );\r
+    /* For voiced frames limit the decision delay to lower than the pitch lag */\r
+    if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {\r
+        for( k = 0; k < NB_SUBFR; k++ ) {\r
+            decisionDelay = SKP_min_int( decisionDelay, psEncCtrlC->pitchL[ k ] - LTP_ORDER / 2 - 1 );\r
+        }\r
+    }\r
+\r
+    if( LSFInterpFactor_Q2 == ( 1 << 2 ) ) {\r
+        LSF_interpolation_flag = 0;\r
+    } else {\r
+        LSF_interpolation_flag = 1;\r
+    }\r
+\r
+    /* Setup pointers to start of sub frame */\r
+    pxq                   = &NSQ->xq[ psEncC->frame_length ];\r
+    NSQ->sLTP_shp_buf_idx = psEncC->frame_length;\r
+    NSQ->sLTP_buf_idx     = psEncC->frame_length;\r
+    subfr = 0;\r
+    for( k = 0; k < NB_SUBFR; k++ ) {\r
+        A_Q12      = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];\r
+        B_Q14      = &LTPCoef_Q14[ k * LTP_ORDER           ];\r
+        AR_shp_Q13 = &AR2_Q13[     k * SHAPE_LPC_ORDER_MAX ];\r
+\r
+        NSQ->rewhite_flag = 0;\r
+        if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {\r
+            /* Voiced */\r
+            lag = psEncCtrlC->pitchL[ k ];\r
+\r
+            /* Re-whitening */\r
+            if( ( k & ( 3 - SKP_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {\r
+                if( k == 2 ) {\r
+                    /* RESET DELAYED DECISIONS */\r
+                    /* Find winner */\r
+                    RDmin_Q10 = psDelDec[ 0 ].RD_Q10;\r
+                    Winner_ind = 0;\r
+                    for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {\r
+                        if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {\r
+                            RDmin_Q10 = psDelDec[ i ].RD_Q10;\r
+                            Winner_ind = i;\r
+                        }\r
+                    }\r
+                    for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {\r
+                        if( i != Winner_ind ) {\r
+                            psDelDec[ i ].RD_Q10 += ( SKP_int32_MAX >> 4 );\r
+                            SKP_assert( psDelDec[ i ].RD_Q10 >= 0 );\r
+                        }\r
+                    }\r
+                    \r
+                    /* Copy final part of signals from winner state to output and long-term filter states */\r
+                    psDD = &psDelDec[ Winner_ind ];\r
+                    last_smple_idx = smpl_buf_idx + decisionDelay;\r
+                    for( i = 0; i < decisionDelay; i++ ) {\r
+                        last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;\r
+                        q[   i - decisionDelay ] = ( SKP_int )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 );\r
+                        pxq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( \r
+                            SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ], \r
+                            psDD->Gain_Q16[ last_smple_idx ] ), 10 ) );\r
+                        NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];\r
+                    }\r
+\r
+                    subfr = 0;\r
+                }\r
+\r
+                /* Rewhiten with new A coefs */\r
+                start_idx = psEncC->frame_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;\r
+                start_idx = SKP_LIMIT( start_idx, 0, psEncC->frame_length - psEncC->predictLPCOrder );\r
+                \r
+                SKP_memset( FiltState, 0, psEncC->predictLPCOrder * sizeof( SKP_int32 ) );\r
+                SKP_Silk_MA_Prediction( &NSQ->xq[ start_idx + k * psEncC->subfr_length ], \r
+                    A_Q12, FiltState, sLTP + start_idx, psEncC->frame_length - start_idx, psEncC->predictLPCOrder );\r
+\r
+                NSQ->sLTP_buf_idx = psEncC->frame_length;\r
+                NSQ->rewhite_flag = 1;\r
+            }\r
+        }\r
+\r
+        /* Noise shape parameters */\r
+        SKP_assert( HarmShapeGain_Q14[ k ] >= 0 );\r
+        HarmShapeFIRPacked_Q14  =                        SKP_RSHIFT( HarmShapeGain_Q14[ k ], 2 );\r
+        HarmShapeFIRPacked_Q14 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );\r
+\r
+        SKP_Silk_nsq_del_dec_scale_states( NSQ, psDelDec, x, x_sc_Q10, \r
+            subfr_length, sLTP, sLTP_Q16, k, psEncC->nStatesDelayedDecision, smpl_buf_idx,\r
+            LTP_scale_Q14, Gains_Q16, psEncCtrlC->pitchL );\r
+\r
+        SKP_Silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psEncCtrlC->sigtype, x_sc_Q10, q, pxq, sLTP_Q16,\r
+            A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], \r
+            Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, \r
+            psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay \r
+        );\r
+        \r
+        x   += psEncC->subfr_length;\r
+        q   += psEncC->subfr_length;\r
+        pxq += psEncC->subfr_length;\r
+    }\r
+\r
+    /* Find winner */\r
+    RDmin_Q10 = psDelDec[ 0 ].RD_Q10;\r
+    Winner_ind = 0;\r
+    for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {\r
+        if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {\r
+            RDmin_Q10 = psDelDec[ k ].RD_Q10;\r
+            Winner_ind = k;\r
+        }\r
+    }\r
+    \r
+    /* Copy final part of signals from winner state to output and long-term filter states */\r
+    psDD = &psDelDec[ Winner_ind ];\r
+    psEncCtrlC->Seed = psDD->SeedInit;\r
+    last_smple_idx = smpl_buf_idx + decisionDelay;\r
+    for( i = 0; i < decisionDelay; i++ ) {\r
+        last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;\r
+        q[   i - decisionDelay ] = ( SKP_int )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 );\r
+        pxq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( \r
+            SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ], psDD->Gain_Q16[ last_smple_idx ] ), 10 ) );\r
+        NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];\r
+        sLTP_Q16[          NSQ->sLTP_buf_idx     - decisionDelay + i ] = psDD->Pred_Q16[  last_smple_idx ];\r
+\r
+    }\r
+    SKP_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );\r
+\r
+    /* Update states */\r
+    NSQ->sLF_AR_shp_Q12    = psDD->LF_AR_Q12;\r
+    NSQ->prev_inv_gain_Q16 = NSQ->prev_inv_gain_Q16;\r
+    NSQ->lagPrev           = psEncCtrlC->pitchL[ NB_SUBFR - 1 ];\r
+\r
+    /* Save quantized speech and noise shaping signals */\r
+    SKP_memcpy( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int16 ) );\r
+    SKP_memcpy( NSQ->sLTP_shp_Q10, &NSQ->sLTP_shp_Q10[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int32 ) );\r
+\r
+}\r
+\r
+/******************************************/\r
+/* Noise shape quantizer for one subframe */\r
+/******************************************/\r
+SKP_INLINE void SKP_Silk_noise_shape_quantizer_del_dec(\r
+    SKP_Silk_nsq_state  *NSQ,                   /* I/O  NSQ state                           */\r
+    NSQ_del_dec_struct  psDelDec[],             /* I/O  Delayed decision states             */\r
+    SKP_int             sigtype,                /* I    Signal type                         */\r
+    const SKP_int32     x_Q10[],                /* I                                        */\r
+    SKP_int             q[],                    /* O                                        */\r
+    SKP_int16           xq[],                   /* O                                        */\r
+    SKP_int32           sLTP_Q16[],             /* I/O  LTP filter state                    */\r
+    const SKP_int16     a_Q12[],                /* I    Short term prediction coefs         */\r
+    const SKP_int16     b_Q14[],                /* I    Long term prediction coefs          */\r
+    const SKP_int16     AR_shp_Q13[],           /* I    Noise shaping coefs                 */\r
+    SKP_int             lag,                    /* I    Pitch lag                           */\r
+    SKP_int32           HarmShapeFIRPacked_Q14, /* I                                        */\r
+    SKP_int             Tilt_Q14,               /* I    Spectral tilt                       */\r
+    SKP_int32           LF_shp_Q14,             /* I                                        */\r
+    SKP_int32           Gain_Q16,               /* I                                        */\r
+    SKP_int             Lambda_Q10,             /* I                                        */\r
+    SKP_int             offset_Q10,             /* I                                        */\r
+    SKP_int             length,                 /* I    Input length                        */\r
+    SKP_int             subfr,                  /* I    Subframe number                     */\r
+    SKP_int             shapingLPCOrder,        /* I    Shaping LPC filter order            */\r
+    SKP_int             predictLPCOrder,        /* I    Prediction LPC filter order         */\r
+    SKP_int             nStatesDelayedDecision, /* I    Number of states in decision tree   */\r
+    SKP_int             *smpl_buf_idx,          /* I    Index to newest samples in buffers  */\r
+    SKP_int             decisionDelay           /* I                                        */\r
+)\r
+{\r
+    SKP_int     i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;\r
+    SKP_int32   Winner_rand_state;\r
+    SKP_int32   LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14;\r
+    SKP_int32   n_LF_Q10;\r
+    SKP_int32   r_Q10, rr_Q20, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;\r
+    SKP_int32   q1_Q10, q2_Q10;\r
+    SKP_int32   Atmp, dither;\r
+    SKP_int32   exc_Q10, LPC_exc_Q10, xq_Q10;\r
+    SKP_int32   tmp, sLF_AR_shp_Q10;\r
+    SKP_int32   *pred_lag_ptr, *shp_lag_ptr;\r
+    SKP_int32   *psLPC_Q14;\r
+    SKP_int32   a_Q12_tmp[ MAX_LPC_ORDER / 2 ], AR_shp_Q13_tmp[ MAX_LPC_ORDER / 2 ];\r
+    NSQ_sample_struct  psSampleState[ DEL_DEC_STATES_MAX ][ 2 ];\r
+    NSQ_del_dec_struct *psDD;\r
+    NSQ_sample_struct  *psSS;\r
+\r
+    shp_lag_ptr  = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];\r
+    pred_lag_ptr = &sLTP_Q16[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];\r
+    \r
+    /* Preload LPC coeficients to array on stack. Gives small performance gain */\r
+    SKP_memcpy( a_Q12_tmp, a_Q12, predictLPCOrder * sizeof( SKP_int16 ) );\r
+    SKP_memcpy( AR_shp_Q13_tmp, AR_shp_Q13, shapingLPCOrder * sizeof( SKP_int16 ) );\r
+\r
+    for( i = 0; i < length; i++ ) {\r
+        /* Perform common calculations used in all states */\r
+\r
+        /* Long-term prediction */\r
+        if( sigtype == SIG_TYPE_VOICED ) {\r
+            /* Unrolled loop */\r
+            LTP_pred_Q14 = SKP_SMULWB(               pred_lag_ptr[  0 ], b_Q14[ 0 ] );\r
+            LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );\r
+            LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );\r
+            LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );\r
+            LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );\r
+            pred_lag_ptr++;\r
+        } else {\r
+            LTP_pred_Q14 = 0;\r
+        }\r
+\r
+        /* Long-term shaping */\r
+        if( lag > 0 ) {\r
+            /* Symmetric, packed FIR coefficients */\r
+            n_LTP_Q14 = SKP_SMULWB( SKP_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );\r
+            n_LTP_Q14 = SKP_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ],                     HarmShapeFIRPacked_Q14 );\r
+            n_LTP_Q14 = SKP_LSHIFT( n_LTP_Q14, 6 );\r
+            shp_lag_ptr++;\r
+        } else {\r
+            n_LTP_Q14 = 0;\r
+        }\r
+\r
+        for( k = 0; k < nStatesDelayedDecision; k++ ) {\r
+            /* Delayed decision state */\r
+            psDD = &psDelDec[ k ];\r
+\r
+            /* Sample state */\r
+            psSS = psSampleState[ k ];\r
+\r
+            /* Generate dither */\r
+            psDD->Seed = SKP_RAND( psDD->Seed );\r
+\r
+            /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */\r
+            dither = SKP_RSHIFT( psDD->Seed, 31 );\r
+            \r
+            /* Pointer used in short term prediction and shaping */\r
+            psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];\r
+            /* Short-term prediction */\r
+            SKP_assert( ( predictLPCOrder  & 1 ) == 0 );    /* check that order is even */\r
+            SKP_assert( ( (SKP_int64)a_Q12 & 3 ) == 0 );    /* check that array starts at 4-byte aligned address */\r
+            SKP_assert( predictLPCOrder >= 10 );            /* check that unrolling works */\r
+\r
+            /* Partially unrolled */\r
+            Atmp = a_Q12_tmp[ 0 ];          /* read two coefficients at once */\r
+            LPC_pred_Q10 = SKP_SMULWB(               psLPC_Q14[ 0  ], Atmp );\r
+            LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -1 ], Atmp );\r
+            Atmp = a_Q12_tmp[ 1 ];\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], Atmp );\r
+            LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -3 ], Atmp );\r
+            Atmp = a_Q12_tmp[ 2 ];\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], Atmp );\r
+            LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -5 ], Atmp );\r
+            Atmp = a_Q12_tmp[ 3 ];\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], Atmp );\r
+            LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -7 ], Atmp );\r
+            Atmp = a_Q12_tmp[ 4 ];\r
+            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], Atmp );\r
+            LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -9 ], Atmp );\r
+            for( j = 10; j < predictLPCOrder; j += 2 ) {\r
+                Atmp = a_Q12_tmp[ j >> 1 ]; /* read two coefficients at once */\r
+                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j     ], Atmp );\r
+                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -j - 1 ], Atmp );\r
+            }\r
+\r
+            /* Noise shape feedback */\r
+            SKP_assert( ( shapingLPCOrder       & 1 ) == 0 );   /* check that order is even */\r
+            SKP_assert( ( (SKP_int64)AR_shp_Q13 & 3 ) == 0 );   /* check that array starts at 4-byte aligned address */\r
+            SKP_assert( shapingLPCOrder >= 12 );                /* check that unrolling works */\r
+            /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the   */\r
+            /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be     */\r
+            /* loaded in reverse order and the code will give the wrong result. In that case swapping   */\r
+            /* the SMLAWB and SMLAWT instructions should solve the problem.                             */\r
+\r
+            /* Partially unrolled */\r
+            Atmp = AR_shp_Q13_tmp[ 0 ];         /* read two coefficients at once */\r
+            n_AR_Q10 = SKP_SMULWB(           psLPC_Q14[ 0  ], Atmp );\r
+            n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -1 ], Atmp );\r
+            Atmp = AR_shp_Q13_tmp[ 1 ];\r
+            n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ -2 ], Atmp );\r
+            n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -3 ], Atmp );\r
+            Atmp = AR_shp_Q13_tmp[ 2 ];\r
+            n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ -4 ], Atmp );\r
+            n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -5 ], Atmp );\r
+            Atmp = AR_shp_Q13_tmp[ 3 ];\r
+            n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ -6 ], Atmp );\r
+            n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -7 ], Atmp );\r
+            Atmp = AR_shp_Q13_tmp[ 4 ];\r
+            n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ -8 ], Atmp );\r
+            n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -9 ], Atmp );\r
+            Atmp = AR_shp_Q13_tmp[ 5 ];\r
+            n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ -10 ], Atmp );\r
+            n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -11 ], Atmp );\r
+            for( j = 12; j < shapingLPCOrder; j += 2 ) {\r
+                Atmp = AR_shp_Q13_tmp[ j >> 1 ];        /* read two coefficients at once */\r
+                n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psLPC_Q14[ -j     ], Atmp );\r
+                n_AR_Q10 = SKP_SMLAWT( n_AR_Q10, psLPC_Q14[ -j - 1 ], Atmp );\r
+            }\r
+            n_AR_Q10 = SKP_RSHIFT( n_AR_Q10, 1 );           /* Q11 -> Q10 */\r
+            n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psDD->LF_AR_Q12, Tilt_Q14 );\r
+\r
+            n_LF_Q10   = SKP_LSHIFT( SKP_SMULWB( psDD->Shape_Q10[ *smpl_buf_idx ], LF_shp_Q14 ), 2 ); \r
+            n_LF_Q10   = SKP_SMLAWT( n_LF_Q10, psDD->LF_AR_Q12, LF_shp_Q14 );       \r
+\r
+            /* Input minus prediction plus noise feedback                       */\r
+            /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP  */\r
+            tmp   = SKP_SUB32( LTP_pred_Q14, n_LTP_Q14 );                       /* Add Q14 stuff */\r
+            tmp   = SKP_RSHIFT_ROUND( tmp, 4 );                                 /* round to Q10  */\r
+            tmp   = SKP_ADD32( tmp, LPC_pred_Q10 );                             /* add Q10 stuff */ \r
+            tmp   = SKP_SUB32( tmp, n_AR_Q10 );                                 /* subtract Q10 stuff */ \r
+            tmp   = SKP_SUB32( tmp, n_LF_Q10 );                                 /* subtract Q10 stuff */ \r
+            r_Q10 = SKP_SUB32( x_Q10[ i ], tmp );                               /* residual error Q10 */\r
+            \r
+\r
+            /* Flip sign depending on dither */\r
+            r_Q10 = ( r_Q10 ^ dither ) - dither;\r
+            r_Q10 = SKP_SUB32( r_Q10, offset_Q10 );\r
+            r_Q10 = SKP_LIMIT( r_Q10, -64 << 10, 64 << 10 );\r
+\r
+            /* Find two quantization level candidates and measure their rate-distortion */\r
+            if( r_Q10 < -1536 ) {\r
+                q1_Q10  = SKP_LSHIFT( SKP_RSHIFT_ROUND( r_Q10, 10 ), 10 );\r
+                r_Q10   = SKP_SUB32( r_Q10, q1_Q10 );\r
+                rd1_Q10 = SKP_RSHIFT( SKP_SMLABB( SKP_MUL( -SKP_ADD32( q1_Q10, offset_Q10 ), Lambda_Q10 ), r_Q10, r_Q10 ), 10 );\r
+                rd2_Q10 = SKP_ADD32( rd1_Q10, 1024 );\r
+                rd2_Q10 = SKP_SUB32( rd2_Q10, SKP_ADD_LSHIFT32( Lambda_Q10, r_Q10, 1 ) );\r
+                q2_Q10  = SKP_ADD32( q1_Q10, 1024 );\r
+            } else if( r_Q10 > 512 ) {\r
+                q1_Q10  = SKP_LSHIFT( SKP_RSHIFT_ROUND( r_Q10, 10 ), 10 );\r
+                r_Q10   = SKP_SUB32( r_Q10, q1_Q10 );\r
+                rd1_Q10 = SKP_RSHIFT( SKP_SMLABB( SKP_MUL( SKP_ADD32( q1_Q10, offset_Q10 ), Lambda_Q10 ), r_Q10, r_Q10 ), 10 );\r
+                rd2_Q10 = SKP_ADD32( rd1_Q10, 1024 );\r
+                rd2_Q10 = SKP_SUB32( rd2_Q10, SKP_SUB_LSHIFT32( Lambda_Q10, r_Q10, 1 ) );\r
+                q2_Q10  = SKP_SUB32( q1_Q10, 1024 );\r
+            } else {            /* r_Q10 >= -1536 && q1_Q10 <= 512 */\r
+                rr_Q20  = SKP_SMULBB( offset_Q10, Lambda_Q10 );\r
+                rd2_Q10 = SKP_RSHIFT( SKP_SMLABB( rr_Q20, r_Q10, r_Q10 ), 10 );\r
+                rd1_Q10 = SKP_ADD32( rd2_Q10, 1024 );\r
+                rd1_Q10 = SKP_ADD32( rd1_Q10, SKP_SUB_RSHIFT32( SKP_ADD_LSHIFT32( Lambda_Q10, r_Q10, 1 ), rr_Q20, 9 ) );\r
+                q1_Q10  = -1024;\r
+                q2_Q10  = 0;\r
+            }\r
+\r
+            if( rd1_Q10 < rd2_Q10 ) {\r
+                psSS[ 0 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd1_Q10 ); \r
+                psSS[ 1 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd2_Q10 );\r
+                psSS[ 0 ].Q_Q10 = q1_Q10;\r
+                psSS[ 1 ].Q_Q10 = q2_Q10;\r
+            } else {\r
+                psSS[ 0 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd2_Q10 );\r
+                psSS[ 1 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd1_Q10 );\r
+                psSS[ 0 ].Q_Q10 = q2_Q10;\r
+                psSS[ 1 ].Q_Q10 = q1_Q10;\r
+            }\r
+\r
+            /* Update states for best quantization */\r
+\r
+            /* Quantized excitation */\r
+            exc_Q10 = SKP_ADD32( offset_Q10, psSS[ 0 ].Q_Q10 );\r
+            exc_Q10 = ( exc_Q10 ^ dither ) - dither;\r
+\r
+            /* Add predictions */\r
+            LPC_exc_Q10 = exc_Q10 + SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 );\r
+            xq_Q10      = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 );\r
+\r
+            /* Update states */\r
+            sLF_AR_shp_Q10         = SKP_SUB32(  xq_Q10, n_AR_Q10 );\r
+            psSS[ 0 ].sLTP_shp_Q10 = SKP_SUB32(  sLF_AR_shp_Q10, n_LF_Q10 );\r
+            psSS[ 0 ].LF_AR_Q12    = SKP_LSHIFT( sLF_AR_shp_Q10, 2 );\r
+            psSS[ 0 ].xq_Q14       = SKP_LSHIFT( xq_Q10,         4 );\r
+            psSS[ 0 ].LPC_exc_Q16  = SKP_LSHIFT( LPC_exc_Q10,    6 );\r
+\r
+            /* Update states for second best quantization */\r
+\r
+            /* Quantized excitation */\r
+            exc_Q10 = SKP_ADD32( offset_Q10, psSS[ 1 ].Q_Q10 );\r
+            exc_Q10 = ( exc_Q10 ^ dither ) - dither;\r
+\r
+            /* Add predictions */\r
+            LPC_exc_Q10 = exc_Q10 + SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 );\r
+            xq_Q10      = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 );\r
+\r
+            /* Update states */\r
+            sLF_AR_shp_Q10         = SKP_SUB32(  xq_Q10, n_AR_Q10 );\r
+            psSS[ 1 ].sLTP_shp_Q10 = SKP_SUB32(  sLF_AR_shp_Q10, n_LF_Q10 );\r
+            psSS[ 1 ].LF_AR_Q12    = SKP_LSHIFT( sLF_AR_shp_Q10, 2 );\r
+            psSS[ 1 ].xq_Q14       = SKP_LSHIFT( xq_Q10,         4 );\r
+            psSS[ 1 ].LPC_exc_Q16  = SKP_LSHIFT( LPC_exc_Q10,    6 );\r
+        }\r
+\r
+        *smpl_buf_idx  = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK;                   /* Index to newest samples              */\r
+        last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK;       /* Index to decisionDelay old samples   */\r
+\r
+        /* Find winner */\r
+        RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;\r
+        Winner_ind = 0;\r
+        for( k = 1; k < nStatesDelayedDecision; k++ ) {\r
+            if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {\r
+                RDmin_Q10   = psSampleState[ k ][ 0 ].RD_Q10;\r
+                Winner_ind = k;\r
+            }\r
+        }\r
+\r
+        /* Increase RD values of expired states */\r
+        Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];\r
+        for( k = 0; k < nStatesDelayedDecision; k++ ) {\r
+            if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {\r
+                psSampleState[ k ][ 0 ].RD_Q10 = SKP_ADD32( psSampleState[ k ][ 0 ].RD_Q10, ( SKP_int32_MAX >> 4 ) );\r
+                psSampleState[ k ][ 1 ].RD_Q10 = SKP_ADD32( psSampleState[ k ][ 1 ].RD_Q10, ( SKP_int32_MAX >> 4 ) );\r
+                SKP_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );\r
+            }\r
+        }\r
+\r
+        /* Find worst in first set and best in second set */\r
+        RDmax_Q10  = psSampleState[ 0 ][ 0 ].RD_Q10;\r
+        RDmin_Q10  = psSampleState[ 0 ][ 1 ].RD_Q10;\r
+        RDmax_ind = 0;\r
+        RDmin_ind = 0;\r
+        for( k = 1; k < nStatesDelayedDecision; k++ ) {\r
+            /* find worst in first set */\r
+            if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {\r
+                RDmax_Q10  = psSampleState[ k ][ 0 ].RD_Q10;\r
+                RDmax_ind = k;\r
+            }\r
+            /* find best in second set */\r
+            if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {\r
+                RDmin_Q10  = psSampleState[ k ][ 1 ].RD_Q10;\r
+                RDmin_ind = k;\r
+            }\r
+        }\r
+\r
+        /* Replace a state if best from second set outperforms worst in first set */\r
+        if( RDmin_Q10 < RDmax_Q10 ) {\r
+            SKP_Silk_copy_del_dec_state( &psDelDec[ RDmax_ind ], &psDelDec[ RDmin_ind ], i ); \r
+            SKP_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );\r
+        }\r
+\r
+        /* Write samples from winner to output and long-term filter states */\r
+        psDD = &psDelDec[ Winner_ind ];\r
+        if( subfr > 0 || i >= decisionDelay ) {\r
+            q[  i - decisionDelay ] = ( SKP_int )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 );\r
+            xq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( \r
+                SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ], psDD->Gain_Q16[ last_smple_idx ] ), 10 ) );\r
+            NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q10[ last_smple_idx ];\r
+            sLTP_Q16[          NSQ->sLTP_buf_idx     - decisionDelay ] = psDD->Pred_Q16[  last_smple_idx ];\r
+        }\r
+        NSQ->sLTP_shp_buf_idx++;\r
+        NSQ->sLTP_buf_idx++;\r
+\r
+        /* Update states */\r
+        for( k = 0; k < nStatesDelayedDecision; k++ ) {\r
+            psDD                                     = &psDelDec[ k ];\r
+            psSS                                     = &psSampleState[ k ][ 0 ];\r
+            psDD->LF_AR_Q12                          = psSS->LF_AR_Q12;\r
+            psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;\r
+            psDD->Xq_Q10[    *smpl_buf_idx ]         = SKP_RSHIFT( psSS->xq_Q14, 4 );\r
+            psDD->Q_Q10[     *smpl_buf_idx ]         = psSS->Q_Q10;\r
+            psDD->Pred_Q16[  *smpl_buf_idx ]         = psSS->LPC_exc_Q16;\r
+            psDD->Shape_Q10[ *smpl_buf_idx ]         = psSS->sLTP_shp_Q10;\r
+            psDD->Seed                               = SKP_ADD_RSHIFT32( psDD->Seed, psSS->Q_Q10, 10 );\r
+            psDD->RandState[ *smpl_buf_idx ]         = psDD->Seed;\r
+            psDD->RD_Q10                             = psSS->RD_Q10;\r
+            psDD->Gain_Q16[  *smpl_buf_idx ]         = Gain_Q16;\r
+        }\r
+    }\r
+    /* Update LPC states */\r
+    for( k = 0; k < nStatesDelayedDecision; k++ ) {\r
+        psDD = &psDelDec[ k ];\r
+        SKP_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );\r
+    }\r
+}\r
+\r
+SKP_INLINE void SKP_Silk_nsq_del_dec_scale_states(\r
+    SKP_Silk_nsq_state  *NSQ,                   /* I/O  NSQ state                           */\r
+    NSQ_del_dec_struct  psDelDec[],             /* I/O  Delayed decision states             */\r
+    const SKP_int16     x[],                    /* I    Input in Q0                         */\r
+    SKP_int32           x_sc_Q10[],             /* O    Input scaled with 1/Gain in Q10     */\r
+    SKP_int             length,                 /* I    Length of input                     */\r
+    SKP_int16           sLTP[],                 /* I    Re-whitened LTP state in Q0         */\r
+    SKP_int32           sLTP_Q16[],             /* O    LTP state matching scaled input     */\r
+    SKP_int             subfr,                  /* I    Subframe number                     */\r
+    SKP_int             nStatesDelayedDecision, /* I    Number of del dec states            */\r
+    SKP_int             smpl_buf_idx,           /* I    Index to newest samples in buffers  */\r
+    const SKP_int       LTP_scale_Q14,          /* I    LTP state scaling                   */\r
+    const SKP_int32     Gains_Q16[ NB_SUBFR ],  /* I                                        */\r
+    const SKP_int       pitchL[ NB_SUBFR ]      /* I    Pitch lag                           */\r
+)\r
+{\r
+    SKP_int            i, k, scale_length, lag;\r
+    SKP_int32          inv_gain_Q16, gain_adj_Q16, inv_gain_Q32;\r
+    NSQ_del_dec_struct *psDD;\r
+\r
+    inv_gain_Q16 = SKP_DIV32( SKP_int32_MAX, SKP_RSHIFT( Gains_Q16[ subfr ], 1 ) );\r
+    inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX );\r
+    lag          = pitchL[ subfr ];\r
+    /* After rewhitening the LTP state is un-scaled. So scale with inv_gain_Q16 */\r
+    if( NSQ->rewhite_flag ) {\r
+        inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 );\r
+        if( subfr == 0 ) {\r
+            /* Do LTP downscaling */\r
+            inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, LTP_scale_Q14 ), 2 );\r
+        }\r
+        for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {\r
+            SKP_assert( i < MAX_FRAME_LENGTH );\r
+            sLTP_Q16[ i ] = SKP_SMULWB( inv_gain_Q32, sLTP[ i ] );\r
+        }\r
+    }\r
+\r
+    /* Adjust for changing gain */\r
+    if( inv_gain_Q16 != NSQ->prev_inv_gain_Q16 ) {\r
+        gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, NSQ->prev_inv_gain_Q16, 16 );\r
+\r
+        for( k = 0; k < nStatesDelayedDecision; k++ ) {\r
+            psDD = &psDelDec[ k ];\r
+            \r
+            /* Scale scalar states */\r
+            psDD->LF_AR_Q12 = SKP_SMULWW( gain_adj_Q16, psDD->LF_AR_Q12 );\r
+            \r
+            /* scale short term state */\r
+            for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {\r
+                psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - i - 1 ] = SKP_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - i - 1 ] );\r
+            }\r
+            for( i = 0; i < DECISION_DELAY; i++ ) {\r
+                psDD->Pred_Q16[  i ] = SKP_SMULWW( gain_adj_Q16, psDD->Pred_Q16[  i ] );\r
+                psDD->Shape_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->Shape_Q10[ i ] );\r
+            }\r
+        }\r
+\r
+        /* Scale long term shaping state */\r
+\r
+        /* Calculate length to be scaled, Worst case: Next frame is voiced with max lag */\r
+        scale_length = length * NB_SUBFR;                                               /* aprox max lag */\r
+        scale_length = scale_length - SKP_SMULBB( NB_SUBFR - ( subfr + 1 ), length );   /* subtract samples that will be too old in next frame */\r
+        scale_length = SKP_max_int( scale_length, lag + LTP_ORDER );                    /* make sure to scale whole pitch period if voiced */\r
+\r
+        for( i = NSQ->sLTP_shp_buf_idx - scale_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {\r
+            NSQ->sLTP_shp_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q10[ i ] );\r
+        }\r
+\r
+        /* Scale LTP predict state */\r
+        if( NSQ->rewhite_flag == 0 ) {\r
+            for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {\r
+                sLTP_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] );\r
+            }\r
+        }\r
+    }\r
+\r
+    /* Scale input */\r
+    for( i = 0; i < length; i++ ) {\r
+        x_sc_Q10[ i ] = SKP_RSHIFT( SKP_SMULBB( x[ i ], ( SKP_int16 )inv_gain_Q16 ), 6 );\r
+    }\r
+\r
+    /* save inv_gain */\r
+    SKP_assert( inv_gain_Q16 != 0 );\r
+    NSQ->prev_inv_gain_Q16 = inv_gain_Q16;\r
+}\r
+\r
+SKP_INLINE void SKP_Silk_copy_del_dec_state(\r
+    NSQ_del_dec_struct  *DD_dst,                /* I    Dst del dec state                   */\r
+    NSQ_del_dec_struct  *DD_src,                /* I    Src del dec state                   */\r
+    SKP_int             LPC_state_idx           /* I    Index to LPC buffer                 */\r
+)\r
+{\r
+    SKP_memcpy( DD_dst->RandState, DD_src->RandState,   DECISION_DELAY * sizeof( SKP_int   ) );\r
+    SKP_memcpy( DD_dst->Q_Q10,     DD_src->Q_Q10,       DECISION_DELAY * sizeof( SKP_int32 ) );\r
+    SKP_memcpy( DD_dst->Pred_Q16,  DD_src->Pred_Q16,    DECISION_DELAY * sizeof( SKP_int32 ) );\r
+    SKP_memcpy( DD_dst->Shape_Q10, DD_src->Shape_Q10,   DECISION_DELAY * sizeof( SKP_int32 ) );\r
+    SKP_memcpy( DD_dst->Xq_Q10,    DD_src->Xq_Q10,      DECISION_DELAY * sizeof( SKP_int32 ) );\r
+\r
+    SKP_memcpy( &DD_dst->sLPC_Q14[ LPC_state_idx ], &DD_src->sLPC_Q14[ LPC_state_idx ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );\r
+    DD_dst->LF_AR_Q12 = DD_src->LF_AR_Q12;\r
+    DD_dst->Seed      = DD_src->Seed;\r
+    DD_dst->SeedInit  = DD_src->SeedInit;\r
+    DD_dst->RD_Q10    = DD_src->RD_Q10;\r
+}\r
diff --git a/src/SKP_Silk_PLC.c b/src/SKP_Silk_PLC.c
new file mode 100644 (file)
index 0000000..746ae10
--- /dev/null
@@ -0,0 +1,389 @@
+/***********************************************************************\r
+Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
+Redistribution and use in source and binary forms, with or without \r
+modification, (subject to the limitations in the disclaimer below) \r
+are permitted provided that the following conditions are met:\r
+- Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+- Redistributions in binary form must reproduce the above copyright \r
+notice, this list of conditions and the following disclaimer in the \r
+documentation and/or other materials provided with the distribution.\r
+- Neither the name of Skype Limited, nor the names of specific \r
+contributors, may be used to endorse or promote products derived from \r
+this software without specific prior written permission.\r
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
+BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+***********************************************************************/\r
+\r
+#include "SKP_Silk_main.h"\r
+#include "SKP_Silk_PLC.h"\r
+\r
+#define NB_ATT 2\r
+static const SKP_int16 HARM_ATT_Q15[NB_ATT]              = { 32440, 31130 }; /* 0.99, 0.95 */\r
+static const SKP_int16 PLC_RAND_ATTENUATE_V_Q15[NB_ATT]  = { 31130, 26214 }; /* 0.95, 0.8 */\r
+static const SKP_int16 PLC_RAND_ATTENUATE_UV_Q15[NB_ATT] = { 32440, 29491 }; /* 0.99, 0.9 */\r
+\r
+void SKP_Silk_PLC_Reset(\r
+    SKP_Silk_decoder_state      *psDec              /* I/O Decoder state        */\r
+)\r
+{\r
+   &n