Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/libvorbis-1.2.0/lib/block.c @ 16

Last change on this file since 16 was 16, checked in by landauf, 16 years ago

added libvorbis

File size: 27.1 KB
Line 
1/********************************************************************
2 *                                                                  *
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7 *                                                                  *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
9 * by the Xiph.Org Foundation http://www.xiph.org/                  *
10 *                                                                  *
11 ********************************************************************
12
13 function: PCM data vector blocking, windowing and dis/reassembly
14 last mod: $Id: block.c 13293 2007-07-24 00:09:47Z xiphmont $
15
16 Handle windowing, overlap-add, etc of the PCM vectors.  This is made
17 more amusing by Vorbis' current two allowed block sizes.
18 
19 ********************************************************************/
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <ogg/ogg.h>
25#include "vorbis/codec.h"
26#include "codec_internal.h"
27
28#include "window.h"
29#include "mdct.h"
30#include "lpc.h"
31#include "registry.h"
32#include "misc.h"
33
34static int ilog2(unsigned int v){
35  int ret=0;
36  if(v)--v;
37  while(v){
38    ret++;
39    v>>=1;
40  }
41  return(ret);
42}
43
44/* pcm accumulator examples (not exhaustive):
45
46 <-------------- lW ---------------->
47                   <--------------- W ---------------->
48:            .....|.....       _______________         |
49:        .'''     |     '''_---      |       |\        |
50:.....'''         |_____--- '''......|       | \_______|
51:.................|__________________|_______|__|______|
52                  |<------ Sl ------>|      > Sr <     |endW
53                  |beginSl           |endSl  |  |endSr   
54                  |beginW            |endlW  |beginSr
55
56
57                      |< lW >|       
58                   <--------------- W ---------------->
59                  |   |  ..  ______________            |
60                  |   | '  `/        |     ---_        |
61                  |___.'___/`.       |         ---_____|
62                  |_______|__|_______|_________________|
63                  |      >|Sl|<      |<------ Sr ----->|endW
64                  |       |  |endSl  |beginSr          |endSr
65                  |beginW |  |endlW                     
66                  mult[0] |beginSl                     mult[n]
67
68 <-------------- lW ----------------->
69                          |<--W-->|                               
70:            ..............  ___  |   |                   
71:        .'''             |`/   \ |   |                       
72:.....'''                 |/`....\|...|                   
73:.........................|___|___|___|                 
74                          |Sl |Sr |endW   
75                          |   |   |endSr
76                          |   |beginSr
77                          |   |endSl
78                          |beginSl
79                          |beginW
80*/
81
82/* block abstraction setup *********************************************/
83
84#ifndef WORD_ALIGN
85#define WORD_ALIGN 8
86#endif
87
88int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
89  int i;
90  memset(vb,0,sizeof(*vb));
91  vb->vd=v;
92  vb->localalloc=0;
93  vb->localstore=NULL;
94  if(v->analysisp){
95    vorbis_block_internal *vbi=
96      vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
97    vbi->ampmax=-9999;
98
99    for(i=0;i<PACKETBLOBS;i++){
100      if(i==PACKETBLOBS/2){
101        vbi->packetblob[i]=&vb->opb;
102      }else{
103        vbi->packetblob[i]=
104          _ogg_calloc(1,sizeof(oggpack_buffer));
105      }
106      oggpack_writeinit(vbi->packetblob[i]);
107    }   
108  }
109
110  return(0);
111}
112
113void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
114  bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
115  if(bytes+vb->localtop>vb->localalloc){
116    /* can't just _ogg_realloc... there are outstanding pointers */
117    if(vb->localstore){
118      struct alloc_chain *link=_ogg_malloc(sizeof(*link));
119      vb->totaluse+=vb->localtop;
120      link->next=vb->reap;
121      link->ptr=vb->localstore;
122      vb->reap=link;
123    }
124    /* highly conservative */
125    vb->localalloc=bytes;
126    vb->localstore=_ogg_malloc(vb->localalloc);
127    vb->localtop=0;
128  }
129  {
130    void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
131    vb->localtop+=bytes;
132    return ret;
133  }
134}
135
136/* reap the chain, pull the ripcord */
137void _vorbis_block_ripcord(vorbis_block *vb){
138  /* reap the chain */
139  struct alloc_chain *reap=vb->reap;
140  while(reap){
141    struct alloc_chain *next=reap->next;
142    _ogg_free(reap->ptr);
143    memset(reap,0,sizeof(*reap));
144    _ogg_free(reap);
145    reap=next;
146  }
147  /* consolidate storage */
148  if(vb->totaluse){
149    vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
150    vb->localalloc+=vb->totaluse;
151    vb->totaluse=0;
152  }
153
154  /* pull the ripcord */
155  vb->localtop=0;
156  vb->reap=NULL;
157}
158
159int vorbis_block_clear(vorbis_block *vb){
160  int i;
161  vorbis_block_internal *vbi=vb->internal;
162
163  _vorbis_block_ripcord(vb);
164  if(vb->localstore)_ogg_free(vb->localstore);
165
166  if(vbi){
167    for(i=0;i<PACKETBLOBS;i++){
168      oggpack_writeclear(vbi->packetblob[i]);
169      if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
170    }
171    _ogg_free(vbi);
172  }
173  memset(vb,0,sizeof(*vb));
174  return(0);
175}
176
177/* Analysis side code, but directly related to blocking.  Thus it's
178   here and not in analysis.c (which is for analysis transforms only).
179   The init is here because some of it is shared */
180
181static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
182  int i;
183  codec_setup_info *ci=vi->codec_setup;
184  private_state *b=NULL;
185  int hs;
186
187  if(ci==NULL) return 1;
188  hs=ci->halfrate_flag; 
189
190  memset(v,0,sizeof(*v));
191  b=v->backend_state=_ogg_calloc(1,sizeof(*b));
192
193  v->vi=vi;
194  b->modebits=ilog2(ci->modes);
195
196  b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
197  b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
198
199  /* MDCT is tranform 0 */
200
201  b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
202  b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
203  mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
204  mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
205
206  /* Vorbis I uses only window type 0 */
207  b->window[0]=ilog2(ci->blocksizes[0])-6;
208  b->window[1]=ilog2(ci->blocksizes[1])-6;
209
210  if(encp){ /* encode/decode differ here */
211
212    /* analysis always needs an fft */
213    drft_init(&b->fft_look[0],ci->blocksizes[0]);
214    drft_init(&b->fft_look[1],ci->blocksizes[1]);
215
216    /* finish the codebooks */
217    if(!ci->fullbooks){
218      ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
219      for(i=0;i<ci->books;i++)
220        vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
221    }
222
223    b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy));
224    for(i=0;i<ci->psys;i++){
225      _vp_psy_init(b->psy+i,
226                   ci->psy_param[i],
227                   &ci->psy_g_param,
228                   ci->blocksizes[ci->psy_param[i]->blockflag]/2,
229                   vi->rate);
230    }
231
232    v->analysisp=1;
233  }else{
234    /* finish the codebooks */
235    if(!ci->fullbooks){
236      ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
237      for(i=0;i<ci->books;i++){
238        vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
239        /* decode codebooks are now standalone after init */
240        vorbis_staticbook_destroy(ci->book_param[i]);
241        ci->book_param[i]=NULL;
242      }
243    }
244  }
245
246  /* initialize the storage vectors. blocksize[1] is small for encode,
247     but the correct size for decode */
248  v->pcm_storage=ci->blocksizes[1];
249  v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
250  v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
251  {
252    int i;
253    for(i=0;i<vi->channels;i++)
254      v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
255  }
256
257  /* all 1 (large block) or 0 (small block) */
258  /* explicitly set for the sake of clarity */
259  v->lW=0; /* previous window size */
260  v->W=0;  /* current window size */
261
262  /* all vector indexes */
263  v->centerW=ci->blocksizes[1]/2;
264
265  v->pcm_current=v->centerW;
266
267  /* initialize all the backend lookups */
268  b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
269  b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
270
271  for(i=0;i<ci->floors;i++)
272    b->flr[i]=_floor_P[ci->floor_type[i]]->
273      look(v,ci->floor_param[i]);
274
275  for(i=0;i<ci->residues;i++)
276    b->residue[i]=_residue_P[ci->residue_type[i]]->
277      look(v,ci->residue_param[i]);   
278
279  return 0;
280}
281
282/* arbitrary settings and spec-mandated numbers get filled in here */
283int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
284  private_state *b=NULL;
285
286  if(_vds_shared_init(v,vi,1))return 1;
287  b=v->backend_state;
288  b->psy_g_look=_vp_global_look(vi);
289
290  /* Initialize the envelope state storage */
291  b->ve=_ogg_calloc(1,sizeof(*b->ve));
292  _ve_envelope_init(b->ve,vi);
293
294  vorbis_bitrate_init(vi,&b->bms);
295
296  /* compressed audio packets start after the headers
297     with sequence number 3 */
298  v->sequence=3;
299
300  return(0);
301}
302
303void vorbis_dsp_clear(vorbis_dsp_state *v){
304  int i;
305  if(v){
306    vorbis_info *vi=v->vi;
307    codec_setup_info *ci=(vi?vi->codec_setup:NULL);
308    private_state *b=v->backend_state;
309
310    if(b){
311       
312      if(b->ve){
313        _ve_envelope_clear(b->ve);
314        _ogg_free(b->ve);
315      }
316
317      if(b->transform[0]){
318        mdct_clear(b->transform[0][0]);
319        _ogg_free(b->transform[0][0]);
320        _ogg_free(b->transform[0]);
321      }
322      if(b->transform[1]){
323        mdct_clear(b->transform[1][0]);
324        _ogg_free(b->transform[1][0]);
325        _ogg_free(b->transform[1]);
326      }
327
328      if(b->flr){
329        if(ci)
330          for(i=0;i<ci->floors;i++)
331            _floor_P[ci->floor_type[i]]->
332              free_look(b->flr[i]);
333        _ogg_free(b->flr);
334      }
335      if(b->residue){
336        if(ci)
337          for(i=0;i<ci->residues;i++)
338            _residue_P[ci->residue_type[i]]->
339              free_look(b->residue[i]);
340        _ogg_free(b->residue);
341      }
342      if(b->psy){
343        if(ci)
344          for(i=0;i<ci->psys;i++)
345            _vp_psy_clear(b->psy+i);
346        _ogg_free(b->psy);
347      }
348
349      if(b->psy_g_look)_vp_global_free(b->psy_g_look);
350      vorbis_bitrate_clear(&b->bms);
351
352      drft_clear(&b->fft_look[0]);
353      drft_clear(&b->fft_look[1]);
354
355    }
356   
357    if(v->pcm){
358      if(vi)
359        for(i=0;i<vi->channels;i++)
360          if(v->pcm[i])_ogg_free(v->pcm[i]);
361      _ogg_free(v->pcm);
362      if(v->pcmret)_ogg_free(v->pcmret);
363    }
364
365    if(b){
366      /* free header, header1, header2 */
367      if(b->header)_ogg_free(b->header);
368      if(b->header1)_ogg_free(b->header1);
369      if(b->header2)_ogg_free(b->header2);
370      _ogg_free(b);
371    }
372   
373    memset(v,0,sizeof(*v));
374  }
375}
376
377float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
378  int i;
379  vorbis_info *vi=v->vi;
380  private_state *b=v->backend_state;
381
382  /* free header, header1, header2 */
383  if(b->header)_ogg_free(b->header);b->header=NULL;
384  if(b->header1)_ogg_free(b->header1);b->header1=NULL;
385  if(b->header2)_ogg_free(b->header2);b->header2=NULL;
386
387  /* Do we have enough storage space for the requested buffer? If not,
388     expand the PCM (and envelope) storage */
389   
390  if(v->pcm_current+vals>=v->pcm_storage){
391    v->pcm_storage=v->pcm_current+vals*2;
392   
393    for(i=0;i<vi->channels;i++){
394      v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
395    }
396  }
397
398  for(i=0;i<vi->channels;i++)
399    v->pcmret[i]=v->pcm[i]+v->pcm_current;
400   
401  return(v->pcmret);
402}
403
404static void _preextrapolate_helper(vorbis_dsp_state *v){
405  int i;
406  int order=32;
407  float *lpc=alloca(order*sizeof(*lpc));
408  float *work=alloca(v->pcm_current*sizeof(*work));
409  long j;
410  v->preextrapolate=1;
411
412  if(v->pcm_current-v->centerW>order*2){ /* safety */
413    for(i=0;i<v->vi->channels;i++){
414      /* need to run the extrapolation in reverse! */
415      for(j=0;j<v->pcm_current;j++)
416        work[j]=v->pcm[i][v->pcm_current-j-1];
417     
418      /* prime as above */
419      vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
420     
421      /* run the predictor filter */
422      vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
423                         order,
424                         work+v->pcm_current-v->centerW,
425                         v->centerW);
426
427      for(j=0;j<v->pcm_current;j++)
428        v->pcm[i][v->pcm_current-j-1]=work[j];
429
430    }
431  }
432}
433
434
435/* call with val<=0 to set eof */
436
437int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
438  vorbis_info *vi=v->vi;
439  codec_setup_info *ci=vi->codec_setup;
440
441  if(vals<=0){
442    int order=32;
443    int i;
444    float *lpc=alloca(order*sizeof(*lpc));
445
446    /* if it wasn't done earlier (very short sample) */
447    if(!v->preextrapolate)
448      _preextrapolate_helper(v);
449
450    /* We're encoding the end of the stream.  Just make sure we have
451       [at least] a few full blocks of zeroes at the end. */
452    /* actually, we don't want zeroes; that could drop a large
453       amplitude off a cliff, creating spread spectrum noise that will
454       suck to encode.  Extrapolate for the sake of cleanliness. */
455
456    vorbis_analysis_buffer(v,ci->blocksizes[1]*3); 
457    v->eofflag=v->pcm_current;
458    v->pcm_current+=ci->blocksizes[1]*3;
459
460    for(i=0;i<vi->channels;i++){
461      if(v->eofflag>order*2){
462        /* extrapolate with LPC to fill in */
463        long n;
464
465        /* make a predictor filter */
466        n=v->eofflag;
467        if(n>ci->blocksizes[1])n=ci->blocksizes[1];
468        vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
469
470        /* run the predictor filter */
471        vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
472                           v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
473      }else{
474        /* not enough data to extrapolate (unlikely to happen due to
475           guarding the overlap, but bulletproof in case that
476           assumtion goes away). zeroes will do. */
477        memset(v->pcm[i]+v->eofflag,0,
478               (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
479
480      }
481    }
482  }else{
483
484    if(v->pcm_current+vals>v->pcm_storage)
485      return(OV_EINVAL);
486
487    v->pcm_current+=vals;
488
489    /* we may want to reverse extrapolate the beginning of a stream
490       too... in case we're beginning on a cliff! */
491    /* clumsy, but simple.  It only runs once, so simple is good. */
492    if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
493      _preextrapolate_helper(v);
494
495  }
496  return(0);
497}
498
499/* do the deltas, envelope shaping, pre-echo and determine the size of
500   the next block on which to continue analysis */
501int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
502  int i;
503  vorbis_info *vi=v->vi;
504  codec_setup_info *ci=vi->codec_setup;
505  private_state *b=v->backend_state;
506  vorbis_look_psy_global *g=b->psy_g_look;
507  long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
508  vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
509
510  /* check to see if we're started... */
511  if(!v->preextrapolate)return(0);
512
513  /* check to see if we're done... */
514  if(v->eofflag==-1)return(0);
515
516  /* By our invariant, we have lW, W and centerW set.  Search for
517     the next boundary so we can determine nW (the next window size)
518     which lets us compute the shape of the current block's window */
519
520  /* we do an envelope search even on a single blocksize; we may still
521     be throwing more bits at impulses, and envelope search handles
522     marking impulses too. */
523  { 
524    long bp=_ve_envelope_search(v);
525    if(bp==-1){
526
527      if(v->eofflag==0)return(0); /* not enough data currently to search for a
528                                     full long block */
529      v->nW=0;
530    }else{
531
532      if(ci->blocksizes[0]==ci->blocksizes[1])
533        v->nW=0;
534      else
535        v->nW=bp;
536    }
537  }
538
539  centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
540
541  {
542    /* center of next block + next block maximum right side. */
543
544    long blockbound=centerNext+ci->blocksizes[v->nW]/2;
545    if(v->pcm_current<blockbound)return(0); /* not enough data yet;
546                                               although this check is
547                                               less strict that the
548                                               _ve_envelope_search,
549                                               the search is not run
550                                               if we only use one
551                                               block size */
552
553
554  }
555 
556  /* fill in the block.  Note that for a short window, lW and nW are *short*
557     regardless of actual settings in the stream */
558
559  _vorbis_block_ripcord(vb);
560  vb->lW=v->lW;
561  vb->W=v->W;
562  vb->nW=v->nW;
563
564  if(v->W){
565    if(!v->lW || !v->nW){
566      vbi->blocktype=BLOCKTYPE_TRANSITION;
567      /*fprintf(stderr,"-");*/
568    }else{
569      vbi->blocktype=BLOCKTYPE_LONG;
570      /*fprintf(stderr,"_");*/
571    }
572  }else{
573    if(_ve_envelope_mark(v)){
574      vbi->blocktype=BLOCKTYPE_IMPULSE;
575      /*fprintf(stderr,"|");*/
576
577    }else{
578      vbi->blocktype=BLOCKTYPE_PADDING;
579      /*fprintf(stderr,".");*/
580
581    }
582  }
583 
584  vb->vd=v;
585  vb->sequence=v->sequence++;
586  vb->granulepos=v->granulepos;
587  vb->pcmend=ci->blocksizes[v->W];
588 
589  /* copy the vectors; this uses the local storage in vb */
590
591  /* this tracks 'strongest peak' for later psychoacoustics */
592  /* moved to the global psy state; clean this mess up */
593  if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
594  g->ampmax=_vp_ampmax_decay(g->ampmax,v);
595  vbi->ampmax=g->ampmax;
596 
597  vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
598  vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
599  for(i=0;i<vi->channels;i++){
600    vbi->pcmdelay[i]=
601      _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
602    memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
603    vb->pcm[i]=vbi->pcmdelay[i]+beginW;
604   
605    /* before we added the delay
606       vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
607       memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
608    */
609   
610  }
611 
612  /* handle eof detection: eof==0 means that we've not yet received EOF
613                           eof>0  marks the last 'real' sample in pcm[]
614                           eof<0  'no more to do'; doesn't get here */
615
616  if(v->eofflag){
617    if(v->centerW>=v->eofflag){
618      v->eofflag=-1;
619      vb->eofflag=1;
620      return(1);
621    }
622  }
623
624  /* advance storage vectors and clean up */
625  {
626    int new_centerNext=ci->blocksizes[1]/2;
627    int movementW=centerNext-new_centerNext;
628
629    if(movementW>0){
630
631      _ve_envelope_shift(b->ve,movementW);
632      v->pcm_current-=movementW;
633     
634      for(i=0;i<vi->channels;i++)
635        memmove(v->pcm[i],v->pcm[i]+movementW,
636                v->pcm_current*sizeof(*v->pcm[i]));
637     
638     
639      v->lW=v->W;
640      v->W=v->nW;
641      v->centerW=new_centerNext;
642     
643      if(v->eofflag){
644        v->eofflag-=movementW;
645        if(v->eofflag<=0)v->eofflag=-1;
646        /* do not add padding to end of stream! */
647        if(v->centerW>=v->eofflag){
648          v->granulepos+=movementW-(v->centerW-v->eofflag);
649        }else{
650          v->granulepos+=movementW;
651        }
652      }else{
653        v->granulepos+=movementW;
654      }
655    }
656  }
657
658  /* done */
659  return(1);
660}
661
662int vorbis_synthesis_restart(vorbis_dsp_state *v){
663  vorbis_info *vi=v->vi;
664  codec_setup_info *ci;
665  int hs;
666
667  if(!v->backend_state)return -1;
668  if(!vi)return -1;
669  ci=vi->codec_setup;
670  if(!ci)return -1;
671  hs=ci->halfrate_flag; 
672
673  v->centerW=ci->blocksizes[1]>>(hs+1);
674  v->pcm_current=v->centerW>>hs;
675 
676  v->pcm_returned=-1;
677  v->granulepos=-1;
678  v->sequence=-1;
679  v->eofflag=0;
680  ((private_state *)(v->backend_state))->sample_count=-1;
681
682  return(0);
683}
684
685int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
686  if(_vds_shared_init(v,vi,0)) return 1;
687  vorbis_synthesis_restart(v);
688
689  return 0;
690}
691
692/* Unlike in analysis, the window is only partially applied for each
693   block.  The time domain envelope is not yet handled at the point of
694   calling (as it relies on the previous block). */
695
696int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
697  vorbis_info *vi=v->vi;
698  codec_setup_info *ci=vi->codec_setup;
699  private_state *b=v->backend_state;
700  int hs=ci->halfrate_flag; 
701  int i,j;
702
703  if(!vb)return(OV_EINVAL);
704  if(v->pcm_current>v->pcm_returned  && v->pcm_returned!=-1)return(OV_EINVAL);
705   
706  v->lW=v->W;
707  v->W=vb->W;
708  v->nW=-1;
709 
710  if((v->sequence==-1)||
711     (v->sequence+1 != vb->sequence)){
712    v->granulepos=-1; /* out of sequence; lose count */
713    b->sample_count=-1;
714  }
715
716  v->sequence=vb->sequence;
717 
718  if(vb->pcm){  /* no pcm to process if vorbis_synthesis_trackonly
719                   was called on block */
720    int n=ci->blocksizes[v->W]>>(hs+1);
721    int n0=ci->blocksizes[0]>>(hs+1);
722    int n1=ci->blocksizes[1]>>(hs+1);
723
724    int thisCenter;
725    int prevCenter;
726   
727    v->glue_bits+=vb->glue_bits;
728    v->time_bits+=vb->time_bits;
729    v->floor_bits+=vb->floor_bits;
730    v->res_bits+=vb->res_bits;
731   
732    if(v->centerW){
733      thisCenter=n1;
734      prevCenter=0;
735    }else{
736      thisCenter=0;
737      prevCenter=n1;
738    }
739   
740    /* v->pcm is now used like a two-stage double buffer.  We don't want
741       to have to constantly shift *or* adjust memory usage.  Don't
742       accept a new block until the old is shifted out */
743   
744    for(j=0;j<vi->channels;j++){
745      /* the overlap/add section */
746      if(v->lW){
747        if(v->W){
748          /* large/large */
749          float *w=_vorbis_window_get(b->window[1]-hs);
750          float *pcm=v->pcm[j]+prevCenter;
751          float *p=vb->pcm[j];
752          for(i=0;i<n1;i++)
753            pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
754        }else{
755          /* large/small */
756          float *w=_vorbis_window_get(b->window[0]-hs);
757          float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
758          float *p=vb->pcm[j];
759          for(i=0;i<n0;i++)
760            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
761        }
762      }else{
763        if(v->W){
764          /* small/large */
765          float *w=_vorbis_window_get(b->window[0]-hs);
766          float *pcm=v->pcm[j]+prevCenter;
767          float *p=vb->pcm[j]+n1/2-n0/2;
768          for(i=0;i<n0;i++)
769            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
770          for(;i<n1/2+n0/2;i++)
771            pcm[i]=p[i];
772        }else{
773          /* small/small */
774          float *w=_vorbis_window_get(b->window[0]-hs);
775          float *pcm=v->pcm[j]+prevCenter;
776          float *p=vb->pcm[j];
777          for(i=0;i<n0;i++)
778            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
779        }
780      }
781     
782      /* the copy section */
783      {
784        float *pcm=v->pcm[j]+thisCenter;
785        float *p=vb->pcm[j]+n;
786        for(i=0;i<n;i++)
787          pcm[i]=p[i];
788      }
789    }
790   
791    if(v->centerW)
792      v->centerW=0;
793    else
794      v->centerW=n1;
795   
796    /* deal with initial packet state; we do this using the explicit
797       pcm_returned==-1 flag otherwise we're sensitive to first block
798       being short or long */
799   
800    if(v->pcm_returned==-1){
801      v->pcm_returned=thisCenter;
802      v->pcm_current=thisCenter;
803    }else{
804      v->pcm_returned=prevCenter;
805      v->pcm_current=prevCenter+
806        ((ci->blocksizes[v->lW]/4+
807        ci->blocksizes[v->W]/4)>>hs);
808    }
809   
810  }
811
812  /* track the frame number... This is for convenience, but also
813     making sure our last packet doesn't end with added padding.  If
814     the last packet is partial, the number of samples we'll have to
815     return will be past the vb->granulepos.
816     
817     This is not foolproof!  It will be confused if we begin
818     decoding at the last page after a seek or hole.  In that case,
819     we don't have a starting point to judge where the last frame
820     is.  For this reason, vorbisfile will always try to make sure
821     it reads the last two marked pages in proper sequence */
822
823  if(b->sample_count==-1){
824    b->sample_count=0;
825  }else{
826    b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
827  }
828 
829  if(v->granulepos==-1){
830    if(vb->granulepos!=-1){ /* only set if we have a position to set to */
831
832      v->granulepos=vb->granulepos;
833
834      /* is this a short page? */
835      if(b->sample_count>v->granulepos){
836        /* corner case; if this is both the first and last audio page,
837           then spec says the end is cut, not beginning */
838        if(vb->eofflag){
839          /* trim the end */
840          /* no preceeding granulepos; assume we started at zero (we'd
841             have to in a short single-page stream) */
842          /* granulepos could be -1 due to a seek, but that would result
843             in a long count, not short count */
844         
845          v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
846        }else{
847          /* trim the beginning */
848          v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
849          if(v->pcm_returned>v->pcm_current)
850            v->pcm_returned=v->pcm_current;
851        }
852
853      }
854
855    }
856  }else{
857    v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
858    if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
859     
860      if(v->granulepos>vb->granulepos){
861        long extra=v->granulepos-vb->granulepos;
862
863        if(extra)
864          if(vb->eofflag){
865            /* partial last frame.  Strip the extra samples off */
866            v->pcm_current-=extra>>hs;
867          } /* else {Shouldn't happen *unless* the bitstream is out of
868               spec.  Either way, believe the bitstream } */
869      } /* else {Shouldn't happen *unless* the bitstream is out of
870           spec.  Either way, believe the bitstream } */
871      v->granulepos=vb->granulepos;
872    }
873  }
874 
875  /* Update, cleanup */
876 
877  if(vb->eofflag)v->eofflag=1;
878  return(0);
879 
880}
881
882/* pcm==NULL indicates we just want the pending samples, no more */
883int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
884  vorbis_info *vi=v->vi;
885
886  if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
887    if(pcm){
888      int i;
889      for(i=0;i<vi->channels;i++)
890        v->pcmret[i]=v->pcm[i]+v->pcm_returned;
891      *pcm=v->pcmret;
892    }
893    return(v->pcm_current-v->pcm_returned);
894  }
895  return(0);
896}
897
898int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
899  if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
900  v->pcm_returned+=n;
901  return(0);
902}
903
904/* intended for use with a specific vorbisfile feature; we want access
905   to the [usually synthetic/postextrapolated] buffer and lapping at
906   the end of a decode cycle, specifically, a half-short-block worth.
907   This funtion works like pcmout above, except it will also expose
908   this implicit buffer data not normally decoded. */
909int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
910  vorbis_info *vi=v->vi;
911  codec_setup_info *ci=vi->codec_setup;
912  int hs=ci->halfrate_flag; 
913 
914  int n=ci->blocksizes[v->W]>>(hs+1);
915  int n0=ci->blocksizes[0]>>(hs+1);
916  int n1=ci->blocksizes[1]>>(hs+1);
917  int i,j;
918
919  if(v->pcm_returned<0)return 0;
920
921  /* our returned data ends at pcm_returned; because the synthesis pcm
922     buffer is a two-fragment ring, that means our data block may be
923     fragmented by buffering, wrapping or a short block not filling
924     out a buffer.  To simplify things, we unfragment if it's at all
925     possibly needed. Otherwise, we'd need to call lapout more than
926     once as well as hold additional dsp state.  Opt for
927     simplicity. */
928
929  /* centerW was advanced by blockin; it would be the center of the
930     *next* block */
931  if(v->centerW==n1){
932    /* the data buffer wraps; swap the halves */
933    /* slow, sure, small */
934    for(j=0;j<vi->channels;j++){
935      float *p=v->pcm[j];
936      for(i=0;i<n1;i++){
937        float temp=p[i];
938        p[i]=p[i+n1];
939        p[i+n1]=temp;
940      }
941    }
942
943    v->pcm_current-=n1;
944    v->pcm_returned-=n1;
945    v->centerW=0;
946  }
947 
948  /* solidify buffer into contiguous space */
949  if((v->lW^v->W)==1){
950    /* long/short or short/long */
951    for(j=0;j<vi->channels;j++){
952      float *s=v->pcm[j];
953      float *d=v->pcm[j]+(n1-n0)/2;
954      for(i=(n1+n0)/2-1;i>=0;--i)
955        d[i]=s[i];
956    }
957    v->pcm_returned+=(n1-n0)/2;
958    v->pcm_current+=(n1-n0)/2;
959  }else{
960    if(v->lW==0){
961      /* short/short */
962      for(j=0;j<vi->channels;j++){
963        float *s=v->pcm[j];
964        float *d=v->pcm[j]+n1-n0;
965        for(i=n0-1;i>=0;--i)
966          d[i]=s[i];
967      }
968      v->pcm_returned+=n1-n0;
969      v->pcm_current+=n1-n0;
970    }
971  }
972   
973  if(pcm){
974    int i;
975    for(i=0;i<vi->channels;i++)
976      v->pcmret[i]=v->pcm[i]+v->pcm_returned;
977    *pcm=v->pcmret;
978  }
979
980  return(n1+n-v->pcm_returned);
981
982}
983
984float *vorbis_window(vorbis_dsp_state *v,int W){
985  vorbis_info *vi=v->vi;
986  codec_setup_info *ci=vi->codec_setup;
987  int hs=ci->halfrate_flag; 
988  private_state *b=v->backend_state;
989
990  if(b->window[W]-1<0)return NULL;
991  return _vorbis_window_get(b->window[W]-hs);
992}
993       
Note: See TracBrowser for help on using the repository browser.