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: floor backend 0 implementation
148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels last mod: $Id: floor0.c 16227 2009-07-08 06:58:46Z xiphmont $
158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************/
178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdlib.h>
198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <string.h>
208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <math.h>
218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <ogg/ogg.h>
228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "vorbis/codec.h"
238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "codec_internal.h"
248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "registry.h"
258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "lpc.h"
268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "lsp.h"
278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "codebook.h"
288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "scales.h"
298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "misc.h"
308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "os.h"
318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "misc.h"
338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdio.h>
348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct {
368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ln;
378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int  m;
388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int **linearmap;
398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int  n[2];
408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor0 *vi;
428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long bits;
448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long frames;
458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} vorbis_look_floor0;
468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/***********************************************/
498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void floor0_free_info(vorbis_info_floor *i){
518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(info){
538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memset(info,0,sizeof(*info));
548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    _ogg_free(info);
558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void floor0_free_look(vorbis_look_floor *i){
598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(look){
618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(look->linearmap){
638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(look->linearmap[0])_ogg_free(look->linearmap[0]);
658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(look->linearmap[1])_ogg_free(look->linearmap[1]);
668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      _ogg_free(look->linearmap);
688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memset(look,0,sizeof(*look));
708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    _ogg_free(look);
718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info     *ci=vi->codec_setup;
768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int j;
778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info));
798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->order=oggpack_read(opb,8);
808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->rate=oggpack_read(opb,16);
818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->barkmap=oggpack_read(opb,16);
828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->ampbits=oggpack_read(opb,6);
838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->ampdB=oggpack_read(opb,8);
848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->numbooks=oggpack_read(opb,4)+1;
858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(info->order<1)goto err_out;
878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(info->rate<1)goto err_out;
888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(info->barkmap<1)goto err_out;
898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(info->numbooks<1)goto err_out;
908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<info->numbooks;j++){
928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    info->books[j]=oggpack_read(opb,8);
938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(info);
968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels err_out:
988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  floor0_free_info(info);
998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(NULL);
1008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* initialize Bark scale and normalization lookups.  We could do this
1038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   with static tables, but Vorbis allows a number of possible
1048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   combinations, so it's best to do it computationally.
1058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   The below is authoritative in terms of defining scale mapping.
1078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   Note that the scale depends on the sampling rate as well as the
1088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   linear block and mapping sizes */
1098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void floor0_map_lazy_init(vorbis_block      *vb,
1118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                 vorbis_info_floor *infoX,
1128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                 vorbis_look_floor0 *look){
1138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!look->linearmap[vb->W]){
1148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_dsp_state   *vd=vb->vd;
1158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_info        *vi=vd->vi;
1168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    codec_setup_info   *ci=vi->codec_setup;
1178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX;
1188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int W=vb->W;
1198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int n=ci->blocksizes[W]/2,j;
1208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* we choose a scaling constant so that:
1228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       floor(bark(rate/2-1)*C)=mapped-1
1238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     floor(bark(rate/2)*C)=mapped */
1248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    float scale=look->ln/toBARK(info->rate/2.f);
1258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* the mapping from a linear scale to a smaller bark scale is
1278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       straightforward.  We do *not* make sure that the linear mapping
1288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       does not skip bark-scale bins; the decoder simply skips them and
1298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       the encoder may do what it wishes in filling them.  They're
1308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       necessary in some mapping combinations to keep the scale spacing
1318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       accurate */
1328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap));
1338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<n;j++){
1348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int val=floor( toBARK((info->rate/2.f)/n*j)
1358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                     *scale); /* bark numbers represent band edges */
1368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
1378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      look->linearmap[W][j]=val;
1388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->linearmap[W][j]=-1;
1408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->n[W]=n;
1418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
1458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                      vorbis_info_floor *i){
1468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
1478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look));
1488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->m=info->order;
1498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->ln=info->barkmap;
1508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->vi=info;
1518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap));
1538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return look;
1558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
1588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
1598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor0 *info=look->vi;
1608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int j,k;
1618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ampraw=oggpack_read(&vb->opb,info->ampbits);
1638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ampraw>0){ /* also handles the -1 out of data case */
1648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long maxval=(1<<info->ampbits)-1;
1658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    float amp=(float)ampraw/maxval*info->ampdB;
1668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
1678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
1698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      codec_setup_info  *ci=vb->vd->vi->codec_setup;
1708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      codebook *b=ci->fullbooks+info->books[booknum];
1718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      float last=0.f;
1728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* the additional b->dim is a guard against any possible stack
1748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels         smash; b->dim is provably more than we can overflow the
1758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels         vector */
1768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1));
1778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(j=0;j<look->m;j+=b->dim)
1798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim)==-1)goto eop;
1808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(j=0;j<look->m;){
1818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
1828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        last=lsp[j-1];
1838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
1848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      lsp[look->m]=amp;
1868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(lsp);
1878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels eop:
1908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(NULL);
1918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
1948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                           void *memo,float *out){
1958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
1968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor0 *info=look->vi;
1978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  floor0_map_lazy_init(vb,info,look);
1998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(memo){
2018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    float *lsp=(float *)memo;
2028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    float amp=lsp[look->m];
2038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* take the coefficients back to a spectral envelope curve */
2058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_lsp_to_curve(out,
2068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                        look->linearmap[vb->W],
2078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                        look->n[vb->W],
2088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                        look->ln,
2098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                        lsp,look->m,amp,(float)info->ampdB);
2108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(1);
2118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memset(out,0,sizeof(*out)*look->n[vb->W]);
2138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
2148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* export hooks */
2178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsconst vorbis_func_floor floor0_exportbundle={
2188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  NULL,&floor0_unpack,&floor0_look,&floor0_free_info,
2198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &floor0_free_look,&floor0_inverse1,&floor0_inverse2
2208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
221