/*
 ** Copyright 2003-2010, VisualOn, Inc.
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
/*******************************************************************************
	File:		grp_data.c

	Content:	Short block grouping function

*******************************************************************************/

#include "basic_op.h"
#include "psy_const.h"
#include "interface.h"
#include "grp_data.h"

/*****************************************************************************
*
* function name: groupShortData
* description:  group short data for next quantization and coding
*
**********************************************************************************/
void
groupShortData(Word32        *mdctSpectrum,
               Word32        *tmpSpectrum,
               SFB_THRESHOLD *sfbThreshold,
               SFB_ENERGY    *sfbEnergy,
               SFB_ENERGY    *sfbEnergyMS,
               SFB_ENERGY    *sfbSpreadedEnergy,
               const Word16   sfbCnt,
               const Word16  *sfbOffset,
               const Word16  *sfbMinSnr,
               Word16        *groupedSfbOffset,
               Word16        *maxSfbPerGroup,
               Word16        *groupedSfbMinSnr,
               const Word16   noOfGroups,
               const Word16  *groupLen)
{
  Word32 i, j;
  Word32 line;
  Word32 sfb;
  Word32 grp;
  Word32 wnd;
  Word32 offset;
  Word32 highestSfb;

  /* for short: regroup and  */
  /* cumulate energies und thresholds group-wise . */
  
  /* calculate sfbCnt */
  highestSfb = 0;                                        
  for (wnd=0; wnd<TRANS_FAC; wnd++) {
    for (sfb=sfbCnt - 1; sfb>=highestSfb; sfb--) {
      for (line=(sfbOffset[sfb + 1] - 1); line>=sfbOffset[sfb]; line--) {
        
        if (mdctSpectrum[wnd*FRAME_LEN_SHORT+line] != 0) break; 
      }
      
      if (line >= sfbOffset[sfb]) break;
    }
    highestSfb = max(highestSfb, sfb);
  }
  
  if (highestSfb < 0) {
    highestSfb = 0;                                      
  }
  *maxSfbPerGroup = highestSfb + 1;

  /* calculate sfbOffset */
  i = 0;                                                 
  offset = 0;                                            
  for (grp = 0; grp < noOfGroups; grp++) {
    for (sfb = 0; sfb < sfbCnt; sfb++) {
      groupedSfbOffset[i] = offset + sfbOffset[sfb] * groupLen[grp];
      i += 1;
    }
    offset += groupLen[grp] * FRAME_LEN_SHORT;
  }
  groupedSfbOffset[i] = FRAME_LEN_LONG;                  
  i += 1;

  /* calculate minSnr */
  i = 0;                                                 
  offset = 0;                                            
  for (grp = 0; grp < noOfGroups; grp++) {
    for (sfb = 0; sfb < sfbCnt; sfb++) {
      groupedSfbMinSnr[i] = sfbMinSnr[sfb];              
      i += 1;
    }
    offset += groupLen[grp] * FRAME_LEN_SHORT;
  }


  /* sum up sfbThresholds */
  wnd = 0;                                                       
  i = 0;                                                         
  for (grp = 0; grp < noOfGroups; grp++) {
    for (sfb = 0; sfb < sfbCnt; sfb++) {
      Word32 thresh = sfbThreshold->sfbShort[wnd][sfb];          
      for (j=1; j<groupLen[grp]; j++) {
        thresh = L_add(thresh, sfbThreshold->sfbShort[wnd+j][sfb]);
      }
      sfbThreshold->sfbLong[i] = thresh;                         
      i += 1;
    }
    wnd += groupLen[grp];
  }

  /* sum up sfbEnergies left/right */
  wnd = 0;                                                       
  i = 0;                                                         
  for (grp = 0; grp < noOfGroups; grp++) {
    for (sfb = 0; sfb < sfbCnt; sfb++) {
      Word32 energy = sfbEnergy->sfbShort[wnd][sfb];             
      for (j=1; j<groupLen[grp]; j++) {
        energy = L_add(energy, sfbEnergy->sfbShort[wnd+j][sfb]);
      }
      sfbEnergy->sfbLong[i] = energy;                            
      i += 1;
    }
    wnd += groupLen[grp];
  }

  /* sum up sfbEnergies mid/side */
  wnd = 0;                                                       
  i = 0;                                                         
  for (grp = 0; grp < noOfGroups; grp++) {
    for (sfb = 0; sfb < sfbCnt; sfb++) {
      Word32 energy = sfbEnergyMS->sfbShort[wnd][sfb];           
      for (j=1; j<groupLen[grp]; j++) {
        energy = L_add(energy, sfbEnergyMS->sfbShort[wnd+j][sfb]);
      }
      sfbEnergyMS->sfbLong[i] = energy;                          
      i += 1;
    }
    wnd += groupLen[grp];
  }

  /* sum up sfbSpreadedEnergies */
  wnd = 0;                                                       
  i = 0;                                                         
  for (grp = 0; grp < noOfGroups; grp++) {
    for (sfb = 0; sfb < sfbCnt; sfb++) {
      Word32 energy = sfbSpreadedEnergy->sfbShort[wnd][sfb];     
      for (j=1; j<groupLen[grp]; j++) {
        energy = L_add(energy, sfbSpreadedEnergy->sfbShort[wnd+j][sfb]);
      }
      sfbSpreadedEnergy->sfbLong[i] = energy;                    
      i += 1;
    }
    wnd += groupLen[grp];
  }

  /* re-group spectrum */
  wnd = 0;                                                       
  i = 0;                                                         
  for (grp = 0; grp < noOfGroups; grp++) {
    for (sfb = 0; sfb < sfbCnt; sfb++) {
      for (j = 0; j < groupLen[grp]; j++) {
        Word16 lineOffset = FRAME_LEN_SHORT * (wnd + j);
        for (line = lineOffset + sfbOffset[sfb]; line < lineOffset + sfbOffset[sfb+1]; line++) {
          tmpSpectrum[i] = mdctSpectrum[line];                   
          i = i + 1;
        }
      }
    }
    wnd += groupLen[grp];
  }

  for(i=0;i<FRAME_LEN_LONG;i+=4) {
    mdctSpectrum[i] = tmpSpectrum[i];  
	mdctSpectrum[i+1] = tmpSpectrum[i+1];  
	mdctSpectrum[i+2] = tmpSpectrum[i+2];  
	mdctSpectrum[i+3] = tmpSpectrum[i+3];  	
  }
}

