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 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 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 19991003");
46 /* convenience function */
47 int vorbis_info_add_comment(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 */
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 vi->channels=_oggpack_read(&opb,32);
103 vi->rate=_oggpack_read(&opb,32);
104 vi->smallblock=_oggpack_read(&opb,32);
105 vi->largeblock=_oggpack_read(&opb,32);
106 vi->envelopesa=_oggpack_read(&opb,32);
107 vi->envelopech=_oggpack_read(&opb,16);
108 vi->floororder=_oggpack_read(&opb,8);
109 vi->flooroctaves=_oggpack_read(&opb,8);
110 vi->floorch=_oggpack_read(&opb,16);
115 /* um... we didn;t get the initial header */
119 int vendorlen=_oggpack_read(&opb,32);
120 vi->vendor=calloc(vendorlen+1,1);
121 _v_readstring(&opb,vi->vendor,vendorlen);
125 vi->comments=_oggpack_read(&opb,32);
126 vi->user_comments=calloc(vi->comments+1,sizeof(char **));
128 for(i=0;i<=vi->comments;i++){
129 int len=_oggpack_read(&opb,32);
130 vi->user_comments[i]=calloc(len+1,1);
131 _v_readstring(&opb,vi->user_comments[i],len);
138 /* um... we didn;t get the initial header */
142 /* not implemented quite yet */
146 /* Not a valid vorbis header type */
155 int vorbis_info_headerout(vorbis_info *vi,
158 ogg_packet *op_code){
165 codec ver (4 octets, lsb first: currently 0x00)
166 pcm channels (4 octets, lsb first)
167 pcm rate (4 octets, lsb first)
169 small block (4 octets, lsb first)
170 large block (4 octets, lsb first)
171 envelopesa (4 octets, lsb first)
172 envelopech (4 octets, lsb first)
175 floorch (4 octets, lsb first)
178 _oggpack_writeinit(&opb);
179 _v_writestring(&opb,"vorbis");
180 _oggpack_write(&opb,0x00,8);
182 _oggpack_write(&opb,0x00,32);
184 _oggpack_write(&opb,vi->channels,32);
185 _oggpack_write(&opb,vi->rate,32);
186 _oggpack_write(&opb,vi->smallblock,32);
187 _oggpack_write(&opb,vi->largeblock,32);
188 _oggpack_write(&opb,vi->envelopesa,32);
189 _oggpack_write(&opb,vi->envelopech,16);
190 _oggpack_write(&opb,vi->floororder,8);
191 _oggpack_write(&opb,vi->flooroctaves,8);
192 _oggpack_write(&opb,vi->floorch,16);
194 /* build the packet */
195 if(vi->header)free(vi->header);
196 memcpy(vi->header,opb.buffer,_oggpack_bytes(&opb));
197 op->packet=vi->header;
198 op->bytes=_oggpack_bytes(&opb);
206 vendor len (4 octets, lsb first)
207 vendor and id (n octects as above)
208 comments (4 octets, lsb first)
209 comment 0 len (4 octets, lsb first)
210 comment 0 len (n octets as above)
212 comment n-1 len (4 octets, lsb first)
213 comment 0-1 len (n octets as above)
216 _oggpack_reset(&opb);
217 _v_writestring(&opb,"vorbis");
218 _oggpack_write(&opb,0x01,8);
221 _oggpack_write(&opb,strlen(vi->vendor),32);
222 _v_writestring(&opb,vi->vendor);
224 _oggpack_write(&opb,0,32);
227 _oggpack_write(&opb,vi->comments,32);
230 for(i=0;i<vi->comments;i++){
231 if(vi->user_comments[i]){
232 _oggpack_write(&opb,strlen(vi->user_comments[i]),32);
233 _v_writestring(&opb,vi->user_comments[i]);
235 _oggpack_write(&opb,0,32);
240 if(vi->header1)free(vi->header1);
241 memcpy(vi->header1,opb.buffer,_oggpack_bytes(&opb));
242 op_comm->packet=vi->header1;
243 op_comm->bytes=_oggpack_bytes(&opb);
251 nul so far; not encoded yet */
253 _oggpack_reset(&opb);
254 _v_writestring(&opb,"vorbis");
255 _oggpack_write(&opb,0x02,8);
257 if(vi->header2)free(vi->header2);
258 memcpy(vi->header2,opb.buffer,_oggpack_bytes(&opb));
259 op_code->packet=vi->header2;
260 op_code->bytes=_oggpack_bytes(&opb);
265 _oggpack_writefree(&opb);
270 int vorbis_info_clear(vorbis_info *vi){
271 /* clear the non-flat storage before zeroing */
274 if(vi->user_comments){
275 char **ptr=vi->user_comments;
279 free(vi->user_comments);
283 if(vi->vendor)free(vi->vendor);
285 /* local encoding storage */
286 if(vi->header)free(vi->header);
287 if(vi->header1)free(vi->header1);
288 if(vi->header2)free(vi->header2);
290 memset(vi,0,sizeof(vorbis_info));