Coverage Report

Created: 2025-09-04 06:19

/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
6.18M
#define WORD_ALIGN 8
75
#endif
76
77
10.3k
int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
78
10.3k
  int i;
79
10.3k
  memset(vb,0,sizeof(*vb));
80
10.3k
  vb->vd=v;
81
10.3k
  vb->localalloc=0;
82
10.3k
  vb->localstore=NULL;
83
10.3k
  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
10.3k
  return(0);
100
10.3k
}
101
102
3.09M
void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
103
3.09M
  bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
104
3.09M
  if(bytes+vb->localtop>vb->localalloc){
105
    /* can't just _ogg_realloc... there are outstanding pointers */
106
472k
    if(vb->localstore){
107
466k
      struct alloc_chain *link=_ogg_malloc(sizeof(*link));
108
466k
      vb->totaluse+=vb->localtop;
109
466k
      link->next=vb->reap;
110
466k
      link->ptr=vb->localstore;
111
466k
      vb->reap=link;
112
466k
    }
113
    /* highly conservative */
114
472k
    vb->localalloc=bytes;
115
472k
    vb->localstore=_ogg_malloc(vb->localalloc);
116
472k
    vb->localtop=0;
117
472k
  }
118
3.09M
  {
119
3.09M
    void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
120
3.09M
    vb->localtop+=bytes;
121
3.09M
    return ret;
122
3.09M
  }
123
3.09M
}
124
125
/* reap the chain, pull the ripcord */
126
1.56M
void _vorbis_block_ripcord(vorbis_block *vb){
127
  /* reap the chain */
128
1.56M
  struct alloc_chain *reap=vb->reap;
129
2.02M
  while(reap){
130
466k
    struct alloc_chain *next=reap->next;
131
466k
    _ogg_free(reap->ptr);
132
466k
    memset(reap,0,sizeof(*reap));
133
466k
    _ogg_free(reap);
134
466k
    reap=next;
135
466k
  }
136
  /* consolidate storage */
137
1.56M
  if(vb->totaluse){
138
7.46k
    vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
139
7.46k
    vb->localalloc+=vb->totaluse;
140
7.46k
    vb->totaluse=0;
141
7.46k
  }
142
143
  /* pull the ripcord */
144
1.56M
  vb->localtop=0;
145
1.56M
  vb->reap=NULL;
146
1.56M
}
147
148
13.0k
int vorbis_block_clear(vorbis_block *vb){
149
13.0k
  int i;
150
13.0k
  vorbis_block_internal *vbi=vb->internal;
151
152
13.0k
  _vorbis_block_ripcord(vb);
153
13.0k
  if(vb->localstore)_ogg_free(vb->localstore);
154
155
13.0k
  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
13.0k
  memset(vb,0,sizeof(*vb));
163
13.0k
  return(0);
164
13.0k
}
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
10.4k
static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
171
10.4k
  int i;
172
10.4k
  codec_setup_info *ci=vi->codec_setup;
173
10.4k
  private_state *b=NULL;
174
10.4k
  int hs;
175
176
10.4k
  if(ci==NULL||
177
10.4k
     ci->modes<=0||
178
10.4k
     ci->blocksizes[0]<64||
179
10.4k
     ci->blocksizes[1]<ci->blocksizes[0]){
180
0
    return 1;
181
0
  }
182
10.4k
  hs=ci->halfrate_flag;
183
184
10.4k
  memset(v,0,sizeof(*v));
185
10.4k
  b=v->backend_state=_ogg_calloc(1,sizeof(*b));
186
187
10.4k
  v->vi=vi;
188
10.4k
  b->modebits=ov_ilog(ci->modes-1);
189
190
10.4k
  b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
191
10.4k
  b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
192
193
  /* MDCT is tranform 0 */
194
195
10.4k
  b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
196
10.4k
  b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
197
10.4k
  mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
198
10.4k
  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
10.4k
  b->window[0]=ov_ilog(ci->blocksizes[0])-7;
208
10.4k
  b->window[1]=ov_ilog(ci->blocksizes[1])-7;
209
210
10.4k
  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
10.4k
  }else{
234
    /* finish the codebooks */
235
10.4k
    if(!ci->fullbooks){
236
10.4k
      ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
237
37.5k
      for(i=0;i<ci->books;i++){
238
27.1k
        if(ci->book_param[i]==NULL)
239
0
          goto abort_books;
240
27.1k
        if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
241
111
          goto abort_books;
242
        /* decode codebooks are now standalone after init */
243
27.0k
        vorbis_staticbook_destroy(ci->book_param[i]);
244
27.0k
        ci->book_param[i]=NULL;
245
27.0k
      }
246
10.4k
    }
247
10.4k
  }
