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 Pathname: pns_left.c 20 21 ------------------------------------------------------------------------------ 22 REVISION HISTORY 23 24 Description: Modified from original shareware code 25 26 Description: Brought code in-line with PV standards. 27 Merged PNS and Intensity blocks into one function. 28 Modified routine to interface with a fixed-point implementation. 29 Modified variable names for clarity. 30 Improved for-loop structure that was previously checking 31 the codebook used in each scale factor band multiple times. 32 33 Description: Added some comments for clarity. 34 35 Description: Changed strategy for q-format. Q-format for SFBs should not 36 be grouped. 37 38 Description: Function had to be modified to obey new interpretation of the 39 sfb_prediction_used flag. LTP takes precedence, and PNS should not be 40 executed when a collision occurs between these two tools. 41 42 Description: 43 (1) Added flag "ltp_data_present" 44 (2) Where feasible, I updated the code to resemble right_ch_sfb_tools_ms.c 45 Just for conformance, readability. 46 47 Description: Added include file - "e_huffmanconst.h" 48 49 Description: The same "Factors" pointer indexing problem that existed in 50 right_ch_sfb_tools_ms also existed here in pns_left.c 51 52 Description: Modified how groups and windows are handled, as the multigroup 53 case was not correct 54 55 Who: Date: 56 Description: 57 ------------------------------------------------------------------------------ 58 INPUT AND OUTPUT DEFINITIONS 59 60 Inputs: 61 62 const FrameInfo *pFrameInfo = Pointer to structure that holds 63 information about each group. 64 (long block flag, 65 number of windows, 66 scalefactor bands per group, etc.) 67 68 const Int group[] = Array that contains indexes of the 69 the first window in the next group. 70 71 const Int codebook_map[] = Array that denotes which Huffman 72 codebook was used for the encoding 73 of each scalefactor band. 74 75 const Int factors[] = Array of scalefactors 76 77 Int sfb_prediction_used[] = Flag that denotes the activation 78 of long term prediction on a sfb 79 basis. 80 81 Bool ltp_data_present = Flag that denotes whether LTP 82 is active for the entire frame. If 83 this flag is FALSE, 84 sfb_prediction_used is garbage. 85 86 Int32 spectral_coef[] = Array of pointers pointing to the 87 spectral coef's for the LEFT channel. 88 89 Int q_format[] = Q-format for the information 90 pointed to by spectral_coef. 91 Indexed by scalefactor band. 92 93 Int32 *pCurrentSeed = Pointer to the current seed for the 94 random number generator. 95 (gen_rand_vector) 96 97 Local Stores/Buffers/Pointers Needed: 98 99 Global Stores/Buffers/Pointers Needed: 100 101 Outputs: 102 103 Pointers and Buffers Modified: 104 Int32 spectral_coef[] = Contains the new spectral information 105 106 Local Stores Modified: 107 108 Global Stores Modified: 109 110 ------------------------------------------------------------------------------ 111 FUNCTION DESCRIPTION 112 113 The function steps through each scalefactor band in the group, and 114 checks for the use of Huffman codebook NOISE_HCB. 115 116 When a SFB utilizing NOISE_HCB is detected, the band in every window in the 117 group has its spectral information filled with scaled random data. 118 119 The scaled random data is generated by the function gen_rand_vector. 120 121 ------------------------------------------------------------------------------ 122 REQUIREMENTS 123 124 This module shall replace bands that were encoded with the Huffman codebook 125 NOISE_HCB with random noise as returned from gen_rand_vector(). The result 126 shall be perceptually indistinguishable from the result obtained by the 127 ISO decoder. 128 129 ------------------------------------------------------------------------------ 130 REFERENCES 131 132 (1) ISO/IEC 14496-3:1999(E) 133 Part 3 134 Subpart 4.5.5 Figures 135 Subpart 4.6.2 ScaleFactors 136 Subpart 4.6.12 Perceptual Noise Substituion (PNS) 137 138 (2) MPEG-2 NBC Audio Decoder 139 "This software module was originally developed by AT&T, Dolby 140 Laboratories, Fraunhofer Gesellschaft IIS in the course of development 141 of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 142 3. This software module is an implementation of a part of one or more 143 MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 144 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio 145 standards free license to this software module or modifications thereof 146 for use in hardware or software products claiming conformance to the 147 MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software 148 module in hardware or software products are advised that this use may 149 infringe existing patents. The original developer of this software 150 module and his/her company, the subsequent editors and their companies, 151 and ISO/IEC have no liability for use of this software module or 152 modifications thereof in an implementation. Copyright is not released 153 for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original 154 developer retains full right to use the code for his/her own purpose, 155 assign or donate the code to a third party and to inhibit third party 156 from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. 157 This copyright notice must be included in all copies or derivative 158 works." 159 Copyright(c)1996. 160 161 ------------------------------------------------------------------------------ 162 PSEUDO-CODE 163 164 pFirst_Window_Coefs = spectral_coef; 165 166 window_start = 0; 167 168 tot_sfb = 0; 169 170 DO 171 172 num_bands = pFrameInfo->sfb_per_win[window_start]; 173 pBand = pFrameInfo->win_sfb_top[window_start]; 174 175 partition = *(pGroup); 176 pGroup = pGroup + 1; 177 178 band_start = 0; 179 180 coef_per_win = pFrameInfo->coef_per_win[window_start]; 181 182 wins_in_group = (partition - window_start); 183 184 FOR (sfb = num_bands; sfb > 0; sfb--) 185 186 band_stop = *pBand; 187 pBand = pBand + 1; 188 189 IF (*(pCodebookMap++) == NOISE_HCB ) 190 191 tempInt = sfb_prediction_used[tot_sfb] AND ltp_data_present; 192 193 IF (tempInt == FALSE) 194 195 pWindow_Coef = pFirst_Window_Coefs + band_start; 196 197 band_length = (band_stop - band_start); 198 199 start_indx = tot_sfb; 200 201 tempInt = *(pFactors); 202 203 FOR (win_indx = wins_in_group; win_indx > 0; win_indx--) 204 205 CALL gen_rand_vector( pWindow_CoefR, 206 band_length, 207 pCurrentSeed, 208 tempInt); 209 210 MODIFYING pWindow_CoefR = scaled random noise 211 pCurrentSeed = current state of the random 212 noise generator. 213 214 RETURNING q_format[start_indx] = q-format for this sfb. 215 216 pWindow_Coef = pWindow_Coef + coef_per_win; 217 218 start_indx = start_indx + 219 pFrameInfo->sfb_per_win[win_indx]; 220 221 ENDFOR 222 223 ENDIF 224 225 ENDIF 226 227 band_start = band_stop; 228 229 tot_sfb = tot_sfb + 1; 230 231 pFactors = pFactors + 1; 232 233 ENDFOR 234 235 coef_per_win = coef_per_win * wins_in_group; 236 wins_in_group = wins_in_group - 1; 237 238 tot_sfb = tot_sfb + num_bands * wins_in_group; 239 pFactors = pFactors + num_bands * wins_in_group; 240 241 pFirst_Window_Coefs = pFirst_Window_Coefs + coef_per_win; 242 243 window_start = partition; 244 245 WHILE (partition < pFrameInfo->num_win); 246 247 ------------------------------------------------------------------------------ 248 RESOURCES USED 249 When the code is written for a specific target processor the 250 the resources used should be documented below. 251 252 STACK USAGE: [stack count for this module] + [variable to represent 253 stack usage for each subroutine called] 254 255 where: [stack usage variable] = stack usage for [subroutine 256 name] (see [filename].ext) 257 258 DATA MEMORY USED: x words 259 260 PROGRAM MEMORY USED: x words 261 262 CLOCK CYCLES: [cycle count equation for this module] + [variable 263 used to represent cycle count for each subroutine 264 called] 265 266 where: [cycle count variable] = cycle count for [subroutine 267 name] (see [filename].ext) 268 269 ------------------------------------------------------------------------------ 270 */ 271 272 273 /*---------------------------------------------------------------------------- 274 ; INCLUDES 275 ----------------------------------------------------------------------------*/ 276 #include "pv_audio_type_defs.h" 277 #include "pns_left.h" 278 #include "e_huffmanconst.h" 279 #include "gen_rand_vector.h" 280 281 /*---------------------------------------------------------------------------- 282 ; MACROS 283 ; Define module specific macros here 284 ----------------------------------------------------------------------------*/ 285 286 /*---------------------------------------------------------------------------- 287 ; DEFINES 288 ; Include all pre-processor statements here. Include conditional 289 ; compile variables also. 290 ----------------------------------------------------------------------------*/ 291 292 /*---------------------------------------------------------------------------- 293 ; LOCAL FUNCTION DEFINITIONS 294 ; Function Prototype declaration 295 ----------------------------------------------------------------------------*/ 296 297 /*---------------------------------------------------------------------------- 298 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS 299 ; Variable declaration - defined here and used outside this module 300 ----------------------------------------------------------------------------*/ 301 302 /*---------------------------------------------------------------------------- 303 ; EXTERNAL FUNCTION REFERENCES 304 ; Declare functions defined elsewhere and referenced in this module 305 ----------------------------------------------------------------------------*/ 306 307 /*---------------------------------------------------------------------------- 308 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 309 ; Declare variables used in this module but defined elsewhere 310 ----------------------------------------------------------------------------*/ 311 312 /*---------------------------------------------------------------------------- 313 ; FUNCTION CODE 314 ----------------------------------------------------------------------------*/ 315 316 void pns_left( 317 const FrameInfo *pFrameInfo, 318 const Int group[], 319 const Int codebook_map[], 320 const Int factors[], 321 const Int sfb_prediction_used[], 322 const Bool ltp_data_present, 323 Int32 spectral_coef[], 324 Int q_format[], 325 Int32 *pCurrentSeed) 326 { 327 328 Int tot_sfb; 329 Int start_indx; 330 331 Int sfb; 332 Int band_stop; 333 334 const Int16 *pBand; 335 336 const Int *pCodebookMap = &(codebook_map[0]); 337 const Int *pGroup = &(group[0]); 338 const Int *pFactors = &(factors[0]); 339 340 Int tempInt; 341 Int32 *pWindow_Coef; 342 343 344 Int32 *spec; 345 346 Int partition; 347 Int win_indx; 348 349 tot_sfb = 0; 350 351 spec = spectral_coef; 352 353 /* PNS goes by group */ 354 win_indx = 0; 355 partition = 0; 356 do 357 { 358 Int num_bands = pFrameInfo->sfb_per_win[partition]; 359 pBand = pFrameInfo->win_sfb_top[partition]; 360 361 /*---------------------------------------------------------- 362 Partition is equal to the first window in the next group 363 364 { Group 0 }{ Group 1 }{ Group 2 }{Group 3} 365 [win 0][win 1][win 2][win 3][win 4][win 5][win 6][win 7] 366 367 pGroup[0] = 2 368 pGroup[1] = 5 369 pGroup[2] = 7 370 pGroup[3] = 8 371 -----------------------------------------------------------*/ 372 373 partition = *pGroup++; /* partition = index of last sbk in group */ 374 375 do 376 { 377 Int band_start = 0; 378 for (sfb = 0; sfb < num_bands; sfb++) 379 { 380 band_stop = pBand[sfb]; /* band is offset table, band_stop is last coef in band */ 381 382 Int band_length = band_stop - band_start; 383 if (pCodebookMap[sfb] == NOISE_HCB) 384 { 385 386 tempInt = sfb_prediction_used[tot_sfb] & ltp_data_present; 387 388 if (tempInt == FALSE) 389 { 390 /* generate random noise */ 391 pWindow_Coef = spec + band_start; 392 393 tempInt = pFactors[sfb]; 394 395 start_indx = tot_sfb++; 396 397 /* reconstruct noise substituted values */ 398 /* generate random noise */ 399 400 q_format[start_indx] = gen_rand_vector(pWindow_Coef, 401 band_length, 402 pCurrentSeed, 403 tempInt); 404 405 } /* if (sfb_prediction_used[tot_sfb] == FALSE) */ 406 407 } /* if (*(pCodebookMap++) == NOISE_HCB) */ 408 else 409 { 410 tot_sfb ++; /* update absolute sfb counter */ 411 } 412 413 band_start = band_stop; 414 415 } /* for (sfb) */ 416 417 spec += pFrameInfo->coef_per_win[win_indx++]; 418 pFactors += num_bands; 419 420 } 421 while (win_indx < partition); 422 423 pCodebookMap += pFrameInfo->sfb_per_win[win_indx-1]; 424 425 } 426 while (partition < pFrameInfo->num_win); 427 428 429 return; 430 431 } /* pns */ 432