1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/***********************************************************************
2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgCopyright (c) 2006-2011, Skype Limited. All rights reserved.
3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgRedistribution and use in source and binary forms, with or without
4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgmodification, are permitted provided that the following conditions
5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgare met:
6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org- Redistributions of source code must retain the above copyright notice,
7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgthis list of conditions and the following disclaimer.
8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org- Redistributions in binary form must reproduce the above copyright
9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgnotice, this list of conditions and the following disclaimer in the
10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgdocumentation and/or other materials provided with the distribution.
11e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org- Neither the name of Internet Society, IETF or IETF Trust, nor the
12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgnames of specific contributors, may be used to endorse or promote
13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgproducts derived from this software without specific prior written
14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgpermission.
15e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgPOSSIBILITY OF SUCH DAMAGE.
26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org***********************************************************************/
27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef HAVE_CONFIG_H
29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "config.h"
30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "main.h"
33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*#define silk_enc_map(a)                ((a) > 0 ? 1 : 0)*/
35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*#define silk_dec_map(a)                ((a) > 0 ? 1 : -1)*/
36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* shifting avoids if-statement */
37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define silk_enc_map(a)                  ( silk_RSHIFT( (a), 15 ) + 1 )
38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define silk_dec_map(a)                  ( silk_LSHIFT( (a),  1 ) - 1 )
39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Encodes signs of excitation */
41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid silk_encode_signs(
42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ec_enc                      *psRangeEnc,                        /* I/O  Compressor data structure                   */
43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const opus_int8             pulses[],                           /* I    pulse signal                                */
44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int                    length,                             /* I    length of input                             */
45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const opus_int              signalType,                         /* I    Signal type                                 */
46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const opus_int              quantOffsetType,                    /* I    Quantization offset type                    */
47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const opus_int              sum_pulses[ MAX_NB_SHELL_BLOCKS ]   /* I    Sum of absolute pulses per block            */
48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org)
49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int         i, j, p;
51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_uint8       icdf[ 2 ];
52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const opus_int8  *q_ptr;
53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const opus_uint8 *icdf_ptr;
54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    icdf[ 1 ] = 0;
56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    q_ptr = pulses;
57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) );
58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    icdf_ptr = &silk_sign_iCDF[ i ];
59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH );
60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for( i = 0; i < length; i++ ) {
61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        p = sum_pulses[ i ];
62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( p > 0 ) {
63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ];
64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) {
65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                if( q_ptr[ j ] != 0 ) {
66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    ec_enc_icdf( psRangeEnc, silk_enc_map( q_ptr[ j ]), icdf, 8 );
67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        q_ptr += SHELL_CODEC_FRAME_LENGTH;
71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Decodes signs of excitation */
75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid silk_decode_signs(
76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ec_dec                      *psRangeDec,                        /* I/O  Compressor data structure                   */
77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int                    pulses[],                           /* I/O  pulse signal                                */
78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int                    length,                             /* I    length of input                             */
79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const opus_int              signalType,                         /* I    Signal type                                 */
80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const opus_int              quantOffsetType,                    /* I    Quantization offset type                    */
81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const opus_int              sum_pulses[ MAX_NB_SHELL_BLOCKS ]   /* I    Sum of absolute pulses per block            */
82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org)
83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int         i, j, p;
85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_uint8       icdf[ 2 ];
86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_int         *q_ptr;
87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    const opus_uint8 *icdf_ptr;
88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    icdf[ 1 ] = 0;
90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    q_ptr = pulses;
91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) );
92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    icdf_ptr = &silk_sign_iCDF[ i ];
93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH );
94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for( i = 0; i < length; i++ ) {
95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        p = sum_pulses[ i ];
96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if( p > 0 ) {
97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ];
98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) {
99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                if( q_ptr[ j ] > 0 ) {
100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    /* attach sign */
101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#if 0
102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    /* conditional implementation */
103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    if( ec_dec_icdf( psRangeDec, icdf, 8 ) == 0 ) {
104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                        q_ptr[ j ] = -q_ptr[ j ];
105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    }
106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else
107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    /* implementation with shift, subtraction, multiplication */
108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    q_ptr[ j ] *= silk_dec_map( ec_dec_icdf( psRangeDec, icdf, 8 ) );
109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                }
111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        q_ptr += SHELL_CODEC_FRAME_LENGTH;
114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
116