1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6 
7  1.    INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18 
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28 
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33 
34 2.    COPYRIGHT LICENSE
35 
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39 
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42 
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48 
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51 
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54 
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60 
61 3.    NO PATENT LICENSE
62 
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67 
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70 
71 4.    DISCLAIMER
72 
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83 
84 5.    CONTACT INFORMATION
85 
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90 
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94 
95 /*********************** MPEG surround encoder library *************************
96 
97    Author(s):   Max Neuendorf
98 
99    Description: Encoder Library Interface
100                 Get windows for framing
101 
102 *******************************************************************************/
103 
104 /**************************************************************************/ /**
105    \file
106    Description of file contents
107  ******************************************************************************/
108 
109 /* Includes ******************************************************************/
110 #include "sacenc_framewindowing.h"
111 #include "sacenc_vectorfunctions.h"
112 
113 /* Defines *******************************************************************/
114 
115 /* Data Types ****************************************************************/
116 typedef struct T_FRAMEWINDOW {
117   INT nTimeSlotsMax;
118   INT bFrameKeep;
119   INT startSlope;
120   INT stopSlope;
121   INT startRect;
122   INT stopRect;
123 
124   INT taperAnaLen;
125   INT taperSynLen;
126   FIXP_WIN pTaperAna__FDK[MAX_TIME_SLOTS];
127   FIXP_WIN pTaperSyn__FDK[MAX_TIME_SLOTS];
128 
129 } FRAMEWINDOW;
130 
131 typedef enum {
132   FIX_INVALID = -1,
133   FIX_RECT_SMOOTH = 0,
134   FIX_SMOOTH_RECT = 1,
135   FIX_LARGE_SMOOTH = 2,
136   FIX_RECT_TRIANG = 3
137 
138 } FIX_TYPE;
139 
140 typedef enum {
141   VAR_INVALID = -1,
142   VAR_HOLD = 0,
143   VAR_ISOLATE = 1
144 
145 } VAR_TYPE;
146 
147 /* Constants *****************************************************************/
148 
149 /* Function / Class Declarations *********************************************/
150 
151 /* Function / Class Definition ***********************************************/
calcTaperWin(FIXP_WIN * pTaperWin,INT timeSlots)152 static void calcTaperWin(FIXP_WIN *pTaperWin, INT timeSlots) {
153   FIXP_DBL x;
154   int i, scale;
155 
156   for (i = 0; i < timeSlots; i++) {
157     x = fDivNormHighPrec((FIXP_DBL)i, (FIXP_DBL)timeSlots, &scale);
158 
159     if (scale < 0) {
160       pTaperWin[i] = FX_DBL2FX_WIN(x >> (-scale));
161     } else {
162       pTaperWin[i] = FX_DBL2FX_WIN(x << (scale));
163     }
164   }
165   pTaperWin[timeSlots] = FX_DBL2FX_WIN((FIXP_DBL)MAXVAL_DBL);
166 }
167 
fdk_sacenc_frameWindow_Create(HANDLE_FRAMEWINDOW * phFrameWindow)168 FDK_SACENC_ERROR fdk_sacenc_frameWindow_Create(
169     HANDLE_FRAMEWINDOW *phFrameWindow) {
170   FDK_SACENC_ERROR error = SACENC_OK;
171 
172   if (NULL == phFrameWindow) {
173     error = SACENC_INVALID_HANDLE;
174   } else {
175     /* Memory Allocation */
176     FDK_ALLOCATE_MEMORY_1D(*phFrameWindow, 1, FRAMEWINDOW);
177   }
178   return error;
179 
180 bail:
181   fdk_sacenc_frameWindow_Destroy(phFrameWindow);
182   return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
183 }
184 
fdk_sacenc_frameWindow_Init(HANDLE_FRAMEWINDOW hFrameWindow,const FRAMEWINDOW_CONFIG * const pFrameWindowConfig)185 FDK_SACENC_ERROR fdk_sacenc_frameWindow_Init(
186     HANDLE_FRAMEWINDOW hFrameWindow,
187     const FRAMEWINDOW_CONFIG *const pFrameWindowConfig) {
188   FDK_SACENC_ERROR error = SACENC_OK;
189 
190   if ((hFrameWindow == NULL) || (pFrameWindowConfig == NULL)) {
191     error = SACENC_INVALID_HANDLE;
192   } else if (pFrameWindowConfig->nTimeSlotsMax < 0) {
193     error = SACENC_INIT_ERROR;
194   } else {
195     int ts;
196     hFrameWindow->bFrameKeep = pFrameWindowConfig->bFrameKeep;
197     hFrameWindow->nTimeSlotsMax = pFrameWindowConfig->nTimeSlotsMax;
198 
199     FIXP_WIN winMaxVal = FX_DBL2FX_WIN((FIXP_DBL)MAXVAL_DBL);
200     int timeSlots = pFrameWindowConfig->nTimeSlotsMax;
201     {
202       hFrameWindow->startSlope = 0;
203       hFrameWindow->stopSlope = ((3 * timeSlots) >> 1) - 1;
204       hFrameWindow->startRect = timeSlots >> 1;
205       hFrameWindow->stopRect = timeSlots;
206       calcTaperWin(hFrameWindow->pTaperSyn__FDK, timeSlots >> 1);
207       hFrameWindow->taperSynLen = timeSlots >> 1;
208     }
209 
210     /* Calculate Taper for non-rect. ana. windows */
211     hFrameWindow->taperAnaLen =
212         hFrameWindow->startRect - hFrameWindow->startSlope;
213     for (ts = 0; ts < hFrameWindow->taperAnaLen; ts++) {
214       { hFrameWindow->pTaperAna__FDK[ts] = winMaxVal; }
215     }
216   }
217 
218   return error;
219 }
220 
fdk_sacenc_frameWindow_Destroy(HANDLE_FRAMEWINDOW * phFrameWindow)221 FDK_SACENC_ERROR fdk_sacenc_frameWindow_Destroy(
222     HANDLE_FRAMEWINDOW *phFrameWindow) {
223   FDK_SACENC_ERROR error = SACENC_OK;
224 
225   if ((NULL != phFrameWindow) && (NULL != *phFrameWindow)) {
226     FDKfree(*phFrameWindow);
227     *phFrameWindow = NULL;
228   }
229   return error;
230 }
231 
FrameWinList_Reset(FRAMEWIN_LIST * const pFrameWinList)232 static FDK_SACENC_ERROR FrameWinList_Reset(FRAMEWIN_LIST *const pFrameWinList) {
233   FDK_SACENC_ERROR error = SACENC_OK;
234 
235   if (NULL == pFrameWinList) {
236     error = SACENC_INVALID_HANDLE;
237   } else {
238     int k = 0;
239     for (k = 0; k < MAX_NUM_PARAMS; k++) {
240       pFrameWinList->dat[k].slot = -1;
241       pFrameWinList->dat[k].hold = FW_INTP;
242     }
243     pFrameWinList->n = 0;
244   }
245   return error;
246 }
247 
FrameWindowList_Add(FRAMEWIN_LIST * const pFrameWinList,const INT slot,const FW_SLOTTYPE hold)248 static FDK_SACENC_ERROR FrameWindowList_Add(FRAMEWIN_LIST *const pFrameWinList,
249                                             const INT slot,
250                                             const FW_SLOTTYPE hold) {
251   FDK_SACENC_ERROR error = SACENC_OK;
252 
253   if (NULL == pFrameWinList) {
254     error = SACENC_INVALID_HANDLE;
255   } else {
256     if (pFrameWinList->n >= MAX_NUM_PARAMS) { /* Place left in List ?*/
257       error = SACENC_PARAM_ERROR;
258     } else if (pFrameWinList->n > 0 &&
259                pFrameWinList->dat[pFrameWinList->n - 1].slot - slot > 0) {
260       error = SACENC_PARAM_ERROR;
261     } else {
262       pFrameWinList->dat[pFrameWinList->n].slot = slot;
263       pFrameWinList->dat[pFrameWinList->n].hold = hold;
264       pFrameWinList->n++;
265     }
266   }
267   return error;
268 }
269 
FrameWindowList_Remove(FRAMEWIN_LIST * const pFrameWinList,const INT idx)270 static FDK_SACENC_ERROR FrameWindowList_Remove(
271     FRAMEWIN_LIST *const pFrameWinList, const INT idx) {
272   FDK_SACENC_ERROR error = SACENC_OK;
273 
274   if (NULL == pFrameWinList) {
275     error = SACENC_INVALID_HANDLE;
276   } else {
277     int k = 0;
278     if (idx < 0 || idx >= MAX_NUM_PARAMS) {
279       error = SACENC_PARAM_ERROR;
280     } else if (pFrameWinList->n > 0) {
281       if (idx == MAX_NUM_PARAMS - 1) {
282         pFrameWinList->dat[idx].slot = -1;
283         pFrameWinList->dat[idx].hold = FW_INTP;
284       } else {
285         for (k = idx; k < MAX_NUM_PARAMS - 1; k++) {
286           pFrameWinList->dat[k] = pFrameWinList->dat[k + 1];
287         }
288       }
289       pFrameWinList->n--;
290     }
291   }
292   return error;
293 }
294 
FrameWindowList_Limit(FRAMEWIN_LIST * const pFrameWinList,const INT ll,const INT ul)295 static FDK_SACENC_ERROR FrameWindowList_Limit(
296     FRAMEWIN_LIST *const pFrameWinList, const INT ll /*lower limit*/,
297     const INT ul /*upper limit*/
298 ) {
299   FDK_SACENC_ERROR error = SACENC_OK;
300 
301   if (NULL == pFrameWinList) {
302     error = SACENC_INVALID_HANDLE;
303   } else {
304     int k = 0;
305     for (k = 0; k < pFrameWinList->n; k++) {
306       if (pFrameWinList->dat[k].slot < ll || pFrameWinList->dat[k].slot > ul) {
307         FrameWindowList_Remove(pFrameWinList, k);
308         --k;
309       }
310     }
311   }
312   return error;
313 }
314 
fdk_sacenc_frameWindow_GetWindow(HANDLE_FRAMEWINDOW hFrameWindow,INT tr_pos[MAX_NUM_PARAMS],const INT timeSlots,FRAMINGINFO * const pFramingInfo,FIXP_WIN * pWindowAna__FDK[MAX_NUM_PARAMS],FRAMEWIN_LIST * const pFrameWinList,const INT avoid_keep)315 FDK_SACENC_ERROR fdk_sacenc_frameWindow_GetWindow(
316     HANDLE_FRAMEWINDOW hFrameWindow, INT tr_pos[MAX_NUM_PARAMS],
317     const INT timeSlots, FRAMINGINFO *const pFramingInfo,
318     FIXP_WIN *pWindowAna__FDK[MAX_NUM_PARAMS],
319     FRAMEWIN_LIST *const pFrameWinList, const INT avoid_keep) {
320   FDK_SACENC_ERROR error = SACENC_OK;
321 
322   if ((hFrameWindow == NULL) || (tr_pos == NULL) || (pFramingInfo == NULL) ||
323       (pFrameWinList == NULL) || (pWindowAna__FDK == NULL)) {
324     error = SACENC_INVALID_HANDLE;
325   } else {
326     const VAR_TYPE varType = VAR_HOLD;
327     const int tranL = 4;
328     int winCnt = 0;
329     int w, ps;
330 
331     int startSlope = hFrameWindow->startSlope;
332     int stopSlope = hFrameWindow->stopSlope;
333     int startRect = hFrameWindow->startRect;
334     int stopRect = hFrameWindow->stopRect;
335     int taperAnaLen = hFrameWindow->taperAnaLen;
336 
337     FIXP_WIN winMaxVal = FX_DBL2FX_WIN((FIXP_DBL)MAXVAL_DBL);
338     FIXP_WIN applyRightWindowGain__FDK[MAX_NUM_PARAMS];
339     FIXP_WIN *pTaperAna__FDK = hFrameWindow->pTaperAna__FDK;
340 
341     /* sanity check */
342     for (ps = 0; ps < MAX_NUM_PARAMS; ps++) {
343       if (pWindowAna__FDK[ps] == NULL) {
344         error = SACENC_INVALID_HANDLE;
345         goto bail;
346       }
347     }
348 
349     if ((timeSlots > hFrameWindow->nTimeSlotsMax) || (timeSlots < 0)) {
350       error = SACENC_INVALID_CONFIG;
351       goto bail;
352     }
353 
354     /* Reset */
355     if (SACENC_OK != (error = FrameWinList_Reset(pFrameWinList))) goto bail;
356 
357     FDKmemclear(applyRightWindowGain__FDK, sizeof(applyRightWindowGain__FDK));
358 
359     if (tr_pos[0] > -1) { /* Transients in first (left) half? */
360       int p_l = tr_pos[0];
361       winCnt = 0;
362 
363       /* Create Parameter Positions */
364       switch (varType) {
365         case VAR_HOLD:
366           if (SACENC_OK !=
367               (error = FrameWindowList_Add(pFrameWinList, p_l - 1, FW_HOLD)))
368             goto bail;
369           if (SACENC_OK !=
370               (error = FrameWindowList_Add(pFrameWinList, p_l, FW_INTP)))
371             goto bail;
372           break;
373         case VAR_ISOLATE:
374           if (SACENC_OK !=
375               (error = FrameWindowList_Add(pFrameWinList, p_l - 1, FW_HOLD)))
376             goto bail;
377           if (SACENC_OK !=
378               (error = FrameWindowList_Add(pFrameWinList, p_l, FW_INTP)))
379             goto bail;
380           if (SACENC_OK != (error = FrameWindowList_Add(pFrameWinList,
381                                                         p_l + tranL, FW_HOLD)))
382             goto bail;
383           if (SACENC_OK != (error = FrameWindowList_Add(
384                                 pFrameWinList, p_l + tranL + 1, FW_INTP)))
385             goto bail;
386           break;
387         default:
388           error = SACENC_INVALID_CONFIG;
389           break;
390       }
391 
392       /* Outside of frame? => Kick Out */
393       if (SACENC_OK !=
394           (error = FrameWindowList_Limit(pFrameWinList, 0, timeSlots - 1)))
395         goto bail;
396 
397       /* Add timeSlots as temporary border for window creation */
398       if (SACENC_OK !=
399           (error = FrameWindowList_Add(pFrameWinList, timeSlots - 1, FW_HOLD)))
400         goto bail;
401 
402       /* Create Windows */
403       for (ps = 0; ps < pFrameWinList->n - 1; ps++) {
404         if (FW_HOLD != pFrameWinList->dat[ps].hold) {
405           int const start = pFrameWinList->dat[ps].slot;
406           int const stop = pFrameWinList->dat[ps + 1].slot;
407 
408           /* Analysis Window */
409           FDKmemset_flex(pWindowAna__FDK[winCnt], FX_DBL2FX_WIN((FIXP_DBL)0),
410                          start);
411           FDKmemset_flex(&pWindowAna__FDK[winCnt][start], winMaxVal,
412                          stop - start + 1);
413           FDKmemset_flex(&pWindowAna__FDK[winCnt][stop + 1],
414                          FX_DBL2FX_WIN((FIXP_DBL)0), timeSlots - stop - 1);
415 
416           applyRightWindowGain__FDK[winCnt] =
417               pWindowAna__FDK[winCnt][timeSlots - 1];
418           winCnt++;
419         }
420       } /* ps */
421 
422       /* Pop temporary frame border */
423       if (SACENC_OK !=
424           (error = FrameWindowList_Remove(pFrameWinList, pFrameWinList->n - 1)))
425         goto bail;
426     } else { /* No transient in left half of ana. window */
427       winCnt = 0;
428 
429       /* Add paramter set at end of frame */
430       if (SACENC_OK !=
431           (error = FrameWindowList_Add(pFrameWinList, timeSlots - 1, FW_INTP)))
432         goto bail;
433       /* Analysis Window */
434       FDKmemset_flex(pWindowAna__FDK[winCnt], FX_DBL2FX_WIN((FIXP_DBL)0),
435                      startSlope);
436       FDKmemcpy_flex(&pWindowAna__FDK[winCnt][startSlope], 1, pTaperAna__FDK, 1,
437                      taperAnaLen);
438       FDKmemset_flex(&pWindowAna__FDK[winCnt][startRect], winMaxVal,
439                      timeSlots - startRect);
440 
441       applyRightWindowGain__FDK[winCnt] = winMaxVal;
442       winCnt++;
443     } /* if (tr_pos[0] > -1) */
444 
445     for (w = 0; w < winCnt; w++) {
446       if (applyRightWindowGain__FDK[w] > (FIXP_WIN)0) {
447         if (tr_pos[1] > -1) { /* Transients in second (right) half? */
448           int p_r = tr_pos[1];
449 
450           /* Analysis Window */
451           FDKmemset_flex(&pWindowAna__FDK[w][timeSlots], winMaxVal,
452                          p_r - timeSlots);
453           FDKmemset_flex(&pWindowAna__FDK[w][p_r], FX_DBL2FX_WIN((FIXP_DBL)0),
454                          2 * timeSlots - p_r);
455 
456         } else { /* No transient in right half of ana. window */
457           /* Analysis Window */
458           FDKmemset_flex(&pWindowAna__FDK[w][timeSlots], winMaxVal,
459                          stopRect - timeSlots + 1);
460           FDKmemcpy_flex(&pWindowAna__FDK[w][stopRect], 1,
461                          &pTaperAna__FDK[taperAnaLen - 1], -1, taperAnaLen);
462           FDKmemset_flex(&pWindowAna__FDK[w][stopSlope + 1],
463                          FX_DBL2FX_WIN((FIXP_DBL)0),
464                          2 * timeSlots - stopSlope - 1);
465 
466         } /* if (tr_pos[1] > -1) */
467 
468         /* Weight */
469         if (applyRightWindowGain__FDK[w] < winMaxVal) {
470           int ts;
471           for (ts = 0; ts < timeSlots; ts++) {
472             pWindowAna__FDK[w][timeSlots + ts] =
473                 FX_DBL2FX_WIN(fMult(pWindowAna__FDK[w][timeSlots + ts],
474                                     applyRightWindowGain__FDK[w]));
475           }
476         }
477       } /* if (applyRightWindowGain[w] > 0.0f) */
478       else {
479         /* All Zero */
480         FDKmemset_flex(&pWindowAna__FDK[w][timeSlots],
481                        FX_DBL2FX_WIN((FIXP_DBL)0), timeSlots);
482       }
483     } /* loop over windows */
484 
485     if (hFrameWindow->bFrameKeep == 1) {
486       FDKmemcpy_flex(&pWindowAna__FDK[0][2 * timeSlots], 1,
487                      &pWindowAna__FDK[0][timeSlots], 1, timeSlots);
488       FDKmemcpy_flex(&pWindowAna__FDK[0][timeSlots], 1, pWindowAna__FDK[0], 1,
489                      timeSlots);
490 
491       if (avoid_keep != 0) {
492         FDKmemset_flex(pWindowAna__FDK[0], FX_DBL2FX_WIN((FIXP_DBL)0),
493                        timeSlots);
494       } else {
495         FDKmemset_flex(pWindowAna__FDK[0], winMaxVal, timeSlots);
496       }
497     } /* if (hFrameWindow->bFrameKeep==1) */
498 
499     /* Feed Info to Bitstream Formatter */
500     pFramingInfo->numParamSets = pFrameWinList->n;
501     pFramingInfo->bsFramingType = 1; /* variable framing */
502     for (ps = 0; ps < pFramingInfo->numParamSets; ps++) {
503       pFramingInfo->bsParamSlots[ps] = pFrameWinList->dat[ps].slot;
504     }
505 
506     /* if there is just one param set at last slot,
507        use fixed framing to save some bits */
508     if ((pFramingInfo->numParamSets == 1) &&
509         (pFramingInfo->bsParamSlots[0] == timeSlots - 1)) {
510       pFramingInfo->bsFramingType = 0;
511     }
512 
513   } /* valid handle */
514 
515 bail:
516 
517   return error;
518 }
519 
fdk_sacenc_analysisWindowing(const INT nTimeSlots,const INT startTimeSlot,FIXP_WIN * pFrameWindowAna__FDK,const FIXP_DPK * const * const ppDataIn__FDK,FIXP_DPK * const * const ppDataOut__FDK,const INT nHybridBands,const INT dim)520 FDK_SACENC_ERROR fdk_sacenc_analysisWindowing(
521     const INT nTimeSlots, const INT startTimeSlot,
522     FIXP_WIN *pFrameWindowAna__FDK, const FIXP_DPK *const *const ppDataIn__FDK,
523     FIXP_DPK *const *const ppDataOut__FDK, const INT nHybridBands,
524     const INT dim) {
525   FDK_SACENC_ERROR error = SACENC_OK;
526 
527   if ((pFrameWindowAna__FDK == NULL) || (ppDataIn__FDK == NULL) ||
528       (ppDataOut__FDK == NULL)) {
529     error = SACENC_INVALID_HANDLE;
530   } else {
531     int i, ts;
532     FIXP_WIN maxVal = FX_DBL2FX_WIN((FIXP_DBL)MAXVAL_DBL);
533 
534     if (dim == FW_CHANGE_DIM) {
535       for (ts = startTimeSlot; ts < nTimeSlots; ts++) {
536         FIXP_WIN win = pFrameWindowAna__FDK[ts];
537         if (win == maxVal) {
538           for (i = 0; i < nHybridBands; i++) {
539             ppDataOut__FDK[i][ts].v.re = ppDataIn__FDK[ts][i].v.re;
540             ppDataOut__FDK[i][ts].v.im = ppDataIn__FDK[ts][i].v.im;
541           }
542         } else {
543           for (i = 0; i < nHybridBands; i++) {
544             ppDataOut__FDK[i][ts].v.re = fMult(win, ppDataIn__FDK[ts][i].v.re);
545             ppDataOut__FDK[i][ts].v.im = fMult(win, ppDataIn__FDK[ts][i].v.im);
546           }
547         }
548       } /* ts */
549     } else {
550       for (ts = startTimeSlot; ts < nTimeSlots; ts++) {
551         FIXP_WIN win = pFrameWindowAna__FDK[ts];
552         if (win == maxVal) {
553           for (i = 0; i < nHybridBands; i++) {
554             ppDataOut__FDK[ts][i].v.re = ppDataIn__FDK[ts][i].v.re;
555             ppDataOut__FDK[ts][i].v.im = ppDataIn__FDK[ts][i].v.im;
556           }
557         } else {
558           for (i = 0; i < nHybridBands; i++) {
559             ppDataOut__FDK[ts][i].v.re = fMult(win, ppDataIn__FDK[ts][i].v.re);
560             ppDataOut__FDK[ts][i].v.im = fMult(win, ppDataIn__FDK[ts][i].v.im);
561           }
562         }
563       } /* ts */
564     }
565   }
566 
567   return error;
568 }
569