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 Filename: sbr_update_freq_scale.c 21 22------------------------------------------------------------------------------ 23 REVISION HISTORY 24 25 26 Who: Date: MM/DD/YYYY 27 Description: 28 29------------------------------------------------------------------------------ 30 INPUT AND OUTPUT DEFINITIONS 31 32 33 34------------------------------------------------------------------------------ 35 FUNCTION DESCRIPTION 36 37 38------------------------------------------------------------------------------ 39 REQUIREMENTS 40 41 42------------------------------------------------------------------------------ 43 REFERENCES 44 45SC 29 Software Copyright Licencing Disclaimer: 46 47This software module was originally developed by 48 Coding Technologies 49 50and edited by 51 - 52 53in the course of development of the ISO/IEC 13818-7 and ISO/IEC 14496-3 54standards for reference purposes and its performance may not have been 55optimized. This software module is an implementation of one or more tools as 56specified by the ISO/IEC 13818-7 and ISO/IEC 14496-3 standards. 57ISO/IEC gives users free license to this software module or modifications 58thereof for use in products claiming conformance to audiovisual and 59image-coding related ITU Recommendations and/or ISO/IEC International 60Standards. ISO/IEC gives users the same free license to this software module or 61modifications thereof for research purposes and further ISO/IEC standardisation. 62Those intending to use this software module in products are advised that its 63use may infringe existing patents. ISO/IEC have no liability for use of this 64software module or modifications thereof. Copyright is not released for 65products that do not conform to audiovisual and image-coding related ITU 66Recommendations and/or ISO/IEC International Standards. 67The original developer retains full right to modify and use the code for its 68own purpose, assign or donate the code to a third party and to inhibit third 69parties from using the code for products that do not conform to audiovisual and 70image-coding related ITU Recommendations and/or ISO/IEC International Standards. 71This copyright notice must be included in all copies or derivative works. 72Copyright (c) ISO/IEC 2002. 73 74------------------------------------------------------------------------------ 75 PSEUDO-CODE 76 77------------------------------------------------------------------------------ 78*/ 79 80 81/*---------------------------------------------------------------------------- 82; INCLUDES 83----------------------------------------------------------------------------*/ 84 85#ifdef AAC_PLUS 86 87 88#include "sbr_update_freq_scale.h" 89#include "shellsort.h" 90 91#include "pv_pow2.h" 92#include "pv_log2.h" 93 94#include "fxp_mul32.h" 95#define R_SHIFT 30 96#define Q_fmt(x) (Int32)(x*((Int32)1<<R_SHIFT) + (x>=0?0.5F:-0.5F)) 97#define Q28fmt(x) (Int32)(x*((Int32)1<<28) + (x>=0?0.5F:-0.5F)) 98 99/*---------------------------------------------------------------------------- 100; MACROS 101; Define module specific macros here 102----------------------------------------------------------------------------*/ 103 104 105/*---------------------------------------------------------------------------- 106; DEFINES 107; Include all pre-processor statements here. Include conditional 108; compile variables also. 109----------------------------------------------------------------------------*/ 110 111/*---------------------------------------------------------------------------- 112; LOCAL FUNCTION DEFINITIONS 113; Function Prototype declaration 114----------------------------------------------------------------------------*/ 115 116/*---------------------------------------------------------------------------- 117; LOCAL STORE/BUFFER/POINTER DEFINITIONS 118; Variable declaration - defined here and used outside this module 119----------------------------------------------------------------------------*/ 120 121/*---------------------------------------------------------------------------- 122; EXTERNAL FUNCTION REFERENCES 123; Declare functions defined elsewhere and referenced in this module 124----------------------------------------------------------------------------*/ 125 126/*---------------------------------------------------------------------------- 127; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 128; Declare variables used in this module but defined elsewhere 129----------------------------------------------------------------------------*/ 130 131/*---------------------------------------------------------------------------- 132; FUNCTION CODE 133----------------------------------------------------------------------------*/ 134 135 136 137void sbr_update_freq_scale(Int32 * v_k_master, 138 Int32 *h_num_bands, 139 const Int32 lsbM, 140 const Int32 usb, 141 const Int32 freqScale, 142 const Int32 alterScale, 143 const Int32 channelOffset) 144{ 145 Int32 i; 146 Int32 numBands = 0; 147 Int32 numBands2; 148 Int32 tmp_q1; 149 150 if (freqScale > 0) /*Bark mode*/ 151 { 152 Int32 reg; 153 Int32 regions; 154 Int32 b_p_o; 155 Int32 k[3]; 156 Int32 d[MAX_SECOND_REGION]; 157 Int32 d2[MAX_SECOND_REGION]; 158 Int32 w[2] = {Q_fmt(1.0F), Q_fmt(1.0F)}; 159 160 161 k[0] = lsbM; 162 k[1] = usb; 163 k[2] = usb; 164 165 b_p_o = (freqScale == 1) ? 12 : 8; 166 b_p_o = (freqScale == 2) ? 10 : b_p_o; 167 168 w[1] = (alterScale == 0) ? Q_fmt(0.5f) : Q_fmt(0.384615384615386f); 169 170 if (usb > fxp_mul32_Q28(lsbM, Q28fmt(2.2449))) 171 { 172 regions = 2; 173 k[1] = (lsbM << 1); 174 } 175 else 176 { 177 regions = 1; 178 } 179 180 *h_num_bands = 0; 181 for (reg = 0; reg < regions; reg++) 182 { 183 if (reg == 0) 184 { 185 186 tmp_q1 = pv_log2((k[1] << 20) / k[0]); 187 188 tmp_q1 = fxp_mul32_Q15(tmp_q1, b_p_o); 189 tmp_q1 = (tmp_q1 + 32) >> 6; 190 191 numBands = tmp_q1 << 1; 192 193 194 CalcBands(d, k[0], k[1], numBands); /* CalcBands => d */ 195 shellsort(d, numBands); /* SortBands sort d */ 196 cumSum(k[0] - channelOffset, 197 d, 198 numBands, 199 (v_k_master + *h_num_bands)); /* cumsum */ 200 201 *h_num_bands += numBands; /* Output nr of bands */ 202 } 203 else 204 { 205 tmp_q1 = pv_log2((k[reg + 1] << 20) / k[reg]); 206 207 tmp_q1 = fxp_mul32_Q30(tmp_q1, w[reg]); 208 tmp_q1 = fxp_mul32_Q15(tmp_q1, b_p_o); 209 tmp_q1 = (tmp_q1 + 16) >> 5; 210 211 numBands2 = tmp_q1 << 1; 212 213 CalcBands(d2, k[reg], k[reg+1], numBands2); /* CalcBands => d */ 214 shellsort(d2, numBands2); /* SortBands sort d */ 215 if (d[numBands-1] > d2[0]) 216 { 217 218 Int32 change = d[numBands-1] - d2[0]; 219 /* Limit the change so that the last band cannot get narrower than the first one */ 220 if (change > (d2[numBands2-1] - d2[0]) >> 1) 221 { 222 change = (d2[numBands2-1] - d2[0]) >> 1; 223 } 224 225 d2[0] += change; 226 d2[numBands2-1] -= change; 227 shellsort(d2, numBands2); 228 229 } 230 cumSum(k[reg] - channelOffset, 231 d2, 232 numBands2, 233 v_k_master + *h_num_bands); /* cumsum */ 234 235 *h_num_bands += numBands2; /* Output nr of bands */ 236 } 237 } 238 } 239 else 240 { /* Linear mode */ 241 Int32 k2_achived; 242 Int32 k2_diff; 243 Int32 diff_tot[MAX_OCTAVE + MAX_SECOND_REGION]; 244 Int32 dk; 245 Int32 incr = 0; 246 247 248 if (alterScale) 249 { 250 numBands = (usb - lsbM) >> 1; 251 dk = 1; 252 k2_achived = lsbM + numBands; 253 } 254 else 255 { 256 numBands = usb - lsbM; 257 if (numBands & 0x1) /* equivalent rounding */ 258 { 259 numBands--; 260 } 261 dk = 2; 262 k2_achived = lsbM + (numBands << 1); 263 } 264 265 k2_diff = usb - k2_achived; 266 267 for (i = 0; i < numBands; i++) 268 { 269 diff_tot[i] = dk; 270 } 271 272 if (k2_diff < 0) /* If linear scale wasn't achived */ 273 { 274 incr = 1; /* and we got too large SBR area */ 275 i = 0; 276 } 277 278 if (k2_diff > 0) /* If linear scale wasn't achived */ 279 { 280 incr = -1; /* and we got too small SBR area */ 281 i = numBands - 1; 282 } 283 284 /* Adjust diff vector to get spec. SBR range */ 285 while (k2_diff != 0) 286 { 287 diff_tot[i] -= incr; 288 i += incr; 289 k2_diff += incr; 290 } 291 292 cumSum(lsbM, 293 diff_tot, 294 numBands, 295 v_k_master); /* cumsum */ 296 297 *h_num_bands = numBands; /* Output nr of bands */ 298 } 299} 300 301 302void CalcBands(Int32 * diff, 303 Int32 start, 304 Int32 stop, 305 Int32 num_bands) 306{ 307 Int32 i; 308 Int32 previous; 309 Int32 current; 310 Int32 tmp_q1; 311 312 313 previous = start; 314 315 for (i = 1; i <= num_bands; i++) 316 { 317 /* float temp=(start * pow( (float)stop/start, (float)i/num_bands)); */ 318 319 tmp_q1 = pv_log2((stop << 20) / start); 320 321 tmp_q1 = fxp_mul32_Q20(tmp_q1, (i << 27) / num_bands); 322 tmp_q1 = pv_pow2(tmp_q1); 323 324 tmp_q1 = fxp_mul32_Q20(tmp_q1, start); 325 326 current = (tmp_q1 + 16) >> 5; 327 328 diff[i-1] = current - previous; 329 previous = current; 330 } 331 332} /* End CalcBands */ 333 334 335void cumSum(Int32 start_value, 336 Int32 * diff, 337 Int32 length, 338 Int32 * start_adress) 339{ 340 Int32 i; 341 Int32 *pt_start_adress = start_adress; 342 Int32 *pt_start_adress_1 = start_adress; 343 Int32 *pt_diff = diff; 344 345 if (length > 0) /* avoid possible error on loop */ 346 { 347 *(pt_start_adress_1++) = start_value; 348 349 for (i = (length >> 1); i != 0; i--) 350 { 351 *(pt_start_adress_1++) = *(pt_start_adress++) + *(pt_diff++); 352 *(pt_start_adress_1++) = *(pt_start_adress++) + *(pt_diff++); 353 } 354 355 if (length&1) 356 { 357 *(pt_start_adress_1) = *(pt_start_adress) + *(pt_diff); 358 } 359 } 360 361} /* End cumSum */ 362 363 364#endif 365