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: Jul 27 1999
19 Handle windowing, overlap-add, etc of the PCM vectors. This is made
20 more amusing by Vorbis' current two allowed block sizes (512 and 2048
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 ********************************************************************/
35 /* pcm accumulator and multipliers
36 examples (not exhaustive):
38 <-------------- lW----------------->
39 <--------------- W ---------------->
40 : .....|..... _______________ |
41 : .''' | '''_--- | |\ |
42 :.....''' |_____--- '''......| | \_______|
43 :.................|__________________|_______|__|______|
44 |<------ Sl ------>| > Sr < |endW
45 |beginSl |endSl | |endSr
46 |beginW |endlW |beginSr
51 <--------------- W ---------------->
52 | | .. ______________ |
54 |___.'___/`. | ---_____|
55 |_______|__|_______|_________________|
56 | >|Sl|< |<------ Sr ----->|endW
57 | | |endSl |beginSr |endSr
59 mult[0] |beginSl mult[n]
61 <-------------- lW----------------->
63 : .............. __ | |
65 :.....''' |/`...\|...|
66 :.........................|__||__|___|
77 /* arbitrary settings and spec-mandated numbers get filled in here */
78 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
79 memset(v,0,sizeof(vorbis_dsp_state));
80 v->samples_per_envelope_step=64;
82 v->block_size[1]=2048;
84 v->window[0][0][0]=_vorbis_window(v->block_size[0],
85 v->block_size[0]/2,v->block_size[0]/2);
86 v->window[0][0][1]=v->window[0][0][0];
87 v->window[0][1][0]=v->window[0][0][0];
88 v->window[0][1][1]=v->window[0][0][0];
90 v->window[1][0][0]=_vorbis_window(v->block_size[1],
91 v->block_size[0]/2,v->block_size[0]/2);
92 v->window[1][0][1]=_vorbis_window(v->block_size[1],
93 v->block_size[0]/2,v->block_size[1]/2);
94 v->window[1][1][0]=_vorbis_window(v->block_size[1],
95 v->block_size[1]/2,v->block_size[0]/2);
96 v->window[1][1][1]=_vorbis_window(v->block_size[1],
97 v->block_size[1]/2,v->block_size[1]/2);
99 /* initialize the storage vectors to a decent size greater than the
102 v->pcm_storage=8192; /* we'll assume later that we have
103 a minimum of twice the blocksize of
104 accumulated samples in analysis */
105 v->pcm_channels=v->vi.channels=vi->channels;
106 v->pcm=malloc(vi->channels*sizeof(double *));
107 v->pcmret=malloc(vi->channels*sizeof(double *));
110 for(i=0;i<vi->channels;i++)
111 v->pcm[i]=calloc(v->pcm_storage,sizeof(double));
114 /* Initialize the envelope multiplier storage */
116 v->envelope_storage=v->pcm_storage/v->samples_per_envelope_step;
117 v->envelope_channels=vi->channels;
118 v->deltas=calloc(v->envelope_channels,sizeof(double *));
119 v->multipliers=calloc(v->envelope_channels,sizeof(int *));
122 for(i=0;i<v->envelope_channels;i++){
123 v->deltas[i]=calloc(v->envelope_storage,sizeof(double));
124 v->multipliers[i]=calloc(v->envelope_storage,sizeof(int));
128 /* all 1 (large block) or 0 (small block) */
129 /* explicitly set for the sake of clarity */
130 v->lW=0; /* previous window size */
131 v->W=0; /* current window size */
133 /* all vector indexes; multiples of samples_per_envelope_step */
134 v->centerW=v->block_size[1]/2;
136 v->pcm_current=v->centerW;
137 v->envelope_current=v->centerW/v->samples_per_envelope_step;
141 void vorbis_analysis_clear(vorbis_dsp_state *v){
145 if(v->window[0][0][0])free(v->window[0][0][0]);
148 if(v->window[1][j][k])free(v->window[1][j][k]);
150 for(i=0;i<v->pcm_channels;i++)
151 if(v->pcm[i])free(v->pcm[i]);
156 for(i=0;i<v->envelope_channels;i++)
157 if(v->deltas[i])free(v->deltas[i]);
161 for(i=0;i<v->envelope_channels;i++)
162 if(v->multipliers[i])free(v->multipliers[i]);
163 free(v->multipliers);
165 memset(v,0,sizeof(vorbis_dsp_state));
169 double **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
172 /* Do we have enough storage space for the requested buffer? If not,
173 expand the PCM (and envelope) storage */
175 if(v->pcm_current+vals>=v->pcm_storage){
176 v->pcm_storage=v->pcm_current+vals*2;
177 v->envelope_storage=v->pcm_storage/v->samples_per_envelope_step;
179 for(i=0;i<v->pcm_channels;i++){
180 v->pcm[i]=realloc(v->pcm[i],v->pcm_storage*sizeof(double));
181 v->deltas[i]=realloc(v->deltas[i],v->envelope_storage*sizeof(double));
182 v->multipliers[i]=realloc(v->multipliers[i],
183 v->envelope_storage*sizeof(double));
188 for(i=0;i<v->pcm_channels;i++)
189 v->pcmret[i]=v->pcm[i]+v->pcm_current;
194 /* call with val<=0 to set eof */
196 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
198 /* We're encoding the end of the stream. Just make sure we have
199 [at least] a full block of zeroes at the end. */
202 vorbis_analysis_buffer(v,v->block_size[1]*2);
203 v->eofflag=v->pcm_current;
204 v->pcm_current+=v->block_size[1]*2;
205 for(i=0;i<v->pcm_channels;i++)
206 memset(v->pcm[i]+v->eofflag,0,
207 (v->pcm_current-v->eofflag)*sizeof(double));
210 if(v->pcm_current+vals>v->pcm_storage)
213 v->pcm_current+=vals;
218 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
220 vb->pcm_storage=v->block_size[1];
221 vb->pcm_channels=v->pcm_channels;
222 vb->mult_storage=v->block_size[1]/v->samples_per_envelope_step;
223 vb->mult_channels=v->envelope_channels;
225 vb->pcm=malloc(vb->pcm_channels*sizeof(double *));
226 for(i=0;i<vb->pcm_channels;i++)
227 vb->pcm[i]=malloc(vb->pcm_storage*sizeof(double));
229 vb->mult=malloc(vb->mult_channels*sizeof(int *));
230 for(i=0;i<vb->mult_channels;i++)
231 vb->mult[i]=malloc(vb->mult_storage*sizeof(int));
235 int vorbis_block_clear(vorbis_block *vb){
238 for(i=0;i<vb->pcm_channels;i++)
243 for(i=0;i<vb->mult_channels;i++)
247 memset(vb,0,sizeof(vorbis_block));
251 /* do the deltas, envelope shaping, pre-echo and determine the size of
252 the next block on which to continue analysis */
253 int vorbis_analysis_block(vorbis_dsp_state *v,vorbis_block *vb){
255 long beginW=v->centerW-v->block_size[v->W]/2,centerNext;
256 long beginM=beginW/v->samples_per_envelope_step;
258 /* check to see if we're done... */
259 if(v->eofflag==-1)return(0);
261 /* if we have any unfilled envelope blocks for which we have PCM
262 data, fill them up in before proceeding. */
264 if(v->pcm_current/v->samples_per_envelope_step>v->envelope_current){
265 _va_envelope_deltas(v);
266 _va_envelope_multipliers(v);
269 /* By our invariant, we have lW, W and centerW set. Search for
270 the next boundary so we can determine nW (the next window size)
271 which lets us compute the shape of the current block's window */
273 /* overconserve for now; any block with a non-placeholder multiplier
274 should be minimal size. We can be greedy and only look at nW size */
277 /* this is a long window; we start the search forward of centerW
278 because that's the fastest we could react anyway */
279 i=v->centerW+v->block_size[1]/4-v->block_size[0]/4;
281 /* short window. Search from centerW */
283 i/=v->samples_per_envelope_step;
285 for(;i<v->envelope_current;i++){
286 for(j=0;j<v->envelope_channels;j++)
287 if(v->multipliers[j][i])break;
288 if(j<v->envelope_channels)break;
291 if(i<v->envelope_current){
292 /* Ooo, we hit a multiplier. Is it beyond the boundary to make the
293 upcoming block large ? */
296 largebound=v->centerW+v->block_size[1];
298 largebound=v->centerW+v->block_size[0]/4+v->block_size[1]*3/4;
299 largebound/=v->samples_per_envelope_step;
307 /* Assume maximum; if the block is incomplete given current
308 buffered data, this will be detected below */
312 /* Do we actually have enough data *now* for the next block? The
313 reason to check is that if we had no multipliers, that could
314 simply been due to running out of data. In that case, we don;t
315 know the size of the next block for sure and we need that now to
316 figure out the window shape of this block */
318 centerNext=v->centerW+v->block_size[v->W]/4+v->block_size[v->nW]/4;
321 long blockbound=centerNext+v->block_size[v->nW]/2;
322 if(v->pcm_current<blockbound)return(0); /* not enough data yet */
325 /* fill in the block */
331 vb->pcmend=v->block_size[v->W];
332 vb->multend=vb->pcmend / v->samples_per_envelope_step;
334 if(v->pcm_channels!=vb->pcm_channels ||
335 v->block_size[1]!=vb->pcm_storage ||
336 v->envelope_channels!=vb->mult_channels){
338 /* Storage not initialized or initilized for some other codec
339 instance with different settings */
341 vorbis_block_clear(vb);
342 vorbis_block_init(v,vb);
345 /* copy the vectors */
346 for(i=0;i<v->pcm_channels;i++)
347 memcpy(vb->pcm[i],v->pcm[i]+beginW,v->block_size[v->W]*sizeof(double));
348 for(i=0;i<v->envelope_channels;i++)
349 memcpy(vb->mult[i],v->multipliers[i]+beginM,v->block_size[v->W]/
350 v->samples_per_envelope_step*sizeof(int));
352 vb->frameno=v->frame;
354 /* handle eof detection: eof==0 means that we've not yet received EOF
355 eof>0 marks the last 'real' sample in pcm[]
356 eof<0 'no more to do'; doesn't get here */
359 if(v->centerW>=v->eofflag){
365 /* advance storage vectors and clean up */
367 int new_centerNext=v->block_size[1]/2;
368 int movementW=centerNext-new_centerNext;
369 int movementM=movementW/v->samples_per_envelope_step;
371 for(i=0;i<v->pcm_channels;i++)
372 memmove(v->pcm[i],v->pcm[i]+movementW,
373 (v->pcm_current-movementW)*sizeof(double));
375 for(i=0;i<v->envelope_channels;i++){
376 memmove(v->deltas[i],v->deltas[i]+movementM,
377 (v->envelope_current-movementM)*sizeof(double));
378 memmove(v->multipliers[i],v->multipliers[i]+movementM,
379 (v->envelope_current-movementM)*sizeof(int));
382 v->pcm_current-=movementW;
383 v->envelope_current-=movementM;
387 v->centerW=new_centerNext;
390 v->samples+=movementW;
393 v->eofflag-=movementW;
409 int vorbis_analysis_packetout(vorbis_dsp_state *v, vorbis_block *vb,
412 /* find block's envelope vector and apply it */
415 /* the real analysis begins; forward MDCT with window */
418 /* Noise floor, resolution floor */
420 /* encode the floor into LSP; get the actual floor back for quant */
422 /* use noise floor, res floor for culling, actual floor for quant */
434 void _va_envelope_deltas(vorbis_dsp_state *v){
438 void _va_envelope_multipliers(vorbis_dsp_state *v){
439 /* set 'random' deltas... */
440 int new_current=v->pcm_current/v->samples_per_envelope_step;
443 for(i=v->envelope_current;i<new_current;i++){
445 for(j=0;j<v->samples_per_envelope_step;j++)
446 if(v->pcm[0][j+i*v->samples_per_envelope_step]>5)flag=1;
448 for(j=0;j<v->envelope_channels;j++)
449 v->multipliers[j][i]=flag;
451 v->envelope_current=i;
455 /* basic test of PCM blocking:
457 construct a PCM vector and block it using preset sizing in our fake
458 delta/multiplier generation. Immediately hand the block over to
459 'synthesis' and rebuild it. */
464 vorbis_dsp_state encode,decode;
470 char *temp[]={ "Test" ,"the Test band", "test records",NULL };
477 vi.user_comments=temp;
478 vi.vendor="Xiphophorus";
480 vorbis_analysis_init(&encode,&vi);
482 memset(&vb,0,sizeof(vorbis_block));
483 vorbis_block_init(&encode,&vb);
485 /* Submit 100K samples of data reading out blocks... */
489 double **buf=vorbis_analysis_buffer(&encode,blocksize);
490 for(i=0;i<blocksize;i++){
494 if((counterin+i)%15000>13000)buf[0][i]+=10;
497 i=(counterin+blocksize>fini?fini-counterin:blocksize);
498 vorbis_analysis_wrote(&encode,i);
501 while(vorbis_analysis_block(&encode,&vb)){
502 double *window=encode.window[vb.W][vb.lW][vb.nW];
505 int begin=counterout-encode.block_size[vb.W]/2;
512 counterout=counterout+encode.block_size[vb.W]/4+
513 encode.block_size[vb.nW]/4;