synthesis.c (4916B)
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-2002 * 9 * by the XIPHOPHORUS Company http://www.xiph.org/ * 10 * * 11 ******************************************************************** 12 13 function: single-block PCM synthesis 14 last mod: $Id: synthesis.c 1919 2005-07-24 14:18:04Z baford $ 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->vd; 28 private_state *b=vd->backend_state; 29 vorbis_info *vi=vd->vi; 30 codec_setup_info *ci=vi->codec_setup; 31 oggpack_buffer *opb=&vb->opb; 32 int type,mode,i; 33 34 /* first things first. Make sure decode is ready */ 35 _vorbis_block_ripcord(vb); 36 oggpack_readinit(opb,op->packet,op->bytes); 37 38 /* Check the packet type */ 39 if(oggpack_read(opb,1)!=0){ 40 /* Oops. This is not an audio data packet */ 41 return(OV_ENOTAUDIO); 42 } 43 44 /* read our mode and pre/post windowsize */ 45 mode=oggpack_read(opb,b->modebits); 46 if(mode==-1)return(OV_EBADPACKET); 47 48 vb->mode=mode; 49 vb->W=ci->mode_param[mode]->blockflag; 50 if(vb->W){ 51 52 /* this doesn;t get mapped through mode selection as it's used 53 only for window selection */ 54 vb->lW=oggpack_read(opb,1); 55 vb->nW=oggpack_read(opb,1); 56 if(vb->nW==-1) return(OV_EBADPACKET); 57 }else{ 58 vb->lW=0; 59 vb->nW=0; 60 } 61 62 /* more setup */ 63 vb->granulepos=op->granulepos; 64 vb->sequence=op->packetno; 65 vb->eofflag=op->e_o_s; 66 67 /* alloc pcm passback storage */ 68 vb->pcmend=ci->blocksizes[vb->W]; 69 vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels); 70 for(i=0;i<vi->channels;i++) 71 vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); 72 73 /* unpack_header enforces range checking */ 74 type=ci->map_type[ci->mode_param[mode]->mapping]; 75 76 return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]-> 77 mapping])); 78 } 79 80 /* used to track pcm position without actually performing decode. 81 Useful for sequential 'fast forward' */ 82 int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){ 83 vorbis_dsp_state *vd=vb->vd; 84 private_state *b=vd->backend_state; 85 vorbis_info *vi=vd->vi; 86 codec_setup_info *ci=vi->codec_setup; 87 oggpack_buffer *opb=&vb->opb; 88 int mode; 89 90 /* first things first. Make sure decode is ready */ 91 _vorbis_block_ripcord(vb); 92 oggpack_readinit(opb,op->packet,op->bytes); 93 94 /* Check the packet type */ 95 if(oggpack_read(opb,1)!=0){ 96 /* Oops. This is not an audio data packet */ 97 return(OV_ENOTAUDIO); 98 } 99 100 /* read our mode and pre/post windowsize */ 101 mode=oggpack_read(opb,b->modebits); 102 if(mode==-1)return(OV_EBADPACKET); 103 104 vb->mode=mode; 105 vb->W=ci->mode_param[mode]->blockflag; 106 if(vb->W){ 107 vb->lW=oggpack_read(opb,1); 108 vb->nW=oggpack_read(opb,1); 109 if(vb->nW==-1) return(OV_EBADPACKET); 110 }else{ 111 vb->lW=0; 112 vb->nW=0; 113 } 114 115 /* more setup */ 116 vb->granulepos=op->granulepos; 117 vb->sequence=op->packetno; 118 vb->eofflag=op->e_o_s; 119 120 /* no pcm */ 121 vb->pcmend=0; 122 vb->pcm=NULL; 123 124 return(0); 125 } 126 127 long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ 128 codec_setup_info *ci=vi->codec_setup; 129 oggpack_buffer opb; 130 int mode; 131 132 oggpack_readinit(&opb,op->packet,op->bytes); 133 134 /* Check the packet type */ 135 if(oggpack_read(&opb,1)!=0){ 136 /* Oops. This is not an audio data packet */ 137 return(OV_ENOTAUDIO); 138 } 139 140 { 141 int modebits=0; 142 int v=ci->modes; 143 while(v>1){ 144 modebits++; 145 v>>=1; 146 } 147 148 /* read our mode and pre/post windowsize */ 149 mode=oggpack_read(&opb,modebits); 150 } 151 if(mode==-1)return(OV_EBADPACKET); 152 return(ci->blocksizes[ci->mode_param[mode]->blockflag]); 153 } 154 155 int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){ 156 /* set / clear half-sample-rate mode */ 157 codec_setup_info *ci=vi->codec_setup; 158 159 /* right now, our MDCT can't handle < 64 sample windows. */ 160 if(ci->blocksizes[0]<=64 && flag)return -1; 161 ci->halfrate_flag=(flag?1:0); 162 return 0; 163 } 164 165 int vorbis_synthesis_halfrate_p(vorbis_info *vi){ 166 codec_setup_info *ci=vi->codec_setup; 167 return ci->halfrate_flag; 168 } 169 170