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.11 1999/12/30 07:26:39 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->threshhold_points=threshhold_points;
48 vi->user_comments=calloc(1,sizeof(char *));
49 vi->vendor=strdup("Xiphophorus libVorbis I 19991104");
54 /* convenience function */
55 int vorbis_info_addcomment(vorbis_info *vi,char *comment){
56 vi->user_comments=realloc(vi->user_comments,
57 (vi->comments+2)*sizeof(char *));
58 vi->user_comments[vi->comments]=strdup(comment);
60 vi->user_comments[vi->comments]=NULL;
64 static void _v_writestring(oggpack_buffer *o,char *s){
66 _oggpack_write(o,*s++,8);
70 static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
72 *buf++=_oggpack_read(o,8);
76 /* The Vorbis header is in three packets; the initial small packet in
77 the first page that identifies basic parameters, a second packet
78 with bitstream comments and a third packet that holds the
81 int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
86 _oggpack_readinit(&opb,op->packet,op->bytes);
88 /* Which of the three types of header is this? */
89 /* Also verify header-ness, vorbis */
93 _v_readstring(&opb,buffer,6);
94 if(memcmp(buffer,"vorbis",6)){
95 /* not a vorbis header */
98 switch(_oggpack_read(&opb,8)){
101 /* Not the initial packet */
105 /* previously initialized info header */
109 if(_oggpack_read(&opb,32)!=0){
112 vi->channels=_oggpack_read(&opb,8);
113 vi->rate=_oggpack_read(&opb,32);
115 vi->bitrate_upper=_oggpack_read(&opb,32);
116 vi->bitrate_nominal=_oggpack_read(&opb,32);
117 vi->bitrate_lower=_oggpack_read(&opb,32);
119 vi->blocksize[0]=1<<_oggpack_read(&opb,4);
120 vi->blocksize[1]=1<<_oggpack_read(&opb,4);
122 vi->floororder[0]=_oggpack_read(&opb,8);
123 vi->floororder[1]=_oggpack_read(&opb,8);
124 vi->flooroctaves[0]=_oggpack_read(&opb,8);
125 vi->flooroctaves[1]=_oggpack_read(&opb,8);
126 vi->floorch=_oggpack_read(&opb,8);
128 if(vi->rate<1)return(-1);
129 if(vi->floorch<1 || vi->floorch>vi->channels)return(-1);
134 /* um... we didn;t get the initial header */
138 int vendorlen=_oggpack_read(&opb,32);
139 vi->vendor=calloc(vendorlen+1,1);
140 _v_readstring(&opb,vi->vendor,vendorlen);
144 vi->comments=_oggpack_read(&opb,32);
145 vi->user_comments=calloc(vi->comments+1,sizeof(char **));
147 for(i=0;i<vi->comments;i++){
148 int len=_oggpack_read(&opb,32);
149 vi->user_comments[i]=calloc(len+1,1);
150 _v_readstring(&opb,vi->user_comments[i],len);
157 /* um... we didn;t get the initial header */
161 /* not implemented quite yet */
165 /* Not a valid vorbis header type */
174 int vorbis_info_headerout(vorbis_info *vi,
177 ogg_packet *op_code){
183 header id 0x80 (byte)
184 codec ver (4 octets, lsb first: currently 0x00)
185 pcm channels (4 octets, lsb first)
186 pcm rate (4 octets, lsb first)
188 small block (4 octets, lsb first)
189 large block (4 octets, lsb first)
190 floor order for small block (octet)
191 floor order for large block (octet)
192 floor octaves for small block (octet)
193 floor octaves for large block (octet)
194 floorch (4 octets, lsb first)
197 _oggpack_writeinit(&opb);
198 _v_writestring(&opb,"vorbis");
199 _oggpack_write(&opb,0x80,8);
201 _oggpack_write(&opb,0x00,32);
203 _oggpack_write(&opb,vi->channels,8);
204 _oggpack_write(&opb,vi->rate,32);
206 _oggpack_write(&opb,vi->bitrate_upper,32);
207 _oggpack_write(&opb,vi->bitrate_nominal,32);
208 _oggpack_write(&opb,vi->bitrate_lower,32);
210 _oggpack_write(&opb,ilog2(vi->blocksize[0]),4);
211 _oggpack_write(&opb,ilog2(vi->blocksize[1]),4);
212 _oggpack_write(&opb,vi->floororder[0],8);
213 _oggpack_write(&opb,vi->floororder[1],8);
214 _oggpack_write(&opb,vi->flooroctaves[0],8);
215 _oggpack_write(&opb,vi->flooroctaves[1],8);
216 _oggpack_write(&opb,vi->floorch,8);
218 /* build the packet */
219 if(vi->header)free(vi->header);
220 vi->header=malloc(_oggpack_bytes(&opb));
221 memcpy(vi->header,opb.buffer,_oggpack_bytes(&opb));
222 op->packet=vi->header;
223 op->bytes=_oggpack_bytes(&opb);
230 header id 0x81 (byte)
231 vendor len (4 octets, lsb first)
232 vendor and id (n octects as above)
233 comments (4 octets, lsb first)
234 comment 0 len (4 octets, lsb first)
235 comment 0 len (n octets as above)
237 comment n-1 len (4 octets, lsb first)
238 comment 0-1 len (n octets as above)
241 _oggpack_reset(&opb);
242 _v_writestring(&opb,"vorbis");
243 _oggpack_write(&opb,0x81,8);
246 _oggpack_write(&opb,strlen(vi->vendor),32);
247 _v_writestring(&opb,vi->vendor);
249 _oggpack_write(&opb,0,32);
252 _oggpack_write(&opb,vi->comments,32);
255 for(i=0;i<vi->comments;i++){
256 if(vi->user_comments[i]){
257 _oggpack_write(&opb,strlen(vi->user_comments[i]),32);
258 _v_writestring(&opb,vi->user_comments[i]);
260 _oggpack_write(&opb,0,32);
265 if(vi->header1)free(vi->header1);
266 vi->header1=malloc(_oggpack_bytes(&opb));
267 memcpy(vi->header1,opb.buffer,_oggpack_bytes(&opb));
268 op_comm->packet=vi->header1;
269 op_comm->bytes=_oggpack_bytes(&opb);
276 header id 0x82 (byte)
277 nul so far; not encoded yet */
279 _oggpack_reset(&opb);
280 _v_writestring(&opb,"vorbis");
281 _oggpack_write(&opb,0x82,8);
283 if(vi->header2)free(vi->header2);
284 vi->header2=malloc(_oggpack_bytes(&opb));
285 memcpy(vi->header2,opb.buffer,_oggpack_bytes(&opb));
286 op_code->packet=vi->header2;
287 op_code->bytes=_oggpack_bytes(&opb);
292 _oggpack_writeclear(&opb);
297 void vorbis_info_clear(vorbis_info *vi){
298 /* clear the non-flat storage before zeroing */
301 if(vi->user_comments){
302 char **ptr=vi->user_comments;
306 free(vi->user_comments);
310 if(vi->vendor)free(vi->vendor);
312 /* local encoding storage */
313 if(vi->header)free(vi->header);
314 if(vi->header1)free(vi->header1);
315 if(vi->header2)free(vi->header2);
317 memset(vi,0,sizeof(vorbis_info));