block.c 23.2 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
 *                                                                  *
Monty's avatar
 
Monty committed
8 9
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
 * by the XIPHOPHORUS Company http://www.xiph.org/                  *
Monty's avatar
 
Monty committed
10

Mike Whitson's avatar
Mike Whitson committed
11 12 13
 ********************************************************************

 function: PCM data vector blocking, windowing and dis/reassembly
Monty's avatar
 
Monty committed
14
 last mod: $Id: block.c,v 1.48 2001/05/27 06:43:59 xiphmont Exp $
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 29
#include "window.h"
#include "envelope.h"
Monty's avatar
 
Monty committed
30
#include "mdct.h"
Monty's avatar
 
Monty committed
31
#include "lpc.h"
Monty's avatar
 
Monty committed
32
#include "registry.h"
Monty's avatar
 
Monty committed
33
#include "codebook.h"
Monty's avatar
 
Monty committed
34
#include "misc.h"
Michael Smith's avatar
 
Michael Smith committed
35
#include "os.h"
Monty's avatar
 
Monty committed
36
#include "psy.h"
Mike Whitson's avatar
Mike Whitson committed
37

Monty's avatar
 
Monty committed
38 39 40 41 42 43 44 45 46
static int ilog2(unsigned int v){
  int ret=0;
  while(v>1){
    ret++;
    v>>=1;
  }
  return(ret);
}

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

Monty's avatar
 
Monty committed
49
 <-------------- lW ---------------->
Mike Whitson's avatar
Mike Whitson committed
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
                   <--------------- 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
71 72 73 74 75 76 77 78 79 80
 <-------------- lW ----------------->
                          |<--W-->|                               