248
249
  /* initialize the storage vectors. blocksize[1] is small for encode,
250
     but the correct size for decode */
251
10.3k
  v->pcm_storage=ci->blocksizes[1];
252
10.3k
  v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
253
10.3k
  v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
254
10.3k
  {
255
10.3k
    int i;
256
906k
    for(i=0;i<vi->channels;i++)
257
895k
      v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
258
10.3k
  }
259
260
  /* all 1 (large block) or 0 (small block) */
261
  /* explicitly set for the sake of clarity */
262
10.3k
  v->lW=0; /* previous window size */
263
10.3k
  v->W=0;  /* current window size */
264
265
  /* all vector indexes */
266
10.3k
  v->centerW=ci->blocksizes[1]/2;
267
268
10.3k
  v->pcm_current=v->centerW;
269
270
  /* initialize all the backend lookups */
271
10.3k
  b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
272
10.3k
  b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
273
274
23.1k
  for(i=0;i<ci->floors;i++)
275
12.7k
    b->flr[i]=_floor_P[ci->floor_type[i]]->
276
12.7k
      look(v,ci->floor_param[i]);
277
278
22.4k
  for(i=0;i<ci->residues;i++)
279
12.0k
    b->residue[i]=_residue_P[ci->residue_type[i]]->
280
12.0k
      look(v,ci->residue_param[i]);
281
282
10.3k
  return 0;
283
111
 abort_books:
284
1.69k
  for(i=0;i<ci->books;i++){
285
1.58k
    if(ci->book_param[i]!=NULL){
286
810
      vorbis_staticbook_destroy(ci->book_param[i]);
287
810
      ci->book_param[i]=NULL;
288
810
    }
289
1.58k
  }
290
111
  vorbis_dsp_clear(v);
291
111
  return -1;
292
10.4k
}
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
13.3k
void vorbis_dsp_clear(vorbis_dsp_state *v){
316
13.3k
  int i;
317
13.3k
  if(v){
318
13.3k
    vorbis_info *vi=v->vi;
319
13.3k
    codec_setup_info *ci=(vi?vi->codec_setup:NULL);
320
13.3k
    private_state *b=v->backend_state;
321
322
13.3k
    if(b){
323
324
10.4k
      if(b->ve){
325
0
        _ve_envelope_clear(b->ve);
326
0
        _ogg_free(b->ve);
327
0
      }
328
329
10.4k
      if(b->transform[0]){
330
10.4k
        mdct_clear(b->transform[0][0]);
331
10.4k
        _ogg_free(b->transform[0][0]);
332
10.4k
        _ogg_free(b->transform[0]);
333
10.4k
      }
334
10.4k
      if(b->transform[1]){
335
10.4k
        mdct_clear(b->transform[1][0]);
336
10.4k
        _ogg_free(b->transform[1][0]);
337
10.4k
        _ogg_free(b->transform[1]);
338
10.4k
      }
339
340
10.4k
      if(b->flr){
341
10.3k
        if(ci)
342
23.1k
          for(i=0;i<ci->floors;i++)
343
12.7k
            _floor_P[ci->floor_type[i]]->
344
12.7k
              free_look(b->flr[i]);
345
10.3k
        _ogg_free(b->flr);
346
10.3k
      }
347
10.4k
      if(b->residue){
348
10.3k
        if(ci)
349
22.4k
          for(i=0;i<ci->residues;i++)
350
12.0k
            _residue_P[ci->residue_type[i]]->
351
12.0k
              free_look(b->residue[i]);
352
10.3k
        _ogg_free(b->residue);
353
10.3k
      }
354
10.4k
      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
10.4k
      if(b->psy_g_look)_vp_global_free(b->psy_g_look);
362
10.4k
      vorbis_bitrate_clear(&b->bms);
363
364
10.4k
      drft_clear(&b->fft_look[0]);
365
10.4k
      drft_clear(&b->fft_look[1]);
366
367
10.4k
    }
368
369
13.3k
    if(v->pcm){
370
10.3k
      if(vi)
371
906k
        for(i=0;i<vi->channels;i++)
372
895k
          if(v->pcm[i])_ogg_free(v->pcm[i]);
373
10.3k
      _ogg_free(v->pcm);
374
10.3k
      if(v->pcmret)_ogg_free(v->pcmret);
375
10.3k
    }
376
377
13.3k
    if(b){
378
      /* free header, header1, header2 */
379
10.4k
      if(b->header)_ogg_free(b->header);
380
10.4k
      if(b->header1)_ogg_free(b->header1);
381
10.4k
      if(b->header2)_ogg_free(b->header2);
382
10.4k
      _ogg_free(b);
383
10.4k
    }
384
385
13.3k
    memset(v,0,sizeof(*v));
386
13.3k
  }
387
13.3k
}
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
10.3k
int vorbis_synthesis_restart(vorbis_dsp_state *v){
695
10.3k
  vorbis_info *vi=v->vi;
696
10.3k
  codec_setup_info *ci;
697
10.3k
  int hs;
698
699
10.3k
  if(!v->backend_state)return -1;
700
10.3k
  if(!vi)return -1;
701
10.3k
  ci=vi->codec_setup;
702
10.3k
  if(!ci)return -1;
703
10.3k
  hs=ci->halfrate_flag;
704
705
10.3k
  v->centerW=ci->blocksizes[1]>>(hs+1);
706
10.3k
  v->pcm_current=v->centerW>>hs;
707
708
10.3k
  v->pcm_returned=-1;
709
10.3k
  v->granulepos=-1;
710
10.3k
  v->sequence=-1;
711
10.3k
  v->eofflag=0;
712
10.3k
  ((private_state *)(v->backend_state))->sample_count=-1;
713
714
10.3k
  return(0);
715
10.3k
}
716
717
10.4k
int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
718
10.4k
  if(_vds_shared_init(v,vi,0)){
719
111
    vorbis_dsp_clear(v);
720
111
    return 1;
721
111
  }
