Coverage Report

Created: 2024-09-06 07:53

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