block.c 28.6 KB
Newer Older
Mike Whitson's avatar
Mike Whitson committed
1 2
/********************************************************************
 *                                                                  *
Monty's avatar
 
Monty committed
3
 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
Monty's avatar
 
Monty committed
4 5 6
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
Mike Whitson's avatar
Mike Whitson committed
7
 *                                                                  *
8 9
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
10
 *                                                                  *
Mike Whitson's avatar
Mike Whitson committed
11 12 13
 ********************************************************************

 function: PCM data vector blocking, windowing and dis/reassembly
14
 last mod: $Id$
Mike Whitson's avatar
Mike Whitson committed
15

Monty's avatar
 
Monty committed
16
 Handle windowing, overlap-add, etc of the PCM vectors.  This is made
Monty's avatar
 
Monty committed
17
 more amusing by Vorbis' current two allowed block sizes.
Mike Whitson's avatar
Mike Whitson committed
18 19 20
 
 ********************************************************************/

Monty's avatar
 
Monty committed
21
#include <stdio.h>
Mike Whitson's avatar
Mike Whitson committed
22
#include <stdlib.h>
Monty's avatar
 
Monty committed
23
#include <string.h>
Monty's avatar
 
Monty committed
24
#include <ogg/ogg.h>
Monty's avatar
 
Monty committed
25
#include "vorbis/codec.h"
Monty's avatar
 
Monty committed
26
#include "codec_internal.h"
Monty's avatar
 
Monty committed
27

Monty's avatar
 
Monty committed
28
#include "window.h"
Monty's avatar
 
Monty committed
29
#include "mdct.h"
Monty's avatar
 
Monty committed
30
#include "lpc.h"
Monty's avatar
 
Monty committed
31
#include "registry.h"
Monty's avatar
 
Monty committed
32
#include "misc.h"
Mike Whitson's avatar
Mike Whitson committed
33

Monty's avatar
 
Monty committed
34 35
static int ilog2(unsigned int v){
  int ret=0;
Monty's avatar
 
Monty committed
36 37
  if(v)--v;
  while(v){
Monty's avatar
 
Monty committed
38 39 40 41 42 43
    ret++;
    v>>=1;
  }
  return(ret);
}

Monty's avatar
 
Monty committed
44
/* pcm accumulator examples (not exhaustive):
Mike Whitson's avatar
Mike Whitson committed
45

Monty's avatar
 
Monty committed
46
 <-------------- lW ---------------->
Mike Whitson's avatar
Mike Whitson committed
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
                   <--------------- W ---------------->
:            .....|.....       _______________         |
:        .'''     |     '''_---      |       |\        |
:.....'''         |_____--- '''......|       | \_______|
:.................|__________________|_______|__|______|
                  |<------ Sl ------>|      > Sr <     |endW
                  |beginSl           |endSl  |  |endSr   
                  |beginW            |endlW  |beginSr


                      |< lW >|       
                   <--------------- W ---------------->
                  |   |  ..  ______________            |
                  |   | '  `/        |     ---_        |
                  |___.'___/`.       |         ---_____| 
                  |_______|__|_______|_________________|
                  |      >|Sl|<      |<------ Sr ----->|endW
                  |       |  |endSl  |beginSr          |endSr
                  |beginW |  |endlW                     
                  mult[0] |beginSl                     mult[n]

Monty's avatar
 
Monty committed
68 69 70 71 72 73 74 75 76 77
 <-------------- lW ----------------->
                          |<--W-->|                               
:            ..............  ___  |   |                    
:        .'''             |`/   \ |   |                       
:.....'''                 |/`....\|...|                    
:.........................|___|___|___|                  
                          |Sl |Sr |endW    
                          |   |   |endSr
                          |   |beginSr
                          |   |endSl
78 79
                          |beginSl
                          |beginW
Mike Whitson's avatar
Mike Whitson committed
80 81
*/

Monty's avatar
 
Monty committed
82 83
/* block abstraction setup *********************************************/

Monty's avatar
 
Monty committed
84 85 86 87
#ifndef WORD_ALIGN
#define WORD_ALIGN 8
#endif

Monty's avatar
 
Monty committed
88
int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
Monty's avatar
 
Monty committed
89
  int i;
90
  memset(vb,0,sizeof(*vb));
Monty's avatar
 
Monty committed
91
  vb->vd=v;
Monty's avatar
 
Monty committed
92 93
  vb->localalloc=0;
  vb->localstore=NULL;
94
  if(v->analysisp>0){
Monty's avatar
 
Monty committed
95 96 97
    vorbis_block_internal *vbi=
      vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
    vbi->ampmax=-9999;
Monty's avatar
 
Monty committed
98 99 100

    for(i=0;i<PACKETBLOBS;i++){
      if(i==PACKETBLOBS/2){
101
        vbi->packetblob[i]=&vb->opb;
Monty's avatar
 
Monty committed
102
      }else{
103 104
        vbi->packetblob[i]=
          _ogg_calloc(1,sizeof(oggpack_buffer));
Monty's avatar
 
Monty committed
105 106 107
      }
      oggpack_writeinit(vbi->packetblob[i]);
    }    
Monty's avatar
 
Monty committed
108
  }
109

Monty's avatar
 
Monty committed
110 111 112
  return(0);
}

Monty's avatar
 