722
10.3k
  vorbis_synthesis_restart(v);
723
10.3k
  return 0;
724
10.4k
}
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
94.0k
int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
731
94.0k
  vorbis_info *vi=v->vi;
732
94.0k
  codec_setup_info *ci=vi->codec_setup;
733
94.0k
  private_state *b=v->backend_state;
734
94.0k
  int hs=ci->halfrate_flag;
735
94.0k
  int i,j;
736
737
94.0k
  if(!vb)return(OV_EINVAL);
738
94.0k
  if(v->pcm_current>v->pcm_returned  && v->pcm_returned!=-1)return(OV_EINVAL);
739
740
86.2k
  v->lW=v->W;
741
86.2k
  v->W=vb->W;
742
86.2k
  v->nW=-1;
743
744
86.2k
  if((v->sequence==-1)||
745
86.2k
     (v->sequence+1 != vb->sequence)){
746
63.8k
    v->granulepos=-1; /* out of sequence; lose count */
747
63.8k
    b->sample_count=-1;
748
63.8k
  }
749
750
86.2k
  v->sequence=vb->sequence;
751
752
86.2k
  if(vb->pcm){  /* no pcm to process if vorbis_synthesis_trackonly
753
                   was called on block */
754
86.2k
    int n=ci->blocksizes[v->W]>>(hs+1);
755
86.2k
    int n0=ci->blocksizes[0]>>(hs+1);
756
86.2k
    int n1=ci->blocksizes[1]>>(hs+1);
757
758
86.2k
    int thisCenter;
759
86.2k
    int prevCenter;
760
761
86.2k
    v->glue_bits+=vb->glue_bits;
762
86.2k
    v->time_bits+=vb->time_bits;
763
86.2k
    v->floor_bits+=vb->floor_bits;
764
86.2k
    v->res_bits+=vb->res_bits;
765
766
86.2k
    if(v->centerW){
767
44.5k
      thisCenter=n1;
768
44.5k
      prevCenter=0;
769
44.5k
    }else{
770
41.6k
      thisCenter=0;
771
41.6k
      prevCenter=n1;
772
41.6k
    }
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.33M
    for(j=0;j<vi->channels;j++){
779
      /* the overlap/add section */
780
2.25M
      if(v->lW){
781
870k
        if(v->W){
782
          /* large/large */
783
862k
          const float *w=_vorbis_window_get(b->window[1]-hs);
784
862k
          float *pcm=v->pcm[j]+prevCenter;
785
862k
          float *p=vb->pcm[j];
786
730M
          for(i=0;i<n1;i++)
787
730M
            pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
788
862k
        }else{
789
          /* large/small */
790
8.10k
          const float *w=_vorbis_window_get(b->window[0]-hs);
791
8.10k
          float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
792
8.10k
          float *p=vb->pcm[j];
793
2.49M
          for(i=0;i<n0;i++)
794
2.48M
            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
795
8.10k
        }
796
1.38M
      }else{
797
1.38M
        if(v->W){
798
          /* small/large */
799
172k
          const float *w=_vorbis_window_get(b->window[0]-hs);
800
172k
          float *pcm=v->pcm[j]+prevCenter;
801
172k
          float *p=vb->pcm[j]+n1/2-n0/2;
802
74.8M
          for(i=0;i<n0;i++)
803
74.6M
            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
804
77.8M
          for(;i<n1/2+n0/2;i++)
805
77.6M
            pcm[i]=p[i];
806
1.20M
        }else{
807
          /* small/small */
808
1.20M
          const float *w=_vorbis_window_get(b->window[0]-hs);
809
1.20M
          float *pcm=v->pcm[j]+prevCenter;
810
1.20M
          float *p=vb->pcm[j];
811
621M
          for(i=0;i<n0;i++)
812
620M
            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
813
1.20M
        }
814
1.38M
      }
815
816
      /* the copy section */
817
2.25M
      {
818
2.25M
        float *pcm=v->pcm[j]+thisCenter;
819
2.25M
        float *p=vb->pcm[j]+n;
820
1.58G
        for(i=0;i<n;i++)
821
1.58G
          pcm[i]=p[i];
822
2.25M
      }
823
2.25M
    }
824
825
86.2k
    if(v->centerW)
826
44.5k
      v->centerW=0;
827
41.6k
    else
828
41.6k
      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
86.2k
    if(v->pcm_returned==-1){
835
6.53k
      v->pcm_returned=thisCenter;
836
6.53k
      v->pcm_current=thisCenter;
837
79.6k
    }else{
838
79.6k
      v->pcm_returned=prevCenter;
839
79.6k
      v->pcm_current=prevCenter+
840
79.6k
        ((ci->blocksizes[v->lW]/4+
841
79.6k
        ci->blocksizes[v->W]/4)>>hs);
842
79.6k
    }
843
844
86.2k
  }
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
86.2k
  if(b->sample_count==-1){
858
63.8k
    b->sample_count=0;
859
63.8k
  }else{
860
22.3k
    b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
861
22.3k
  }
