examples/SFExamples/oggvorbiscodec/src/libvorbis/examples/seeking_example.c

00001 /********************************************************************
00002  *                                                                  *
00003  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
00004  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
00005  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
00006  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
00007  *                                                                  *
00008  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
00009  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
00010  *                                                                  *
00011  ********************************************************************
00012 
00013  function: illustrate seeking, and test it too
00014  last mod: $Id: seeking_example.c 7187 2004-07-20 07:24:27Z xiphmont $
00015 
00016  ********************************************************************/
00017 
00018 #include <stdlib.h>
00019 #include <stdio.h>
00020 #include "vorbis/codec.h"
00021 #include "vorbis/vorbisfile.h"
00022 
00023 #if defined(_WIN32) && !defined(__SYMBIAN32__) /* We need the following two to set stdin/stdout to binary */
00024 # include <io.h>
00025 # include <fcntl.h>
00026 #endif
00027 
00028 void _verify(OggVorbis_File *ov,ogg_int64_t pos,
00029              ogg_int64_t val,ogg_int64_t pcmval,
00030              ogg_int64_t pcmlength,
00031              char *bigassbuffer){
00032   int j;
00033   long bread;
00034   char buffer[4096];
00035   int dummy;
00036 
00037   /* verify the raw position, the pcm position and position decode */
00038   if(val!=-1 && ov_raw_tell(ov)<val){
00039     printf("raw position out of tolerance: requested %ld, got %ld\n",
00040            (long)val,(long)ov_raw_tell(ov));
00041     exit(1);
00042   }
00043   if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){
00044     printf("pcm position out of tolerance: requested %ld, got %ld\n",
00045            (long)pcmval,(long)ov_pcm_tell(ov));
00046     exit(1);
00047   }
00048   pos=ov_pcm_tell(ov);
00049   if(pos<0 || pos>pcmlength){
00050     printf("pcm position out of bounds: got %ld\n",(long)pos);
00051     exit(1);
00052   }
00053   bread=ov_read(ov,buffer,4096,1,1,1,&dummy);
00054   for(j=0;j<bread;j++){
00055     if(buffer[j]!=bigassbuffer[j+pos*2]){
00056       printf("data position after seek doesn't match pcm position\n");
00057 
00058       {
00059         FILE *f=fopen("a.m","w");
00060         for(j=0;j<bread;j++)fprintf(f,"%d\n",(int)buffer[j]);
00061         fclose(f);
00062         f=fopen("b.m","w");
00063         for(j=0;j<bread;j++)fprintf(f,"%d\n",(int)bigassbuffer[j+pos*2]);
00064         fclose(f);
00065       }
00066 
00067       exit(1);
00068     }
00069   }
00070 }
00071 
00072 int main(){
00073   OggVorbis_File ov;
00074   int i,ret;
00075   ogg_int64_t pcmlength;
00076   char *bigassbuffer;
00077   int dummy;
00078 
00079 #if defined(_WIN32) && !defined(__SYMBIAN32__) /* We need to set stdin/stdout to binary mode. Damn windows. */
00080   _setmode( _fileno( stdin ), _O_BINARY );
00081   _setmode( _fileno( stdout ), _O_BINARY );
00082 #endif
00083 
00084 
00085   /* open the file/pipe on stdin */
00086   if(ov_open(stdin,&ov,NULL,-1)<0){
00087     printf("Could not open input as an OggVorbis file.\n\n");
00088     exit(1);
00089   }
00090 
00091   if(ov_seekable(&ov)){
00092 
00093     /* to simplify our own lives, we want to assume the whole file is
00094        stereo.  Verify this to avoid potentially mystifying users
00095        (pissing them off is OK, just don't confuse them) */
00096     for(i=0;i<ov.links;i++){
00097       vorbis_info *vi=ov_info(&ov,i);
00098       if(vi->channels!=2){
00099         printf("Sorry; right now seeking_test can only use Vorbis files\n"
00100                "that are entirely stereo.\n\n");
00101         exit(1);
00102       }
00103     }
00104     
00105     /* because we want to do sample-level verification that the seek
00106        does what it claimed, decode the entire file into memory */
00107     fflush(stdout);
00108     pcmlength=ov_pcm_total(&ov,-1);
00109     bigassbuffer=malloc(pcmlength*2); /* w00t */
00110     i=0;
00111     while(i<pcmlength*2){
00112       int ret=ov_read(&ov,bigassbuffer+i,pcmlength*2-i,1,1,1,&dummy);
00113       if(ret<0)continue;
00114       if(ret){
00115         i+=ret;
00116       }else{
00117         pcmlength=i/2;
00118       }
00119       fprintf(stderr,"\rloading.... [%ld left]              ",
00120               (long)(pcmlength*2-i));
00121     }
00122     
00123     /* Exercise all the real seeking cases; ov_raw_seek,
00124        ov_pcm_seek_page and ov_pcm_seek.  time seek is just a wrapper
00125        on pcm_seek */
00126     {
00127       ogg_int64_t length=ov.end;
00128       printf("\rtesting raw seeking to random places in %ld bytes....\n",
00129              (long)length);
00130     
00131       for(i=0;i<1000;i++){
00132         ogg_int64_t val=(double)rand()/RAND_MAX*length;
00133         ogg_int64_t pos;
00134         printf("\r\t%d [raw position %ld]...     ",i,(long)val);
00135         fflush(stdout);
00136         ret=ov_raw_seek(&ov,val);
00137         if(ret<0){
00138           printf("seek failed: %d\n",ret);
00139           exit(1);
00140         }
00141 
00142         _verify(&ov,pos,val,-1,pcmlength,bigassbuffer);
00143 
00144       }
00145     }
00146 
00147     printf("\r");
00148     {
00149       printf("testing pcm page seeking to random places in %ld samples....\n",
00150              (long)pcmlength);
00151     
00152       for(i=0;i<1000;i++){
00153         ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
00154         ogg_int64_t pos;
00155         printf("\r\t%d [pcm position %ld]...     ",i,(long)val);
00156         fflush(stdout);
00157         ret=ov_pcm_seek_page(&ov,val);
00158         if(ret<0){
00159           printf("seek failed: %d\n",ret);
00160           exit(1);
00161         }
00162 
00163         _verify(&ov,pos,-1,val,pcmlength,bigassbuffer);
00164 
00165       }
00166     }
00167     
00168     printf("\r");
00169     {
00170       ogg_int64_t length=ov.end;
00171       printf("testing pcm exact seeking to random places in %ld samples....\n",
00172              (long)pcmlength);
00173     
00174       for(i=0;i<1000;i++){
00175         ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
00176         ogg_int64_t pos;
00177         printf("\r\t%d [pcm position %ld]...     ",i,(long)val);
00178         fflush(stdout);
00179         ret=ov_pcm_seek(&ov,val);
00180         if(ret<0){
00181           printf("seek failed: %d\n",ret);
00182           exit(1);
00183         }
00184         if(ov_pcm_tell(&ov)!=val){
00185           printf("Declared position didn't perfectly match request: %ld != %ld\n",
00186                  (long)val,(long)ov_pcm_tell(&ov));
00187           exit(1);
00188         }
00189 
00190         _verify(&ov,pos,-1,val,pcmlength,bigassbuffer);
00191 
00192       }
00193     }
00194     
00195     printf("\r                                           \nOK.\n\n");
00196 
00197 
00198   }else{
00199     printf("Standard input was not seekable.\n");
00200   }
00201 
00202   ov_clear(&ov);
00203   return 0;
00204 }
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 

Generated by  doxygen 1.6.2