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