dc316530b34049bda200e82267309abfedccfa36
[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: PCM data vector blocking, windowing and dis/reassembly
15  author: Monty <xiphmont@mit.edu>
16  modifications by: Monty
17  last modification date: Jun 26 1999
18
19  Handle windowing, overlap-add, etc of the original (and synthesized)
20  PCM vectors.  This is made more amusing by Vorbis' current two allowed
21  block sizes (512 and 2048 elements/channel).
22  
23  Vorbis manipulates the dynamic range of the incoming PCM data
24  envelope to minimise time-domain energy leakage from percussive and
25  plosive waveforms being quantized in the MDCT domain.
26
27  ********************************************************************/
28
29 #include <stdlib.h>
30
31 /* pcm accumulator and multipliers 
32    examples (not exhaustive):
33
34  <-------------- lW----------------->
35                    <--------------- W ---------------->
36 :            .....|.....       _______________         |
37 :        .'''     |     '''_---      |       |\        |
38 :.....'''         |_____--- '''......|       | \_______|
39 :.................|__________________|_______|__|______|
40                   |<------ Sl ------>|      > Sr <     |endW
41                   |beginSl           |endSl  |  |endSr   
42                   |beginW            |endlW  |beginSr
43                   mult[0]                              mult[n]
44
45
46                       |< lW >|       
47                    <--------------- W ---------------->
48                   |   |  ..  ______________            |
49                   |   | '  `/        |     ---_        |
50                   |___.'___/`.       |         ---_____| 
51                   |_______|__|_______|_________________|
52                   |      >|Sl|<      |<------ Sr ----->|endW
53                   |       |  |endSl  |beginSr          |endSr
54                   |beginW |  |endlW                     
55                   mult[0] |beginSl                     mult[n]
56
57  <-------------- lW----------------->
58                           |<-W-->|                               
59 :            ..............  __  |   |                    
60 :        .'''             |`/  \ |   |                       
61 :.....'''                 |/`...\|...|                    
62 :.........................|__||__|___|                  
63                           |Sl||Sr|endW    
64                           |  ||  |endSr
65                           |  ||beginSr
66                           |  |endSl
67                           |beginSl
68                           |beginW
69                           mult[0]
70                                  mult[n]
71 */
72
73 typedef struct vorbis_state{
74   int samples_per_envelope_step;
75   int block_size[2];
76   double *window[2][2][2]; /* windowsize, leadin, leadout */
77
78   double **pcm;
79   int      pcm_storage;
80   int      pcm_channels;
81   int      pcm_current;
82
83   double **deltas;
84   int    **multipliers;
85   int      envelope_storage;
86   int      envelope_channels;
87   int      envelope_current;
88
89   int  initflag;
90
91   long lW;
92   long W;
93   long Sl;
94   long Sr;
95
96   long beginW;
97   long endW;
98   long beginSl;
99   long endSl;
100   long beginSr;
101   long endSr;
102
103   long frame;
104   long samples;
105
106 } vorbis_state;
107
108 /* arbitrary settings and spec-mandated numbers get filled in here */
109 void vorbis_init_state(vorbis_state *v,int channels,int mode){
110   memset(v,0,sizeof(vorbis_state));
111   v->samples_per_envelope_step=64;
112   v->block_size[0]=512; 
113   v->block_size[1]=2048;
114   
115   v->window[0][0][0]=vorbis_window(v->block_size[0],
116                                    v->block_size[0]/2,v->block_size[0]/2);
117   v->window[1][0][0]=vorbis_window(v->block_size[1],
118                                    v->block_size[0]/2,v->block_size[0]/2);
119   v->window[1][0][1]=vorbis_window(v->block_size[1],
120                                    v->block_size[0]/2,v->block_size[1]/2);
121   v->window[1][1][0]=vorbis_window(v->block_size[1],
122                                    v->block_size[1]/2,v->block_size[0]/2);
123   v->window[1][1][1]=vorbis_window(v->block_size[1],
124                                    v->block_size[1]/2,v->block_size[1]/2);
125
126   /* initialize the storage vectors to a decent size greater than the
127      minimum */
128   
129   v->pcm_storage=8192; /* 8k samples.  we'll assume later that we have
130                           a minimum of twice the blocksize (2k) of
131                           accumulated samples in analysis */
132   v->pcm_channels=channels;
133   v->pcm=malloc(channels*sizeof(double *));
134   {
135     int i;
136     for(i=0;i<channels;i++)
137       v->pcm[i]=calloc(v->pcm_storage,sizeof(double));
138   }
139
140   /* Initialize the envelope multiplier storage */
141   
142   v->envelope_storage=v->pcmstorage/v->samples_per_envelope_step+1;
143   v->envelope_channels=channels;
144   v->deltas=calloc(v->envelope_channels,sizeof(double *));
145   v->multipliers=calloc(v->envelope_channels,sizeof(int *));
146   {
147     int i;
148     for(i=0;i<v->envelope_channels;i++){
149       v->deltas[i]=calloc(v->envelope_storage,sizeof(double));
150       v->multipliers[i]=calloc(v->envelope_storage,sizeof(int));
151     }
152   }
153
154   /* all 1 (large block) or 0 (small block) */
155   /*v->lW=0; previous window size */
156   /*v->W=0;  determined during analysis */
157   /*v->Sl=0; previous Sr */
158   /*v->Sr=0; determined during analysis */
159
160   /* all vector indexes; multiples of samples_per_envelope_step */
161   /*v->beginW=0;  determined during analysis */
162   /*v->endW=0;    determined during analysis */
163     v->beginSl=v->block_size[1]/4-v->block_size[0]/4;
164     v->endSl=v->beginSl+v->block_size[0]/2;
165   /*v->beginSr=0; determined during analysis */
166   /*v->endSr=0;   determined during analysis */
167
168   /*v->frame=0;*/
169   /*v->samples=0;*/
170
171   v->pcm_current=v->endSl;
172   v->last_multiplier=v->endSl/v->samples_per_envelope_step+1;
173
174   v->initflag=1;
175 }
176
177 void vorbis_free_state(vorbis_state *v){
178   int i,j,k;
179   if(v){
180     for(i=0;i<2;i++)
181       for(j=0;j<2;j++)
182         for(k=0;k<2;k++)
183           if(v->window[i][j][k])free(v->window[i][j][k]);
184     if(v->pcm){
185       for(i=0;i<v->pcm_channels;i++)
186         if(v->pcm[i])free(v->pcm[i]);
187       free(v->pcm);
188     }
189     if(v->deltas){
190       for(i=0;i<v->envelope_channels;i++)
191         if(v->deltas[i])free(v->deltas[i]);
192       free(v->deltas);
193     }
194     if(v->multipliers){
195       for(i=0;i<v->envelope_channels;i++)
196         if(v->multipliers[i])free(v->multipliers[i]);
197       free(v->multipliers);
198     }
199     free(v);
200   }
201 }
202
203 int vorbis_analysis(vorbis_state *v, double **pcm, int vals){
204   int i;
205
206   /* vorbis encode state initialization */
207   if(!v->initflag)
208     vorbis_init_settings(v);
209
210   /* first we need to handle incoming data (if any) */
211   
212   if(vals>0){
213     /* Do we have enough storage space for the incoming data? If not,
214        expand the PCM storage */
215
216     if(v->pcm_current+vals>=pcm_storage){
217       for(i=0;i<v->pcm_channels;i++)
218         v->pcm[i]=realloc(v->pcm[i],
219                           (v->pcm_current+vals*2)*sizeof(double));
220       v->pcm_storage=v->pcm_current+vals*2;
221     }
222
223     /* If we're encoding the end of the stream and we're handing in
224        padding, vals will be set, but the passed in buffer will be
225        NULL; just add in zeroes */
226
227     for(i=0;i<v->pcm_channels;i++)
228       if(pcm==NULL)
229         memset(v->pcm[i]+v->pcm_current,0,vals*sizeof(double));
230       else
231         memcpy(v->pcm[i]+v->pcm_current,pcm[i],vals*sizeof(double));
232
233     v->pcm_current+=vals;
234   }
235
236   /* Do we definately have enough for a frame? We assume we have more
237      than actually necessary to encode the current block to make some
238      analysis easier. */
239
240   if(v->pcm_current-v->endSl<v->blocksize[1]*2)
241     return(0);
242
243   /* we have enough. begin analysis */
244   /* complete the envelope analysis vectors */
245
246   
247
248   /* decide the blocksize of this frame */
249
250
251   /* algebra to set the rest of the window alignment vectors; many are
252      just derived, but they make the process clearer for the time
253      being */
254
255
256
257   /* the real analysis begins; forward MDCT with window */
258
259   
260   /* Noise floor, resolution floor */
261
262   /* encode the floor into LSP; get the actual floor back for quant */
263
264   /* use noise floor, res floor for culling, actual floor for quant */
265
266   /* encode residue */
267
268   /* advance storage vectors and clean up */
269   /* center the window leadout on blocksize[1]/4 */
270   {
271     int new_beginSr,new_endSr,movement,emove;
272
273     /* first do the pcm storage */
274     if(v->Sr){
275       new_beginSl=0;
276       new_endSl=v->blocksize[1]/2;
277     }else{
278       new_beginSl=v->blocksize[1]/4-v->blocksize[0]/4;
279       new_endSl=new_beginSr+v->blocksize[0]/2;
280     }
281     movement=v->beginSr-new_beginSl;
282
283     for(i=0;i<v->pcm_channels;i++)
284       memmove(v->pcm[i],v->pcm[i]+movement,
285               (v->pcm_current-movement)*sizeof(double));
286     v->pcm_current-=movement;
287     v->lW=W;
288     v->Sl=v->Sr;
289     v->beginSl=new_beginSl;
290     v->endSl=new_endSl;
291     v->frame++;
292     v->samples+=movement;
293
294     /* now advance the multipliers */
295     emove=movement/samples_per_envelope_step; 
296     for(i=0;i<v->envelope_channels;i++){
297       memmove(v->deltas[i],v->deltas[i]+emove,
298               (v->envelope_current-emove)*sizeof(double));
299       memmove(v->multipliers[i],v->multipliers[i]+emove,
300               (v->envelope_current-emove)*sizeof(int));
301     }
302     v->envelope_current-=emove;
303   }
304
305   /* done */
306   return(1);
307 }
308
309
310
311