Coverage Report

Created: 2025-12-14 06:33

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