Add support for named files on the command line, while maintaining
[platform/upstream/libvorbis.git] / examples / seeking_example.c
1 /********************************************************************
2  *                                                                  *
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.       *
7  *                                                                  *
8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
9  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
10
11  ********************************************************************
12
13  function: illustrate seeking, and test it too
14  last mod: $Id: seeking_example.c,v 1.9 2001/09/15 04:47:48 cwolf Exp $
15
16  ********************************************************************/
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include "vorbis/codec.h"
21 #include "vorbis/vorbisfile.h"
22 //#include "../lib/misc.h"
23
24 #ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
25 # include <io.h>
26 # include <fcntl.h>
27 #endif
28
29 void _verify(OggVorbis_File *ov,ogg_int64_t pos,
30              ogg_int64_t val,ogg_int64_t pcmval,
31              ogg_int64_t pcmlength,
32              char *bigassbuffer){
33   int j;
34   long bread;
35   char buffer[4096];
36   int dummy;
37
38   /* verify the raw position, the pcm position and position decode */
39   if(val!=-1 && ov_raw_tell(ov)<val){
40     printf("raw position out of tolerance: requested %ld, got %ld\n",
41            (long)val,(long)ov_raw_tell(ov));
42     exit(1);
43   }
44   if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){
45     printf("pcm position out of tolerance: requested %ld, got %ld\n",
46            (long)pcmval,(long)ov_pcm_tell(ov));
47     exit(1);
48   }
49   pos=ov_pcm_tell(ov);
50   if(pos<0 || pos>pcmlength){
51     printf("pcm position out of bounds: got %ld\n",(long)pos);
52     exit(1);
53   }
54   bread=ov_read(ov,buffer,4096,1,1,1,&dummy);
55   for(j=0;j<bread;j++){
56     if(buffer[j]!=bigassbuffer[j+pos*2]){
57       printf("data position after seek doesn't match pcm position\n");
58       exit(1);
59     }
60   }
61 }
62
63 int main(int argc, char *argv[]){
64   OggVorbis_File ov;
65   int i,ret;
66   ogg_int64_t pcmlength;
67   char *bigassbuffer;
68   int dummy;
69   char msg[256];
70   FILE *fpin=NULL;
71
72 #ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
73   _setmode( _fileno( stdin ), _O_BINARY );
74   _setmode( _fileno( stdout ), _O_BINARY );
75 #endif
76
77   /* If command line args were supplied, open the named file(s)
78      for i/o, else maintain use of stdin/stdout.*/
79   if (argc == 2)
80   {
81     if ((fpin = fopen(argv[1], "rb")) == (FILE*)NULL)
82     {
83       (void)sprintf(msg, "Can't open \"%s\" for input", argv[1]);
84       perror(msg);
85       return 1;
86     }
87   }
88   else
89     fpin = stdin;
90
91   /* open the file/pipe on stdin */
92   if(ov_open(fpin,&ov,NULL,-1)<0){
93     printf("Could not open input as an OggVorbis file.\n\n");
94     exit(1);
95   }
96
97   if(ov_seekable(&ov)){
98
99     /* to simplify our own lives, we want to assume the whole file is
100        stereo.  Verify this to avoid potentially mystifying users
101        (pissing them off is OK, just don't confuse them) */
102     for(i=0;i<ov.links;i++){
103       vorbis_info *vi=ov_info(&ov,i);
104       if(vi->channels!=2){
105         printf("Sorry; right now seeking_test can only use Vorbis files\n"
106                "that are entirely stereo.\n\n");
107         exit(1);
108       }
109     }
110     
111     /* because we want to do sample-level verification that the seek
112        does what it claimed, decode the entire file into memory */
113     printf("loading....\n");
114     fflush(stdout);
115     pcmlength=ov_pcm_total(&ov,-1);
116     bigassbuffer=malloc(pcmlength*2); /* w00t */
117     i=0;
118     while(i<pcmlength*2){
119       int ret=ov_read(&ov,bigassbuffer+i,pcmlength*2-i,1,1,1,&dummy);
120       if(ret<0)continue;
121       if(ret){
122         i+=ret;
123       }else{
124         pcmlength=i/2;
125       }
126     }
127     
128     /* Exercise all the real seeking cases; ov_raw_seek,
129        ov_pcm_seek_page and ov_pcm_seek.  time seek is just a wrapper
130        on pcm_seek */
131     {
132       ogg_int64_t length=ov.end;
133       printf("testing raw seeking to random places in %ld bytes....\n",
134              (long)length);
135     
136       for(i=0;i<1000;i++){
137         ogg_int64_t val=(double)rand()/RAND_MAX*length;
138         ogg_int64_t pos;
139         printf("\r\t%d [raw position %ld]...     ",i,(long)val);
140         fflush(stdout);
141         ret=ov_raw_seek(&ov,val);
142         if(ret<0){
143           printf("seek failed: %d\n",ret);
144           exit(1);
145         }
146
147         _verify(&ov,pos,val,-1,pcmlength,bigassbuffer);
148
149       }
150     }
151
152     printf("\r");
153     {
154       ogg_int64_t length=ov.end;
155       printf("testing pcm page seeking to random places in %ld samples....\n",
156              (long)pcmlength);
157     
158       for(i=0;i<1000;i++){
159         ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
160         ogg_int64_t pos;
161         printf("\r\t%d [pcm position %ld]...     ",i,(long)val);
162         fflush(stdout);
163         ret=ov_pcm_seek_page(&ov,val);
164         if(ret<0){
165           printf("seek failed: %d\n",ret);
166           exit(1);
167         }
168
169         _verify(&ov,pos,-1,val,pcmlength,bigassbuffer);
170
171       }
172     }
173     
174     printf("\r");
175     {
176       ogg_int64_t length=ov.end;
177       printf("testing pcm exact seeking to random places in %ld samples....\n",
178              (long)pcmlength);
179     
180       for(i=0;i<1000;i++){
181         ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
182         ogg_int64_t pos;
183         printf("\r\t%d [pcm position %ld]...     ",i,(long)val);
184         fflush(stdout);
185         ret=ov_pcm_seek(&ov,val);
186         if(ret<0){
187           printf("seek failed: %d\n",ret);
188           exit(1);
189         }
190         if(ov_pcm_tell(&ov)!=val){
191           printf("Decalred position didn't perfectly match request: %ld != %ld\n",
192                  (long)val,(long)ov_pcm_tell(&ov));
193           exit(1);
194         }
195
196         _verify(&ov,pos,-1,val,pcmlength,bigassbuffer);
197
198       }
199     }
200     
201     printf("\r                                           \nOK.\n\n");
202
203
204   }else{
205     printf("Standard input was not seekable.\n");
206   }
207
208   ov_clear(&ov);
209   return 0;
210 }
211
212
213
214
215
216
217
218
219
220
221
222
223