ref: 8e6d4a76d616b39464f4e4a08915871f14cef1f8
parent: 643aed3d2763db2a328a865d134e7d0a719c938e
author: Timothy B. Terriberry <tterribe@xiph.org>
date: Sun Sep 30 19:30:37 EDT 2012
Add status output to opusfile_example. This displays the current raw position, PCM position, and instantaneous bitrate once per second of output. This is useful when testing against long-running streams.
--- a/examples/opusfile_example.c
+++ b/examples/opusfile_example.c
@@ -32,10 +32,77 @@
# define op_read_native_stereo op_read_float_stereo
#endif
+static void print_duration(FILE *_fp,ogg_int64_t _nsamples,int _frac){
+ ogg_int64_t seconds;
+ ogg_int64_t minutes;
+ ogg_int64_t hours;
+ ogg_int64_t days;
+ ogg_int64_t weeks;
+ _nsamples+=_frac?24:24000;
+ seconds=_nsamples/48000;
+ _nsamples-=seconds*48000;
+ minutes=seconds/60;
+ seconds-=minutes*60;
+ hours=minutes/60;
+ minutes-=hours*60;
+ days=hours/24;
+ hours-=days*24;
+ weeks=days/7;
+ days-=weeks*7;
+ if(weeks)fprintf(_fp,"%liw",(long)weeks);
+ if(weeks||days)fprintf(_fp,"%id",(int)days);
+ if(weeks||days||hours){
+ if(weeks||days)fprintf(_fp,"%02ih",(int)hours);
+ else fprintf(_fp,"%ih",(int)hours);
+ }
+ if(weeks||days||hours||minutes){
+ if(weeks||days||hours)fprintf(_fp,"%02im",(int)minutes);
+ else fprintf(_fp,"%im",(int)minutes);
+ fprintf(_fp,"%02i",(int)seconds);
+ }
+ else fprintf(_fp,"%i",(int)seconds);
+ if(_frac)fprintf(_fp,".%03i",(int)(_nsamples/48));
+ fprintf(_fp,"s");
+}
+
+static void print_size(FILE *_fp,opus_int64 _nbytes,int _metric,
+ const char *_spacer){
+ static const char SUFFIXES[7]={' ','k','M','G','T','P','E'};
+ opus_int64 val;
+ opus_int64 den;
+ opus_int64 round;
+ int base;
+ int shift;
+ base=_metric?1000:1024;
+ round=0;
+ den=1;
+ for(shift=0;shift<6;shift++){
+ if(_nbytes<den*base-round)break;
+ den*=base;
+ round=den>>1;
+ }
+ val=(_nbytes+round)/den;
+ if(den>1&&val<10){
+ if(den>=1000000000)val=(_nbytes+(round/100))/(den/100);
+ else val=(_nbytes*100+round)/den;
+ fprintf(_fp,"%li.%02i%s%c",(long)(val/100),(int)(val%100),
+ _spacer,SUFFIXES[shift]);
+ }
+ else if(den>1&&val<100){
+ if(den>=1000000000)val=(_nbytes+(round/10))/(den/10);
+ else val=(_nbytes*10+round)/den;
+ fprintf(_fp,"%li.%i%s%c",(long)(val/10),(int)(val%10),
+ _spacer,SUFFIXES[shift]);
+ }
+ else fprintf(_fp,"%li%s%c",(long)val,_spacer,SUFFIXES[shift]);
+}
+
int main(int _argc,const char **_argv){
OggOpusFile *of;
ogg_int64_t pcm_offset;
+ ogg_int64_t pcm_print_offset;
ogg_int64_t nsamples;
+ opus_int32 bitrate;
int ret;
int prev_li;
#if defined(_WIN32)
@@ -80,10 +147,16 @@
}
if(op_seekable(of)){
ogg_int64_t duration;
+ opus_int64 size;
fprintf(stderr,"Total number of links: %i\n",op_link_count(of));
duration=op_pcm_total(of,-1);
- fprintf(stderr,"Total duration: %f seconds (%li samples @ 48 kHz).\n",
- duration/48000.0,(long)duration);
+ fprintf(stderr,"Total duration: ");
+ print_duration(stderr,duration,3);
+ fprintf(stderr," (%li samples @ 48 kHz)\n",(long)duration);
+ size=op_raw_total(of,-1);
+ fprintf(stderr,"Total size: ");
+ print_size(stderr,size,0,"");
+ fprintf(stderr,"\n");
}
prev_li=-1;
nsamples=0;
@@ -91,6 +164,8 @@
if(pcm_offset!=0){
fprintf(stderr,"Non-zero starting PCM offset: %li\n",(long)pcm_offset);
}
+ pcm_print_offset=pcm_offset-48000;
+ bitrate=0;
for(;;){
ogg_int64_t next_pcm_offset;
op_sample pcm[120*48*2];
@@ -97,7 +172,7 @@
int li;
ret=op_read_native_stereo(of,pcm,sizeof(pcm)/sizeof(*pcm));
if(ret<0){
- fprintf(stderr,"Error decoding '%s': %i\n",_argv[1],ret);
+ fprintf(stderr,"\nError decoding '%s': %i\n",_argv[1],ret);
ret=EXIT_FAILURE;
break;
}
@@ -108,14 +183,20 @@
int ci;
/*We found a new link.
Print out some information.*/
- fprintf(stderr,"Decoding link %i:\n",li);
+ fprintf(stderr,"Decoding link %i: \n",li);
head=op_head(of,li);
fprintf(stderr," Channels: %i\n",head->channel_count);
if(op_seekable(of)){
ogg_int64_t duration;
+ opus_int64 size;
duration=op_pcm_total(of,li);
- fprintf(stderr," Duration: %f seconds (%li samples @ 48 kHz).\n",
- duration/48000.0,(long)duration);
+ fprintf(stderr," Duration: ");
+ print_duration(stderr,duration,3);
+ fprintf(stderr," (%li samples @ 48 kHz)\n",(long)duration);
+ size=op_raw_total(of,li);
+ fprintf(stderr," Size: ");
+ print_size(stderr,size,0,"");
+ fprintf(stderr,"\n");
}
if(head->input_sample_rate){
fprintf(stderr," Original sampling rate: %lu Hz\n",
@@ -135,9 +216,24 @@
}
}
}
+ if(li!=prev_li||pcm_offset>=pcm_print_offset+48000){
+ opus_int32 next_bitrate;
+ opus_int64 raw_offset;
+ next_bitrate=op_bitrate_instant(of);
+ if(next_bitrate>=0)bitrate=next_bitrate;
+ raw_offset=op_raw_tell(of);
+ fprintf(stderr,"\r ");
+ print_size(stderr,raw_offset,0,"");
+ fprintf(stderr," ");
+ print_duration(stderr,pcm_offset,0);
+ fprintf(stderr," (");
+ print_size(stderr,bitrate,1," ");
+ fprintf(stderr,"bps) \r");
+ pcm_print_offset=pcm_offset;
+ }
next_pcm_offset=op_pcm_tell(of);
if(pcm_offset+ret!=next_pcm_offset){
- fprintf(stderr,"PCM offset gap! %li+%i!=%li\n",
+ fprintf(stderr,"\nPCM offset gap! %li+%i!=%li\n",
(long)pcm_offset,ret,(long)next_pcm_offset);
}
pcm_offset=next_pcm_offset;
@@ -146,7 +242,8 @@
break;
}
if(!fwrite(pcm,sizeof(*pcm)*2,ret,stdout)){
- fprintf(stderr,"Error writing decoded audio data: %s\n",strerror(errno));
+ fprintf(stderr,"\nError writing decoded audio data: %s\n",
+ strerror(errno));
ret=EXIT_FAILURE;
break;
}
@@ -155,7 +252,9 @@
}
op_free(of);
if(ret==EXIT_SUCCESS){
- fprintf(stderr,"Done (played %li samples).\n",(long)nsamples);
+ fprintf(stderr,"\nDone: played ");
+ print_duration(stderr,nsamples,3);
+ fprintf(stderr," (%li samples @ 48 kHz).\n",(long)nsamples);
}
return ret;
}
--- a/examples/seeking_example.c
+++ b/examples/seeking_example.c
@@ -238,9 +238,17 @@
days-=weeks*7;
if(weeks)fprintf(_fp,"%liw",(long)weeks);
if(weeks||days)fprintf(_fp,"%id",(int)days);
- if(weeks||days||hours)fprintf(_fp,"%ih",(int)hours);
- if(weeks||days||hours||minutes)fprintf(_fp,"%im",(int)minutes);
- fprintf(_fp,"%i.%03is",(int)seconds,(int)(_nsamples+24)/48);
+ if(weeks||days||hours){
+ if(weeks||days)fprintf(_fp,"%02ih",(int)hours);
+ else fprintf(_fp,"%ih",(int)hours);
+ }
+ if(weeks||days||hours||minutes){
+ if(weeks||days||hours)fprintf(_fp,"%02im",(int)minutes);
+ else fprintf(_fp,"%im",(int)minutes);
+ fprintf(_fp,"%02i",(int)seconds);
+ }
+ else fprintf(_fp,"%i",(int)seconds);
+ fprintf(_fp,".%03is",(int)(_nsamples+24)/48);
}
int main(int _argc,const char **_argv){