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