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-1999 *
9 * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
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
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).
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.
27 ********************************************************************/
31 /* pcm accumulator and multipliers
32 examples (not exhaustive):
34 <-------------- lW----------------->
35 <--------------- W ---------------->
36 : .....|..... _______________ |
37 : .''' | '''_--- | |\ |
38 :.....''' |_____--- '''......| | \_______|
39 :.................|__________________|_______|__|______|
40 |<------ Sl ------>| > Sr < |endW
41 |beginSl |endSl | |endSr
42 |beginW |endlW |beginSr
47 <--------------- W ---------------->
48 | | .. ______________ |
50 |___.'___/`. | ---_____|
51 |_______|__|_______|_________________|
52 | >|Sl|< |<------ Sr ----->|endW
53 | | |endSl |beginSr |endSr
55 mult[0] |beginSl mult[n]
57 <-------------- lW----------------->
59 : .............. __ | |
61 :.....''' |/`...\|...|
62 :.........................|__||__|___|
73 typedef struct vorbis_state{
74 int samples_per_envelope_step;
76 double *window[2][2][2]; /* windowsize, leadin, leadout */
86 int envelope_channels;
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;
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);
126 /* initialize the storage vectors to a decent size greater than the
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 *));
136 for(i=0;i<channels;i++)
137 v->pcm[i]=calloc(v->pcm_storage,sizeof(double));
140 /* Initialize the envelope multiplier storage */
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 *));
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));
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 */
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 */
171 v->pcm_current=v->endSl;
172 v->last_multiplier=v->endSl/v->samples_per_envelope_step+1;
177 void vorbis_free_state(vorbis_state *v){
183 if(v->window[i][j][k])free(v->window[i][j][k]);
185 for(i=0;i<v->pcm_channels;i++)
186 if(v->pcm[i])free(v->pcm[i]);
190 for(i=0;i<v->envelope_channels;i++)
191 if(v->deltas[i])free(v->deltas[i]);
195 for(i=0;i<v->envelope_channels;i++)
196 if(v->multipliers[i])free(v->multipliers[i]);
197 free(v->multipliers);
203 int vorbis_analysis(vorbis_state *v, double **pcm, int vals){
206 /* vorbis encode state initialization */
208 vorbis_init_settings(v);
210 /* first we need to handle incoming data (if any) */
213 /* Do we have enough storage space for the incoming data? If not,
214 expand the PCM storage */
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;
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 */
227 for(i=0;i<v->pcm_channels;i++)
229 memset(v->pcm[i]+v->pcm_current,0,vals*sizeof(double));
231 memcpy(v->pcm[i]+v->pcm_current,pcm[i],vals*sizeof(double));
233 v->pcm_current+=vals;
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
240 if(v->pcm_current-v->endSl<v->blocksize[1]*2)
243 /* we have enough. begin analysis */
244 /* complete the envelope analysis vectors */
248 /* decide the blocksize of this frame */
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
257 /* the real analysis begins; forward MDCT with window */
260 /* Noise floor, resolution floor */
262 /* encode the floor into LSP; get the actual floor back for quant */
264 /* use noise floor, res floor for culling, actual floor for quant */
268 /* advance storage vectors and clean up */
269 /* center the window leadout on blocksize[1]/4 */
271 int new_beginSr,new_endSr,movement,emove;
273 /* first do the pcm storage */
276 new_endSl=v->blocksize[1]/2;
278 new_beginSl=v->blocksize[1]/4-v->blocksize[0]/4;
279 new_endSl=new_beginSr+v->blocksize[0]/2;
281 movement=v->beginSr-new_beginSl;
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;
289 v->beginSl=new_beginSl;
292 v->samples+=movement;
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));
302 v->envelope_current-=emove;