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: maintain the info structure, info <-> header packets
15 author: Monty <xiphmont@mit.edu>
16 modifications by: Monty
17 last modification date: Oct 06 1999
19 ********************************************************************/
21 /* This fills in a vorbis_info structure with settings from a few
22 pre-defined encoding modes. Also handles choosing/blowing in the
30 void vorbis_info_init(vorbis_info *vi){
31 memset(vi,0,sizeof(vorbis_info));
34 /* one test mode for now; temporary of course */
35 int vorbis_info_modeset(vorbis_info *vi, int mode){
36 if(mode<0 || mode>predef_mode_max)return(-1);
38 /* handle the flat settings first */
39 memcpy(vi,&(predef_modes[mode]),sizeof(vorbis_info));
40 vi->threshhold_points=threshhold_points;
41 vi->user_comments=calloc(1,sizeof(char *));
42 vi->vendor=strdup("Xiphophorus libVorbis I 19991018");
47 /* convenience function */
48 int vorbis_info_addcomment(vorbis_info *vi,char *comment){
49 vi->user_comments=realloc(vi->user_comments,
50 (vi->comments+2)*sizeof(char *));
51 vi->user_comments[vi->comments]=strdup(comment);
53 vi->user_comments[vi->comments]=NULL;
57 static void _v_writestring(oggpack_buffer *o,char *s){
59 _oggpack_write(o,*s++,8);
63 static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
65 *buf++=_oggpack_read(o,8);
69 /* The Vorbis header is in three packets; the initial small packet in
70 the first page that identifies basic parameters, a second packet
71 with bitstream comments and a third packet that holds the
74 int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
79 _oggpack_readinit(&opb,op->packet,op->bytes);
81 /* Which of the three types of header is this? */
82 /* Also verify header-ness, vorbis */
86 _v_readstring(&opb,buffer,6);
87 if(memcmp(buffer,"vorbis",6)){
88 /* not a vorbis header */
91 switch(_oggpack_read(&opb,8)){
94 /* Not the initial packet */
98 /* previously initialized info header */
102 if(_oggpack_read(&opb,32)!=0){
105 vi->channels=_oggpack_read(&opb,32);
106 vi->rate=_oggpack_read(&opb,32);
108 vi->blocksize[0]=_oggpack_read(&opb,32);
109 vi->blocksize[1]=_oggpack_read(&opb,32);
111 vi->floororder[0]=_oggpack_read(&opb,8);
112 vi->floororder[1]=_oggpack_read(&opb,8);
113 vi->flooroctaves[0]=_oggpack_read(&opb,8);
114 vi->flooroctaves[1]=_oggpack_read(&opb,8);
116 vi->envelopesa=_oggpack_read(&opb,32);
117 vi->envelopech=_oggpack_read(&opb,16);
118 vi->floorch=_oggpack_read(&opb,16);
123 /* um... we didn;t get the initial header */
127 int vendorlen=_oggpack_read(&opb,32);
128 vi->vendor=calloc(vendorlen+1,1);
129 _v_readstring(&opb,vi->vendor,vendorlen);
133 vi->comments=_oggpack_read(&opb,32);
134 vi->user_comments=calloc(vi->comments+1,sizeof(char **));
136 for(i=0;i<vi->comments;i++){
137 int len=_oggpack_read(&opb,32);
138 vi->user_comments[i]=calloc(len+1,1);
139 _v_readstring(&opb,vi->user_comments[i],len);
146 /* um... we didn;t get the initial header */
150 /* not implemented quite yet */
154 /* Not a valid vorbis header type */
163 int vorbis_info_headerout(vorbis_info *vi,
166 ogg_packet *op_code){
172 header id 0x80 (byte)
173 codec ver (4 octets, lsb first: currently 0x00)
174 pcm channels (4 octets, lsb first)
175 pcm rate (4 octets, lsb first)
177 small block (4 octets, lsb first)
178 large block (4 octets, lsb first)
179 floor order for small block (octet)
180 floor order for large block (octet)
181 floor octaves for small block (octet)
182 floor octaves for large block (octet)
184 envelopesa (4 octets, lsb first)
185 envelopech (4 octets, lsb first)
186 floorch (4 octets, lsb first)
189 _oggpack_writeinit(&opb);
190 _v_writestring(&opb,"vorbis");
191 _oggpack_write(&opb,0x80,8);
193 _oggpack_write(&opb,0x00,32);
195 _oggpack_write(&opb,vi->channels,32);
196 _oggpack_write(&opb,vi->rate,32);
197 _oggpack_write(&opb,vi->blocksize[0],32);
198 _oggpack_write(&opb,vi->blocksize[1],32);
199 _oggpack_write(&opb,vi->floororder[0],8);
200 _oggpack_write(&opb,vi->floororder[1],8);
201 _oggpack_write(&opb,vi->flooroctaves[0],8);
202 _oggpack_write(&opb,vi->flooroctaves[1],8);
203 _oggpack_write(&opb,vi->envelopesa,32);
204 _oggpack_write(&opb,vi->envelopech,16);
205 _oggpack_write(&opb,vi->floorch,16);
207 /* build the packet */
208 if(vi->header)free(vi->header);
209 vi->header=malloc(_oggpack_bytes(&opb));
210 memcpy(vi->header,opb.buffer,_oggpack_bytes(&opb));
211 op->packet=vi->header;
212 op->bytes=_oggpack_bytes(&opb);
219 header id 0x81 (byte)
220 vendor len (4 octets, lsb first)
221 vendor and id (n octects as above)
222 comments (4 octets, lsb first)
223 comment 0 len (4 octets, lsb first)
224 comment 0 len (n octets as above)
226 comment n-1 len (4 octets, lsb first)
227 comment 0-1 len (n octets as above)
230 _oggpack_reset(&opb);
231 _v_writestring(&opb,"vorbis");
232 _oggpack_write(&opb,0x81,8);
235 _oggpack_write(&opb,strlen(vi->vendor),32);
236 _v_writestring(&opb,vi->vendor);
238 _oggpack_write(&opb,0,32);
241 _oggpack_write(&opb,vi->comments,32);
244 for(i=0;i<vi->comments;i++){
245 if(vi->user_comments[i]){
246 _oggpack_write(&opb,strlen(vi->user_comments[i]),32);
247 _v_writestring(&opb,vi->user_comments[i]);
249 _oggpack_write(&opb,0,32);
254 if(vi->header1)free(vi->header1);
255 vi->header1=malloc(_oggpack_bytes(&opb));
256 memcpy(vi->header1,opb.buffer,_oggpack_bytes(&opb));
257 op_comm->packet=vi->header1;
258 op_comm->bytes=_oggpack_bytes(&opb);
265 header id 0x82 (byte)
266 nul so far; not encoded yet */
268 _oggpack_reset(&opb);
269 _v_writestring(&opb,"vorbis");
270 _oggpack_write(&opb,0x82,8);
272 if(vi->header2)free(vi->header2);
273 vi->header2=malloc(_oggpack_bytes(&opb));
274 memcpy(vi->header2,opb.buffer,_oggpack_bytes(&opb));
275 op_code->packet=vi->header2;
276 op_code->bytes=_oggpack_bytes(&opb);
281 _oggpack_writeclear(&opb);
286 void vorbis_info_clear(vorbis_info *vi){
287 /* clear the non-flat storage before zeroing */
290 if(vi->user_comments){
291 char **ptr=vi->user_comments;
295 free(vi->user_comments);
299 if(vi->vendor)free(vi->vendor);
301 /* local encoding storage */
302 if(vi->header)free(vi->header);
303 if(vi->header1)free(vi->header1);
304 if(vi->header2)free(vi->header2);
306 memset(vi,0,sizeof(vorbis_info));