Monty committed
113 114 115
void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
  bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
  if(bytes+vb->localtop>vb->localalloc){
Monty's avatar
 
Monty committed
116
    /* can't just _ogg_realloc... there are outstanding pointers */
Monty's avatar
 
Monty committed
117
    if(vb->localstore){
118
      struct alloc_chain *link=_ogg_malloc(sizeof(*link));
Monty's avatar
 
Monty committed
119 120 121 122 123 124 125
      vb->totaluse+=vb->localtop;
      link->next=vb->reap;
      link->ptr=vb->localstore;
      vb->reap=link;
    }
    /* highly conservative */
    vb->localalloc=bytes;
Monty's avatar
 
Monty committed
126
    vb->localstore=_ogg_malloc(vb->localalloc);
Monty's avatar
 
Monty committed
127
    vb->localtop=0;
Monty's avatar
 
Monty committed
128
  }
Monty's avatar
 
Monty committed
129
  {
Monty's avatar
 
Monty committed
130
    void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
Monty's avatar
 
Monty committed
131 132 133
    vb->localtop+=bytes;
    return ret;
  }
Monty's avatar
 
Monty committed
134 135
}

Monty's avatar
 
Monty committed
136
/* reap the chain, pull the ripcord */
Monty's avatar
 
Monty committed
137
void _vorbis_block_ripcord(vorbis_block *vb){
Monty's avatar
 
Monty committed
138 139 140 141
  /* reap the chain */
  struct alloc_chain *reap=vb->reap;
  while(reap){
    struct alloc_chain *next=reap->next;
Monty's avatar
 
Monty committed
142
    _ogg_free(reap->ptr);
143
    memset(reap,0,sizeof(*reap));
Monty's avatar
 
Monty committed
144
    _ogg_free(reap);
Monty's avatar
 
Monty committed
145 146 147 148
    reap=next;
  }
  /* consolidate storage */
  if(vb->totaluse){
Monty's avatar
 
Monty committed
149
    vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
Monty's avatar
 
Monty committed
150 151 152 153 154
    vb->localalloc+=vb->totaluse;
    vb->totaluse=0;
  }

  /* pull the ripcord */
Monty's avatar
 
Monty committed
155
  vb->localtop=0;
Monty's avatar
 
Monty committed
156
  vb->reap=NULL;
Monty's avatar
 
Monty committed
157 158 159
}

int vorbis_block_clear(vorbis_block *vb){
Monty's avatar
 
Monty committed
160 161 162
  int i;
  vorbis_block_internal *vbi=vb->internal;

Monty's avatar
 
Monty committed
163
  _vorbis_block_ripcord(vb);
Monty's avatar
 
Monty committed
164
  if(vb->localstore)_ogg_free(vb->localstore);
Monty's avatar
 
Monty committed
165

Monty's avatar
 
Monty committed
166 167 168 169 170 171 172
  if(vbi){
    for(i=0;i<PACKETBLOBS;i++){
      oggpack_writeclear(vbi->packetblob[i]);
      if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
    }
    _ogg_free(vbi);
  }
173
  memset(vb,0,sizeof(*vb));
Monty's avatar
 
Monty committed
174 175 176 177 178 179 180
  return(0);
}

/* Analysis side code, but directly related to blocking.  Thus it's
   here and not in analysis.c (which is for analysis transforms only).
   The init is here because some of it is shared */

Monty's avatar
 
Monty committed
181
static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
Monty's avatar
 
Monty committed
182
  int i;
Monty's avatar
 
Monty committed
183
  codec_setup_info *ci=vi->codec_setup;
Monty's avatar
 
Monty committed
184
  private_state *b=NULL;
Monty's avatar
 
Monty committed
185 186 187 188
  int hs;

  if(ci==NULL) return 1;
  hs=ci->halfrate_flag; 
Monty's avatar
 
Monty committed
189

190 191
  memset(v,0,sizeof(*v));
  b=v->backend_state=_ogg_calloc(1,sizeof(*b));
Monty's avatar
 
Monty committed
192

Monty's avatar
 
Monty committed
193
  v->vi=vi;
Monty's avatar
 
Monty committed
194
  b->modebits=ilog2(ci->modes);
Monty's avatar
 
Monty committed
195

196 197
  b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
  b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
Monty's avatar
 
Monty committed
198

Monty's avatar
 
Monty committed
199 200
  /* MDCT is tranform 0 */

Monty's avatar
 
Monty committed
201 202
  b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
  b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
Monty's avatar
 
Monty committed
203 204
  mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
  mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
Monty's avatar
 
Monty committed
205

Monty's avatar
 
Monty committed
206
  /* Vorbis I uses only window type 0 */
Monty's avatar
 
Monty committed
207 208
  b->window[0]=ilog2(ci->blocksizes[0])-6;
  b->window[1]=ilog2(ci->blocksizes[1])-6;
Monty's avatar
 
Monty committed
209

Monty's avatar
 
