Coverage Report

Created: 2026-04-01 07:42

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