Coverage Report

Created: 2025-08-09 06:29

/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.26M
#define WORD_ALIGN 8
75
#endif
76
77
10.2k
int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
78
10.2k
  int i;
79
10.2k
  memset(vb,0,sizeof(*vb));
80
10.2k
  vb->vd=v;
81
10.2k
  vb->localalloc=0;
82
10.2k
  vb->localstore=NULL;
83
10.2k
  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.2k
  return(0);
100
10.2k
}
101
102
3.13M
void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
103
3.13M
  bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
104
3.13M
  if(bytes+vb->localtop>vb->localalloc){
105
    /* can't just _ogg_realloc... there are outstanding pointers */
106
477k
    if(vb->localstore){
107
470k
      struct alloc_chain *link=_ogg_malloc(sizeof(*link));
108
470k
      vb->totaluse+=vb->localtop;
109
470k
      link->next=vb->reap;
110
470k
      link->ptr=vb->localstore;
111
470k
      vb->reap=link;
112
470k
    }
113
    /* highly conservative */
114
477k
    vb->localalloc=bytes;
115
477k
    vb->localstore=_ogg_malloc(vb->localalloc);
116
477k
    vb->localtop=0;
117
477k
  }
118
3.13M
  {
119
3.13M
    void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
120
3.13M
    vb->localtop+=bytes;
121
3.13M
    return ret;
122
3.13M
  }
123
3.13M
}
124
125
/* reap the chain, pull the ripcord */
126
2.98M
void _vorbis_block_ripcord(vorbis_block *vb){
127
  /* reap the chain */
128
2.98M
  struct alloc_chain *reap=vb->reap;
129
3.45M
  while(reap){
130
470k
    struct alloc_chain *next=reap->next;
131
470k
    _ogg_free(reap->ptr);
132
470k
    memset(reap,0,sizeof(*reap));
133
470k
    _ogg_free(reap);
134
470k
    reap=next;
135
470k
  }
136
  /* consolidate storage */
137
2.98M
  if(vb->totaluse){
138
8.10k
    vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
139
8.10k
    vb->localalloc+=vb->totaluse;
140
8.10k
    vb->totaluse=0;
141
8.10k
  }
142
143
  /* pull the ripcord */
144
2.98M
  vb->localtop=0;
145
2.98M
  vb->reap=NULL;
146
2.98M
}
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
33.7k
      for(i=0;i<ci->books;i++){
238
23.4k
        if(ci->book_param[i]==NULL)
239
0
          goto abort_books;
240
23.4k
        if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
241
137
          goto abort_books;
242
        /* decode codebooks are now standalone after init */
243
23.3k
        vorbis_staticbook_destroy(ci->book_param[i]);
244
23.3k
        ci->book_param[i]=NULL;
245
23.3k
      }
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.2k
  v->pcm_storage=ci->blocksizes[1];
252
10.2k
  v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
253
10.2k
  v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
254
10.2k
  {
255
10.2k
    int i;
256
770k
    for(i=0;i<vi->channels;i++)
257
760k
      v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
258
10.2k
  }
259
260
  /* all 1 (large block) or 0 (small block) */
261
  /* explicitly set for the sake of clarity */
262
10.2k
  v->lW=0; /* previous window size */
263
10.2k
  v->W=0;  /* current window size */
264
265
  /* all vector indexes */
266
10.2k
  v->centerW=ci->blocksizes[1]/2;
267
268
10.2k
  v->pcm_current=v->centerW;
269
270
  /* initialize all the backend lookups */
271
10.2k
  b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
272
10.2k
  b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
273
274
21.9k
  for(i=0;i<ci->floors;i++)
275
11.7k
    b->flr[i]=_floor_P[ci->floor_type[i]]->
276
11.7k
      look(v,ci->floor_param[i]);
277
278
23.4k
  for(i=0;i<ci->residues;i++)
279
13.1k
    b->residue[i]=_residue_P[ci->residue_type[i]]->
280
13.1k
      look(v,ci->residue_param[i]);
281
282
10.2k
  return 0;
283
137
 abort_books:
284
1.52k
  for(i=0;i<ci->books;i++){
285
1.38k
    if(ci->book_param[i]!=NULL){
286
792
      vorbis_staticbook_destroy(ci->book_param[i]);
287
792
      ci->book_param[i]=NULL;
288
792
    }
289
1.38k
  }
290
137
  vorbis_dsp_clear(v);
291
137
  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.2k
        if(ci)
342
21.9k
          for(i=0;i<ci->floors;i++)
343
11.7k
            _floor_P[ci->floor_type[i]]->
344
11.7k
              free_look(b->flr[i]);
345
10.2k
        _ogg_free(b->flr);