Monty committed
210
  if(encp){ /* encode/decode differ here */
Monty's avatar
 
Monty committed
211 212 213 214 215

    /* analysis always needs an fft */
    drft_init(&b->fft_look[0],ci->blocksizes[0]);
    drft_init(&b->fft_look[1],ci->blocksizes[1]);

Monty's avatar
 
Monty committed
216
    /* finish the codebooks */
Monty's avatar
 
Monty committed
217 218 219
    if(!ci->fullbooks){
      ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
      for(i=0;i<ci->books;i++)
220
        vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
Monty's avatar
 
Monty committed
221
    }
Monty's avatar
 
Monty committed
222 223 224 225

    b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy));
    for(i=0;i<ci->psys;i++){
      _vp_psy_init(b->psy+i,
226 227 228 229
                   ci->psy_param[i],
                   &ci->psy_g_param,
                   ci->blocksizes[ci->psy_param[i]->blockflag]/2,
                   vi->rate);
Monty's avatar
 
Monty committed
230 231
    }

Monty's avatar
 
Monty committed
232 233 234
    v->analysisp=1;
  }else{
    /* finish the codebooks */
Monty's avatar
 
Monty committed
235 236 237
    if(!ci->fullbooks){
      ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
      for(i=0;i<ci->books;i++){
238 239 240 241 242
        if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
          return -1;
        /* decode codebooks are now standalone after init */
        vorbis_staticbook_destroy(ci->book_param[i]);
        ci->book_param[i]=NULL;
Monty's avatar
 
Monty committed
243
      }
Monty's avatar
 
Monty committed
244
    }
Monty's avatar
 
Monty committed
245 246
  }

Monty's avatar
 
Monty committed
247 248 249
  /* initialize the storage vectors. blocksize[1] is small for encode,
     but the correct size for decode */
  v->pcm_storage=ci->blocksizes[1];
250 251
  v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
  v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
Mike Whitson's avatar
Mike Whitson committed
252 253
  {
    int i;
Monty's avatar
 
Monty committed
254
    for(i=0;i<vi->channels;i++)
255
      v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
Mike Whitson's avatar
Mike Whitson committed
256 257 258
  }

  /* all 1 (large block) or 0 (small block) */
Monty's avatar
 
Monty committed
259 260 261
  /* explicitly set for the sake of clarity */
  v->lW=0; /* previous window size */
  v->W=0;  /* current window size */
Mike Whitson's avatar
Mike Whitson committed
262

Monty's avatar
 
Monty committed
263
  /* all vector indexes */
Monty's avatar
 
Monty committed
264
  v->centerW=ci->blocksizes[1]/2;
Mike Whitson's avatar
Mike Whitson committed
265

Monty's avatar
 
Monty committed
266
  v->pcm_current=v->centerW;
Monty's avatar
 
Monty committed
267

Monty's avatar
 
Monty committed
268 269 270 271 272 273 274 275 276 277 278
  /* initialize all the backend lookups */
  b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
  b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));

  for(i=0;i<ci->floors;i++)
    b->flr[i]=_floor_P[ci->floor_type[i]]->
      look(v,ci->floor_param[i]);

  for(i=0;i<ci->residues;i++)
    b->residue[i]=_residue_P[ci->residue_type[i]]->
      look(v,ci->residue_param[i]);    
Monty's avatar
 
Monty committed
279

Monty's avatar
 
Monty committed
280
  return 0;
Mike Whitson's avatar
Mike Whitson committed
281 282
}

Monty's avatar
 
Monty committed
283 284
/* arbitrary settings and spec-mandated numbers get filled in here */
int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
Monty's avatar
 
Monty committed
285
  private_state *b=NULL;
Monty's avatar
 
Monty committed
286

Monty's avatar
 
Monty committed
287
  if(_vds_shared_init(v,vi,1))return 1;
Monty's avatar
 
Monty committed
288
  b=v->backend_state;
Monty's avatar
 
Monty committed
289
  b->psy_g_look=_vp_global_look(vi);
Monty's avatar
 
Monty committed
290

Monty's avatar
 
Monty committed
291
  /* Initialize the envelope state storage */
292
  b->ve=_ogg_calloc(1,sizeof(*b->ve));
Monty's avatar
 
Monty committed
293
  _ve_envelope_init(b->ve,vi);
Monty's avatar
 
Monty committed
294 295 296

  vorbis_bitrate_init(vi,&b->bms);

297 298 299 300
  /* compressed audio packets start after the headers
     with sequence number 3 */
  v->sequence=3;

Monty's avatar
 
Monty committed
301 302 303
  return(0);
}

Monty's avatar
 
