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