Incremental update.
authorMonty <xiphmont@xiph.org>
Sun, 3 Oct 1999 21:13:43 +0000 (21:13 +0000)
committerMonty <xiphmont@xiph.org>
Sun, 3 Oct 1999 21:13:43 +0000 (21:13 +0000)
Restore bitwise.c's ability to code 32 bit quantities.
Corrections to API
correction to framing.c: initial packet must be the only one in the first page

Monty

svn path=/trunk/vorbis/; revision=136

lib/bitwise.c
lib/codec.h
lib/dsptest.c
lib/framing.c
lib/info.c
lib/modes.h

index 2a6820c..ffc02ce 100644 (file)
@@ -59,7 +59,7 @@ void _oggpack_readinit(oggpack_buffer *b,char *buf,int bytes){
   b->storage=bytes;
 }
 
-/* Takes only up to 31 bits. We won't need it all */
+/* Takes only up to 32 bits. */
 void _oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
   if(b->endbyte+4>=b->storage){
     b->buffer=realloc(b->buffer,b->storage+BUFFER_INCREMENT);
@@ -79,7 +79,10 @@ void _oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
       if(bits>=24){
        b->ptr[3]=value>>(24-b->endbit);  
        if(bits>=32){
-         b->ptr[4]=value>>(32-b->endbit); /*can't get here if endbit==0*/
+         if(b->endbit)
+           b->ptr[4]=value>>(32-b->endbit);
+         else
+           b->ptr[4]=0;
        }
       }
     }
@@ -90,7 +93,7 @@ void _oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
   b->endbit=bits&7;
 }
 
-/* Read in bits without advancing the bitptr; bits < 32 */
+/* Read in bits without advancing the bitptr; bits <= 32 */
 long _oggpack_look(oggpack_buffer *b,int bits){
   unsigned long ret;
   unsigned long m=mask[bits];
@@ -109,9 +112,8 @@ long _oggpack_look(oggpack_buffer *b,int bits){
       ret|=b->ptr[2]<<(16-b->endbit);  
       if(bits>24){
        ret|=b->ptr[3]<<(24-b->endbit);  
-       if(bits>32){
-         ret|=b->ptr[4]<<(32-b->endbit); /*can't get here if endbit==0*/
-       }
+       if(bits>32 && b->endbit)
+         ret|=b->ptr[4]<<(32-b->endbit);
       }
     }
   }
@@ -138,7 +140,7 @@ void _oggpack_adv1(oggpack_buffer *b){
   }
 }
 
-/* bits < 32 */
+/* bits <= 32 */
 long _oggpack_read(oggpack_buffer *b,int bits){
   unsigned long ret;
   unsigned long m=mask[bits];
@@ -158,8 +160,8 @@ long _oggpack_read(oggpack_buffer *b,int bits){
       ret|=b->ptr[2]<<(16-b->endbit);  
       if(bits>24){
        ret|=b->ptr[3]<<(24-b->endbit);  
-       if(bits>32){
-         ret|=b->ptr[4]<<(32-b->endbit); /*can't get here if endbit==0*/
+       if(bits>32 && b->endbit){
+         ret|=b->ptr[4]<<(32-b->endbit);
        }
       }
     }
@@ -288,27 +290,27 @@ int main(void){
 
   int onesize=33;
   static int one[]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
-                   34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
-                   223,4};
+                    34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
+                    223,4};
 
   int twosize=6;
   static int two[]={61,255,255,251,231,29};
 
   int threesize=54;
   static int three[]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
-                     142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
-                     58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
-                     100,52,4,14,18,86,77,1};
+                      142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
+                      58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
+                      100,52,4,14,18,86,77,1};
 
   int foursize=38;
   static int four[]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
-                    132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
-                    28,2,133,0,1};
+                     132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
+                     28,2,133,0,1};
 
   int fivesize=45;
   static int five[]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
-                    241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
-                    84,75,159,2,1,0,132,192,8,0,0,18,22};
+                     241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
+                     84,75,159,2,1,0,132,192,8,0,0,18,22};
 
   int sixsize=7;
   static int six[]={17,177,170,242,169,19,148};
