1 /********************************************************************
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. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
9 * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: single-block PCM analysis
15 last mod: $Id: analysis.c,v 1.20 2000/01/05 03:10:53 xiphmont Exp $
17 ********************************************************************/
22 #include "vorbis/codec.h"
33 /* this code is still seriously abbreviated. I'm filling in pieces as
34 we go... --Monty 19991004 */
36 int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
38 double *window=vb->vd->window[vb->W][vb->lW][vb->nW];
39 psy_lookup *vp=&vb->vd->vp[vb->W];
40 lpc_lookup *vl=&vb->vd->vl[vb->W];
41 vorbis_dsp_state *vd=vb->vd;
42 vorbis_info *vi=vd->vi;
43 oggpack_buffer *opb=&vb->opb;
46 int spectral_order=vi->floororder[vb->W];
49 vb->time_envelope_bits=0;
50 vb->spectral_envelope_bits=0;
51 vb->spectral_residue_bits=0;
53 /*lpc_lookup *vbal=&vb->vd->vbal[vb->W];
54 double balance_v[vbal->m];
57 /* first things first. Make sure encode is ready*/
59 /* Encode the packet type */
60 _oggpack_write(opb,0,1);
62 /* Encode the block size */
63 _oggpack_write(opb,vb->W,1);
65 _oggpack_write(opb,vb->lW,1);
66 _oggpack_write(opb,vb->nW,1);
69 /* No envelope encoding yet */
70 _oggpack_write(opb,0,1);
72 /* time domain PCM -> MDCT domain */
73 for(i=0;i<vi->channels;i++)
74 mdct_forward(&vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
78 /* extract the spectral envelope and residue */
79 /* just do by channel. No coupling yet */
81 for(i=0;i<vi->channels;i++){
84 double *floor=alloca(n/2*sizeof(double));
85 double *curve=alloca(n/2*sizeof(double));
86 double *lpc=vb->lpc[i];
87 double *lsp=vb->lsp[i];
89 memset(floor,0,sizeof(double)*n/2);
96 sprintf(buffer,"Aspectrum%d.m",vb->sequence);
97 out=fopen(buffer,"w+");
99 fprintf(out,"%g\n",vb->pcm[i][j]);
105 _vp_mask_floor(vp,vb->pcm[i],floor);
112 sprintf(buffer,"Apremask%d.m",vb->sequence);
113 out=fopen(buffer,"w+");
115 fprintf(out,"%g\n",floor[j]);
120 /* Convert our floor to a set of lpc coefficients */
121 vb->amp[i]=sqrt(vorbis_curve_to_lpc(floor,lpc,vl));
123 /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
124 vorbis_lpc_to_lsp(lpc,lsp,vl->m);
126 /* code the spectral envelope; mutates the lsp coeffs to reflect
127 what was actually encoded */
128 _vs_spectrum_encode(vb,vb->amp[i],lsp);
130 /* Generate residue from the decoded envelope, which will be
131 slightly different to the pre-encoding floor due to
132 quantization. Slow, yes, but perhaps more accurate */
134 vorbis_lsp_to_lpc(lsp,lpc,vl->m);
135 vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl);
137 /* this may do various interesting massaging too...*/
138 if(vb->amp[i])_vs_residue_train(vb,vb->pcm[i],curve,n/2);
139 _vs_residue_quantize(vb->pcm[i],curve,vi,n/2);
146 sprintf(buffer,"Alpc%d.m",vb->sequence);
147 out=fopen(buffer,"w+");
149 fprintf(out,"%g\n",lpc[j]);
152 sprintf(buffer,"Alsp%d.m",vb->sequence);
153 out=fopen(buffer,"w+");
155 fprintf(out,"%g\n",lsp[j]);
158 sprintf(buffer,"Amask%d.m",vb->sequence);
159 out=fopen(buffer,"w+");
161 fprintf(out,"%g\n",curve[j]);
164 sprintf(buffer,"Ares%d.m",vb->sequence);
165 out=fopen(buffer,"w+");
167 fprintf(out,"%g\n",vb->pcm[i][j]);
172 /* encode the residue */
173 _vs_residue_encode(vb,vb->pcm[i]);
178 /* set up the packet wrapper */
180 op->packet=opb->buffer;
181 op->bytes=_oggpack_bytes(opb);
183 op->e_o_s=vb->eofflag;
184 op->frameno=vb->frameno;
185 op->packetno=vb->sequence; /* for sake of completeness */
193 /* commented out, relocated balance stuff */
195 double *C=vb->pcm[0];
196 double *D=vb->pcm[1];
198 balance_amp=_vp_balance_compute(D,C,balance_v,vbal);
204 sprintf(buffer,"com%d.m",frameno);
205 out=fopen(buffer,"w+");
207 fprintf(out," 0. 0.\n");
208 fprintf(out,"%g %g\n",C[i],D[i]);
213 sprintf(buffer,"L%d.m",frameno);
214 out=fopen(buffer,"w+");
216 fprintf(out,"%g\n",C[i]);
219 sprintf(buffer,"R%d.m",frameno);
220 out=fopen(buffer,"w+");
222 fprintf(out,"%g\n",D[i]);
228 _vp_balance_apply(D,C,balance_v,balance_amp,vbal,1);
234 sprintf(buffer,"bal%d.m",frameno);
235 out=fopen(buffer,"w+");
237 fprintf(out," 0. 0.\n");
238 fprintf(out,"%g %g\n",C[i],D[i]);
242 sprintf(buffer,"C%d.m",frameno);
243 out=fopen(buffer,"w+");
245 fprintf(out,"%g\n",C[i]);
248 sprintf(buffer,"D%d.m",frameno);
249 out=fopen(buffer,"w+");
251 fprintf(out,"%g\n",D[i]);