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-2007 * |
---|
9 | * by the Xiph.Org Foundation http://www.xiph.org/ * |
---|
10 | * * |
---|
11 | ******************************************************************** |
---|
12 | |
---|
13 | function: illustrate seeking, and test it too |
---|
14 | last mod: $Id: seeking_example.c 13293 2007-07-24 00:09:47Z xiphmont $ |
---|
15 | |
---|
16 | ********************************************************************/ |
---|
17 | |
---|
18 | #include <stdlib.h> |
---|
19 | #include <stdio.h> |
---|
20 | #include "vorbis/codec.h" |
---|
21 | #include "vorbis/vorbisfile.h" |
---|
22 | |
---|
23 | #ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */ |
---|
24 | # include <io.h> |
---|
25 | # include <fcntl.h> |
---|
26 | #endif |
---|
27 | |
---|
28 | void _verify(OggVorbis_File *ov, |
---|
29 | ogg_int64_t val,ogg_int64_t pcmval,double timeval, |
---|
30 | ogg_int64_t pcmlength, |
---|
31 | char *bigassbuffer){ |
---|
32 | int j; |
---|
33 | long bread; |
---|
34 | char buffer[4096]; |
---|
35 | int dummy; |
---|
36 | ogg_int64_t pos; |
---|
37 | |
---|
38 | /* verify the raw position, the pcm position and position decode */ |
---|
39 | if(val!=-1 && ov_raw_tell(ov)<val){ |
---|
40 | fprintf(stderr,"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 | fprintf(stderr,"pcm position out of tolerance: requested %ld, got %ld\n", |
---|
46 | (long)pcmval,(long)ov_pcm_tell(ov)); |
---|
47 | exit(1); |
---|
48 | } |
---|
49 | if(timeval!=-1 && ov_time_tell(ov)>timeval){ |
---|
50 | fprintf(stderr,"time position out of tolerance: requested %f, got %f\n", |
---|
51 | timeval,ov_time_tell(ov)); |
---|
52 | exit(1); |
---|
53 | } |
---|
54 | pos=ov_pcm_tell(ov); |
---|
55 | if(pos<0 || pos>pcmlength){ |
---|
56 | fprintf(stderr,"pcm position out of bounds: got %ld\n",(long)pos); |
---|
57 | exit(1); |
---|
58 | } |
---|
59 | bread=ov_read(ov,buffer,4096,1,1,1,&dummy); |
---|
60 | for(j=0;j<bread;j++){ |
---|
61 | if(buffer[j]!=bigassbuffer[j+pos*2]){ |
---|
62 | fprintf(stderr,"data position after seek doesn't match pcm position\n"); |
---|
63 | |
---|
64 | { |
---|
65 | FILE *f=fopen("a.m","w"); |
---|
66 | for(j=0;j<bread;j++)fprintf(f,"%d\n",(int)buffer[j]); |
---|
67 | fclose(f); |
---|
68 | f=fopen("b.m","w"); |
---|
69 | for(j=0;j<bread;j++)fprintf(f,"%d\n",(int)bigassbuffer[j+pos*2]); |
---|
70 | fclose(f); |
---|
71 | } |
---|
72 | |
---|
73 | exit(1); |
---|
74 | } |
---|
75 | } |
---|
76 | } |
---|
77 | |
---|
78 | int main(){ |
---|
79 | OggVorbis_File ov; |
---|
80 | int i,ret; |
---|
81 | ogg_int64_t pcmlength; |
---|
82 | double timelength; |
---|
83 | char *bigassbuffer; |
---|
84 | int dummy; |
---|
85 | |
---|
86 | #ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */ |
---|
87 | _setmode( _fileno( stdin ), _O_BINARY ); |
---|
88 | #endif |
---|
89 | |
---|
90 | |
---|
91 | /* open the file/pipe on stdin */ |
---|
92 | if(ov_open_callbacks(stdin,&ov,NULL,-1,OV_CALLBACKS_NOCLOSE)<0){ |
---|
93 | fprintf(stderr,"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 | fprintf(stderr,"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 | pcmlength=ov_pcm_total(&ov,-1); |
---|
114 | timelength=ov_time_total(&ov,-1); |
---|
115 | bigassbuffer=malloc(pcmlength*2); /* w00t */ |
---|
116 | i=0; |
---|
117 | while(i<pcmlength*2){ |
---|
118 | int ret=ov_read(&ov,bigassbuffer+i,pcmlength*2-i,1,1,1,&dummy); |
---|
119 | if(ret<0)continue; |
---|
120 | if(ret){ |
---|
121 | i+=ret; |
---|
122 | }else{ |
---|
123 | pcmlength=i/2; |
---|
124 | } |
---|
125 | fprintf(stderr,"\rloading.... [%ld left] ", |
---|
126 | (long)(pcmlength*2-i)); |
---|
127 | } |
---|
128 | |
---|
129 | { |
---|
130 | ogg_int64_t length=ov.end; |
---|
131 | fprintf(stderr,"\rtesting raw seeking to random places in %ld bytes....\n", |
---|
132 | (long)length); |
---|
133 | |
---|
134 | for(i=0;i<1000;i++){ |
---|
135 | ogg_int64_t val=(double)rand()/RAND_MAX*length; |
---|
136 | fprintf(stderr,"\r\t%d [raw position %ld]... ",i,(long)val); |
---|
137 | ret=ov_raw_seek(&ov,val); |
---|
138 | if(ret<0){ |
---|
139 | fprintf(stderr,"seek failed: %d\n",ret); |
---|
140 | exit(1); |
---|
141 | } |
---|
142 | |
---|
143 | _verify(&ov,val,-1,-1.,pcmlength,bigassbuffer); |
---|
144 | |
---|
145 | } |
---|
146 | } |
---|
147 | |
---|
148 | fprintf(stderr,"\r"); |
---|
149 | { |
---|
150 | fprintf(stderr,"testing pcm page seeking to random places in %ld samples....\n", |
---|
151 | (long)pcmlength); |
---|
152 | |
---|
153 | for(i=0;i<1000;i++){ |
---|
154 | ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength; |
---|
155 | fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val); |
---|
156 | ret=ov_pcm_seek_page(&ov,val); |
---|
157 | if(ret<0){ |
---|
158 | fprintf(stderr,"seek failed: %d\n",ret); |
---|
159 | exit(1); |
---|
160 | } |
---|
161 | |
---|
162 | _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer); |
---|
163 | |
---|
164 | } |
---|
165 | } |
---|
166 | |
---|
167 | fprintf(stderr,"\r"); |
---|
168 | { |
---|
169 | fprintf(stderr,"testing pcm exact seeking to random places in %ld samples....\n", |
---|
170 | (long)pcmlength); |
---|
171 | |
---|
172 | for(i=0;i<1000;i++){ |
---|
173 | ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength; |
---|
174 | fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val); |
---|
175 | ret=ov_pcm_seek(&ov,val); |
---|
176 | if(ret<0){ |
---|
177 | fprintf(stderr,"seek failed: %d\n",ret); |
---|
178 | exit(1); |
---|
179 | } |
---|
180 | if(ov_pcm_tell(&ov)!=val){ |
---|
181 | fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n", |
---|
182 | (long)val,(long)ov_pcm_tell(&ov)); |
---|
183 | exit(1); |
---|
184 | } |
---|
185 | |
---|
186 | _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer); |
---|
187 | |
---|
188 | } |
---|
189 | } |
---|
190 | |
---|
191 | fprintf(stderr,"\r"); |
---|
192 | { |
---|
193 | fprintf(stderr,"testing time page seeking to random places in %f seconds....\n", |
---|
194 | timelength); |
---|
195 | |
---|
196 | for(i=0;i<1000;i++){ |
---|
197 | double val=(double)rand()/RAND_MAX*timelength; |
---|
198 | fprintf(stderr,"\r\t%d [time position %f]... ",i,val); |
---|
199 | ret=ov_time_seek_page(&ov,val); |
---|
200 | if(ret<0){ |
---|
201 | fprintf(stderr,"seek failed: %d\n",ret); |
---|
202 | exit(1); |
---|
203 | } |
---|
204 | |
---|
205 | _verify(&ov,-1,-1,val,pcmlength,bigassbuffer); |
---|
206 | |
---|
207 | } |
---|
208 | } |
---|
209 | |
---|
210 | fprintf(stderr,"\r"); |
---|
211 | { |
---|
212 | fprintf(stderr,"testing time exact seeking to random places in %f seconds....\n", |
---|
213 | timelength); |
---|
214 | |
---|
215 | for(i=0;i<1000;i++){ |
---|
216 | double val=(double)rand()/RAND_MAX*timelength; |
---|
217 | fprintf(stderr,"\r\t%d [time position %f]... ",i,val); |
---|
218 | ret=ov_time_seek(&ov,val); |
---|
219 | if(ret<0){ |
---|
220 | fprintf(stderr,"seek failed: %d\n",ret); |
---|
221 | exit(1); |
---|
222 | } |
---|
223 | if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){ |
---|
224 | fprintf(stderr,"Declared position didn't perfectly match request: %f != %f\n", |
---|
225 | val,ov_time_tell(&ov)); |
---|
226 | exit(1); |
---|
227 | } |
---|
228 | |
---|
229 | _verify(&ov,-1,-1,val,pcmlength,bigassbuffer); |
---|
230 | |
---|
231 | } |
---|
232 | } |
---|
233 | |
---|
234 | fprintf(stderr,"\r \nOK.\n\n"); |
---|
235 | |
---|
236 | |
---|
237 | }else{ |
---|
238 | fprintf(stderr,"Standard input was not seekable.\n"); |
---|
239 | } |
---|
240 | |
---|
241 | ov_clear(&ov); |
---|
242 | return 0; |
---|
243 | } |
---|
244 | |
---|
245 | |
---|
246 | |
---|
247 | |
---|
248 | |
---|
249 | |
---|
250 | |
---|
251 | |
---|
252 | |
---|
253 | |
---|
254 | |
---|
255 | |
---|
256 | |
---|