137fe158a8611dd11ec0253ab1552399b780988dcGloria Wang/************************************************************************
22da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * Copyright (C) 2002-2009, Xiph.org Foundation
32da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd
437fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * All rights reserved.
537fe158a8611dd11ec0253ab1552399b780988dcGloria Wang *
637fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * Redistribution and use in source and binary forms, with or without
72da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * modification, are permitted provided that the following conditions
82da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * are met:
937fe158a8611dd11ec0253ab1552399b780988dcGloria Wang *
1037fe158a8611dd11ec0253ab1552399b780988dcGloria Wang *     * Redistributions of source code must retain the above copyright
1137fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * notice, this list of conditions and the following disclaimer.
1237fe158a8611dd11ec0253ab1552399b780988dcGloria Wang *     * Redistributions in binary form must reproduce the above
1337fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * copyright notice, this list of conditions and the following disclaimer
1437fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * in the documentation and/or other materials provided with the
1537fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * distribution.
162da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang *     * Neither the names of the Xiph.org Foundation nor Pinknoise
172da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * Productions Ltd nor the names of its contributors may be used to
182da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * endorse or promote products derived from this software without
192da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * specific prior written permission.
2037fe158a8611dd11ec0253ab1552399b780988dcGloria Wang *
2137fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2237fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2337fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2437fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2537fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2637fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2737fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2837fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2937fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3037fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3137fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3237fe158a8611dd11ec0253ab1552399b780988dcGloria Wang ************************************************************************
337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang function: floor backend 0 implementation
357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3637fe158a8611dd11ec0253ab1552399b780988dcGloria Wang ************************************************************************/
377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <stdlib.h>
397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <string.h>
407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <math.h>
417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "ogg.h"
427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "ivorbiscodec.h"
437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "codec_internal.h"
447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "codebook.h"
457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "misc.h"
467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "os.h"
477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#define LSP_FRACBITS 14
497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangextern const ogg_int32_t FLOOR_fromdB_LOOKUP[];
507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/*************** LSP decode ********************/
527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "lsp_lookup.h"
547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   16.16 format
577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   returns in m.8 format */
587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic long ADJUST_SQRT2[2]={8192,5792};
607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic inline ogg_int32_t vorbis_invsqlook_i(long a,long e){
617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1);
627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  long d=a&INVSQ_LOOKUP_I_MASK;                              /*  0.10 */
637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  long val=INVSQ_LOOKUP_I[i]-                                /*  1.16 */
647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ((INVSQ_LOOKUP_IDel[i]*d)>>INVSQ_LOOKUP_I_SHIFT);        /* result 1.16 */
657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  val*=ADJUST_SQRT2[e&1];
667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  e=(e>>1)+21;
677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return(val>>e);
687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* interpolated lookup based fromdB function, domain -140dB to 0dB only */
717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* a is in n.12 format */
727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifdef _LOW_ACCURACY_
737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic inline ogg_int32_t vorbis_fromdBlook_i(long a){
747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(a>0) return 0x7fffffff;
757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(a<(-140<<12)) return 0;
767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return FLOOR_fromdB_LOOKUP[((a+140)*467)>>20]<<9;
777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#else
797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic inline ogg_int32_t vorbis_fromdBlook_i(long a){
807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(a>0) return 0x7fffffff;
817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(a<(-140<<12)) return 0;
827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return FLOOR_fromdB_LOOKUP[((a+(140<<12))*467)>>20];
837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif
857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* interpolated lookup based cos function, domain 0 to PI only */
877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic inline ogg_int32_t vorbis_coslook_i(long a){
897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int i=a>>COS_LOOKUP_I_SHIFT;
907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int d=a&COS_LOOKUP_I_MASK;
917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			   COS_LOOKUP_I_SHIFT);
937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* interpolated half-wave lookup based cos function */
967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* a is in 0.16 format, where 0==0, 2^^16==PI, return .LSP_FRACBITS */
977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic inline ogg_int32_t vorbis_coslook2_i(long a){
987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int i=a>>COS_LOOKUP_I_SHIFT;
997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int d=a&COS_LOOKUP_I_MASK;
1007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return ((COS_LOOKUP_I[i]<<COS_LOOKUP_I_SHIFT)-
1017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
1027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
1037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
1047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic const ogg_uint16_t barklook[54]={
1067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  0,51,102,154,            206,258,311,365,
1077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  420,477,535,594,         656,719,785,854,
1087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  926,1002,1082,1166,      1256,1352,1454,1564,
1097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  1683,1812,1953,2107,     2276,2463,2670,2900,
1107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  3155,3440,3756,4106,     4493,4919,5387,5901,
1117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  6466,7094,7798,8599,     9528,10623,11935,13524,
1127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  15453,17775,20517,23667, 27183,31004
1137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang};
1147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* used in init only; interpolate the long way */
1167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic inline ogg_int32_t toBARK(int n){
1177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int i;
1187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  for(i=0;i<54;i++)
1197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(n>=barklook[i] && n<barklook[i+1])break;
1207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(i==54){
1227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return 54<<14;
1237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }else{
1247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return (i<<14)+(((n-barklook[i])*
1257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		     ((1UL<<31)/(barklook[i+1]-barklook[i])))>>17);
1267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
1277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
1287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic const unsigned char MLOOP_1[64]={
1307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13,
1317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  14,14,14,14, 14,14,14,14, 14,14,14,14, 14,14,14,14,
1327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
1337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
1347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang};
1357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic const unsigned char MLOOP_2[64]={
1377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  0,4,5,5, 6,6,6,6, 7,7,7,7, 7,7,7,7,
1387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,
1397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
1407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
1417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang};
1427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic const unsigned char MLOOP_3[8]={0,1,2,2,3,3,3,3};
1447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvoid vorbis_lsp_to_curve(ogg_int32_t *curve,int n,int ln,
1467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			 ogg_int32_t *lsp,int m,
1477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			 ogg_int32_t amp,
1487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			 ogg_int32_t ampoffset,
1497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			 ogg_int32_t nyq){
1507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* 0 <= m < 256 */
1527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* set up for using all int later */
1547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int i;
1557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int ampoffseti=ampoffset*4096;
1567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int ampi=amp;
1577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  ogg_int32_t *ilsp=(ogg_int32_t *)alloca(m*sizeof(*ilsp));
1587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  ogg_uint32_t inyq= (1UL<<31) / toBARK(nyq);
1607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  ogg_uint32_t imap= (1UL<<31) / ln;
1617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  ogg_uint32_t tBnyq1 = toBARK(nyq)<<1;
1627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* Besenham for frequency scale to avoid a division */
1647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int f=0;
1657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int fdx=n;
1667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int fbase=nyq/fdx;
1677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int ferr=0;
1687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int fdy=nyq-fbase*fdx;
1697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int map=0;
1707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifdef _LOW_ACCURACY_
1727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  ogg_uint32_t nextbark=((tBnyq1<<11)/ln)>>12;
1737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#else
1747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  ogg_uint32_t nextbark=MULT31(imap>>1,tBnyq1);
1757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif
1767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int nextf=barklook[nextbark>>14]+(((nextbark&0x3fff)*
1777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    (barklook[(nextbark>>14)+1]-barklook[nextbark>>14]))>>14);
1787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* lsp is in 8.24, range 0 to PI; coslook wants it in .16 0 to 1*/
1807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  for(i=0;i<m;i++){
1817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifndef _LOW_ACCURACY_
1827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ogg_int32_t val=MULT32(lsp[i],0x517cc2);
1837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#else
1847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ogg_int32_t val=((lsp[i]>>10)*0x517d)>>14;
1857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif
1867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* safeguard against a malicious stream */
1887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(val<0 || (val>>COS_LOOKUP_I_SHIFT)>=COS_LOOKUP_I_SZ){
1897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      memset(curve,0,sizeof(*curve)*n);
1907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      return;
1917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
1927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ilsp[i]=vorbis_coslook_i(val);
1947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
1957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  i=0;
1977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  while(i<n){
1987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int j;
1997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ogg_uint32_t pi=46341; /* 2**-.5 in 0.16 */
2007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ogg_uint32_t qi=46341;
2017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ogg_int32_t qexp=0,shift;
2027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ogg_int32_t wi;
2037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    wi=vorbis_coslook2_i((map*imap)>>15);
2057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifdef _V_LSP_MATH_ASM
2087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    lsp_loop_asm(&qi,&pi,&qexp,ilsp,wi,m);
2097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    pi=((pi*pi)>>16);
2117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    qi=((qi*qi)>>16);
2127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(m&1){
2147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qexp= qexp*2-28*((m+1)>>1)+m;
2157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      pi*=(1<<14)-((wi*wi)>>14);
2167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi+=pi>>14;
2177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }else{
2187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qexp= qexp*2-13*m;
2197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      pi*=(1<<14)-wi;
2217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi*=(1<<14)+wi;
2227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi=(qi+pi)>>14;
2247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
2257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */
2277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi>>=1; qexp++;
2287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }else
2297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      lsp_norm_asm(&qi,&qexp);
2307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#else
2327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    qi*=labs(ilsp[0]-wi);
2347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    pi*=labs(ilsp[1]-wi);
2357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for(j=3;j<m;j+=2){
2377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(!(shift=MLOOP_1[(pi|qi)>>25]))
2387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      	if(!(shift=MLOOP_2[(pi|qi)>>19]))
2397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      	  shift=MLOOP_3[(pi|qi)>>16];
2407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi=(qi>>shift)*labs(ilsp[j-1]-wi);
2427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      pi=(pi>>shift)*labs(ilsp[j]-wi);
2437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qexp+=shift;
2447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
2457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(!(shift=MLOOP_1[(pi|qi)>>25]))
2467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(!(shift=MLOOP_2[(pi|qi)>>19]))
2477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	shift=MLOOP_3[(pi|qi)>>16];
2487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* pi,qi normalized collectively, both tracked using qexp */
2507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(m&1){
2527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* odd order filter; slightly assymetric */
2537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* the last coefficient */
2547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi=(qi>>shift)*labs(ilsp[j-1]-wi);
2557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      pi=(pi>>shift)<<14;
2567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qexp+=shift;
2577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(!(shift=MLOOP_1[(pi|qi)>>25]))
2597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(!(shift=MLOOP_2[(pi|qi)>>19]))
2607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  shift=MLOOP_3[(pi|qi)>>16];
2617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      pi>>=shift;
2637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi>>=shift;
2647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qexp+=shift-14*((m+1)>>1);
2657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      pi=((pi*pi)>>16);
2677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi=((qi*qi)>>16);
2687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qexp=qexp*2+m;
2697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      pi*=(1<<14)-((wi*wi)>>14);
2717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi+=pi>>14;
2727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }else{
2747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* even order filter; still symmetric */
2757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't
2777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	 worth tracking step by step */
2787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      pi>>=shift;
2807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi>>=shift;
2817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qexp+=shift-7*m;
2827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      pi=((pi*pi)>>16);
2847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi=((qi*qi)>>16);
2857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qexp=qexp*2+m;
2867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      pi*=(1<<14)-wi;
2887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi*=(1<<14)+wi;
2897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi=(qi+pi)>>14;
2907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
2927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* we've let the normalization drift because it wasn't important;
2957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang       however, for the lookup, things must be normalized again.  We
2967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang       need at most one right shift or a number of left shifts */
2977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */
2997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      qi>>=1; qexp++;
3007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }else
3017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/
3027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	qi<<=1; qexp--;
3037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
3047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif
3067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    amp=vorbis_fromdBlook_i(ampi*                     /*  n.4         */
3087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			    vorbis_invsqlook_i(qi,qexp)-
3097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			                              /*  m.8, m+n<=8 */
3107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			    ampoffseti);              /*  8.12[0]     */
3117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifdef _LOW_ACCURACY_
3137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    amp>>=9;
3147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif
3157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    curve[i]= MULT31_SHIFT15(curve[i],amp);
3167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    while(++i<n){
3187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* line plot to get new f */
3207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      ferr+=fdy;
3217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(ferr>=fdx){
3227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	ferr-=fdx;
3237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	f++;
3247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
3257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      f+=fbase;
3267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(f>=nextf)break;
3287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      curve[i]= MULT31_SHIFT15(curve[i],amp);
3307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
3317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    while(1){
3337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      map++;
3347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(map+1<ln){
3367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifdef _LOW_ACCURACY_
3387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	nextbark=((tBnyq1<<11)/ln*(map+1))>>12;
3397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#else
3407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	nextbark=MULT31((map+1)*(imap>>1),tBnyq1);
3417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif
3427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	nextf=barklook[nextbark>>14]+
3437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  (((nextbark&0x3fff)*
3447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    (barklook[(nextbark>>14)+1]-barklook[nextbark>>14]))>>14);
3457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(f<=nextf)break;
3467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }else{
3487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	nextf=9999999;
3497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	break;
3507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
3517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
3527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(map>=ln){
3537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      map=ln-1; /* guard against the approximation */
3547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      nextf=9999999;
3557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
3567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
3577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
3587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/*************** vorbis decode glue ************/
3607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvoid floor0_free_info(vorbis_info_floor *i){
3627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
3637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(info)_ogg_free(info);
3647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
3657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvorbis_info_floor *floor0_info_unpack (vorbis_info *vi,oggpack_buffer *opb){
3677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
3687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int j;
3697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  vorbis_info_floor0 *info=(vorbis_info_floor0 *)_ogg_malloc(sizeof(*info));
3717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->order=oggpack_read(opb,8);
3727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->rate=oggpack_read(opb,16);
3737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->barkmap=oggpack_read(opb,16);
3747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->ampbits=oggpack_read(opb,6);
3757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->ampdB=oggpack_read(opb,8);
3767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->numbooks=oggpack_read(opb,4)+1;
3777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(info->order<1)goto err_out;
3797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(info->rate<1)goto err_out;
3807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(info->barkmap<1)goto err_out;
3817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  for(j=0;j<info->numbooks;j++){
3837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    info->books[j]=(char)oggpack_read(opb,8);
3847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(info->books[j]>=ci->books)goto err_out;
3857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
3867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(oggpack_eop(opb))goto err_out;
3887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return(info);
3897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang err_out:
3917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  floor0_free_info(info);
3927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return(NULL);
3937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
3947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint floor0_memosize(vorbis_info_floor *i){
3967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
3977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return info->order+1;
3987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
3997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangogg_int32_t *floor0_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *i,
4017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			     ogg_int32_t *lsp){
4027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
4037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int j,k;
4047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int ampraw=oggpack_read(&vd->opb,info->ampbits);
4067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(ampraw>0){ /* also handles the -1 out of data case */
4077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    long maxval=(1<<info->ampbits)-1;
4087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int amp=((ampraw*info->ampdB)<<4)/maxval;
4097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int booknum=oggpack_read(&vd->opb,_ilog(info->numbooks));
4107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
4127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      codec_setup_info  *ci=(codec_setup_info *)vd->vi->codec_setup;
4137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      codebook *b=ci->book_param+info->books[booknum];
4147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      ogg_int32_t last=0;
4157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(j=0;j<info->order;j+=b->dim)
4177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(vorbis_book_decodev_set(b,lsp+j,&vd->opb,b->dim,-24)==-1)goto eop;
4187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(j=0;j<info->order;){
4197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
4207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	last=lsp[j-1];
4217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
4227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      lsp[info->order]=amp;
4247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      return(lsp);
4257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
4267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
4277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang eop:
4287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return(NULL);
4297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
4307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint floor0_inverse2(vorbis_dsp_state *vd,vorbis_info_floor *i,
4327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			   ogg_int32_t *lsp,ogg_int32_t *out){
4337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
4347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  codec_setup_info  *ci=(codec_setup_info *)vd->vi->codec_setup;
4357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(lsp){
4377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ogg_int32_t amp=lsp[info->order];
4387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* take the coefficients back to a spectral envelope curve */
4407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    vorbis_lsp_to_curve(out,ci->blocksizes[vd->W]/2,info->barkmap,
4417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			lsp,info->order,amp,info->ampdB,
4427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			info->rate>>1);
4437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return(1);
4447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
4457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  memset(out,0,sizeof(*out)*ci->blocksizes[vd->W]/2);
4467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return(0);
4477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
4487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
449