1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
13 function: illustrate seeking, and test it too
16 ********************************************************************/
20 #include "vorbis/codec.h"
21 #include "vorbis/vorbisfile.h"
23 #ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
28 void _verify(OggVorbis_File *ov,
29 ogg_int64_t val,ogg_int64_t pcmval,double timeval,
30 ogg_int64_t pcmlength,
38 int hs = ov_halfrate_p(ov);
40 /* verify the raw position, the pcm position and position decode */
41 if(val!=-1 && ov_raw_tell(ov)<val){
42 fprintf(stderr,"raw position out of tolerance: requested %ld, got %ld\n",
43 (long)val,(long)ov_raw_tell(ov));
46 if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){
47 fprintf(stderr,"pcm position out of tolerance: requested %ld, got %ld\n",
48 (long)pcmval,(long)ov_pcm_tell(ov));
51 if(timeval!=-1 && ov_time_tell(ov)>timeval){
52 fprintf(stderr,"time position out of tolerance: requested %f, got %f\n",
53 timeval,ov_time_tell(ov));
57 if(pos<0 || pos>pcmlength){
58 fprintf(stderr,"pcm position out of bounds: got %ld\n",(long)pos);
61 bread=ov_read(ov,buffer,4096,1,1,1,&dummy);
63 if(buffer[j]!=bigassbuffer[j+((pos>>hs)*2)]){
64 fprintf(stderr,"data after seek doesn't match declared pcm position %ld\n",(long)pos);
66 for(i=0;i<(pcmlength>>hs)*2-bread;i++){
68 if(buffer[j] != bigassbuffer[i+j])break;
70 fprintf(stderr,"data after seek appears to match position %ld\n",(long)((i/2)<<hs));
74 FILE *f=fopen("a.m","w");
75 for(j=0;j<bread;j++)fprintf(f,"%d %d\n",j,(int)buffer[j]);
78 for(j=-4096;j<bread+4096;j++)
79 if(j+((pos*2)>>hs)>=0 && (j+((pos*2)>>hs))<(pcmlength>>hs)*2)
80 fprintf(f,"%d %d\n",j,(int)bigassbuffer[j+((pos*2)>>hs)]);
92 ogg_int64_t pcmlength;
98 #ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
99 _setmode( _fileno( stdin ), _O_BINARY );
103 /* open the file/pipe on stdin */
104 if(ov_open_callbacks(stdin,&ov,NULL,-1,OV_CALLBACKS_NOCLOSE)<0){
105 fprintf(stderr,"Could not open input as an OggVorbis file.\n\n");
109 #if 0 /*enable this code to test seeking with halfrate decode */
110 if(ov_halfrate(&ov,1)){
111 fprintf(stderr,"Sorry; unable to set half-rate decode.\n\n");
117 if(ov_seekable(&ov)){
119 /* to simplify our own lives, we want to assume the whole file is
120 stereo. Verify this to avoid potentially mystifying users
121 (pissing them off is OK, just don't confuse them) */
122 for(i=0;i<ov.links;i++){
123 vorbis_info *vi=ov_info(&ov,i);
125 fprintf(stderr,"Sorry; right now seeking_test can only use Vorbis files\n"
126 "that are entirely stereo.\n\n");
131 /* because we want to do sample-level verification that the seek
132 does what it claimed, decode the entire file into memory */
133 pcmlength=ov_pcm_total(&ov,-1);
134 timelength=ov_time_total(&ov,-1);
135 bigassbuffer=malloc((pcmlength>>hs)*2); /* w00t */
137 while(i<(pcmlength>>hs)*2){
138 int ret=ov_read(&ov,bigassbuffer+i,((pcmlength>>hs)*2)-i,1,1,1,&dummy);
140 fprintf(stderr,"Error reading file.\n");
148 fprintf(stderr,"\rloading.... [%ld left] ",
149 (long)((pcmlength>>hs)*2-i));
153 ogg_int64_t length=ov.end;
154 fprintf(stderr,"\rtesting raw seeking to random places in %ld bytes....\n",
158 ogg_int64_t val=(double)rand()/RAND_MAX*length;
159 fprintf(stderr,"\r\t%d [raw position %ld]... ",i,(long)val);
160 ret=ov_raw_seek(&ov,val);
162 fprintf(stderr,"seek failed: %d\n",ret);
166 _verify(&ov,val,-1,-1.,pcmlength,bigassbuffer);
171 fprintf(stderr,"\r");
173 fprintf(stderr,"testing pcm page seeking to random places in %ld samples....\n",
177 ogg_int64_t val= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength;
178 fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val);
179 ret=ov_pcm_seek_page(&ov,val);
181 fprintf(stderr,"seek failed: %d\n",ret);
185 _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);
190 fprintf(stderr,"\r");
193 ogg_int64_t val= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength;
194 fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val);
195 ret=ov_pcm_seek(&ov,val);
197 fprintf(stderr,"seek failed: %d\n",ret);
200 if(ov_pcm_tell(&ov)!=((val>>hs)<<hs)){
201 fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n",
202 (long)val,(long)ov_pcm_tell(&ov));
206 _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);
211 fprintf(stderr,"\r");
213 fprintf(stderr,"testing time page seeking to random places in %f seconds....\n",
217 double val=(double)rand()/RAND_MAX*timelength;
218 fprintf(stderr,"\r\t%d [time position %f]... ",i,val);
219 ret=ov_time_seek_page(&ov,val);
221 fprintf(stderr,"seek failed: %d\n",ret);
225 _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);
230 fprintf(stderr,"\r");
232 fprintf(stderr,"testing time exact seeking to random places in %f seconds....\n",
236 double val=(double)rand()/RAND_MAX*timelength;
237 fprintf(stderr,"\r\t%d [time position %f]... ",i,val);
238 ret=ov_time_seek(&ov,val);
240 fprintf(stderr,"seek failed: %d\n",ret);
243 if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){
244 fprintf(stderr,"Declared position didn't perfectly match request: %f != %f\n",
245 val,ov_time_tell(&ov));
249 _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);
254 fprintf(stderr,"\r \nOK.\n\n");
258 fprintf(stderr,"Standard input was not seekable.\n");