Monty committed
304
void vorbis_dsp_clear(vorbis_dsp_state *v){
Monty's avatar
 
Monty committed
305
  int i;
Mike Whitson's avatar
Mike Whitson committed
306
  if(v){
Monty's avatar
 
Monty committed
307
    vorbis_info *vi=v->vi;
Monty's avatar
 
Monty committed
308
    codec_setup_info *ci=(vi?vi->codec_setup:NULL);
Monty's avatar
 
Monty committed
309
    private_state *b=v->backend_state;
Monty's avatar
 
Monty committed
310 311

    if(b){
312
        
Monty's avatar
 
Monty committed
313
      if(b->ve){
314 315
        _ve_envelope_clear(b->ve);
        _ogg_free(b->ve);
Monty's avatar
 
Monty committed
316 317 318
      }

      if(b->transform[0]){
319 320 321
        mdct_clear(b->transform[0][0]);
        _ogg_free(b->transform[0][0]);
        _ogg_free(b->transform[0]);
Monty's avatar
 
Monty committed
322 323
      }
      if(b->transform[1]){
324 325 326
        mdct_clear(b->transform[1][0]);
        _ogg_free(b->transform[1][0]);
        _ogg_free(b->transform[1]);
Monty's avatar
 
Monty committed
327
      }
Monty's avatar
 
Monty committed
328 329

      if(b->flr){
330 331 332 333 334
        if(ci)
          for(i=0;i<ci->floors;i++)
            _floor_P[ci->floor_type[i]]->
              free_look(b->flr[i]);
        _ogg_free(b->flr);
Monty's avatar
 
Monty committed
335 336
      }
      if(b->residue){
337 338 339 340 341
        if(ci)
          for(i=0;i<ci->residues;i++)
            _residue_P[ci->residue_type[i]]->
              free_look(b->residue[i]);
        _ogg_free(b->residue);
Monty's avatar
 
Monty committed
342 343
      }
      if(b->psy){
344 345 346 347
        if(ci)
          for(i=0;i<ci->psys;i++)
            _vp_psy_clear(b->psy+i);
        _ogg_free(b->psy);
Monty's avatar
 
Monty committed
348 349
      }

Monty's avatar
 
Monty committed
350
      if(b->psy_g_look)_vp_global_free(b->psy_g_look);
Monty's avatar
 
Monty committed
351
      vorbis_bitrate_clear(&b->bms);
Monty's avatar
 
Monty committed
352 353 354 355

      drft_clear(&b->fft_look[0]);
      drft_clear(&b->fft_look[1]);

Monty's avatar
 
Monty committed
356 357
    }
    
Mike Whitson's avatar
Mike Whitson committed
358
    if(v->pcm){
359
      if(vi)
360 361
        for(i=0;i<vi->channels;i++)
          if(v->pcm[i])_ogg_free(v->pcm[i]);
Monty's avatar
 
Monty committed
362 363
      _ogg_free(v->pcm);
      if(v->pcmret)_ogg_free(v->pcmret);
Mike Whitson's avatar
Mike Whitson committed
364
    }
Monty's avatar
 
Monty committed
365

Monty's avatar
 
Monty committed
366 367
    if(b){
      /* free header, header1, header2 */
Monty's avatar
 
Monty committed
368 369 370 371
      if(b->header)_ogg_free(b->header);
      if(b->header1)_ogg_free(b->header1);
      if(b->header2)_ogg_free(b->header2);
      _ogg_free(b);
Monty's avatar
 
Monty committed
372 373
    }
    
374
    memset(v,0,sizeof(*v));
Mike Whitson's avatar
Mike Whitson committed
375 376 377
  }
}

Monty's avatar
 
Monty committed
378
float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
Mike Whitson's avatar
Mike Whitson committed
379
  int i;
Monty's avatar
 
Monty committed
380
  vorbis_info *vi=v->vi;
Monty's avatar
 
Monty committed
381
  private_state *b=v->backend_state;
Mike Whitson's avatar
Mike Whitson committed
382

Monty's avatar
 
Monty committed
383
  /* free header, header1, header2 */
Monty's avatar
 
Monty committed
384 385 386
  if(b->header)_ogg_free(b->header);b->header=NULL;
  if(b->header1)_ogg_free(b->header1);b->header1=NULL;
  if(b->header2)_ogg_free(b->header2);b->header2=NULL;
Monty's avatar
 
Monty committed
387

Monty's avatar
 
Monty committed
388 389 390 391 392 393
  /* Do we have enough storage space for the requested buffer? If not,
     expand the PCM (and envelope) storage */
    
  if(v->pcm_current+vals>=v->pcm_storage){
    v->pcm_storage=v->pcm_current+vals*2;
   
Monty's avatar
 
Monty committed
394
    for(i=0;i<vi->channels;i++){
395
      v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
Monty's avatar
 
Monty committed
396
    }
Monty's avatar
 
Monty committed
397
  }
Mike Whitson's avatar
Mike Whitson committed
398

Monty's avatar
 
Monty committed
399
  for(i=0;i<vi->channels;i++)
Monty's avatar
 
Monty committed
400 401 402 403
    v->pcmret[i]=v->pcm[i]+v->pcm_current;
    
  return(v->pcmret);
}
Mike Whitson's avatar
Mike Whitson committed
404

Monty's avatar
 
Monty committed
405
static void _preextrapolate_helper(vorbis_dsp_state *v){
Monty's avatar
 
Monty committed
406
  int i;
Monty's avatar
Monty committed
407
  int order=16;
408 409
  float *lpc=alloca(order*sizeof(*lpc));
  float *work=alloca(v->pcm_current*sizeof(*work));
Monty's avatar
 
Monty committed
410
  long j;
Monty's avatar
 
Monty committed
411
  v->preextrapolate=1;
Monty's avatar
 
Monty committed
412 413 414

  if(v->pcm_current-v->centerW>order*2){ /* safety */
    for(i=0;i<v->vi->channels;i++){
Monty's avatar
 
Monty committed
415
      /* need to run the extrapolation in reverse! */
Monty's avatar
 
Monty committed
416
      for(j=0;j<v->pcm_current;j++)
417
        work[j]=v->pcm[i][v->pcm_current-j-1];
Monty's avatar
 
Monty committed
418 419 420
      
      /* prime as above */
      vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
Monty's avatar
Monty committed
421 422 423

#if 0
      if(v->vi->channels==2){
424 425 426 427
        if(i==0)
          _analysis_output("predataL",0,work,v->pcm_current-v->centerW,0,0,0);
        else
          _analysis_output("predataR",0,work,v->pcm_current-v->centerW,0,0,0);
Monty's avatar
Monty committed
428
      }else{
429
        _analysis_output("predata",0,work,v->pcm_current-v->centerW,0,0,0);
Monty's avatar
Monty committed
430 431 432
      }
#endif 
 
Monty's avatar
 
Monty committed
433 434
      /* run the predictor filter */
      vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
435 436 437
                         order,
                         work+v->pcm_current-v->centerW,
                         v->centerW);
Monty's avatar
 
Monty committed
438

Monty's avatar
 
Monty committed
439
      for(j=0;j<v->pcm_current;j++)
440
        v->pcm[i][v->pcm_current-j-1]=work[j];
Monty's avatar
 
Monty committed
441

Monty's avatar
 
Monty committed
442 443 444 445 446
    }
  }
}


