Line data Source code
1 :
2 : /******************************************************************************************************
3 :
4 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
5 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
6 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
7 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
8 : contributors to this repository. All Rights Reserved.
9 :
10 : This software is protected by copyright law and by international treaties.
11 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
12 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
13 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
14 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
15 : contributors to this repository retain full ownership rights in their respective contributions in
16 : the software. This notice grants no license of any kind, including but not limited to patent
17 : license, nor is any license granted by implication, estoppel or otherwise.
18 :
19 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
20 : contributions.
21 :
22 : This software is provided "AS IS", without any express or implied warranties. The software is in the
23 : development stage. It is intended exclusively for experts who have experience with such software and
24 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
25 : and fitness for a particular purpose are hereby disclaimed and excluded.
26 :
27 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
28 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
29 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
30 : the United Nations Convention on Contracts on the International Sales of Goods.
31 :
32 : *******************************************************************************************************/
33 :
34 : #include <stdint.h>
35 : #include "options.h"
36 : #include <math.h>
37 : #include <assert.h>
38 : #include "prot_fx.h"
39 : #include "ivas_prot_rend_fx.h"
40 : #include "ivas_rom_rend.h"
41 : #include "wmc_auto.h"
42 : #include "ivas_prot_fx.h"
43 :
44 :
45 : /*-----------------------------------------------------------------------*
46 : * Global function definitions
47 : *-----------------------------------------------------------------------*/
48 :
49 : /*-------------------------------------------------------------------------*
50 : * ivas_sba_get_hoa_dec_matrix()
51 : *
52 : * Computes the ALLRAD decoder matrix for HOA to loudspeakers
53 : *-------------------------------------------------------------------------*/
54 : #define TEMP_VAL 1963413621 // Q37 (1.f / num_td)
55 168 : ivas_error ivas_sba_get_hoa_dec_matrix_fx(
56 : const IVAS_OUTPUT_SETUP hOutSetup, /* i : target output setup */
57 : Word32 **hoa_dec_mtx, /* o : ALLRAD decoder matrix, Q29 */
58 : const Word16 ambisonics_order /* i : Ambisonics order */
59 : )
60 : {
61 : Word16 i, j, k;
62 : Word16 num_harm, num_td, num_spk;
63 : const Word32 *t_design_azi, *t_design_ele;
64 : Word32 tmp_val;
65 : Word32 G_td_int[MAX_OUTPUT_CHANNELS];
66 : Word32 Y_td_int[SBA_NHARM_HOA3];
67 : Word32 *p_dec_mtx;
68 : EFAP_HANDLE hEFAP;
69 : ivas_error error;
70 :
71 168 : error = IVAS_ERR_OK;
72 168 : move16();
73 :
74 : /* Allocate memory */
75 168 : assert( *hoa_dec_mtx == NULL && "hoa_dec_mtx != NULL" );
76 168 : IF( ( *hoa_dec_mtx = (Word32 *) malloc( SBA_NHARM_HOA3 * ( hOutSetup.nchan_out_woLFE ) * sizeof( Word32 ) ) ) == NULL )
77 : {
78 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "ALLRAD: Cannot allocate memory!" ) );
79 : }
80 :
81 : /* Initialization by zeroing all SH coeff up to 3rd order (IVAS convention) */
82 168 : num_spk = hOutSetup.nchan_out_woLFE;
83 168 : move16();
84 168 : p_dec_mtx = *hoa_dec_mtx;
85 :
86 1148 : FOR( i = 0; i < num_spk; i++ )
87 : {
88 16660 : FOR( j = 0; j < SBA_NHARM_HOA3; j++ )
89 : {
90 15680 : *( p_dec_mtx++ ) = 0;
91 15680 : move32();
92 : }
93 : }
94 :
95 168 : IF( EQ_32( hOutSetup.output_config, IVAS_AUDIO_CONFIG_MONO ) )
96 : {
97 65 : ( *hoa_dec_mtx )[0] = ONE_IN_Q29; // 1.f in Q29
98 65 : move32();
99 : }
100 103 : ELSE IF( EQ_32( hOutSetup.output_config, IVAS_AUDIO_CONFIG_STEREO ) )
101 : {
102 8 : ( *hoa_dec_mtx )[0] = ONE_IN_Q28; // 0.5f in Q29
103 8 : ( *hoa_dec_mtx )[1] = ONE_IN_Q28; // 0.5f in Q29
104 8 : ( *hoa_dec_mtx )[SBA_NHARM_HOA3] = ONE_IN_Q28; // 0.5f in Q29
105 8 : ( *hoa_dec_mtx )[SBA_NHARM_HOA3 + 1] = -ONE_IN_Q28; // 0.5f in Q29
106 8 : move32();
107 8 : move32();
108 8 : move32();
109 8 : move32();
110 : }
111 95 : ELSE IF( hOutSetup.is_loudspeaker_setup )
112 : {
113 : /* init EFIP */
114 95 : IF( NE_16( ( error = efap_init_data_fx( &( hEFAP ), hOutSetup.ls_azimuth_fx, hOutSetup.ls_elevation_fx, num_spk, EFAP_MODE_EFIP ) ), IVAS_ERR_OK ) )
115 : {
116 0 : return error;
117 : }
118 :
119 95 : num_harm = ivas_sba_get_nchan_fx( ambisonics_order, 0 );
120 :
121 : /* Get t-design values */
122 95 : num_td = SBA_T_DESIGN_11_SIZE;
123 95 : move16();
124 95 : t_design_azi = t_design_11_azimuth_int;
125 95 : t_design_ele = t_design_11_elevation_int;
126 :
127 : /* dec_mtx = ( 1 / num_td ) * (G_td * Y_td') * diag(norm_sn3d) */
128 6745 : FOR( i = 0; i < num_td; i++ )
129 : {
130 : /* spherical harmonics response for t-design, corresponding to ambisonic order */
131 6650 : IF( L_shr( t_design_azi[i], 22 ) > 0 )
132 : {
133 3325 : IF( L_shr( t_design_ele[i], 22 ) > 0 )
134 : {
135 1710 : ivas_dirac_dec_get_response_fx( extract_l( L_shr( t_design_azi[i], 22 ) ), extract_l( L_shr( t_design_ele[i], 22 ) ), Y_td_int, ambisonics_order, Q29 );
136 : }
137 : ELSE
138 : {
139 1615 : ivas_dirac_dec_get_response_fx(
140 1615 : extract_l( L_shr( t_design_azi[i], 22 ) ), add( extract_l( L_shr( t_design_ele[i], 22 ) ), 1 ),
141 : Y_td_int, ambisonics_order, Q29 );
142 : }
143 : }
144 : ELSE
145 : {
146 3325 : IF( L_shr( t_design_ele[i], 22 ) > 0 )
147 : {
148 1615 : ivas_dirac_dec_get_response_fx( add( extract_l( L_shr( t_design_azi[i], 22 ) ), 1 ),
149 1615 : extract_l( L_shr( t_design_ele[i], 22 ) ),
150 : Y_td_int, ambisonics_order, Q29 );
151 : }
152 : ELSE
153 : {
154 1710 : ivas_dirac_dec_get_response_fx(
155 1710 : add( extract_l( L_shr( t_design_azi[i], 22 ) ), 1 ),
156 1710 : add( extract_l( L_shr( t_design_ele[i], 22 ) ), 1 ),
157 : Y_td_int, ambisonics_order, Q29 );
158 : }
159 : }
160 76720 : FOR( j = 0; j < num_harm; j++ )
161 : {
162 70070 : Y_td_int[j] = L_shl( Mpy_32_32( Y_td_int[j], norm_sn3d_hoa3_int[j] ), Q1 ); // Q28
163 70070 : move32();
164 : }
165 :
166 : /* t-design to real LS panning gains */
167 6650 : efap_determine_gains_fx( hEFAP, G_td_int, t_design_azi[i], t_design_ele[i], EFAP_MODE_EFIP ); // G_td_int Q30
168 :
169 6650 : p_dec_mtx = *hoa_dec_mtx;
170 69580 : FOR( j = 0; j < num_spk; j++ )
171 : {
172 62930 : Word32 dec_mtx_temp = 0;
173 62930 : move32();
174 735630 : FOR( k = 0; k < num_harm; k++ )
175 : {
176 672700 : dec_mtx_temp = Mpy_32_32( G_td_int[j], Y_td_int[k] ); // Q27
177 672700 : *p_dec_mtx = L_add( *p_dec_mtx, L_shr( dec_mtx_temp, 2 ) ); // Q25
178 672700 : move32();
179 672700 : p_dec_mtx++;
180 : }
181 62930 : p_dec_mtx += sub( SBA_NHARM_HOA3, num_harm );
182 : }
183 : }
184 :
185 95 : tmp_val = TEMP_VAL;
186 95 : move32();
187 95 : p_dec_mtx = *hoa_dec_mtx;
188 994 : FOR( i = 0; i < num_spk; i++ )
189 : {
190 899 : Word32 dec_mtx_temp_scale = 0;
191 899 : move32();
192 10509 : FOR( j = 0; j < num_harm; j++ )
193 : {
194 9610 : dec_mtx_temp_scale = Mpy_32_32( tmp_val, norm_sn3d_hoa3_int[j] ); // Q35
195 9610 : *p_dec_mtx = Mpy_32_32( *p_dec_mtx, dec_mtx_temp_scale ); // Q29
196 9610 : move32();
197 9610 : p_dec_mtx++;
198 : }
199 899 : p_dec_mtx += sub( SBA_NHARM_HOA3, num_harm );
200 : }
201 :
202 : /* free EFAP handle */
203 95 : efap_free_data_fx( &hEFAP );
204 : }
205 : ELSE
206 : {
207 0 : assert( 0 && "ALLRAD: output not supported!!!" );
208 : }
209 :
210 :
211 168 : return error;
212 : }
|