cd08ff601ece0782f46d47214ef2e102cfcce3e2
[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-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 synthesis
15  author: Monty <xiphmont@mit.edu>
16  modifications by: Monty
17  last modification date: Oct 07 1999
18
19  ********************************************************************/
20
21 #include <stdio.h>
22 #include "codec.h"
23 #include "envelope.h"
24 #include "mdct.h"
25 #include "lpc.h"
26 #include "lsp.h"
27 #include "bitwise.h"
28 #include "spectrum.h"
29
30 int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
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   /* Encode the block size */
48   vb->W=_oggpack_read(opb,1);
49
50   /* other random setup */
51   vb->frameno=op->frameno;
52   vb->eofflag=op->e_o_s;
53   vl=&vb->vd->vl[vb->W];
54   spectral_order=vi->floororder[vb->W];
55
56   /* The storage vectors are large enough; set the use markers */
57   n=vb->pcmend=vi->blocksize[vb->W];
58   vb->multend=n/vi->envelopesa;
59   
60   /* recover the time envelope */
61   if(_ve_envelope_decode(vb)<0)return(-1);
62
63   for(i=0;i<vi->channels;i++){
64     double *lpc=vb->lpc[i];
65     double *lsp=vb->lsp[i];
66     
67     /* recover the spectral envelope */
68     if(_vs_spectrum_decode(vb,&vb->amp[i],lsp)<0)return(-1);
69     
70     /* recover the spectral residue */  
71     if(_vs_residue_decode(vb,vb->pcm[i])<0)return(-1);
72
73     /* LSP->LPC */
74     vorbis_lsp_to_lpc(lsp,lpc,vl->m); 
75
76     /* apply envelope to residue */
77     
78     vorbis_lpc_apply(vb->pcm[i],lpc,vb->amp[i],vl);
79       
80     /* MDCT->time */
81     mdct_backward(&vb->vd->vm[vb->W],vb->pcm[i],vb->pcm[i]);
82     
83   }
84
85   /* apply time domain envelope */
86   _ve_envelope_apply(vb,1);
87   
88   return(0);
89 }
90
91