cannam@86
|
1 /********************************************************************
|
cannam@86
|
2 * *
|
cannam@86
|
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
|
cannam@86
|
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
cannam@86
|
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
cannam@86
|
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
cannam@86
|
7 * *
|
cannam@86
|
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
cannam@86
|
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
|
cannam@86
|
10 * *
|
cannam@86
|
11 ********************************************************************
|
cannam@86
|
12
|
cannam@86
|
13 function: illustrate seeking, and test it too
|
cannam@86
|
14 last mod: $Id: seeking_example.c 17561 2010-10-23 10:34:24Z xiphmont $
|
cannam@86
|
15
|
cannam@86
|
16 ********************************************************************/
|
cannam@86
|
17
|
cannam@86
|
18 #include <stdlib.h>
|
cannam@86
|
19 #include <stdio.h>
|
cannam@86
|
20 #include "vorbis/codec.h"
|
cannam@86
|
21 #include "vorbis/vorbisfile.h"
|
cannam@86
|
22
|
cannam@86
|
23 #ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
|
cannam@86
|
24 # include <io.h>
|
cannam@86
|
25 # include <fcntl.h>
|
cannam@86
|
26 #endif
|
cannam@86
|
27
|
cannam@86
|
28 void _verify(OggVorbis_File *ov,
|
cannam@86
|
29 ogg_int64_t val,ogg_int64_t pcmval,double timeval,
|
cannam@86
|
30 ogg_int64_t pcmlength,
|
cannam@86
|
31 char *bigassbuffer){
|
cannam@86
|
32 off_t i;
|
cannam@86
|
33 int j;
|
cannam@86
|
34 long bread;
|
cannam@86
|
35 char buffer[4096];
|
cannam@86
|
36 int dummy;
|
cannam@86
|
37 ogg_int64_t pos;
|
cannam@86
|
38 int hs = ov_halfrate_p(ov);
|
cannam@86
|
39
|
cannam@86
|
40 /* verify the raw position, the pcm position and position decode */
|
cannam@86
|
41 if(val!=-1 && ov_raw_tell(ov)<val){
|
cannam@86
|
42 fprintf(stderr,"raw position out of tolerance: requested %ld, got %ld\n",
|
cannam@86
|
43 (long)val,(long)ov_raw_tell(ov));
|
cannam@86
|
44 exit(1);
|
cannam@86
|
45 }
|
cannam@86
|
46 if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){
|
cannam@86
|
47 fprintf(stderr,"pcm position out of tolerance: requested %ld, got %ld\n",
|
cannam@86
|
48 (long)pcmval,(long)ov_pcm_tell(ov));
|
cannam@86
|
49 exit(1);
|
cannam@86
|
50 }
|
cannam@86
|
51 if(timeval!=-1 && ov_time_tell(ov)>timeval){
|
cannam@86
|
52 fprintf(stderr,"time position out of tolerance: requested %f, got %f\n",
|
cannam@86
|
53 timeval,ov_time_tell(ov));
|
cannam@86
|
54 exit(1);
|
cannam@86
|
55 }
|
cannam@86
|
56 pos=ov_pcm_tell(ov);
|
cannam@86
|
57 if(pos<0 || pos>pcmlength){
|
cannam@86
|
58 fprintf(stderr,"pcm position out of bounds: got %ld\n",(long)pos);
|
cannam@86
|
59 exit(1);
|
cannam@86
|
60 }
|
cannam@86
|
61 bread=ov_read(ov,buffer,4096,1,1,1,&dummy);
|
cannam@86
|
62 for(j=0;j<bread;j++){
|
cannam@86
|
63 if(buffer[j]!=bigassbuffer[j+((pos>>hs)*2)]){
|
cannam@86
|
64 fprintf(stderr,"data after seek doesn't match declared pcm position %ld\n",(long)pos);
|
cannam@86
|
65
|
cannam@86
|
66 for(i=0;i<(pcmlength>>hs)*2-bread;i++){
|
cannam@86
|
67 for(j=0;j<bread;j++)
|
cannam@86
|
68 if(buffer[j] != bigassbuffer[i+j])break;
|
cannam@86
|
69 if(j==bread){
|
cannam@86
|
70 fprintf(stderr,"data after seek appears to match position %ld\n",(long)((i/2)<<hs));
|
cannam@86
|
71 }
|
cannam@86
|
72 }
|
cannam@86
|
73 {
|
cannam@86
|
74 FILE *f=fopen("a.m","w");
|
cannam@86
|
75 for(j=0;j<bread;j++)fprintf(f,"%d %d\n",j,(int)buffer[j]);
|
cannam@86
|
76 fclose(f);
|
cannam@86
|
77 f=fopen("b.m","w");
|
cannam@86
|
78 for(j=-4096;j<bread+4096;j++)
|
cannam@86
|
79 if(j+((pos*2)>>hs)>=0 && (j+((pos*2)>>hs))<(pcmlength>>hs)*2)
|
cannam@86
|
80 fprintf(f,"%d %d\n",j,(int)bigassbuffer[j+((pos*2)>>hs)]);
|
cannam@86
|
81 fclose(f);
|
cannam@86
|
82 }
|
cannam@86
|
83
|
cannam@86
|
84 exit(1);
|
cannam@86
|
85 }
|
cannam@86
|
86 }
|
cannam@86
|
87 }
|
cannam@86
|
88
|
cannam@86
|
89 int main(){
|
cannam@86
|
90 OggVorbis_File ov;
|
cannam@86
|
91 int i,ret;
|
cannam@86
|
92 ogg_int64_t pcmlength;
|
cannam@86
|
93 double timelength;
|
cannam@86
|
94 char *bigassbuffer;
|
cannam@86
|
95 int dummy;
|
cannam@86
|
96 int hs=0;
|
cannam@86
|
97
|
cannam@86
|
98 #ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
|
cannam@86
|
99 _setmode( _fileno( stdin ), _O_BINARY );
|
cannam@86
|
100 #endif
|
cannam@86
|
101
|
cannam@86
|
102
|
cannam@86
|
103 /* open the file/pipe on stdin */
|
cannam@86
|
104 if(ov_open_callbacks(stdin,&ov,NULL,-1,OV_CALLBACKS_NOCLOSE)<0){
|
cannam@86
|
105 fprintf(stderr,"Could not open input as an OggVorbis file.\n\n");
|
cannam@86
|
106 exit(1);
|
cannam@86
|
107 }
|
cannam@86
|
108
|
cannam@86
|
109 #if 0 /*enable this code to test seeking with halfrate decode */
|
cannam@86
|
110 if(ov_halfrate(&ov,1)){
|
cannam@86
|
111 fprintf(stderr,"Sorry; unable to set half-rate decode.\n\n");
|
cannam@86
|
112 exit(1);
|
cannam@86
|
113 }else
|
cannam@86
|
114 hs=1;
|
cannam@86
|
115 #endif
|
cannam@86
|
116
|
cannam@86
|
117 if(ov_seekable(&ov)){
|
cannam@86
|
118
|
cannam@86
|
119 /* to simplify our own lives, we want to assume the whole file is
|
cannam@86
|
120 stereo. Verify this to avoid potentially mystifying users
|
cannam@86
|
121 (pissing them off is OK, just don't confuse them) */
|
cannam@86
|
122 for(i=0;i<ov.links;i++){
|
cannam@86
|
123 vorbis_info *vi=ov_info(&ov,i);
|
cannam@86
|
124 if(vi->channels!=2){
|
cannam@86
|
125 fprintf(stderr,"Sorry; right now seeking_test can only use Vorbis files\n"
|
cannam@86
|
126 "that are entirely stereo.\n\n");
|
cannam@86
|
127 exit(1);
|
cannam@86
|
128 }
|
cannam@86
|
129 }
|
cannam@86
|
130
|
cannam@86
|
131 /* because we want to do sample-level verification that the seek
|
cannam@86
|
132 does what it claimed, decode the entire file into memory */
|
cannam@86
|
133 pcmlength=ov_pcm_total(&ov,-1);
|
cannam@86
|
134 timelength=ov_time_total(&ov,-1);
|
cannam@86
|
135 bigassbuffer=malloc((pcmlength>>hs)*2); /* w00t */
|
cannam@86
|
136 i=0;
|
cannam@86
|
137 while(i<(pcmlength>>hs)*2){
|
cannam@86
|
138 int ret=ov_read(&ov,bigassbuffer+i,((pcmlength>>hs)*2)-i,1,1,1,&dummy);
|
cannam@86
|
139 if(ret<0){
|
cannam@86
|
140 fprintf(stderr,"Error reading file.\n");
|
cannam@86
|
141 exit(1);
|
cannam@86
|
142 }
|
cannam@86
|
143 if(ret){
|
cannam@86
|
144 i+=ret;
|
cannam@86
|
145 }else{
|
cannam@86
|
146 pcmlength=(i/2)<<hs;
|
cannam@86
|
147 }
|
cannam@86
|
148 fprintf(stderr,"\rloading.... [%ld left] ",
|
cannam@86
|
149 (long)((pcmlength>>hs)*2-i));
|
cannam@86
|
150 }
|
cannam@86
|
151
|
cannam@86
|
152 {
|
cannam@86
|
153 ogg_int64_t length=ov.end;
|
cannam@86
|
154 fprintf(stderr,"\rtesting raw seeking to random places in %ld bytes....\n",
|
cannam@86
|
155 (long)length);
|
cannam@86
|
156
|
cannam@86
|
157 for(i=0;i<1000;i++){
|
cannam@86
|
158 ogg_int64_t val=(double)rand()/RAND_MAX*length;
|
cannam@86
|
159 fprintf(stderr,"\r\t%d [raw position %ld]... ",i,(long)val);
|
cannam@86
|
160 ret=ov_raw_seek(&ov,val);
|
cannam@86
|
161 if(ret<0){
|
cannam@86
|
162 fprintf(stderr,"seek failed: %d\n",ret);
|
cannam@86
|
163 exit(1);
|
cannam@86
|
164 }
|
cannam@86
|
165
|
cannam@86
|
166 _verify(&ov,val,-1,-1.,pcmlength,bigassbuffer);
|
cannam@86
|
167
|
cannam@86
|
168 }
|
cannam@86
|
169 }
|
cannam@86
|
170
|
cannam@86
|
171 fprintf(stderr,"\r");
|
cannam@86
|
172 {
|
cannam@86
|
173 fprintf(stderr,"testing pcm page seeking to random places in %ld samples....\n",
|
cannam@86
|
174 (long)pcmlength);
|
cannam@86
|
175
|
cannam@86
|
176 for(i=0;i<1000;i++){
|
cannam@86
|
177 ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
|
cannam@86
|
178 fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val);
|
cannam@86
|
179 ret=ov_pcm_seek_page(&ov,val);
|
cannam@86
|
180 if(ret<0){
|
cannam@86
|
181 fprintf(stderr,"seek failed: %d\n",ret);
|
cannam@86
|
182 exit(1);
|
cannam@86
|
183 }
|
cannam@86
|
184
|
cannam@86
|
185 _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);
|
cannam@86
|
186
|
cannam@86
|
187 }
|
cannam@86
|
188 }
|
cannam@86
|
189
|
cannam@86
|
190 fprintf(stderr,"\r");
|
cannam@86
|
191 {
|
cannam@86
|
192 fprintf(stderr,"testing pcm exact seeking to random places in %ld samples....\n",
|
cannam@86
|
193 (long)pcmlength);
|
cannam@86
|
194
|
cannam@86
|
195 for(i=0;i<1000;i++){
|
cannam@86
|
196 ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
|
cannam@86
|
197 fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val);
|
cannam@86
|
198 ret=ov_pcm_seek(&ov,val);
|
cannam@86
|
199 if(ret<0){
|
cannam@86
|
200 fprintf(stderr,"seek failed: %d\n",ret);
|
cannam@86
|
201 exit(1);
|
cannam@86
|
202 }
|
cannam@86
|
203 if(ov_pcm_tell(&ov)!=((val>>hs)<<hs)){
|
cannam@86
|
204 fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n",
|
cannam@86
|
205 (long)val,(long)ov_pcm_tell(&ov));
|
cannam@86
|
206 exit(1);
|
cannam@86
|
207 }
|
cannam@86
|
208
|
cannam@86
|
209 _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);
|
cannam@86
|
210
|
cannam@86
|
211 }
|
cannam@86
|
212 }
|
cannam@86
|
213
|
cannam@86
|
214 fprintf(stderr,"\r");
|
cannam@86
|
215 {
|
cannam@86
|
216 fprintf(stderr,"testing time page seeking to random places in %f seconds....\n",
|
cannam@86
|
217 timelength);
|
cannam@86
|
218
|
cannam@86
|
219 for(i=0;i<1000;i++){
|
cannam@86
|
220 double val=(double)rand()/RAND_MAX*timelength;
|
cannam@86
|
221 fprintf(stderr,"\r\t%d [time position %f]... ",i,val);
|
cannam@86
|
222 ret=ov_time_seek_page(&ov,val);
|
cannam@86
|
223 if(ret<0){
|
cannam@86
|
224 fprintf(stderr,"seek failed: %d\n",ret);
|
cannam@86
|
225 exit(1);
|
cannam@86
|
226 }
|
cannam@86
|
227
|
cannam@86
|
228 _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);
|
cannam@86
|
229
|
cannam@86
|
230 }
|
cannam@86
|
231 }
|
cannam@86
|
232
|
cannam@86
|
233 fprintf(stderr,"\r");
|
cannam@86
|
234 {
|
cannam@86
|
235 fprintf(stderr,"testing time exact seeking to random places in %f seconds....\n",
|
cannam@86
|
236 timelength);
|
cannam@86
|
237
|
cannam@86
|
238 for(i=0;i<1000;i++){
|
cannam@86
|
239 double val=(double)rand()/RAND_MAX*timelength;
|
cannam@86
|
240 fprintf(stderr,"\r\t%d [time position %f]... ",i,val);
|
cannam@86
|
241 ret=ov_time_seek(&ov,val);
|
cannam@86
|
242 if(ret<0){
|
cannam@86
|
243 fprintf(stderr,"seek failed: %d\n",ret);
|
cannam@86
|
244 exit(1);
|
cannam@86
|
245 }
|
cannam@86
|
246 if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){
|
cannam@86
|
247 fprintf(stderr,"Declared position didn't perfectly match request: %f != %f\n",
|
cannam@86
|
248 val,ov_time_tell(&ov));
|
cannam@86
|
249 exit(1);
|
cannam@86
|
250 }
|
cannam@86
|
251
|
cannam@86
|
252 _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);
|
cannam@86
|
253
|
cannam@86
|
254 }
|
cannam@86
|
255 }
|
cannam@86
|
256
|
cannam@86
|
257 fprintf(stderr,"\r \nOK.\n\n");
|
cannam@86
|
258
|
cannam@86
|
259
|
cannam@86
|
260 }else{
|
cannam@86
|
261 fprintf(stderr,"Standard input was not seekable.\n");
|
cannam@86
|
262 }
|
cannam@86
|
263
|
cannam@86
|
264 ov_clear(&ov);
|
cannam@86
|
265 return 0;
|
cannam@86
|
266 }
|
cannam@86
|
267
|
cannam@86
|
268
|
cannam@86
|
269
|
cannam@86
|
270
|
cannam@86
|
271
|
cannam@86
|
272
|
cannam@86
|
273
|
cannam@86
|
274
|
cannam@86
|
275
|
cannam@86
|
276
|
cannam@86
|
277
|
cannam@86
|
278
|
cannam@86
|
279
|