comparison src/libvorbis-1.3.3/examples/seeking_example.c @ 1:05aa0afa9217

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