1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *
9 * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: simple example decoder
15 author: Monty <xiphmont@mit.edu>
16 modifications by: Monty
17 last modification date: Oct 04 1999
19 ********************************************************************/
21 /* Takes a vorbis bitstream from stdin and writes raw stereo PCM to
28 int16_t convbuffer[4096]; /* take 8k out of the data segment, not the stack */
32 ogg_sync_state oy; /* sync and verify incoming physical bitstream */
33 ogg_stream_state os; /* take physical pages, weld into a logical
35 ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
36 ogg_packet op; /* one raw packet of data for decode */
38 vorbis_info vi; /* struct that stores all the static vorbis bitstream
40 vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
41 vorbis_block vb; /* local working space for packet->PCM decode */
48 /********** Decode setup ************/
50 ogg_sync_init(&oy); /* Now we can read pages */
52 /* grab some data at the head of the stream. We want the first page
53 (which is guaranteed to be small and only contain the Vorbis
54 stream initial header) We need the first page to get the stream
57 /* submit a 4k block to libvorbis */
58 buffer=ogg_sync_buffer(&oy,4096);
59 bytes=fread(buffer,1,4096,stdin);
60 ogg_sync_wrote(&oy,bytes);
62 /* Get the first page. */
63 if(ogg_sync_pageout(&oy,&og)!=1){
64 /* error case. Must not be Vorbis data */
65 fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n");
69 /* Get the serial number and set up the rest of decode. */
70 /* serialno first; use it to set up a logical stream */
71 ogg_stream_init(&os,ogg_page_serialno(&og));
73 /* extract the initial header from the first page and verify that the
74 Ogg bitstream is in fact Vorbis data */
76 /* I handle the initial header first instead of just having the code
77 read all three Vorbis headers at once because reading the initial
78 header is an easy way to identify a Vorbis bitstream and it's
79 useful to see that functionality seperated out. */
81 vorbis_info_init(&vi);
82 if(ogg_stream_pagein(&os,&og)<0){
83 /* error; stream version mismatch perhaps */
84 fprintf(stderr,"Error reading first page of Ogg bitstream data.\n");
88 if(ogg_stream_packetout(&os,&op)!=1){
89 /* no page? must not be vorbis */
90 fprintf(stderr,"Error reading initial header packet.\n");
94 if(vorbis_info_headerin(&vi,&op)<0){
95 /* error case; not a vorbis header */
96 fprintf(stderr,"This Ogg bitstream does not contain Vorbis audio data.\n");
100 /* At this point, we're sure we're Vorbis. We've set up the logical
101 (Ogg) bitstream decoder. Get the comment and codebook headers and
102 set up the Vorbis decoder */
104 /* The next two packets in order are the comment and codebook headers.
105 They're likely large and may span multiple pages. Thus we reead
106 and submit data until we get our two pacakets, watching that no
107 pages are missing. If a page is missing, error out; losing a
108 header page is the only place where missing data is fatal. */
113 int result=ogg_sync_pageout(&oy,&og);
114 if(result==0)break; /* Need more data */
115 /* Don't complain about missing or corrupt data yet. We'll
116 catch it at the packet output phase */
118 ogg_stream_pagein(&os,&og); /* we can ignore any errors here
119 as they'll also become apparent
122 result=ogg_stream_packetout(&os,&op);
125 /* Uh oh; data at some point was corrupted or missing!
126 We can't tolerate that in a header. Die. */
127 fprintf(stderr,"Corrupt secondary header. Exiting.\n");
130 vorbis_info_headerin(&vi,&op);
135 /* no harm in not checking before adding more */
136 buffer=ogg_sync_buffer(&oy,4096);
137 bytes=fread(buffer,1,4096,stdin);
139 fprintf(stderr,"End of file before finding all Vorbis headers!\n");
142 ogg_sync_wrote(&oy,bytes);
145 /* Throw the comments plus a few lines about the bitstream we're
148 char **ptr=vi.user_comments;
150 fprintf(stderr,"%s\n",*ptr);
153 fprintf(stderr,"\nBitstream is %d channel, %dHz\n",vi.channels,vi.rate);
154 fprintf(stderr,"Encoded by: %s\n\n",vi.vendor);
157 convsize=4096/vi.channels;
159 /* OK, got and parsed all three headers. Initialize the Vorbis
160 packet->PCM decoder. */
161 vorbis_synthesis_init(&vd,&vi); /* central decode state */
162 vorbis_block_init(&vd,&vb); /* local state for most of the decode
163 so multiple block decodes can
164 proceed in parallel. We could init
165 multiple vorbis_block structures
168 /* The rest is just a straight decode loop until end of stream */
171 int result=ogg_sync_pageout(&oy,&og);
172 if(result==0)break; /* need more data */
173 if(result==-1){ /* missing or corrupt data at this page position */
174 fprintf(stderr,"Corrupt or missing data in bitstream; "
177 ogg_stream_pagein(&os,&og); /* can safely ignore errors at
180 result=ogg_stream_packetout(&os,&op);
181 if(result==0)break; /* need more data */
182 if(result==-1){ /* missing or corrupt data at this page position */
183 /* no reason to complain; already complained above */
185 /* we have a packet. Decode it */
189 vorbis_synthesis(&vb,&op);
190 vorbis_synthesis_blockin(&vd,&vb);
193 **pcm is a multichannel double vector. In stereo, for
194 example, pcm[0] is left, and pcm[1] is right. samples is
195 the size of each channel. Convert the float values
196 (-1.<=range<=1.) to whatever PCM format and write it out */
198 while((samples=vorbis_synthesis_pcmout(&vd,&pcm))>0){
201 int out=(samples<convsize?samples:convsize);
203 /* convert doubles to 16 bit signed ints (host order) and
205 for(i=0;i<vi.channels;i++){
206 int16_t *ptr=convbuffer+i;
209 int val=rint(mono[j]*32767.);
210 /* might as well guard clipping */
225 fprintf(stderr,"Clipping in frame %ld\n",vd.sequence);
228 fwrite(convbuffer,2*vi.channels,out,stdout);
230 vorbis_synthesis_read(&vd,out); /* tell libvorbis how
236 if(ogg_page_eos(&og))eos=1;
240 buffer=ogg_sync_buffer(&oy,4096);
241 bytes=fread(buffer,1,4096,stdin);
242 ogg_sync_wrote(&oy,bytes);
247 /* clean up and exit (this example doesn't deal with the possibility
248 of chaining logical streams */
251 ogg_stream_clear(&os);
253 /* ogg_page and ogg_packet structs always point to storage in
254 libvorbis. They're never freed or manipulated directly */
256 vorbis_dsp_clear(&vd);
257 vorbis_block_clear(&vb);
258 vorbis_info_clear(&vi); /* must be called last */
260 fprintf(stderr,"Done.\n");