:            ..............  ___  |   |                    
:        .'''             |`/   \ |   |                       
:.....'''                 |/`....\|...|                    
:.........................|___|___|___|                  
                          |Sl |Sr |endW    
                          |   |   |endSr
                          |   |beginSr
                          |   |endSl
Mike Whitson's avatar
Mike Whitson committed
81 82 83 84
			  |beginSl
			  |beginW
*/

Monty's avatar
 
Monty committed
85 86
/* block abstraction setup *********************************************/

Monty's avatar
 
Monty committed
87 88 89 90
#ifndef WORD_ALIGN
#define WORD_ALIGN 8
#endif

Monty's avatar
 
Monty committed
91 92 93
int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
  memset(vb,0,sizeof(vorbis_block));
  vb->vd=v;
Monty's avatar
 
Monty committed
94 95
  vb->localalloc=0;
  vb->localstore=NULL;
Monty's avatar
 
Monty committed
96
  if(v->analysisp){
Monty's avatar
 
Monty committed
97
    oggpack_writeinit(&vb->opb);
Monty's avatar
 
Monty committed
98 99 100 101
    vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
    ((vorbis_block_internal *)vb->internal)->ampmax=-9999;
  }
  
Monty's avatar
 
Monty committed
102 103 104
  return(0);
}

Monty's avatar
 
Monty committed
105 106 107
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
108
    /* can't just _ogg_realloc... there are outstanding pointers */
Monty's avatar
 
Monty committed
109
    if(vb->localstore){
Monty's avatar
 
Monty committed
110
      struct alloc_chain *link=_ogg_malloc(sizeof(struct alloc_chain));
Monty's avatar
 
Monty committed
111 112 113 114 115 116 117
      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
118
    vb->localstore=_ogg_malloc(vb->localalloc);
Monty's avatar
 
Monty committed
119
    vb->localtop=0;
Monty's avatar
 
Monty committed
120
  }
Monty's avatar
 
Monty committed
121
  {
Monty's avatar
 
Monty committed
122
    void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
Monty's avatar
 
Monty committed
123 124 125
    vb->localtop+=bytes;
    return ret;
  }
Monty's avatar
 
Monty committed
126 127
}

Monty's avatar
 
Monty committed
128
/* reap the chain, pull the ripcord */
Monty's avatar
 
Monty committed
129
void _vorbis_block_ripcord(vorbis_block *vb){
Monty's avatar
 
Monty committed
130 131 132 133
  /* reap the chain */
  struct alloc_chain *reap=vb->reap;
  while(reap){
    struct alloc_chain *next=reap->next;
Monty's avatar
 
Monty committed
134
    _ogg_free(reap->ptr);
Monty's avatar
 
Monty committed
135
    memset(reap,0,sizeof(struct alloc_chain));
Monty's avatar
 
Monty committed
136
    _ogg_free(reap);
Monty's avatar
 
Monty committed
137 138 139 140
    reap=next;
  }
  /* consolidate storage */
  if(vb->totaluse){
Monty's avatar
 
Monty committed
141
    vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
Monty's avatar
 
Monty committed
142 143 144 145 146
    vb->localalloc+=vb->totaluse;
    vb->totaluse=0;
  }

  /* pull the ripcord */
Monty's avatar
 
Monty committed
147
  vb->localtop=0;
Monty's avatar
 
Monty committed
148
  vb->reap=NULL;
Monty's avatar
 
Monty committed
149 150 151
}

int vorbis_block_clear(vorbis_block *vb){
Monty's avatar
 
Monty committed
152 153
  if(vb->vd)
    if(vb->vd->analysisp)
Monty's avatar
 
Monty committed
154
      oggpack_writeclear(&vb->opb);
Monty's avatar
 
Monty committed
155
  _vorbis_block_ripcord(vb);
Monty's avatar
 
Monty committed
156
  if(vb->localstore)_ogg_free(vb->localstore);
Monty's avatar
 
Monty committed
157
  if(vb->internal)_ogg_free(vb->internal);
Monty's avatar
 
Monty committed
158

Monty's avatar
 
Monty committed
159 160 161 162 163 164 165 166
  memset(vb,0,sizeof(vorbis_block));
  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
167
static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
Monty's avatar
 
Monty committed
168
  int i;
Monty's avatar
 
Monty committed
169 170 171
  codec_setup_info *ci=vi->codec_setup;
  backend_lookup_state *b=NULL;

Monty's avatar
 
Monty committed
172
  memset(v,0,sizeof(vorbis_dsp_state));
Monty's avatar
 
Monty committed
173
  b=v->backend_state=_ogg_calloc(1,sizeof(backend_lookup_state));
Monty's avatar
 
Monty committed
174

Monty's avatar
 
Monty committed
175
  v->vi=vi;
Monty's avatar
 
Monty committed
176
  b->modebits=ilog2(ci->modes);
Monty's avatar
 
Monty committed
177
  b->ampmax=-9999;
Monty's avatar
 
Monty committed
178

Monty's avatar
 
Monty committed
179 180
  b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
  b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
Monty's avatar
 
Monty committed
181

Monty's avatar
 
Monty committed
182 183
  /* MDCT is tranform 0 */

Monty's avatar
 
Monty committed
184 185 186 187
  b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
  b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
  mdct_init(b->transform[0][0],ci->blocksizes[0]);
  mdct_init(b->transform[1][0],ci->blocksizes[1]);
Monty's avatar
 
Monty committed
188

Monty's avatar
 
Monty committed
189 190 191 192 193 194 195 196
  b->window[0][0][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
  b->window[0][0][1]=b->window[0][0][0];
  b->window[0][1][0]=b->window[0][0][0];
  b->window[0][1][1]=b->window[0][0][0];
  b->window[1][0][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
  b->window[1][0][1]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
  b->window[1][1][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
  b->window[1][1][1]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
Monty's avatar
 
Monty committed
197 198

  for(i=0;i<VI_WINDOWB;i++){
Monty's avatar
 
Monty committed
199 200 201 202 203 204 205 206 207 208
    b->window[0][0][0][i]=
      _vorbis_window(i,ci->blocksizes[0],ci->blocksizes[0]/2,ci->blocksizes[0]/2);
    b->window[1][0][0][i]=
      _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[0]/2,ci->blocksizes[0]/2);
    b->window[1][0][1][i]=
      _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[0]/2,ci->blocksizes[1]/2);
    b->window[1][1][0][i]=
      _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[1]/2,ci->blocksizes[0]/2);
    b->window[1][1][1][i]=
      _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[1]/2,ci->blocksizes[1]/2);
Monty's avatar
 
Monty committed
209
  }
Monty's avatar
 
Monty committed
210

Monty's avatar
 
Monty committed
211 212
  if(encp){ /* encode/decode differ here */
    /* finish the codebooks */
Monty's avatar
 
Monty committed
213 214 215
    b->fullbooks=_ogg_calloc(ci->books,sizeof(codebook));
    for(i=0;i<ci->books;i++)
      vorbis_book_init_encode(b->fullbooks+i,ci->book_param[i]);
Monty's avatar
 
Monty committed
216 217 218
    v->analysisp=1;
  }else{
    /* finish the codebooks */
Monty's avatar
 
Monty committed
219 220 221
    b->fullbooks=_ogg_calloc(ci->books,sizeof(codebook));
    for(i=0;i<ci->books;i++)
      vorbis_book_init_decode(b->fullbooks+i,ci->book_param[i]);
Monty's avatar
 
Monty committed
222 223
  }

Mike Whitson's avatar
Mike Whitson committed
224 225 226
  /* initialize the storage vectors to a decent size greater than the
     minimum */
  
Monty's avatar
 
Monty committed
227 228
  v->pcm_storage=8192; /* we'll assume later that we have
			  a minimum of twice the blocksize of
Mike Whitson's avatar
Mike Whitson committed
229
			  accumulated samples in analysis */
Monty's avatar
 
Monty committed
230 231
  v->pcm=_ogg_malloc(vi->channels*sizeof(float *));
  v->pcmret=_ogg_malloc(vi->channels*sizeof(float *));
Mike Whitson's avatar
Mike Whitson committed
232 233
  {
    int i;
Monty's avatar
 
Monty committed
234
    for(i=0;i<vi->channels;i++)
Monty's avatar
 
Monty committed
235
      v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(float));
Mike Whitson's avatar
Mike Whitson committed
236 237 238
  }

  /* all 1 (large block) or 0 (small block) */
Monty's avatar
 
Monty committed
239 240 241
  /* 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
242

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

Monty's avatar
 
Monty committed
246
  v->pcm_current=v->centerW;
Monty's avatar
 
Monty committed
247 248

  /* initialize all the mapping/backend lookups */
Monty's avatar
 
Monty committed
249 250 251 252 253 254
  b->mode=_ogg_calloc(ci->modes,sizeof(vorbis_look_mapping *));
  for(i=0;i<ci->modes;i++){
    int mapnum=ci->mode_param[i]->mapping;
    int maptype=ci->map_type[mapnum];
    b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i],
					 ci->map_param[mapnum]);
Monty's avatar
 
Monty committed
255 256
  }

Monty's avatar
 
Monty committed
257
  return(0);
Mike Whitson's avatar
Mike Whitson committed
258 259
}

Monty's avatar
 
Monty committed
260 261
/* 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
262 263
  backend_lookup_state *b=NULL;

Monty's avatar
 
Monty committed
264
  _vds_shared_init(v,vi,1);
Monty's avatar
 
Monty committed
265
  b=v->backend_state;
Monty's avatar
 
Monty committed
266

Monty's avatar
 
Monty committed
267
  /* Initialize the envelope state storage */
Monty's avatar
 
Monty committed
268 269
  b->ve=_ogg_calloc(1,sizeof(envelope_lookup));
  _ve_envelope_init(b->ve,vi);
Monty's avatar
 
Monty committed
270

Monty's avatar
 
Monty committed
271 272 273
  return(0);
}

Monty's avatar
 
Monty committed
274
void vorbis_dsp_clear(vorbis_dsp_state *v){
Mike Whitson's avatar
Mike Whitson committed
275 276
  int i,j,k;
  if(v){
Monty's avatar
 
Monty committed
277
    vorbis_info *vi=v->vi;
Monty's avatar
 
Monty committed
278 279 280 281 282 283
    codec_setup_info *ci=(vi?vi->codec_setup:NULL);
    backend_lookup_state *b=v->backend_state;

    if(b){
      if(b->window[0][0][0]){
	for(i=0;i<VI_WINDOWB;i++)
Monty's avatar
 
Monty committed
284 285
	  if(b->window[0][0][0][i])_ogg_free(b->window[0][0][0][i]);
	_ogg_free(b->window[0][0][0]);
Monty's avatar
 
Monty committed
286 287 288 289
	
	for(j=0;j<2;j++)
	  for(k=0;k<2;k++){
	    for(i=0;i<VI_WINDOWB;i++)
Monty's avatar
 
Monty committed
290 291
	      if(b->window[1][j][k][i])_ogg_free(b->window[1][j][k][i]);
	    _ogg_free(b->window[1][j][k]);
Monty's avatar
 
Monty committed
292 293
	  }
      }
Monty's avatar
 
Monty committed
294

Monty's avatar
 
Monty committed
295 296
      if(b->ve){
	_ve_envelope_clear(b->ve);
Monty's avatar
 
Monty committed
297
	_ogg_free(b->ve);
Monty's avatar
 
Monty committed
298 299 300 301
      }

      if(b->transform[0]){
	mdct_clear(b->transform[0][0]);
Monty's avatar
 
Monty committed
302 303
	_ogg_free(b->transform[0][0]);
	_ogg_free(b->transform[0]);
Monty's avatar
 
Monty committed
304 305 306
      }
      if(b->transform[1]){
	mdct_clear(b->transform[1][0]);
Monty's avatar
 
Monty committed
307 308
	_ogg_free(b->transform[1][0]);
	_ogg_free(b->transform[1]);
Monty's avatar
 
Monty committed
309 310
      }
      
Monty's avatar
 
Monty committed
311 312
    }
    
Mike Whitson's avatar
Mike Whitson committed
313
    if(v->pcm){
Monty's avatar
 
Monty committed
314
      for(i=0;i<vi->channels;i++)
Monty's avatar
 
Monty committed
315 316 317
	if(v->pcm[i])_ogg_free(v->pcm[i]);
      _ogg_free(v->pcm);
      if(v->pcmret)_ogg_free(v->pcmret);
Mike Whitson's avatar
Mike Whitson committed
318
    }
Monty's avatar
 
Monty committed
319

Monty's avatar
 
Monty committed
320
    /* free mode lookups; these are actually vorbis_look_mapping structs */
Monty's avatar
 
Monty committed
321 322 323 324 325
    if(ci){
      for(i=0;i<ci->modes;i++){
	int mapnum=ci->mode_param[i]->mapping;
	int maptype=ci->map_type[mapnum];
	if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]);
Monty's avatar
 
Monty committed
326 327
      }
      /* free codebooks */
Monty's avatar
 
Monty committed
328 329
      for(i=0;i<ci->books;i++)
	if(b && b->fullbooks)vorbis_book_clear(b->fullbooks+i);
Monty's avatar
 
Monty committed
330
    }
Monty's avatar
 
Monty committed
331

Monty's avatar
 
Monty committed
332
    if(b){
Monty's avatar
 
Monty committed
333 334
      if(b->mode)_ogg_free(b->mode);    
      if(b->fullbooks)_ogg_free(b->fullbooks);
Monty's avatar
 
Monty committed
335 336
      
      /* free header, header1, header2 */
Monty's avatar
 
Monty committed
337 338 339 340
      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
341 342
    }
    
Monty's avatar
 
Monty committed
343
    memset(v,0,sizeof(vorbis_dsp_state));
Mike Whitson's avatar
Mike Whitson committed
344 345 346
  }
}

Monty's avatar
 
Monty committed
347
float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
Mike Whitson's avatar
Mike Whitson committed
348
  int i;
Monty's avatar
 
Monty committed
349
  vorbis_info *vi=v->vi;
Monty's avatar
 
Monty committed
350
  backend_lookup_state *b=v->backend_state;
Mike Whitson's avatar
Mike Whitson committed
351

Monty's avatar
 
Monty committed
352
  /* free header, header1, header2 */
Monty's avatar
 
Monty committed
353 354 355
  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
356

Monty's avatar
 
Monty committed
357 358 359 360 361 362
  /* 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
363
    for(i=0;i<vi->channels;i++){
Monty's avatar
 
Monty committed
364
      v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(float));
Monty's avatar
 
Monty committed
365
    }
Monty's avatar
 
Monty committed
366
  }
Mike Whitson's avatar
Mike Whitson committed
367

Monty's avatar
 
Monty committed
368
  for(i=0;i<vi->channels;i++)
Monty's avatar
 
Monty committed
369 370 371 372
    v->pcmret[i]=v->pcm[i]+v->pcm_current;
    
  return(v->pcmret);
}
Mike Whitson's avatar
Mike Whitson committed
373

Monty's avatar
 
Monty committed
374
static void _preextrapolate_helper(vorbis_dsp_state *v){
Monty's avatar
 
Monty committed
375 376
  int i;
  int order=32;
Monty's avatar
 
Monty committed
377 378
  float *lpc=alloca(order*sizeof(float));
  float *work=alloca(v->pcm_current*sizeof(float));
Monty's avatar
 
Monty committed
379
  long j;
Monty's avatar
 
Monty committed
380
  v->preextrapolate=1;
Monty's avatar
 
Monty committed
381 382 383 384

  if(v->pcm_current-v->centerW>order*2){ /* safety */
    for(i=0;i<v->vi->channels;i++){
      
Monty's avatar
 
Monty committed
385
      /* need to run the extrapolation in reverse! */
Monty's avatar
 
Monty committed
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
      for(j=0;j<v->pcm_current;j++)
	work[j]=v->pcm[i][v->pcm_current-j-1];
      
      /* prime as above */
      vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
      
      /* run the predictor filter */
      vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
			 order,
			 work+v->pcm_current-v->centerW,
			 v->centerW);
      for(j=0;j<v->pcm_current;j++)
	v->pcm[i][v->pcm_current-j-1]=work[j];
    }
  }
}


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

Monty's avatar
 
Monty committed
406
int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
Monty's avatar
 
Monty committed
407
  vorbis_info *vi=v->vi;
Monty's avatar
 
Monty committed
408 409
  codec_setup_info *ci=vi->codec_setup;

Monty's avatar
 
Monty committed
410
  if(vals<=0){
Monty's avatar
 
Monty committed
411 412
    int order=32;
    int i;
Monty's avatar
 
Monty committed
413
    float *lpc=alloca(order*sizeof(float));
Monty's avatar
 
Monty committed
414 415

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

Monty's avatar
 
Monty committed
419 420
    /* We're encoding the end of the stream.  Just make sure we have
       [at least] a full block of zeroes at the end. */
Monty's avatar
 
Monty committed
421 422 423
    /* 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
424

Monty's avatar
 
Monty committed
425
    vorbis_analysis_buffer(v,ci->blocksizes[1]*2);
Monty's avatar
 
Monty committed
426
    v->eofflag=v->pcm_current;
Monty's avatar
 
Monty committed
427
    v->pcm_current+=ci->blocksizes[1]*2;
Monty's avatar
 
Monty committed
428 429 430 431 432 433 434 435

    for(i=0;i<vi->channels;i++){
      if(v->eofflag>order*2){
	/* extrapolate with LPC to fill in */
	long n;

	/* make a predictor filter */
	n=v->eofflag;
Monty's avatar
 
Monty committed
436
	if(n>ci->blocksizes[1])n=ci->blocksizes[1];
Monty's avatar
 
Monty committed
437 438 439 440 441 442
	vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);

	/* 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);
      }else{
Monty's avatar
 
Monty committed
443
	/* not enough data to extrapolate (unlikely to happen due to
Monty's avatar
 
Monty committed
444 445 446
           guarding the overlap, but bulletproof in case that
           assumtion goes away). zeroes will do. */
	memset(v->pcm[i]+v->eofflag,0,
Monty's avatar
 
Monty committed
447
	       (v->pcm_current-v->eofflag)*sizeof(float));
Monty's avatar
 
Monty committed
448 449 450

      }
    }
Monty's avatar
 
Monty committed
451
  }else{
Monty's avatar
 
Monty committed
452

Monty's avatar
 
Monty committed
453
    if(v->pcm_current+vals>v->pcm_storage)
Monty's avatar
 
Monty committed
454
      return(OV_EINVAL);
Mike Whitson's avatar
Mike Whitson committed
455

Monty's avatar
 
Monty committed
456
    v->pcm_current+=vals;
Monty's avatar
 
Monty committed
457

Monty's avatar
 
Monty committed
458
    /* we may want to reverse extrapolate the beginning of a stream
Monty's avatar
 
Monty committed
459 460
       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
461
    if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
Monty's avatar
 
Monty committed
462
      _preextrapolate_helper(v);
Monty's avatar
 
Monty committed
463

Monty's avatar
 
Monty committed
464
  }
Monty's avatar
 
Monty committed
465 466
  return(0);
}
Mike Whitson's avatar
Mike Whitson committed
467

Monty's avatar
 
Monty committed
468 469
/* 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
470
int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
Monty's avatar
 
Monty committed
471
  int i;
Monty's avatar
 
Monty committed
472
  vorbis_info *vi=v->vi;
Monty's avatar
 
Monty committed
473 474 475
  codec_setup_info *ci=vi->codec_setup;
  backend_lookup_state *b=v->backend_state;
  long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
Mike Whitson's avatar
Mike Whitson committed
476

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

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

Monty's avatar
 
Monty committed
483 484 485
  /* 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 */
Mike Whitson's avatar
Mike Whitson committed
486
  
Monty's avatar
 
Monty committed
487
  if(ci->blocksizes[0]<ci->blocksizes[1]){
Monty's avatar
 
Monty committed
488 489 490 491 492
    long largebound;
    long bp;

    if(v->W)
      /* min boundary; nW large, next small */
Monty's avatar
 
Monty committed
493
      largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]/4;
Monty's avatar
 
Monty committed
494 495
    else
      /* min boundary; nW large, next small */
Monty's avatar
 
Monty committed
496
      largebound=v->centerW+ci->blocksizes[1]/2+ci->blocksizes[0]/2;
Monty's avatar
 
Monty committed
497 498 499 500 501

    bp=_ve_envelope_search(v,largebound);
    if(bp==-1)return(0); /* not enough data currently to search for a
                            full long block */
    v->nW=bp;
Monty's avatar
 
Monty committed
502

Monty's avatar
 
Monty committed
503
  }else
Monty's avatar
 
Monty committed
504
    v->nW=0;
Monty's avatar
 
Monty committed
505
  
Monty's avatar
 
Monty committed
506
  centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
Monty's avatar
 
Monty committed
507

Monty's avatar
 
Monty committed
508
  {
Monty's avatar
 
Monty committed
509
    /* center of next block + next block maximum right side. */
Monty's avatar
 
Monty committed
510

Monty's avatar
 
Monty committed
511
    long blockbound=centerNext+ci->blocksizes[v->nW]/2;
Monty's avatar
 
Monty committed
512 513 514 515 516 517 518
    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
519
  }
Monty's avatar
 
Monty committed
520 521 522
  
  /* 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
523

Monty's avatar
 
Monty committed
524
  _vorbis_block_ripcord(vb);
Monty's avatar
 
Monty committed
525 526 527 528 529 530 531 532 533
  if(v->W){
    vb->lW=v->lW;
    vb->W=v->W;
    vb->nW=v->nW;
  }else{
    vb->lW=0;
    vb->W=v->W;
    vb->nW=0;
  }
Monty's avatar
 
Monty committed
534
  vb->vd=v;
Monty's avatar
 
Monty committed
535
  vb->sequence=v->sequence;
Monty's avatar
 
Monty committed
536
  vb->granulepos=v->granulepos;
Monty's avatar
 
Monty committed
537
  vb->pcmend=ci->blocksizes[v->W];
Monty's avatar
 
Monty committed
538

Monty's avatar
 
Monty committed
539
  
Monty's avatar
 
Monty committed
540 541
  /* copy the vectors; this uses the local storage in vb */
  {
Monty's avatar
 
Monty committed
542 543 544 545 546 547 548
    vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;

    /* this tracks 'strongest peak' for later psychoacoustics */
    if(vbi->ampmax>b->ampmax)b->ampmax=vbi->ampmax;
    b->ampmax=_vp_ampmax_decay(b->ampmax,v);
    vbi->ampmax=b->ampmax;

Monty's avatar
 
Monty committed
549
    vb->pcm=_vorbis_block_alloc(vb,sizeof(float *)*vi->channels);
Monty's avatar
 
Monty committed
550
    vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(float *)*vi->channels);
Monty's avatar
 
Monty committed
551
    for(i=0;i<vi->channels;i++){
Monty's avatar
 
Monty committed
552 553 554 555 556 557
      vbi->pcmdelay[i]=
	_vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(float));
      memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(float));
      vb->pcm[i]=vbi->pcmdelay[i]+beginW;
      
      /* before we added the delay 
Monty's avatar
 
Monty committed
558
      vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(float));
Monty's avatar
 
Monty committed
559
      memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(float));
Monty's avatar
 
Monty committed
560 561
      */

Monty's avatar
 
Monty committed
562 563
    }
  }
Monty's avatar
 
Monty committed
564
  
Monty's avatar
 
Monty committed
565 566 567 568 569
  /* 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
570
    if(v->centerW>=v->eofflag){
Monty's avatar
 
Monty committed
571 572
      v->eofflag=-1;
      vb->eofflag=1;
Monty's avatar
 
Monty committed
573
      return(1);
Monty's avatar
 
Monty committed
574 575
    }
  }
Mike Whitson's avatar
Mike Whitson committed
576 577 578

  /* advance storage vectors and clean up */
  {
Monty's avatar
 
Monty committed
579
    int new_centerNext=ci->blocksizes[1]/2+ci->delaycache;
Monty's avatar
 
Monty committed
580
    int movementW=centerNext-new_centerNext;
Monty's avatar
 
Monty committed
581

Monty's avatar
 
Monty committed
582
    if(movementW>0){
Monty's avatar
 
Monty committed
583

Monty's avatar
 
Monty committed
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
      _ve_envelope_shift(b->ve,movementW);
      v->pcm_current-=movementW;
      
      for(i=0;i<vi->channels;i++)
	memmove(v->pcm[i],v->pcm[i]+movementW,
		v->pcm_current*sizeof(float));
      
      
      v->lW=v->W;
      v->W=v->nW;
      v->centerW=new_centerNext;
      
      v->sequence++;
      
      if(v->eofflag){
	v->eofflag-=movementW;
	/* 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
606
      }else{
Monty's avatar
 
Monty committed
607
	v->granulepos+=movementW;
Monty's avatar
 
Monty committed
608
      }
Monty's avatar
 
Monty committed
609
    }
Mike Whitson's avatar
Mike Whitson committed
610 611 612 613 614
  }

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

Monty's avatar
 
Monty committed
616
int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
Monty's avatar
 
Monty committed
617
  codec_setup_info *ci=vi->codec_setup;
Monty's avatar
 
Monty committed
618
  _vds_shared_init(v,vi,0);
Monty's avatar
 
Monty committed
619

Monty's avatar
 
Monty committed
620
  v->pcm_returned=-1;
Monty's avatar
 
Monty committed
621
  v->granulepos=-1;
Monty's avatar
 
Monty committed
622 623
  v->sequence=-1;

Monty's avatar
 
Monty committed
624 625
  return(0);
}
Monty's avatar
 
Monty committed
626

Monty's avatar
 
Monty committed
627
/* Unlike in analysis, the window is only partially applied for each
Monty's avatar
 
Monty committed
628 629
   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
630

Monty's avatar
 
Monty committed
631
int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
Monty's avatar
 
Monty committed
632
  vorbis_info *vi=v->vi;
Monty's avatar
 
Monty committed
633
  codec_setup_info *ci=vi->codec_setup;
Monty's avatar
 
Monty committed
634

Monty's avatar
 
Monty committed
635
  /* Shift out any PCM that we returned previously */
Monty's avatar
 
Monty committed
636
  /* centerW is currently the center of the last block added */
Monty's avatar
 
Monty committed
637 638 639 640 641 642

  if(v->centerW>ci->blocksizes[1]/2 &&
  /* Quick additional hack; to avoid *alot* of shifts, use an
     oversized buffer.  This increases memory usage, but doesn't make
     much difference wrt L1/L2 cache pressure. */
     v->pcm_returned>8192){
Monty's avatar
 
Monty committed
643

Monty's avatar
 
Monty committed
644 645
    /* don't shift too much; we need to have a minimum PCM buffer of
       1/2 long block */
Monty's avatar
 
Monty committed
646

Monty's avatar
 
Monty committed
647
    int shiftPCM=v->centerW-ci->blocksizes[1]/2;
Monty's avatar
 
Monty committed
648
    shiftPCM=(v->pcm_returned<shiftPCM?v->pcm_returned:shiftPCM);
Monty's avatar
 
Monty committed
649

Monty's avatar
 
Monty committed
650 651 652
    v->pcm_current-=shiftPCM;
    v->centerW-=shiftPCM;
    v->pcm_returned-=shiftPCM;
Monty's avatar
 
Monty committed
653
    
Monty's avatar
 
Monty committed
654
    if(shiftPCM){
Monty's avatar
 
Monty committed
655
      int i;
Monty's avatar
 
Monty committed
656
      for(i=0;i<vi->channels;i++)
Monty's avatar
 
Monty committed
657
	memmove(v->pcm[i],v->pcm[i]+shiftPCM,
Monty's avatar
 
Monty committed
658
		v->pcm_current*sizeof(float));
Monty's avatar
 
Monty committed
659 660
    }
  }
Monty's avatar
 
Monty committed
661

Monty's avatar
 
Monty committed
662 663
  v->lW=v->W;
  v->W=vb->W;
Monty's avatar
 
Monty committed
664
  v->nW=-1;
Monty's avatar
 
Monty committed
665

Monty's avatar
 
Monty committed
666 667 668 669
  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
670

Monty's avatar
 
Monty committed
671
  if(v->sequence+1 != vb->sequence)v->granulepos=-1; /* out of sequence;
Monty's avatar
 
Monty committed
672 673
                                                     lose count */

Monty's avatar
 
Monty committed
674
  v->sequence=vb->sequence;
Monty's avatar
 
Monty committed
675

Monty's avatar
 
Monty committed
676
  {
Monty's avatar
 
Monty committed
677 678
    int sizeW=ci->blocksizes[v->W];
    int centerW=v->centerW+ci->blocksizes[v->lW]/4+sizeW/4;
Monty's avatar
 
Monty committed
679 680 681 682
    int beginW=centerW-sizeW/2;
    int endW=beginW+sizeW;
    int beginSl;
    int endSl;
Monty's avatar
 
Monty committed
683
    int i,j;
Monty's avatar
 
Monty committed
684

Monty's avatar
 
Monty committed
685
    /* Do we have enough PCM/mult storage for the block? */
Monty's avatar
 
Monty committed
686
    if(endW>v->pcm_storage){
Monty's avatar
 
Monty committed
687
      /* expand the storage */
Monty's avatar
 
Monty committed
688
      v->pcm_storage=endW+ci->blocksizes[1];
Monty's avatar
 
Monty committed
689
   
Monty's avatar
 
Monty committed
690
      for(i=0;i<vi->channels;i++)
Monty's avatar
 
Monty committed
691
	v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(float)); 
Monty's avatar
 
Monty committed
692
    }
Monty's avatar
 
Monty committed
693

Monty's avatar
 
Monty committed
694 695
    /* overlap/add PCM */

Monty's avatar
 
Monty committed
696
    switch(v->W){
Monty's avatar
 
Monty committed
697 698
    case 0:
      beginSl=0;
Monty's avatar
 
Monty committed
699
      endSl=ci->blocksizes[0]/2;
Monty's avatar
 
Monty committed
700 701
      break;
    case 1:
Monty's avatar
 
Monty committed
702 703
      beginSl=ci->blocksizes[1]/4-ci->blocksizes[v->lW]/4;
      endSl=beginSl+ci->blocksizes[v->lW]/2;
Monty's avatar
 
Monty committed
704
      break;
Monty's avatar
 
Monty committed
705 706
    default:
      return(-1);
Monty's avatar
 
Monty committed
707
    }
Monty's avatar
 
Monty committed
708

Monty's avatar
 
Monty committed
709
    for(j=0;j<vi->channels;j++){
Monty's avatar
 
Monty committed
710
      static int seq=0;
Monty's avatar
 
Monty committed
711 712 713
      float *pcm=v->pcm[j]+beginW;
      float *p=vb->pcm[j];

Monty's avatar
 
Monty committed
714
      /* the overlap/add section */
Monty's avatar
 
Monty committed
715
      for(i=beginSl;i<endSl;i++)
Monty's avatar
 
Monty committed
716
	pcm[i]+=p[i];
Monty's avatar
 
Monty committed
717 718
      /* the remaining section */
      for(;i<sizeW;i++)
Monty's avatar
 
Monty committed
719
	pcm[i]=p[i];
Monty's avatar
 
Monty committed
720 721 722 723

      _analysis_output("lapped",seq,pcm,sizeW,0,0);
      _analysis_output("buffered",seq++,v->pcm[j],sizeW+beginW,0,0);
    
Monty's avatar
 
Monty committed
724 725
    }

Monty's avatar
 
Monty committed
726 727 728 729 730 731
    /* 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 */

    if(v->pcm_returned==-1)
      v->pcm_returned=centerW;
Monty's avatar
 
Monty committed
732

Monty's avatar
 
Monty committed
733 734 735
    /* 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
Monty's avatar
 
Monty committed
736
       return will be past the vb->granulepos.
Monty's avatar
 
Monty committed
737 738 739 740 741 742 743
       
       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
744
    if(v->granulepos==-1)
Monty's avatar
 
Monty committed
745 746 747 748 749
      if(vb->granulepos==-1){
	v->granulepos=0;
      }else{
	v->granulepos=vb->granulepos;
      }
Monty's avatar
 
Monty committed
750
    else{
Monty's avatar
 
Monty committed
751 752
      v->granulepos+=(centerW-v->centerW);
      if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
Monty's avatar
 
Monty committed
753 754 755 756 757 758 759 760

	if(v->granulepos>vb->granulepos){
	  long extra=v->granulepos-vb->granulepos;

	  if(vb->eofflag){
	    /* partial last frame.  Strip the extra samples off */
	    centerW-=extra;
	  }else if(vb->sequence == 1){
Monty's avatar
 
Monty committed
761 762 763
	    /* ^^^ argh, this can be 1 from seeking! */


Monty's avatar
 
Monty committed
764 765 766 767 768 769
	    /* partial first frame.  Discard extra leading samples */
	    v->pcm_returned+=extra;
	    if(v->pcm_returned>centerW)v->pcm_returned=centerW;
	    
	  }
	  
Monty's avatar
 
Monty committed
770
	}/* else{ Shouldn't happen *unless* the bitstream is out of
Monty's avatar
 
Monty committed
771
	    spec.  Either way, believe the bitstream } */
Monty's avatar
 
Monty committed
772
	v->granulepos=vb->granulepos;
Monty's avatar
 
Monty committed
773 774 775
      }
    }

Monty's avatar
 
Monty committed
776
    /* Update, cleanup */
Monty's avatar
 
Monty committed
777

Monty's avatar
 
Monty committed
778 779
    v->centerW=centerW;
    v->pcm_current=endW;
Monty's avatar
 
Monty committed
780

Monty's avatar
 
Monty committed
781 782
    if(vb->eofflag)v->eofflag=1;
  }
Monty's avatar
 
Monty committed
783

Monty's avatar
 
Monty committed
784
  return(0);
Monty's avatar
 
Monty committed
785 786
}

Monty's avatar
 
Monty committed
787
/* pcm==NULL indicates we just want the pending samples, no more */
Monty's avatar
 
Monty committed
788
int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
Monty's avatar
 
Monty committed
789
  vorbis_info *vi=v->vi;
Monty's avatar
 
Monty committed
790
  if(v->pcm_returned>-1 && v->pcm_returned<v->centerW){
Monty's avatar
 
Monty committed
791 792 793 794 795 796
    if(pcm){
      int i;
      for(i=0;i<vi->channels;i++)
	v->pcmret[i]=v->pcm[i]+v->pcm_returned;
      *pcm=v->pcmret;
    }
Monty's avatar
 
Monty committed
797 798 799 800
    return(v->centerW-v->pcm_returned);
  }
  return(0);
}
Monty's avatar
 
Monty committed
801

Monty's avatar
 
Monty committed
802
int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
Monty's avatar
 
Monty committed
803
  if(bytes && v->pcm_returned+bytes>v->centerW)return(OV_EINVAL);
Monty's avatar
 
Monty committed
804 805 806
  v->pcm_returned+=bytes;
  return(0);
}
Monty's avatar
 
Monty committed
807