d617d6a197c6df165b22282cb4b73425ed3a4e15
[platform/upstream/libvorbis.git] / lib / analysis.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: single-block PCM analysis
15  author: Monty <xiphmont@mit.edu>
16  modifications by: Monty
17  last modification date: Oct 7 1999
18
19  ********************************************************************/
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <math.h>
24 #include "lpc.h"
25 #include "lsp.h"
26 #include "codec.h"
27 #include "envelope.h"
28 #include "mdct.h"
29 #include "psy.h"
30 #include "bitwise.h"
31 #include "spectrum.h"
32
33 /* this code is still seriously abbreviated.  I'm filling in pieces as
34    we go... --Monty 19991004 */
35
36 int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
37   static int frameno=0;
38   
39   int i;
40   double           *window=vb->vd->window[vb->W][vb->lW][vb->nW];
41   lpc_lookup       *vl=&vb->vd->vl[vb->W];
42   vorbis_dsp_state *vd=vb->vd;
43   vorbis_info      *vi=vd->vi;
44   oggpack_buffer   *opb=&vb->opb;
45
46   int              n=vb->pcmend;
47   int              spectral_order=vi->floororder[vb->W];
48
49   /*lpc_lookup       *vbal=&vb->vd->vbal[vb->W];
50     double balance_v[vbal->m];
51     double balance_amp;*/
52
53   /* first things first.  Make sure encode is ready*/
54   _oggpack_reset(opb);
55   /* Encode the packet type */
56   _oggpack_write(opb,0,1);
57   /* Encode the block size */
58   _oggpack_write(opb,vb->W,1);
59
60   /* we have the preecho metrics; decide what to do with them */
61   /*_ve_envelope_sparsify(vb);
62     _ve_envelope_apply(vb,0);*/
63
64   /* Encode the envelope */
65   /*if(_ve_envelope_encode(vb))return(-1);*/
66   
67   /* time domain PCM -> MDCT domain */
68   for(i=0;i<vi->channels;i++)
69     mdct_forward(&vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
70
71   /* no balance yet */
72     
73   /* extract the spectral envelope and residue */
74   /* just do by channel.  No coupling yet */
75   {
76     for(i=0;i<vi->channels;i++){
77       double floor[n/2];
78       double curve[n/2];
79       double *lpc=vb->lpc[i];
80       double *lsp=vb->lsp[i];
81
82       memset(floor,0,sizeof(double)*n/2);
83       
84       _vp_noise_floor(vb->pcm[i],floor,n/2);
85       _vp_mask_floor(vb->pcm[i],floor,n/2);
86
87       /* Convert our floor to a set of lpc coefficients */
88       vb->amp[i]=sqrt(vorbis_curve_to_lpc(floor,lpc,vl));
89
90       /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
91       vorbis_lpc_to_lsp(lpc,lsp,vl->m);
92
93       /* code the spectral envelope; mutates the lsp coeffs to reflect
94          what was actually encoded */
95       _vs_spectrum_encode(vb,vb->amp[i],lsp);
96
97       /* Generate residue from the decoded envelope, which will be
98          slightly different to the pre-encoding floor due to
99          quantization.  Slow, yes, but perhaps more accurate */
100
101       vorbis_lsp_to_lpc(lsp,lpc,vl->m); 
102       vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl);
103       
104       /* this may do various interesting massaging too...*/
105       _vs_residue_quantize(vb->pcm[i],curve,vi,n/2);
106
107       /* encode the residue */
108       _vs_residue_encode(vb,vb->pcm[i]);
109
110     }
111   }
112
113   /* set up the packet wrapper */
114
115   op->packet=opb->buffer;
116   op->bytes=_oggpack_bytes(opb);
117   op->b_o_s=0;
118   op->e_o_s=vb->eofflag;
119   op->frameno=vb->frameno;
120
121   return(0);
122 }
123
124
125
126
127 /* commented out, relocated balance stuff */
128   /*{
129     double *C=vb->pcm[0];
130     double *D=vb->pcm[1];
131     
132     balance_amp=_vp_balance_compute(D,C,balance_v,vbal);
133     
134     {
135       FILE *out;
136       char buffer[80];
137       
138       sprintf(buffer,"com%d.m",frameno);
139       out=fopen(buffer,"w+");
140       for(i=0;i<n/2;i++){
141         fprintf(out," 0. 0.\n");
142         fprintf(out,"%g %g\n",C[i],D[i]);
143         fprintf(out,"\n");
144       }
145       fclose(out);
146       
147       sprintf(buffer,"L%d.m",frameno);
148       out=fopen(buffer,"w+");
149       for(i=0;i<n/2;i++){
150         fprintf(out,"%g\n",C[i]);
151       }
152       fclose(out);
153       sprintf(buffer,"R%d.m",frameno);
154       out=fopen(buffer,"w+");
155       for(i=0;i<n/2;i++){
156         fprintf(out,"%g\n",D[i]);
157       }
158       fclose(out);
159       
160     }
161     
162     _vp_balance_apply(D,C,balance_v,balance_amp,vbal,1);
163       
164     {
165       FILE *out;
166       char buffer[80];
167       
168       sprintf(buffer,"bal%d.m",frameno);
169       out=fopen(buffer,"w+");
170       for(i=0;i<n/2;i++){
171         fprintf(out," 0. 0.\n");
172         fprintf(out,"%g %g\n",C[i],D[i]);
173         fprintf(out,"\n");
174       }
175       fclose(out);
176       sprintf(buffer,"C%d.m",frameno);
177       out=fopen(buffer,"w+");
178       for(i=0;i<n/2;i++){
179         fprintf(out,"%g\n",C[i]);
180       }
181       fclose(out);
182       sprintf(buffer,"D%d.m",frameno);
183       out=fopen(buffer,"w+");
184       for(i=0;i<n/2;i++){
185         fprintf(out,"%g\n",D[i]);
186       }
187       fclose(out);
188       
189     }
190   }*/