/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggVorbis SOFTWARE 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 SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
 * by the XIPHOPHORUS Company http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: lookup based functions
  last mod: $Id: lookup.c,v 1.8 2001/12/20 01:00:27 segher Exp $

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

#include "lookup_data.h"

/* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
   16.16 format

   returns in m.8 format */
static int32_t ADJUST_SQRT2[2]={8192,5792};
int32_t vorbis_invsqlook_i(int32_t a,int32_t e){
  int32_t i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1);
  int32_t d=a&INVSQ_LOOKUP_I_MASK;                             /*  0.10 */
  int32_t val=INVSQ_LOOKUP_I[i]-                               /*  1.16 */
    (((INVSQ_LOOKUP_I[i]-INVSQ_LOOKUP_I[i+1])*               /*  0.16 */
      d)>>INVSQ_LOOKUP_I_SHIFT);                             /* result 1.16 */

  val*=ADJUST_SQRT2[e&1];
  e=(e>>1)+21;

  return(val>>e);
}

/* interpolated lookup based fromdB function, domain -140dB to 0dB only */
/* a is in n.12 format */
xint vorbis_fromdBlook_i(int32_t a, int32_t* shift)
{
	int i = (-a)>>(12-FROMdB2_SHIFT);
	if (i < 0) return XIUNIT;
	if (i >= (FROMdB_LOOKUP_SZ<<FROMdB_SHIFT)) return XIZERO;

	const fromdB_look* db = FROMdB_LOOKUP + (i>>FROMdB_SHIFT);
	*shift = db->shift;
	return LMULSHR(db->val, FROMdB2_LOOKUP[i&FROMdB2_MASK], 0);
}

/* interpolated lookup based cos function, domain 0 to PI only */
/* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
int32_t vorbis_coslook_i(int32_t a){
  int i=a>>COS_LOOKUP_I_SHIFT;
  int d=a&COS_LOOKUP_I_MASK;
  return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
			   COS_LOOKUP_I_SHIFT);
}
