/* $Header: /cvs/root/winamp/vlb/dolby_imdct.cpp,v 1.1 2009/04/28 20:21:09 audiodsp Exp $ */ /***************************************************************************\ * * Copyright 2000-2002 Dolby Laboratories, Inc. All Rights * Reserved. Do not copy. Do not distribute. * Confidential information. * * filename: dolby_imdct.cpp * project : MPEG-2 AAC Decoder * contents/description: IMDCT transform routines * \***************************************************************************/ #include"dolby_imdct.h" #ifdef INTERPOLATE_WINDOW #include "window_tab.h" #endif /* #defines related to Izero and CalculateKBDWindowExact */ #define IzeroEPSILON 1E-21 /* Max error acceptable in Izero */ #define M_PI 3.14159265358979323846264338327950288f /*------------------------ Window Functions ---------------------------*/ void Sine_Window(float*pfWindow,int iSize) { #ifdef INTERPOLATE_WINDOW int count, j; switch (iSize) { case 256: for(j=0; j < iSize/2 ;j++) { pfWindow[j]=(float)(sin_short[j]); } break; case 512: count = 0; for (j = 0; j < iSize/4-1; j++) { pfWindow[count++] = (float) sin_short[j]; pfWindow[count++] = (float) ((sin_short[j] + sin_short[j + 1]) * 0.5); } pfWindow[count++] = (float) sin_short[j]; pfWindow[count] = (float) 1.0; break; case 2048: for(j=0; j < iSize/2 ;j++) { pfWindow[j]=(float)(sin_long[j]); } break; case 4096: count = 0; for (j = 0; j < iSize/4-1; j++) { pfWindow[count++] = (float) sin_long[j]; pfWindow[count++] = (float) ((sin_long[j] + sin_long[j + 1]) * 0.5); } pfWindow[count++] = (float) sin_long[j]; pfWindow[count] = (float) 1.0; break; } #else int n; for(n=0;n= IzeroEPSILON * sum); return (sum); } /***************************************************************************** functionname: CalculateKBDWindowExact description: calculates the window coefficients for the Kaiser-Bessel derived window returns: input: window length, alpha output: window coefficients *****************************************************************************/ void CalculateKBDWindowExact(float * win, float alpha, int length) { int i; float IBeta; float tmp; float sum = 0.0; alpha *= M_PI; IBeta = 1.0f / Izero(alpha); /* calculate lower half of Kaiser Bessel window */ for (i = 0; i < (length >> 1); i++) { tmp = 4.0f * (float) i / (float) length - 1.0f; win[i] = Izero(alpha * ((float) sqrt(1.0f - tmp * tmp))) * IBeta; sum += win[i]; } sum = 1.0f / sum; tmp = 0.0; /* calculate lower half of window */ for (i = 0; i < (length >> 1); i++) { tmp += win[i]; win[i] = (float) sqrt(tmp * sum); } } void KBD_Window(float*pfWindow,int iSize) { #ifdef INTERPOLATE_WINDOW int count, j; switch (iSize) { case 256: for(j=0; j < iSize/2 ;j++) { pfWindow[j]=(float)(KBD_short[j]); } break; case 512: count = 0; for (j = 0; j < iSize/4-1; j++) { pfWindow[count++] = (float) KBD_short[j]; pfWindow[count++] = (float) ((KBD_short[j] + KBD_short[j + 1]) * 0.5); } pfWindow[count++] = (float) KBD_short[j]; pfWindow[count] = (float) 1.0; break; case 2048: for(j=0; j < iSize/2 ;j++) { pfWindow[j]=(float)(KBD_long[j]); } break; case 4096: count = 0; for (j = 0; j < iSize/4-1; j++) { pfWindow[count++] = (float) KBD_long[j]; pfWindow[count++] = (float) ((KBD_long[j] + KBD_long[j + 1]) * 0.5); } pfWindow[count++] = (float) KBD_long[j]; pfWindow[count] = (float) 1.0; break; } #else /* The stock AAC MP4 encoder calculates KBD windows with different alphas depending on the blocklength. We must match those windows here. */ switch(iSize) { case 256: case 512: CalculateKBDWindowExact(pfWindow, 6.0, iSize); break; case 2048: case 4096: CalculateKBDWindowExact(pfWindow, 4.0, iSize); break; default: CalculateKBDWindowExact(pfWindow, 4.0, iSize); } #endif } /*----------------------- DOLBY IMDCT ---------------------------------*/ IMDCTObject::IMDCTObject(int _iLongSize, int _iOverlap) :iLongSize(_iLongSize), iHLongSize(_iLongSize/2), iOverlap(_iOverlap), iOldShape(0) { if(iLongSize==0){ return; } if(iOverlap==0){ return; } int n,k; //Obtain memory for Short Windows: //These arrays are larger than they need to be, //but are made this large for convenience iShortSize = iLongSize / 8; iHShortSize = iHLongSize / 8; pfShortWindowSin = new float[iHLongSize]; pfShortWindowKBD = new float[iHLongSize]; //Obtain memory for Longwindows: pfLongWindowSin=new float[iHLongSize]; pfS2LWindowSin=new float[iHLongSize]; pfLongWindowKBD=new float[iHLongSize]; pfS2LWindowKBD=new float[iHLongSize]; //Obtain memory for temporary buffer: pfTempBuffer=new float[iLongSize]; pfEightWindowsBuffer=new float[iLongSize]; pfSavedBuffer=new float[iHLongSize]; for(n=0;n