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 : #include <assert.h>
34 : #include <stdint.h>
35 : #include "options.h"
36 : #include "ivas_cnst.h"
37 : #include "ivas_rom_com.h"
38 : #include "ivas_prot.h"
39 : #include "rom_com.h"
40 : #include "prot.h"
41 : #include "wmc_auto.h"
42 :
43 : /*-------------------------------------------------------------------*
44 : * Local union
45 : *-------------------------------------------------------------------*/
46 :
47 : #ifndef BASOP_NOGLOB
48 : typedef union
49 : #else /* BASOP_NOGLOB */
50 : typedef union
51 : #endif /* BASOP_NOGLOB */
52 : {
53 : MDCTStereoBands_config const *steBands;
54 : SpectrumWarping const *lpcBndsParam;
55 : } SBPARAMS;
56 :
57 :
58 : /*-------------------------------------------------------------------*
59 : * stereo_mdct_init_bands()
60 : *
61 : * initialize stereo band tables for MDCT stereo
62 : *-------------------------------------------------------------------*/
63 :
64 2896836 : void stereo_mdct_init_bands(
65 : const int16_t L_frame, /* i : frame length */
66 : const int16_t tmp_tcx_mode, /* i : tcx mode (TCX10, TCX 20), -1 if transition frame */
67 : const int32_t element_brate, /* i : element bitrate */
68 : const int16_t igf, /* i : flag indicating if IGF is used */
69 : const H_IGF_GRID hIgfGrid, /* i : IGF grid setup */
70 : int16_t *sfbOffset, /* o : sfb offset table */
71 : int16_t *sfbCnt /* o : number of sfbs */
72 : )
73 : {
74 : SBPARAMS sfbParam;
75 : int16_t i, cnt, specStartOffset, L_frameTCX, tcx_mode;
76 : const uint8_t *sfbWidths;
77 :
78 2896836 : if ( tmp_tcx_mode > 0 )
79 : {
80 1931224 : tcx_mode = tmp_tcx_mode;
81 1931224 : L_frameTCX = ( tcx_mode == TCX_20_CORE ) ? L_frame : ( L_frame / 2 );
82 : }
83 : else
84 : {
85 : /*transition frame*/
86 965612 : L_frameTCX = L_frame + L_frame / 4;
87 965612 : tcx_mode = TCX_20_CORE;
88 : }
89 :
90 : /* select table */
91 2896836 : if ( L_frame == L_FRAME48k )
92 : {
93 1822443 : sfbParam.steBands = mdctStereoBands_32000_640;
94 :
95 1822443 : cnt = ( tcx_mode == TCX_20_CORE ? sfbParam.steBands->bdnCnt_TCX20[0] : sfbParam.steBands->bndCnt_TCX10[0] );
96 :
97 1822443 : sfbWidths = ( tcx_mode == TCX_20_CORE ? sfbParam.steBands->bandLengthsTCX20 : sfbParam.steBands->bandLengthsTCX10 );
98 : }
99 : else
100 : {
101 1074393 : if ( element_brate < IVAS_96k )
102 : {
103 606261 : sfbParam.steBands = mdctStereoBands_32000_640;
104 :
105 606261 : switch ( L_frame )
106 : {
107 501240 : case L_FRAME32k:
108 501240 : cnt = ( tcx_mode == TCX_20_CORE ? sfbParam.steBands->bdnCnt_TCX20[1] : sfbParam.steBands->bndCnt_TCX10[1] );
109 501240 : break;
110 0 : case L_FRAME25_6k:
111 0 : cnt = ( tcx_mode == TCX_20_CORE ? sfbParam.steBands->bdnCnt_TCX20[2] : sfbParam.steBands->bndCnt_TCX10[2] );
112 0 : break;
113 105021 : case L_FRAME16k:
114 105021 : cnt = ( tcx_mode == TCX_20_CORE ? sfbParam.steBands->bdnCnt_TCX20[3] : sfbParam.steBands->bndCnt_TCX10[3] );
115 105021 : break;
116 0 : default:
117 0 : assert( !"Subband division not defined for this frame size" );
118 : return;
119 : }
120 :
121 606261 : sfbWidths = ( tcx_mode == TCX_20_CORE ? sfbParam.steBands->bandLengthsTCX20 : sfbParam.steBands->bandLengthsTCX10 );
122 : }
123 : else
124 : {
125 468132 : switch ( L_frame )
126 : {
127 310245 : case L_FRAME48k:
128 : case L_FRAME32k:
129 310245 : sfbParam.lpcBndsParam = sw32000Hz;
130 310245 : break;
131 0 : case L_FRAME25_6k:
132 0 : sfbParam.lpcBndsParam = sw25600Hz;
133 0 : break;
134 157887 : case L_FRAME16k:
135 157887 : sfbParam.lpcBndsParam = sw16000Hz;
136 157887 : break;
137 0 : default:
138 0 : assert( !"Subband division not defined for this frame size" );
139 : return;
140 : }
141 :
142 468132 : sfbWidths = ( tcx_mode == TCX_20_CORE ? sfbParam.lpcBndsParam->bandLengthsTCX20 : sfbParam.lpcBndsParam->bandLengthsTCX10 );
143 468132 : cnt = 64;
144 : }
145 : }
146 :
147 : /* calc sfb offsets */
148 2896836 : specStartOffset = 0;
149 :
150 127568897 : for ( i = 0; i < cnt; i++ )
151 : {
152 124672061 : sfbOffset[i] = min( specStartOffset, L_frameTCX );
153 124672061 : specStartOffset += sfbWidths[i];
154 :
155 124672061 : if ( sfbOffset[i] >= L_frameTCX )
156 : {
157 0 : break;
158 : }
159 : }
160 :
161 2896836 : *sfbCnt = i;
162 2896836 : sfbOffset[*sfbCnt] = min( specStartOffset, L_frameTCX );
163 :
164 2896836 : if ( igf )
165 : {
166 1707174 : int16_t sfbOldCnt = *sfbCnt;
167 1707174 : int16_t igfSfbStep = hIgfGrid->infoIsRefined ? 2 : 1;
168 : int16_t k;
169 :
170 : /* modify sfb bands according to igf grid */
171 1707174 : assert( hIgfGrid != NULL );
172 :
173 : /* find sfb where IGF starts */
174 59067251 : for ( i = 0; i <= *sfbCnt; i++ )
175 : {
176 59067194 : if ( sfbOffset[i] >= hIgfGrid->startLine )
177 : {
178 : /* set band border to igf start line */
179 1707117 : sfbOffset[i] = hIgfGrid->startLine;
180 1707117 : *sfbCnt = i;
181 1707117 : break;
182 : }
183 : }
184 : /* change bands above the igf start line to match igf bands */
185 10220755 : for ( i = 1, k = igfSfbStep; i < hIgfGrid->swb_offset_len; i++, k += igfSfbStep )
186 : {
187 8513581 : sfbOffset[*sfbCnt + i] = hIgfGrid->swb_offset[k];
188 : }
189 :
190 1707174 : *sfbCnt += ( hIgfGrid->swb_offset_len - 1 );
191 :
192 : /* better save than sorry, overwrite anything that is left above */
193 4469691 : for ( i = *sfbCnt + 1; i < sfbOldCnt + 1; i++ )
194 : {
195 2762517 : sfbOffset[i] = 0;
196 : }
197 : }
198 : else
199 : {
200 1189662 : if ( sfbOffset[*sfbCnt] < L_frameTCX )
201 : {
202 431550 : int16_t nMissingBins = L_frameTCX - sfbOffset[*sfbCnt];
203 431550 : if ( sfbWidths[i] / 2 < nMissingBins )
204 : {
205 396554 : ( *sfbCnt )++;
206 : }
207 431550 : sfbOffset[*sfbCnt] = L_frameTCX;
208 : }
209 : }
210 2896836 : return;
211 : }
212 :
213 : /*-------------------------------------------------------------------*
214 : * stereo_mdct_init_igf_start_band()
215 : *
216 : * initialize start band of the IGF in MDCT stereo
217 : *-------------------------------------------------------------------*/
218 :
219 1902041 : void stereo_mdct_init_igf_start_band(
220 : STEREO_MDCT_BAND_PARAMETERS *stbParams, /* i/o: stereo frequency band parameters */
221 : const float transFac, /* i : transform factor */
222 : const int16_t bwidth, /* i : audio bandwidth */
223 : const int32_t element_brate /* i : element bitrate */
224 : )
225 : {
226 : int16_t i, bitRateIndex, igfStartLine;
227 : const int16_t *swb_offset;
228 : #ifdef DEBUGGING
229 : stbParams->sfbIgfStart = 0;
230 : #endif
231 :
232 1902041 : bitRateIndex = IGF_MapBitRateToIndex( element_brate, bwidth, IVAS_CPE_MDCT, 0 );
233 1902041 : swb_offset = &swb_offset_LB_new[bitRateIndex][1];
234 1902041 : igfStartLine = IGF_ApplyTransFac( swb_offset[0], transFac );
235 :
236 65540104 : for ( i = 0; i < stbParams->sfbCnt; i++ )
237 : {
238 65540104 : if ( igfStartLine == stbParams->sfbOffset[i] )
239 : {
240 1902041 : stbParams->sfbIgfStart = i;
241 1902041 : break;
242 : }
243 : }
244 :
245 1902041 : stbParams->nBandsStereoCore = stbParams->sfbIgfStart;
246 :
247 : #ifdef DEBUGGING
248 : assert( stbParams->sfbIgfStart > 0 );
249 : #endif
250 :
251 1902041 : return;
252 : }
|