1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE.   *
4  *                                                                  *
5  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
6  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
8  *                                                                  *
9  * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002    *
10  * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
11  *                                                                  *
12  ********************************************************************
13 
14  function: PCM data vector blocking, windowing and dis/reassembly
15 
16  ********************************************************************/
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include "ogg.h"
22 #include "ivorbiscodec.h"
23 #include "codec_internal.h"
24 
25 #include "window.h"
26 #include "registry.h"
27 #include "misc.h"
28 
ilog(unsigned int v)29 static int ilog(unsigned int v){
30   int ret=0;
31   if(v)--v;
32   while(v){
33     ret++;
34     v>>=1;
35   }
36   return(ret);
37 }
38 
39 /* pcm accumulator examples (not exhaustive):
40 
41  <-------------- lW ---------------->
42                    <--------------- W ---------------->
43 :            .....|.....       _______________         |
44 :        .'''     |     '''_---      |       |\        |
45 :.....'''         |_____--- '''......|       | \_______|
46 :.................|__________________|_______|__|______|
47                   |<------ Sl ------>|      > Sr <     |endW
48                   |beginSl           |endSl  |  |endSr
49                   |beginW            |endlW  |beginSr
50 
51 
52                       |< lW >|
53                    <--------------- W ---------------->
54                   |   |  ..  ______________            |
55                   |   | '  `/        |     ---_        |
56                   |___.'___/`.       |         ---_____|
57                   |_______|__|_______|_________________|
58                   |      >|Sl|<      |<------ Sr ----->|endW
59                   |       |  |endSl  |beginSr          |endSr
60                   |beginW |  |endlW
61                   mult[0] |beginSl                     mult[n]
62 
63  <-------------- lW ----------------->
64                           |<--W-->|
65 :            ..............  ___  |   |
66 :        .'''             |`/   \ |   |
67 :.....'''                 |/`....\|...|
68 :.........................|___|___|___|
69                           |Sl |Sr |endW
70                           |   |   |endSr
71                           |   |beginSr
72                           |   |endSl
73 			  |beginSl
74 			  |beginW
75 */
76 
77 /* block abstraction setup *********************************************/
78 
79 #ifndef WORD_ALIGN
80 #define WORD_ALIGN 8
81 #endif
82 
vorbis_block_init(vorbis_dsp_state * v,vorbis_block * vb)83 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
84   memset(vb,0,sizeof(*vb));
85   vb->vd=v;
86   vb->localalloc=0;
87   vb->localstore=NULL;
88 
89   return(0);
90 }
91 
_vorbis_block_alloc(vorbis_block * vb,long bytes)92 void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
93   bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
94   if(bytes+vb->localtop>vb->localalloc){
95     /* can't just realloc... there are outstanding pointers */
96     if(vb->localstore){
97       struct alloc_chain *link=(struct alloc_chain *)malloc(sizeof(*link));
98       vb->totaluse+=vb->localtop;
99       link->next=vb->reap;
100       link->ptr=vb->localstore;
101       vb->reap=link;
102     }
103     /* highly conservative */
104     vb->localalloc=bytes;
105     vb->localstore=malloc(vb->localalloc);
106     vb->localtop=0;
107   }
108   {
109     void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
110     vb->localtop+=bytes;
111     return ret;
112   }
113 }
114 
115 /* reap the chain, pull the ripcord */
_vorbis_block_ripcord(vorbis_block * vb)116 void _vorbis_block_ripcord(vorbis_block *vb){
117   /* reap the chain */
118   struct alloc_chain *reap=vb->reap;
119   while(reap){
120     struct alloc_chain *next=reap->next;
121     free(reap->ptr);
122     memset(reap,0,sizeof(*reap));
123     free(reap);
124     reap=next;
125   }
126   /* consolidate storage */
127   if(vb->totaluse){
128     vb->localstore=realloc(vb->localstore,vb->totaluse+vb->localalloc);
129     vb->localalloc+=vb->totaluse;
130     vb->totaluse=0;
131   }
132 
133   /* pull the ripcord */
134   vb->localtop=0;
135   vb->reap=NULL;
136 }
137 
vorbis_block_clear(vorbis_block * vb)138 int vorbis_block_clear(vorbis_block *vb){
139   _vorbis_block_ripcord(vb);
140   if(vb->localstore)
141      free(vb->localstore);
142 
143   memset(vb,0,sizeof(*vb));
144   return(0);
145 }
146 
_vds_init(vorbis_dsp_state * v,vorbis_info * vi)147 static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
148   int i;
149   codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
150   private_state *b=NULL;
151 
152   if(ci==NULL) return 1;
153 
154   memset(v,0,sizeof(*v));
155   b=(private_state *)(v->backend_state=calloc(1,sizeof(*b)));
156 
157   v->vi=vi;
158   b->modebits=ilog(ci->modes);
159 
160   /* Vorbis I uses only window type 0 */
161   b->window[0]=_vorbis_window(0,ci->blocksizes[0]/2);
162   b->window[1]=_vorbis_window(0,ci->blocksizes[1]/2);
163 
164   /* finish the codebooks */
165   if(!ci->fullbooks){
166     ci->fullbooks=(codebook *)calloc(ci->books,sizeof(*ci->fullbooks));
167     for(i=0;i<ci->books;i++){
168       if(ci->book_param[i]==NULL)
169         goto abort_books;
170       if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
171         goto abort_books;
172       /* decode codebooks are now standalone after init */
173       vorbis_staticbook_destroy(ci->book_param[i]);
174       ci->book_param[i]=NULL;
175     }
176   }
177 
178   v->pcm_storage=ci->blocksizes[1];
179   v->pcm=(int32_t **)malloc(vi->channels*sizeof(*v->pcm));
180   v->pcmret=(int32_t **)malloc(vi->channels*sizeof(*v->pcmret));
181   for(i=0;i<vi->channels;i++)
182     v->pcm[i]=(int32_t *)calloc(v->pcm_storage,sizeof(*v->pcm[i]));
183 
184   /* all 1 (large block) or 0 (small block) */
185   /* explicitly set for the sake of clarity */
186   v->lW=0; /* previous window size */
187   v->W=0;  /* current window size */
188 
189   /* initialize all the mapping/backend lookups */
190   b->mode=(vorbis_look_mapping **)calloc(ci->modes,sizeof(*b->mode));
191   for(i=0;i<ci->modes;i++){
192     int mapnum=ci->mode_param[i]->mapping;
193     int maptype=ci->map_type[mapnum];
194     b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i],
195 					 ci->map_param[mapnum]);
196   }
197   return 0;
198 abort_books:
199   for(i=0;i<ci->books;i++){
200     if(ci->book_param[i]!=NULL){
201       vorbis_staticbook_destroy(ci->book_param[i]);
202       ci->book_param[i]=NULL;
203     }
204   }
205   vorbis_dsp_clear(v);
206   return -1;
207 }
208 
vorbis_synthesis_restart(vorbis_dsp_state * v)209 int vorbis_synthesis_restart(vorbis_dsp_state *v){
210   vorbis_info *vi=v->vi;
211   codec_setup_info *ci;
212 
213   if(!v->backend_state)return -1;
214   if(!vi)return -1;
215   ci=vi->codec_setup;
216   if(!ci)return -1;
217 
218   v->centerW=ci->blocksizes[1]/2;
219   v->pcm_current=v->centerW;
220 
221   v->pcm_returned=-1;
222   v->granulepos=-1;
223   v->sequence=-1;
224   ((private_state *)(v->backend_state))->sample_count=-1;
225 
226   return(0);
227 }
228 
vorbis_synthesis_init(vorbis_dsp_state * v,vorbis_info * vi)229 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
230   if(_vds_init(v,vi))return 1;
231   vorbis_synthesis_restart(v);
232 
233   return 0;
234 }
235 
vorbis_dsp_clear(vorbis_dsp_state * v)236 void vorbis_dsp_clear(vorbis_dsp_state *v){
237   int i;
238   if(v){
239     vorbis_info *vi=v->vi;
240     codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL);
241     private_state *b=(private_state *)v->backend_state;
242 
243     if(v->pcm)
244     {
245        if(vi)
246           for(i=0;i<vi->channels;i++)
247              if(v->pcm[i])
248                 free(v->pcm[i]);
249        free(v->pcm);
250        if(v->pcmret)
251           free(v->pcmret);
252     }
253 
254     /* free mode lookups; these are actually vorbis_look_mapping structs */
255     if(ci){
256       for(i=0;i<ci->modes;i++){
257 	int mapnum=ci->mode_param[i]->mapping;
258 	int maptype=ci->map_type[mapnum];
259 	if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]);
260       }
261     }
262 
263     if(b)
264     {
265       if(b->mode)
266          free(b->mode);
267       free(b);
268     }
269 
270     memset(v,0,sizeof(*v));
271   }
272 }
273 
274 /* Unlike in analysis, the window is only partially applied for each
275    block.  The time domain envelope is not yet handled at the point of
276    calling (as it relies on the previous block). */
277 
vorbis_synthesis_blockin(vorbis_dsp_state * v,vorbis_block * vb)278 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
279   vorbis_info *vi=v->vi;
280   codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
281   private_state *b=v->backend_state;
282   int i,j;
283 
284   if(v->pcm_current>v->pcm_returned  && v->pcm_returned!=-1)return(OV_EINVAL);
285 
286   v->lW=v->W;
287   v->W=vb->W;
288   v->nW=-1;
289 
290   if((v->sequence==-1)||
291      (v->sequence+1 != vb->sequence)){
292     v->granulepos=-1; /* out of sequence; lose count */
293     b->sample_count=-1;
294   }
295 
296   v->sequence=vb->sequence;
297 
298   if(vb->pcm){  /* no pcm to process if vorbis_synthesis_trackonly
299                    was called on block */
300     int n=ci->blocksizes[v->W]/2;
301     int n0=ci->blocksizes[0]/2;
302     int n1=ci->blocksizes[1]/2;
303 
304     int thisCenter;
305     int prevCenter;
306 
307     if(v->centerW){
308       thisCenter=n1;
309       prevCenter=0;
310     }else{
311       thisCenter=0;
312       prevCenter=n1;
313     }
314 
315     /* v->pcm is now used like a two-stage double buffer.  We don't want
316        to have to constantly shift *or* adjust memory usage.  Don't
317        accept a new block until the old is shifted out */
318 
319     /* overlap/add PCM */
320 
321     for(j=0;j<vi->channels;j++){
322       /* the overlap/add section */
323       if(v->lW){
324 	if(v->W){
325 	  /* large/large */
326 	  int32_t *pcm=v->pcm[j]+prevCenter;
327 	  int32_t *p=vb->pcm[j];
328 	  for(i=0;i<n1;i++)
329 	    pcm[i]+=p[i];
330 	}else{
331 	  /* large/small */
332 	  int32_t *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
333 	  int32_t *p=vb->pcm[j];
334 	  for(i=0;i<n0;i++)
335 	    pcm[i]+=p[i];
336 	}
337       }else{
338 	if(v->W){
339 	  /* small/large */
340 	  int32_t *pcm=v->pcm[j]+prevCenter;
341 	  int32_t *p=vb->pcm[j]+n1/2-n0/2;
342 	  for(i=0;i<n0;i++)
343 	    pcm[i]+=p[i];
344 	  for(;i<n1/2+n0/2;i++)
345 	    pcm[i]=p[i];
346 	}else{
347 	  /* small/small */
348 	  int32_t *pcm=v->pcm[j]+prevCenter;
349 	  int32_t *p=vb->pcm[j];
350 	  for(i=0;i<n0;i++)
351 	    pcm[i]+=p[i];
352 	}
353       }
354 
355       /* the copy section */
356       {
357 	int32_t *pcm=v->pcm[j]+thisCenter;
358 	int32_t *p=vb->pcm[j]+n;
359 	for(i=0;i<n;i++)
360 	  pcm[i]=p[i];
361       }
362     }
363 
364     if(v->centerW)
365       v->centerW=0;
366     else
367       v->centerW=n1;
368 
369     /* deal with initial packet state; we do this using the explicit
370        pcm_returned==-1 flag otherwise we're sensitive to first block
371        being short or long */
372 
373     if(v->pcm_returned==-1){
374       v->pcm_returned=thisCenter;
375       v->pcm_current=thisCenter;
376     }else{
377       v->pcm_returned=prevCenter;
378       v->pcm_current=prevCenter+
379 	ci->blocksizes[v->lW]/4+
380 	ci->blocksizes[v->W]/4;
381     }
382 
383   }
384 
385   /* track the frame number... This is for convenience, but also
386      making sure our last packet doesn't end with added padding.  If
387      the last packet is partial, the number of samples we'll have to
388      return will be past the vb->granulepos.
389 
390      This is not foolproof!  It will be confused if we begin
391      decoding at the last page after a seek or hole.  In that case,
392      we don't have a starting point to judge where the last frame
393      is.  For this reason, vorbisfile will always try to make sure
394      it reads the last two marked pages in proper sequence */
395 
396   if(b->sample_count==-1){
397     b->sample_count=0;
398   }else{
399     b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
400   }
401 
402   if(v->granulepos==-1){
403     if(vb->granulepos!=-1){ /* only set if we have a position to set to */
404 
405       v->granulepos=vb->granulepos;
406 
407       /* is this a short page? */
408       if(b->sample_count>v->granulepos){
409 	/* corner case; if this is both the first and last audio page,
410 	   then spec says the end is cut, not beginning */
411 	long extra=b->sample_count-vb->granulepos;
412 
413         /* we use int64_t for granule positions because a
414            uint64 isn't universally available.  Unfortunately,
415            that means granposes can be 'negative' and result in
416            extra being negative */
417         if(extra<0)
418           extra=0;
419 
420 	if(vb->eofflag){
421 	  /* trim the end */
422 	  /* no preceeding granulepos; assume we started at zero (we'd
423 	     have to in a short single-page stream) */
424 	  /* granulepos could be -1 due to a seek, but that would result
425 	     in a long coun`t, not short count */
426 
427           /* Guard against corrupt/malicious frames that set EOP and
428              a backdated granpos; don't rewind more samples than we
429              actually have */
430           if(extra > v->pcm_current - v->pcm_returned)
431             extra = v->pcm_current - v->pcm_returned;
432 
433 	  v->pcm_current-=extra;
434 	}else{
435 	  /* trim the beginning */
436 	  v->pcm_returned+=extra;
437 	  if(v->pcm_returned>v->pcm_current)
438 	    v->pcm_returned=v->pcm_current;
439 	}
440 
441       }
442 
443     }
444   }else{
445     v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
446     if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
447 
448       if(v->granulepos>vb->granulepos){
449 	long extra=v->granulepos-vb->granulepos;
450 
451 	if(extra)
452 	  if(vb->eofflag){
453 	    /* partial last frame.  Strip the extra samples off */
454 
455             /* Guard against corrupt/malicious frames that set EOP and
456                a backdated granpos; don't rewind more samples than we
457                actually have */
458             if(extra > v->pcm_current - v->pcm_returned)
459               extra = v->pcm_current - v->pcm_returned;
460 
461             /* we use int64_t for granule positions because a
462                uint64 isn't universally available.  Unfortunately,
463                that means granposes can be 'negative' and result in
464                extra being negative */
465             if(extra<0)
466               extra=0;
467 
468             v->pcm_current-=extra;
469 
470 	  } /* else {Shouldn't happen *unless* the bitstream is out of
471 	       spec.  Either way, believe the bitstream } */
472       } /* else {Shouldn't happen *unless* the bitstream is out of
473 	   spec.  Either way, believe the bitstream } */
474       v->granulepos=vb->granulepos;
475     }
476   }
477 
478   /* Update, cleanup */
479 
480   if(vb->eofflag)v->eofflag=1;
481   return(0);
482 }
483 
484 /* pcm==NULL indicates we just want the pending samples, no more */
vorbis_synthesis_pcmout(vorbis_dsp_state * v,int32_t *** pcm)485 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,int32_t ***pcm){
486   vorbis_info *vi=v->vi;
487   if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
488     if(pcm){
489       int i;
490       for(i=0;i<vi->channels;i++)
491 	v->pcmret[i]=v->pcm[i]+v->pcm_returned;
492       *pcm=v->pcmret;
493     }
494     return(v->pcm_current-v->pcm_returned);
495   }
496   return(0);
497 }
498 
vorbis_synthesis_read(vorbis_dsp_state * v,int bytes)499 int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
500   if(bytes && v->pcm_returned+bytes>v->pcm_current)return(OV_EINVAL);
501   v->pcm_returned+=bytes;
502   return(0);
503 }
504 
505