@@ -329,21 +331,21 @@ int main(void){
   cliptest(testbuffer2,test2size,0,three,threesize);
   fprintf(stderr,"ok.");
 
-  fprintf(stderr,"\n31 bit preclipped packing: ");
+  fprintf(stderr,"\n32 bit preclipped packing: ");
   _oggpack_reset(&o);
   for(i=0;i<test2size;i++)
-    _oggpack_write(&o,large[i],31);
+    _oggpack_write(&o,large[i],32);
   buffer=o.buffer;
   bytes=_oggpack_bytes(&o);
   _oggpack_readinit(&r,buffer,bytes);
   for(i=0;i<test2size;i++){
-    if(_oggpack_look(&r,31)==-1)report("out of data. failed!");
-    if(_oggpack_look(&r,31)!=large[i]){
-      fprintf(stderr,"%ld != %ld (%lx!=%lx):",_oggpack_look(&r,31),large[i],
-             _oggpack_look(&r,31),large[i]);
+    if(_oggpack_look(&r,32)==-1)report("out of data. failed!");
+    if(_oggpack_look(&r,32)!=large[i]){
+      fprintf(stderr,"%ld != %ld (%lx!=%lx):",_oggpack_look(&r,32),large[i],
+             _oggpack_look(&r,32),large[i]);
       report("read incorrect value!\n");
     }
-    _oggpack_adv(&r,31);
+    _oggpack_adv(&r,32);
   }
   if(_oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
   fprintf(stderr,"ok.");
index db97004..8f8c622 100644 (file)
@@ -98,6 +98,14 @@ typedef struct vorbis_info{
 
   double preecho_thresh;
   double preecho_clamp;
+
+  /* local storage, only used on the encoding size.  This way the
+     application does not need to worry about freeing some packets'
+     memory and not others'.  Packet storage is always tracked */
+  char *header;
+  char *header1;
+  char *header2;
+
 } vorbis_info;
  
 /* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
@@ -287,7 +295,10 @@ extern int vorbis_info_clear(vorbis_info *vi);
 extern int vorbis_info_modeset(vorbis_info *vi, int mode); 
 extern int vorbis_info_addcomment(vorbis_info *vi, char *comment); 
 extern int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op);
-extern int vorbis_info_headerout(vorbis_info *vi,ogg_packet *op);
+extern int vorbis_info_headerout(vorbis_info *vi,
+                                ogg_packet *op,
+                                ogg_packet *op_comm,
+                                ogg_packet *op_code);
 
 extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
 extern int vorbis_block_clear(vorbis_block *vb);
index 2a8abe2..8bd17e1 100644 (file)
@@ -12,8 +12,6 @@ int main(){
    long counterout=0;
    int done=0;
    char *temp[]={ "Test" ,"the Test band", "test records",NULL };
-   int mtemp[]={0,1};
-   int mtemp2[]={0,1};
    int frame=0;
    int i;
 
@@ -29,8 +27,7 @@ int main(){
    vi.largeblock=2048;
    vi.envelopesa=64;
    vi.envelopech=2;
-   vi.envelopemap=mtemp;
-   vi.floormap=mtemp2;
+
    vi.floororder=30;
    vi.flooroctaves=5;
    vi.floorch=2;
index c53ff0e..30943a9 100644 (file)
@@ -221,7 +221,7 @@ int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
 
 /* This constructs pages from buffered packet segments.  The pointers
 returned are to static buffers; do not free. The returned buffers are
-good only until the next call (using the same os) */
+good only until the next call (using the same ogg_stream_state) */
 
 int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
   int i;
@@ -238,9 +238,11 @@ int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
     os->body_returned=0;
   }
 
-  if((os->e_o_s&&os->lacing_fill) || 
-     os->body_fill > 4096 || 
-     os->lacing_fill>=255){
+  if((os->e_o_s&&os->lacing_fill) ||  /* 'were done, now flush' case */
+     os->body_fill > 4096 ||          /* 'page nominal size' case */
+     os->lacing_fill>=255 ||          /* 'segment table full' case */
+     (os->lacing_fill&&!os->b_o_s)){  /* 'initial header page' case */
+
     int vals=0,bytes=0;
     int maxvals=(os->lacing_fill>255?255:os->lacing_fill);
     long acc=0;
@@ -248,10 +250,23 @@ int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
 
     /* construct a page */
     /* decide how many segments to include */
-    for(vals=0;vals<maxvals;vals++){
-      if(acc>4096)break;
-      acc+=os->lacing_vals[vals]&0x0ff;
-      if((os->lacing_vals[vals]&0x0ff)<255)pcm_pos=os->pcm_vals[vals];
+
+    /* If this is the initial header case, the first page must only include
+       the initial header packet */
+    if(os->b_o_s==0){  /* 'initial header page' case */
+      pcm_pos=0;
+      for(vals=0;vals<maxvals;vals++){
+       if((os->lacing_vals[vals]&0x0ff)<255){
+         vals++;
+         break;
+       }
+      }
+    }else{
+      for(vals=0;vals<maxvals;vals++){
+       if(acc>4096)break;
+       acc+=os->lacing_vals[vals]&0x0ff;
+       if((os->lacing_vals[vals]&0x0ff)<255)pcm_pos=os->pcm_vals[vals];
+      }
     }
 
     /* construct the header in temp storage */
@@ -259,10 +274,9 @@ int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
 
     /* stream structure version */
     os->header[4]=0x00;
-
     
-    os->header[5]=0x00;
     /* continued packet flag? */
+    os->header[5]=0x00;
     if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01;
     /* first page flag? */
     if(os->b_o_s==0)os->header[5]|=0x02;
@@ -935,16 +949,37 @@ int main(void){
      the checksums are working.  */
 
   {
+    /* 17 only */
+    int packets[]={17, -1};
+    int head1[] = {0x4f,0x67,0x67,0x53,0,0x06,
+                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                  0x01,0x02,0x03,0x04,0,0,0,0,
+                  0x15,0xed,0xec,0x91,
+                  1,
+                  17};
+    int *headret[]={head1,NULL};
+    
+    fprintf(stderr,"testing single page encoding... ");
+    test_pack(packets,headret);
+  }
+
+  {
     /* 17, 254, 255, 256, 500, 510, 600 byte, pad */
     int packets[]={17, 254, 255, 256, 500, 510, 600, -1};
-    int head1[] = {0x4f,0x67,0x67,0x53,0,0x06,
-                  0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+    int head1[] = {0x4f,0x67,0x67,0x53,0,0x02,
+                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                   0x01,0x02,0x03,0x04,0,0,0,0,
-                  0x46,0x39,0xee,0xcb,
-                  14,
-                  17,254,255,0,255,1,255,245,255,255,0,
+                  0x59,0x10,0x6c,0x2c,
+                  1,
+                   17};
+    int head2[] = {0x4f,0x67,0x67,0x53,0,0x04,
+                  0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+                  0x01,0x02,0x03,0x04,1,0,0,0,
+                  0x89,0x33,0x85,0xce,
+                  13,
+                  254,255,0,255,1,255,245,255,255,0,
                   255,255,90};
-    int *headret[]={head1,NULL};
+    int *headret[]={head1,head2,NULL};
     
     fprintf(stderr,"testing basic page encoding... ");
     test_pack(packets,headret);
@@ -954,71 +989,84 @@ int main(void){
     /* nil packets; beginning,middle,end */
     int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1};
 
-    int head1[] = {0x4f,0x67,0x67,0x53,0,0x06,
-                  0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
+    int head1[] = {0x4f,0x67,0x67,0x53,0,0x02,
+                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                   0x01,0x02,0x03,0x04,0,0,0,0,
-                  0xf6,0x56,0x56,0x9e,
-                  18,
-                  0,17,254,255,0,0,255,1,0,255,245,255,255,0,
+                  0xff,0x7b,0x23,0x17,
+                  1,
+                  0};
+    int head2[] = {0x4f,0x67,0x67,0x53,0,0x04,
+                  0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
+                  0x01,0x02,0x03,0x04,1,0,0,0,
+                  0x5c,0x3f,0x66,0xcb,
+                  17,
+                  17,254,255,0,0,255,1,0,255,245,255,255,0,
                   255,255,90,0};
-    int *headret[]={head1,NULL};
+    int *headret[]={head1,head2,NULL};
     
     fprintf(stderr,"testing basic nil packets... ");
     test_pack(packets,headret);
   }
 
   {
-    /* starting new page with first segment */
+    /* large initial packet */
     int packets[]={4345,259,255,-1};
 
     int head1[] = {0x4f,0x67,0x67,0x53,0,0x02,
                   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                   0x01,0x02,0x03,0x04,0,0,0,0,
-                  0x7e,0x3e,0xa9,0x86,
-                  17,
+                  0x01,0x27,0x31,0xaa,
+                  18,
                   255,255,255,255,255,255,255,255,
-                  255,255,255,255,255,255,255,255,255};
+                  255,255,255,255,255,255,255,255,255,10};
 
-    int head2[] = {0x4f,0x67,0x67,0x53,0,0x05,
+    int head2[] = {0x4f,0x67,0x67,0x53,0,0x04,
                   0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
                   0x01,0x02,0x03,0x04,1,0,0,0,
-                  0x28,0x26,0x8c,0x6a,
-                  5,
-                  10,255,4,255,0};
+                  0x7f,0x4e,0x8a,0xd2,
+                  4,
+                  255,4,255,0};
     int *headret[]={head1,head2,NULL};
     
-    fprintf(stderr,"testing single-packet page span... ");
+    fprintf(stderr,"testing initial-packet lacing > 4k... ");
     test_pack(packets,headret);
   }
 
   {
-    int packets[]={100,4345,259,255,-1};
+    /* continuing packet test */
+    int packets[]={0,4345,259,255,-1};
 
     int head1[] = {0x4f,0x67,0x67,0x53,0,0x02,
-                  0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                   0x01,0x02,0x03,0x04,0,0,0,0,
-                  0x9f,0x45,0x89,0x8c,
+                  0xff,0x7b,0x23,0x17,
+                  1,
+                  0};
+
+    int head2[] = {0x4f,0x67,0x67,0x53,0,0x00,
+                  0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                  0x01,0x02,0x03,0x04,1,0,0,0,
+                  0x34,0x24,0xd5,0x29,
                   17,
-                  100,255,255,255,255,255,255,255,255,
-                  255,255,255,255,255,255,255,255};
+                  255,255,255,255,255,255,255,255,
+                  255,255,255,255,255,255,255,255,255};
 
-    int head2[] = {0x4f,0x67,0x67,0x53,0,0x05,
+    int head3[] = {0x4f,0x67,0x67,0x53,0,0x05,
                   0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
-                  0x01,0x02,0x03,0x04,1,0,0,0,
-                  0xe6,0x35,0xfc,0xb7,
-                  6,
-                  255,10,255,4,255,0};
-    int *headret[]={head1,head2,NULL};
+                  0x01,0x02,0x03,0x04,2,0,0,0,
+                  0xc8,0xc3,0xcb,0xed,
+                  5,
+                  10,255,4,255,0};
+    int *headret[]={head1,head2,head3,NULL};
     
-    fprintf(stderr,"testing multi-packet page span... ");
+    fprintf(stderr,"testing single packet page span... ");
     test_pack(packets,headret);
   }
 
-
   /* page with the 255 segment limit */
   {
 
-    int packets[]={10,10,10,10,10,10,10,10,
+    int packets[]={0,10,10,10,10,10,10,10,10,
                   10,10,10,10,10,10,10,10,
                   10,10,10,10,10,10,10,10,
                   10,10,10,10,10,10,10,10,
@@ -1052,9 +1100,16 @@ int main(void){
                   10,10,10,10,10,10,10,50,-1};
 
     int head1[] = {0x4f,0x67,0x67,0x53,0,0x02,
-                  0x07,0xf8,0x03,0x00,0x00,0x00,0x00,0x00,
+                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                   0x01,0x02,0x03,0x04,0,0,0,0,
-                  0x2f,0xe5,0xf5,0x43,
+                  0xff,0x7b,0x23,0x17,
+                  1,
+                  0};
+
+    int head2[] = {0x4f,0x67,0x67,0x53,0,0x00,
+                  0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
+                  0x01,0x02,0x03,0x04,1,0,0,0,
+                  0xed,0x2a,0x2e,0xa7,
                   255,
                   10,10,10,10,10,10,10,10,
                   10,10,10,10,10,10,10,10,
@@ -1089,13 +1144,13 @@ int main(void){
                   10,10,10,10,10,10,10,10,
                   10,10,10,10,10,10,10};
 
-    int head2[] = {0x4f,0x67,0x67,0x53,0,0x04,
-                  0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
-                  0x01,0x02,0x03,0x04,1,0,0,0,
-                  0x46,0x8b,0x88,0x90,
+    int head3[] = {0x4f,0x67,0x67,0x53,0,0x04,
+                  0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
+                  0x01,0x02,0x03,0x04,2,0,0,0,
+                  0x6c,0x3b,0x82,0x3d,
                   1,
                   50};
-    int *headret[]={head1,head2,NULL};
+    int *headret[]={head1,head2,head3,NULL};
     
     fprintf(stderr,"testing max packet segments... ");
     test_pack(packets,headret);
@@ -1104,31 +1159,38 @@ int main(void){
   {
     /* packet that overspans over an entire page */
 
-    int packets[]={100,9000,259,255,-1};
+    int packets[]={0,100,9000,259,255,-1};
 
     int head1[] = {0x4f,0x67,0x67,0x53,0,0x02,
-                  0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                   0x01,0x02,0x03,0x04,0,0,0,0,
-                  0x9f,0x45,0x89,0x8c,
+                  0xff,0x7b,0x23,0x17,
+                  1,
+                  0};
+
+    int head2[] = {0x4f,0x67,0x67,0x53,0,0x00,
+                  0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
+                  0x01,0x02,0x03,0x04,1,0,0,0,
+                  0x3c,0xd9,0x4d,0x3f,
                   17,
                   100,255,255,255,255,255,255,255,255,
                   255,255,255,255,255,255,255,255};
 
-    int head2[] = {0x4f,0x67,0x67,0x53,0,0x01,
-                  0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-                  0x01,0x02,0x03,0x04,1,0,0,0,
-                  0xaf,0x9d,0xf1,0x76,
+    int head3[] = {0x4f,0x67,0x67,0x53,0,0x01,
+                  0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
+                  0x01,0x02,0x03,0x04,2,0,0,0,
+                  0xbd,0xd5,0xb5,0x8b,
                   17,
                   255,255,255,255,255,255,255,255,
                   255,255,255,255,255,255,255,255,255};
 
-    int head3[] = {0x4f,0x67,0x67,0x53,0,0x05,
-                  0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
-                  0x01,0x02,0x03,0x04,2,0,0,0,
-                  0xe1,0x61,0x9f,0xbd,
+    int head4[] = {0x4f,0x67,0x67,0x53,0,0x05,
+                  0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
+                  0x01,0x02,0x03,0x04,3,0,0,0,
+                  0xef,0xdd,0x88,0xde,
                   7,
                   255,255,75,255,4,255,0};
-    int *headret[]={head1,head2,head3,NULL};
+    int *headret[]={head1,head2,head3,head4,NULL};
     
     fprintf(stderr,"testing very large packets... ");
     test_pack(packets,headret);
@@ -1137,23 +1199,30 @@ int main(void){
   {
     /* term only page.  why not? */
 
-    int packets[]={100,4080,-1};
+    int packets[]={0,100,4080,-1};
 
     int head1[] = {0x4f,0x67,0x67,0x53,0,0x02,
-                  0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                   0x01,0x02,0x03,0x04,0,0,0,0,
-                  0x9f,0x45,0x89,0x8c,
+                  0xff,0x7b,0x23,0x17,
+                  1,
+                  0};
+
+    int head2[] = {0x4f,0x67,0x67,0x53,0,0x00,
+                  0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
+                  0x01,0x02,0x03,0x04,1,0,0,0,
+                  0x3c,0xd9,0x4d,0x3f,
                   17,
                   100,255,255,255,255,255,255,255,255,
                   255,255,255,255,255,255,255,255};
 
-    int head2[] = {0x4f,0x67,0x67,0x53,0,0x05,
-                  0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
-                  0x01,0x02,0x03,0x04,1,0,0,0,
-                  0xf1,0x29,0xfc,0x4c,
+    int head3[] = {0x4f,0x67,0x67,0x53,0,0x05,
+                  0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
+                  0x01,0x02,0x03,0x04,2,0,0,0,
+                  0xd4,0xe0,0x60,0xe5,
                   1,0};
 
-    int *headret[]={head1,head2,NULL};
+    int *headret[]={head1,head2,head3,NULL};
     
     fprintf(stderr,"testing zero data page (1 nil packet)... ");
     test_pack(packets,headret);
@@ -1164,9 +1233,9 @@ int main(void){
   {
     /* build a bunch of pages for testing */
     unsigned char *data=malloc(1024*1024);
-    int pl[]={100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1};
+    int pl[]={0,100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1};
     int inptr=0,i,j;
-    ogg_page og[4];
+    ogg_page og[5];
     
     ogg_stream_reset(&os_en);
 
@@ -1186,7 +1255,7 @@ int main(void){
     free(data);
 
     /* retrieve finished pages */
-    for(i=0;i<4;i++){
+    for(i=0;i<5;i++){
       if(ogg_stream_pageout(&os_en,&og[i])==0){
        fprintf(stderr,"Too few pages output building sync tests!\n");
        exit(1);
@@ -1203,7 +1272,7 @@ int main(void){
 
       ogg_sync_reset(&oy);
       ogg_stream_reset(&os_de);
-      for(i=0;i<4;i++){
+      for(i=0;i<5;i++){
        memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
               og[i].header_len);
        ogg_sync_wrote(&oy,og[i].header_len);
@@ -1214,6 +1283,8 @@ int main(void){
       ogg_sync_pageout(&oy,&temp);
       ogg_stream_pagein(&os_de,&temp);
       ogg_sync_pageout(&oy,&temp);
+      ogg_stream_pagein(&os_de,&temp);
+      ogg_sync_pageout(&oy,&temp);
       /* skip */
       ogg_sync_pageout(&oy,&temp);
       ogg_stream_pagein(&os_de,&temp);
@@ -1221,17 +1292,19 @@ int main(void){
       /* do we get the expected results/packets? */
       
       if(ogg_stream_packetout(&os_de,&test)!=1)error();
-      checkpacket(&test,100,0,-1);
+      checkpacket(&test,0,0,0);
+      if(ogg_stream_packetout(&os_de,&test)!=1)error();
+      checkpacket(&test,100,1,-1);
       if(ogg_stream_packetout(&os_de,&test)!=1)error();
-      checkpacket(&test,4079,1,2000);
+      checkpacket(&test,4079,2,3000);
       if(ogg_stream_packetout(&os_de,&test)!=-1){
        fprintf(stderr,"Error: loss of page did not return error\n");
        exit(1);
       }
       if(ogg_stream_packetout(&os_de,&test)!=1)error();
-      checkpacket(&test,76,4,-1);
+      checkpacket(&test,76,5,-1);
       if(ogg_stream_packetout(&os_de,&test)!=1)error();
-      checkpacket(&test,34,5,-1);
+      checkpacket(&test,34,6,-1);
       fprintf(stderr,"ok.\n");
     }
 
@@ -1244,7 +1317,7 @@ int main(void){
 
       ogg_sync_reset(&oy);
       ogg_stream_reset(&os_de);
-      for(i=0;i<4;i++){
+      for(i=0;i<5;i++){
        memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
               og[i].header_len);
        ogg_sync_wrote(&oy,og[i].header_len);
@@ -1257,6 +1330,8 @@ int main(void){
       ogg_sync_pageout(&oy,&temp);
       ogg_stream_pagein(&os_de,&temp);
       ogg_sync_pageout(&oy,&temp);
+      ogg_stream_pagein(&os_de,&temp);
+      ogg_sync_pageout(&oy,&temp);
       /* skip */
       ogg_sync_pageout(&oy,&temp);
       ogg_stream_pagein(&os_de,&temp);
@@ -1264,17 +1339,19 @@ int main(void){
       /* do we get the expected results/packets? */
       
       if(ogg_stream_packetout(&os_de,&test)!=1)error();
-      checkpacket(&test,100,0,-1);
+      checkpacket(&test,0,0,0);
       if(ogg_stream_packetout(&os_de,&test)!=1)error();
-      checkpacket(&test,4079,1,2000);
+      checkpacket(&test,100,1,-1);
       if(ogg_stream_packetout(&os_de,&test)!=1)error();
-      checkpacket(&test,2956,2,3000);
+      checkpacket(&test,4079,2,3000);
+      if(ogg_stream_packetout(&os_de,&test)!=1)error();
+      checkpacket(&test,2956,3,4000);
       if(ogg_stream_packetout(&os_de,&test)!=-1){
        fprintf(stderr,"Error: loss of page did not return error\n");
        exit(1);
       }
       if(ogg_stream_packetout(&os_de,&test)!=1)error();
-      checkpacket(&test,300,12,13000);
+      checkpacket(&test,300,13,14000);
       fprintf(stderr,"ok.\n");
     }
     
@@ -1284,37 +1361,37 @@ int main(void){
       /* Test fractional page inputs: incomplete capture */
       fprintf(stderr,"Testing sync on partial inputs... ");
       ogg_sync_reset(&oy);
-      memcpy(ogg_sync_buffer(&oy,og[0].header_len),og[0].header,
+      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
             3);
       ogg_sync_wrote(&oy,3);
       if(ogg_sync_pageout(&oy,&og_de)>0)error();
       
       /* Test fractional page inputs: incomplete fixed header */
-      memcpy(ogg_sync_buffer(&oy,og[0].header_len),og[0].header+3,
+      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3,
             20);
       ogg_sync_wrote(&oy,20);
       if(ogg_sync_pageout(&oy,&og_de)>0)error();
       
       /* Test fractional page inputs: incomplete header */
-      memcpy(ogg_sync_buffer(&oy,og[0].header_len),og[0].header+23,
+      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23,
             5);
       ogg_sync_wrote(&oy,5);
       if(ogg_sync_pageout(&oy,&og_de)>0)error();
       
       /* Test fractional page inputs: incomplete body */
       
-      memcpy(ogg_sync_buffer(&oy,og[0].header_len),og[0].header+28,
-            og[0].header_len-28);
-      ogg_sync_wrote(&oy,og[0].header_len-28);
+      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28,
+            og[1].header_len-28);
+      ogg_sync_wrote(&oy,og[1].header_len-28);
       if(ogg_sync_pageout(&oy,&og_de)>0)error();
       
-      memcpy(ogg_sync_buffer(&oy,og[0].body_len),og[0].body,1000);
+      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000);
       ogg_sync_wrote(&oy,1000);
       if(ogg_sync_pageout(&oy,&og_de)>0)error();
       
-      memcpy(ogg_sync_buffer(&oy,og[0].body_len),og[0].body+1000,
-            og[0].body_len-1000);
-      ogg_sync_wrote(&oy,og[0].body_len-1000);
+      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000,
+            og[1].body_len-1000);
+      ogg_sync_wrote(&oy,og[1].body_len-1000);
       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
       
       fprintf(stderr,"ok.\n");
@@ -1326,13 +1403,13 @@ int main(void){
       fprintf(stderr,"Testing sync on 1+partial inputs... ");
       ogg_sync_reset(&oy); 
 
-      memcpy(ogg_sync_buffer(&oy,og[0].header_len),og[0].header,
-            og[0].header_len);
-      ogg_sync_wrote(&oy,og[0].header_len);
+      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
+            og[1].header_len);
+      ogg_sync_wrote(&oy,og[1].header_len);
 
-      memcpy(ogg_sync_buffer(&oy,og[0].body_len),og[0].body,
-            og[0].body_len);
-      ogg_sync_wrote(&oy,og[0].body_len);
+      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
+            og[1].body_len);
+      ogg_sync_wrote(&oy,og[1].body_len);
 
       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
             20);
@@ -1358,31 +1435,31 @@ int main(void){
       ogg_sync_reset(&oy); 
       
       /* 'garbage' */
-      memcpy(ogg_sync_buffer(&oy,og[0].body_len),og[0].body,
-            og[0].body_len);
-      ogg_sync_wrote(&oy,og[0].body_len);
+      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
+            og[1].body_len);
+      ogg_sync_wrote(&oy,og[1].body_len);
 
-      memcpy(ogg_sync_buffer(&oy,og[0].header_len),og[0].header,
-            og[0].header_len);
-      ogg_sync_wrote(&oy,og[0].header_len);
+      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
+            og[1].header_len);
+      ogg_sync_wrote(&oy,og[1].header_len);
 
-      memcpy(ogg_sync_buffer(&oy,og[0].body_len),og[0].body,
-            og[0].body_len);
-      ogg_sync_wrote(&oy,og[0].body_len);
+      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
+            og[1].body_len);
+      ogg_sync_wrote(&oy,og[1].body_len);
 
-      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
+      memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
             20);
       ogg_sync_wrote(&oy,20);
       if(ogg_sync_pageout(&oy,&og_de)>0)error();
       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
       if(ogg_sync_pageout(&oy,&og_de)>0)error();
 
-      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20,
-            og[1].header_len-20);
-      ogg_sync_wrote(&oy,og[1].header_len-20);
-      memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
-            og[1].body_len);
-      ogg_sync_wrote(&oy,og[1].body_len);
+      memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20,
+            og[2].header_len-20);
+      ogg_sync_wrote(&oy,og[2].header_len-20);
+      memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
+            og[2].body_len);
+      ogg_sync_wrote(&oy,og[2].body_len);
       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
 
       fprintf(stderr,"ok.\n");
@@ -1394,35 +1471,35 @@ int main(void){
       fprintf(stderr,"Testing recapture... ");
       ogg_sync_reset(&oy); 
 
-      memcpy(ogg_sync_buffer(&oy,og[0].header_len),og[0].header,
-            og[0].header_len);
-      ogg_sync_wrote(&oy,og[0].header_len);
-
-      memcpy(ogg_sync_buffer(&oy,og[0].body_len),og[0].body,
-            og[0].body_len);
-      ogg_sync_wrote(&oy,og[0].body_len);
-
-      memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
-            og[1].header_len);
-      ogg_sync_wrote(&oy,og[1].header_len);
-
       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
             og[1].header_len);
       ogg_sync_wrote(&oy,og[1].header_len);
 
-      if(ogg_sync_pageout(&oy,&og_de)<=0)error();
-
       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
-            og[1].body_len-5);
-      ogg_sync_wrote(&oy,og[1].body_len-5);
+            og[1].body_len);
+      ogg_sync_wrote(&oy,og[1].body_len);
 
       memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
             og[2].header_len);
       ogg_sync_wrote(&oy,og[2].header_len);
 
+      memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
+            og[2].header_len);
+      ogg_sync_wrote(&oy,og[2].header_len);
+
+      if(ogg_sync_pageout(&oy,&og_de)<=0)error();
+
       memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
-            og[2].body_len);
-      ogg_sync_wrote(&oy,og[2].body_len);
+            og[2].body_len-5);
+      ogg_sync_wrote(&oy,og[2].body_len-5);
+
+      memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header,
+            og[3].header_len);
+      ogg_sync_wrote(&oy,og[3].header_len);
+
+      memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body,
+            og[3].body_len);
+      ogg_sync_wrote(&oy,og[3].body_len);
 
       if(ogg_sync_pageout(&oy,&og_de)>0)error();
       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
index e21bd2d..ee74ba2 100644 (file)
@@ -14,7 +14,7 @@
  function: maintain the info structure, info <-> header packets
  author: Monty <xiphmont@mit.edu>
  modifications by: Monty
- last modification date: Oct 02 1999
+ last modification date: Oct 03 1999
 
  ********************************************************************/
 
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "modes.h"
+#include "bitwise.h"
 
 /* one test mode for now; temporary of course */
 int vorbis_info_modeset(vorbis_info *vi, int mode){
@@ -33,6 +34,7 @@ int vorbis_info_modeset(vorbis_info *vi, int mode){
   /* handle the flat settings first */
   memcpy(vi,&(predef_modes[mode]),sizeof(vorbis_info));
   vi->user_comments=calloc(1,sizeof(char *));
+  vi->vendor=strdup("Xiphophorus libVorbis I 19991003");
 
   return(0);
 }
@@ -47,18 +49,127 @@ int vorbis_info_add_comment(vorbis_info *vi,char *comment){
   return(0);
 }
 
+static int _v_writestring(oggpack_buffer *o,char *s){
+  while(*s){
+    _oggpack_write(o,*s++,8);
+  }
+}
+
+static char *_v_readstring(oggpack_buffer *o,int bytes){
+  char *ret=calloc(bytes+1,1);
+  char *ptr=ret;
+  while(bytes--){
+    *ptr++=_oggpack_read(o,8);
+  }
+  return(ret);
+}
+
 /* The Vorbis header is in three packets; the initial small packet in
-   the first page that identifies basic parameters, a second
-   [optional] packet with bitstream comments and a third packet that
-   holds the codebook. */
+   the first page that identifies basic parameters, a second packet
+   with bitstream comments and a third packet that holds the
+   codebook. */
 
 int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
 
 }
 
-int vorbis_info_headerout(vorbis_info *vi,ogg_packet *op){
-
+int vorbis_info_headerout(vorbis_info *vi,
+                         ogg_packet *op,
+                         ogg_packet *op_comm,
+                         ogg_packet *op_code){
+
+  oggpack_buffer opb;
+  /* initial header:
+
+     codec id     "vorbis"
+     codec ver    (4 octets, lsb first: currently 0x00)
+     pcm channels (4 octets, lsb first)
+     pcm rate     (4 octets, lsb first)
+     
+     small block  (4 octets, lsb first)
+     large block  (4 octets, lsb first)
+     envelopesa   (4 octets, lsb first)
+     envelopech   (4 octets, lsb first)
+     floororder   octet
+     flooroctaves octet
+     floorch      (4 octets, lsb first)
+   */
+
+  _oggpack_writeinit(&opb);
+  _v_writestring(&obp,"vorbis");
+  _oggpack_write(&opb,0x00,32);
+
+  _oggpack_write(&opb,vi->channels,32);
+  _oggpack_write(&opb,vi->rate,32);
+  _oggpack_write(&opb,vi->smallblock,32);
+  _oggpack_write(&opb,vi->largeblock,32);
+  _oggpack_write(&opb,vi->envelopesa,32);
+  _oggpack_write(&opb,vi->envelopech,32);
+  _oggpack_write(&opb,vi->floororder,8);
+  _oggpack_write(&opb,vi->flooroctaves,8);
+  _oggpack_write(&opb,vi->floorch,32);
+
+  /* build the packet */
+  if(vi->header)free(vi->header);
+  vi->header=memcpy(opb.buffer,_oggpack_bytes(&opb));
+  op->packet=vi->header;
+  op->bytes=_oggpack_bytes(&opb);
+  op->b_o_s=1;
+  op->e_o_s=0;
+  op->frameno=0;
+
+  /* comment header:
+     vendor len     (4 octets, lsb first)
+     vendor and id  (n octects as above)
+     comments       (4 octets, lsb first)
+     comment 0 len  (4 octets, lsb first)
+     comment 0 len  (n octets as above)
+     ...
+     comment n-1 len  (4 octets, lsb first)
+     comment 0-1 len  (n octets as above)
+  */
+
+  _oggpack_reset(&opb);
+  if(vi->vendor){
+    _oggpack_write(&opb,strlen(vi->vendor),32);
+    _oggpack_write(&opb,vi->vendor,strlen(vi->vendor));
+  }else{
+    _oggpack_write(&opb,0,32);
+  }
+  
+  _oggpack_write(&opb,vi->max_comment,32);
+  if(vi->max_comment){
+    int i;
+    for(i=0;i<=vi->max_comment;i++){
+      if(vi->user_comments[i]){
+       _oggpack_write(&opb,strlen(vi->user_comments[i]),32);
+       _oggpack_write(&opb,vi->user_comments[i],strlen(vi->user_comments[i]));
+      }else{
+       _oggpack_write(&opb,0,32);
+      }
+    }
+  }
+  
+  if(vi->header1)free(vi->header1);
+  vi->header1=memcpy(opb.buffer,_oggpack_bytes(&opb));
+  op_comm->packet=vi->header1;
+  op_comm->bytes=_oggpack_bytes(&opb);
+  op_comm->b_o_s=0;
+  op_comm->e_o_s=0;
+  op_comm->frameno=0;
+
+  /* codebook header:
+     nul so far; not encoded yet */
+
+  if(vi->header2)free(vi->header2);
+  vi->header2=NULL;
+  op_code->packet=vi->header2;
+  op_code->bytes=0;
+  op_code->b_o_s=0;
+  op_code->e_o_s=0;
+  op_code->frameno=0;
 
+  return(0);
 }
 
 int vorbis_info_clear(vorbis_info *vi){
@@ -76,6 +187,11 @@ int vorbis_info_clear(vorbis_info *vi){
   /* vendor string */
   if(vi->vendor)free(vi->vendor);
 
+  /* local encoding storage */
+  if(vi->header)free(vi->header);
+  if(vi->header1)free(vi->header1);
+  if(vi->header2)free(vi->header2);
+
   memset(vi,0,sizeof(vorbis_info));
 }
   
index d5ad4e1..6927adf 100644 (file)
@@ -26,7 +26,8 @@
 
 vorbis_info predef_modes[]={
   /* CD quality stereo, no channel coupling */
-  { 2, 44100, 0, NULL, 0, NULL, 512, 2048, 64, 2, 30, 5, 2, 0, 0, 10, .5 },
+  { 2, 44100, 0, NULL, 0, NULL, 512, 2048, 64, 2, 30, 5, 2, 0, 0, 10, .5,
+                                            NULL,NULL,NULL},
 
 };