Monty's avatar
 
Monty committed
447 448
/* call with val<=0 to set eof */

Monty's avatar
 
Monty committed
449
int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
Monty's avatar
 
Monty committed
450
  vorbis_info *vi=v->vi;
Monty's avatar
 
Monty committed
451 452
  codec_setup_info *ci=vi->codec_setup;

Monty's avatar
 
Monty committed
453
  if(vals<=0){
Monty's avatar
 
Monty committed
454 455
    int order=32;
    int i;
456
    float *lpc=alloca(order*sizeof(*lpc));
Monty's avatar
 
Monty committed
457 458

    /* if it wasn't done earlier (very short sample) */
Monty's avatar
 
Monty committed
459 460
    if(!v->preextrapolate)
      _preextrapolate_helper(v);
Monty's avatar
 
Monty committed
461

Monty's avatar
 
Monty committed
462
    /* We're encoding the end of the stream.  Just make sure we have
Monty's avatar
 
Monty committed
463
       [at least] a few full blocks of zeroes at the end. */
Monty's avatar
 
Monty committed
464 465 466
    /* actually, we don't want zeroes; that could drop a large
       amplitude off a cliff, creating spread spectrum noise that will
       suck to encode.  Extrapolate for the sake of cleanliness. */
Monty's avatar
 
Monty committed
467

Monty's avatar
 
Monty committed
468
    vorbis_analysis_buffer(v,ci->blocksizes[1]*3); 
Monty's avatar
 
Monty committed
469
    v->eofflag=v->pcm_current;
Monty's avatar
 
Monty committed
470
    v->pcm_current+=ci->blocksizes[1]*3;
Monty's avatar
 
Monty committed
471 472 473

    for(i=0;i<vi->channels;i++){
      if(v->eofflag>order*2){
474 475
        /* extrapolate with LPC to fill in */
        long n;
Monty's avatar
 
Monty committed
476

477 478 479 480
        /* make a predictor filter */
        n=v->eofflag;
        if(n>ci->blocksizes[1])n=ci->blocksizes[1];
        vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
Monty's avatar
 
Monty committed
481

482 483 484
        /* run the predictor filter */
        vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
                           v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
Monty's avatar
 
Monty committed
485
      }else{
486
        /* not enough data to extrapolate (unlikely to happen due to
Monty's avatar
 
Monty committed
487 488
           guarding the overlap, but bulletproof in case that
           assumtion goes away). zeroes will do. */
489 490
        memset(v->pcm[i]+v->eofflag,0,
               (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
Monty's avatar
 
Monty committed
491 492 493

      }
    }
Monty's avatar
 
Monty committed
494
  }else{
Monty's avatar
 
Monty committed
495

Monty's avatar
 
Monty committed
496
    if(v->pcm_current+vals>v->pcm_storage)
Monty's avatar
 
Monty committed
497
      return(OV_EINVAL);
Mike Whitson's avatar
Mike Whitson committed
498

Monty's avatar
 
Monty committed
499
    v->pcm_current+=vals;
Monty's avatar
 
Monty committed
500

Monty's avatar
 
Monty committed
501
    /* we may want to reverse extrapolate the beginning of a stream
Monty's avatar
 
Monty committed
502 503
       too... in case we're beginning on a cliff! */
    /* clumsy, but simple.  It only runs once, so simple is good. */
Monty's avatar
 
Monty committed
504
    if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
Monty's avatar
 
Monty committed
505
      _preextrapolate_helper(v);
Monty's avatar
 
Monty committed
506

Monty's avatar
 
Monty committed
507
  }
Monty's avatar
 
Monty committed
508 509
  return(0);
}
Mike Whitson's avatar
Mike Whitson committed
510

Monty's avatar
 
Monty committed
511 512
/* do the deltas, envelope shaping, pre-echo and determine the size of
   the next block on which to continue analysis */
Monty's avatar
 
Monty committed
513
int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
Monty's avatar
 
Monty committed
514
  int i;
Monty's avatar
 
Monty committed
515
  vorbis_info *vi=v->vi;
Monty's avatar
 
Monty committed
516
  codec_setup_info *ci=vi->codec_setup;
Monty's avatar
 
Monty committed
517
  private_state *b=v->backend_state;
Monty's avatar
 
Monty committed
518
  vorbis_look_psy_global *g=b->psy_g_look;
Monty's avatar
 
Monty committed
519
  long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
Monty's avatar
 
Monty committed
520
  vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
Mike Whitson's avatar
Mike Whitson committed
521

Monty's avatar
 
Monty committed
522
  /* check to see if we're started... */
Monty's avatar
 
Monty committed
523
  if(!v->preextrapolate)return(0);
Monty's avatar
 
Monty committed
524

Monty's avatar
 
Monty committed
525 526
  /* check to see if we're done... */
  if(v->eofflag==-1)return(0);
Mike Whitson's avatar
Mike Whitson committed
527

Monty's avatar
 
Monty committed
528 529 530
  /* By our invariant, we have lW, W and centerW set.  Search for
     the next boundary so we can determine nW (the next window size)
     which lets us compute the shape of the current block's window */
Monty's avatar
 
Monty committed
531 532 533 534 535

  /* we do an envelope search even on a single blocksize; we may still
     be throwing more bits at impulses, and envelope search handles
     marking impulses too. */
  {  
Monty's avatar
 
Monty committed
536
    long bp=_ve_envelope_search(v);
Monty's avatar
 
Monty committed
537
    if(bp==-1){
Monty's avatar
 
Monty committed
538

Monty's avatar
 
Monty committed
539
      if(v->eofflag==0)return(0); /* not enough data currently to search for a
540
                                     full long block */
Monty's avatar
 
Monty committed
541 542
      v->nW=0;
    }else{
Monty's avatar
 
Monty committed
543 544

      if(ci->blocksizes[0]==ci->blocksizes[1])
545
        v->nW=0;
Monty's avatar
 
Monty committed
546
      else
547
        v->nW=bp;
Monty's avatar
 
Monty committed
548
    }
Monty's avatar
 
Monty committed
549
  }
Monty's avatar
 
Monty committed
550

Monty's avatar
 
Monty committed
551
  centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
Monty's avatar
 
Monty committed
552

Monty's avatar
 
Monty committed
553
  {
Monty's avatar
 
Monty committed
554
    /* center of next block + next block maximum right side. */
Monty's avatar
 
Monty committed
555

Monty's avatar
 
Monty committed
556
    long blockbound=centerNext+ci->blocksizes[v->nW]/2;
Monty's avatar
 
Monty committed
557 558 559 560 561 562 563
    if(v->pcm_current<blockbound)return(0); /* not enough data yet;
                                               although this check is
                                               less strict that the
                                               _ve_envelope_search,
                                               the search is not run
                                               if we only use one
                                               block size */
Monty's avatar
 
Monty committed
564 565


Monty's avatar
 
Monty committed
566
  }
Monty's avatar
 
Monty committed
567 568 569
  
  /* fill in the block.  Note that for a short window, lW and nW are *short*
     regardless of actual settings in the stream */
Monty's avatar
 
Monty committed
570

Monty's avatar
 
Monty committed
571
  _vorbis_block_ripcord(vb);
Monty's avatar
 
Monty committed
572 573 574
  vb->lW=v->lW;
  vb->W=v->W;
  vb->nW=v->nW;
Monty's avatar
 
Monty committed
575 576

  if(v->W){
Monty's avatar
 
Monty committed
577
    if(!v->lW || !v->nW){
Monty's avatar
 
Monty committed
578
      vbi->blocktype=BLOCKTYPE_TRANSITION;
Monty's avatar
 
Monty committed
579
      /*fprintf(stderr,"-");*/
Monty's avatar
 
Monty committed
580
    }else{
Monty's avatar
 
Monty committed
581
      vbi->blocktype=BLOCKTYPE_LONG;
Monty's avatar
 
Monty committed
582
      /*fprintf(stderr,"_");*/
Monty's avatar
 
Monty committed
583
    }
Monty's avatar
 
Monty committed
584
  }else{
Monty's avatar
 
Monty committed
585
    if(_ve_envelope_mark(v)){
Monty's avatar
 
Monty committed
586
      vbi->blocktype=BLOCKTYPE_IMPULSE;
Monty's avatar
 
Monty committed
587
      /*fprintf(stderr,"|");*/
Monty's avatar
 
Monty committed
588 589

    }else{
Monty's avatar
 
Monty committed
590
      vbi->blocktype=BLOCKTYPE_PADDING;
Monty's avatar
 
Monty committed
591
      /*fprintf(stderr,".");*/
Monty's avatar
 
Monty committed
592 593

    }
Monty's avatar
 
Monty committed
594 595
  }
 
Monty's avatar
 
Monty committed
596
  vb->vd=v;
Monty's avatar
 
Monty committed
597
  vb->sequence=v->sequence++;
Monty's avatar
 
Monty committed
598
  vb->granulepos=v->granulepos;
Monty's avatar
 
Monty committed
599
  vb->pcmend=ci->blocksizes[v->W];
Monty's avatar
 
Monty committed
600
  
Monty's avatar
 
Monty committed
601
  /* copy the vectors; this uses the local storage in vb */
Monty's avatar
 
Monty committed
602

Monty's avatar
 
Monty committed
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
  /* this tracks 'strongest peak' for later psychoacoustics */
  /* moved to the global psy state; clean this mess up */
  if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
  g->ampmax=_vp_ampmax_decay(g->ampmax,v);
  vbi->ampmax=g->ampmax;
  
  vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
  vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
  for(i=0;i<vi->channels;i++){
    vbi->pcmdelay[i]=
      _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
    memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
    vb->pcm[i]=vbi->pcmdelay[i]+beginW;
    
    /* before we added the delay 
       vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
       memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
    */
    
Monty's avatar
 
Monty committed
622
  }
Monty's avatar
 
Monty committed
623
  
Monty's avatar
 
Monty committed
624 625 626 627 628
  /* handle eof detection: eof==0 means that we've not yet received EOF
                           eof>0  marks the last 'real' sample in pcm[]
                           eof<0  'no more to do'; doesn't get here */

  if(v->eofflag){
Monty's avatar
 
Monty committed
629
    if(v->centerW>=v->eofflag){
Monty's avatar
 
Monty committed
630 631
      v->eofflag=-1;
      vb->eofflag=1;
Monty's avatar
 
Monty committed
632
      return(1);
Monty's avatar
 
Monty committed
633 634
    }
  }
Mike Whitson's avatar
Mike Whitson committed
635 636 637

  /* advance storage vectors and clean up */
  {
Monty's avatar
 
Monty committed
638
    int new_centerNext=ci->blocksizes[1]/2;
Monty's avatar
 
Monty committed
639
    int movementW=centerNext-new_centerNext;
Monty's avatar
 
Monty committed
640

Monty's avatar
 
Monty committed
641
    if(movementW>0){
Monty's avatar
 
Monty committed
642

Monty's avatar
 
Monty committed
643 644 645 646
      _ve_envelope_shift(b->ve,movementW);
      v->pcm_current-=movementW;
      
      for(i=0;i<vi->channels;i++)
647 648
        memmove(v->pcm[i],v->pcm[i]+movementW,
                v->pcm_current*sizeof(*v->pcm[i]));
Monty's avatar
 
Monty committed
649 650 651 652 653 654 655
      
      
      v->lW=v->W;
      v->W=v->nW;
      v->centerW=new_centerNext;
      
      if(v->eofflag){
656 657 658 659 660 661 662 663
        v->eofflag-=movementW;
        if(v->eofflag<=0)v->eofflag=-1;
        /* do not add padding to end of stream! */
        if(v->centerW>=v->eofflag){
          v->granulepos+=movementW-(v->centerW-v->eofflag);
        }else{
          v->granulepos+=movementW;
        }
Monty's avatar
 
Monty committed
664
      }else{
665
        v->granulepos+=movementW;
Monty's avatar
 
Monty committed
666
      }
Monty's avatar
 
Monty committed
667
    }
Mike Whitson's avatar
Mike Whitson committed
668 669 670 671 672
  }

  /* done */
  return(1);
}
Monty's avatar
 
