1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/****************************************************************************************
19Portions of this file are derived from the following 3GPP standard:
20
21    3GPP TS 26.173
22    ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec
23    Available from http://www.3gpp.org
24
25(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26Permission to distribute, modify and use this file under the standard license
27terms listed above has been obtained from the copyright holder.
28****************************************************************************************/
29/*
30------------------------------------------------------------------------------
31
32
33
34 Filename: phase_dispersion.cpp
35
36     Date: 05/08/2007
37
38------------------------------------------------------------------------------
39 REVISION HISTORY
40
41
42 Description:
43
44------------------------------------------------------------------------------
45 INPUT AND OUTPUT DEFINITIONS
46
47     int16 gain_code,               (i) Q0  : gain of code
48     int16 gain_pit,                (i) Q14 : gain of pitch
49     int16 code[],                  (i/o)   : code vector
50     int16 mode,                    (i)     : level, 0=hi, 1=lo, 2=off
51     int16 disp_mem[],              (i/o)   : static memory (size = 8)
52     int16 ScratchMem[]
53
54------------------------------------------------------------------------------
55 FUNCTION DESCRIPTION
56
57    post-processing to enhance noise in low bit rate.
58
59------------------------------------------------------------------------------
60 REQUIREMENTS
61
62
63------------------------------------------------------------------------------
64 REFERENCES
65
66------------------------------------------------------------------------------
67 PSEUDO-CODE
68
69------------------------------------------------------------------------------
70*/
71
72
73/*----------------------------------------------------------------------------
74; INCLUDES
75----------------------------------------------------------------------------*/
76
77#include "pv_amr_wb_type_defs.h"
78#include "pvamrwbdecoder_basic_op.h"
79#include "pvamrwbdecoder_cnst.h"
80#include "pvamrwbdecoder_mem_funcs.h"
81#include "pvamrwbdecoder_acelp.h"
82#include "pvamrwb_math_op.h"
83
84
85/*----------------------------------------------------------------------------
86; MACROS
87; Define module specific macros here
88----------------------------------------------------------------------------*/
89
90
91/*----------------------------------------------------------------------------
92; DEFINES
93; Include all pre-processor statements here. Include conditional
94; compile variables also.
95----------------------------------------------------------------------------*/
96#define pitch_0_9  14746                   /* 0.9 in Q14 */
97#define pitch_0_6  9830                    /* 0.6 in Q14 */
98#define L_SUBFR 64
99
100/*----------------------------------------------------------------------------
101; LOCAL FUNCTION DEFINITIONS
102; Function Prototype declaration
103----------------------------------------------------------------------------*/
104
105/*----------------------------------------------------------------------------
106; LOCAL STORE/BUFFER/POINTER DEFINITIONS
107; Variable declaration - defined here and used outside this module
108----------------------------------------------------------------------------*/
109/* impulse response with phase dispersion */
110
111/* 2.0 - 6.4 kHz phase dispersion */
112static const int16 ph_imp_low[L_SUBFR] =
113{
114    20182,  9693,  3270, -3437, 2864, -5240,  1589, -1357,
115    600,  3893, -1497,  -698, 1203, -5249,  1199,  5371,
116    -1488,  -705, -2887,  1976,  898,   721, -3876,  4227,
117    -5112,  6400, -1032, -4725, 4093, -4352,  3205,  2130,
118    -1996, -1835,  2648, -1786, -406,   573,  2484, -3608,
119    3139, -1363, -2566,  3808, -639, -2051,  -541,  2376,
120    3932, -6262,  1432, -3601, 4889,   370,   567, -1163,
121    -2854,  1914,    39, -2418, 3454,  2975, -4021,  3431
122};
123
124/* 3.2 - 6.4 kHz phase dispersion */
125static const int16 ph_imp_mid[L_SUBFR] =
126{
127    24098, 10460, -5263,  -763,  2048,  -927,  1753, -3323,
128    2212,   652, -2146,  2487, -3539,  4109, -2107,  -374,
129    -626,  4270, -5485,  2235,  1858, -2769,   744,  1140,
130    -763, -1615,  4060, -4574,  2982, -1163,   731, -1098,
131    803,   167,  -714,   606,  -560,   639,    43, -1766,
132    3228, -2782,   665,   763,   233, -2002,  1291,  1871,
133    -3470,  1032,  2710, -4040,  3624, -4214,  5292, -4270,
134    1563,   108,  -580,  1642, -2458,   957,  544,   2540
135};
136
137/*----------------------------------------------------------------------------
138; EXTERNAL FUNCTION REFERENCES
139; Declare functions defined elsewhere and referenced in this module
140----------------------------------------------------------------------------*/
141
142/*----------------------------------------------------------------------------
143; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
144; Declare variables used in this module but defined elsewhere
145----------------------------------------------------------------------------*/
146
147/*----------------------------------------------------------------------------
148; FUNCTION CODE
149----------------------------------------------------------------------------*/
150
151void phase_dispersion(
152    int16 gain_code,             /* (i) Q0  : gain of code             */
153    int16 gain_pit,              /* (i) Q14 : gain of pitch            */
154    int16 code[],                /* (i/o)   : code vector              */
155    int16 mode,                  /* (i)     : level, 0=hi, 1=lo, 2=off */
156    int16 disp_mem[],            /* (i/o)   : static memory (size = 8) */
157    int16 ScratchMem[]
158)
159{
160    int16 i, j, state;
161    int16 *prev_gain_pit, *prev_gain_code, *prev_state;
162    int16 *code2 = ScratchMem;
163
164    prev_state = disp_mem;
165    prev_gain_code = disp_mem + 1;
166    prev_gain_pit = disp_mem + 2;
167
168    pv_memset((void *)code2, 0, (2*L_SUBFR)*sizeof(*code2));
169
170
171    if (gain_pit < pitch_0_6)
172    {
173        state = 0;
174    }
175    else if (gain_pit < pitch_0_9)
176    {
177        state = 1;
178    }
179    else
180    {
181        state = 2;
182    }
183
184    for (i = 5; i > 0; i--)
185    {
186        prev_gain_pit[i] = prev_gain_pit[i - 1];
187    }
188    prev_gain_pit[0] = gain_pit;
189
190    if (sub_int16(gain_code, *prev_gain_code) > shl_int16(*prev_gain_code, 1))
191    {
192        /* onset */
193        if (state < 2)
194        {
195            state++;
196        }
197    }
198    else
199    {
200        j = 0;
201        for (i = 0; i < 6; i++)
202        {
203            if (prev_gain_pit[i] < pitch_0_6)
204            {
205                j++;
206            }
207        }
208
209        if (j > 2)
210        {
211            state = 0;
212        }
213        if (state > *prev_state + 1)
214        {
215            state--;
216        }
217    }
218
219    *prev_gain_code = gain_code;
220    *prev_state = state;
221
222    /* circular convolution */
223
224    state += mode;              /* level of dispersion */
225
226    if (state == 0)
227    {
228        for (i = 0; i < L_SUBFR; i++)
229        {
230            if (code[i] != 0)
231            {
232                for (j = 0; j < L_SUBFR; j++)
233                {
234                    code2[i + j] = add_int16(code2[i + j], mult_int16_r(code[i], ph_imp_low[j]));
235                }
236            }
237        }
238    }
239    else if (state == 1)
240    {
241        for (i = 0; i < L_SUBFR; i++)
242        {
243            if (code[i] != 0)
244            {
245                for (j = 0; j < L_SUBFR; j++)
246                {
247                    code2[i + j] = add_int16(code2[i + j], mult_int16_r(code[i], ph_imp_mid[j]));
248                }
249            }
250        }
251    }
252    if (state < 2)
253    {
254        for (i = 0; i < L_SUBFR; i++)
255        {
256            code[i] = add_int16(code2[i], code2[i + L_SUBFR]);
257        }
258    }
259    return;
260}
261
262