misc/libtremor/tremor/vorbisfile.c
changeset 7849 a12155461b34
parent 7697 767d3c4153a1
child 7859 519d5bc91dd3
equal deleted inserted replaced
7848:775a72905708 7849:a12155461b34
    10  * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
    10  * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
    11  *                                                                  *
    11  *                                                                  *
    12  ********************************************************************
    12  ********************************************************************
    13 
    13 
    14  function: stdio-based convenience library for opening/seeking/decoding
    14  function: stdio-based convenience library for opening/seeking/decoding
    15  last mod: $Id: vorbisfile.c,v 1.6.2.4 2003/04/29 04:03:27 xiphmont Exp $
    15  last mod: $Id: vorbisfile.c,v 1.6 2003/03/30 23:40:56 xiphmont Exp $
    16 
    16 
    17  ********************************************************************/
    17  ********************************************************************/
    18 
    18 
    19 #include <stdlib.h>
    19 #include <stdlib.h>
    20 #include <stdio.h>
    20 #include <stdio.h>
    21 #include <errno.h>
    21 #include <errno.h>
    22 #include <string.h>
    22 #include <string.h>
    23 #include <math.h>
    23 #include <math.h>
    24 
    24 
    25 #include "codec_internal.h"
    25 #include "ivorbiscodec.h"
    26 #include "ivorbisfile.h"
    26 #include "ivorbisfile.h"
    27 
    27 
    28 #include "os.h"
       
    29 #include "misc.h"
    28 #include "misc.h"
    30 
       
    31 #define  NOTOPEN   0
       
    32 #define  PARTOPEN  1
       
    33 #define  OPENED    2
       
    34 #define  STREAMSET 3 /* serialno and link set, but not to current link */
       
    35 #define  LINKSET   4 /* serialno and link set to current link */
       
    36 #define  INITSET   5
       
    37 
    29 
    38 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
    30 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
    39    one logical bitstream arranged end to end (the only form of Ogg
    31    one logical bitstream arranged end to end (the only form of Ogg
    40    multiplexing allowed in a Vorbis bitstream; grouping [parallel
    32    multiplexing allowed in a Vorbis bitstream; grouping [parallel
    41    multiplexing] is not allowed in Vorbis) */
    33    multiplexing] is not allowed in Vorbis) */
    70   errno=0;
    62   errno=0;
    71   if(vf->datasource){
    63   if(vf->datasource){
    72     unsigned char *buffer=ogg_sync_bufferin(vf->oy,CHUNKSIZE);
    64     unsigned char *buffer=ogg_sync_bufferin(vf->oy,CHUNKSIZE);
    73     long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
    65     long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
    74     if(bytes>0)ogg_sync_wrote(vf->oy,bytes);
    66     if(bytes>0)ogg_sync_wrote(vf->oy,bytes);
    75     if(bytes==0 && errno)return -1;
    67     if(bytes==0 && errno)return(-1);
    76     return bytes;
    68     return(bytes);
    77   }else
    69   }else
    78     return 0;
    70     return(0);
    79 }
    71 }
    80 
    72 
    81 /* save a tiny smidge of verbosity to make the code more readable */
    73 /* save a tiny smidge of verbosity to make the code more readable */
    82 static void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
    74 static void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
    83   if(vf->datasource){ 
    75   if(vf->datasource){ 
   109 				  ogg_int64_t boundary){
   101 				  ogg_int64_t boundary){
   110   if(boundary>0)boundary+=vf->offset;
   102   if(boundary>0)boundary+=vf->offset;
   111   while(1){
   103   while(1){
   112     long more;
   104     long more;
   113 
   105 
   114     if(boundary>0 && vf->offset>=boundary)return OV_FALSE;
   106     if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
   115     more=ogg_sync_pageseek(vf->oy,og);
   107     more=ogg_sync_pageseek(vf->oy,og);
   116     
   108     
   117     if(more<0){
   109     if(more<0){
   118       /* skipped n bytes */
   110       /* skipped n bytes */
   119       vf->offset-=more;
   111       vf->offset-=more;
   120     }else{
   112     }else{
   121       if(more==0){
   113       if(more==0){
   122 	/* send more paramedics */
   114 	/* send more paramedics */
   123 	if(!boundary)return OV_FALSE;
   115 	if(!boundary)return(OV_FALSE);
   124 	{
   116 	{
   125 	  long ret=_get_data(vf);
   117 	  long ret=_get_data(vf);
   126 	  if(ret==0)return OV_EOF;
   118 	  if(ret==0)return(OV_EOF);
   127 	  if(ret<0)return OV_EREAD;
   119 	  if(ret<0)return(OV_EREAD);
   128 	}
   120 	}
   129       }else{
   121       }else{
   130 	/* got a page.  Return the offset at the page beginning,
   122 	/* got a page.  Return the offset at the page beginning,
   131            advance the internal offset past the page end */
   123            advance the internal offset past the page end */
   132 	ogg_int64_t ret=vf->offset;
   124 	ogg_int64_t ret=vf->offset;
   133 	vf->offset+=more;
   125 	vf->offset+=more;
   134 	return ret;
   126 	return(ret);
   135 	
   127 	
   136       }
   128       }
   137     }
   129     }
   138   }
   130   }
   139 }
   131 }
   155     if(begin<0)
   147     if(begin<0)
   156       begin=0;
   148       begin=0;
   157     _seek_helper(vf,begin);
   149     _seek_helper(vf,begin);
   158     while(vf->offset<end){
   150     while(vf->offset<end){
   159       ret=_get_next_page(vf,og,end-vf->offset);
   151       ret=_get_next_page(vf,og,end-vf->offset);
   160       if(ret==OV_EREAD)return OV_EREAD;
   152       if(ret==OV_EREAD)return(OV_EREAD);
   161       if(ret<0){
   153       if(ret<0){
   162 	break;
   154 	break;
   163       }else{
   155       }else{
   164 	offset=ret;
   156 	offset=ret;
   165       }
   157       }
   169   /* we have the offset.  Actually snork and hold the page now */
   161   /* we have the offset.  Actually snork and hold the page now */
   170   _seek_helper(vf,offset);
   162   _seek_helper(vf,offset);
   171   ret=_get_next_page(vf,og,CHUNKSIZE);
   163   ret=_get_next_page(vf,og,CHUNKSIZE);
   172   if(ret<0)
   164   if(ret<0)
   173     /* this shouldn't be possible */
   165     /* this shouldn't be possible */
   174     return OV_EFAULT;
   166     return(OV_EFAULT);
   175 
   167 
   176   return offset;
   168   return(offset);
   177 }
   169 }
   178 
   170 
   179 /* finds each bitstream link one at a time using a bisection search
   171 /* finds each bitstream link one at a time using a bisection search
   180    (has to begin by knowing the offset of the lb's initial page).
   172    (has to begin by knowing the offset of the lb's initial page).
   181    Recurses for each link so it can alloc the link storage after
   173    Recurses for each link so it can alloc the link storage after
   202       bisect=(searched+endsearched)/2;
   194       bisect=(searched+endsearched)/2;
   203     }
   195     }
   204     
   196     
   205     _seek_helper(vf,bisect);
   197     _seek_helper(vf,bisect);
   206     ret=_get_next_page(vf,&og,-1);
   198     ret=_get_next_page(vf,&og,-1);
   207     if(ret==OV_EREAD)return OV_EREAD;
   199     if(ret==OV_EREAD)return(OV_EREAD);
   208     if(ret<0 || ogg_page_serialno(&og)!=currentno){
   200     if(ret<0 || ogg_page_serialno(&og)!=currentno){
   209       endsearched=bisect;
   201       endsearched=bisect;
   210       if(ret>=0)next=ret;
   202       if(ret>=0)next=ret;
   211     }else{
   203     }else{
   212       searched=ret+og.header_len+og.body_len;
   204       searched=ret+og.header_len+og.body_len;
   214     ogg_page_release(&og);
   206     ogg_page_release(&og);
   215   }
   207   }
   216 
   208 
   217   _seek_helper(vf,next);
   209   _seek_helper(vf,next);
   218   ret=_get_next_page(vf,&og,-1);
   210   ret=_get_next_page(vf,&og,-1);
   219   if(ret==OV_EREAD)return OV_EREAD;
   211   if(ret==OV_EREAD)return(OV_EREAD);
   220   
   212   
   221   if(searched>=end || ret<0){
   213   if(searched>=end || ret<0){
   222     ogg_page_release(&og);
   214     ogg_page_release(&og);
   223     vf->links=m+1;
   215     vf->links=m+1;
   224     vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
   216     vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
   226     vf->offsets[m+1]=searched;
   218     vf->offsets[m+1]=searched;
   227   }else{
   219   }else{
   228     ret=_bisect_forward_serialno(vf,next,vf->offset,
   220     ret=_bisect_forward_serialno(vf,next,vf->offset,
   229 				 end,ogg_page_serialno(&og),m+1);
   221 				 end,ogg_page_serialno(&og),m+1);
   230     ogg_page_release(&og);
   222     ogg_page_release(&og);
   231     if(ret==OV_EREAD)return OV_EREAD;
   223     if(ret==OV_EREAD)return(OV_EREAD);
   232   }
   224   }
   233   
   225   
   234   vf->offsets[m]=begin;
   226   vf->offsets[m]=begin;
   235   vf->serialnos[m]=currentno;
   227   vf->serialnos[m]=currentno;
   236   return 0;
   228   return(0);
   237 }
       
   238 
       
   239 static int _decode_clear(OggVorbis_File *vf){
       
   240   if(vf->ready_state==INITSET){
       
   241     vorbis_dsp_destroy(vf->vd);
       
   242     vf->vd=0;
       
   243     vf->ready_state=STREAMSET;
       
   244   }
       
   245   
       
   246   if(vf->ready_state>=STREAMSET){
       
   247     vorbis_info_clear(&vf->vi);
       
   248     vorbis_comment_clear(&vf->vc);
       
   249     vf->ready_state=OPENED;
       
   250   }
       
   251   return 0;
       
   252 }
   229 }
   253 
   230 
   254 /* uses the local ogg_stream storage in vf; this is important for
   231 /* uses the local ogg_stream storage in vf; this is important for
   255    non-streaming input sources */
   232    non-streaming input sources */
   256 /* consumes the page that's passed in (if any) */
   233 /* consumes the page that's passed in (if any) */
   257 /* state is LINKSET upon successful return */
       
   258 
   234 
   259 static int _fetch_headers(OggVorbis_File *vf,
   235 static int _fetch_headers(OggVorbis_File *vf,
   260 			  vorbis_info *vi,
   236 			  vorbis_info *vi,
   261 			  vorbis_comment *vc,
   237 			  vorbis_comment *vc,
   262 			  ogg_uint32_t *serialno,
   238 			  ogg_uint32_t *serialno,
   263 			  ogg_page *og_ptr){
   239 			  ogg_page *og_ptr){
   264   ogg_page og={0,0,0,0};
   240   ogg_page og={0,0,0,0};
   265   ogg_packet op={0,0,0,0,0,0};
   241   ogg_packet op={0,0,0,0,0,0};
   266   int i,ret;
   242   int i,ret;
   267   
   243   
   268   if(vf->ready_state>OPENED)_decode_clear(vf);
       
   269 
       
   270   if(!og_ptr){
   244   if(!og_ptr){
   271     ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
   245     ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
   272     if(llret==OV_EREAD)return OV_EREAD;
   246     if(llret==OV_EREAD)return(OV_EREAD);
   273     if(llret<0)return OV_ENOTVORBIS;
   247     if(llret<0)return OV_ENOTVORBIS;
   274     og_ptr=&og;
   248     og_ptr=&og;
   275   }
   249   }
   276 
   250 
   277   ogg_stream_reset_serialno(vf->os,ogg_page_serialno(og_ptr));
   251   ogg_stream_reset_serialno(vf->os,ogg_page_serialno(og_ptr));
   278   if(serialno)*serialno=vf->os->serialno;
   252   if(serialno)*serialno=vf->os->serialno;
       
   253   vf->ready_state=STREAMSET;
   279   
   254   
   280   /* extract the initial header from the first page and verify that the
   255   /* extract the initial header from the first page and verify that the
   281      Ogg bitstream is in fact Vorbis data */
   256      Ogg bitstream is in fact Vorbis data */
   282   
   257   
   283   vorbis_info_init(vi);
   258   vorbis_info_init(vi);
   291       if(result==0)break;
   266       if(result==0)break;
   292       if(result==-1){
   267       if(result==-1){
   293 	ret=OV_EBADHEADER;
   268 	ret=OV_EBADHEADER;
   294 	goto bail_header;
   269 	goto bail_header;
   295       }
   270       }
   296       if((ret=vorbis_dsp_headerin(vi,vc,&op))){
   271       if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
   297 	goto bail_header;
   272 	goto bail_header;
   298       }
   273       }
   299       i++;
   274       i++;
   300     }
   275     }
   301     if(i<3)
   276     if(i<3)
   305       }
   280       }
   306   }
   281   }
   307 
   282 
   308   ogg_packet_release(&op);
   283   ogg_packet_release(&op);
   309   ogg_page_release(&og);
   284   ogg_page_release(&og);
   310   vf->ready_state=LINKSET;
       
   311   return 0; 
   285   return 0; 
   312 
   286 
   313  bail_header:
   287  bail_header:
   314   ogg_packet_release(&op);
   288   ogg_packet_release(&op);
   315   ogg_page_release(&og);
   289   ogg_page_release(&og);
   318   vf->ready_state=OPENED;
   292   vf->ready_state=OPENED;
   319 
   293 
   320   return ret;
   294   return ret;
   321 }
   295 }
   322 
   296 
   323 /* we no longer preload all vorbis_info (and the associated
   297 /* last step of the OggVorbis_File initialization; get all the
   324    codec_setup) structs.  Call this to seek and fetch the info from
   298    vorbis_info structs and PCM positions.  Only called by the seekable
   325    the bitstream, if needed */
   299    initialization (local stream storage is hacked slightly; pay
   326 static int _set_link_number(OggVorbis_File *vf,int link){
   300    attention to how that's done) */
   327   if(link != vf->current_link) _decode_clear(vf);
       
   328   if(vf->ready_state<STREAMSET){
       
   329     _seek_helper(vf,vf->offsets[link]);
       
   330     ogg_stream_reset_serialno(vf->os,vf->serialnos[link]);
       
   331     vf->current_serialno=vf->serialnos[link];
       
   332     vf->current_link=link;
       
   333     return _fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,NULL);
       
   334   }
       
   335   return 0;
       
   336 }
       
   337 
       
   338 static int _set_link_number_preserve_pos(OggVorbis_File *vf,int link){
       
   339   ogg_int64_t pos=vf->offset;
       
   340   int ret=_set_link_number(vf,link);
       
   341   if(ret)return ret;
       
   342   _seek_helper(vf,pos);
       
   343   if(pos<vf->offsets[link] || pos>=vf->offsets[link+1])
       
   344     vf->ready_state=STREAMSET;
       
   345   return 0;
       
   346 }
       
   347 
       
   348 /* last step of the OggVorbis_File initialization; get all the offset
       
   349    positions.  Only called by the seekable initialization (local
       
   350    stream storage is hacked slightly; pay attention to how that's
       
   351    done) */
       
   352 
   301 
   353 /* this is void and does not propogate errors up because we want to be
   302 /* this is void and does not propogate errors up because we want to be
   354    able to open and use damaged bitstreams as well as we can.  Just
   303    able to open and use damaged bitstreams as well as we can.  Just
   355    watch out for missing information for links in the OggVorbis_File
   304    watch out for missing information for links in the OggVorbis_File
   356    struct */
   305    struct */
   357 static void _prefetch_all_offsets(OggVorbis_File *vf, ogg_int64_t dataoffset){
   306 static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){
   358   ogg_page og={0,0,0,0};
   307   ogg_page og={0,0,0,0};
   359   int i;
   308   int i;
   360   ogg_int64_t ret;
   309   ogg_int64_t ret;
   361   
   310   
       
   311   vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
       
   312   vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
   362   vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
   313   vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
   363   vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
   314   vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
   364   
   315   
   365   for(i=0;i<vf->links;i++){
   316   for(i=0;i<vf->links;i++){
   366     if(i==0){
   317     if(i==0){
   371     }else{
   322     }else{
   372 
   323 
   373       /* seek to the location of the initial header */
   324       /* seek to the location of the initial header */
   374 
   325 
   375       _seek_helper(vf,vf->offsets[i]);
   326       _seek_helper(vf,vf->offsets[i]);
   376       if(_fetch_headers(vf,&vf->vi,&vf->vc,NULL,NULL)<0){
   327       if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
   377     	vf->dataoffsets[i]=-1;
   328     	vf->dataoffsets[i]=-1;
   378       }else{
   329       }else{
   379 	vf->dataoffsets[i]=vf->offset;
   330 	vf->dataoffsets[i]=vf->offset;
   380       }
   331       }
   381     }
   332     }
   405 
   356 
   406 	/* count blocksizes of all frames in the page */
   357 	/* count blocksizes of all frames in the page */
   407 	ogg_stream_pagein(vf->os,&og);
   358 	ogg_stream_pagein(vf->os,&og);
   408 	while((result=ogg_stream_packetout(vf->os,&op))){
   359 	while((result=ogg_stream_packetout(vf->os,&op))){
   409 	  if(result>0){ /* ignore holes */
   360 	  if(result>0){ /* ignore holes */
   410 	    long thisblock=vorbis_packet_blocksize(&vf->vi,&op);
   361 	    long thisblock=vorbis_packet_blocksize(vf->vi+i,&op);
   411 	    if(lastblock!=-1)
   362 	    if(lastblock!=-1)
   412 	      accumulated+=(lastblock+thisblock)>>2;
   363 	      accumulated+=(lastblock+thisblock)>>2;
   413 	    lastblock=thisblock;
   364 	    lastblock=thisblock;
   414 	  }
   365 	  }
   415 	}
   366 	}
   437 
   388 
   438       while(1){
   389       while(1){
   439 	ret=_get_prev_page(vf,&og);
   390 	ret=_get_prev_page(vf,&og);
   440 	if(ret<0){
   391 	if(ret<0){
   441 	  /* this should not be possible */
   392 	  /* this should not be possible */
   442 	  vorbis_info_clear(&vf->vi);
   393 	  vorbis_info_clear(vf->vi+i);
   443 	  vorbis_comment_clear(&vf->vc);
   394 	  vorbis_comment_clear(vf->vc+i);
   444 	  break;
   395 	  break;
   445 	}
   396 	}
   446 	if(ogg_page_granulepos(&og)!=-1){
   397 	if(ogg_page_granulepos(&og)!=-1){
   447 	  vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
   398 	  vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
   448 	  break;
   399 	  break;
   452     }
   403     }
   453   }
   404   }
   454   ogg_page_release(&og);
   405   ogg_page_release(&og);
   455 }
   406 }
   456 
   407 
   457 static int _make_decode_ready(OggVorbis_File *vf){
   408 static void _make_decode_ready(OggVorbis_File *vf){
   458   int i;
   409   if(vf->ready_state!=STREAMSET)return;
   459   switch(vf->ready_state){
   410   if(vf->seekable){
   460   case OPENED:
   411     vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
   461   case STREAMSET:
   412   }else{
   462     for(i=0;i<vf->links;i++)
   413     vorbis_synthesis_init(&vf->vd,vf->vi);
   463       if(vf->offsets[i+1]>=vf->offset)break;
   414   }    
   464     if(i==vf->links)return -1;
   415   vorbis_block_init(&vf->vd,&vf->vb);
   465     i=_set_link_number_preserve_pos(vf,i);
   416   vf->ready_state=INITSET;
   466     if(i)return i;
   417   vf->bittrack=0;
   467     /* fall through */
   418   vf->samptrack=0;
   468   case LINKSET:
   419   return;
   469     vf->vd=vorbis_dsp_create(&vf->vi);
       
   470     vf->ready_state=INITSET;
       
   471     vf->bittrack=0;
       
   472     vf->samptrack=0;
       
   473   case INITSET:
       
   474     return 0;
       
   475   default:
       
   476     return -1;
       
   477   }
       
   478   
       
   479 }
   420 }
   480 
   421 
   481 static int _open_seekable2(OggVorbis_File *vf){
   422 static int _open_seekable2(OggVorbis_File *vf){
   482   ogg_uint32_t serialno=vf->current_serialno;
   423   ogg_uint32_t serialno=vf->current_serialno;
   483   ogg_uint32_t tempserialno;
   424   ogg_uint32_t tempserialno;
   491   vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
   432   vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
   492   
   433   
   493   /* We get the offset for the last page of the physical bitstream.
   434   /* We get the offset for the last page of the physical bitstream.
   494      Most OggVorbis files will contain a single logical bitstream */
   435      Most OggVorbis files will contain a single logical bitstream */
   495   end=_get_prev_page(vf,&og);
   436   end=_get_prev_page(vf,&og);
   496   if(end<0)return end;
   437   if(end<0)return(end);
   497 
   438 
   498   /* more than one logical bitstream? */
   439   /* more than one logical bitstream? */
   499   tempserialno=ogg_page_serialno(&og);
   440   tempserialno=ogg_page_serialno(&og);
   500   ogg_page_release(&og);
   441   ogg_page_release(&og);
   501 
   442 
   502   if(tempserialno!=serialno){
   443   if(tempserialno!=serialno){
   503 
   444 
   504     /* Chained bitstream. Bisect-search each logical bitstream
   445     /* Chained bitstream. Bisect-search each logical bitstream
   505        section.  Do so based on serial number only */
   446        section.  Do so based on serial number only */
   506     if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return OV_EREAD;
   447     if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD);
   507 
   448 
   508   }else{
   449   }else{
   509 
   450 
   510     /* Only one logical bitstream */
   451     /* Only one logical bitstream */
   511     if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return OV_EREAD;
   452     if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD);
   512 
   453 
   513   }
   454   }
   514 
   455 
   515   /* the initial header memory is referenced by vf after; don't free it */
   456   /* the initial header memory is referenced by vf after; don't free it */
   516   _prefetch_all_offsets(vf,dataoffset);
   457   _prefetch_all_headers(vf,dataoffset);
   517   return ov_raw_seek(vf,0);
   458   return(ov_raw_seek(vf,0));
       
   459 }
       
   460 
       
   461 /* clear out the current logical bitstream decoder */ 
       
   462 static void _decode_clear(OggVorbis_File *vf){
       
   463   vorbis_dsp_clear(&vf->vd);
       
   464   vorbis_block_clear(&vf->vb);
       
   465   vf->ready_state=OPENED;
   518 }
   466 }
   519 
   467 
   520 /* fetch and process a packet.  Handles the case where we're at a
   468 /* fetch and process a packet.  Handles the case where we're at a
   521    bitstream boundary and dumps the decoding machine.  If the decoding
   469    bitstream boundary and dumps the decoding machine.  If the decoding
   522    machine is unloaded, it loads it.  It also keeps pcm_offset up to
   470    machine is unloaded, it loads it.  It also keeps pcm_offset up to
   551 	  goto cleanup;
   499 	  goto cleanup;
   552 	}
   500 	}
   553 	if(result>0){
   501 	if(result>0){
   554 	  /* got a packet.  process it */
   502 	  /* got a packet.  process it */
   555 	  granulepos=op.granulepos;
   503 	  granulepos=op.granulepos;
   556 	  if(!vorbis_dsp_synthesis(vf->vd,&op,1)){ /* lazy check for lazy
   504 	  if(!vorbis_synthesis(&vf->vb,&op,1)){ /* lazy check for lazy
   557 						      header handling.  The
   505 						      header handling.  The
   558 						      header packets aren't
   506 						      header packets aren't
   559 						      audio, so if/when we
   507 						      audio, so if/when we
   560 						      submit them,
   508 						      submit them,
   561 						      vorbis_synthesis will
   509 						      vorbis_synthesis will
   562 						      reject them */
   510 						      reject them */
   563 	    
   511 
   564 	    vf->samptrack+=vorbis_dsp_pcmout(vf->vd,NULL,0);
   512 	    /* suck in the synthesis data and track bitrate */
   565 	    vf->bittrack+=op.bytes*8;
   513 	    {
       
   514 	      int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
       
   515 	      /* for proper use of libvorbis within libvorbisfile,
       
   516                  oldsamples will always be zero. */
       
   517 	      if(oldsamples){
       
   518 		ret=OV_EFAULT;
       
   519 		goto cleanup;
       
   520 	      }
       
   521 
       
   522 	      vorbis_synthesis_blockin(&vf->vd,&vf->vb);
       
   523 	      vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
       
   524 	      vf->bittrack+=op.bytes*8;
       
   525 	    }
   566 	  
   526 	  
   567 	    /* update the pcm offset. */
   527 	    /* update the pcm offset. */
   568 	    if(granulepos!=-1 && !op.e_o_s){
   528 	    if(granulepos!=-1 && !op.e_o_s){
   569 	      int link=(vf->seekable?vf->current_link:0);
   529 	      int link=(vf->seekable?vf->current_link:0);
   570 	      int i,samples;
   530 	      int i,samples;
   587 	      if(granulepos<0)granulepos=0; /* actually, this
   547 	      if(granulepos<0)granulepos=0; /* actually, this
   588 					       shouldn't be possible
   548 					       shouldn't be possible
   589 					       here unless the stream
   549 					       here unless the stream
   590 					       is very broken */
   550 					       is very broken */
   591 
   551 
   592 	      samples=vorbis_dsp_pcmout(vf->vd,NULL,0);
   552 	      samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
   593 	    
   553 	    
   594 	      granulepos-=samples;
   554 	      granulepos-=samples;
   595 	      for(i=0;i<link;i++)
   555 	      for(i=0;i<link;i++)
   596 	        granulepos+=vf->pcmlengths[i*2+1];
   556 	        granulepos+=vf->pcmlengths[i*2+1];
   597 	      vf->pcm_offset=granulepos;
   557 	      vf->pcm_offset=granulepos;
   627 	    ret=OV_EOF;
   587 	    ret=OV_EOF;
   628 	    goto cleanup;
   588 	    goto cleanup;
   629 	  }
   589 	  }
   630 
   590 
   631 	  _decode_clear(vf);
   591 	  _decode_clear(vf);
       
   592 	  
       
   593 	  if(!vf->seekable){
       
   594 	    vorbis_info_clear(vf->vi);
       
   595 	    vorbis_comment_clear(vf->vc);
       
   596 	  }
   632 	}
   597 	}
   633       }
   598       }
   634     }
   599     }
   635 
   600 
   636     /* Do we need to load a new machine before submitting the page? */
   601     /* Do we need to load a new machine before submitting the page? */
   644        boundary if we just left the previous logical bitstream and
   609        boundary if we just left the previous logical bitstream and
   645        we're now nominally at the header of the next bitstream
   610        we're now nominally at the header of the next bitstream
   646     */
   611     */
   647 
   612 
   648     if(vf->ready_state!=INITSET){ 
   613     if(vf->ready_state!=INITSET){ 
   649       int link,ret;
   614       int link;
   650 
   615 
   651       if(vf->ready_state<STREAMSET){
   616       if(vf->ready_state<STREAMSET){
   652 	if(vf->seekable){
   617 	if(vf->seekable){
   653 	  vf->current_serialno=ogg_page_serialno(&og);
   618 	  vf->current_serialno=ogg_page_serialno(&og);
   654 	  
   619 	  
   660 	  if(link==vf->links){
   625 	  if(link==vf->links){
   661 	    ret=OV_EBADLINK; /* sign of a bogus stream.  error out,
   626 	    ret=OV_EBADLINK; /* sign of a bogus stream.  error out,
   662 				leave machine uninitialized */
   627 				leave machine uninitialized */
   663 	    goto cleanup;
   628 	    goto cleanup;
   664 	  }
   629 	  }
   665 
   630 	  
   666 	  vf->current_link=link;
   631 	  vf->current_link=link;
   667 	  ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
   632 	  
   668 	  if(ret) goto cleanup;
   633 	  ogg_stream_reset_serialno(vf->os,vf->current_serialno);
       
   634 	  vf->ready_state=STREAMSET;
   669 	  
   635 	  
   670 	}else{
   636 	}else{
   671 	  /* we're streaming */
   637 	  /* we're streaming */
   672 	  /* fetch the three header packets, build the info struct */
   638 	  /* fetch the three header packets, build the info struct */
   673 	  
   639 	  
   674 	  int ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
   640 	  int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
   675 	  if(ret) goto cleanup;
   641 	  if(ret) goto cleanup;
   676 	  vf->current_link++;
   642 	  vf->current_link++;
       
   643 	  link=0;
   677 	}
   644 	}
   678       }
   645       }
   679       
   646       
   680       if(_make_decode_ready(vf)) return OV_EBADLINK;
   647       _make_decode_ready(vf);
   681     }
   648     }
   682     ogg_stream_pagein(vf->os,&og);
   649     ogg_stream_pagein(vf->os,&og);
   683   }
   650   }
   684  cleanup:
   651  cleanup:
   685   ogg_packet_release(&op);
   652   ogg_packet_release(&op);
   688 }
   655 }
   689 
   656 
   690 /* if, eg, 64 bit stdio is configured by default, this will build with
   657 /* if, eg, 64 bit stdio is configured by default, this will build with
   691    fseek64 */
   658    fseek64 */
   692 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
   659 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
   693   if(f==NULL)return -1;
   660   if(f==NULL)return(-1);
   694   return fseek(f,off,whence);
   661   return fseek(f,off,whence);
   695 }
   662 }
   696 
   663 
   697 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
   664 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
   698 		     long ibytes, ov_callbacks callbacks){
   665 		     long ibytes, ov_callbacks callbacks){
   699   int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
   666   int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
   700   int ret;
   667   int ret;
   701 
   668 
   702   memset(vf,0,sizeof(*vf));
   669   memset(vf,0,sizeof(*vf));
   703 
       
   704   /* Tremor assumes in multiple places that right shift of a signed
       
   705      integer is an arithmetic shift */
       
   706   if( (-1>>1) != -1) return OV_EIMPL;
       
   707 
       
   708   vf->datasource=f;
   670   vf->datasource=f;
   709   vf->callbacks = callbacks;
   671   vf->callbacks = callbacks;
   710 
   672 
   711   /* init the framing state */
   673   /* init the framing state */
   712   vf->oy=ogg_sync_create();
   674   vf->oy=ogg_sync_create();
   725   if(offsettest!=-1)vf->seekable=1;
   687   if(offsettest!=-1)vf->seekable=1;
   726 
   688 
   727   /* No seeking yet; Set up a 'single' (current) logical bitstream
   689   /* No seeking yet; Set up a 'single' (current) logical bitstream
   728      entry for partial open */
   690      entry for partial open */
   729   vf->links=1;
   691   vf->links=1;
       
   692   vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
       
   693   vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
   730   vf->os=ogg_stream_create(-1); /* fill in the serialno later */
   694   vf->os=ogg_stream_create(-1); /* fill in the serialno later */
   731 
   695 
   732   /* Try to fetch the headers, maintaining all the storage */
   696   /* Try to fetch the headers, maintaining all the storage */
   733   if((ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,NULL))<0){
   697   if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
   734     vf->datasource=NULL;
   698     vf->datasource=NULL;
   735     ov_clear(vf);
   699     ov_clear(vf);
   736   }else if(vf->ready_state < PARTOPEN)
   700   }else if(vf->ready_state < PARTOPEN)
   737     vf->ready_state=PARTOPEN;
   701     vf->ready_state=PARTOPEN;
   738   return ret;
   702   return(ret);
   739 }
   703 }
   740 
   704 
   741 static int _ov_open2(OggVorbis_File *vf){
   705 static int _ov_open2(OggVorbis_File *vf){
   742   if(vf->ready_state < OPENED)
   706   if(vf->ready_state < OPENED)
   743     vf->ready_state=OPENED;
   707     vf->ready_state=OPENED;
   745     int ret=_open_seekable2(vf);
   709     int ret=_open_seekable2(vf);
   746     if(ret){
   710     if(ret){
   747       vf->datasource=NULL;
   711       vf->datasource=NULL;
   748       ov_clear(vf);
   712       ov_clear(vf);
   749     }
   713     }
   750     return ret;
   714     return(ret);
   751   }
   715   }
   752   return 0;
   716   return 0;
   753 }
   717 }
   754 
   718 
   755 
   719 
   756 /* clear out the OggVorbis_File struct */
   720 /* clear out the OggVorbis_File struct */
   757 int ov_clear(OggVorbis_File *vf){
   721 int ov_clear(OggVorbis_File *vf){
   758   if(vf){
   722   if(vf){
   759     vorbis_dsp_destroy(vf->vd);
   723     vorbis_block_clear(&vf->vb);
   760     vf->vd=0;
   724     vorbis_dsp_clear(&vf->vd);
   761     ogg_stream_destroy(vf->os);
   725     ogg_stream_destroy(vf->os);
   762     vorbis_info_clear(&vf->vi);
   726     
   763     vorbis_comment_clear(&vf->vc);
   727     if(vf->vi && vf->links){
       
   728       int i;
       
   729       for(i=0;i<vf->links;i++){
       
   730 	vorbis_info_clear(vf->vi+i);
       
   731 	vorbis_comment_clear(vf->vc+i);
       
   732       }
       
   733       _ogg_free(vf->vi);
       
   734       _ogg_free(vf->vc);
       
   735     }
   764     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
   736     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
   765     if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
   737     if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
   766     if(vf->serialnos)_ogg_free(vf->serialnos);
   738     if(vf->serialnos)_ogg_free(vf->serialnos);
   767     if(vf->offsets)_ogg_free(vf->offsets);
   739     if(vf->offsets)_ogg_free(vf->offsets);
   768     ogg_sync_destroy(vf->oy);
   740     ogg_sync_destroy(vf->oy);
   769 
   741 
   770     if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
   742     if(vf->datasource && vf->callbacks.close_func)
       
   743       (vf->callbacks.close_func)(vf->datasource);
   771     memset(vf,0,sizeof(*vf));
   744     memset(vf,0,sizeof(*vf));
   772   }
   745   }
   773 #ifdef DEBUG_LEAKS
   746 #ifdef DEBUG_LEAKS
   774   _VDBG_dump();
   747   _VDBG_dump();
   775 #endif
   748 #endif
   776   return 0;
   749   return(0);
   777 }
   750 }
   778 
   751 
   779 /* inspects the OggVorbis file and finds/documents all the logical
   752 /* inspects the OggVorbis file and finds/documents all the logical
   780    bitstreams contained in it.  Tries to be tolerant of logical
   753    bitstreams contained in it.  Tries to be tolerant of logical
   781    bitstream sections that are truncated/woogie. 
   754    bitstream sections that are truncated/woogie. 
   823 
   796 
   824   return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
   797   return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
   825 }
   798 }
   826   
   799   
   827 int ov_test_open(OggVorbis_File *vf){
   800 int ov_test_open(OggVorbis_File *vf){
   828   if(vf->ready_state!=PARTOPEN)return OV_EINVAL;
   801   if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
   829   return _ov_open2(vf);
   802   return _ov_open2(vf);
   830 }
   803 }
   831 
   804 
   832 /* How many logical bitstreams in this physical bitstream? */
   805 /* How many logical bitstreams in this physical bitstream? */
   833 long ov_streams(OggVorbis_File *vf){
   806 long ov_streams(OggVorbis_File *vf){
   847 
   820 
   848    If you want the actual bitrate field settings, get them from the
   821    If you want the actual bitrate field settings, get them from the
   849    vorbis_info structs */
   822    vorbis_info structs */
   850 
   823 
   851 long ov_bitrate(OggVorbis_File *vf,int i){
   824 long ov_bitrate(OggVorbis_File *vf,int i){
   852   if(vf->ready_state<OPENED)return OV_EINVAL;
   825   if(vf->ready_state<OPENED)return(OV_EINVAL);
   853   if(i>=vf->links)return OV_EINVAL;
   826   if(i>=vf->links)return(OV_EINVAL);
   854   if(!vf->seekable && i!=0)return ov_bitrate(vf,0);
   827   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
   855   if(i<0){
   828   if(i<0){
   856     ogg_int64_t bits=0;
   829     ogg_int64_t bits=0;
   857     int i;
   830     int i;
   858     for(i=0;i<vf->links;i++)
   831     for(i=0;i<vf->links;i++)
   859       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
   832       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
   860     /* This once read: return(rint(bits/ov_time_total(vf,-1)));
   833     /* This once read: return(rint(bits/ov_time_total(vf,-1)));
   861      * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
   834      * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
   862      * so this is slightly transformed to make it work.
   835      * so this is slightly transformed to make it work.
   863      */
   836      */
   864     return bits*1000/ov_time_total(vf,-1);
   837     return(bits*1000/ov_time_total(vf,-1));
   865   }else{
   838   }else{
   866     if(vf->seekable){
   839     if(vf->seekable){
   867       /* return the actual bitrate */
   840       /* return the actual bitrate */
   868       return (vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i);
   841       return((vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i));
   869     }else{
   842     }else{
   870       /* return nominal if set */
   843       /* return nominal if set */
   871       if(vf->vi.bitrate_nominal>0){
   844       if(vf->vi[i].bitrate_nominal>0){
   872 	return vf->vi.bitrate_nominal;
   845 	return vf->vi[i].bitrate_nominal;
   873       }else{
   846       }else{
   874 	if(vf->vi.bitrate_upper>0){
   847 	if(vf->vi[i].bitrate_upper>0){
   875 	  if(vf->vi.bitrate_lower>0){
   848 	  if(vf->vi[i].bitrate_lower>0){
   876 	    return (vf->vi.bitrate_upper+vf->vi.bitrate_lower)/2;
   849 	    return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
   877 	  }else{
   850 	  }else{
   878 	    return vf->vi.bitrate_upper;
   851 	    return vf->vi[i].bitrate_upper;
   879 	  }
   852 	  }
   880 	}
   853 	}
   881 	return OV_FALSE;
   854 	return(OV_FALSE);
   882       }
   855       }
   883     }
   856     }
   884   }
   857   }
   885 }
   858 }
   886 
   859 
   887 /* returns the actual bitrate since last call.  returns -1 if no
   860 /* returns the actual bitrate since last call.  returns -1 if no
   888    additional data to offer since last call (or at beginning of stream),
   861    additional data to offer since last call (or at beginning of stream),
   889    EINVAL if stream is only partially open 
   862    EINVAL if stream is only partially open 
   890 */
   863 */
   891 long ov_bitrate_instant(OggVorbis_File *vf){
   864 long ov_bitrate_instant(OggVorbis_File *vf){
       
   865   int link=(vf->seekable?vf->current_link:0);
   892   long ret;
   866   long ret;
   893   if(vf->ready_state<OPENED)return OV_EINVAL;
   867   if(vf->ready_state<OPENED)return(OV_EINVAL);
   894   if(vf->samptrack==0)return OV_FALSE;
   868   if(vf->samptrack==0)return(OV_FALSE);
   895   ret=vf->bittrack/vf->samptrack*vf->vi.rate;
   869   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate;
   896   vf->bittrack=0;
   870   vf->bittrack=0;
   897   vf->samptrack=0;
   871   vf->samptrack=0;
   898   return ret;
   872   return(ret);
   899 }
   873 }
   900 
   874 
   901 /* Guess */
   875 /* Guess */
   902 long ov_serialnumber(OggVorbis_File *vf,int i){
   876 long ov_serialnumber(OggVorbis_File *vf,int i){
   903   if(i>=vf->links)return ov_serialnumber(vf,vf->links-1);
   877   if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
   904   if(!vf->seekable && i>=0)return ov_serialnumber(vf,-1);
   878   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
   905   if(i<0){
   879   if(i<0){
   906     return vf->current_serialno;
   880     return(vf->current_serialno);
   907   }else{
   881   }else{
   908     return vf->serialnos[i];
   882     return(vf->serialnos[i]);
   909   }
   883   }
   910 }
   884 }
   911 
   885 
   912 /* returns: total raw (compressed) length of content if i==-1
   886 /* returns: total raw (compressed) length of content if i==-1
   913             raw (compressed) length of that logical bitstream for i==0 to n
   887             raw (compressed) length of that logical bitstream for i==0 to n
   914 	    OV_EINVAL if the stream is not seekable (we can't know the length)
   888 	    OV_EINVAL if the stream is not seekable (we can't know the length)
   915 	    or if stream is only partially open
   889 	    or if stream is only partially open
   916 */
   890 */
   917 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
   891 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
   918   if(vf->ready_state<OPENED)return OV_EINVAL;
   892   if(vf->ready_state<OPENED)return(OV_EINVAL);
   919   if(!vf->seekable || i>=vf->links)return OV_EINVAL;
   893   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
   920   if(i<0){
   894   if(i<0){
   921     ogg_int64_t acc=0;
   895     ogg_int64_t acc=0;
   922     int i;
   896     int i;
   923     for(i=0;i<vf->links;i++)
   897     for(i=0;i<vf->links;i++)
   924       acc+=ov_raw_total(vf,i);
   898       acc+=ov_raw_total(vf,i);
   925     return acc;
   899     return(acc);
   926   }else{
   900   }else{
   927     return vf->offsets[i+1]-vf->offsets[i];
   901     return(vf->offsets[i+1]-vf->offsets[i]);
   928   }
   902   }
   929 }
   903 }
   930 
   904 
   931 /* returns: total PCM length (samples) of content if i==-1 PCM length
   905 /* returns: total PCM length (samples) of content if i==-1 PCM length
   932 	    (samples) of that logical bitstream for i==0 to n
   906 	    (samples) of that logical bitstream for i==0 to n
   933 	    OV_EINVAL if the stream is not seekable (we can't know the
   907 	    OV_EINVAL if the stream is not seekable (we can't know the
   934 	    length) or only partially open 
   908 	    length) or only partially open 
   935 */
   909 */
   936 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
   910 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
   937   if(vf->ready_state<OPENED)return OV_EINVAL;
   911   if(vf->ready_state<OPENED)return(OV_EINVAL);
   938   if(!vf->seekable || i>=vf->links)return OV_EINVAL;
   912   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
   939   if(i<0){
   913   if(i<0){
   940     ogg_int64_t acc=0;
   914     ogg_int64_t acc=0;
   941     int i;
   915     int i;
   942     for(i=0;i<vf->links;i++)
   916     for(i=0;i<vf->links;i++)
   943       acc+=ov_pcm_total(vf,i);
   917       acc+=ov_pcm_total(vf,i);
   944     return acc;
   918     return(acc);
   945   }else{
   919   }else{
   946     return vf->pcmlengths[i*2+1];
   920     return(vf->pcmlengths[i*2+1]);
   947   }
   921   }
   948 }
   922 }
   949 
   923 
   950 /* returns: total milliseconds of content if i==-1
   924 /* returns: total milliseconds of content if i==-1
   951             milliseconds in that logical bitstream for i==0 to n
   925             milliseconds in that logical bitstream for i==0 to n
   952 	    OV_EINVAL if the stream is not seekable (we can't know the
   926 	    OV_EINVAL if the stream is not seekable (we can't know the
   953 	    length) or only partially open 
   927 	    length) or only partially open 
   954 */
   928 */
   955 ogg_int64_t ov_time_total(OggVorbis_File *vf,int i){
   929 ogg_int64_t ov_time_total(OggVorbis_File *vf,int i){
   956   if(vf->ready_state<OPENED)return OV_EINVAL;
   930   if(vf->ready_state<OPENED)return(OV_EINVAL);
   957   if(!vf->seekable || i>=vf->links)return OV_EINVAL;
   931   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
   958   if(i<0){
   932   if(i<0){
   959     ogg_int64_t acc=0;
   933     ogg_int64_t acc=0;
   960     int i;
   934     int i;
   961     for(i=0;i<vf->links;i++)
   935     for(i=0;i<vf->links;i++)
   962       acc+=ov_time_total(vf,i);
   936       acc+=ov_time_total(vf,i);
   963     return acc;
   937     return(acc);
   964   }else{
   938   }else{
   965     return ((ogg_int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi.rate;
   939     return(((ogg_int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi[i].rate);
   966   }
   940   }
   967 }
   941 }
   968 
   942 
   969 /* seek to an offset relative to the *compressed* data. This also
   943 /* seek to an offset relative to the *compressed* data. This also
   970    scans packets to update the PCM cursor. It will cross a logical
   944    scans packets to update the PCM cursor. It will cross a logical
   976 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
   950 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
   977   ogg_stream_state *work_os=NULL;
   951   ogg_stream_state *work_os=NULL;
   978   ogg_page og={0,0,0,0};
   952   ogg_page og={0,0,0,0};
   979   ogg_packet op={0,0,0,0,0,0};
   953   ogg_packet op={0,0,0,0,0,0};
   980   
   954   
   981   if(vf->ready_state<OPENED)return OV_EINVAL;
   955   if(vf->ready_state<OPENED)return(OV_EINVAL);
   982   if(!vf->seekable)
   956   if(!vf->seekable)
   983     return OV_ENOSEEK; /* don't dump machine if we can't seek */
   957     return(OV_ENOSEEK); /* don't dump machine if we can't seek */
   984 
   958 
   985   if(pos<0 || pos>vf->end)return OV_EINVAL;
   959   if(pos<0 || pos>vf->end)return(OV_EINVAL);
   986 
   960 
   987   /* don't yet clear out decoding machine (if it's initialized), in
   961   /* don't yet clear out decoding machine (if it's initialized), in
   988      the case we're in the same link.  Restart the decode lapping, and
   962      the case we're in the same link.  Restart the decode lapping, and
   989      let _fetch_and_process_packet deal with a potential bitstream
   963      let _fetch_and_process_packet deal with a potential bitstream
   990      boundary */
   964      boundary */
   991   vf->pcm_offset=-1;
   965   vf->pcm_offset=-1;
   992   ogg_stream_reset_serialno(vf->os,
   966   ogg_stream_reset_serialno(vf->os,
   993 			    vf->current_serialno); /* must set serialno */
   967 			    vf->current_serialno); /* must set serialno */
   994   vorbis_dsp_restart(vf->vd);
   968   vorbis_synthesis_restart(&vf->vd);
   995     
   969     
   996   _seek_helper(vf,pos);
   970   _seek_helper(vf,pos);
   997 
   971 
   998   /* we need to make sure the pcm_offset is set, but we don't want to
   972   /* we need to make sure the pcm_offset is set, but we don't want to
   999      advance the raw cursor past good packets just to get to the first
   973      advance the raw cursor past good packets just to get to the first
  1012 
   986 
  1013   {
   987   {
  1014     int lastblock=0;
   988     int lastblock=0;
  1015     int accblock=0;
   989     int accblock=0;
  1016     int thisblock;
   990     int thisblock;
  1017     int eosflag;
   991     int eosflag=0;
  1018 
   992 
  1019     work_os=ogg_stream_create(vf->current_serialno); /* get the memory ready */
   993     work_os=ogg_stream_create(vf->current_serialno); /* get the memory ready */
  1020     while(1){
   994     while(1){
  1021       if(vf->ready_state>=STREAMSET){
   995       if(vf->ready_state>=STREAMSET){
  1022 	/* snarf/scan a packet if we can */
   996 	/* snarf/scan a packet if we can */
  1023 	int result=ogg_stream_packetout(work_os,&op);
   997 	int result=ogg_stream_packetout(work_os,&op);
  1024       
   998       
  1025 	if(result>0){
   999 	if(result>0){
  1026 
  1000 
  1027 	  if(vf->vi.codec_setup){
  1001 	  if(vf->vi[vf->current_link].codec_setup){
  1028 	    thisblock=vorbis_packet_blocksize(&vf->vi,&op);
  1002 	    thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
  1029 	    if(thisblock<0){
  1003 	    if(thisblock<0){
  1030 	      ogg_stream_packetout(vf->os,NULL);
  1004 	      ogg_stream_packetout(vf->os,NULL);
  1031 	      thisblock=0;
  1005 	      thisblock=0;
  1032 	    }else{
  1006 	    }else{
  1033 	      
  1007 	      
  1063 	/* huh?  Bogus stream with packets but no granulepos */
  1037 	/* huh?  Bogus stream with packets but no granulepos */
  1064 	vf->pcm_offset=-1;
  1038 	vf->pcm_offset=-1;
  1065 	break;
  1039 	break;
  1066       }
  1040       }
  1067       
  1041       
  1068       /* did we just grab a page from other than current link? */
  1042       /* has our decoding just traversed a bitstream boundary? */
  1069       if(vf->ready_state>=STREAMSET)
  1043       if(vf->ready_state>=STREAMSET)
  1070 	if(vf->current_serialno!=ogg_page_serialno(&og)){
  1044 	if(vf->current_serialno!=ogg_page_serialno(&og)){
  1071 	  _decode_clear(vf); /* clear out stream state */
  1045 	  _decode_clear(vf); /* clear out stream state */
  1072 	  ogg_stream_destroy(work_os);
  1046 	  ogg_stream_destroy(work_os);
  1073 	}
  1047 	}
  1080 	  if(vf->serialnos[link]==vf->current_serialno)break;
  1054 	  if(vf->serialnos[link]==vf->current_serialno)break;
  1081 	if(link==vf->links)
  1055 	if(link==vf->links)
  1082 	  goto seek_error; /* sign of a bogus stream.  error out,
  1056 	  goto seek_error; /* sign of a bogus stream.  error out,
  1083 			      leave machine uninitialized */
  1057 			      leave machine uninitialized */
  1084  
  1058  
  1085 	/* need to initialize machine to this link */
  1059 	vf->current_link=link;
  1086 	{
  1060 	
  1087 	  int ret=_set_link_number_preserve_pos(vf,link);
       
  1088 	  if(ret) goto seek_error;
       
  1089 	}
       
  1090 	ogg_stream_reset_serialno(vf->os,vf->current_serialno);
  1061 	ogg_stream_reset_serialno(vf->os,vf->current_serialno);
  1091 	ogg_stream_reset_serialno(work_os,vf->current_serialno); 
  1062 	ogg_stream_reset_serialno(work_os,vf->current_serialno); 
  1092 	
  1063 	vf->ready_state=STREAMSET;
  1093 	
  1064 	
  1094       }
  1065       }
  1095     
  1066     
  1096       {
  1067       {
  1097 	ogg_page dup;
  1068 	ogg_page dup;
  1106   ogg_packet_release(&op);
  1077   ogg_packet_release(&op);
  1107   ogg_page_release(&og);
  1078   ogg_page_release(&og);
  1108   ogg_stream_destroy(work_os);
  1079   ogg_stream_destroy(work_os);
  1109   vf->bittrack=0;
  1080   vf->bittrack=0;
  1110   vf->samptrack=0;
  1081   vf->samptrack=0;
  1111   return 0;
  1082   return(0);
  1112 
  1083 
  1113  seek_error:
  1084  seek_error:
  1114   ogg_packet_release(&op);
  1085   ogg_packet_release(&op);
  1115   ogg_page_release(&og);
  1086   ogg_page_release(&og);
  1116 
  1087 
  1132   ogg_int64_t result=0;
  1103   ogg_int64_t result=0;
  1133   ogg_int64_t total=ov_pcm_total(vf,-1);
  1104   ogg_int64_t total=ov_pcm_total(vf,-1);
  1134   ogg_page og={0,0,0,0};
  1105   ogg_page og={0,0,0,0};
  1135   ogg_packet op={0,0,0,0,0,0};
  1106   ogg_packet op={0,0,0,0,0,0};
  1136 
  1107 
  1137   if(vf->ready_state<OPENED)return OV_EINVAL;
  1108   if(vf->ready_state<OPENED)return(OV_EINVAL);
  1138   if(!vf->seekable)return OV_ENOSEEK;
  1109   if(!vf->seekable)return(OV_ENOSEEK);
  1139   if(pos<0 || pos>total)return OV_EINVAL;
  1110   if(pos<0 || pos>total)return(OV_EINVAL);
  1140  
  1111  
  1141   /* which bitstream section does this pcm offset occur in? */
  1112   /* which bitstream section does this pcm offset occur in? */
  1142   for(link=vf->links-1;link>=0;link--){
  1113   for(link=vf->links-1;link>=0;link--){
  1143     total-=vf->pcmlengths[link*2+1];
  1114     total-=vf->pcmlengths[link*2+1];
  1144     if(pos>=total)break;
  1115     if(pos>=total)break;
  1145   }
  1116   }
  1146 
       
  1147 
       
  1148   if(link!=vf->current_link){
       
  1149     int ret=_set_link_number(vf,link);
       
  1150     if(ret) goto seek_error;
       
  1151   }else{
       
  1152     vorbis_dsp_restart(vf->vd);
       
  1153   }
       
  1154 
       
  1155   ogg_stream_reset_serialno(vf->os,vf->serialnos[link]);
       
  1156 
  1117 
  1157   /* search within the logical bitstream for the page with the highest
  1118   /* search within the logical bitstream for the page with the highest
  1158      pcm_pos preceeding (or equal to) pos.  There is a danger here;
  1119      pcm_pos preceeding (or equal to) pos.  There is a danger here;
  1159      missing pages or incorrect frame number information in the
  1120      missing pages or incorrect frame number information in the
  1160      bitstream could make our task impossible.  Account for that (it
  1121      bitstream could make our task impossible.  Account for that (it
  1234       _seek_helper(vf,best);
  1195       _seek_helper(vf,best);
  1235       vf->pcm_offset=-1;
  1196       vf->pcm_offset=-1;
  1236       
  1197       
  1237       if(_get_next_page(vf,&og,-1)<0){
  1198       if(_get_next_page(vf,&og,-1)<0){
  1238 	ogg_page_release(&og);
  1199 	ogg_page_release(&og);
  1239 	return OV_EOF; /* shouldn't happen */
  1200 	return(OV_EOF); /* shouldn't happen */
  1240       }
  1201       }
  1241 
  1202 
       
  1203       if(link!=vf->current_link){
       
  1204 	/* Different link; dump entire decode machine */
       
  1205 	_decode_clear(vf);  
       
  1206 	
       
  1207 	vf->current_link=link;
       
  1208 	vf->current_serialno=ogg_page_serialno(&og);
       
  1209 	vf->ready_state=STREAMSET;
       
  1210 	
       
  1211       }else{
       
  1212 	vorbis_synthesis_restart(&vf->vd);
       
  1213       }
       
  1214 
       
  1215       ogg_stream_reset_serialno(vf->os,vf->current_serialno);
  1242       ogg_stream_pagein(vf->os,&og);
  1216       ogg_stream_pagein(vf->os,&og);
  1243 
  1217 
  1244       /* pull out all but last packet; the one with granulepos */
  1218       /* pull out all but last packet; the one with granulepos */
  1245       while(1){
  1219       while(1){
  1246 	result=ogg_stream_packetpeek(vf->os,&op);
  1220 	result=ogg_stream_packetpeek(vf->os,&op);
  1285   vf->bittrack=0;
  1259   vf->bittrack=0;
  1286   vf->samptrack=0;
  1260   vf->samptrack=0;
  1287 
  1261 
  1288   ogg_page_release(&og);
  1262   ogg_page_release(&og);
  1289   ogg_packet_release(&op);
  1263   ogg_packet_release(&op);
  1290   return 0;
  1264   return(0);
  1291   
  1265   
  1292  seek_error:
  1266  seek_error:
  1293 
  1267 
  1294   ogg_page_release(&og);
  1268   ogg_page_release(&og);
  1295   ogg_packet_release(&op);
  1269   ogg_packet_release(&op);
  1306 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
  1280 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
  1307   ogg_packet op={0,0,0,0,0,0};
  1281   ogg_packet op={0,0,0,0,0,0};
  1308   ogg_page og={0,0,0,0};
  1282   ogg_page og={0,0,0,0};
  1309   int thisblock,lastblock=0;
  1283   int thisblock,lastblock=0;
  1310   int ret=ov_pcm_seek_page(vf,pos);
  1284   int ret=ov_pcm_seek_page(vf,pos);
  1311   if(ret<0)return ret;
  1285   if(ret<0)return(ret);
  1312   if(_make_decode_ready(vf))return OV_EBADLINK;
  1286   _make_decode_ready(vf);
  1313 
  1287 
  1314   /* discard leading packets we don't need for the lapping of the
  1288   /* discard leading packets we don't need for the lapping of the
  1315      position we want; don't decode them */
  1289      position we want; don't decode them */
  1316 
  1290 
  1317   while(1){
  1291   while(1){
  1318 
  1292 
  1319     int ret=ogg_stream_packetpeek(vf->os,&op);
  1293     int ret=ogg_stream_packetpeek(vf->os,&op);
  1320     if(ret>0){
  1294     if(ret>0){
  1321       thisblock=vorbis_packet_blocksize(&vf->vi,&op);
  1295       thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
  1322       if(thisblock<0){
  1296       if(thisblock<0){
  1323 	ogg_stream_packetout(vf->os,NULL);
  1297 	ogg_stream_packetout(vf->os,NULL);
  1324 	continue; /* non audio packet */
  1298 	continue; /* non audio packet */
  1325       }
  1299       }
  1326       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
  1300       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
  1327       
  1301       
  1328       if(vf->pcm_offset+((thisblock+
  1302       if(vf->pcm_offset+((thisblock+
  1329 			  vorbis_info_blocksize(&vf->vi,1))>>2)>=pos)break;
  1303 			  vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
  1330       
  1304       
  1331       /* remove the packet from packet queue and track its granulepos */
  1305       /* remove the packet from packet queue and track its granulepos */
  1332       ogg_stream_packetout(vf->os,NULL);
  1306       ogg_stream_packetout(vf->os,NULL);
  1333       vorbis_dsp_synthesis(vf->vd,&op,0);  /* set up a vb with
  1307       vorbis_synthesis(&vf->vb,&op,0);  /* set up a vb with
  1334 					      only tracking, no
  1308 					   only tracking, no
  1335 					      pcm_decode */
  1309 					   pcm_decode */
       
  1310       vorbis_synthesis_blockin(&vf->vd,&vf->vb); 
  1336       
  1311       
  1337       /* end of logical stream case is hard, especially with exact
  1312       /* end of logical stream case is hard, especially with exact
  1338 	 length positioning. */
  1313 	 length positioning. */
  1339       
  1314       
  1340       if(op.granulepos>-1){
  1315       if(op.granulepos>-1){
  1354       /* suck in a new page */
  1329       /* suck in a new page */
  1355       if(_get_next_page(vf,&og,-1)<0)break;
  1330       if(_get_next_page(vf,&og,-1)<0)break;
  1356       if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
  1331       if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
  1357       
  1332       
  1358       if(vf->ready_state<STREAMSET){
  1333       if(vf->ready_state<STREAMSET){
  1359 	int link,ret;
  1334 	int link;
  1360 	
  1335 	
  1361 	vf->current_serialno=ogg_page_serialno(&og);
  1336 	vf->current_serialno=ogg_page_serialno(&og);
  1362 	for(link=0;link<vf->links;link++)
  1337 	for(link=0;link<vf->links;link++)
  1363 	  if(vf->serialnos[link]==vf->current_serialno)break;
  1338 	  if(vf->serialnos[link]==vf->current_serialno)break;
  1364 	if(link==vf->links){
  1339 	if(link==vf->links){
  1365 	  ogg_page_release(&og);
  1340 	  ogg_page_release(&og);
  1366 	  ogg_packet_release(&op);
  1341 	  ogg_packet_release(&op);
  1367 	  return OV_EBADLINK;
  1342 	  return(OV_EBADLINK);
  1368 	}
  1343 	}
  1369 
       
  1370 
       
  1371 	vf->current_link=link;
  1344 	vf->current_link=link;
  1372 	ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
  1345 	
  1373 	if(ret) return ret;
  1346 	ogg_stream_reset_serialno(vf->os,vf->current_serialno); 
  1374 	if(_make_decode_ready(vf))return OV_EBADLINK;
  1347 	vf->ready_state=STREAMSET;      
       
  1348 	_make_decode_ready(vf);
  1375 	lastblock=0;
  1349 	lastblock=0;
  1376       }
  1350       }
  1377 
  1351 
  1378       ogg_stream_pagein(vf->os,&og);
  1352       ogg_stream_pagein(vf->os,&og);
  1379     }
  1353     }
  1383   vf->samptrack=0;
  1357   vf->samptrack=0;
  1384   /* discard samples until we reach the desired position. Crossing a
  1358   /* discard samples until we reach the desired position. Crossing a
  1385      logical bitstream boundary with abandon is OK. */
  1359      logical bitstream boundary with abandon is OK. */
  1386   while(vf->pcm_offset<pos){
  1360   while(vf->pcm_offset<pos){
  1387     ogg_int64_t target=pos-vf->pcm_offset;
  1361     ogg_int64_t target=pos-vf->pcm_offset;
  1388     long samples=vorbis_dsp_pcmout(vf->vd,NULL,0);
  1362     long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
  1389 
  1363 
  1390     if(samples>target)samples=target;
  1364     if(samples>target)samples=target;
  1391     vorbis_dsp_read(vf->vd,samples);
  1365     vorbis_synthesis_read(&vf->vd,samples);
  1392     vf->pcm_offset+=samples;
  1366     vf->pcm_offset+=samples;
  1393     
  1367     
  1394     if(samples<target)
  1368     if(samples<target)
  1395       if(_fetch_and_process_packet(vf,1,1)<=0)
  1369       if(_fetch_and_process_packet(vf,1,1)<=0)
  1396 	vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
  1370 	vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
  1408 
  1382 
  1409   int link=-1;
  1383   int link=-1;
  1410   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
  1384   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
  1411   ogg_int64_t time_total=ov_time_total(vf,-1);
  1385   ogg_int64_t time_total=ov_time_total(vf,-1);
  1412 
  1386 
  1413   if(vf->ready_state<OPENED)return OV_EINVAL;
  1387   if(vf->ready_state<OPENED)return(OV_EINVAL);
  1414   if(!vf->seekable)return OV_ENOSEEK;
  1388   if(!vf->seekable)return(OV_ENOSEEK);
  1415   if(milliseconds<0 || milliseconds>time_total)return OV_EINVAL;
  1389   if(milliseconds<0 || milliseconds>time_total)return(OV_EINVAL);
  1416   
  1390   
  1417   /* which bitstream section does this time offset occur in? */
  1391   /* which bitstream section does this time offset occur in? */
  1418   for(link=vf->links-1;link>=0;link--){
  1392   for(link=vf->links-1;link>=0;link--){
  1419     pcm_total-=vf->pcmlengths[link*2+1];
  1393     pcm_total-=vf->pcmlengths[link*2+1];
  1420     time_total-=ov_time_total(vf,link);
  1394     time_total-=ov_time_total(vf,link);
  1421     if(milliseconds>=time_total)break;
  1395     if(milliseconds>=time_total)break;
  1422   }
  1396   }
  1423 
  1397 
  1424   /* enough information to convert time offset to pcm offset */
  1398   /* enough information to convert time offset to pcm offset */
  1425   {
  1399   {
  1426     int ret=_set_link_number(vf,link);
  1400     ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000;
  1427     if(ret)return ret;
  1401     return(ov_pcm_seek(vf,target));
  1428     return 
       
  1429       ov_pcm_seek(vf,pcm_total+(milliseconds-time_total)*
       
  1430 		  vf->vi.rate/1000);
       
  1431   }
  1402   }
  1432 }
  1403 }
  1433 
  1404 
  1434 /* page-granularity version of ov_time_seek 
  1405 /* page-granularity version of ov_time_seek 
  1435    returns zero on success, nonzero on failure */
  1406    returns zero on success, nonzero on failure */
  1438 
  1409 
  1439   int link=-1;
  1410   int link=-1;
  1440   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
  1411   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
  1441   ogg_int64_t time_total=ov_time_total(vf,-1);
  1412   ogg_int64_t time_total=ov_time_total(vf,-1);
  1442 
  1413 
  1443   if(vf->ready_state<OPENED)return OV_EINVAL;
  1414   if(vf->ready_state<OPENED)return(OV_EINVAL);
  1444   if(!vf->seekable)return OV_ENOSEEK;
  1415   if(!vf->seekable)return(OV_ENOSEEK);
  1445   if(milliseconds<0 || milliseconds>time_total)return OV_EINVAL;
  1416   if(milliseconds<0 || milliseconds>time_total)return(OV_EINVAL);
  1446   
  1417   
  1447   /* which bitstream section does this time offset occur in? */
  1418   /* which bitstream section does this time offset occur in? */
  1448   for(link=vf->links-1;link>=0;link--){
  1419   for(link=vf->links-1;link>=0;link--){
  1449     pcm_total-=vf->pcmlengths[link*2+1];
  1420     pcm_total-=vf->pcmlengths[link*2+1];
  1450     time_total-=ov_time_total(vf,link);
  1421     time_total-=ov_time_total(vf,link);
  1451     if(milliseconds>=time_total)break;
  1422     if(milliseconds>=time_total)break;
  1452   }
  1423   }
  1453 
  1424 
  1454   /* enough information to convert time offset to pcm offset */
  1425   /* enough information to convert time offset to pcm offset */
  1455   {
  1426   {
  1456     int ret=_set_link_number(vf,link);
  1427     ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000;
  1457     if(ret)return ret;
  1428     return(ov_pcm_seek_page(vf,target));
  1458     return 
       
  1459       ov_pcm_seek_page(vf,pcm_total+(milliseconds-time_total)*
       
  1460 		       vf->vi.rate/1000);
       
  1461   }
  1429   }
  1462 }
  1430 }
  1463 
  1431 
  1464 /* tell the current stream offset cursor.  Note that seek followed by
  1432 /* tell the current stream offset cursor.  Note that seek followed by
  1465    tell will likely not give the set offset due to caching */
  1433    tell will likely not give the set offset due to caching */
  1466 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
  1434 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
  1467   if(vf->ready_state<OPENED)return OV_EINVAL;
  1435   if(vf->ready_state<OPENED)return(OV_EINVAL);
  1468   return vf->offset;
  1436   return(vf->offset);
  1469 }
  1437 }
  1470 
  1438 
  1471 /* return PCM offset (sample) of next PCM sample to be read */
  1439 /* return PCM offset (sample) of next PCM sample to be read */
  1472 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
  1440 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
  1473   if(vf->ready_state<OPENED)return OV_EINVAL;
  1441   if(vf->ready_state<OPENED)return(OV_EINVAL);
  1474   return vf->pcm_offset;
  1442   return(vf->pcm_offset);
  1475 }
  1443 }
  1476 
  1444 
  1477 /* return time offset (milliseconds) of next PCM sample to be read */
  1445 /* return time offset (milliseconds) of next PCM sample to be read */
  1478 ogg_int64_t ov_time_tell(OggVorbis_File *vf){
  1446 ogg_int64_t ov_time_tell(OggVorbis_File *vf){
  1479   int link=0;
  1447   int link=0;
  1480   ogg_int64_t pcm_total=0;
  1448   ogg_int64_t pcm_total=0;
  1481   ogg_int64_t time_total=0;
  1449   ogg_int64_t time_total=0;
  1482   
  1450   
  1483   if(vf->ready_state<OPENED)return OV_EINVAL;
  1451   if(vf->ready_state<OPENED)return(OV_EINVAL);
  1484   if(vf->seekable){
  1452   if(vf->seekable){
  1485     pcm_total=ov_pcm_total(vf,-1);
  1453     pcm_total=ov_pcm_total(vf,-1);
  1486     time_total=ov_time_total(vf,-1);
  1454     time_total=ov_time_total(vf,-1);
  1487   
  1455   
  1488     /* which bitstream section does this time offset occur in? */
  1456     /* which bitstream section does this time offset occur in? */
  1491       time_total-=ov_time_total(vf,link);
  1459       time_total-=ov_time_total(vf,link);
  1492       if(vf->pcm_offset>=pcm_total)break;
  1460       if(vf->pcm_offset>=pcm_total)break;
  1493     }
  1461     }
  1494   }
  1462   }
  1495 
  1463 
  1496   return time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi.rate;
  1464   return(time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi[link].rate);
  1497 }
  1465 }
  1498 
  1466 
  1499 /*  link:   -1) return the vorbis_info struct for the bitstream section
  1467 /*  link:   -1) return the vorbis_info struct for the bitstream section
  1500                 currently being decoded
  1468                 currently being decoded
  1501            0-n) to request information for a specific bitstream section
  1469            0-n) to request information for a specific bitstream section
  1504     current bitstream.  NULL in the case that the machine is not
  1472     current bitstream.  NULL in the case that the machine is not
  1505     initialized */
  1473     initialized */
  1506 
  1474 
  1507 vorbis_info *ov_info(OggVorbis_File *vf,int link){
  1475 vorbis_info *ov_info(OggVorbis_File *vf,int link){
  1508   if(vf->seekable){
  1476   if(vf->seekable){
  1509     if(link>=vf->links)return NULL;
  1477     if(link<0)
  1510     if(link>=0){
  1478       if(vf->ready_state>=STREAMSET)
  1511       int ret=_set_link_number_preserve_pos(vf,link);
  1479 	return vf->vi+vf->current_link;
  1512       if(ret)return NULL;
  1480       else
  1513     }
  1481       return vf->vi;
  1514   }
  1482     else
  1515   return &vf->vi;
  1483       if(link>=vf->links)
       
  1484 	return NULL;
       
  1485       else
       
  1486 	return vf->vi+link;
       
  1487   }else{
       
  1488     return vf->vi;
       
  1489   }
  1516 }
  1490 }
  1517 
  1491 
  1518 /* grr, strong typing, grr, no templates/inheritence, grr */
  1492 /* grr, strong typing, grr, no templates/inheritence, grr */
  1519 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
  1493 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
  1520   if(vf->seekable){
  1494   if(vf->seekable){
  1521     if(link>=vf->links)return NULL;
  1495     if(link<0)
  1522     if(link>=0){
  1496       if(vf->ready_state>=STREAMSET)
  1523       int ret=_set_link_number_preserve_pos(vf,link);
  1497 	return vf->vc+vf->current_link;
  1524       if(ret)return NULL;
  1498       else
  1525     }
  1499 	return vf->vc;
  1526   }
  1500     else
  1527   return &vf->vc;
  1501       if(link>=vf->links)
       
  1502 	return NULL;
       
  1503       else
       
  1504 	return vf->vc+link;
       
  1505   }else{
       
  1506     return vf->vc;
       
  1507   }
  1528 }
  1508 }
  1529 
  1509 
  1530 /* up to this point, everything could more or less hide the multiple
  1510 /* up to this point, everything could more or less hide the multiple
  1531    logical bitstream nature of chaining from the toplevel application
  1511    logical bitstream nature of chaining from the toplevel application
  1532    if the toplevel application didn't particularly care.  However, at
  1512    if the toplevel application didn't particularly care.  However, at
  1552 		   return length is not related to the 'length' passed
  1532 		   return length is not related to the 'length' passed
  1553 		   in, just guaranteed to fit.
  1533 		   in, just guaranteed to fit.
  1554 
  1534 
  1555 	    *section) set to the logical bitstream number */
  1535 	    *section) set to the logical bitstream number */
  1556 
  1536 
  1557 long ov_read(OggVorbis_File *vf,void *buffer,int bytes_req,int *bitstream){
  1537 long ov_read(OggVorbis_File *vf,char *buffer,int bytes_req,int *bitstream){
  1558 
  1538   int i,j;
       
  1539 
       
  1540   ogg_int32_t **pcm;
  1559   long samples;
  1541   long samples;
  1560   long channels;
  1542 
  1561 
  1543   if(vf->ready_state<OPENED)return(OV_EINVAL);
  1562   if(vf->ready_state<OPENED)return OV_EINVAL;
       
  1563 
  1544 
  1564   while(1){
  1545   while(1){
  1565     if(vf->ready_state==INITSET){
  1546     if(vf->ready_state==INITSET){
  1566       channels=vf->vi.channels;
  1547       samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
  1567       samples=vorbis_dsp_pcmout(vf->vd,buffer,(bytes_req>>1)/channels);
  1548       if(samples)break;
  1568       if(samples){
       
  1569 	if(samples>0){
       
  1570 	  vorbis_dsp_read(vf->vd,samples);
       
  1571 	  vf->pcm_offset+=samples;
       
  1572 	  if(bitstream)*bitstream=vf->current_link;
       
  1573 	  return samples*2*channels;
       
  1574 	}
       
  1575 	return samples;
       
  1576       }
       
  1577     }
  1549     }
  1578 
  1550 
  1579     /* suck in another packet */
  1551     /* suck in another packet */
  1580     {
  1552     {
  1581       int ret=_fetch_and_process_packet(vf,1,1);
  1553       int ret=_fetch_and_process_packet(vf,1,1);
  1582       if(ret==OV_EOF)
  1554       if(ret==OV_EOF)
  1583 	return 0;
  1555 	return(0);
  1584       if(ret<=0)
  1556       if(ret<=0)
  1585 	return ret;
  1557 	return(ret);
  1586     }
  1558     }
  1587 
  1559 
  1588   }
  1560   }
  1589 }
  1561 
       
  1562   if(samples>0){
       
  1563   
       
  1564     /* yay! proceed to pack data into the byte buffer */
       
  1565     
       
  1566     long channels=ov_info(vf,-1)->channels;
       
  1567 
       
  1568     if(samples>(bytes_req/(2*channels)))
       
  1569       samples=bytes_req/(2*channels);      
       
  1570     
       
  1571     for(i=0;i<channels;i++) { /* It's faster in this order */
       
  1572       ogg_int32_t *src=pcm[i];
       
  1573       short *dest=((short *)buffer)+i;
       
  1574       for(j=0;j<samples;j++) {
       
  1575         *dest=CLIP_TO_15(src[j]>>9);
       
  1576         dest+=channels;
       
  1577       }
       
  1578     }
       
  1579     
       
  1580     vorbis_synthesis_read(&vf->vd,samples);
       
  1581     vf->pcm_offset+=samples;
       
  1582     if(bitstream)*bitstream=vf->current_link;
       
  1583     return(samples*2*channels);
       
  1584   }else{
       
  1585     return(samples);
       
  1586   }
       
  1587 }