862
863
86.2k
  if(v->granulepos==-1){
864
83.4k
    if(vb->granulepos!=-1){ /* only set if we have a position to set to */
865
866
17.5k
      v->granulepos=vb->granulepos;
867
868
      /* is this a short page? */
869
17.5k
      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
7.14k
       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
7.14k
        if(extra<0)
879
198
          extra=0;
880
881
7.14k
        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
3.80k
          if(extra > (v->pcm_current - v->pcm_returned)<<hs)
892
3.47k
            extra = (v->pcm_current - v->pcm_returned)<<hs;
893
894
3.80k
          v->pcm_current-=extra>>hs;
895
3.80k
        }else{
896
          /* trim the beginning */
897
3.34k
          v->pcm_returned+=extra>>hs;
898
3.34k
          if(v->pcm_returned>v->pcm_current)
899
1.45k
            v->pcm_returned=v->pcm_current;
900
3.34k
        }
901
902
7.14k
      }
903
904
17.5k
    }
905
83.4k
  }else{
906
2.76k
    v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
907
2.76k
    if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
908
909
2.26k
      if(v->granulepos>vb->granulepos){
910
2.01k
        long extra=v->granulepos-vb->granulepos;
911
912
2.01k
        if(extra)
913
2.01k
          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
1.15k
            if(extra > (v->pcm_current - v->pcm_returned)<<hs)
920
372
              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
1.15k
            if(extra<0)
927
349
              extra=0;
928
929
1.15k
            v->pcm_current-=extra>>hs;
930
1.15k
          } /* else {Shouldn't happen *unless* the bitstream is out of
931
               spec.  Either way, believe the bitstream } */
932
2.01k
      } /* else {Shouldn't happen *unless* the bitstream is out of
933
           spec.  Either way, believe the bitstream } */
934
2.26k
      v->granulepos=vb->granulepos;
935
2.26k
    }
936
2.76k
  }
937
938
  /* Update, cleanup */
939
940
86.2k
  if(vb->eofflag)v->eofflag=1;
941
86.2k
  return(0);
942
943
94.0k
}
944
945
/* pcm==NULL indicates we just want the pending samples, no more */
946
832k
int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
947
832k
  vorbis_info *vi=v->vi;
948
949
832k
  if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
950
601k
    if(pcm){
951
517k
      int i;
952
76.7M
      for(i=0;i<vi->channels;i++)
953
76.2M
        v->pcmret[i]=v->pcm[i]+v->pcm_returned;
954
517k
      *pcm=v->pcmret;
955
517k
    }
956
601k
    return(v->pcm_current-v->pcm_returned);
957
601k
  }
958
231k
  return(0);
959
832k
}
960
961
517k
int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
962
517k
  if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
963
517k
  v->pcm_returned+=n;
964
517k
  return(0);
965
517k
}
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
}