Home | History | Annotate | Download | only in lib
      1 /********************************************************************
      2  *                                                                  *
      3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
      4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
      5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
      6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
      7  *                                                                  *
      8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
      9  * by the Xiph.Org Foundation http://www.xiph.org/                  *
     10  *                                                                  *
     11  ********************************************************************
     12 
     13  function: single-block PCM synthesis
     14  last mod: $Id: synthesis.c 17027 2010-03-25 05:21:20Z xiphmont $
     15 
     16  ********************************************************************/
     17 
     18 #include <stdio.h>
     19 #include <ogg/ogg.h>
     20 #include "vorbis/codec.h"
     21 #include "codec_internal.h"
     22 #include "registry.h"
     23 #include "misc.h"
     24 #include "os.h"
     25 
     26 int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
     27   vorbis_dsp_state     *vd= vb ? vb->vd : 0;
     28   private_state        *b= vd ? vd->backend_state : 0;
     29   vorbis_info          *vi= vd ? vd->vi : 0;
     30   codec_setup_info     *ci= vi ? vi->codec_setup : 0;
     31   oggpack_buffer       *opb=vb ? &vb->opb : 0;
     32   int                   type,mode,i;
     33 
     34   if (!vd || !b || !vi || !ci || !opb) {
     35     return OV_EBADPACKET;
     36   }
     37 
     38   /* first things first.  Make sure decode is ready */
     39   _vorbis_block_ripcord(vb);
     40   oggpack_readinit(opb,op->packet,op->bytes);
     41 
     42   /* Check the packet type */
     43   if(oggpack_read(opb,1)!=0){
     44     /* Oops.  This is not an audio data packet */
     45     return(OV_ENOTAUDIO);
     46   }
     47 
     48   /* read our mode and pre/post windowsize */
     49   mode=oggpack_read(opb,b->modebits);
     50   if(mode==-1){
     51     return(OV_EBADPACKET);
     52   }
     53 
     54   vb->mode=mode;
     55   if(!ci->mode_param[mode]){
     56     return(OV_EBADPACKET);
     57   }
     58 
     59   vb->W=ci->mode_param[mode]->blockflag;
     60   if(vb->W){
     61 
     62     /* this doesn;t get mapped through mode selection as it's used
     63        only for window selection */
     64     vb->lW=oggpack_read(opb,1);
     65     vb->nW=oggpack_read(opb,1);
     66     if(vb->nW==-1){
     67       return(OV_EBADPACKET);
     68     }
     69   }else{
     70     vb->lW=0;
     71     vb->nW=0;
     72   }
     73 
     74   /* more setup */
     75   vb->granulepos=op->granulepos;
     76   vb->sequence=op->packetno;
     77   vb->eofflag=op->e_o_s;
     78 
     79   /* alloc pcm passback storage */
     80   vb->pcmend=ci->blocksizes[vb->W];
     81   vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
     82   for(i=0;i<vi->channels;i++)
     83     vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
     84 
     85   /* unpack_header enforces range checking */
     86   type=ci->map_type[ci->mode_param[mode]->mapping];
     87 
     88   return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]->
     89                                                    mapping]));
     90 }
     91 
     92 /* used to track pcm position without actually performing decode.
     93    Useful for sequential 'fast forward' */
     94 int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){
     95   vorbis_dsp_state     *vd=vb->vd;
     96   private_state        *b=vd->backend_state;
     97   vorbis_info          *vi=vd->vi;
     98   codec_setup_info     *ci=vi->codec_setup;
     99   oggpack_buffer       *opb=&vb->opb;
    100   int                   mode;
    101 
    102   /* first things first.  Make sure decode is ready */
    103   _vorbis_block_ripcord(vb);
    104   oggpack_readinit(opb,op->packet,op->bytes);
    105 
    106   /* Check the packet type */
    107   if(oggpack_read(opb,1)!=0){
    108     /* Oops.  This is not an audio data packet */
    109     return(OV_ENOTAUDIO);
    110   }
    111 
    112   /* read our mode and pre/post windowsize */
    113   mode=oggpack_read(opb,b->modebits);
    114   if(mode==-1)return(OV_EBADPACKET);
    115 
    116   vb->mode=mode;
    117   vb->W=ci->mode_param[mode]->blockflag;
    118   if(vb->W){
    119     vb->lW=oggpack_read(opb,1);
    120     vb->nW=oggpack_read(opb,1);
    121     if(vb->nW==-1)   return(OV_EBADPACKET);
    122   }else{
    123     vb->lW=0;
    124     vb->nW=0;
    125   }
    126 
    127   /* more setup */
    128   vb->granulepos=op->granulepos;
    129   vb->sequence=op->packetno;
    130   vb->eofflag=op->e_o_s;
    131 
    132   /* no pcm */
    133   vb->pcmend=0;
    134   vb->pcm=NULL;
    135 
    136   return(0);
    137 }
    138 
    139 long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
    140   codec_setup_info     *ci=vi->codec_setup;
    141   oggpack_buffer       opb;
    142   int                  mode;
    143 
    144   oggpack_readinit(&opb,op->packet,op->bytes);
    145 
    146   /* Check the packet type */
    147   if(oggpack_read(&opb,1)!=0){
    148     /* Oops.  This is not an audio data packet */
    149     return(OV_ENOTAUDIO);
    150   }
    151 
    152   {
    153     int modebits=0;
    154     int v=ci->modes;
    155     while(v>1){
    156       modebits++;
    157       v>>=1;
    158     }
    159 
    160     /* read our mode and pre/post windowsize */
    161     mode=oggpack_read(&opb,modebits);
    162   }
    163   if(mode==-1)return(OV_EBADPACKET);
    164   return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
    165 }
    166 
    167 int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){
    168   /* set / clear half-sample-rate mode */
    169   codec_setup_info     *ci=vi->codec_setup;
    170 
    171   /* right now, our MDCT can't handle < 64 sample windows. */
    172   if(ci->blocksizes[0]<=64 && flag)return -1;
    173   ci->halfrate_flag=(flag?1:0);
    174   return 0;
    175 }
    176 
    177 int vorbis_synthesis_halfrate_p(vorbis_info *vi){
    178   codec_setup_info     *ci=vi->codec_setup;
    179   return ci->halfrate_flag;
    180 }
    181