LCOV - code coverage report
Current view: top level - lib_dec - ivas_mono_dmx_renderer.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 55 56 98.2 %
Date: 2025-05-23 08:37:30 Functions: 5 5 100.0 %

          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 "options.h"
      35             : #include <math.h>
      36             : #include "cnst.h"
      37             : #include "prot.h"
      38             : #include "ivas_prot.h"
      39             : #include "ivas_cnst.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "ivas_rom_dec.h"
      42             : #include "wmc_auto.h"
      43             : 
      44             : 
      45             : /*-------------------------------------------------------------------------
      46             :  * Local constants
      47             :  *------------------------------------------------------------------------*/
      48             : 
      49             : #define DOWNMIX_ALPHA    0.95f /* Smoothing coefficient */
      50             : #define DOWNMIX_MAX_GAIN 4.0f  /* Maximum allowed gain  */
      51             : 
      52             : 
      53             : /*-------------------------------------------------------------------------
      54             :  * ivas_mono_dmx_renderer_open()
      55             :  *
      56             :  * Open decoder downmix handle
      57             :  *-------------------------------------------------------------------------*/
      58             : 
      59         141 : ivas_error ivas_mono_dmx_renderer_open(
      60             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure  */
      61             : )
      62             : {
      63             :     MONO_DOWNMIX_RENDERER_HANDLE hDownmix;
      64             : 
      65         141 :     if ( ( hDownmix = (MONO_DOWNMIX_RENDERER_HANDLE) malloc( sizeof( MONO_DOWNMIX_RENDERER_STRUCT ) ) ) == NULL )
      66             :     {
      67           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for downmixing\n" ) );
      68             :     }
      69             : 
      70         141 :     hDownmix->inputEnergy = 0;
      71         141 :     hDownmix->protoEnergy = 0;
      72         141 :     st_ivas->hMonoDmxRenderer = hDownmix;
      73             : 
      74         141 :     return IVAS_ERR_OK;
      75             : }
      76             : 
      77             : 
      78             : /*-------------------------------------------------------------------------
      79             :  * ivas_mono_dmx_renderer_close()
      80             :  *
      81             :  * Close decoder downmix handle
      82             :  *-------------------------------------------------------------------------*/
      83             : 
      84        7758 : void ivas_mono_dmx_renderer_close(
      85             :     MONO_DOWNMIX_RENDERER_HANDLE *hMonoDmxRenderer /* i/ i/o: Mono downmix structure */
      86             : )
      87             : {
      88        7758 :     if ( hMonoDmxRenderer == NULL || *hMonoDmxRenderer == NULL )
      89             :     {
      90        7617 :         return;
      91             :     }
      92             : 
      93         141 :     free( *hMonoDmxRenderer );
      94         141 :     *hMonoDmxRenderer = NULL;
      95             : 
      96         141 :     return;
      97             : }
      98             : 
      99             : 
     100             : /*-------------------------------------------------------------------------
     101             :  * ivas_ism_mono_dmx()
     102             :  *
     103             :  * Downmix process
     104             :  *------------------------------------------------------------------------*/
     105             : 
     106       17832 : void ivas_ism_mono_dmx(
     107             :     Decoder_Struct *st_ivas,   /* i/o: IVAS decoder structure                                */
     108             :     float *output_f[],         /* i/o: synthesized core-coder transport channels/mono output */
     109             :     const int16_t output_frame /* i  : output frame length                                   */
     110             : )
     111             : {
     112             :     int16_t i, j, numInputChannels;
     113             :     float proto_signal[L_FRAME48k], eq;
     114             :     float inputEnergy_local, protoEnergy_local;
     115             :     MONO_DOWNMIX_RENDERER_HANDLE hDownmix;
     116             : 
     117       17832 :     numInputChannels = st_ivas->nSCE;
     118       17832 :     if ( st_ivas->ivas_format == SBA_ISM_FORMAT )
     119             :     {
     120        3000 :         numInputChannels = st_ivas->nchan_ism;
     121             :     }
     122             : 
     123       17832 :     if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
     124             :     {
     125        2925 :         if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
     126             :         {
     127        1785 :             numInputChannels = st_ivas->nchan_transport + 1;
     128             :         }
     129             :         else
     130             :         {
     131        1140 :             numInputChannels = st_ivas->nchan_transport + st_ivas->nchan_ism;
     132             :         }
     133             :     }
     134             : 
     135       17832 :     hDownmix = st_ivas->hMonoDmxRenderer;
     136       17832 :     set_zero( proto_signal, output_frame );
     137       17832 :     inputEnergy_local = 0;
     138       17832 :     protoEnergy_local = 0;
     139             : 
     140             :     /* Compute the Proto Signal */
     141       54291 :     for ( i = 0; i < numInputChannels; i++ )
     142             :     {
     143       36459 :         v_add( output_f[i], proto_signal, proto_signal, output_frame );
     144             :     }
     145             : 
     146             :     /* compute the input energy, proto energy */
     147    14285352 :     for ( i = 0; i < output_frame; i++ )
     148             :     {
     149    14267520 :         protoEnergy_local += proto_signal[i] * proto_signal[i];
     150             : 
     151    42576960 :         for ( j = 0; j < numInputChannels; j++ )
     152             :         {
     153    28309440 :             inputEnergy_local += ( output_f[j][i] * output_f[j][i] );
     154             :         }
     155             :     }
     156       17832 :     hDownmix->inputEnergy *= DOWNMIX_ALPHA;
     157       17832 :     hDownmix->protoEnergy *= DOWNMIX_ALPHA;
     158       17832 :     hDownmix->inputEnergy += ( 1.0f - DOWNMIX_ALPHA ) * inputEnergy_local;
     159       17832 :     hDownmix->protoEnergy += ( 1.0f - DOWNMIX_ALPHA ) * protoEnergy_local;
     160             : 
     161             :     /* compute the eq factor */
     162       17832 :     eq = min( DOWNMIX_MAX_GAIN, sqrtf( hDownmix->inputEnergy / ( EPSILON + hDownmix->protoEnergy ) ) );
     163             : 
     164             :     /* equalize the downmix */
     165       17832 :     v_multc( proto_signal, eq, output_f[0], output_frame );
     166             : 
     167       17832 :     return;
     168             : }
     169             : 
     170             : 
     171             : /*-------------------------------------------------------------------------
     172             :  * ivas_mono_stereo_downmix_mcmasa()
     173             :  *
     174             :  * Downmix process in McMASA
     175             :  *------------------------------------------------------------------------*/
     176             : 
     177        1497 : void ivas_mono_stereo_downmix_mcmasa(
     178             :     Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure                                          */
     179             :     float *output_f[],       /* i/o: synthesized core-coder transport channels/mono or stereo output */
     180             :     int16_t output_frame     /* i  : output frame length per channel                                 */
     181             : )
     182             : {
     183             :     int16_t i;
     184             : 
     185             :     float dmx_tmp[L_FRAME48k];
     186             : 
     187        1497 :     set_zero( dmx_tmp, output_frame );
     188             : 
     189             :     /* Dowmix center channel to L and R */
     190        1497 :     if ( st_ivas->hDecoderConfig->nchan_out == 2 && st_ivas->hOutSetup.separateChannelEnabled )
     191             :     {
     192         600 :         v_multc_acc( output_f[st_ivas->hOutSetup.separateChannelIndex], INV_SQRT2, output_f[0], output_frame );
     193         600 :         v_multc_acc( output_f[st_ivas->hOutSetup.separateChannelIndex], INV_SQRT2, output_f[1], output_frame );
     194             :     }
     195             :     /* Mono downmix */
     196         897 :     else if ( st_ivas->hDecoderConfig->nchan_out == 1 )
     197             :     {
     198             :         /* Downmix L and R to dmx_tmp */
     199        2691 :         for ( i = 0; i < st_ivas->nchan_transport; i++ )
     200             :         {
     201        1794 :             v_multc_acc( output_f[i], INV_SQRT2, dmx_tmp, output_frame );
     202             :         }
     203             :         /* Add center channel */
     204         897 :         if ( st_ivas->hOutSetup.separateChannelEnabled )
     205             :         {
     206         447 :             v_add( output_f[st_ivas->hOutSetup.separateChannelIndex], dmx_tmp, dmx_tmp, output_frame );
     207             :         }
     208             : 
     209             :         /* Move to output */
     210         897 :         mvr2r( dmx_tmp, output_f[0], output_frame );
     211             :     }
     212             : 
     213        1497 :     return;
     214             : }
     215             : 
     216             : 
     217             : /*-------------------------------------------------------------------------
     218             :  * ivas_apply_non_diegetic_panning()
     219             :  *
     220             :  * Apply non-diegetic panning
     221             :  *------------------------------------------------------------------------*/
     222             : 
     223       10500 : void ivas_apply_non_diegetic_panning(
     224             :     float *input_f,                    /* i  : non-diegetic object                                         */
     225             :     float *output_f[],                 /* o  : core-coder transport mono channel/stereo output  */
     226             :     const float non_diegetic_pan_gain, /* i  : non-diegetic panning gain                        */
     227             :     const int16_t output_frame         /* i  : output frame length per channel                  */
     228             : )
     229             : {
     230             :     float pan_left, pan_right;
     231             : 
     232       10500 :     pan_left = ( non_diegetic_pan_gain + 1.f ) * 0.5f;
     233       10500 :     pan_right = 1.f - pan_left;
     234       10500 :     v_multc( input_f, pan_right, output_f[1], output_frame );
     235       10500 :     v_multc( input_f, pan_left, output_f[0], output_frame );
     236             : 
     237       10500 :     return;
     238             : }

Generated by: LCOV version 1.14