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: Aug 05 1999
19 Handle windowing, overlap-add, etc of the PCM vectors. This is made
20 more amusing by Vorbis' current two allowed block sizes.
22 Vorbis manipulates the dynamic range of the incoming PCM data
23 envelope to minimise time-domain energy leakage from percussive and
24 plosive waveforms being quantized in the MDCT domain.
26 ********************************************************************/
35 /* pcm accumulator examples (not exhaustive):
37 <-------------- lW ---------------->
38 <--------------- W ---------------->
39 : .....|..... _______________ |
40 : .''' | '''_--- | |\ |
41 :.....''' |_____--- '''......| | \_______|
42 :.................|__________________|_______|__|______|
43 |<------ Sl ------>| > Sr < |endW
44 |beginSl |endSl | |endSr
45 |beginW |endlW |beginSr
49 <--------------- W ---------------->
50 | | .. ______________ |
52 |___.'___/`. | ---_____|
53 |_______|__|_______|_________________|
54 | >|Sl|< |<------ Sr ----->|endW
55 | | |endSl |beginSr |endSr
57 mult[0] |beginSl mult[n]
59 <-------------- lW ----------------->
61 : .............. ___ | |
63 :.....''' |/`....\|...|
64 :.........................|___|___|___|
73 static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){
74 memset(v,0,sizeof(vorbis_dsp_state));
76 memcpy(&v->vi,vi,sizeof(vorbis_info));
77 _ve_envelope_init(&v->ve,vi->envelopesa);
79 v->samples_per_envelope_step=vi->envelopesa;
80 v->block_size[0]=vi->smallblock;
81 v->block_size[1]=vi->largeblock;
83 v->window[0][0][0]=_vorbis_window(v->block_size[0],
84 v->block_size[0]/2,v->block_size[0]/2);
85 v->window[0][0][1]=v->window[0][0][0];
86 v->window[0][1][0]=v->window[0][0][0];
87 v->window[0][1][1]=v->window[0][0][0];
89 v->window[1][0][0]=_vorbis_window(v->block_size[1],
90 v->block_size[0]/2,v->block_size[0]/2);
91 v->window[1][0][1]=_vorbis_window(v->block_size[1],
92 v->block_size[0]/2,v->block_size[1]/2);
93 v->window[1][1][0]=_vorbis_window(v->block_size[1],
94 v->block_size[1]/2,v->block_size[0]/2);
95 v->window[1][1][1]=_vorbis_window(v->block_size[1],
96 v->block_size[1]/2,v->block_size[1]/2);
98 /* initialize the storage vectors to a decent size greater than the
101 v->pcm_storage=8192; /* we'll assume later that we have
102 a minimum of twice the blocksize of
103 accumulated samples in analysis */
104 v->pcm_channels=v->vi.channels=vi->channels;
105 v->pcm=malloc(vi->channels*sizeof(double *));
106 v->pcmret=malloc(vi->channels*sizeof(double *));
109 for(i=0;i<vi->channels;i++)
110 v->pcm[i]=calloc(v->pcm_storage,sizeof(double));
113 /* Initialize the envelope multiplier storage */
116 v->envelope_storage=v->pcm_storage/v->samples_per_envelope_step;
117 v->envelope_channels=vi->envelopech;
118 v->multipliers=calloc(v->envelope_channels,sizeof(double *));
121 for(i=0;i<v->envelope_channels;i++){
122 v->multipliers[i]=calloc(v->envelope_storage,sizeof(double));
127 /* all 1 (large block) or 0 (small block) */
128 /* explicitly set for the sake of clarity */
129 v->lW=0; /* previous window size */
130 v->W=0; /* current window size */
132 /* all vector indexes; multiples of samples_per_envelope_step */
133 v->centerW=v->block_size[1]/2;
135 v->pcm_current=v->centerW;
136 v->envelope_current=v->centerW/v->samples_per_envelope_step;
140 /* arbitrary settings and spec-mandated numbers get filled in here */
141 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
145 vi->envelopech=vi->channels;
146 vi->preecho_thresh=10.;
147 vi->preecho_thresh=4.;
148 vi->envelopemap=calloc(2,sizeof(int));
149 vi->envelopemap[0]=0;
150 vi->envelopemap[1]=1;
152 _vds_shared_init(v,vi);
157 void vorbis_analysis_clear(vorbis_dsp_state *v){
161 if(v->window[0][0][0])free(v->window[0][0][0]);
164 if(v->window[1][j][k])free(v->window[1][j][k]);
166 for(i=0;i<v->pcm_channels;i++)
167 if(v->pcm[i])free(v->pcm[i]);
172 for(i=0;i<v->envelope_channels;i++)
173 if(v->multipliers[i])free(v->multipliers[i]);
174 free(v->multipliers);
176 memset(v,0,sizeof(vorbis_dsp_state));
180 double **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
183 /* Do we have enough storage space for the requested buffer? If not,
184 expand the PCM (and envelope) storage */
186 if(v->pcm_current+vals>=v->pcm_storage){
187 v->pcm_storage=v->pcm_current+vals*2;
188 v->envelope_storage=v->pcm_storage/v->samples_per_envelope_step;
190 for(i=0;i<v->pcm_channels;i++){
191 v->pcm[i]=realloc(v->pcm[i],v->pcm_storage*sizeof(double));
193 for(i=0;i<v->envelope_channels;i++){
194 v->multipliers[i]=realloc(v->multipliers[i],
195 v->envelope_storage*sizeof(double));
199 for(i=0;i<v->pcm_channels;i++)
200 v->pcmret[i]=v->pcm[i]+v->pcm_current;
205 /* call with val<=0 to set eof */
207 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
209 /* We're encoding the end of the stream. Just make sure we have
210 [at least] a full block of zeroes at the end. */
213 vorbis_analysis_buffer(v,v->block_size[1]*2);
214 v->eofflag=v->pcm_current;
215 v->pcm_current+=v->block_size[1]*2;
216 for(i=0;i<v->pcm_channels;i++)
217 memset(v->pcm[i]+v->eofflag,0,
218 (v->pcm_current-v->eofflag)*sizeof(double));
221 if(v->pcm_current+vals>v->pcm_storage)
224 v->pcm_current+=vals;
229 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
231 vb->pcm_storage=v->block_size[1];
232 vb->pcm_channels=v->pcm_channels;
233 vb->mult_storage=v->block_size[1]/v->samples_per_envelope_step;
234 vb->mult_channels=v->envelope_channels;
236 vb->pcm=malloc(vb->pcm_channels*sizeof(double *));
237 for(i=0;i<vb->pcm_channels;i++)
238 vb->pcm[i]=malloc(vb->pcm_storage*sizeof(double));
240 vb->mult=malloc(vb->mult_channels*sizeof(double *));
241 for(i=0;i<vb->mult_channels;i++)
242 vb->mult[i]=malloc(vb->mult_storage*sizeof(double));
246 int vorbis_block_clear(vorbis_block *vb){
249 for(i=0;i<vb->pcm_channels;i++)
254 for(i=0;i<vb->mult_channels;i++)
258 memset(vb,0,sizeof(vorbis_block));
262 /* do the deltas, envelope shaping, pre-echo and determine the size of
263 the next block on which to continue analysis */
264 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
266 long beginW=v->centerW-v->block_size[v->W]/2,centerNext;
267 long beginM=beginW/v->samples_per_envelope_step;
269 /* check to see if we're done... */
270 if(v->eofflag==-1)return(0);
272 /* if we have any unfilled envelope blocks for which we have PCM
273 data, fill them up in before proceeding. */
275 if(v->pcm_current/v->samples_per_envelope_step>v->envelope_current){
276 /* This generates the multipliers, but does not sparsify the vector.
277 That's done by block before coding */
278 _ve_envelope_multipliers(v);
281 /* By our invariant, we have lW, W and centerW set. Search for
282 the next boundary so we can determine nW (the next window size)
283 which lets us compute the shape of the current block's window */
285 /* overconserve for now; any block with a non-placeholder multiplier
286 should be minimal size. We can be greedy and only look at nW size */
289 /* this is a long window; we start the search forward of centerW
290 because that's the fastest we could react anyway */
291 i=v->centerW+v->block_size[1]/4-v->block_size[0]/4;
293 /* short window. Search from centerW */
295 i/=v->samples_per_envelope_step;
297 for(;i<v->envelope_current;i++){
298 for(j=0;j<v->envelope_channels;j++)
299 if(v->multipliers[j][i-1]*v->vi.preecho_thresh<
300 v->multipliers[j][i])break;
301 if(j<v->envelope_channels)break;
304 if(i<v->envelope_current){
305 /* Ooo, we hit a multiplier. Is it beyond the boundary to make the
306 upcoming block large ? */
309 largebound=v->centerW+v->block_size[1];
311 largebound=v->centerW+v->block_size[0]/4+v->block_size[1]*3/4;
312 largebound/=v->samples_per_envelope_step;
320 /* Assume maximum; if the block is incomplete given current
321 buffered data, this will be detected below */
325 /* Do we actually have enough data *now* for the next block? The
326 reason to check is that if we had no multipliers, that could
327 simply been due to running out of data. In that case, we don;t
328 know the size of the next block for sure and we need that now to
329 figure out the window shape of this block */
331 centerNext=v->centerW+v->block_size[v->W]/4+v->block_size[v->nW]/4;
334 long blockbound=centerNext+v->block_size[v->nW]/2;
335 if(v->pcm_current<blockbound)return(0); /* not enough data yet */
338 /* fill in the block */
344 vb->pcmend=v->block_size[v->W];
345 vb->multend=vb->pcmend / v->samples_per_envelope_step;
347 if(v->pcm_channels!=vb->pcm_channels ||
348 v->block_size[1]!=vb->pcm_storage ||
349 v->envelope_channels!=vb->mult_channels){
351 /* Storage not initialized or initilized for some other codec
352 instance with different settings */
354 vorbis_block_clear(vb);
355 vorbis_block_init(v,vb);
358 /* copy the vectors */
359 for(i=0;i<v->pcm_channels;i++)
360 memcpy(vb->pcm[i],v->pcm[i]+beginW,v->block_size[v->W]*sizeof(double));
361 for(i=0;i<v->envelope_channels;i++)
362 memcpy(vb->mult[i],v->multipliers[i]+beginM,v->block_size[v->W]/
363 v->samples_per_envelope_step*sizeof(double));
365 vb->frameno=v->frame;
367 /* handle eof detection: eof==0 means that we've not yet received EOF
368 eof>0 marks the last 'real' sample in pcm[]
369 eof<0 'no more to do'; doesn't get here */
372 if(v->centerW>=v->eofflag){
378 /* advance storage vectors and clean up */
380 int new_centerNext=v->block_size[1]/2;
381 int movementW=centerNext-new_centerNext;
382 int movementM=movementW/v->samples_per_envelope_step;
384 /* the multipliers and pcm stay synced up because the blocksizes
385 must be multiples of samples_per_envelope_step (minimum
388 for(i=0;i<v->pcm_channels;i++)
389 memmove(v->pcm[i],v->pcm[i]+movementW,
390 (v->pcm_current-movementW)*sizeof(double));
392 for(i=0;i<v->envelope_channels;i++){
393 memmove(v->multipliers[i],v->multipliers[i]+movementM,
394 (v->envelope_current-movementM)*sizeof(double));
397 v->pcm_current-=movementW;
398 v->envelope_current-=movementM;
402 v->centerW=new_centerNext;
405 v->samples+=movementW;
408 v->eofflag-=movementW;
415 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
416 int temp=vi->envelopech;
417 vi->envelopech=0; /* we don't need multiplier buffering in syn */
418 _vds_shared_init(v,vi);
421 /* Adjust centerW to allow an easier mechanism for determining output */
422 v->pcm_returned=v->centerW;
423 v->centerW-= v->block_size[v->W]/4+v->block_size[v->lW]/4;
427 /* Unike in analysis, the window is only partially applied. Envelope
428 is previously applied (the whole envelope, if any, is shipped in
431 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
433 /* Shift out any PCM that we returned previously */
435 if(v->pcm_returned && v->centerW>v->block_size[1]/2){
437 /* don't shift too much; we need to have a minimum PCM buffer of
440 int shift=v->centerW-v->block_size[1]/2;
441 shift=(v->pcm_returned<shift?v->pcm_returned:shift);
443 v->pcm_current-=shift;
445 v->pcm_returned-=shift;
449 for(i=0;i<v->pcm_channels;i++)
450 memmove(v->pcm[i],v->pcm[i]+shift,
451 v->pcm_current*sizeof(double));
456 int sizeW=v->block_size[vb->W];
457 int centerW=v->centerW+v->block_size[vb->lW]/4+sizeW/4;
458 int beginW=centerW-sizeW/2;
459 int endW=beginW+sizeW;
465 /* Do we have enough PCM storage for the block? */
466 if(endW>v->pcm_storage){
467 /* expand the PCM storage */
469 v->pcm_storage=endW+v->block_size[1];
471 for(i=0;i<v->pcm_channels;i++)
472 v->pcm[i]=realloc(v->pcm[i],v->pcm_storage*sizeof(double));
479 endSl=v->block_size[0]/2;
482 beginSl=v->block_size[1]/4-v->block_size[vb->lW]/4;
483 endSl=beginSl+v->block_size[vb->lW]/2;
487 window=v->window[vb->W][0][vb->lW]+v->block_size[vb->W]/2;
489 for(j=0;j<v->pcm_channels;j++){
490 double *pcm=v->pcm[j]+beginW;
492 /* the add section */
493 for(i=beginSl;i<endSl;i++)
494 pcm[i]=pcm[i]*window[i]+vb->pcm[j][i];
495 /* the remaining section */
497 pcm[i]=vb->pcm[j][i];
500 /* Update, cleanup */
505 if(vb->eofflag)v->eofflag=1;
510 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,double ***pcm){
511 if(v->pcm_returned<v->centerW){
513 for(i=0;i<v->pcm_channels;i++)
514 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
516 return(v->centerW-v->pcm_returned);
521 int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
522 if(bytes && v->pcm_returned+bytes>v->centerW)return(-1);
523 v->pcm_returned+=bytes;
531 /* basic test of PCM blocking:
533 construct a PCM vector and block it using preset sizing in our fake
534 delta/multiplier generation. Immediately hand the block over to
535 'synthesis' and rebuild it. */
540 vorbis_dsp_state encode,decode;
547 char *temp[]={ "Test" ,"the Test band", "test records",NULL };
556 vi.user_comments=temp;
557 vi.vendor="Xiphophorus";
559 vorbis_analysis_init(&encode,&vi);
560 vorbis_synthesis_init(&decode,&vi);
562 memset(&vb,0,sizeof(vorbis_block));
563 vorbis_block_init(&encode,&vb);
565 ml[0]=MDCT_init(encode.block_size[0]);
566 ml[1]=MDCT_init(encode.block_size[1]);
568 /* Submit 100K samples of data reading out blocks... */
572 double **buf=vorbis_analysis_buffer(&encode,blocksize);
573 for(i=0;i<blocksize;i++){
574 buf[0][i]=sin((counterin+i)%500/500.*M_PI*2)+2;
577 if((counterin+i)%15000>13000)buf[0][i]+=10;
580 i=(counterin+blocksize>fini?fini-counterin:blocksize);
581 vorbis_analysis_wrote(&encode,i);
584 while(vorbis_analysis_blockout(&encode,&vb)){
590 double *window=encode.window[vb.W][vb.lW][vb.nW];
593 _ve_envelope_sparsify(&vb);
594 _ve_envelope_apply(&vb,0);
596 for(i=0;i<vb.pcm_channels;i++)
597 MDCT(vb.pcm[i],vb.pcm[i],ml[vb.W],window);
599 for(i=0;i<vb.pcm_channels;i++)
600 iMDCT(vb.pcm[i],vb.pcm[i],ml[vb.W],window);
608 int avail=encode.block_size[vb.W];
609 int beginW=countermid-avail/2;
611 sprintf(path,"ana%d",vb.frameno);
615 fprintf(out,"%d %g\n",i+beginW,vb.pcm[0][i]);
618 fprintf(out,"%d %g\n",i+beginW,window[i]);
621 countermid+=encode.block_size[vb.W]/4+encode.block_size[vb.nW]/4;
625 _ve_envelope_apply(&vb,1);
626 vorbis_synthesis_blockin(&decode,&vb);
629 while((avail=vorbis_synthesis_pcmout(&decode,&pcm))){
634 sprintf(path,"syn%d",frame);
638 fprintf(out,"%ld %g\n",i+counterout,pcm[0][i]);
641 fprintf(out,"%ld %g\n",i+counterout,pcm[1][i]);
645 vorbis_synthesis_read(&decode,avail);