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