Coverage Report

Created: 2026-08-31 06:57

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