diff options
Diffstat (limited to 'thirdparty/libvorbis/synthesis.c')
| -rw-r--r-- | thirdparty/libvorbis/synthesis.c | 180 | 
1 files changed, 180 insertions, 0 deletions
diff --git a/thirdparty/libvorbis/synthesis.c b/thirdparty/libvorbis/synthesis.c new file mode 100644 index 0000000000..932d271a63 --- /dev/null +++ b/thirdparty/libvorbis/synthesis.c @@ -0,0 +1,180 @@ +/******************************************************************** + *                                                                  * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       * + *                                                                  * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015             * + * by the Xiph.Org Foundation http://www.xiph.org/                  * + *                                                                  * + ******************************************************************** + + function: single-block PCM synthesis + last mod: $Id: synthesis.c 19441 2015-01-21 01:17:41Z xiphmont $ + + ********************************************************************/ + +#include <stdio.h> +#include <ogg/ogg.h> +#include "vorbis/codec.h" +#include "codec_internal.h" +#include "registry.h" +#include "misc.h" +#include "os.h" + +int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){ +  vorbis_dsp_state     *vd= vb ? vb->vd : 0; +  private_state        *b= vd ? vd->backend_state : 0; +  vorbis_info          *vi= vd ? vd->vi : 0; +  codec_setup_info     *ci= vi ? vi->codec_setup : 0; +  oggpack_buffer       *opb=vb ? &vb->opb : 0; +  int                   type,mode,i; + +  if (!vd || !b || !vi || !ci || !opb) { +    return OV_EBADPACKET; +  } + +  /* first things first.  Make sure decode is ready */ +  _vorbis_block_ripcord(vb); +  oggpack_readinit(opb,op->packet,op->bytes); + +  /* Check the packet type */ +  if(oggpack_read(opb,1)!=0){ +    /* Oops.  This is not an audio data packet */ +    return(OV_ENOTAUDIO); +  } + +  /* read our mode and pre/post windowsize */ +  mode=oggpack_read(opb,b->modebits); +  if(mode==-1){ +    return(OV_EBADPACKET); +  } + +  vb->mode=mode; +  if(!ci->mode_param[mode]){ +    return(OV_EBADPACKET); +  } + +  vb->W=ci->mode_param[mode]->blockflag; +  if(vb->W){ + +    /* this doesn;t get mapped through mode selection as it's used +       only for window selection */ +    vb->lW=oggpack_read(opb,1); +    vb->nW=oggpack_read(opb,1); +    if(vb->nW==-1){ +      return(OV_EBADPACKET); +    } +  }else{ +    vb->lW=0; +    vb->nW=0; +  } + +  /* more setup */ +  vb->granulepos=op->granulepos; +  vb->sequence=op->packetno; +  vb->eofflag=op->e_o_s; + +  /* alloc pcm passback storage */ +  vb->pcmend=ci->blocksizes[vb->W]; +  vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels); +  for(i=0;i<vi->channels;i++) +    vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); + +  /* unpack_header enforces range checking */ +  type=ci->map_type[ci->mode_param[mode]->mapping]; + +  return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]-> +                                                   mapping])); +} + +/* used to track pcm position without actually performing decode. +   Useful for sequential 'fast forward' */ +int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){ +  vorbis_dsp_state     *vd=vb->vd; +  private_state        *b=vd->backend_state; +  vorbis_info          *vi=vd->vi; +  codec_setup_info     *ci=vi->codec_setup; +  oggpack_buffer       *opb=&vb->opb; +  int                   mode; + +  /* first things first.  Make sure decode is ready */ +  _vorbis_block_ripcord(vb); +  oggpack_readinit(opb,op->packet,op->bytes); + +  /* Check the packet type */ +  if(oggpack_read(opb,1)!=0){ +    /* Oops.  This is not an audio data packet */ +    return(OV_ENOTAUDIO); +  } + +  /* read our mode and pre/post windowsize */ +  mode=oggpack_read(opb,b->modebits); +  if(mode==-1)return(OV_EBADPACKET); + +  vb->mode=mode; +  if(!ci->mode_param[mode]){ +    return(OV_EBADPACKET); +  } +   +  vb->W=ci->mode_param[mode]->blockflag; +  if(vb->W){ +    vb->lW=oggpack_read(opb,1); +    vb->nW=oggpack_read(opb,1); +    if(vb->nW==-1)   return(OV_EBADPACKET); +  }else{ +    vb->lW=0; +    vb->nW=0; +  } + +  /* more setup */ +  vb->granulepos=op->granulepos; +  vb->sequence=op->packetno; +  vb->eofflag=op->e_o_s; + +  /* no pcm */ +  vb->pcmend=0; +  vb->pcm=NULL; + +  return(0); +} + +long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ +  codec_setup_info     *ci=vi->codec_setup; +  oggpack_buffer       opb; +  int                  mode; + +  if(ci==NULL || ci->modes<=0){ +    /* codec setup not properly intialized */ +    return(OV_EFAULT); +  } + +  oggpack_readinit(&opb,op->packet,op->bytes); + +  /* Check the packet type */ +  if(oggpack_read(&opb,1)!=0){ +    /* Oops.  This is not an audio data packet */ +    return(OV_ENOTAUDIO); +  } + +  /* read our mode and pre/post windowsize */ +  mode=oggpack_read(&opb,ov_ilog(ci->modes-1)); +  if(mode==-1 || !ci->mode_param[mode])return(OV_EBADPACKET); +  return(ci->blocksizes[ci->mode_param[mode]->blockflag]); +} + +int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){ +  /* set / clear half-sample-rate mode */ +  codec_setup_info     *ci=vi->codec_setup; + +  /* right now, our MDCT can't handle < 64 sample windows. */ +  if(ci->blocksizes[0]<=64 && flag)return -1; +  ci->halfrate_flag=(flag?1:0); +  return 0; +} + +int vorbis_synthesis_halfrate_p(vorbis_info *vi){ +  codec_setup_info     *ci=vi->codec_setup; +  return ci->halfrate_flag; +}  |