Coverage Report

Created: 2024-07-27 06:05

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