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->user_comments=calloc(1,sizeof(char *));
41 vi->vendor=strdup("Xiphophorus libVorbis I 19991012");
46 /* convenience function */
47 int vorbis_info_addcomment(vorbis_info *vi,char *comment){
48 vi->user_comments=realloc(vi->user_comments,
49 (vi->comments+1)*sizeof(char *));
50 vi->user_comments[vi->comments]=strdup(comment);
52 vi->user_comments[vi->comments]=NULL;
56 static void _v_writestring(oggpack_buffer *o,char *s){
58 _oggpack_write(o,*s++,8);
62 static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
64 *buf++=_oggpack_read(o,8);
68 /* The Vorbis header is in three packets; the initial small packet in
69 the first page that identifies basic parameters, a second packet
70 with bitstream comments and a third packet that holds the
73 int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
78 _oggpack_readinit(&opb,op->packet,op->bytes);
80 /* Which of the three types of header is this? */
81 /* Also verify header-ness, vorbis */
85 _v_readstring(&opb,buffer,6);
86 if(memcmp(buffer,"vorbis",6)){
87 /* not a vorbis header */
90 switch(_oggpack_read(&opb,8)){
93 /* Not the initial packet */
97 /* previously initialized info header */
101 if(_oggpack_read(&opb,32)!=0){
104 vi->channels=_oggpack_read(&opb,32);
105 vi->rate=_oggpack_read(&opb,32);
107 vi->blocksize[0]=_oggpack_read(&opb,32);
108 vi->blocksize[1]=_oggpack_read(&opb,32);
110 vi->floororder[0]=_oggpack_read(&opb,8);
111 vi->floororder[1]=_oggpack_read(&opb,8);
112 vi->flooroctaves[0]=_oggpack_read(&opb,8);
113 vi->flooroctaves[1]=_oggpack_read(&opb,8);
115 vi->envelopesa=_oggpack_read(&opb,32);
116 vi->envelopech=_oggpack_read(&opb,16);
117 vi->floorch=_oggpack_read(&opb,16);
122 /* um... we didn;t get the initial header */
126 int vendorlen=_oggpack_read(&opb,32);
127 vi->vendor=calloc(vendorlen+1,1);
128 _v_readstring(&opb,vi->vendor,vendorlen);
132 vi->comments=_oggpack_read(&opb,32);
133 vi->user_comments=calloc(vi->comments+1,sizeof(char **));
135 for(i=0;i<vi->comments;i++){
136 int len=_oggpack_read(&opb,32);
137 vi->user_comments[i]=calloc(len+1,1);
138 _v_readstring(&opb,vi->user_comments[i],len);
145 /* um... we didn;t get the initial header */
149 /* not implemented quite yet */
153 /* Not a valid vorbis header type */
162 int vorbis_info_headerout(vorbis_info *vi,
165 ogg_packet *op_code){
171 header id 0x80 (byte)
172 codec ver (4 octets, lsb first: currently 0x00)
173 pcm channels (4 octets, lsb first)
174 pcm rate (4 octets, lsb first)
176 small block (4 octets, lsb first)
177 large block (4 octets, lsb first)
178 floor order for small block (octet)
179 floor order for large block (octet)
180 floor octaves for small block (octet)
181 floor octaves for large block (octet)
183 envelopesa (4 octets, lsb first)
184 envelopech (4 octets, lsb first)
185 floorch (4 octets, lsb first)
188 _oggpack_writeinit(&opb);
189 _v_writestring(&opb,"vorbis");
190 _oggpack_write(&opb,0x80,8);
192 _oggpack_write(&opb,0x00,32);
194 _oggpack_write(&opb,vi->channels,32);
195 _oggpack_write(&opb,vi->rate,32);
196 _oggpack_write(&opb,vi->blocksize[0],32);
197 _oggpack_write(&opb,vi->blocksize[1],32);
198 _oggpack_write(&opb,vi->floororder[0],8);
199 _oggpack_write(&opb,vi->floororder[1],8);
200 _oggpack_write(&opb,vi->flooroctaves[0],8);
201 _oggpack_write(&opb,vi->flooroctaves[1],8);
202 _oggpack_write(&opb,vi->envelopesa,32);
203 _oggpack_write(&opb,vi->envelopech,16);
204 _oggpack_write(&opb,vi->floorch,16);
206 /* build the packet */
207 if(vi->header)free(vi->header);
208 vi->header=malloc(_oggpack_bytes(&opb));
209 memcpy(vi->header,opb.buffer,_oggpack_bytes(&opb));
210 op->packet=vi->header;
211 op->bytes=_oggpack_bytes(&opb);
218 header id 0x81 (byte)
219 vendor len (4 octets, lsb first)
220 vendor and id (n octects as above)
221 comments (4 octets, lsb first)
222 comment 0 len (4 octets, lsb first)
223 comment 0 len (n octets as above)
225 comment n-1 len (4 octets, lsb first)
226 comment 0-1 len (n octets as above)
229 _oggpack_reset(&opb);
230 _v_writestring(&opb,"vorbis");
231 _oggpack_write(&opb,0x81,8);
234 _oggpack_write(&opb,strlen(vi->vendor),32);
235 _v_writestring(&opb,vi->vendor);
237 _oggpack_write(&opb,0,32);
240 _oggpack_write(&opb,vi->comments,32);
243 for(i=0;i<vi->comments;i++){
244 if(vi->user_comments[i]){
245 _oggpack_write(&opb,strlen(vi->user_comments[i]),32);
246 _v_writestring(&opb,vi->user_comments[i]);
248 _oggpack_write(&opb,0,32);
253 if(vi->header1)free(vi->header1);
254 vi->header1=malloc(_oggpack_bytes(&opb));
255 memcpy(vi->header1,opb.buffer,_oggpack_bytes(&opb));
256 op_comm->packet=vi->header1;
257 op_comm->bytes=_oggpack_bytes(&opb);
264 header id 0x82 (byte)
265 nul so far; not encoded yet */
267 _oggpack_reset(&opb);
268 _v_writestring(&opb,"vorbis");
269 _oggpack_write(&opb,0x82,8);
271 if(vi->header2)free(vi->header2);
272 vi->header2=malloc(_oggpack_bytes(&opb));
273 memcpy(vi->header2,opb.buffer,_oggpack_bytes(&opb));
274 op_code->packet=vi->header2;
275 op_code->bytes=_oggpack_bytes(&opb);
280 _oggpack_writeclear(&opb);
285 void vorbis_info_clear(vorbis_info *vi){
286 /* clear the non-flat storage before zeroing */
289 if(vi->user_comments){
290 char **ptr=vi->user_comments;
294 free(vi->user_comments);
298 if(vi->vendor)free(vi->vendor);
300 /* local encoding storage */
301 if(vi->header)free(vi->header);
302 if(vi->header1)free(vi->header1);
303 if(vi->header2)free(vi->header2);
305 memset(vi,0,sizeof(vorbis_info));