Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/libvorbis-1.2.0/examples/encoder_example.c @ 16

Last change on this file since 16 was 16, checked in by landauf, 16 years ago

added libvorbis

File size: 8.4 KB
Line 
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-2007             *
9 * by the Xiph.Org Foundation http://www.xiph.org/                  *
10 *                                                                  *
11 ********************************************************************
12
13 function: simple example encoder
14 last mod: $Id: encoder_example.c 13293 2007-07-24 00:09:47Z xiphmont $
15
16 ********************************************************************/
17
18/* takes a stereo 16bit 44.1kHz WAV file from stdin and encodes it into
19   a Vorbis bitstream */
20
21/* Note that this is POSIX, not ANSI, code */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <time.h>
27#include <math.h>
28#include <vorbis/vorbisenc.h>
29
30#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
31#include <io.h>
32#include <fcntl.h>
33#endif
34
35#if defined(__MACOS__) && defined(__MWERKS__)
36#include <console.h>      /* CodeWarrior's Mac "command-line" support */
37#endif
38
39#define READ 1024
40signed char readbuffer[READ*4+44]; /* out of the data segment, not the stack */
41
42int main(){
43  ogg_stream_state os; /* take physical pages, weld into a logical
44                          stream of packets */
45  ogg_page         og; /* one Ogg bitstream page.  Vorbis packets are inside */
46  ogg_packet       op; /* one raw packet of data for decode */
47 
48  vorbis_info      vi; /* struct that stores all the static vorbis bitstream
49                          settings */
50  vorbis_comment   vc; /* struct that stores all the user comments */
51
52  vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
53  vorbis_block     vb; /* local working space for packet->PCM decode */
54
55  int eos=0,ret;
56  int i, founddata;
57
58#if defined(macintosh) && defined(__MWERKS__)
59  int argc = 0;
60  char **argv = NULL;
61  argc = ccommand(&argv); /* get a "command line" from the Mac user */
62                          /* this also lets the user set stdin and stdout */
63#endif
64
65  /* we cheat on the WAV header; we just bypass 44 bytes and never
66     verify that it matches 16bit/stereo/44.1kHz.  This is just an
67     example, after all. */
68
69#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
70  /* if we were reading/writing a file, it would also need to in
71     binary mode, eg, fopen("file.wav","wb"); */
72  /* Beware the evil ifdef. We avoid these where we can, but this one we
73     cannot. Don't add any more, you'll probably go to hell if you do. */
74  _setmode( _fileno( stdin ), _O_BINARY );
75  _setmode( _fileno( stdout ), _O_BINARY );
76#endif
77
78
79  /* we cheat on the WAV header; we just bypass the header and never
80     verify that it matches 16bit/stereo/44.1kHz.  This is just an
81     example, after all. */
82
83  readbuffer[0] = '\0';
84  for (i=0, founddata=0; i<30 && ! feof(stdin) && ! ferror(stdin); i++)
85  {
86    fread(readbuffer,1,2,stdin);
87
88    if ( ! strncmp((char*)readbuffer, "da", 2) )
89    {
90      founddata = 1;
91      fread(readbuffer,1,6,stdin);
92      break;
93    }
94  }
95
96  /********** Encode setup ************/
97
98  vorbis_info_init(&vi);
99
100  /* choose an encoding mode.  A few possibilities commented out, one
101     actually used: */
102
103  /*********************************************************************
104   Encoding using a VBR quality mode.  The usable range is -.1
105   (lowest quality, smallest file) to 1. (highest quality, largest file).
106   Example quality mode .4: 44kHz stereo coupled, roughly 128kbps VBR
107 
108   ret = vorbis_encode_init_vbr(&vi,2,44100,.4);
109
110   ---------------------------------------------------------------------
111
112   Encoding using an average bitrate mode (ABR).
113   example: 44kHz stereo coupled, average 128kbps VBR
114 
115   ret = vorbis_encode_init(&vi,2,44100,-1,128000,-1);
116
117   ---------------------------------------------------------------------
118
119   Encode using a quality mode, but select that quality mode by asking for
120   an approximate bitrate.  This is not ABR, it is true VBR, but selected
121   using the bitrate interface, and then turning bitrate management off:
122
123   ret = ( vorbis_encode_setup_managed(&vi,2,44100,-1,128000,-1) ||
124           vorbis_encode_ctl(&vi,OV_ECTL_RATEMANAGE2_SET,NULL) ||
125           vorbis_encode_setup_init(&vi));
126
127   *********************************************************************/
128
129  ret=vorbis_encode_init_vbr(&vi,2,44100,0.1);
130
131  /* do not continue if setup failed; this can happen if we ask for a
132     mode that libVorbis does not support (eg, too low a bitrate, etc,
133     will return 'OV_EIMPL') */
134
135  if(ret)exit(1);
136
137  /* add a comment */
138  vorbis_comment_init(&vc);
139  vorbis_comment_add_tag(&vc,"ENCODER","encoder_example.c");
140
141  /* set up the analysis state and auxiliary encoding storage */
142  vorbis_analysis_init(&vd,&vi);
143  vorbis_block_init(&vd,&vb);
144 
145  /* set up our packet->stream encoder */
146  /* pick a random serial number; that way we can more likely build
147     chained streams just by concatenation */
148  srand(time(NULL));
149  ogg_stream_init(&os,rand());
150
151  /* Vorbis streams begin with three headers; the initial header (with
152     most of the codec setup parameters) which is mandated by the Ogg
153     bitstream spec.  The second header holds any comment fields.  The
154     third header holds the bitstream codebook.  We merely need to
155     make the headers, then pass them to libvorbis one at a time;
156     libvorbis handles the additional Ogg bitstream constraints */
157
158  {
159    ogg_packet header;
160    ogg_packet header_comm;
161    ogg_packet header_code;
162
163    vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
164    ogg_stream_packetin(&os,&header); /* automatically placed in its own
165                                         page */
166    ogg_stream_packetin(&os,&header_comm);
167    ogg_stream_packetin(&os,&header_code);
168
169        /* This ensures the actual
170         * audio data will start on a new page, as per spec
171         */
172        while(!eos){
173                int result=ogg_stream_flush(&os,&og);
174                if(result==0)break;
175                fwrite(og.header,1,og.header_len,stdout);
176                fwrite(og.body,1,og.body_len,stdout);
177        }
178
179  }
180 
181  while(!eos){
182    long i;
183    long bytes=fread(readbuffer,1,READ*4,stdin); /* stereo hardwired here */
184
185    if(bytes==0){
186      /* end of file.  this can be done implicitly in the mainline,
187         but it's easier to see here in non-clever fashion.
188         Tell the library we're at end of stream so that it can handle
189         the last frame and mark end of stream in the output properly */
190      vorbis_analysis_wrote(&vd,0);
191
192    }else{
193      /* data to encode */
194
195      /* expose the buffer to submit data */
196      float **buffer=vorbis_analysis_buffer(&vd,READ);
197     
198      /* uninterleave samples */
199      for(i=0;i<bytes/4;i++){
200        buffer[0][i]=((readbuffer[i*4+1]<<8)|
201                      (0x00ff&(int)readbuffer[i*4]))/32768.f;
202        buffer[1][i]=((readbuffer[i*4+3]<<8)|
203                      (0x00ff&(int)readbuffer[i*4+2]))/32768.f;
204      }
205   
206      /* tell the library how much we actually submitted */
207      vorbis_analysis_wrote(&vd,i);
208    }
209
210    /* vorbis does some data preanalysis, then divvies up blocks for
211       more involved (potentially parallel) processing.  Get a single
212       block for encoding now */
213    while(vorbis_analysis_blockout(&vd,&vb)==1){
214
215      /* analysis, assume we want to use bitrate management */
216      vorbis_analysis(&vb,NULL);
217      vorbis_bitrate_addblock(&vb);
218
219      while(vorbis_bitrate_flushpacket(&vd,&op)){
220       
221        /* weld the packet into the bitstream */
222        ogg_stream_packetin(&os,&op);
223       
224        /* write out pages (if any) */
225        while(!eos){
226          int result=ogg_stream_pageout(&os,&og);
227          if(result==0)break;
228          fwrite(og.header,1,og.header_len,stdout);
229          fwrite(og.body,1,og.body_len,stdout);
230         
231          /* this could be set above, but for illustrative purposes, I do
232             it here (to show that vorbis does know where the stream ends) */
233         
234          if(ogg_page_eos(&og))eos=1;
235        }
236      }
237    }
238  }
239
240  /* clean up and exit.  vorbis_info_clear() must be called last */
241 
242  ogg_stream_clear(&os);
243  vorbis_block_clear(&vb);
244  vorbis_dsp_clear(&vd);
245  vorbis_comment_clear(&vc);
246  vorbis_info_clear(&vi);
247 
248  /* ogg_page and ogg_packet structs always point to storage in
249     libvorbis.  They're never freed or manipulated directly */
250 
251  fprintf(stderr,"Done.\n");
252  return(0);
253}
Note: See TracBrowser for help on using the repository browser.