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