18e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/********************************************************************
28e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
38e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
48e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
58e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
68e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
78e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
88e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
98e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * by the Xiph.Org Foundation http://www.xiph.org/                  *
108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************
128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels function: PCM data vector blocking, windowing and dis/reassembly
148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels last mod: $Id: block.c 16330 2009-07-24 01:58:50Z xiphmont $
158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels Handle windowing, overlap-add, etc of the PCM vectors.  This is made
178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels more amusing by Vorbis' current two allowed block sizes.
188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************/
208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdio.h>
228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdlib.h>
238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <string.h>
248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <ogg/ogg.h>
258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "vorbis/codec.h"
268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "codec_internal.h"
278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "window.h"
298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "mdct.h"
308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "lpc.h"
318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "registry.h"
328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "misc.h"
338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int ilog2(unsigned int v){
358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ret=0;
368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v)--v;
378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  while(v){
388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ret++;
398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v>>=1;
408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(ret);
428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* pcm accumulator examples (not exhaustive):
458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels <-------------- lW ---------------->
478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                   <--------------- W ---------------->
488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels:            .....|.....       _______________         |
498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels:        .'''     |     '''_---      |       |\        |
508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels:.....'''         |_____--- '''......|       | \_______|
518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels:.................|__________________|_______|__|______|
528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  |<------ Sl ------>|      > Sr <     |endW
538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  |beginSl           |endSl  |  |endSr
548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  |beginW            |endlW  |beginSr
558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                      |< lW >|
588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                   <--------------- W ---------------->
598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  |   |  ..  ______________            |
608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  |   | '  `/        |     ---_        |
618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  |___.'___/`.       |         ---_____|
628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  |_______|__|_______|_________________|
638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  |      >|Sl|<      |<------ Sr ----->|endW
648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  |       |  |endSl  |beginSr          |endSr
658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  |beginW |  |endlW
668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  mult[0] |beginSl                     mult[n]
678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels <-------------- lW ----------------->
698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          |<--W-->|
708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels:            ..............  ___  |   |
718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels:        .'''             |`/   \ |   |
728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels:.....'''                 |/`....\|...|
738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels:.........................|___|___|___|
748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          |Sl |Sr |endW
758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          |   |   |endSr
768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          |   |beginSr
778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          |   |endSl
788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          |beginSl
798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          |beginW
808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels*/
818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* block abstraction setup *********************************************/
838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#ifndef WORD_ALIGN
858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#define WORD_ALIGN 8
868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memset(vb,0,sizeof(*vb));
918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->vd=v;
928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->localalloc=0;
938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->localstore=NULL;
948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v->analysisp){
958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_block_internal *vbi=
968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vbi->ampmax=-9999;
988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<PACKETBLOBS;i++){
1008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(i==PACKETBLOBS/2){
1018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        vbi->packetblob[i]=&vb->opb;
1028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }else{
1038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        vbi->packetblob[i]=
1048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          _ogg_calloc(1,sizeof(oggpack_buffer));
1058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
1068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      oggpack_writeinit(vbi->packetblob[i]);
1078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
1118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid *_vorbis_block_alloc(vorbis_block *vb,long bytes){
1148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
1158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(bytes+vb->localtop>vb->localalloc){
1168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* can't just _ogg_realloc... there are outstanding pointers */
1178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(vb->localstore){
1188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      struct alloc_chain *link=_ogg_malloc(sizeof(*link));
1198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vb->totaluse+=vb->localtop;
1208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      link->next=vb->reap;
1218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      link->ptr=vb->localstore;
1228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vb->reap=link;
1238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* highly conservative */
1258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->localalloc=bytes;
1268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->localstore=_ogg_malloc(vb->localalloc);
1278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->localtop=0;
1288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
1308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
1318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->localtop+=bytes;
1328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return ret;
1338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* reap the chain, pull the ripcord */
1378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid _vorbis_block_ripcord(vorbis_block *vb){
1388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* reap the chain */
1398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  struct alloc_chain *reap=vb->reap;
1408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  while(reap){
1418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    struct alloc_chain *next=reap->next;
1428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    _ogg_free(reap->ptr);
1438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memset(reap,0,sizeof(*reap));
1448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    _ogg_free(reap);
1458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    reap=next;
1468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* consolidate storage */
1488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(vb->totaluse){
1498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
1508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->localalloc+=vb->totaluse;
1518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->totaluse=0;
1528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* pull the ripcord */
1558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->localtop=0;
1568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->reap=NULL;
1578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_block_clear(vorbis_block *vb){
1608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
1618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_block_internal *vbi=vb->internal;
1628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  _vorbis_block_ripcord(vb);
1648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(vb->localstore)_ogg_free(vb->localstore);
1658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(vbi){
1678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<PACKETBLOBS;i++){
1688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      oggpack_writeclear(vbi->packetblob[i]);
1698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
1708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    _ogg_free(vbi);
1728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memset(vb,0,sizeof(*vb));
1748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
1758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* Analysis side code, but directly related to blocking.  Thus it's
1788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   here and not in analysis.c (which is for analysis transforms only).
1798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   The init is here because some of it is shared */
1808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
1828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
1838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
1848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  private_state *b=NULL;
1858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int hs;
1868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ci==NULL) return 1;
1888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hs=ci->halfrate_flag;
1898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memset(v,0,sizeof(*v));
1918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b=v->backend_state=_ogg_calloc(1,sizeof(*b));
1928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->vi=vi;
1948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b->modebits=ilog2(ci->modes);
1958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
1978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
1988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* MDCT is tranform 0 */
2008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
2028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
2038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
2048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
2058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* Vorbis I uses only window type 0 */
2078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b->window[0]=ilog2(ci->blocksizes[0])-6;
2088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b->window[1]=ilog2(ci->blocksizes[1])-6;
2098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(encp){ /* encode/decode differ here */
2118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* analysis always needs an fft */
2138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    drft_init(&b->fft_look[0],ci->blocksizes[0]);
2148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    drft_init(&b->fft_look[1],ci->blocksizes[1]);
2158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* finish the codebooks */
2178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(!ci->fullbooks){
2188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
2198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<ci->books;i++)
2208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
2218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy));
2248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<ci->psys;i++){
2258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      _vp_psy_init(b->psy+i,
2268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                   ci->psy_param[i],
2278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                   &ci->psy_g_param,
2288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                   ci->blocksizes[ci->psy_param[i]->blockflag]/2,
2298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                   vi->rate);
2308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->analysisp=1;
2338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
2348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* finish the codebooks */
2358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(!ci->fullbooks)
2368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
2378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<ci->books;i++){
2388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(ci->book_param[i]==NULL)
2398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        goto abort_books;
2408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
2418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        goto abort_books;
2428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* decode codebooks are now standalone after init */
2438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vorbis_staticbook_destroy(ci->book_param[i]);
2448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      ci->book_param[i]=NULL;
2458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* initialize the storage vectors. blocksize[1] is small for encode,
2498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     but the correct size for decode */
2508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->pcm_storage=ci->blocksizes[1];
2518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
2528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
2538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
2548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int i;
2558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<vi->channels;i++)
2568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
2578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* all 1 (large block) or 0 (small block) */
2608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* explicitly set for the sake of clarity */
2618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->lW=0; /* previous window size */
2628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->W=0;  /* current window size */
2638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* all vector indexes */
2658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->centerW=ci->blocksizes[1]/2;
2668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->pcm_current=v->centerW;
2688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* initialize all the backend lookups */
2708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
2718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
2728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<ci->floors;i++)
2748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    b->flr[i]=_floor_P[ci->floor_type[i]]->
2758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      look(v,ci->floor_param[i]);
2768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<ci->residues;i++)
2788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    b->residue[i]=_residue_P[ci->residue_type[i]]->
2798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      look(v,ci->residue_param[i]);
2808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return 0;
2828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels abort_books:
2838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<ci->books;i++){
2848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(ci->book_param[i]!=NULL){
2858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vorbis_staticbook_destroy(ci->book_param[i]);
2868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      ci->book_param[i]=NULL;
2878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_dsp_clear(v);
2908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return -1;
2918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* arbitrary settings and spec-mandated numbers get filled in here */
2948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
2958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  private_state *b=NULL;
2968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(_vds_shared_init(v,vi,1))return 1;
2988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b=v->backend_state;
2998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b->psy_g_look=_vp_global_look(vi);
3008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* Initialize the envelope state storage */
3028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  b->ve=_ogg_calloc(1,sizeof(*b->ve));
3038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  _ve_envelope_init(b->ve,vi);
3048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_bitrate_init(vi,&b->bms);
3068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* compressed audio packets start after the headers
3088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     with sequence number 3 */
3098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->sequence=3;
3108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
3128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
3138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid vorbis_dsp_clear(vorbis_dsp_state *v){
3158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
3168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v){
3178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_info *vi=v->vi;
3188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    codec_setup_info *ci=(vi?vi->codec_setup:NULL);
3198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    private_state *b=v->backend_state;
3208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(b){
3228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(b->ve){
3248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        _ve_envelope_clear(b->ve);
3258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        _ogg_free(b->ve);
3268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
3278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(b->transform[0]){
3298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        mdct_clear(b->transform[0][0]);
3308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        _ogg_free(b->transform[0][0]);
3318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        _ogg_free(b->transform[0]);
3328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
3338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(b->transform[1]){
3348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        mdct_clear(b->transform[1][0]);
3358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        _ogg_free(b->transform[1][0]);
3368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        _ogg_free(b->transform[1]);
3378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
3388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(b->flr){
3408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(ci)
3418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          for(i=0;i<ci->floors;i++)
3428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            _floor_P[ci->floor_type[i]]->
3438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              free_look(b->flr[i]);
3448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        _ogg_free(b->flr);
3458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
3468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(b->residue){
3478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(ci)
3488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          for(i=0;i<ci->residues;i++)
3498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            _residue_P[ci->residue_type[i]]->
3508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              free_look(b->residue[i]);
3518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        _ogg_free(b->residue);
3528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
3538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(b->psy){
3548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(ci)
3558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          for(i=0;i<ci->psys;i++)
3568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            _vp_psy_clear(b->psy+i);
3578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        _ogg_free(b->psy);
3588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
3598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(b->psy_g_look)_vp_global_free(b->psy_g_look);
3618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vorbis_bitrate_clear(&b->bms);
3628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      drft_clear(&b->fft_look[0]);
3648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      drft_clear(&b->fft_look[1]);
3658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
3678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(v->pcm){
3698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(vi)
3708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(i=0;i<vi->channels;i++)
3718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(v->pcm[i])_ogg_free(v->pcm[i]);
3728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      _ogg_free(v->pcm);
3738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(v->pcmret)_ogg_free(v->pcmret);
3748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
3758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(b){
3778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* free header, header1, header2 */
3788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(b->header)_ogg_free(b->header);
3798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(b->header1)_ogg_free(b->header1);
3808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(b->header2)_ogg_free(b->header2);
3818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      _ogg_free(b);
3828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
3838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memset(v,0,sizeof(*v));
3858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
3868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
3878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
3898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
3908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info *vi=v->vi;
3918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  private_state *b=v->backend_state;
3928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* free header, header1, header2 */
3948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(b->header)_ogg_free(b->header);b->header=NULL;
3958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(b->header1)_ogg_free(b->header1);b->header1=NULL;
3968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(b->header2)_ogg_free(b->header2);b->header2=NULL;
3978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* Do we have enough storage space for the requested buffer? If not,
3998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     expand the PCM (and envelope) storage */
4008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v->pcm_current+vals>=v->pcm_storage){
4028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->pcm_storage=v->pcm_current+vals*2;
4038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<vi->channels;i++){
4058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
4068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
4078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
4088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<vi->channels;i++)
4108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->pcmret[i]=v->pcm[i]+v->pcm_current;
4118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(v->pcmret);
4138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
4148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void _preextrapolate_helper(vorbis_dsp_state *v){
4168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
4178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int order=16;
4188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float *lpc=alloca(order*sizeof(*lpc));
4198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float *work=alloca(v->pcm_current*sizeof(*work));
4208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long j;
4218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->preextrapolate=1;
4228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v->pcm_current-v->centerW>order*2){ /* safety */
4248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<v->vi->channels;i++){
4258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* need to run the extrapolation in reverse! */
4268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(j=0;j<v->pcm_current;j++)
4278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        work[j]=v->pcm[i][v->pcm_current-j-1];
4288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* prime as above */
4308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
4318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#if 0
4338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(v->vi->channels==2){
4348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(i==0)
4358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          _analysis_output("predataL",0,work,v->pcm_current-v->centerW,0,0,0);
4368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        else
4378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          _analysis_output("predataR",0,work,v->pcm_current-v->centerW,0,0,0);
4388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }else{
4398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        _analysis_output("predata",0,work,v->pcm_current-v->centerW,0,0,0);
4408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
4418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
4428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* run the predictor filter */
4448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
4458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                         order,
4468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                         work+v->pcm_current-v->centerW,
4478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                         v->centerW);
4488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(j=0;j<v->pcm_current;j++)
4508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        v->pcm[i][v->pcm_current-j-1]=work[j];
4518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
4538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
4548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
4558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* call with val<=0 to set eof */
4588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
4608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info *vi=v->vi;
4618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
4628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(vals<=0){
4648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int order=32;
4658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int i;
4668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    float *lpc=alloca(order*sizeof(*lpc));
4678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* if it wasn't done earlier (very short sample) */
4698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(!v->preextrapolate)
4708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      _preextrapolate_helper(v);
4718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* We're encoding the end of the stream.  Just make sure we have
4738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       [at least] a few full blocks of zeroes at the end. */
4748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* actually, we don't want zeroes; that could drop a large
4758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       amplitude off a cliff, creating spread spectrum noise that will
4768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       suck to encode.  Extrapolate for the sake of cleanliness. */
4778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
4798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->eofflag=v->pcm_current;
4808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->pcm_current+=ci->blocksizes[1]*3;
4818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<vi->channels;i++){
4838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(v->eofflag>order*2){
4848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* extrapolate with LPC to fill in */
4858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        long n;
4868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* make a predictor filter */
4888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        n=v->eofflag;
4898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(n>ci->blocksizes[1])n=ci->blocksizes[1];
4908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
4918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* run the predictor filter */
4938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
4948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                           v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
4958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }else{
4968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* not enough data to extrapolate (unlikely to happen due to
4978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           guarding the overlap, but bulletproof in case that
4988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           assumtion goes away). zeroes will do. */
4998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        memset(v->pcm[i]+v->eofflag,0,
5008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels               (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
5018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
5038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
5048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
5058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(v->pcm_current+vals>v->pcm_storage)
5078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(OV_EINVAL);
5088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->pcm_current+=vals;
5108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* we may want to reverse extrapolate the beginning of a stream
5128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       too... in case we're beginning on a cliff! */
5138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* clumsy, but simple.  It only runs once, so simple is good. */
5148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
5158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      _preextrapolate_helper(v);
5168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
5188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
5198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
5208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* do the deltas, envelope shaping, pre-echo and determine the size of
5228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   the next block on which to continue analysis */
5238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
5248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
5258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info *vi=v->vi;
5268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
5278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  private_state *b=v->backend_state;
5288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_psy_global *g=b->psy_g_look;
5298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
5308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
5318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* check to see if we're started... */
5338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!v->preextrapolate)return(0);
5348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* check to see if we're done... */
5368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v->eofflag==-1)return(0);
5378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* By our invariant, we have lW, W and centerW set.  Search for
5398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     the next boundary so we can determine nW (the next window size)
5408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     which lets us compute the shape of the current block's window */
5418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* we do an envelope search even on a single blocksize; we may still
5438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     be throwing more bits at impulses, and envelope search handles
5448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     marking impulses too. */
5458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
5468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long bp=_ve_envelope_search(v);
5478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(bp==-1){
5488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(v->eofflag==0)return(0); /* not enough data currently to search for a
5508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                     full long block */
5518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->nW=0;
5528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
5538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(ci->blocksizes[0]==ci->blocksizes[1])
5558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        v->nW=0;
5568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      else
5578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        v->nW=bp;
5588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
5598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
5608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
5628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
5648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* center of next block + next block maximum right side. */
5658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long blockbound=centerNext+ci->blocksizes[v->nW]/2;
5678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(v->pcm_current<blockbound)return(0); /* not enough data yet;
5688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                               although this check is
5698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                               less strict that the
5708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                               _ve_envelope_search,
5718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                               the search is not run
5728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                               if we only use one
5738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                               block size */
5748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
5778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* fill in the block.  Note that for a short window, lW and nW are *short*
5798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     regardless of actual settings in the stream */
5808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  _vorbis_block_ripcord(vb);
5828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->lW=v->lW;
5838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->W=v->W;
5848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->nW=v->nW;
5858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v->W){
5878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(!v->lW || !v->nW){
5888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vbi->blocktype=BLOCKTYPE_TRANSITION;
5898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /*fprintf(stderr,"-");*/
5908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
5918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vbi->blocktype=BLOCKTYPE_LONG;
5928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /*fprintf(stderr,"_");*/
5938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
5948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
5958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(_ve_envelope_mark(v)){
5968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vbi->blocktype=BLOCKTYPE_IMPULSE;
5978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /*fprintf(stderr,"|");*/
5988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
6008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vbi->blocktype=BLOCKTYPE_PADDING;
6018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /*fprintf(stderr,".");*/
6028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
6048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
6058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->vd=v;
6078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->sequence=v->sequence++;
6088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->granulepos=v->granulepos;
6098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->pcmend=ci->blocksizes[v->W];
6108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* copy the vectors; this uses the local storage in vb */
6128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* this tracks 'strongest peak' for later psychoacoustics */
6148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* moved to the global psy state; clean this mess up */
6158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
6168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  g->ampmax=_vp_ampmax_decay(g->ampmax,v);
6178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vbi->ampmax=g->ampmax;
6188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
6208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
6218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<vi->channels;i++){
6228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vbi->pcmdelay[i]=
6238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
6248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
6258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->pcm[i]=vbi->pcmdelay[i]+beginW;
6268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* before we added the delay
6288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
6298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
6308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    */
6318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
6338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* handle eof detection: eof==0 means that we've not yet received EOF
6358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                           eof>0  marks the last 'real' sample in pcm[]
6368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                           eof<0  'no more to do'; doesn't get here */
6378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v->eofflag){
6398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(v->centerW>=v->eofflag){
6408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->eofflag=-1;
6418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      vb->eofflag=1;
6428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(1);
6438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
6448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
6458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* advance storage vectors and clean up */
6478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
6488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int new_centerNext=ci->blocksizes[1]/2;
6498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int movementW=centerNext-new_centerNext;
6508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(movementW>0){
6528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      _ve_envelope_shift(b->ve,movementW);
6548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->pcm_current-=movementW;
6558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<vi->channels;i++)
6578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        memmove(v->pcm[i],v->pcm[i]+movementW,
6588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                v->pcm_current*sizeof(*v->pcm[i]));
6598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->lW=v->W;
6628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->W=v->nW;
6638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->centerW=new_centerNext;
6648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(v->eofflag){
6668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        v->eofflag-=movementW;
6678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(v->eofflag<=0)v->eofflag=-1;
6688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* do not add padding to end of stream! */
6698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(v->centerW>=v->eofflag){
6708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          v->granulepos+=movementW-(v->centerW-v->eofflag);
6718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }else{
6728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          v->granulepos+=movementW;
6738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
6748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }else{
6758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        v->granulepos+=movementW;
6768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
6778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
6788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
6798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* done */
6818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(1);
6828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
6838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_synthesis_restart(vorbis_dsp_state *v){
6858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info *vi=v->vi;
6868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci;
6878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int hs;
6888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!v->backend_state)return -1;
6908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!vi)return -1;
6918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ci=vi->codec_setup;
6928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!ci)return -1;
6938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  hs=ci->halfrate_flag;
6948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->centerW=ci->blocksizes[1]>>(hs+1);
6968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->pcm_current=v->centerW>>hs;
6978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->pcm_returned=-1;
6998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->granulepos=-1;
7008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->sequence=-1;
7018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->eofflag=0;
7028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ((private_state *)(v->backend_state))->sample_count=-1;
7038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
7058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
7068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
7088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(_vds_shared_init(v,vi,0)){
7098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_dsp_clear(v);
7108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return 1;
7118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
7128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_synthesis_restart(v);
7138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return 0;
7148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
7158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* Unlike in analysis, the window is only partially applied for each
7178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   block.  The time domain envelope is not yet handled at the point of
7188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   calling (as it relies on the previous block). */
7198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
7218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info *vi=v->vi;
7228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
7238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  private_state *b=v->backend_state;
7248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int hs=ci->halfrate_flag;
7258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,j;
7268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!vb)return(OV_EINVAL);
7288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v->pcm_current>v->pcm_returned  && v->pcm_returned!=-1)return(OV_EINVAL);
7298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->lW=v->W;
7318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->W=vb->W;
7328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->nW=-1;
7338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if((v->sequence==-1)||
7358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     (v->sequence+1 != vb->sequence)){
7368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->granulepos=-1; /* out of sequence; lose count */
7378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    b->sample_count=-1;
7388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
7398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->sequence=vb->sequence;
7418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(vb->pcm){  /* no pcm to process if vorbis_synthesis_trackonly
7438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                   was called on block */
7448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int n=ci->blocksizes[v->W]>>(hs+1);
7458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int n0=ci->blocksizes[0]>>(hs+1);
7468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int n1=ci->blocksizes[1]>>(hs+1);
7478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int thisCenter;
7498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int prevCenter;
7508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->glue_bits+=vb->glue_bits;
7528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->time_bits+=vb->time_bits;
7538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->floor_bits+=vb->floor_bits;
7548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->res_bits+=vb->res_bits;
7558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(v->centerW){
7578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      thisCenter=n1;
7588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      prevCenter=0;
7598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
7608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      thisCenter=0;
7618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      prevCenter=n1;
7628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
7638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* v->pcm is now used like a two-stage double buffer.  We don't want
7658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       to have to constantly shift *or* adjust memory usage.  Don't
7668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       accept a new block until the old is shifted out */
7678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<vi->channels;j++){
7698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* the overlap/add section */
7708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(v->lW){
7718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(v->W){
7728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* large/large */
7738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float *w=_vorbis_window_get(b->window[1]-hs);
7748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float *pcm=v->pcm[j]+prevCenter;
7758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float *p=vb->pcm[j];
7768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          for(i=0;i<n1;i++)
7778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
7788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }else{
7798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* large/small */
7808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float *w=_vorbis_window_get(b->window[0]-hs);
7818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
7828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float *p=vb->pcm[j];
7838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          for(i=0;i<n0;i++)
7848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
7858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
7868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }else{
7878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(v->W){
7888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* small/large */
7898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float *w=_vorbis_window_get(b->window[0]-hs);
7908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float *pcm=v->pcm[j]+prevCenter;
7918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float *p=vb->pcm[j]+n1/2-n0/2;
7928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          for(i=0;i<n0;i++)
7938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
7948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          for(;i<n1/2+n0/2;i++)
7958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            pcm[i]=p[i];
7968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }else{
7978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* small/small */
7988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float *w=_vorbis_window_get(b->window[0]-hs);
7998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float *pcm=v->pcm[j]+prevCenter;
8008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float *p=vb->pcm[j];
8018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          for(i=0;i<n0;i++)
8028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
8038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
8048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
8058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* the copy section */
8078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      {
8088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        float *pcm=v->pcm[j]+thisCenter;
8098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        float *p=vb->pcm[j]+n;
8108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(i=0;i<n;i++)
8118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          pcm[i]=p[i];
8128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
8138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
8148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(v->centerW)
8168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->centerW=0;
8178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    else
8188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->centerW=n1;
8198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* deal with initial packet state; we do this using the explicit
8218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       pcm_returned==-1 flag otherwise we're sensitive to first block
8228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       being short or long */
8238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(v->pcm_returned==-1){
8258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->pcm_returned=thisCenter;
8268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->pcm_current=thisCenter;
8278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
8288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->pcm_returned=prevCenter;
8298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->pcm_current=prevCenter+
8308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ((ci->blocksizes[v->lW]/4+
8318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ci->blocksizes[v->W]/4)>>hs);
8328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
8338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
8358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* track the frame number... This is for convenience, but also
8378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     making sure our last packet doesn't end with added padding.  If
8388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     the last packet is partial, the number of samples we'll have to
8398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     return will be past the vb->granulepos.
8408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     This is not foolproof!  It will be confused if we begin
8428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     decoding at the last page after a seek or hole.  In that case,
8438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     we don't have a starting point to judge where the last frame
8448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     is.  For this reason, vorbisfile will always try to make sure
8458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     it reads the last two marked pages in proper sequence */
8468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(b->sample_count==-1){
8488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    b->sample_count=0;
8498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
8508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
8518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
8528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v->granulepos==-1){
8548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(vb->granulepos!=-1){ /* only set if we have a position to set to */
8558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->granulepos=vb->granulepos;
8578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* is this a short page? */
8598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(b->sample_count>v->granulepos){
8608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* corner case; if this is both the first and last audio page,
8618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           then spec says the end is cut, not beginning */
8628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(vb->eofflag){
8638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* trim the end */
8648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* no preceeding granulepos; assume we started at zero (we'd
8658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels             have to in a short single-page stream) */
8668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* granulepos could be -1 due to a seek, but that would result
8678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels             in a long count, not short count */
8688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
8708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }else{
8718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* trim the beginning */
8728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
8738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(v->pcm_returned>v->pcm_current)
8748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            v->pcm_returned=v->pcm_current;
8758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
8768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
8788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
8808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
8818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
8828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
8838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(v->granulepos>vb->granulepos){
8858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        long extra=v->granulepos-vb->granulepos;
8868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(extra)
8888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(vb->eofflag){
8898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            /* partial last frame.  Strip the extra samples off */
8908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            v->pcm_current-=extra>>hs;
8918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          } /* else {Shouldn't happen *unless* the bitstream is out of
8928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels               spec.  Either way, believe the bitstream } */
8938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      } /* else {Shouldn't happen *unless* the bitstream is out of
8948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           spec.  Either way, believe the bitstream } */
8958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->granulepos=vb->granulepos;
8968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
8978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
8988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* Update, cleanup */
9008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(vb->eofflag)v->eofflag=1;
9028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
9038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
9058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* pcm==NULL indicates we just want the pending samples, no more */
9078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
9088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info *vi=v->vi;
9098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
9118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(pcm){
9128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int i;
9138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<vi->channels;i++)
9148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        v->pcmret[i]=v->pcm[i]+v->pcm_returned;
9158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      *pcm=v->pcmret;
9168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
9178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(v->pcm_current-v->pcm_returned);
9188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
9198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
9208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
9218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_synthesis_read(vorbis_dsp_state *v,int n){
9238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
9248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  v->pcm_returned+=n;
9258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
9268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
9278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* intended for use with a specific vorbisfile feature; we want access
9298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   to the [usually synthetic/postextrapolated] buffer and lapping at
9308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   the end of a decode cycle, specifically, a half-short-block worth.
9318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   This funtion works like pcmout above, except it will also expose
9328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   this implicit buffer data not normally decoded. */
9338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
9348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info *vi=v->vi;
9358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
9368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int hs=ci->halfrate_flag;
9378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int n=ci->blocksizes[v->W]>>(hs+1);
9398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int n0=ci->blocksizes[0]>>(hs+1);
9408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int n1=ci->blocksizes[1]>>(hs+1);
9418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,j;
9428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v->pcm_returned<0)return 0;
9448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* our returned data ends at pcm_returned; because the synthesis pcm
9468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     buffer is a two-fragment ring, that means our data block may be
9478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     fragmented by buffering, wrapping or a short block not filling
9488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     out a buffer.  To simplify things, we unfragment if it's at all
9498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     possibly needed. Otherwise, we'd need to call lapout more than
9508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     once as well as hold additional dsp state.  Opt for
9518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     simplicity. */
9528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* centerW was advanced by blockin; it would be the center of the
9548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     *next* block */
9558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v->centerW==n1){
9568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* the data buffer wraps; swap the halves */
9578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* slow, sure, small */
9588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<vi->channels;j++){
9598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      float *p=v->pcm[j];
9608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<n1;i++){
9618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        float temp=p[i];
9628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        p[i]=p[i+n1];
9638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        p[i+n1]=temp;
9648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
9658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
9668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->pcm_current-=n1;
9688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->pcm_returned-=n1;
9698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->centerW=0;
9708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
9718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* solidify buffer into contiguous space */
9738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if((v->lW^v->W)==1){
9748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* long/short or short/long */
9758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<vi->channels;j++){
9768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      float *s=v->pcm[j];
9778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      float *d=v->pcm[j]+(n1-n0)/2;
9788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=(n1+n0)/2-1;i>=0;--i)
9798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        d[i]=s[i];
9808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
9818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->pcm_returned+=(n1-n0)/2;
9828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v->pcm_current+=(n1-n0)/2;
9838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
9848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(v->lW==0){
9858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* short/short */
9868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(j=0;j<vi->channels;j++){
9878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        float *s=v->pcm[j];
9888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        float *d=v->pcm[j]+n1-n0;
9898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(i=n0-1;i>=0;--i)
9908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          d[i]=s[i];
9918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
9928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->pcm_returned+=n1-n0;
9938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->pcm_current+=n1-n0;
9948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
9958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
9968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(pcm){
9988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int i;
9998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<vi->channels;i++)
10008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v->pcmret[i]=v->pcm[i]+v->pcm_returned;
10018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    *pcm=v->pcmret;
10028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
10038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(n1+n-v->pcm_returned);
10058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
10078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat *vorbis_window(vorbis_dsp_state *v,int W){
10098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info *vi=v->vi;
10108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vi->codec_setup;
10118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int hs=ci->halfrate_flag;
10128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  private_state *b=v->backend_state;
10138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(b->window[W]-1<0)return NULL;
10158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return _vorbis_window_get(b->window[W]-hs);
10168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1017