/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE.   *
 *                                                                  *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002    *
 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

 function: window functions

 ********************************************************************/

#include "window.h"

extern int32_t vwin64(void);
extern int32_t vwin128(void);
extern int32_t vwin256(void);
extern int32_t vwin512(void);
extern int32_t vwin1024(void);
extern int32_t vwin2048(void);
extern int32_t vwin4096(void);
extern int32_t vwin8192(void);

const int32_t* _vorbis_window(int type, int left)
{
  switch(type){
  case 0:

    switch(left){
    case 32:
      return (int32_t*) vwin64;
    case 64:
      return (int32_t*) vwin128;
    case 128:
      return (int32_t*) vwin256;
    case 256:
      return (int32_t*) vwin512;
    case 512:
      return (int32_t*) vwin1024;
    case 1024:
      return (int32_t*) vwin2048;
    case 2048:
      return (int32_t*) vwin4096;
    case 4096:
      return (int32_t*) vwin8192;
    default:
      return(NULL);
    }
    break;
  default:
    return(NULL);
  }
}

extern void window_left(xint* d, const int32_t* w, int32_t n);
extern void window_right(xint* d, const int32_t* w, int32_t n);

void _vorbis_apply_window(xint* d, const int32_t* window[2], int32_t* blocksizes,
			  int lW,int W,int nW)
{
	int32_t n  = blocksizes[W]>>1;
	int32_t ln = blocksizes[lW]>>1;
	int32_t rn = blocksizes[nW]>>1;

	xint* leftbegin  = d + (n/2-ln/2);
	xint* rightbegin = d + (n+n/2-rn/2);

	int32_t i;

	// zero left margin
	for(i = 0; i < n/2-ln/2; i++)
		d[i] = 0;

	// apply left window part
	window_left(leftbegin, window[lW], ln);

	// keep center unchanged

	// apply right window part
	window_right(rightbegin, window[nW], rn);

	// zero right margin
	for(i = n + n/2 + rn/2;i<2*n;i++)
		d[i] = 0;
}
