Coverage Report

Created: 2026-10-28 08:13

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