346
10.2k
      }
347
10.4k
      if(b->residue){
348
10.2k
        if(ci)
349
23.4k
          for(i=0;i<ci->residues;i++)
350
13.1k
            _residue_P[ci->residue_type[i]]->
351
13.1k
              free_look(b->residue[i]);
352
10.2k
        _ogg_free(b->residue);
353
10.2k
      }
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.2k
      if(vi)
371
770k
        for(i=0;i<vi->channels;i++)
372
760k
          if(v->pcm[i])_ogg_free(v->pcm[i]);
373
10.2k
      _ogg_free(v->pcm);
374
10.2k
      if(v->pcmret)_ogg_free(v->pcmret);
375
10.2k
    }
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.2k
int vorbis_synthesis_restart(vorbis_dsp_state *v){
695
10.2k
  vorbis_info *vi=v->vi;
696
10.2k
  codec_setup_info *ci;
697
10.2k
  int hs;
698
699
10.2k
  if(!v->backend_state)return -1;
700
10.2k
  if(!vi)return -1;
701
10.2k
  ci=vi->codec_setup;
702
10.2k
  if(!ci)return -1;
703
10.2k
  hs=ci->halfrate_flag;
704
705
10.2k
  v->centerW=ci->blocksizes[1]>>(hs+1);
706
10.2k
  v->pcm_current=v->centerW>>hs;
707
708
10.2k
  v->pcm_returned=-1;
709
10.2k
  v->granulepos=-1;
710
10.2k
  v->sequence=-1;
711
10.2k
  v->eofflag=0;
712
10.2k
  ((private_state *)(v->backend_state))->sample_count=-1;
713
714
10.2k
  return(0);
715
10.2k
}
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
137
    vorbis_dsp_clear(v);
720
137
    return 1;
721
137
  }
722
10.2k
  vorbis_synthesis_restart(v);
723
10.2k
  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
139k
int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
731
139k
  vorbis_info *vi=v->vi;
732
139k
  codec_setup_info *ci=vi->codec_setup;
733
139k
  private_state *b=v->backend_state;
734
139k
  int hs=ci->halfrate_flag;
735
139k
  int i,j;
736
737
139k
  if(!vb)return(OV_EINVAL);
738
139k
  if(v->pcm_current>v->pcm_returned  && v->pcm_returned!=-1)return(OV_EINVAL);
739
740
132k
  v->lW=v->W;
741
132k
  v->W=vb->W;
742
132k
  v->nW=-1;
743
744
132k
  if((v->sequence==-1)||
745
132k
     (v->sequence+1 != vb->sequence)){
746
110k
    v->granulepos=-1; /* out of sequence; lose count */
747
110k
    b->sample_count=-1;
748
110k
  }
749
750
132k
  v->sequence=vb->sequence;
751
752
132k
  if(vb->pcm){  /* no pcm to process if vorbis_synthesis_trackonly
753
                   was called on block */
754
132k
    int n=ci->blocksizes[v->W]>>(hs+1);
755
132k
    int n0=ci->blocksizes[0]>>(hs+1);
756
132k
    int n1=ci->blocksizes[1]>>(hs+1);
757
758
132k
    int thisCenter;
759
132k
    int prevCenter;
760
761
132k
    v->glue_bits+=vb->glue_bits;
762
132k
    v->time_bits+=vb->time_bits;
763
132k
    v->floor_bits+=vb->floor_bits;
764
132k
    v->res_bits+=vb->res_bits;
765
766
132k
    if(v->centerW){
767
67.6k
      thisCenter=n1;
768
67.6k
      prevCenter=0;
769
67.6k
    }else{
770
64.7k
      thisCenter=0;
771
64.7k
      prevCenter=n1;
772
64.7k
    }
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.27M
    for(j=0;j<vi->channels;j++){
779
      /* the overlap/add section */
780
2.14M
      if(v->lW){
781
685k
        if(v->W){
782
          /* large/large */
783
674k
          const float *w=_vorbis_window_get(b->window[1]-hs);
784
674k
          float *pcm=v->pcm[j]+prevCenter;
785
674k
          float *p=vb->pcm[j];
786
608M
          for(i=0;i<n1;i++)
787
607M
            pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
788
674k
        }else{
789
          /* large/small */
790
11.3k
          const float *w=_vorbis_window_get(b->window[0]-hs);
791
11.3k
          float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
792
11.3k
          float *p=vb->pcm[j];
793
2.84M
          for(i=0;i<n0;i++)
794
2.83M
            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
795
11.3k
        }
796
1.45M
      }else{
797
1.45M
        if(v->W){
798
          /* small/large */
799
207k
          const float *w=_vorbis_window_get(b->window[0]-hs);
800
207k
          float *pcm=v->pcm[j]+prevCenter;
801
207k
          float *p=vb->pcm[j]+n1/2-n0/2;
802
106M
          for(i=0;i<n0;i++)
803
106M
            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
804
89.4M
          for(;i<n1/2+n0/2;i++)
805
89.2M
            pcm[i]=p[i];
806
1.24M
        }else{
807
          /* small/small */
808
1.24M
          const float *w=_vorbis_window_get(b->window[0]-hs);
809
1.24M
          float *pcm=v->pcm[j]+prevCenter;
810
1.24M
          float *p=vb->pcm[j];
811
529M
          for(i=0;i<n0;i++)
812
528M
            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
813
1.24M
        }
814
1.45M
      }
815
816
      /* the copy section */
817
2.14M
      {
818
2.14M
        float *pcm=v->pcm[j]+thisCenter;
819
2.14M
        float *p=vb->pcm[j]+n;
820
1.42G
        for(i=0;i<n;i++)
821
1.42G
          pcm[i]=p[i];
822
2.14M
      }
823
2.14M
    }
824
825
132k
    if(v->centerW)
826
67.6k
      v->centerW=0;
827
64.7k
    else
828
64.7k
      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
132k
    if(v->pcm_returned==-1){
835
6.82k
      v->pcm_returned=thisCenter;
836
6.82k
      v->pcm_current=thisCenter;
837
125k
    }else{
838
125k
      v->pcm_returned=prevCenter;
839
125k
      v->pcm_current=prevCenter+
840
125k
        ((ci->blocksizes[v->lW]/4+
841
125k
        ci->blocksizes[v->W]/4)>>hs);
842
125k
    }
843
844
132k
  }
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
132k
  if(b->sample_count==-1){
858
110k
    b->sample_count=0;
859
110k
  }else{
860
21.8k
    b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
861
21.8k
  }