Monty committed
673

Monty's avatar
 
Monty committed
674 675 676
int vorbis_synthesis_restart(vorbis_dsp_state *v){
  vorbis_info *vi=v->vi;
  codec_setup_info *ci;
Monty's avatar
 
Monty committed
677
  int hs;
Monty's avatar
 
Monty committed
678 679 680 681 682

  if(!v->backend_state)return -1;
  if(!vi)return -1;
  ci=vi->codec_setup;
  if(!ci)return -1;
Monty's avatar
 
Monty committed
683
  hs=ci->halfrate_flag; 
Monty's avatar
 
Monty committed
684

Monty's avatar
 
Monty committed
685 686
  v->centerW=ci->blocksizes[1]>>(hs+1);
  v->pcm_current=v->centerW>>hs;
Monty's avatar
 
Monty committed
687
  
Monty's avatar
 
Monty committed
688
  v->pcm_returned=-1;
Monty's avatar
 
Monty committed
689
  v->granulepos=-1;
Monty's avatar
 
Monty committed
690
  v->sequence=-1;
Monty's avatar
 
Monty committed
691
  v->eofflag=0;
Monty's avatar
 
Monty committed
692
  ((private_state *)(v->backend_state))->sample_count=-1;
Monty's avatar
 
Monty committed
693

Monty's avatar
 
Monty committed
694 695
  return(0);
}
Monty's avatar
 
