cannam@86: /******************************************************************** cannam@86: * * cannam@86: * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * cannam@86: * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * cannam@86: * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * cannam@86: * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * cannam@86: * * cannam@86: * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * cannam@86: * by the Xiph.Org Foundation http://www.xiph.org/ * cannam@86: * * cannam@86: ******************************************************************** cannam@86: cannam@86: function: illustrate seeking, and test it too cannam@86: last mod: $Id: seeking_example.c 17561 2010-10-23 10:34:24Z xiphmont $ cannam@86: cannam@86: ********************************************************************/ cannam@86: cannam@86: #include cannam@86: #include cannam@86: #include "vorbis/codec.h" cannam@86: #include "vorbis/vorbisfile.h" cannam@86: cannam@86: #ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */ cannam@86: # include cannam@86: # include cannam@86: #endif cannam@86: cannam@86: void _verify(OggVorbis_File *ov, cannam@86: ogg_int64_t val,ogg_int64_t pcmval,double timeval, cannam@86: ogg_int64_t pcmlength, cannam@86: char *bigassbuffer){ cannam@86: off_t i; cannam@86: int j; cannam@86: long bread; cannam@86: char buffer[4096]; cannam@86: int dummy; cannam@86: ogg_int64_t pos; cannam@86: int hs = ov_halfrate_p(ov); cannam@86: cannam@86: /* verify the raw position, the pcm position and position decode */ cannam@86: if(val!=-1 && ov_raw_tell(ov)pcmval){ cannam@86: fprintf(stderr,"pcm position out of tolerance: requested %ld, got %ld\n", cannam@86: (long)pcmval,(long)ov_pcm_tell(ov)); cannam@86: exit(1); cannam@86: } cannam@86: if(timeval!=-1 && ov_time_tell(ov)>timeval){ cannam@86: fprintf(stderr,"time position out of tolerance: requested %f, got %f\n", cannam@86: timeval,ov_time_tell(ov)); cannam@86: exit(1); cannam@86: } cannam@86: pos=ov_pcm_tell(ov); cannam@86: if(pos<0 || pos>pcmlength){ cannam@86: fprintf(stderr,"pcm position out of bounds: got %ld\n",(long)pos); cannam@86: exit(1); cannam@86: } cannam@86: bread=ov_read(ov,buffer,4096,1,1,1,&dummy); cannam@86: for(j=0;j>hs)*2)]){ cannam@86: fprintf(stderr,"data after seek doesn't match declared pcm position %ld\n",(long)pos); cannam@86: cannam@86: for(i=0;i<(pcmlength>>hs)*2-bread;i++){ cannam@86: for(j=0;j>hs)>=0 && (j+((pos*2)>>hs))<(pcmlength>>hs)*2) cannam@86: fprintf(f,"%d %d\n",j,(int)bigassbuffer[j+((pos*2)>>hs)]); cannam@86: fclose(f); cannam@86: } cannam@86: cannam@86: exit(1); cannam@86: } cannam@86: } cannam@86: } cannam@86: cannam@86: int main(){ cannam@86: OggVorbis_File ov; cannam@86: int i,ret; cannam@86: ogg_int64_t pcmlength; cannam@86: double timelength; cannam@86: char *bigassbuffer; cannam@86: int dummy; cannam@86: int hs=0; cannam@86: cannam@86: #ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */ cannam@86: _setmode( _fileno( stdin ), _O_BINARY ); cannam@86: #endif cannam@86: cannam@86: cannam@86: /* open the file/pipe on stdin */ cannam@86: if(ov_open_callbacks(stdin,&ov,NULL,-1,OV_CALLBACKS_NOCLOSE)<0){ cannam@86: fprintf(stderr,"Could not open input as an OggVorbis file.\n\n"); cannam@86: exit(1); cannam@86: } cannam@86: cannam@86: #if 0 /*enable this code to test seeking with halfrate decode */ cannam@86: if(ov_halfrate(&ov,1)){ cannam@86: fprintf(stderr,"Sorry; unable to set half-rate decode.\n\n"); cannam@86: exit(1); cannam@86: }else cannam@86: hs=1; cannam@86: #endif cannam@86: cannam@86: if(ov_seekable(&ov)){ cannam@86: cannam@86: /* to simplify our own lives, we want to assume the whole file is cannam@86: stereo. Verify this to avoid potentially mystifying users cannam@86: (pissing them off is OK, just don't confuse them) */ cannam@86: for(i=0;ichannels!=2){ cannam@86: fprintf(stderr,"Sorry; right now seeking_test can only use Vorbis files\n" cannam@86: "that are entirely stereo.\n\n"); cannam@86: exit(1); cannam@86: } cannam@86: } cannam@86: cannam@86: /* because we want to do sample-level verification that the seek cannam@86: does what it claimed, decode the entire file into memory */ cannam@86: pcmlength=ov_pcm_total(&ov,-1); cannam@86: timelength=ov_time_total(&ov,-1); cannam@86: bigassbuffer=malloc((pcmlength>>hs)*2); /* w00t */ cannam@86: i=0; cannam@86: while(i<(pcmlength>>hs)*2){ cannam@86: int ret=ov_read(&ov,bigassbuffer+i,((pcmlength>>hs)*2)-i,1,1,1,&dummy); cannam@86: if(ret<0){ cannam@86: fprintf(stderr,"Error reading file.\n"); cannam@86: exit(1); cannam@86: } cannam@86: if(ret){ cannam@86: i+=ret; cannam@86: }else{ cannam@86: pcmlength=(i/2)<>hs)*2-i)); cannam@86: } cannam@86: cannam@86: { cannam@86: ogg_int64_t length=ov.end; cannam@86: fprintf(stderr,"\rtesting raw seeking to random places in %ld bytes....\n", cannam@86: (long)length); cannam@86: cannam@86: for(i=0;i<1000;i++){ cannam@86: ogg_int64_t val=(double)rand()/RAND_MAX*length; cannam@86: fprintf(stderr,"\r\t%d [raw position %ld]... ",i,(long)val); cannam@86: ret=ov_raw_seek(&ov,val); cannam@86: if(ret<0){ cannam@86: fprintf(stderr,"seek failed: %d\n",ret); cannam@86: exit(1); cannam@86: } cannam@86: cannam@86: _verify(&ov,val,-1,-1.,pcmlength,bigassbuffer); cannam@86: cannam@86: } cannam@86: } cannam@86: cannam@86: fprintf(stderr,"\r"); cannam@86: { cannam@86: fprintf(stderr,"testing pcm page seeking to random places in %ld samples....\n", cannam@86: (long)pcmlength); cannam@86: cannam@86: for(i=0;i<1000;i++){ cannam@86: ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength; cannam@86: fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val); cannam@86: ret=ov_pcm_seek_page(&ov,val); cannam@86: if(ret<0){ cannam@86: fprintf(stderr,"seek failed: %d\n",ret); cannam@86: exit(1); cannam@86: } cannam@86: cannam@86: _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer); cannam@86: cannam@86: } cannam@86: } cannam@86: cannam@86: fprintf(stderr,"\r"); cannam@86: { cannam@86: fprintf(stderr,"testing pcm exact seeking to random places in %ld samples....\n", cannam@86: (long)pcmlength); cannam@86: cannam@86: for(i=0;i<1000;i++){ cannam@86: ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength; cannam@86: fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val); cannam@86: ret=ov_pcm_seek(&ov,val); cannam@86: if(ret<0){ cannam@86: fprintf(stderr,"seek failed: %d\n",ret); cannam@86: exit(1); cannam@86: } cannam@86: if(ov_pcm_tell(&ov)!=((val>>hs)<val+1){ cannam@86: fprintf(stderr,"Declared position didn't perfectly match request: %f != %f\n", cannam@86: val,ov_time_tell(&ov)); cannam@86: exit(1); cannam@86: } cannam@86: cannam@86: _verify(&ov,-1,-1,val,pcmlength,bigassbuffer); cannam@86: cannam@86: } cannam@86: } cannam@86: cannam@86: fprintf(stderr,"\r \nOK.\n\n"); cannam@86: cannam@86: cannam@86: }else{ cannam@86: fprintf(stderr,"Standard input was not seekable.\n"); cannam@86: } cannam@86: cannam@86: ov_clear(&ov); cannam@86: return 0; cannam@86: } cannam@86: cannam@86: cannam@86: cannam@86: cannam@86: cannam@86: cannam@86: cannam@86: cannam@86: cannam@86: cannam@86: cannam@86: cannam@86: