001/* JOrbis
002 * Copyright (C) 2000 ymnk, JCraft,Inc.
003 *  
004 * Written by: 2000 ymnk<ymnk@jcaft.com>
005 *   
006 * Many thanks to 
007 *   Monty <monty@xiph.org> and 
008 *   The XIPHOPHORUS Company http://www.xiph.org/ .
009 * JOrbis has been based on their awesome works, Vorbis codec.
010 *   
011 * This program is free software; you can redistribute it and/or
012 * modify it under the terms of the GNU Library General Public License
013 * as published by the Free Software Foundation; either version 2 of
014 * the License, or (at your option) any later version.
015   
016 * This program is distributed in the hope that it will be useful,
017 * but WITHOUT ANY WARRANTY; without even the implied warranty of
018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
019 * GNU Library General Public License for more details.
020 * 
021 * You should have received a copy of the GNU Library General Public
022 * License along with this program; if not, write to the Free Software
023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
024 */
025
026package com.jcraft.jorbis;
027
028/*
029  function: LSP (also called LSF) conversion routines
030
031  The LSP generation code is taken (with minimal modification) from
032  "On the Computation of the LSP Frequencies" by Joseph Rothweiler
033  <rothwlr@altavista.net>, available at:
034  
035  http://www2.xtdl.com/~rothwlr/lsfpaper/lsfpage.html 
036 ********************************************************************/
037
038class Lsp{
039
040  static final float M_PI=(float)(3.1415926539);
041
042  static void lsp_to_curve(float[] curve,
043                           int[] map, int n, int ln,
044                           float[] lsp, int m,
045                           float amp, float ampoffset){
046    int i;
047    float wdel=M_PI/ln;
048    for(i=0;i<m;i++)lsp[i]=Lookup.coslook(lsp[i]);
049    int m2=(m/2)*2;
050
051    i=0;
052    while(i<n){
053      int k=map[i];
054      float p=.7071067812f;
055      float q=.7071067812f;
056      float w=Lookup.coslook(wdel*k);
057      int ftmp=0;
058      int c=m>>>1;
059
060      for(int j=0;j<m2;j+=2){
061        q*=lsp[j]-w;
062        p*=lsp[j+1]-w;
063      }
064
065      if((m&1)!=0){
066        /* odd order filter; slightly assymetric */
067        /* the last coefficient */
068        q*=lsp[m-1]-w;
069        q*=q;
070        p*=p*(1.f-w*w);
071      }
072      else{
073        /* even order filter; still symmetric */
074        q*=q*(1.f+w);
075        p*=p*(1.f-w);
076      }
077
078      //  q=frexp(p+q,&qexp);
079      q=p+q;
080      int hx=Float.floatToIntBits(q);
081      int ix=0x7fffffff&hx;
082      int qexp=0;
083
084      if(ix>=0x7f800000||(ix==0)){
085        // 0,inf,nan
086      }
087      else{
088        if(ix<0x00800000){            // subnormal
089          q*=3.3554432000e+07;        // 0x4c000000
090          hx=Float.floatToIntBits(q);
091          ix=0x7fffffff&hx;
092          qexp=-25;
093        }
094        qexp += ((ix>>>23)-126);
095        hx=(hx&0x807fffff)|0x3f000000;
096        q=Float.intBitsToFloat(hx);
097      }
098
099      q=Lookup.fromdBlook(amp*
100                          Lookup.invsqlook(q)*
101                          Lookup.invsq2explook(qexp+m)-ampoffset);
102
103      do{curve[i++]*=q;}
104//    do{curve[i++]=q;}
105      while(i<n&&map[i]==k);
106
107    }
108  }
109}
110
111