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-2000 *
9 * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: maintain the info structure, info <-> header packets
15 last mod: $Id: info.c,v 1.13 2000/01/04 09:05:00 xiphmont Exp $
17 ********************************************************************/
19 /* This fills in a vorbis_info structure with settings from a few
20 pre-defined encoding modes. Also handles choosing/blowing in the
28 static int ilog2(unsigned int v){
37 void vorbis_info_init(vorbis_info *vi){
38 memset(vi,0,sizeof(vorbis_info));
41 /* one test mode for now; temporary of course */
42 int vorbis_info_modeset(vorbis_info *vi, int mode){
43 if(mode<0 || mode>predef_mode_max)return(-1);
45 /* handle the flat settings first */
46 memcpy(vi,&(predef_modes[mode]),sizeof(vorbis_info));
47 vi->user_comments=calloc(1,sizeof(char *));
48 vi->vendor=strdup("Xiphophorus libVorbis I 19991230");
53 /* convenience function */
54 int vorbis_info_addcomment(vorbis_info *vi,char *comment){
55 vi->user_comments=realloc(vi->user_comments,
56 (vi->comments+2)*sizeof(char *));
57 vi->user_comments[vi->comments]=strdup(comment);
59 vi->user_comments[vi->comments]=NULL;
63 static void _v_writestring(oggpack_buffer *o,char *s){
65 _oggpack_write(o,*s++,8);
69 static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
71 *buf++=_oggpack_read(o,8);
75 /* The Vorbis header is in three packets; the initial small packet in
76 the first page that identifies basic parameters, a second packet
77 with bitstream comments and a third packet that holds the
80 int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
85 _oggpack_readinit(&opb,op->packet,op->bytes);
87 /* Which of the three types of header is this? */
88 /* Also verify header-ness, vorbis */
92 _v_readstring(&opb,buffer,6);
93 if(memcmp(buffer,"vorbis",6)){
94 /* not a vorbis header */
97 switch(_oggpack_read(&opb,8)){
100 /* Not the initial packet */
104 /* previously initialized info header */
108 if(_oggpack_read(&opb,32)!=0){
111 vi->channels=_oggpack_read(&opb,8);
112 vi->rate=_oggpack_read(&opb,32);
114 vi->bitrate_upper=_oggpack_read(&opb,32);
115 vi->bitrate_nominal=_oggpack_read(&opb,32);
116 vi->bitrate_lower=_oggpack_read(&opb,32);
118 vi->blocksize[0]=1<<_oggpack_read(&opb,4);
119 vi->blocksize[1]=1<<_oggpack_read(&opb,4);
121 vi->floororder[0]=_oggpack_read(&opb,8);
122 vi->floororder[1]=_oggpack_read(&opb,8);
123 vi->floormap[0]=_oggpack_read(&opb,16);
124 vi->floormap[1]=_oggpack_read(&opb,16);
125 vi->floorch=_oggpack_read(&opb,8);
127 if(vi->rate<1)return(-1);
128 if(vi->floorch<1 || vi->floorch>vi->channels)return(-1);
133 /* um... we didn;t get the initial header */
137 int vendorlen=_oggpack_read(&opb,32);
138 vi->vendor=calloc(vendorlen+1,1);
139 _v_readstring(&opb,vi->vendor,vendorlen);
143 vi->comments=_oggpack_read(&opb,32);
144 vi->user_comments=calloc(vi->comments+1,sizeof(char **));
146 for(i=0;i<vi->comments;i++){
147 int len=_oggpack_read(&opb,32);
148 vi->user_comments[i]=calloc(len+1,1);
149 _v_readstring(&opb,vi->user_comments[i],len);
156 /* um... we didn;t get the initial header */
160 /* not implemented quite yet */
164 /* Not a valid vorbis header type */
173 int vorbis_info_headerout(vorbis_info *vi,
176 ogg_packet *op_code){
182 header id 0x80 (byte)
183 codec ver (4 octets, lsb first: currently 0x00)
184 pcm channels (4 octets, lsb first)
185 pcm rate (4 octets, lsb first)
187 small block (4 octets, lsb first)
188 large block (4 octets, lsb first)
189 floor order for small block (octet)
190 floor order for large block (octet)
191 floor octaves for small block (octet)
192 floor octaves for large block (octet)
193 floorch (4 octets, lsb first)
196 _oggpack_writeinit(&opb);
197 _v_writestring(&opb,"vorbis");
198 _oggpack_write(&opb,0x80,8);
200 _oggpack_write(&opb,0x00,32);
202 _oggpack_write(&opb,vi->channels,8);
203 _oggpack_write(&opb,vi->rate,32);
205 _oggpack_write(&opb,vi->bitrate_upper,32);
206 _oggpack_write(&opb,vi->bitrate_nominal,32);
207 _oggpack_write(&opb,vi->bitrate_lower,32);
209 _oggpack_write(&opb,ilog2(vi->blocksize[0]),4);
210 _oggpack_write(&opb,ilog2(vi->blocksize[1]),4);
211 _oggpack_write(&opb,vi->floororder[0],8);
212 _oggpack_write(&opb,vi->floororder[1],8);
213 _oggpack_write(&opb,vi->floormap[0],16);
214 _oggpack_write(&opb,vi->floormap[1],16);
215 _oggpack_write(&opb,vi->floorch,8);
217 /* build the packet */
218 if(vi->header)free(vi->header);
219 vi->header=malloc(_oggpack_bytes(&opb));
220 memcpy(vi->header,opb.buffer,_oggpack_bytes(&opb));
221 op->packet=vi->header;
222 op->bytes=_oggpack_bytes(&opb);
229 header id 0x81 (byte)
230 vendor len (4 octets, lsb first)
231 vendor and id (n octects as above)
232 comments (4 octets, lsb first)
233 comment 0 len (4 octets, lsb first)
234 comment 0 len (n octets as above)
236 comment n-1 len (4 octets, lsb first)
237 comment 0-1 len (n octets as above)
240 _oggpack_reset(&opb);
241 _v_writestring(&opb,"vorbis");
242 _oggpack_write(&opb,0x81,8);
245 _oggpack_write(&opb,strlen(vi->vendor),32);
246 _v_writestring(&opb,vi->vendor);
248 _oggpack_write(&opb,0,32);
251 _oggpack_write(&opb,vi->comments,32);
254 for(i=0;i<vi->comments;i++){
255 if(vi->user_comments[i]){
256 _oggpack_write(&opb,strlen(vi->user_comments[i]),32);
257 _v_writestring(&opb,vi->user_comments[i]);
259 _oggpack_write(&opb,0,32);
264 if(vi->header1)free(vi->header1);
265 vi->header1=malloc(_oggpack_bytes(&opb));
266 memcpy(vi->header1,opb.buffer,_oggpack_bytes(&opb));
267 op_comm->packet=vi->header1;
268 op_comm->bytes=_oggpack_bytes(&opb);
275 header id 0x82 (byte)
276 nul so far; not encoded yet */
278 _oggpack_reset(&opb);
279 _v_writestring(&opb,"vorbis");
280 _oggpack_write(&opb,0x82,8);
282 if(vi->header2)free(vi->header2);
283 vi->header2=malloc(_oggpack_bytes(&opb));
284 memcpy(vi->header2,opb.buffer,_oggpack_bytes(&opb));
285 op_code->packet=vi->header2;
286 op_code->bytes=_oggpack_bytes(&opb);
291 _oggpack_writeclear(&opb);
296 void vorbis_info_clear(vorbis_info *vi){
297 /* clear the non-flat storage before zeroing */
300 if(vi->user_comments){
301 char **ptr=vi->user_comments;
305 free(vi->user_comments);
309 if(vi->vendor)free(vi->vendor);
311 /* local encoding storage */
312 if(vi->header)free(vi->header);
313 if(vi->header1)free(vi->header1);
314 if(vi->header2)free(vi->header2);
316 memset(vi,0,sizeof(vorbis_info));