862
863
132k
  if(v->granulepos==-1){
864
129k
    if(vb->granulepos!=-1){ /* only set if we have a position to set to */
865
866
24.1k
      v->granulepos=vb->granulepos;
867
868
      /* is this a short page? */
869
24.1k
      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
8.46k
       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
8.46k
        if(extra<0)
879
219
          extra=0;
880
881
8.46k
        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.55k
          if(extra > (v->pcm_current - v->pcm_returned)<<hs)
892
3.25k
            extra = (v->pcm_current - v->pcm_returned)<<hs;
893
894
3.55k
          v->pcm_current-=extra>>hs;
895
4.91k
        }else{
896
          /* trim the beginning */
897
4.91k
          v->pcm_returned+=extra>>hs;
898
4.91k
          if(v->pcm_returned>v->pcm_current)
899
2.57k
            v->pcm_returned=v->pcm_current;
900
4.91k
        }
901
902
8.46k
      }
903
904
24.1k
    }
905
129k
  }else{
906
3.32k
    v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
907
3.32k
    if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
908
909
2.59k
      if(v->granulepos>vb->granulepos){
910
2.05k
        long extra=v->granulepos-vb->granulepos;
911
912
2.05k
        if(extra)
913
2.05k
          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.41k
            if(extra > (v->pcm_current - v->pcm_returned)<<hs)
920
508
              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.41k
            if(extra<0)
927
324
              extra=0;
928
929
1.41k
            v->pcm_current-=extra>>hs;
930
1.41k
          } /* else {Shouldn't happen *unless* the bitstream is out of
931
               spec.  Either way, believe the bitstream } */
932
2.05k
      } /* else {Shouldn't happen *unless* the bitstream is out of
933
           spec.  Either way, believe the bitstream } */
934
2.59k
      v->granulepos=vb->granulepos;
935
2.59k
    }
936
3.32k
  }
937
938
  /* Update, cleanup */
939
940
132k
  if(vb->eofflag)v->eofflag=1;
941
132k
  return(0);
942
943
139k
}
944
945
/* pcm==NULL indicates we just want the pending samples, no more */
946
1.01M
int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
947
1.01M
  vorbis_info *vi=v->vi;
948
949
1.01M
  if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
950
686k
    if(pcm){
951
550k
      int i;
952
73.4M
      for(i=0;i<vi->channels;i++)
953
72.8M
        v->pcmret[i]=v->pcm[i]+v->pcm_returned;
954
550k
      *pcm=v->pcmret;
955
550k
    }
956
686k
    return(v->pcm_current-v->pcm_returned);
957
686k
  }
958
330k
  return(0);
959
1.01M
}
960
961
550k
int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
962
550k
  if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
963
550k
  v->pcm_returned+=n;
964
550k
  return(0);
965
550k
}
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
}