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");
192 fprintf(stderr,"testing pcm exact seeking to random places in %f seconds....\n",
195 ogg_int64_t val= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength;
196 fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val);
197 ret=ov_pcm_seek(&ov,val);
199 fprintf(stderr,"seek failed: %d\n",ret);
202 if(ov_pcm_tell(&ov)!=((val>>hs)<<hs)){
203 fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n",
204 (long)val,(long)ov_pcm_tell(&ov));
208 _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);
213 fprintf(stderr,"\r");
215 fprintf(stderr,"testing time page seeking to random places in %f seconds....\n",
219 double val=(double)rand()/RAND_MAX*timelength;
220 fprintf(stderr,"\r\t%d [time position %f]... ",i,val);
221 ret=ov_time_seek_page(&ov,val);
223 fprintf(stderr,"seek failed: %d\n",ret);
227 _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);
232 fprintf(stderr,"\r");
234 fprintf(stderr,"testing time exact seeking to random places in %f seconds....\n",
238 double val=(double)rand()/RAND_MAX*timelength;
239 fprintf(stderr,"\r\t%d [time position %f]... ",i,val);
240 ret=ov_time_seek(&ov,val);
242 fprintf(stderr,"seek failed: %d\n",ret);
245 if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){
246 fprintf(stderr,"Declared position didn't perfectly match request: %f != %f\n",
247 val,ov_time_tell(&ov));
251 _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);
256 fprintf(stderr,"\r \nOK.\n\n");
260 fprintf(stderr,"Standard input was not seekable.\n");