LCOV - code coverage report
Current view: top level - lib_rend - ivas_allrad_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 71 74 95.9 %
Date: 2025-05-03 01:55:50 Functions: 1 1 100.0 %

          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             : }

Generated by: LCOV version 1.14