Monty committed
696

Monty's avatar
 
Monty committed
697
int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
698 699 700 701
  if(_vds_shared_init(v,vi,0)){
    vorbis_dsp_clear(v);
    return 1;
  }
Monty's avatar
 
Monty committed
702
  vorbis_synthesis_restart(v);
Monty's avatar
 
Monty committed
703
  return 0;
Monty's avatar
 
Monty committed
704 705
}

Monty's avatar
 
Monty committed
706
/* Unlike in analysis, the window is only partially applied for each
Monty's avatar
 
Monty committed
707 708
   block.  The time domain envelope is not yet handled at the point of
   calling (as it relies on the previous block). */
Monty's avatar
 
Monty committed
709

Monty's avatar
 
Monty committed
710
int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
Monty's avatar
 
Monty committed
711
  vorbis_info *vi=v->vi;
Monty's avatar
 
Monty committed
712
  codec_setup_info *ci=vi->codec_setup;
Monty's avatar
 
Monty committed
713
  private_state *b=v->backend_state;
Monty's avatar
 
Monty committed
714
  int hs=ci->halfrate_flag; 
Monty's avatar
 
Monty committed
715
  int i,j;
Monty's avatar
 
Monty committed
716

Monty's avatar
 
Monty committed
717
  if(!vb)return(OV_EINVAL);
Monty's avatar
 
Monty committed
718
  if(v->pcm_current>v->pcm_returned  && v->pcm_returned!=-1)return(OV_EINVAL);
