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 <stdint.h>
34 : #include <math.h>
35 : #include "options.h"
36 : #include "ivas_prot_fx.h"
37 : #include "prot_fx.h"
38 : #include "wmc_auto.h"
39 :
40 :
41 : /*-------------------------------------------------------------------*
42 : * ivas_ism_dtx_dec_fx()
43 : *
44 : * ISM DTX Metadata decoding routine
45 : *-------------------------------------------------------------------*/
46 2151 : void ivas_ism_dtx_dec_fx(
47 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
48 : Word16 *nb_bits_metadata /* o : number of metadata bits */
49 : )
50 : {
51 : Word16 ch, nchan_ism, nchan_ism_prev;
52 : Word32 ivas_total_brate;
53 : Word16 md_diff_flag[MAX_NUM_OBJECTS];
54 : Word16 flag_noisy_speech, sce_id_dtx;
55 : Decoder_State *st;
56 :
57 2151 : ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
58 2151 : move32();
59 :
60 2151 : nchan_ism_prev = st_ivas->nchan_ism;
61 2151 : move16();
62 :
63 2151 : test();
64 2151 : IF( !st_ivas->bfi && EQ_32( ivas_total_brate, IVAS_SID_5k2 ) )
65 : {
66 : /* 'nchan_ism' was read in ivas_dec_setup() */
67 550 : nchan_ism = st_ivas->nchan_ism;
68 :
69 : /* ism_mode was read in ivas_dec_setup() as well as reconfiguration ivas_ism_dec_config() */
70 : }
71 : ELSE
72 : {
73 1601 : nchan_ism = nchan_ism_prev;
74 : }
75 2151 : move16();
76 :
77 : /* Metadata decoding and dequantization */
78 2151 : ivas_ism_metadata_sid_dec_fx( st_ivas->hSCE, ivas_total_brate, st_ivas->bfi, nchan_ism, st_ivas->nchan_transport, st_ivas->ism_mode,
79 2151 : &flag_noisy_speech, &sce_id_dtx, st_ivas->hIsmMetaData, nb_bits_metadata );
80 :
81 2151 : test();
82 2151 : IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) && !st_ivas->bfi )
83 : {
84 550 : if ( st_ivas->hParamIsmDec != NULL )
85 : {
86 107 : st_ivas->hParamIsmDec->hParamIsm->flag_noisy_speech = flag_noisy_speech;
87 107 : move16();
88 : }
89 :
90 550 : st_ivas->hISMDTX.sce_id_dtx = sce_id_dtx;
91 550 : move16();
92 : }
93 :
94 2151 : set16_fx( md_diff_flag, 1, nchan_ism );
95 :
96 2151 : IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
97 : {
98 1620 : FOR( ch = 0; ch < nchan_ism; ch++ )
99 : {
100 1296 : st_ivas->hParamIsmDec->azimuth_values_fx[ch] = st_ivas->hIsmMetaData[ch]->azimuth_fx; // Q22
101 1296 : st_ivas->hParamIsmDec->elevation_values_fx[ch] = st_ivas->hIsmMetaData[ch]->elevation_fx; // Q22
102 1296 : move32();
103 1296 : move32();
104 : }
105 : }
106 : /* synch common seed between SCEs */
107 2151 : IF( EQ_32( st_ivas->ism_mode, ISM_MODE_DISC ) )
108 : {
109 6489 : FOR( ch = 0; ch < nchan_ism; ++ch )
110 : {
111 4662 : st_ivas->hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed = st_ivas->hSCE[st_ivas->hISMDTX.sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed;
112 4662 : move16();
113 : }
114 : }
115 :
116 2151 : update_last_metadata_fx( nchan_ism, st_ivas->hIsmMetaData, md_diff_flag );
117 :
118 2151 : st_ivas->hISMDTX.ism_dtx_hangover_cnt = 0;
119 2151 : move16();
120 :
121 2151 : test();
122 2151 : IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) && !st_ivas->bfi )
123 : {
124 2152 : FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
125 : {
126 1602 : nb_bits_metadata[ch] = nb_bits_metadata[sce_id_dtx];
127 1602 : move16();
128 : }
129 : }
130 :
131 2151 : IF( !st_ivas->bfi )
132 : {
133 7461 : FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
134 : {
135 5310 : st = st_ivas->hSCE[ch]->hCoreCoder[0];
136 5310 : st->bit_stream = st_ivas->hSCE[0]->hCoreCoder[0]->bit_stream;
137 5310 : st->next_bit_pos = 0; /* note: needed in paramISM -> discISM switching */
138 5310 : move16();
139 5310 : st->cng_ism_flag = 1;
140 5310 : move16();
141 5310 : st->L_frame = s_min( st->L_frame, L_FRAME16k ); /* note: needed for switching from active frame with L_frame=640 to CNG in object with no SID */
142 5310 : move16();
143 : }
144 : }
145 :
146 2151 : return;
147 : }
148 :
149 :
150 : /*-------------------------------------------------------------------*
151 : * ivs_ism_dtx_limit_noise_energy_for_near_silence()
152 : *
153 : * for DTX frames where the energy of the sent noise estimate of the dominant object
154 : * is near silence, limit the other objects CNG energies to the same level
155 : *-------------------------------------------------------------------*/
156 2151 : void ivas_ism_dtx_limit_noise_energy_for_near_silence_fx(
157 : SCE_DEC_HANDLE hSCE[], /* i/o: SCE decoder structures */
158 : const Word16 sce_id_dtx, /* i : SCE DTX ID */
159 : const Word16 nchan_transport, /* i : number of transport channels */
160 : Word16 *Q_cngNoiseLevel /* i : stores Q factor of hFdCngCom->cngNoiseLevel for various channels*/
161 : )
162 : {
163 : Word32 fac_fx, cng_noise_nrg_obj_fx, cng_noise_nrg_dominant_fx;
164 : Word16 ch, cng_noise_level_len, Q_cng_noise_nrg_dominant, Q_fac;
165 : HANDLE_FD_CNG_COM hFdCngCom;
166 2151 : hFdCngCom = hSCE[sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom;
167 2151 : cng_noise_level_len = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
168 2151 : Q_cng_noise_nrg_dominant = add( Q_cngNoiseLevel[sce_id_dtx], Q_cngNoiseLevel[sce_id_dtx] ); /*stores Q for cng_noise_nrg_dominant_fx*/
169 2151 : cng_noise_nrg_dominant_fx = dotp_fixed_o( hFdCngCom->cngNoiseLevel, hFdCngCom->cngNoiseLevel, cng_noise_level_len, 9 /*log2(len(hFdCngCom->cngNoiseLevel))*/, &Q_cng_noise_nrg_dominant ); /*Resultant Q_cng_noise_nrg_dominant= (Q_cng_noise_nrg_dominant-x)<=31*/
170 2151 : IF( LT_32( cng_noise_nrg_dominant_fx, L_shl_sat( 1, Q_cng_noise_nrg_dominant ) ) ) /*cng_noise_nrg_dominant<1.f*/
171 : {
172 2827 : FOR( ch = 0; ch < nchan_transport; ch++ )
173 : {
174 2071 : IF( EQ_16( ch, sce_id_dtx ) )
175 : {
176 756 : CONTINUE;
177 : }
178 1315 : hFdCngCom = hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom;
179 1315 : cng_noise_level_len = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
180 1315 : Word16 Q_cng_noise_nrg_obj = add( Q_cngNoiseLevel[ch], Q_cngNoiseLevel[ch] ); /*Stores Q-factor of cng_noise_nrg_obj*/
181 1315 : cng_noise_nrg_obj_fx = dotp_fixed_o( hFdCngCom->cngNoiseLevel, hFdCngCom->cngNoiseLevel, cng_noise_level_len, 9, &Q_cng_noise_nrg_obj ); /*Resultant Q_cng_noise_nrg_obj= (Q_cng_noise_nrg_obj-x)<=31*/
182 1315 : IF( GT_32( cng_noise_nrg_obj_fx, cng_noise_nrg_dominant_fx ) )
183 : {
184 203 : Word32 temp = 0;
185 203 : move32();
186 203 : IF( L_shr( cng_noise_nrg_dominant_fx, 1 ) )
187 : {
188 203 : temp = divide3232( L_shr( cng_noise_nrg_dominant_fx, 1 ), cng_noise_nrg_obj_fx ); /*Stores value of cng_noise_nrg_dominant_fx/cng_noise_nrg_obj_fx*/
189 : }
190 203 : Word16 Q_temp = add( sub( sub( Q_cng_noise_nrg_dominant, 1 ), Q_cng_noise_nrg_obj ), 15 ); /*Stores resultant Q after divide3232 operation above*/
191 203 : IF( EQ_16( Q_temp % 2, 1 ) ) /*Making Q_temp even for sqrt function*/
192 : {
193 7 : Q_temp = sub( Q_temp, 1 );
194 7 : temp = L_shr( temp, 1 );
195 : }
196 203 : fac_fx = getSqrtWord32( temp ); /*Resultant Q=Q_temp/2*/
197 203 : Q_fac = shr( Q_temp, 1 );
198 203 : v_multc_fixed( hFdCngCom->cngNoiseLevel, fac_fx, hFdCngCom->cngNoiseLevel, cng_noise_level_len ); /*Resultant Q of cngNoiseLevel is Q_cngNoiseLevel for ch*/
199 203 : scale_sig32( hFdCngCom->cngNoiseLevel, cng_noise_level_len, negate( sub( 31, Q_fac ) ) ); /*Restoring Q of hFdCngCom->cngNoiseLevel to Q_cngNoiseLevel */
200 : }
201 : }
202 : }
203 2151 : return;
204 : }
|