42e5096897b0cdbe8295731493d7225477909106
[platform/upstream/libvorbis.git] / lib / spectrum.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5  * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
6  * PLEASE READ THESE TERMS DISTRIBUTING.                            *
7  *                                                                  *
8  * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999             *
9  * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company       *
10  * http://www.xiph.org/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: spectrum envelope and residue code/decode
15  author: Monty <xiphmont@mit.edu>
16  modifications by: Monty
17  last modification date: Oct 17 1999
18
19  ********************************************************************/
20
21 #include <stdio.h>
22 #include <math.h>
23 #include "codec.h"
24 #include "bitwise.h"
25 #include "spectrum.h"
26
27 /* this code is still seriously abbreviated.  I'm filling in pieces as
28    we go... --Monty 19991004 */
29
30 /* unlike other LPC-based coders, we never apply the filter, only
31    inspect the frequency response, thus we don't need to guard against
32    instability.  However, two coefficients quantising to the same
33    value will cause the response to explode.  */
34
35 int _vs_spectrum_encode(vorbis_block *vb,double amp,double *lsp){
36   /* no real coding yet.  Just write out full sized words for now
37      because people need bitstreams to work with */
38
39   int scale=vb->W;
40   int m=vb->vd->vi->floororder[scale];
41   int n=vb->pcmend/2;
42   int last=0;
43   double dlast=0.;
44   double min=M_PI/n/2.;
45   
46   int bits=rint(log(n)/log(2));
47   int i;
48   
49   _oggpack_write(&vb->opb,amp*327680,18);
50   
51   for(i=0;i<m;i++){
52     int val=rint(lsp[i]/M_PI*n-last);
53     _oggpack_write(&vb->opb,val,bits);
54     lsp[i]=(last+=val)*M_PI/n;
55
56     /* Underpowered but sufficient */
57     if(lsp[i]<dlast+min)lsp[i]=dlast+min;
58     dlast=lsp[i];
59   }
60   return(0);
61 }
62
63 int _vs_spectrum_decode(vorbis_block *vb,double *amp,double *lsp){
64   int scale=vb->W;
65   int m=vb->vd->vi->floororder[scale];
66   int n=vb->pcmend/2;
67   int last=0;
68   double dlast=0.;
69   int bits=rint(log(n)/log(2));
70   int i;
71   double min=M_PI/n/2.;
72
73   *amp=_oggpack_read(&vb->opb,18)/327680.;
74
75   for(i=0;i<m;i++){
76     int val=_oggpack_read(&vb->opb,bits);
77     lsp[i]=(last+=val)*M_PI/n;
78     /* Underpowered but sufficient */
79     if(lsp[i]<dlast+min)lsp[i]=dlast+min;
80     dlast=lsp[i];
81   }
82   return(0);
83 }
84
85
86 void _vs_residue_quantize(double *data,double *curve,
87                                  vorbis_info *vi,int n){
88
89   /* The following is temporary, hardwired bullshit */
90   int i;
91
92   for(i=0;i<n;i++){
93
94     int val=rint(data[i]/curve[i]);
95     if(val>16)val=16;
96     if(val<-16)val=-16;
97
98     if(val==0 || val==2 || val==-2){
99       if(data[i]<0){
100         val=-1;
101       }else{
102         val=1;
103       }
104     }
105     
106     data[i]=val;
107     /*if(val<0){
108     }else{
109       data[i]=val+15;
110       }*/
111   }
112 }
113
114 int _vs_residue_encode(vorbis_block *vb,double *data){
115   /* no real coding yet.  Just write out full sized words for now
116      because people need bitstreams to work with */
117
118   int              n=vb->pcmend/2;
119   int i;
120
121   for(i=0;i<n;i++){
122     _oggpack_write(&vb->opb,(int)(data[i]+16),6);
123   }
124
125   return(0);
126 }
127
128 int _vs_residue_decode(vorbis_block *vb,double *data){
129   /* no real coding yet.  Just write out full sized words for now
130      because people need bitstreams to work with */
131
132   int              n=vb->pcmend/2;
133   int i;
134
135   for(i=0;i<n;i++){
136     data[i]=_oggpack_read(&vb->opb,6)-16;
137     /*if(data[i]>=0)data[i]+=1;*/
138   }
139   return(0);
140 }
141