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: single-block PCM synthesis
148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels last mod: $Id: synthesis.c 17027 2010-03-25 05:21:20Z xiphmont $
158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************/
178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdio.h>
198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <ogg/ogg.h>
208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "vorbis/codec.h"
218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "codec_internal.h"
228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "registry.h"
238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "misc.h"
248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "os.h"
258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_dsp_state     *vd= vb ? vb->vd : 0;
288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  private_state        *b= vd ? vd->backend_state : 0;
298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info          *vi= vd ? vd->vi : 0;
308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info     *ci= vi ? vi->codec_setup : 0;
318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_buffer       *opb=vb ? &vb->opb : 0;
328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int                   type,mode,i;
338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if (!vd || !b || !vi || !ci || !opb) {
358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return OV_EBADPACKET;
368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* first things first.  Make sure decode is ready */
398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  _vorbis_block_ripcord(vb);
408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_readinit(opb,op->packet,op->bytes);
418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* Check the packet type */
438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(oggpack_read(opb,1)!=0){
448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* Oops.  This is not an audio data packet */
458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(OV_ENOTAUDIO);
468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* read our mode and pre/post windowsize */
498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  mode=oggpack_read(opb,b->modebits);
508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(mode==-1){
518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(OV_EBADPACKET);
528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->mode=mode;
558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(!ci->mode_param[mode]){
568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(OV_EBADPACKET);
578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->W=ci->mode_param[mode]->blockflag;
608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(vb->W){
618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* this doesn;t get mapped through mode selection as it's used
638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       only for window selection */
648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->lW=oggpack_read(opb,1);
658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->nW=oggpack_read(opb,1);
668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(vb->nW==-1){
678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(OV_EBADPACKET);
688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->lW=0;
718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->nW=0;
728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* more setup */
758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->granulepos=op->granulepos;
768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->sequence=op->packetno;
778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->eofflag=op->e_o_s;
788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* alloc pcm passback storage */
808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->pcmend=ci->blocksizes[vb->W];
818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<vi->channels;i++)
838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* unpack_header enforces range checking */
868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  type=ci->map_type[ci->mode_param[mode]->mapping];
878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]->
898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                                   mapping]));
908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* used to track pcm position without actually performing decode.
938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   Useful for sequential 'fast forward' */
948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){
958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_dsp_state     *vd=vb->vd;
968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  private_state        *b=vd->backend_state;
978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info          *vi=vd->vi;
988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info     *ci=vi->codec_setup;
998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_buffer       *opb=&vb->opb;
1008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int                   mode;
1018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* first things first.  Make sure decode is ready */
1038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  _vorbis_block_ripcord(vb);
1048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_readinit(opb,op->packet,op->bytes);
1058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* Check the packet type */
1078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(oggpack_read(opb,1)!=0){
1088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* Oops.  This is not an audio data packet */
1098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(OV_ENOTAUDIO);
1108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* read our mode and pre/post windowsize */
1138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  mode=oggpack_read(opb,b->modebits);
1148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(mode==-1)return(OV_EBADPACKET);
1158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->mode=mode;
1178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->W=ci->mode_param[mode]->blockflag;
1188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(vb->W){
1198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->lW=oggpack_read(opb,1);
1208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->nW=oggpack_read(opb,1);
1218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(vb->nW==-1)   return(OV_EBADPACKET);
1228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
1238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->lW=0;
1248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vb->nW=0;
1258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* more setup */
1288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->granulepos=op->granulepos;
1298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->sequence=op->packetno;
1308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->eofflag=op->e_o_s;
1318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* no pcm */
1338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->pcmend=0;
1348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vb->pcm=NULL;
1358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
1378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelslong vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
1408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info     *ci=vi->codec_setup;
1418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_buffer       opb;
1428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int                  mode;
1438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_readinit(&opb,op->packet,op->bytes);
1458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* Check the packet type */
1478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(oggpack_read(&opb,1)!=0){
1488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* Oops.  This is not an audio data packet */
1498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(OV_ENOTAUDIO);
1508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
1538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int modebits=0;
1548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int v=ci->modes;
1558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    while(v>1){
1568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      modebits++;
1578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      v>>=1;
1588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* read our mode and pre/post windowsize */
1618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    mode=oggpack_read(&opb,modebits);
1628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(mode==-1)return(OV_EBADPACKET);
1648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
1658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_synthesis_halfrate(vorbis_info *vi,int flag){
1688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* set / clear half-sample-rate mode */
1698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info     *ci=vi->codec_setup;
1708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* right now, our MDCT can't handle < 64 sample windows. */
1728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(ci->blocksizes[0]<=64 && flag)return -1;
1738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ci->halfrate_flag=(flag?1:0);
1748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return 0;
1758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint vorbis_synthesis_halfrate_p(vorbis_info *vi){
1788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info     *ci=vi->codec_setup;
1798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return ci->halfrate_flag;
1808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
181