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: Nov 04 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 static int ilog2(unsigned int v){
39 void vorbis_info_init(vorbis_info *vi){
40 memset(vi,0,sizeof(vorbis_info));
43 /* one test mode for now; temporary of course */
44 int vorbis_info_modeset(vorbis_info *vi, int mode){
45 if(mode<0 || mode>predef_mode_max)return(-1);
47 /* handle the flat settings first */
48 memcpy(vi,&(predef_modes[mode]),sizeof(vorbis_info));
49 vi->threshhold_points=threshhold_points;
50 vi->user_comments=calloc(1,sizeof(char *));
51 vi->vendor=strdup("Xiphophorus libVorbis I 19991104");
56 /* convenience function */
57 int vorbis_info_addcomment(vorbis_info *vi,char *comment){
58 vi->user_comments=realloc(vi->user_comments,
59 (vi->comments+2)*sizeof(char *));
60 vi->user_comments[vi->comments]=strdup(comment);
62 vi->user_comments[vi->comments]=NULL;
66 static void _v_writestring(oggpack_buffer *o,char *s){
68 _oggpack_write(o,*s++,8);
72 static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
74 *buf++=_oggpack_read(o,8);
78 /* The Vorbis header is in three packets; the initial small packet in
79 the first page that identifies basic parameters, a second packet
80 with bitstream comments and a third packet that holds the
83 int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
88 _oggpack_readinit(&opb,op->packet,op->bytes);
90 /* Which of the three types of header is this? */
91 /* Also verify header-ness, vorbis */
95 _v_readstring(&opb,buffer,6);
96 if(memcmp(buffer,"vorbis",6)){
97 /* not a vorbis header */
100 switch(_oggpack_read(&opb,8)){
103 /* Not the initial packet */
107 /* previously initialized info header */
111 if(_oggpack_read(&opb,32)!=0){
114 vi->channels=_oggpack_read(&opb,8);
115 vi->rate=_oggpack_read(&opb,32);
117 vi->bitrate_upper=_oggpack_read(&opb,32);
118 vi->bitrate_nominal=_oggpack_read(&opb,32);
119 vi->bitrate_lower=_oggpack_read(&opb,32);
121 vi->blocksize[0]=1<<_oggpack_read(&opb,4);
122 vi->blocksize[1]=1<<_oggpack_read(&opb,4);
124 vi->floororder[0]=_oggpack_read(&opb,8);
125 vi->floororder[1]=_oggpack_read(&opb,8);
126 vi->flooroctaves[0]=_oggpack_read(&opb,8);
127 vi->flooroctaves[1]=_oggpack_read(&opb,8);
128 vi->floorch=_oggpack_read(&opb,8);
130 if(vi->rate<1)return(-1);
131 if(vi->floorch<1 || vi->floorch>vi->channels)return(-1);
136 /* um... we didn;t get the initial header */
140 int vendorlen=_oggpack_read(&opb,32);
141 vi->vendor=calloc(vendorlen+1,1);
142 _v_readstring(&opb,vi->vendor,vendorlen);
146 vi->comments=_oggpack_read(&opb,32);
147 vi->user_comments=calloc(vi->comments+1,sizeof(char **));
149 for(i=0;i<vi->comments;i++){
150 int len=_oggpack_read(&opb,32);
151 vi->user_comments[i]=calloc(len+1,1);
152 _v_readstring(&opb,vi->user_comments[i],len);
159 /* um... we didn;t get the initial header */
163 /* not implemented quite yet */
167 /* Not a valid vorbis header type */
176 int vorbis_info_headerout(vorbis_info *vi,
179 ogg_packet *op_code){
185 header id 0x80 (byte)
186 codec ver (4 octets, lsb first: currently 0x00)
187 pcm channels (4 octets, lsb first)
188 pcm rate (4 octets, lsb first)
190 small block (4 octets, lsb first)
191 large block (4 octets, lsb first)
192 floor order for small block (octet)
193 floor order for large block (octet)
194 floor octaves for small block (octet)
195 floor octaves for large block (octet)
196 floorch (4 octets, lsb first)
199 _oggpack_writeinit(&opb);
200 _v_writestring(&opb,"vorbis");
201 _oggpack_write(&opb,0x80,8);
203 _oggpack_write(&opb,0x00,32);
205 _oggpack_write(&opb,vi->channels,8);
206 _oggpack_write(&opb,vi->rate,32);
208 _oggpack_write(&opb,vi->bitrate_upper,32);
209 _oggpack_write(&opb,vi->bitrate_nominal,32);
210 _oggpack_write(&opb,vi->bitrate_lower,32);
212 _oggpack_write(&opb,ilog2(vi->blocksize[0]),4);
213 _oggpack_write(&opb,ilog2(vi->blocksize[1]),4);
214 _oggpack_write(&opb,vi->floororder[0],8);
215 _oggpack_write(&opb,vi->floororder[1],8);
216 _oggpack_write(&opb,vi->flooroctaves[0],8);
217 _oggpack_write(&opb,vi->flooroctaves[1],8);
218 _oggpack_write(&opb,vi->floorch,8);
220 /* build the packet */
221 if(vi->header)free(vi->header);
222 vi->header=malloc(_oggpack_bytes(&opb));
223 memcpy(vi->header,opb.buffer,_oggpack_bytes(&opb));
224 op->packet=vi->header;
225 op->bytes=_oggpack_bytes(&opb);
232 header id 0x81 (byte)
233 vendor len (4 octets, lsb first)
234 vendor and id (n octects as above)
235 comments (4 octets, lsb first)
236 comment 0 len (4 octets, lsb first)
237 comment 0 len (n octets as above)
239 comment n-1 len (4 octets, lsb first)
240 comment 0-1 len (n octets as above)
243 _oggpack_reset(&opb);
244 _v_writestring(&opb,"vorbis");
245 _oggpack_write(&opb,0x81,8);
248 _oggpack_write(&opb,strlen(vi->vendor),32);
249 _v_writestring(&opb,vi->vendor);
251 _oggpack_write(&opb,0,32);
254 _oggpack_write(&opb,vi->comments,32);
257 for(i=0;i<vi->comments;i++){
258 if(vi->user_comments[i]){
259 _oggpack_write(&opb,strlen(vi->user_comments[i]),32);
260 _v_writestring(&opb,vi->user_comments[i]);
262 _oggpack_write(&opb,0,32);
267 if(vi->header1)free(vi->header1);
268 vi->header1=malloc(_oggpack_bytes(&opb));
269 memcpy(vi->header1,opb.buffer,_oggpack_bytes(&opb));
270 op_comm->packet=vi->header1;
271 op_comm->bytes=_oggpack_bytes(&opb);
278 header id 0x82 (byte)
279 nul so far; not encoded yet */
281 _oggpack_reset(&opb);
282 _v_writestring(&opb,"vorbis");
283 _oggpack_write(&opb,0x82,8);
285 if(vi->header2)free(vi->header2);
286 vi->header2=malloc(_oggpack_bytes(&opb));
287 memcpy(vi->header2,opb.buffer,_oggpack_bytes(&opb));
288 op_code->packet=vi->header2;
289 op_code->bytes=_oggpack_bytes(&opb);
294 _oggpack_writeclear(&opb);
299 void vorbis_info_clear(vorbis_info *vi){
300 /* clear the non-flat storage before zeroing */
303 if(vi->user_comments){
304 char **ptr=vi->user_comments;
308 free(vi->user_comments);
312 if(vi->vendor)free(vi->vendor);
314 /* local encoding storage */
315 if(vi->header)free(vi->header);
316 if(vi->header1)free(vi->header1);
317 if(vi->header2)free(vi->header2);
319 memset(vi,0,sizeof(vorbis_info));