Incremental update toward VQ integration, vorbis_info rearrangement
[platform/upstream/libvorbis.git] / lib / synthesis.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-2000             *
9  * by Monty <monty@xiph.org> and The XIPHOPHORUS Company            *
10  * http://www.xiph.org/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: single-block PCM synthesis
15  last mod: $Id: synthesis.c,v 1.12 2000/01/12 11:34:41 xiphmont Exp $
16
17  ********************************************************************/
18
19 #include <stdio.h>
20 #include "vorbis/codec.h"
21
22 #include "envelope.h"
23 #include "mdct.h"
24 #include "lpc.h"
25 #include "lsp.h"
26 #include "bitwise.h"
27 #include "spectrum.h"
28
29 int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
30   double           *window;
31   vorbis_dsp_state *vd=vb->vd;
32   vorbis_info      *vi=vd->vi;
33   oggpack_buffer   *opb=&vb->opb;
34   lpc_lookup       *vl;
35   int              spectral_order;
36   int              n,i;
37
38   /* first things first.  Make sure decode is ready */
39   _oggpack_readinit(opb,op->packet,op->bytes);
40
41   /* Check the packet type */
42   if(_oggpack_read(opb,1)!=0){
43     /* Oops.  This is not an audio data packet */
44     return(-1);
45   }
46
47   /* Decode the block size */
48   vb->W=_oggpack_read(opb,1);
49   if(vb->W){
50     vb->lW=_oggpack_read(opb,1);
51     vb->nW=_oggpack_read(opb,1);
52   }else{
53     vb->lW=0;
54     vb->nW=0;
55   }
56
57   window=vb->vd->window[vb->W][vb->lW][vb->nW];
58
59   /* other random setup */
60   vb->frameno=op->frameno;
61   vb->sequence=op->packetno-3; /* first block is third packet */
62
63   vb->eofflag=op->e_o_s;
64   vl=&vb->vd->vl[vb->W];
65   spectral_order=vi->floororder[vb->W];
66
67   /* The storage vectors are large enough; set the use markers */
68   n=vb->pcmend=vi->blocksize[vb->W];
69   
70   /* No envelope encoding yet */
71   _oggpack_read(opb,0,1);
72
73   for(i=0;i<vi->channels;i++){
74     double *lpc=vb->lpc[i];
75     double *lsp=vb->lsp[i];
76     
77     /* recover the spectral envelope */
78     if(_vs_spectrum_decode(vb,&vb->amp[i],lsp)<0)return(-1);
79     
80     /* recover the spectral residue */  
81     if(_vs_residue_decode(vb,vb->pcm[i])<0)return(-1);
82
83 #ifdef ANALYSIS
84     {
85       int j;
86       FILE *out;
87       char buffer[80];
88       
89       sprintf(buffer,"Sres%d.m",vb->sequence);
90       out=fopen(buffer,"w+");
91       for(j=0;j<n/2;j++)
92         fprintf(out,"%g\n",vb->pcm[i][j]);
93       fclose(out);
94     }
95 #endif
96
97     /* LSP->LPC */
98     vorbis_lsp_to_lpc(lsp,lpc,vl->m); 
99
100     /* apply envelope to residue */
101     
102 #ifdef ANALYSIS
103     {
104       int j;
105       FILE *out;
106       char buffer[80];
107       double curve[n/2];
108       vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl);
109       
110       
111       sprintf(buffer,"Smask%d.m",vb->sequence);
112       out=fopen(buffer,"w+");
113       for(j=0;j<n/2;j++)
114         fprintf(out,"%g\n",curve[j]);
115       fclose(out);
116
117       sprintf(buffer,"Slsp%d.m",vb->sequence);
118       out=fopen(buffer,"w+");
119       for(j=0;j<vl->m;j++)
120         fprintf(out,"%g\n",lsp[j]);
121       fclose(out);
122
123       sprintf(buffer,"Slpc%d.m",vb->sequence);
124       out=fopen(buffer,"w+");
125       for(j=0;j<vl->m;j++)
126         fprintf(out,"%g\n",lpc[j]);
127       fclose(out);
128     }
129 #endif
130
131     vorbis_lpc_apply(vb->pcm[i],lpc,vb->amp[i],vl);
132
133 #ifdef ANALYSIS
134     {
135       int j;
136       FILE *out;
137       char buffer[80];
138       
139       sprintf(buffer,"Sspectrum%d.m",vb->sequence);
140       out=fopen(buffer,"w+");
141       for(j=0;j<n/2;j++)
142         fprintf(out,"%g\n",vb->pcm[i][j]);
143       fclose(out);
144     }
145 #endif
146       
147
148     /* MDCT->time */
149     mdct_backward(&vb->vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
150     
151   }
152   return(0);
153 }
154
155