Monty's avatar
 
Monty committed
719
    
Monty's avatar
 
Monty committed
720 721
  v->lW=v->W;
  v->W=vb->W;
Monty's avatar
 
Monty committed
722
  v->nW=-1;
Monty's avatar
 
Monty committed
723
  
Monty's avatar
 
Monty committed
724 725 726 727 728 729
  if((v->sequence==-1)||
     (v->sequence+1 != vb->sequence)){
    v->granulepos=-1; /* out of sequence; lose count */
    b->sample_count=-1;
  }

Monty's avatar
 
Monty committed
730
  v->sequence=vb->sequence;
Monty's avatar
 
Monty committed
731
  
Monty's avatar
 
Monty committed
732
  if(vb->pcm){  /* no pcm to process if vorbis_synthesis_trackonly 
733
                   was called on block */
Monty's avatar
 
Monty committed
734 735 736 737
    int n=ci->blocksizes[v->W]>>(hs+1);
    int n0=ci->blocksizes[0]>>(hs+1);
    int n1=ci->blocksizes[1]>>(hs+1);

Monty's avatar
 
Monty committed
738 739 740
    int thisCenter;
    int prevCenter;
    
Monty's avatar
 
Monty committed
741 742 743 744 745
    v->glue_bits+=vb->glue_bits;
    v->time_bits+=vb->time_bits;
    v->floor_bits+=vb->floor_bits;
    v->res_bits+=vb->res_bits;
    
Monty's avatar
 
Monty committed
746 747 748 749
    if(v->centerW){
      thisCenter=n1;
      prevCenter=0;
    }else{
Monty's avatar
 
Monty committed
750 751
      thisCenter=0;
      prevCenter=n1;
Monty's avatar
 
Monty committed
752
    }
Monty's avatar
 
Monty committed
753 754 755 756 757
    
    /* v->pcm is now used like a two-stage double buffer.  We don't want
       to have to constantly shift *or* adjust memory usage.  Don't
       accept a new block until the old is shifted out */
    
Monty's avatar
 
Monty committed
758
    for(j=0;j<vi->channels;j++){
Monty's avatar
 
Monty committed
759
      /* the overlap/add section */
Monty's avatar
 
Monty committed
760
      if(v->lW){
761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
        if(v->W){
          /* large/large */
          float *w=_vorbis_window_get(b->window[1]-hs);
          float *pcm=v->pcm[j]+prevCenter;
          float *p=vb->pcm[j];
          for(i=0;i<n1;i++)
            pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
        }else{
          /* large/small */
          float *w=_vorbis_window_get(b->window[0]-hs);
          float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
          float *p=vb->pcm[j];
          for(i=0;i<n0;i++)
            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
        }
Monty's avatar
 
Monty committed
776
      }else{
777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
        if(v->W){
          /* small/large */
          float *w=_vorbis_window_get(b->window[0]-hs);
          float *pcm=v->pcm[j]+prevCenter;
          float *p=vb->pcm[j]+n1/2-n0/2;
          for(i=0;i<n0;i++)
            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
          for(;i<n1/2+n0/2;i++)
            pcm[i]=p[i];
        }else{
          /* small/small */
          float *w=_vorbis_window_get(b->window[0]-hs);
          float *pcm=v->pcm[j]+prevCenter;
          float *p=vb->pcm[j];
          for(i=0;i<n0;i++)
            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
        }
Monty's avatar
 
Monty committed
794 795 796 797
      }
      
      /* the copy section */
      {
798 799 800 801
        float *pcm=v->pcm[j]+thisCenter;
        float *p=vb->pcm[j]+n;
        for(i=0;i<n;i++)
          pcm[i]=p[i];
Monty's avatar
 
Monty committed
802
      }
Monty's avatar
 
Monty committed
803
    }
Monty's avatar
 
Monty committed
804 805 806 807 808 809
    
    if(v->centerW)
      v->centerW=0;
    else
      v->centerW=n1;
    
Monty's avatar
 
Monty committed
810 811 812
    /* deal with initial packet state; we do this using the explicit
       pcm_returned==-1 flag otherwise we're sensitive to first block
       being short or long */
Monty's avatar
 
Monty committed
813
    
Monty's avatar
 
Monty committed
814 815 816 817 818 819
    if(v->pcm_returned==-1){
      v->pcm_returned=thisCenter;
      v->pcm_current=thisCenter;
    }else{
      v->pcm_returned=prevCenter;
      v->pcm_current=prevCenter+
820 821
        ((ci->blocksizes[v->lW]/4+
        ci->blocksizes[v->W]/4)>>hs);
Monty's avatar
 
Monty committed
822
    }
Monty's avatar
 
Monty committed
823 824
    
  }
Monty's avatar
 
Monty committed
825

Monty's avatar
 
Monty committed
826 827 828 829 830 831 832 833 834 835
  /* track the frame number... This is for convenience, but also
     making sure our last packet doesn't end with added padding.  If
     the last packet is partial, the number of samples we'll have to
     return will be past the vb->granulepos.
     
     This is not foolproof!  It will be confused if we begin
     decoding at the last page after a seek or hole.  In that case,
     we don't have a starting point to judge where the last frame
     is.  For this reason, vorbisfile will always try to make sure
     it reads the last two marked pages in proper sequence */
Monty's avatar
 
Monty committed
836 837 838