1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 /* 19 20 Pathname: intensity_right.c 21 22 ------------------------------------------------------------------------------ 23 REVISION HISTORY 24 25 Description: Modified per review comments. 26 27 Description: Noticed that the code could be more efficient by 28 using some other method for storing the sign. The code was changed to 29 use a signed Int to store the table, and an adjustment of the q-format to 30 reflect the difference between the data being shifted by 16 and the table 31 being stored in q-15 format. 32 33 Description: Updated pseudocode 34 35 Description: When the multiplication of two 16-bits variables is stored in 36 an 32-bits variable, the result should be typecasted explicitly 37 to Int32 before it is stored. 38 *(pCoefRight++) = (Int32) tempInt2 * multiplier; 39 40 Description: 41 ------------------------------------------------------------------------------ 42 INPUT AND OUTPUT DEFINITIONS 43 44 Inputs: 45 46 scalefactor = Multiplier used to scale the data extracted from the left 47 channel for use on the right. 48 [const Int] 49 50 coef_per_win = Number of coefficients per window. 51 (128 for short, 1024 for long) 52 [const Int] 53 54 sfb_per_win = Number of scalefactor bands per window. This should be 55 a number divisible by four. 56 [const Int] 57 58 wins_in_group = The number of windows in the group being decoded. 59 This number falls within the range 1-8. 60 [const Int] 61 62 band_length = The length of the scalefactor band being decoded. 63 This value is divisible by 4. 64 [const Int] 65 66 codebook = Value that denotes which Huffman codebook was used for 67 the encoding of this grouped scalefactor band. 68 [const Int] 69 70 ms_used = Flag that denotes whether M/S is active for this band. 71 [const Bool] 72 73 q_formatLeft = The Q-format for the left channel's fixed-point spectral 74 coefficients, on a per-scalefactor band, non-grouped basis. 75 [const Int *, length MAXBANDS] 76 77 q_formatRight = The Q-format for the right channel's fixed-point spectral 78 coefficients, on a per-scalefactor band, non-grouped basis. 79 [Int *, length MAXBANDS] 80 81 coefLeft = Array containing the fixed-point spectral coefficients 82 for the left channel. 83 [const Int32 *, length 1024] 84 85 coefRight = Array containing the fixed-point spectral coefficients 86 for the right channel. 87 [Int32 *, length 1024] 88 89 Local Stores/Buffers/Pointers Needed: 90 intensity_factor = Table which stores the values of 91 0.5^(0), 0.5^(1/4), 0.5^(2/4) and 0.5^(3/4) 92 [UInt, length 4] 93 94 Global Stores/Buffers/Pointers Needed: 95 None 96 97 Outputs: 98 None 99 100 Pointers and Buffers Modified: 101 coefRight[] Contains the new spectral information 102 103 q_formatRight[] Q-format may be updated with changed fixed-point 104 data in coefRight. 105 106 Local Stores Modified: 107 None 108 109 Global Stores Modified: 110 None 111 112 ------------------------------------------------------------------------------ 113 FUNCTION DESCRIPTION 114 115 This function applies Intensity Stereo, generating data on the right channel 116 that is derived from data on the Left. A scalefactor is applied using the 117 following formula... 118 119 RightCh = LeftCh*0.5^(scalefactor/4) 120 121 This function works for one scalefactor band, which may belong to a group. 122 (i.e. the same scalefactor band repeated across multiple windows belonging 123 to one group.) 124 125 ------------------------------------------------------------------------------ 126 REQUIREMENTS 127 128 codebook must be either INTENSITY_HCB or INTENSITY_HCB2 when this function 129 is called. 130 131 ms_used must be 1 when TRUE, 0 when FALSE. 132 133 wins_in_group falls within the range [1-8] 134 135 ------------------------------------------------------------------------------ 136 REFERENCES 137 138 (1) ISO/IEC 14496-3:1999(E) 139 Part 3 140 Subpart 4.6.7.2.3 Decoding Process (Intensity Stereo) 141 142 (2) MPEG-2 NBC Audio Decoder 143 "This software module was originally developed by AT&T, Dolby 144 Laboratories, Fraunhofer Gesellschaft IIS in the course of development 145 of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 146 3. This software module is an implementation of a part of one or more 147 MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 148 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio 149 standards free license to this software module or modifications thereof 150 for use in hardware or software products claiming conformance to the 151 MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software 152 module in hardware or software products are advised that this use may 153 infringe existing patents. The original developer of this software 154 module and his/her company, the subsequent editors and their companies, 155 and ISO/IEC have no liability for use of this software module or 156 modifications thereof in an implementation. Copyright is not released 157 for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original 158 developer retains full right to use the code for his/her own purpose, 159 assign or donate the code to a third party and to inhibit third party 160 from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. 161 This copyright notice must be included in all copies or derivative 162 works." 163 Copyright(c)1996. 164 165 ------------------------------------------------------------------------------ 166 PSEUDO-CODE 167 multiplier = codebook AND 0x1; 168 169 multiplier = multiplier XOR ms_used; 170 171 multiplier = multiplier << 1; 172 173 multiplier = multiplier - 1; 174 175 multiplier = multiplier * intensity_factor[scalefactor & 0x3]; 176 177 scf_div_4 = (scalefactor >> 2); 178 179 nextWinPtrUpdate = (coef_per_win - band_length); 180 181 FOR (win_indx = wins_in_group; win_indx > 0; win_indx--) 182 183 *(pQformatRight) = scf_div_4 + *(pQformatLeft) - 1; 184 185 FOR (tempInt = band_length; tempInt > 0; tempInt--) 186 tempInt2 = (Int)(*(pCoefLeft) >> 16); 187 188 *(pCoefRight) = tempInt2 * multiplier; 189 190 pCoefRight = pCoefRight + 1; 191 pCoefLeft = pCoefLeft + 1; 192 193 ENDFOR 194 195 pCoefRight = pCoefRight + nextWinPtrUpdate; 196 pCoefLeft = pCoefLeft + nextWinPtrUpdate; 197 198 pQformatRight = pQformatRight + sfb_per_win; 199 pQformatLeft = pQformatLeft + sfb_per_win; 200 ENDFOR 201 202 ------------------------------------------------------------------------------ 203 RESOURCES USED 204 When the code is written for a specific target processor the 205 resources used should be documented below. 206 207 STACK USAGE: [stack count for this module] + [variable to represent 208 stack usage for each subroutine called] 209 210 where: [stack usage variable] = stack usage for [subroutine 211 name] (see [filename].ext) 212 213 DATA MEMORY USED: x words 214 215 PROGRAM MEMORY USED: x words 216 217 CLOCK CYCLES: [cycle count equation for this module] + [variable 218 used to represent cycle count for each subroutine 219 called] 220 221 where: [cycle count variable] = cycle count for [subroutine 222 name] (see [filename].ext) 223 224 ------------------------------------------------------------------------------ 225 */ 226 227 228 /*---------------------------------------------------------------------------- 229 ; INCLUDES 230 ----------------------------------------------------------------------------*/ 231 #include "pv_audio_type_defs.h" 232 #include "intensity_right.h" 233 #include "e_huffmanconst.h" 234 235 #include "fxp_mul32.h" 236 #include "aac_mem_funcs.h" 237 238 239 /*---------------------------------------------------------------------------- 240 ; MACROS 241 ; Define module specific macros here 242 ----------------------------------------------------------------------------*/ 243 244 /*---------------------------------------------------------------------------- 245 ; DEFINES 246 ; Include all pre-processor statements here. Include conditional 247 ; compile variables also. 248 ----------------------------------------------------------------------------*/ 249 250 /*---------------------------------------------------------------------------- 251 ; LOCAL FUNCTION DEFINITIONS 252 ; Function Prototype declaration 253 ----------------------------------------------------------------------------*/ 254 255 /*---------------------------------------------------------------------------- 256 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS 257 ; Variable declaration - defined here and used outside this module 258 ----------------------------------------------------------------------------*/ 259 const Int16 intensity_factor[4] = 260 { 261 32767, /* (0.5^0.00)*2^15 - 1 (minus 1 for storage as type Int) */ 262 27554, /* (0.5^0.25)*2^15 */ 263 23170, /* (0.5^0.50)*2^15 */ 264 19484 265 }; /* (0.5^0.75)*2^15 */ 266 267 268 /*---------------------------------------------------------------------------- 269 ; EXTERNAL FUNCTION REFERENCES 270 ; Declare functions defined elsewhere and referenced in this module 271 ----------------------------------------------------------------------------*/ 272 273 /*---------------------------------------------------------------------------- 274 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 275 ; Declare variables used in this module but defined elsewhere 276 ----------------------------------------------------------------------------*/ 277 278 /*---------------------------------------------------------------------------- 279 ; FUNCTION CODE 280 ----------------------------------------------------------------------------*/ 281 282 void intensity_right( 283 const Int scalefactor, 284 const Int coef_per_win, 285 const Int sfb_per_win, 286 const Int wins_in_group, 287 const Int band_length, 288 const Int codebook, 289 const Bool ms_used, 290 const Int q_formatLeft[], 291 Int q_formatRight[], 292 const Int32 coefLeft[], 293 Int32 coefRight[]) 294 295 { 296 const Int32 *pCoefLeft = coefLeft; 297 Int32 *pCoefRight = coefRight; 298 299 const Int *pQformatLeft = q_formatLeft; 300 Int *pQformatRight = q_formatRight; 301 302 Int multiplier; 303 Int scf_div_4; 304 Int nextWinPtrUpdate; 305 306 /* 307 * The sign of the intensity multiplier obeys the following table... 308 * 309 * codebook | ms_used | multiplier 310 * -------------------------------------- 311 * INTENSITY_HCB | TRUE | -1 312 * INTENSITY_HCB | FALSE | +1 313 * INTENSITY_HCB2 | TRUE | +1 314 * INTENSITY_HCB2 | FALSE | -1 315 * 316 * In binary, the above table is represented as... 317 * 318 * codebook | ms_used | multiplier 319 * -------------------------------------- 320 * 1111b | 1 | -1 321 * 1111b | 0 | +1 322 * 1110b | 1 | +1 323 * 1110b | 0 | -1 324 * 325 */ 326 327 /* 328 * Deriving the correct value for "multiplier" is illustrated 329 * below for all 4 possible combinations of codebook and ms_used 330 */ 331 332 /* 333 * 1111b AND 0x1 = 1b 334 * 1111b AND 0x1 = 1b 335 * 1110b AND 0x1 = 0b 336 * 1110b AND 0x1 = 0b 337 */ 338 multiplier = (codebook & 0x1); 339 340 /* 341 * 1b XOR 1 = 0b 342 * 1b XOR 0 = 1b 343 * 0b XOR 1 = 1b 344 * 0b XOR 0 = 0b 345 */ 346 multiplier ^= ms_used; 347 348 /* 349 * 0b << 1 = 0 350 * 1b << 1 = 2 351 * 1b << 1 = 2 352 * 0b << 1 = 0 353 */ 354 multiplier <<= 1; 355 356 /* 357 * 0 - 1 = -1 358 * 2 - 1 = +1 359 * 2 - 1 = +1 360 * 0 - 1 = -1 361 */ 362 multiplier--; 363 364 multiplier *= intensity_factor[scalefactor & 0x3]; 365 366 scf_div_4 = (scalefactor >> 2); 367 368 /* 369 * Step through all the windows in this group, replacing this 370 * band in each window's spectrum with 371 * left-channel correlated data 372 */ 373 374 nextWinPtrUpdate = (coef_per_win - band_length); 375 376 for (Int win_indx = wins_in_group; win_indx > 0; win_indx--) 377 { 378 379 /* 380 * Calculate q_formatRight 381 * 382 * q_formatLeft must be included, since the values 383 * on the right-channel are derived from the values 384 * on the left-channel. 385 * 386 * scalefactor/4 is included, since the intensity 387 * formula is RightCh = LeftCh*0.5^(scalefactor/4) 388 * 389 * powers of 0.5 increase the q_format by 1. 390 * (Another way to multiply something by 0.5^(x) 391 * is to increase its q-format by x.) 392 * 393 * Finally the q-format must be decreased by 1. 394 * The reason for this is because the table is stored 395 * in q-15 format, but we are shifting by 16 to do 396 * a 16 x 16 multiply. 397 */ 398 399 *(pQformatRight) = scf_div_4 + *(pQformatLeft); 400 401 /* 402 * reconstruct right intensity values 403 * 404 * to make things faster, this for loop 405 * can be partially unrolled, since band_length is a multiple 406 * of four. 407 */ 408 409 410 if (multiplier == 32767) 411 { 412 Int32 tempInt2 = *(pCoefLeft++); 413 Int32 tempInt22 = *(pCoefLeft++); 414 415 for (Int tempInt = band_length >> 1; tempInt > 0; tempInt--) 416 { 417 *(pCoefRight++) = tempInt2; 418 *(pCoefRight++) = tempInt22; 419 tempInt2 = *(pCoefLeft++); 420 tempInt22 = *(pCoefLeft++); 421 } 422 423 } 424 else 425 { 426 427 Int32 tempInt2 = *(pCoefLeft++); 428 Int32 tempInt22 = *(pCoefLeft++); 429 for (Int tempInt = band_length >> 1; tempInt > 0; tempInt--) 430 { 431 *(pCoefRight++) = fxp_mul32_by_16(tempInt2, multiplier) << 1; 432 *(pCoefRight++) = fxp_mul32_by_16(tempInt22, multiplier) << 1; 433 tempInt2 = *(pCoefLeft++); 434 tempInt22 = *(pCoefLeft++); 435 } 436 } 437 438 /* 439 * Set pCoefRight and pCoefLeft to the beginning of 440 * this sfb in the next window in the group. 441 */ 442 443 pCoefRight += nextWinPtrUpdate; 444 pCoefLeft += (nextWinPtrUpdate - 2); 445 446 /* 447 * Update pQformatRight and pQformatLeft to this sfb in 448 * in the next window in the group. 449 */ 450 451 pQformatRight += sfb_per_win; 452 pQformatLeft += sfb_per_win; 453 454 } /* for (win_indx) */ 455 456 457 } /* void intensity_right */ 458