00001 /******************************************************************** 00002 * * 00003 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * 00004 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 00005 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 00006 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 00007 * * 00008 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * 00009 * by the XIPHOPHORUS Company http://www.xiph.org/ * 00010 * * 00011 ******************************************************************** 00012 00013 function: simple example encoder 00014 last mod: $Id: encoder_example.c 7187 2004-07-20 07:24:27Z xiphmont $ 00015 00016 ********************************************************************/ 00017 00018 /* takes a stereo 16bit 44.1kHz WAV file from stdin and encodes it into 00019 a Vorbis bitstream */ 00020 00021 /* Note that this is POSIX, not ANSI, code */ 00022 00023 #include <stdio.h> 00024 #include <stdlib.h> 00025 #include <string.h> 00026 #include <time.h> 00027 #include <math.h> 00028 #include <vorbis/vorbisenc.h> 00029 00030 #if defined(_WIN32) && !defined(__SYMBIAN32__) /* We need the following two to set stdin/stdout to binary */ 00031 #include <io.h> 00032 #include <fcntl.h> 00033 #endif 00034 00035 #if defined(__MACOS__) && defined(__MWERKS__) 00036 #include <console.h> /* CodeWarrior's Mac "command-line" support */ 00037 #endif 00038 00039 #define READ 1024 00040 signed char readbuffer[READ*4+44]; /* out of the data segment, not the stack */ 00041 00042 int main(){ 00043 ogg_stream_state os; /* take physical pages, weld into a logical 00044 stream of packets */ 00045 ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */ 00046 ogg_packet op; /* one raw packet of data for decode */ 00047 00048 vorbis_info vi; /* struct that stores all the static vorbis bitstream 00049 settings */ 00050 vorbis_comment vc; /* struct that stores all the user comments */ 00051 00052 vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ 00053 vorbis_block vb; /* local working space for packet->PCM decode */ 00054 00055 int eos=0,ret; 00056 int i, founddata; 00057 00058 #if defined(macintosh) && defined(__MWERKS__) 00059 int argc = 0; 00060 char **argv = NULL; 00061 argc = ccommand(&argv); /* get a "command line" from the Mac user */ 00062 /* this also lets the user set stdin and stdout */ 00063 #endif 00064 00065 /* we cheat on the WAV header; we just bypass 44 bytes and never 00066 verify that it matches 16bit/stereo/44.1kHz. This is just an 00067 example, after all. */ 00068 00069 #if defined(_WIN32) && !defined(__SYMBIAN32__) /* We need to set stdin/stdout to binary mode. Damn windows. */ 00070 /* if we were reading/writing a file, it would also need to in 00071 binary mode, eg, fopen("file.wav","wb"); */ 00072 /* Beware the evil ifdef. We avoid these where we can, but this one we 00073 cannot. Don't add any more, you'll probably go to hell if you do. */ 00074 _setmode( _fileno( stdin ), _O_BINARY ); 00075 _setmode( _fileno( stdout ), _O_BINARY ); 00076 #endif 00077 00078 00079 /* we cheat on the WAV header; we just bypass the header and never 00080 verify that it matches 16bit/stereo/44.1kHz. This is just an 00081 example, after all. */ 00082 00083 readbuffer[0] = '\0'; 00084 for (i=0, founddata=0; i<30 && ! feof(stdin) && ! ferror(stdin); i++) 00085 { 00086 fread(readbuffer,1,2,stdin); 00087 00088 if ( ! strncmp((char*)readbuffer, "da", 2) ) 00089 { 00090 founddata = 1; 00091 fread(readbuffer,1,6,stdin); 00092 break; 00093 } 00094 } 00095 00096 /********** Encode setup ************/ 00097 00098 vorbis_info_init(&vi); 00099 00100 /* choose an encoding mode. A few possibilities commented out, one 00101 actually used: */ 00102 00103 /********************************************************************* 00104 Encoding using a VBR quality mode. The usable range is -.1 00105 (lowest quality, smallest file) to 1. (highest quality, largest file). 00106 Example quality mode .4: 44kHz stereo coupled, roughly 128kbps VBR 00107 00108 ret = vorbis_encode_init_vbr(&vi,2,44100,.4); 00109 00110 --------------------------------------------------------------------- 00111 00112 Encoding using an average bitrate mode (ABR). 00113 example: 44kHz stereo coupled, average 128kbps VBR 00114 00115 ret = vorbis_encode_init(&vi,2,44100,-1,128000,-1); 00116 00117 --------------------------------------------------------------------- 00118 00119 Encode using a quality mode, but select that quality mode by asking for 00120 an approximate bitrate. This is not ABR, it is true VBR, but selected 00121 using the bitrate interface, and then turning bitrate management off: 00122 00123 ret = ( vorbis_encode_setup_managed(&vi,2,44100,-1,128000,-1) || 00124 vorbis_encode_ctl(&vi,OV_ECTL_RATEMANAGE2_SET,NULL) || 00125 vorbis_encode_setup_init(&vi)); 00126 00127 *********************************************************************/ 00128 00129 ret=vorbis_encode_init_vbr(&vi,2,44100,0.1); 00130 00131 /* do not continue if setup failed; this can happen if we ask for a 00132 mode that libVorbis does not support (eg, too low a bitrate, etc, 00133 will return 'OV_EIMPL') */ 00134 00135 if(ret)exit(1); 00136 00137 /* add a comment */ 00138 vorbis_comment_init(&vc); 00139 vorbis_comment_add_tag(&vc,"ENCODER","encoder_example.c"); 00140 00141 /* set up the analysis state and auxiliary encoding storage */ 00142 vorbis_analysis_init(&vd,&vi); 00143 vorbis_block_init(&vd,&vb); 00144 00145 /* set up our packet->stream encoder */ 00146 /* pick a random serial number; that way we can more likely build 00147 chained streams just by concatenation */ 00148 srand(time(NULL)); 00149 ogg_stream_init(&os,rand()); 00150 00151 /* Vorbis streams begin with three headers; the initial header (with 00152 most of the codec setup parameters) which is mandated by the Ogg 00153 bitstream spec. The second header holds any comment fields. The 00154 third header holds the bitstream codebook. We merely need to 00155 make the headers, then pass them to libvorbis one at a time; 00156 libvorbis handles the additional Ogg bitstream constraints */ 00157 00158 { 00159 ogg_packet header; 00160 ogg_packet header_comm; 00161 ogg_packet header_code; 00162 00163 vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code); 00164 ogg_stream_packetin(&os,&header); /* automatically placed in its own 00165 page */ 00166 ogg_stream_packetin(&os,&header_comm); 00167 ogg_stream_packetin(&os,&header_code); 00168 00169 /* This ensures the actual 00170 * audio data will start on a new page, as per spec 00171 */ 00172 while(!eos){ 00173 int result=ogg_stream_flush(&os,&og); 00174 if(result==0)break; 00175 fwrite(og.header,1,og.header_len,stdout); 00176 fwrite(og.body,1,og.body_len,stdout); 00177 } 00178 00179 } 00180 00181 while(!eos){ 00182 long i; 00183 long bytes=fread(readbuffer,1,READ*4,stdin); /* stereo hardwired here */ 00184 00185 if(bytes==0){ 00186 /* end of file. this can be done implicitly in the mainline, 00187 but it's easier to see here in non-clever fashion. 00188 Tell the library we're at end of stream so that it can handle 00189 the last frame and mark end of stream in the output properly */ 00190 vorbis_analysis_wrote(&vd,0); 00191 00192 }else{ 00193 /* data to encode */ 00194 00195 /* expose the buffer to submit data */ 00196 float **buffer=vorbis_analysis_buffer(&vd,READ); 00197 00198 /* uninterleave samples */ 00199 for(i=0;i<bytes/4;i++){ 00200 buffer[0][i]=((readbuffer[i*4+1]<<8)| 00201 (0x00ff&(int)readbuffer[i*4]))/32768.f; 00202 buffer[1][i]=((readbuffer[i*4+3]<<8)| 00203 (0x00ff&(int)readbuffer[i*4+2]))/32768.f; 00204 } 00205 00206 /* tell the library how much we actually submitted */ 00207 vorbis_analysis_wrote(&vd,i); 00208 } 00209 00210 /* vorbis does some data preanalysis, then divvies up blocks for 00211 more involved (potentially parallel) processing. Get a single 00212 block for encoding now */ 00213 while(vorbis_analysis_blockout(&vd,&vb)==1){ 00214 00215 /* analysis, assume we want to use bitrate management */ 00216 vorbis_analysis(&vb,NULL); 00217 vorbis_bitrate_addblock(&vb); 00218 00219 while(vorbis_bitrate_flushpacket(&vd,&op)){ 00220 00221 /* weld the packet into the bitstream */ 00222 ogg_stream_packetin(&os,&op); 00223 00224 /* write out pages (if any) */ 00225 while(!eos){ 00226 int result=ogg_stream_pageout(&os,&og); 00227 if(result==0)break; 00228 fwrite(og.header,1,og.header_len,stdout); 00229 fwrite(og.body,1,og.body_len,stdout); 00230 00231 /* this could be set above, but for illustrative purposes, I do 00232 it here (to show that vorbis does know where the stream ends) */ 00233 00234 if(ogg_page_eos(&og))eos=1; 00235 } 00236 } 00237 } 00238 } 00239 00240 /* clean up and exit. vorbis_info_clear() must be called last */ 00241 00242 ogg_stream_clear(&os); 00243 vorbis_block_clear(&vb); 00244 vorbis_dsp_clear(&vd); 00245 vorbis_comment_clear(&vc); 00246 vorbis_info_clear(&vi); 00247 00248 /* ogg_page and ogg_packet structs always point to storage in 00249 libvorbis. They're never freed or manipulated directly */ 00250 00251 fprintf(stderr,"Done.\n"); 00252 return(0); 00253 }