Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <assert.h>
38 : #include <stdint.h>
39 : #include "options.h"
40 : #include "cnst.h"
41 : #include "stl.h"
42 : #include "basop_util.h"
43 : #include "prot.h"
44 : #include "rom_com.h"
45 : #include "wmc_auto.h"
46 :
47 : /*-------------------------------------------------------------------*
48 : * UnmapIndex()
49 : *
50 : *
51 : *-------------------------------------------------------------------*/
52 :
53 252597 : void UnmapIndex(
54 : const int16_t PeriodicityIndex,
55 : const int16_t Bandwidth,
56 : const int16_t LtpPitchLag,
57 : const int16_t SmallerLags,
58 : int16_t *FractionalResolution,
59 : int32_t *Lag )
60 : {
61 252597 : if ( ( LtpPitchLag > 0 ) && ( PeriodicityIndex & kLtpHmFlag ) )
62 78481 : {
63 : int16_t LtpPitchIndex, Multiplier;
64 78481 : LtpPitchIndex = PeriodicityIndex >> 9;
65 78481 : Multiplier = PeriodicityIndex & 0xff;
66 78481 : assert( 0 <= LtpPitchIndex && LtpPitchIndex <= 16 );
67 78481 : assert( 1 <= Multiplier && Multiplier <= ( 1 << NumRatioBits[Bandwidth][LtpPitchIndex] ) );
68 78481 : *FractionalResolution = kLtpHmFractionalResolution;
69 78481 : *Lag = ( LtpPitchLag * (int32_t) ( 4 * Ratios[Bandwidth][LtpPitchIndex][Multiplier - 1] ) ) >> 2;
70 : }
71 : else
72 : {
73 174116 : if ( PeriodicityIndex < 16 )
74 : {
75 100505 : *FractionalResolution = 3;
76 100505 : *Lag = PeriodicityIndex + GET_ADJ( 0, 6 );
77 : }
78 73611 : else if ( PeriodicityIndex < 80 )
79 : {
80 34043 : *FractionalResolution = 4;
81 34043 : *Lag = PeriodicityIndex + GET_ADJ( 16, 8 );
82 : }
83 39568 : else if ( PeriodicityIndex < 208 )
84 : {
85 33404 : *FractionalResolution = 3;
86 33404 : *Lag = PeriodicityIndex + GET_ADJ( 80, 12 );
87 : }
88 6164 : else if ( PeriodicityIndex < 224 || SmallerLags )
89 : {
90 4925 : *FractionalResolution = 1;
91 4925 : *Lag = PeriodicityIndex + GET_ADJ( 208, 28 );
92 : }
93 : else
94 : {
95 1239 : *FractionalResolution = 0;
96 1239 : *Lag = PeriodicityIndex + GET_ADJ( 224, 188 );
97 : }
98 : }
99 :
100 252597 : return;
101 : }
102 :
103 :
104 : /*-------------------------------------------------------------------*
105 : * ConfigureContextHm()
106 : *
107 : *
108 : *-------------------------------------------------------------------*/
109 :
110 218869 : void ConfigureContextHm(
111 : const int16_t NumCoeffs, /* (I) Number of coefficients */
112 : const int16_t TargetBits, /* (I) Target bit budget (excl. Done flag) */
113 : const int16_t PeriodicityIndex, /* (I) Pitch related index */
114 : const int16_t LtpPitchLag, /* (I) TCX-LTP pitch in F.D. */
115 : CONTEXT_HM_CONFIG *hm_cfg /* (O) Context-based harmonic model configuration */
116 : )
117 : {
118 : int16_t Bandwidth, SmallerLags;
119 : int32_t i, Lag;
120 : int16_t j, FractionalResolution;
121 : int32_t Limit;
122 : int16_t Index;
123 : int16_t *tmp;
124 :
125 218869 : Bandwidth = 0;
126 218869 : if ( NumCoeffs >= 256 )
127 : {
128 218869 : Bandwidth = 1;
129 : }
130 :
131 218869 : SmallerLags = 0;
132 :
133 218869 : if ( TargetBits <= kSmallerLagsTargetBitsThreshold || Bandwidth == 0 )
134 : {
135 10368 : SmallerLags = 1;
136 : }
137 :
138 218869 : UnmapIndex( PeriodicityIndex, Bandwidth, LtpPitchLag, SmallerLags, &FractionalResolution, &Lag );
139 :
140 : /* Set up and fill peakIndices */
141 218869 : hm_cfg->peakIndices = hm_cfg->indexBuffer;
142 218869 : tmp = hm_cfg->peakIndices;
143 218869 : Limit = ( NumCoeffs - 1 ) << FractionalResolution;
144 :
145 21528993 : for ( i = Lag; i < Limit; i += Lag )
146 : {
147 21310124 : Index = (int16_t) ( i >> FractionalResolution );
148 21310124 : *tmp++ = Index - 1;
149 21310124 : *tmp++ = Index;
150 21310124 : *tmp++ = Index + 1;
151 : }
152 218869 : hm_cfg->numPeakIndices = (int16_t) ( tmp - hm_cfg->indexBuffer );
153 :
154 : /* Set up and fill holeIndices */
155 218869 : hm_cfg->holeIndices = hm_cfg->indexBuffer + hm_cfg->numPeakIndices;
156 218869 : tmp = hm_cfg->holeIndices;
157 218869 : Index = 0;
158 :
159 21528993 : for ( j = 0; j < hm_cfg->numPeakIndices; j += 3 )
160 : {
161 138468088 : for ( ; Index < hm_cfg->peakIndices[j]; ++Index )
162 : {
163 117157964 : *tmp++ = Index;
164 : }
165 21310124 : Index += 3; /* Skip the peak */
166 : }
167 :
168 1568293 : for ( ; Index < NumCoeffs; ++Index )
169 : {
170 1349424 : *tmp++ = Index;
171 : }
172 218869 : hm_cfg->numHoleIndices = (int16_t) ( tmp - hm_cfg->holeIndices );
173 : /* Add extremal element signaling the end of the buffer */
174 218869 : *tmp++ = NumCoeffs;
175 :
176 218869 : return;
177 : }
178 :
179 :
180 : /*-------------------------------------------------------------------*
181 : * CountIndexBits()
182 : *
183 : *
184 : *-------------------------------------------------------------------*/
185 :
186 207761 : int16_t CountIndexBits(
187 : const int16_t Bandwidth,
188 : const int16_t PeriodicityIndex )
189 : {
190 207761 : if ( PeriodicityIndex & kLtpHmFlag )
191 : {
192 55575 : int16_t LtpPitchIndex = PeriodicityIndex >> 9;
193 55575 : return NumRatioBits[Bandwidth][LtpPitchIndex];
194 : }
195 :
196 152186 : return 8;
197 : }
198 :
199 : #define WMC_TOOL_SKIP
200 :
201 : /*-------------------------------------------------------------------*
202 : * tcx_hm_render()
203 : *
204 : *
205 : *-------------------------------------------------------------------*/
206 :
207 33728 : int16_t tcx_hm_render(
208 : const int32_t lag, /* i : pitch lag */
209 : const int16_t fract_res, /* i : fractional resolution of the lag */
210 : Word16 p[] /* o : harmonic model (Q13) */
211 : )
212 : {
213 : int16_t k;
214 : Word32 f0, tmp32;
215 : Word16 height, PeakDeviation, tmp;
216 :
217 : /* Set up overall shape */
218 :
219 33728 : f0 = L_shl( lag, sub( 15, fract_res ) ); /* Q15 */
220 :
221 33728 : tmp32 = Mpy_32_16( f0, -26474 );
222 33728 : tmp32 = L_shr_r( BASOP_Util_InvLog2( L_shl( tmp32, 7 ) ), 2 );
223 33728 : tmp32 = L_sub( 603979776L, tmp32 );
224 33728 : tmp32 = L_add( L_add( tmp32, tmp32 ), Mpy_32_16( tmp32, 26214 ) );
225 33728 : height = round_fx( tmp32 ); /* Q13 */
226 :
227 33728 : tmp32 = Mpy_32_16( f0, -18910 );
228 33728 : tmp32 = L_shr_r( BASOP_Util_InvLog2( L_shl( tmp32, 7 ) ), 2 );
229 33728 : tmp32 = L_sub( 1395864371L, tmp32 );
230 33728 : PeakDeviation = round_fx( tmp32 ); /* Q14 */
231 :
232 33728 : IF( sub( 13915, PeakDeviation ) > 0 )
233 : {
234 : /* A bit error was encountered */
235 0 : return 1;
236 : }
237 : ELSE
238 : {
239 33728 : tmp = div_s( 13915, PeakDeviation );
240 33728 : tmp = mult_r( tmp, tmp ); /* Q15 */
241 : }
242 :
243 : /* Render the prototype peak */
244 33728 : p[kTcxHmParabolaHalfWidth] = height;
245 :
246 168640 : for ( k = 1; k <= kTcxHmParabolaHalfWidth; ++k )
247 : {
248 134912 : p[kTcxHmParabolaHalfWidth + k] = round_fx( Mpy_32_16( BASOP_Util_InvLog2( L_shl( L_mult0( mult0( negate( k ), k ), tmp ), 10 ) ), height ) );
249 : }
250 : /* Mirror */
251 168640 : for ( k = -kTcxHmParabolaHalfWidth; k < 0; ++k )
252 : {
253 134912 : p[kTcxHmParabolaHalfWidth + k] = p[kTcxHmParabolaHalfWidth - k];
254 : }
255 :
256 33728 : return 0;
257 : }
258 :
259 :
260 : /*-------------------------------------------------------------------*
261 : * tcx_hm_modify_envelope()
262 : *
263 : *
264 : *-------------------------------------------------------------------*/
265 :
266 56309 : void tcx_hm_modify_envelope(
267 : const Word16 gain, /* i : HM gain (Q11) */
268 : const int32_t lag,
269 : const int16_t fract_res,
270 : const Word16 p[], /* i : harmonic model (Q13) */
271 : Word32 env[], /* i/o: envelope (Q16) */
272 : const int16_t L_frame /* i : number of spectral lines */
273 : )
274 : {
275 : int32_t h, x, k;
276 : Word16 inv_shape[2 * kTcxHmParabolaHalfWidth + 1]; /* Q15 */
277 :
278 56309 : if ( gain == 0 )
279 : {
280 10559 : return;
281 : }
282 :
283 457500 : for ( k = 0; k < 2 * kTcxHmParabolaHalfWidth + 1; ++k )
284 : {
285 411750 : inv_shape[k] = div_s( 512, add( 512, round_fx( L_mult( gain, p[k] ) ) ) );
286 : }
287 :
288 45750 : h = 1;
289 45750 : k = lag >> fract_res;
290 :
291 2238856 : while ( k <= L_frame + kTcxHmParabolaHalfWidth - 1 )
292 : {
293 21806407 : for ( x = max( 0, k - kTcxHmParabolaHalfWidth ); x <= min( k + kTcxHmParabolaHalfWidth, L_frame - 1 ); ++x )
294 : {
295 19613301 : env[x] = Mpy_32_16( env[x], inv_shape[x - k + kTcxHmParabolaHalfWidth] );
296 : }
297 2193106 : ++h;
298 2193106 : k = ( h * lag ) >> fract_res;
299 : }
300 :
301 45750 : return;
302 : }
303 :
304 : #undef WMC_TOOL_SKIP
|