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 "isar_lcld_prot.h" 36 : #include "prot.h" 37 : #include "isar_rom_lcld_tables.h" 38 : #include <stdio.h> 39 : #include "wmc_auto.h" 40 : 41 : 42 : /*------------------------------------------------------------------------------------------* 43 : * Local constants 44 : *------------------------------------------------------------------------------------------*/ 45 : 46 : #define PERCEPTUAL_MODEL_SCALE ( 64 ) 47 : #define PERCEPTUAL_MODEL_ALPHA_SCALE ( 614 ) 48 : #define PERCEPTUAL_MODEL_ALPHA_INV_SCALE ( 6827 ) 49 : #define PERCEPTUAL_MODEL_ALPHA_SHIFT ( 11 ) 50 : 51 : 52 : /*------------------------------------------------------------------------------------------* 53 : * Function LogAdd() 54 : * 55 : * 56 : *------------------------------------------------------------------------------------------*/ 57 : 58 0 : static inline int32_t LogAdd( 59 : const int32_t iVal1, 60 : const int32_t iVal2 ) 61 : { 62 : int32_t iRetVal; 63 : 64 0 : if ( iVal1 > iVal2 ) 65 : { 66 0 : iRetVal = iVal1 - iVal2; 67 0 : iRetVal = ( iRetVal < ( LOG_ADD_TABLE_LENGTH - 1 ) ) ? iRetVal : ( LOG_ADD_TABLE_LENGTH - 1 ); 68 0 : iRetVal = iVal1 + c_aiLogAddTable[iRetVal]; 69 : } 70 : else 71 : { 72 0 : iRetVal = iVal2 - iVal1; 73 0 : iRetVal = ( iRetVal < ( LOG_ADD_TABLE_LENGTH - 1 ) ) ? iRetVal : ( LOG_ADD_TABLE_LENGTH - 1 ); 74 0 : iRetVal = iVal2 + c_aiLogAddTable[iRetVal]; 75 : } 76 : 77 0 : return iRetVal; 78 : } 79 : 80 : 81 : /*------------------------------------------------------------------------------------------* 82 : * Function PerceptualModel() 83 : * 84 : * 85 : *------------------------------------------------------------------------------------------*/ 86 : 87 0 : void PerceptualModel( 88 : const int32_t iMaxQuantBands, 89 : const int32_t *piRMSEnvelope, 90 : int32_t *piExcitation, 91 : int32_t *piSMR ) 92 : { 93 : int32_t n; 94 : 95 0 : for ( n = 0; n < iMaxQuantBands; n++ ) 96 : { 97 : int32_t iSLOffset; 98 : 99 0 : piExcitation[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n]; 100 : 101 : /* Calculate sensation level offset */ 102 0 : iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; 103 : 104 : /* Offset envelope by sensation level offset */ 105 0 : piExcitation[n] -= iSLOffset; 106 : 107 : /* Convert to loudness domain (x^0.3) */ 108 0 : piExcitation[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; 109 : } 110 : 111 : /* Spread excitation function */ 112 0 : for ( n = 0; n < iMaxQuantBands; n++ ) 113 : { 114 : int32_t k; 115 : const int32_t *piSpread; 116 : 117 0 : piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; 118 0 : piSMR[n] = piExcitation[n] + piSpread[n]; 119 0 : for ( k = 0; k < iMaxQuantBands; k++ ) 120 : { 121 0 : if ( k != n ) 122 : { 123 0 : piSMR[n] = LogAdd( piSMR[n], piExcitation[k] + piSpread[k] ); 124 : } 125 : } 126 : } 127 : 128 0 : for ( n = 0; n < iMaxQuantBands; n++ ) 129 : { 130 0 : piSMR[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; 131 0 : piSMR[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n] - piSMR[n]; 132 : } 133 : 134 0 : return; 135 : } 136 : 137 : 138 : /*------------------------------------------------------------------------------------------* 139 : * Function PerceptualModelStereo() 140 : * 141 : * 142 : *------------------------------------------------------------------------------------------*/ 143 : 144 0 : void PerceptualModelStereo( 145 : const int32_t iMaxQuantBands, 146 : const int32_t *piMSFlags, 147 : const int32_t *piRMSEnvelope0, 148 : const int32_t *piRMSEnvelope1, 149 : int32_t *piExcitation0, 150 : int32_t *piExcitation1, 151 : int32_t *piSMR0, 152 : int32_t *piSMR1 ) 153 : { 154 : int32_t n; 155 : 156 0 : for ( n = 0; n < iMaxQuantBands; n++ ) 157 : { 158 : int32_t iMaxRMSEnv; 159 : int32_t iSLOffset; 160 : 161 0 : iMaxRMSEnv = piRMSEnvelope0[n]; 162 : 163 0 : piExcitation0[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; /* piRMSEnvelope0[n] */ 164 : 165 : /* Calculate sensation level offset */ 166 0 : iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation0[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; 167 : 168 : /* Offset envelope by sensation level offset */ 169 0 : piExcitation0[n] -= iSLOffset; 170 : 171 : /* Convert to loudness domain (x^0.3) */ 172 0 : piExcitation0[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; 173 : } 174 : 175 : /* Spread excitation function */ 176 0 : for ( n = 0; n < iMaxQuantBands; n++ ) 177 : { 178 : int32_t k; 179 : const int32_t *piSpread; 180 : 181 0 : piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; 182 0 : piSMR0[n] = piExcitation0[n] + piSpread[n]; 183 0 : for ( k = 0; k < iMaxQuantBands; k++ ) 184 : { 185 0 : if ( k != n ) 186 : { 187 0 : piSMR0[n] = LogAdd( piSMR0[n], piExcitation0[k] + piSpread[k] ); 188 : } 189 : } 190 : } 191 : 192 0 : for ( n = 0; n < iMaxQuantBands; n++ ) 193 : { 194 : int32_t iMaxRMSEnv; 195 : int32_t iSLOffset; 196 : 197 0 : iMaxRMSEnv = piRMSEnvelope1[n]; 198 : 199 0 : piExcitation1[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; /* piRMSEnvelope1[n] */ 200 : 201 : /* Calculate sensation level offset */ 202 0 : iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation1[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; 203 : 204 : /* Offset envelope by sensation level offset */ 205 0 : piExcitation1[n] -= iSLOffset; 206 : 207 : /* Convert to loudness domain (x^0.3) */ 208 0 : piExcitation1[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; 209 : } 210 : 211 : /* Spread excitation function */ 212 0 : for ( n = 0; n < iMaxQuantBands; n++ ) 213 : { 214 : int32_t k; 215 : const int32_t *piSpread; 216 : 217 0 : piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; 218 0 : piSMR1[n] = piExcitation1[n] + piSpread[n]; 219 0 : for ( k = 0; k < iMaxQuantBands; k++ ) 220 : { 221 0 : if ( k != n ) 222 : { 223 0 : piSMR1[n] = LogAdd( piSMR1[n], piExcitation1[k] + piSpread[k] ); 224 : } 225 : } 226 : } 227 : 228 0 : for ( n = 0; n < iMaxQuantBands; n++ ) 229 : { 230 0 : if ( piMSFlags[n] == 1 ) 231 : { 232 0 : piSMR0[n] = ( piSMR0[n] > piSMR1[n] ) ? piSMR0[n] : piSMR1[n]; 233 0 : piSMR1[n] = piSMR0[n]; 234 : } 235 : } 236 : 237 0 : for ( n = 0; n < iMaxQuantBands; n++ ) 238 : { 239 0 : piSMR0[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; 240 0 : piSMR0[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope0[n] + c_aiBandwidthAdjust48[n] - piSMR0[n]; 241 : } 242 : 243 0 : for ( n = 0; n < iMaxQuantBands; n++ ) 244 : { 245 0 : piSMR1[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; 246 0 : piSMR1[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope1[n] + c_aiBandwidthAdjust48[n] - piSMR1[n]; 247 : } 248 : 249 0 : return; 250 : }