diff options
Diffstat (limited to 'vorbis/examples')
-rw-r--r-- | vorbis/examples/Makefile.am | 34 | ||||
-rw-r--r-- | vorbis/examples/chaining_example.c | 71 | ||||
-rw-r--r-- | vorbis/examples/decoder_example.c | 313 | ||||
-rw-r--r-- | vorbis/examples/encoder_example.c | 251 | ||||
-rwxr-xr-x | vorbis/examples/frameview.pl | 630 | ||||
-rw-r--r-- | vorbis/examples/seeking_example.c | 277 | ||||
-rw-r--r-- | vorbis/examples/vorbisfile_example.c | 91 |
7 files changed, 1667 insertions, 0 deletions
diff --git a/vorbis/examples/Makefile.am b/vorbis/examples/Makefile.am new file mode 100644 index 0000000..5881635 --- /dev/null +++ b/vorbis/examples/Makefile.am @@ -0,0 +1,34 @@ +## Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = foreign + +noinst_PROGRAMS = decoder_example encoder_example chaining_example\ + vorbisfile_example seeking_example + +EXTRA_DIST = frameview.pl + +AM_CPPFLAGS = -I$(top_srcdir)/include @OGG_CFLAGS@ + +# uncomment to build static executables from the example code +#LDFLAGS = -all-static + +decoder_example_SOURCES = decoder_example.c +decoder_example_LDADD = $(top_builddir)/lib/libvorbis.la @OGG_LIBS@ + +encoder_example_SOURCES = encoder_example.c +encoder_example_LDADD = $(top_builddir)/lib/libvorbisenc.la $(top_builddir)/lib/libvorbis.la @OGG_LIBS@ + +chaining_example_SOURCES = chaining_example.c +chaining_example_LDADD = $(top_builddir)/lib/libvorbisfile.la $(top_builddir)/lib/libvorbis.la @OGG_LIBS@ + +vorbisfile_example_SOURCES = vorbisfile_example.c +vorbisfile_example_LDADD = $(top_builddir)/lib/libvorbisfile.la $(top_builddir)/lib/libvorbis.la @OGG_LIBS@ + +seeking_example_SOURCES = seeking_example.c +seeking_example_LDADD = $(top_builddir)/lib/libvorbisfile.la $(top_builddir)/lib/libvorbis.la @OGG_LIBS@ + +debug: + $(MAKE) all CFLAGS="@DEBUG@" + +profile: + $(MAKE) all CFLAGS="@PROFILE@" diff --git a/vorbis/examples/chaining_example.c b/vorbis/examples/chaining_example.c new file mode 100644 index 0000000..19215d7 --- /dev/null +++ b/vorbis/examples/chaining_example.c @@ -0,0 +1,71 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: illustrate simple use of chained bitstream and vorbisfile.a + + ********************************************************************/ + +#include <stdlib.h> +#include <vorbis/codec.h> +#include <vorbis/vorbisfile.h> + +#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */ +#include <io.h> +#include <fcntl.h> +#endif + +int main(){ + OggVorbis_File ov; + int i; + +#ifdef _WIN32 /* We need to set stdin to binary mode. Damn windows. */ + /* Beware the evil ifdef. We avoid these where we can, but this one we + cannot. Don't add any more, you'll probably go to hell if you do. */ + _setmode( _fileno( stdin ), _O_BINARY ); +#endif + + /* open the file/pipe on stdin */ + if(ov_open_callbacks(stdin,&ov,NULL,-1,OV_CALLBACKS_NOCLOSE)<0){ + printf("Could not open input as an OggVorbis file.\n\n"); + exit(1); + } + + /* print details about each logical bitstream in the input */ + if(ov_seekable(&ov)){ + printf("Input bitstream contained %ld logical bitstream section(s).\n", + ov_streams(&ov)); + printf("Total bitstream samples: %ld\n\n", + (long)ov_pcm_total(&ov,-1)); + printf("Total bitstream playing time: %ld seconds\n\n", + (long)ov_time_total(&ov,-1)); + + }else{ + printf("Standard input was not seekable.\n" + "First logical bitstream information:\n\n"); + } + + for(i=0;i<ov_streams(&ov);i++){ + vorbis_info *vi=ov_info(&ov,i); + printf("\tlogical bitstream section %d information:\n",i+1); + printf("\t\t%ldHz %d channels bitrate %ldkbps serial number=%ld\n", + vi->rate,vi->channels,ov_bitrate(&ov,i)/1000, + ov_serialnumber(&ov,i)); + printf("\t\theader length: %ld bytes\n",(long) + (ov.dataoffsets[i]-ov.offsets[i])); + printf("\t\tcompressed length: %ld bytes\n",(long)(ov_raw_total(&ov,i))); + printf("\t\tplay time: %lds\n",(long)ov_time_total(&ov,i)); + } + + ov_clear(&ov); + return 0; +} + diff --git a/vorbis/examples/decoder_example.c b/vorbis/examples/decoder_example.c new file mode 100644 index 0000000..e264e40 --- /dev/null +++ b/vorbis/examples/decoder_example.c @@ -0,0 +1,313 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: simple example decoder + + ********************************************************************/ + +/* Takes a vorbis bitstream from stdin and writes raw stereo PCM to + stdout. Decodes simple and chained OggVorbis files from beginning + to end. Vorbisfile.a is somewhat more complex than the code below. */ + +/* Note that this is POSIX, not ANSI code */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <vorbis/codec.h> + +#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */ +#include <io.h> +#include <fcntl.h> +#endif + +#if defined(__MACOS__) && defined(__MWERKS__) +#include <console.h> /* CodeWarrior's Mac "command-line" support */ +#endif + +ogg_int16_t convbuffer[4096]; /* take 8k out of the data segment, not the stack */ +int convsize=4096; + +extern void _VDBG_dump(void); + +int main(){ + ogg_sync_state oy; /* sync and verify incoming physical bitstream */ + ogg_stream_state os; /* take physical pages, weld into a logical + stream of packets */ + ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */ + ogg_packet op; /* one raw packet of data for decode */ + + vorbis_info vi; /* struct that stores all the static vorbis bitstream + settings */ + vorbis_comment vc; /* struct that stores all the bitstream user comments */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + char *buffer; + int bytes; + +#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */ + /* Beware the evil ifdef. We avoid these where we can, but this one we + cannot. Don't add any more, you'll probably go to hell if you do. */ + _setmode( _fileno( stdin ), _O_BINARY ); + _setmode( _fileno( stdout ), _O_BINARY ); +#endif + +#if defined(macintosh) && defined(__MWERKS__) + { + int argc; + char **argv; + argc=ccommand(&argv); /* get a "command line" from the Mac user */ + /* this also lets the user set stdin and stdout */ + } +#endif + + /********** Decode setup ************/ + + ogg_sync_init(&oy); /* Now we can read pages */ + + while(1){ /* we repeat if the bitstream is chained */ + int eos=0; + int i; + + /* grab some data at the head of the stream. We want the first page + (which is guaranteed to be small and only contain the Vorbis + stream initial header) We need the first page to get the stream + serialno. */ + + /* submit a 4k block to libvorbis' Ogg layer */ + buffer=ogg_sync_buffer(&oy,4096); + bytes=fread(buffer,1,4096,stdin); + ogg_sync_wrote(&oy,bytes); + + /* Get the first page. */ + if(ogg_sync_pageout(&oy,&og)!=1){ + /* have we simply run out of data? If so, we're done. */ + if(bytes<4096)break; + + /* error case. Must not be Vorbis data */ + fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n"); + exit(1); + } + + /* Get the serial number and set up the rest of decode. */ + /* serialno first; use it to set up a logical stream */ + ogg_stream_init(&os,ogg_page_serialno(&og)); + + /* extract the initial header from the first page and verify that the + Ogg bitstream is in fact Vorbis data */ + + /* I handle the initial header first instead of just having the code + read all three Vorbis headers at once because reading the initial + header is an easy way to identify a Vorbis bitstream and it's + useful to see that functionality seperated out. */ + + vorbis_info_init(&vi); + vorbis_comment_init(&vc); + if(ogg_stream_pagein(&os,&og)<0){ + /* error; stream version mismatch perhaps */ + fprintf(stderr,"Error reading first page of Ogg bitstream data.\n"); + exit(1); + } + + if(ogg_stream_packetout(&os,&op)!=1){ + /* no page? must not be vorbis */ + fprintf(stderr,"Error reading initial header packet.\n"); + exit(1); + } + + if(vorbis_synthesis_headerin(&vi,&vc,&op)<0){ + /* error case; not a vorbis header */ + fprintf(stderr,"This Ogg bitstream does not contain Vorbis " + "audio data.\n"); + exit(1); + } + + /* At this point, we're sure we're Vorbis. We've set up the logical + (Ogg) bitstream decoder. Get the comment and codebook headers and + set up the Vorbis decoder */ + + /* The next two packets in order are the comment and codebook headers. + They're likely large and may span multiple pages. Thus we read + and submit data until we get our two packets, watching that no + pages are missing. If a page is missing, error out; losing a + header page is the only place where missing data is fatal. */ + + i=0; + while(i<2){ + while(i<2){ + int result=ogg_sync_pageout(&oy,&og); + if(result==0)break; /* Need more data */ + /* Don't complain about missing or corrupt data yet. We'll + catch it at the packet output phase */ + if(result==1){ + ogg_stream_pagein(&os,&og); /* we can ignore any errors here + as they'll also become apparent + at packetout */ + while(i<2){ + result=ogg_stream_packetout(&os,&op); + if(result==0)break; + if(result<0){ + /* Uh oh; data at some point was corrupted or missing! + We can't tolerate that in a header. Die. */ + fprintf(stderr,"Corrupt secondary header. Exiting.\n"); + exit(1); + } + result=vorbis_synthesis_headerin(&vi,&vc,&op); + if(result<0){ + fprintf(stderr,"Corrupt secondary header. Exiting.\n"); + exit(1); + } + i++; + } + } + } + /* no harm in not checking before adding more */ + buffer=ogg_sync_buffer(&oy,4096); + bytes=fread(buffer,1,4096,stdin); + if(bytes==0 && i<2){ + fprintf(stderr,"End of file before finding all Vorbis headers!\n"); + exit(1); + } + ogg_sync_wrote(&oy,bytes); + } + + /* Throw the comments plus a few lines about the bitstream we're + decoding */ + { + char **ptr=vc.user_comments; + while(*ptr){ + fprintf(stderr,"%s\n",*ptr); + ++ptr; + } + fprintf(stderr,"\nBitstream is %d channel, %ldHz\n",vi.channels,vi.rate); + fprintf(stderr,"Encoded by: %s\n\n",vc.vendor); + } + + convsize=4096/vi.channels; + + /* OK, got and parsed all three headers. Initialize the Vorbis + packet->PCM decoder. */ + if(vorbis_synthesis_init(&vd,&vi)==0){ /* central decode state */ + vorbis_block_init(&vd,&vb); /* local state for most of the decode + so multiple block decodes can + proceed in parallel. We could init + multiple vorbis_block structures + for vd here */ + + /* The rest is just a straight decode loop until end of stream */ + while(!eos){ + while(!eos){ + int result=ogg_sync_pageout(&oy,&og); + if(result==0)break; /* need more data */ + if(result<0){ /* missing or corrupt data at this page position */ + fprintf(stderr,"Corrupt or missing data in bitstream; " + "continuing...\n"); + }else{ + ogg_stream_pagein(&os,&og); /* can safely ignore errors at + this point */ + while(1){ + result=ogg_stream_packetout(&os,&op); + + if(result==0)break; /* need more data */ + if(result<0){ /* missing or corrupt data at this page position */ + /* no reason to complain; already complained above */ + }else{ + /* we have a packet. Decode it */ + float **pcm; + int samples; + + if(vorbis_synthesis(&vb,&op)==0) /* test for success! */ + vorbis_synthesis_blockin(&vd,&vb); + /* + + **pcm is a multichannel float vector. In stereo, for + example, pcm[0] is left, and pcm[1] is right. samples is + the size of each channel. Convert the float values + (-1.<=range<=1.) to whatever PCM format and write it out */ + + while((samples=vorbis_synthesis_pcmout(&vd,&pcm))>0){ + int j; + int clipflag=0; + int bout=(samples<convsize?samples:convsize); + + /* convert floats to 16 bit signed ints (host order) and + interleave */ + for(i=0;i<vi.channels;i++){ + ogg_int16_t *ptr=convbuffer+i; + float *mono=pcm[i]; + for(j=0;j<bout;j++){ +#if 1 + int val=floor(mono[j]*32767.f+.5f); +#else /* optional dither */ + int val=mono[j]*32767.f+drand48()-0.5f; +#endif + /* might as well guard against clipping */ + if(val>32767){ + val=32767; + clipflag=1; + } + if(val<-32768){ + val=-32768; + clipflag=1; + } + *ptr=val; + ptr+=vi.channels; + } + } + + if(clipflag) + fprintf(stderr,"Clipping in frame %ld\n",(long)(vd.sequence)); + + + fwrite(convbuffer,2*vi.channels,bout,stdout); + + vorbis_synthesis_read(&vd,bout); /* tell libvorbis how + many samples we + actually consumed */ + } + } + } + if(ogg_page_eos(&og))eos=1; + } + } + if(!eos){ + buffer=ogg_sync_buffer(&oy,4096); + bytes=fread(buffer,1,4096,stdin); + ogg_sync_wrote(&oy,bytes); + if(bytes==0)eos=1; + } + } + + /* ogg_page and ogg_packet structs always point to storage in + libvorbis. They're never freed or manipulated directly */ + + vorbis_block_clear(&vb); + vorbis_dsp_clear(&vd); + }else{ + fprintf(stderr,"Error: Corrupt header during playback initialization.\n"); + } + + /* clean up this logical bitstream; before exit we see if we're + followed by another [chained] */ + + ogg_stream_clear(&os); + vorbis_comment_clear(&vc); + vorbis_info_clear(&vi); /* must be called last */ + } + + /* OK, clean up the framer */ + ogg_sync_clear(&oy); + + fprintf(stderr,"Done.\n"); + return(0); +} diff --git a/vorbis/examples/encoder_example.c b/vorbis/examples/encoder_example.c new file mode 100644 index 0000000..d46a051 --- /dev/null +++ b/vorbis/examples/encoder_example.c @@ -0,0 +1,251 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: simple example encoder + + ********************************************************************/ + +/* takes a stereo 16bit 44.1kHz WAV file from stdin and encodes it into + a Vorbis bitstream */ + +/* Note that this is POSIX, not ANSI, code */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <math.h> +#include <vorbis/vorbisenc.h> + +#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */ +#include <io.h> +#include <fcntl.h> +#endif + +#if defined(__MACOS__) && defined(__MWERKS__) +#include <console.h> /* CodeWarrior's Mac "command-line" support */ +#endif + +#define READ 1024 +signed char readbuffer[READ*4+44]; /* out of the data segment, not the stack */ + +int main(){ + ogg_stream_state os; /* take physical pages, weld into a logical + stream of packets */ + ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */ + ogg_packet op; /* one raw packet of data for decode */ + + vorbis_info vi; /* struct that stores all the static vorbis bitstream + settings */ + vorbis_comment vc; /* struct that stores all the user comments */ + + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + int eos=0,ret; + int i, founddata; + +#if defined(macintosh) && defined(__MWERKS__) + int argc = 0; + char **argv = NULL; + argc = ccommand(&argv); /* get a "command line" from the Mac user */ + /* this also lets the user set stdin and stdout */ +#endif + + /* we cheat on the WAV header; we just bypass 44 bytes (simplest WAV + header is 44 bytes) and assume that the data is 44.1khz, stereo, 16 bit + little endian pcm samples. This is just an example, after all. */ + +#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */ + /* if we were reading/writing a file, it would also need to in + binary mode, eg, fopen("file.wav","wb"); */ + /* Beware the evil ifdef. We avoid these where we can, but this one we + cannot. Don't add any more, you'll probably go to hell if you do. */ + _setmode( _fileno( stdin ), _O_BINARY ); + _setmode( _fileno( stdout ), _O_BINARY ); +#endif + + + /* we cheat on the WAV header; we just bypass the header and never + verify that it matches 16bit/stereo/44.1kHz. This is just an + example, after all. */ + + readbuffer[0] = '\0'; + for (i=0, founddata=0; i<30 && ! feof(stdin) && ! ferror(stdin); i++) + { + fread(readbuffer,1,2,stdin); + + if ( ! strncmp((char*)readbuffer, "da", 2) ){ + founddata = 1; + fread(readbuffer,1,6,stdin); + break; + } + } + + /********** Encode setup ************/ + + vorbis_info_init(&vi); + + /* choose an encoding mode. A few possibilities commented out, one + actually used: */ + + /********************************************************************* + Encoding using a VBR quality mode. The usable range is -.1 + (lowest quality, smallest file) to 1. (highest quality, largest file). + Example quality mode .4: 44kHz stereo coupled, roughly 128kbps VBR + + ret = vorbis_encode_init_vbr(&vi,2,44100,.4); + + --------------------------------------------------------------------- + + Encoding using an average bitrate mode (ABR). + example: 44kHz stereo coupled, average 128kbps VBR + + ret = vorbis_encode_init(&vi,2,44100,-1,128000,-1); + + --------------------------------------------------------------------- + + Encode using a quality mode, but select that quality mode by asking for + an approximate bitrate. This is not ABR, it is true VBR, but selected + using the bitrate interface, and then turning bitrate management off: + + ret = ( vorbis_encode_setup_managed(&vi,2,44100,-1,128000,-1) || + vorbis_encode_ctl(&vi,OV_ECTL_RATEMANAGE2_SET,NULL) || + vorbis_encode_setup_init(&vi)); + + *********************************************************************/ + + ret=vorbis_encode_init_vbr(&vi,2,44100,0.1); + + /* do not continue if setup failed; this can happen if we ask for a + mode that libVorbis does not support (eg, too low a bitrate, etc, + will return 'OV_EIMPL') */ + + if(ret)exit(1); + + /* add a comment */ + vorbis_comment_init(&vc); + vorbis_comment_add_tag(&vc,"ENCODER","encoder_example.c"); + + /* set up the analysis state and auxiliary encoding storage */ + vorbis_analysis_init(&vd,&vi); + vorbis_block_init(&vd,&vb); + + /* set up our packet->stream encoder */ + /* pick a random serial number; that way we can more likely build + chained streams just by concatenation */ + srand(time(NULL)); + ogg_stream_init(&os,rand()); + + /* Vorbis streams begin with three headers; the initial header (with + most of the codec setup parameters) which is mandated by the Ogg + bitstream spec. The second header holds any comment fields. The + third header holds the bitstream codebook. We merely need to + make the headers, then pass them to libvorbis one at a time; + libvorbis handles the additional Ogg bitstream constraints */ + + { + ogg_packet header; + ogg_packet header_comm; + ogg_packet header_code; + + vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code); + ogg_stream_packetin(&os,&header); /* automatically placed in its own + page */ + ogg_stream_packetin(&os,&header_comm); + ogg_stream_packetin(&os,&header_code); + + /* This ensures the actual + * audio data will start on a new page, as per spec + */ + while(!eos){ + int result=ogg_stream_flush(&os,&og); + if(result==0)break; + fwrite(og.header,1,og.header_len,stdout); + fwrite(og.body,1,og.body_len,stdout); + } + + } + + while(!eos){ + long i; + long bytes=fread(readbuffer,1,READ*4,stdin); /* stereo hardwired here */ + + if(bytes==0){ + /* end of file. this can be done implicitly in the mainline, + but it's easier to see here in non-clever fashion. + Tell the library we're at end of stream so that it can handle + the last frame and mark end of stream in the output properly */ + vorbis_analysis_wrote(&vd,0); + + }else{ + /* data to encode */ + + /* expose the buffer to submit data */ + float **buffer=vorbis_analysis_buffer(&vd,READ); + + /* uninterleave samples */ + for(i=0;i<bytes/4;i++){ + buffer[0][i]=((readbuffer[i*4+1]<<8)| + (0x00ff&(int)readbuffer[i*4]))/32768.f; + buffer[1][i]=((readbuffer[i*4+3]<<8)| + (0x00ff&(int)readbuffer[i*4+2]))/32768.f; + } + + /* tell the library how much we actually submitted */ + vorbis_analysis_wrote(&vd,i); + } + + /* vorbis does some data preanalysis, then divvies up blocks for + more involved (potentially parallel) processing. Get a single + block for encoding now */ + while(vorbis_analysis_blockout(&vd,&vb)==1){ + + /* analysis, assume we want to use bitrate management */ + vorbis_analysis(&vb,NULL); + vorbis_bitrate_addblock(&vb); + + while(vorbis_bitrate_flushpacket(&vd,&op)){ + + /* weld the packet into the bitstream */ + ogg_stream_packetin(&os,&op); + + /* write out pages (if any) */ + while(!eos){ + int result=ogg_stream_pageout(&os,&og); + if(result==0)break; + fwrite(og.header,1,og.header_len,stdout); + fwrite(og.body,1,og.body_len,stdout); + + /* this could be set above, but for illustrative purposes, I do + it here (to show that vorbis does know where the stream ends) */ + + if(ogg_page_eos(&og))eos=1; + } + } + } + } + + /* clean up and exit. vorbis_info_clear() must be called last */ + + ogg_stream_clear(&os); + vorbis_block_clear(&vb); + vorbis_dsp_clear(&vd); + vorbis_comment_clear(&vc); + vorbis_info_clear(&vi); + + /* ogg_page and ogg_packet structs always point to storage in + libvorbis. They're never freed or manipulated directly */ + + fprintf(stderr,"Done.\n"); + return(0); +} diff --git a/vorbis/examples/frameview.pl b/vorbis/examples/frameview.pl new file mode 100755 index 0000000..edcf5d0 --- /dev/null +++ b/vorbis/examples/frameview.pl @@ -0,0 +1,630 @@ +#!/usr/bin/perl -w +use strict; +use Tk; +use Tk::Xrm; +use Tk qw(exit); + +my $version="Analyzer 20020429"; + +my %bases; +my $first_file=undef; +my $last_file=undef; +my $fileno=0; + +my @panel_labels; +my @panel_ones; +my @panel_twos; +my @panel_onevars; +my @panel_twovars; +my @panel_keys; +my $panel_count; + +# pop the toplevels + +my $toplevel=new MainWindow(-class=>'AnalyzerGraph'); +my $Xname=$toplevel->Class; +$toplevel->optionAdd("$Xname.geometry", "800x600",20); + +my $geometry=$toplevel->optionGet('geometry',''); +$geometry=~/^(\d+)x(\d+)/; + +$toplevel->configure(-width=>$1); +$toplevel->configure(-height=>$2); + + + + + +$toplevel->optionAdd("$Xname.background", "#4fc627",20); +$toplevel->optionAdd("$Xname*highlightBackground", "#80c0d3",20); +$toplevel->optionAdd("$Xname.Panel.background", "#4fc627",20); +$toplevel->optionAdd("$Xname.Panel.foreground", "#d0d0d0",20); +$toplevel->optionAdd("$Xname.Panel.font", + '-*-helvetica-bold-r-*-*-18-*-*-*-*-*-*-*',20); +$toplevel->optionAdd("$Xname*Statuslabel.font", + '-*-helvetica-bold-r-*-*-18-*-*-*-*-*-*-*',20); +$toplevel->optionAdd("$Xname*Statuslabel.foreground", "#606060"); +$toplevel->optionAdd("$Xname*Status.font", + '-*-helvetica-bold-r-*-*-18-*-*-*-*-*-*-*',20); + +$toplevel->optionAdd("$Xname*AlertDetail.font", + '-*-helvetica-medium-r-*-*-10-*-*-*-*-*-*-*',20); + + +$toplevel->optionAdd("$Xname*background", "#d0d0d0",20); +$toplevel->optionAdd("$Xname*foreground", '#000000',20); + +$toplevel->optionAdd("$Xname*Button*background", "#f0d0b0",20); +$toplevel->optionAdd("$Xname*Button*foreground", '#000000',20); +$toplevel->optionAdd("$Xname*Button*borderWidth", '2',20); +$toplevel->optionAdd("$Xname*Button*relief", 'groove',20); +$toplevel->optionAdd("$Xname*Button*padY", 1,20); + +#$toplevel->optionAdd("$Xname*Scale*background", "#f0d0b0",20); +$toplevel->optionAdd("$Xname*Scale*foreground", '#000000',20); +$toplevel->optionAdd("$Xname*Scale*borderWidth", '1',20); +#$toplevel->optionAdd("$Xname*Scale*relief", 'groove',20); +$toplevel->optionAdd("$Xname*Scale*padY", 1,20); + +$toplevel->optionAdd("$Xname*Checkbutton*background", "#f0d0b0",20); +$toplevel->optionAdd("$Xname*Checkbutton*foreground", '#000000',20); +$toplevel->optionAdd("$Xname*Checkbutton*borderWidth", '2',20); +$toplevel->optionAdd("$Xname*Checkbutton*relief", 'groove',20); + +$toplevel->optionAdd("$Xname*activeBackground", "#ffffff",20); +$toplevel->optionAdd("$Xname*activeForeground", '#0000a0',20); +$toplevel->optionAdd("$Xname*borderWidth", 0,20); +$toplevel->optionAdd("$Xname*relief", 'flat',20); +$toplevel->optionAdd("$Xname*activeBorderWidth", 1,20); +$toplevel->optionAdd("$Xname*highlightThickness", 0,20); +$toplevel->optionAdd("$Xname*padX", 2,20); +$toplevel->optionAdd("$Xname*padY", 2,20); +$toplevel->optionAdd("$Xname*font", + '-*-helvetica-bold-r-*-*-12-*-*-*-*-*-*-*',20); +$toplevel->optionAdd("$Xname*Entry.font", + '-*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*',20); +$toplevel->optionAdd("$Xname*Exit.font", + '-*-helvetica-bold-r-*-*-10-*-*-*-*-*-*-*',20); +$toplevel->optionAdd("$Xname*Exit.relief", 'groove',20); +$toplevel->optionAdd("$Xname*Exit.padX", 1,20); +$toplevel->optionAdd("$Xname*Exit.padY", 1,20); +$toplevel->optionAdd("$Xname*Exit.borderWidth", 2,20); +$toplevel->optionAdd("$Xname*Exit*background", "#a0a0a0",20); +$toplevel->optionAdd("$Xname*Exit*disabledForeground", "#ffffff",20); + +#$toplevel->optionAdd("$Xname*Canvas.background", "#c0c0c0",20); + +$toplevel->optionAdd("$Xname*Entry.background", "#ffffff",20); +$toplevel->optionAdd("$Xname*Entry.disabledForeground", "#c0c0c0",20); +$toplevel->optionAdd("$Xname*Entry.relief", "sunken",20); +$toplevel->optionAdd("$Xname*Entry.borderWidth", 1,20); + +$toplevel->optionAdd("$Xname*Field.background", "#ffffff",20); +$toplevel->optionAdd("$Xname*Field.disabledForeground", "#c0c0c0",20); +$toplevel->optionAdd("$Xname*Field.relief", "flat",20); +$toplevel->optionAdd("$Xname*Field.borderWidth", 1,20); + +$toplevel->optionAdd("$Xname*Label.disabledForeground", "#c0c0c0",20); +$toplevel->optionAdd("$Xname*Label.borderWidth", 1,20); + +$toplevel->configure(-background=>$toplevel->optionGet("background","")); + +#$toplevel->resizable(FALSE,FALSE); + +my $panel=new MainWindow(-class=>'AnalyzerPanel'); +my $X2name=$panel->Class; + +$panel->optionAdd("$X2name.background", "#353535",20); +$panel->optionAdd("$X2name*highlightBackground", "#80c0d3",20); +$panel->optionAdd("$X2name.Panel.background", "#353535",20); +$panel->optionAdd("$X2name.Panel.foreground", "#4fc627",20); +$panel->optionAdd("$X2name.Panel.font", + '-*-helvetica-bold-o-*-*-18-*-*-*-*-*-*-*',20); +$panel->optionAdd("$X2name*Statuslabel.font", + '-*-helvetica-bold-r-*-*-18-*-*-*-*-*-*-*',20); +$panel->optionAdd("$X2name*Statuslabel.foreground", "#4fc627",20); +$panel->optionAdd("$X2name*Status.font", + '-*-helvetica-bold-r-*-*-18-*-*-*-*-*-*-*',20); + +$panel->optionAdd("$X2name*AlertDetail.font", + '-*-helvetica-medium-r-*-*-10-*-*-*-*-*-*-*',20); + + +$panel->optionAdd("$X2name*background", "#d0d0d0",20); +$panel->optionAdd("$X2name*foreground", '#000000',20); + +$panel->optionAdd("$X2name*Button*background", "#f0d0b0",20); +$panel->optionAdd("$X2name*Button*foreground", '#000000',20); +$panel->optionAdd("$X2name*Button*borderWidth", '2',20); +$panel->optionAdd("$X2name*Button*relief", 'groove',20); +$panel->optionAdd("$X2name*Button*padY", 1,20); + +$panel->optionAdd("$X2name*Checkbutton*background", "#f0d0b0",20); +$panel->optionAdd("$X2name*Checkbutton*foreground", '#000000',20); +$panel->optionAdd("$X2name*Checkbutton*borderWidth", '2',20); +#$panel->optionAdd("$X2name*Checkbutton*padX", '0',20); +#$panel->optionAdd("$X2name*Checkbutton*padY", '0',20); +#$panel->optionAdd("$X2name*Checkbutton*relief", 'groove',20); + +$panel->optionAdd("$X2name*activeBackground", "#ffffff",20); +$panel->optionAdd("$X2name*activeForeground", '#0000a0',20); +$panel->optionAdd("$X2name*borderWidth", 0,20); +$panel->optionAdd("$X2name*relief", 'flat',20); +$panel->optionAdd("$X2name*activeBorderWidth", 1,20); +$panel->optionAdd("$X2name*highlightThickness", 0,20); +$panel->optionAdd("$X2name*padX", 2,20); +$panel->optionAdd("$X2name*padY", 2,20); +$panel->optionAdd("$X2name*font", + '-*-helvetica-bold-r-*-*-12-*-*-*-*-*-*-*',20); +$panel->optionAdd("$X2name*Entry.font", + '-*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*',20); + +$panel->optionAdd("$X2name*Exit.font", + '-*-helvetica-bold-r-*-*-10-*-*-*-*-*-*-*',20); +$panel->optionAdd("$X2name*Exit.relief", 'groove',20); +$panel->optionAdd("$X2name*Exit.padX", 1,20); +$panel->optionAdd("$X2name*Exit.padY", 1,20); +$panel->optionAdd("$X2name*Exit.borderWidth", 2,20); +$panel->optionAdd("$X2name*Exit*background", "#a0a0a0",20); +$panel->optionAdd("$X2name*Exit*disabledForeground", "#ffffff",20); + +$panel->optionAdd("$X2name*Entry.background", "#ffffff",20); +$panel->optionAdd("$X2name*Entry.disabledForeground", "#c0c0c0",20); +$panel->optionAdd("$X2name*Entry.relief", "sunken",20); +$panel->optionAdd("$X2name*Entry.borderWidth", 1,20); + +$panel->optionAdd("$X2name*Field.background", "#ffffff",20); +$panel->optionAdd("$X2name*Field.disabledForeground", "#c0c0c0",20); +$panel->optionAdd("$X2name*Field.relief", "flat",20); +$panel->optionAdd("$X2name*Field.borderWidth", 1,20); + +$panel->optionAdd("$X2name*Label.disabledForeground", "#c0c0c0",20); +$panel->optionAdd("$X2name*Label.borderWidth", 1,20); + +$panel->configure(-background=>$panel->optionGet("background","")); + +#$panel->resizable("FALSE","FALSE"); + +my $panel_shell=$panel->Label(Name=>"shell",-borderwidth=>1,-relief=>'raised')-> + place(-x=>10,-y=>36,-relwidth=>1.0,-relheight=>1.0, + -width=>-20,-height=>-46,-anchor=>'nw'); + +my $panel_quit=$panel_shell->Button(-class=>"Exit",-text=>"quit",-command=>[sub{Shutdown()}])-> + place(-x=>-1,-y=>-1,-relx=>1.0,-rely=>1.0,-anchor=>'se'); + +$panel->Label(Name=>"logo text",-class=>"Panel",-text=>$version)-> + place(-x=>5,-y=>5,-anchor=>'nw'); + + +my $graph_shell=$toplevel->Label(Name=>"shell",-borderwidth=>1,-relief=>'raised')-> + place(-x=>10,-y=>36,-relwidth=>1.0,-relheight=>1.0, + -width=>-20,-height=>-46,-anchor=>'nw'); + +my $graph_status=$toplevel->Label(Name=>"logo text",-class=>"Panel",-text=>"Starting up")-> + place(-x=>5,-y=>5,-anchor=>'nw'); + + +my $panely=5; +my $panel_rescan=$panel_shell->Button(-text=>"rescan",-command=>[sub{scan_directory()}])-> + place(-x=>-5,-relx=>1.,-y=>$panely,-anchor=>'ne'); +$panely+=$panel_rescan->reqheight()+6; + + +my$temp=$graph_shell->Button(-text=>"<<", + -command=>[sub{$fileno-=10;$fileno=$first_file if($fileno<$first_file); + load_graph();}])-> + place(-x=>5,-y=>-5,-rely=>1.,-relwidth=>.2,-width=>-5,-anchor=>'sw'); +$graph_shell->Button(-text=>">>", + -command=>[sub{$fileno+=10;$fileno=$last_file if($fileno>$last_file); + load_graph();}])-> + place(-x=>-5,-y=>-5,-relwidth=>.2,-rely=>1.,-width=>-5,-relx=>1.,-anchor=>'se'); +$graph_shell->Button(-text=>"<", + -command=>[sub{$fileno-=1;$fileno=$first_file if($fileno<$first_file); + load_graph();}])-> + place(-x=>5,-y=>-5,-relwidth=>.3,-width=>-7,-rely=>1.,-relx=>.2,-anchor=>'sw'); +$graph_shell->Button(-text=>">", + -command=>[sub{$fileno+=1;$fileno=$last_file if($fileno>$last_file); + load_graph();}])-> + place(-x=>-5,-y=>-5,-relwidth=>.3,-width=>-7,-rely=>1.,-relx=>.8,-anchor=>'se'); +my$graphy=-10-$temp->reqheight(); +my$graph_slider=$temp=$graph_shell->Scale(-bigincrement=>1, + -resolution=>1, + -showvalue=>'TRUE',-variable=>\$fileno,-orient=>'horizontal')-> + place(-x=>5,-y=>$graphy,-relwidth=>1.,-rely=>1.,-width=>-10,-anchor=>'sw'); +$graphy-=$temp->reqheight()+5; + +my$onecrop; +my$twocrop; + +my$oneresize=$temp=$graph_shell->Checkbutton(-text=>"rescale",-variable=>\$onecrop, + -command=>[sub{draw_graph();}])-> + place(-x=>5,-y=>5,-anchor=>'nw'); + +my$one=$graph_shell->Canvas()-> + place(-relwidth=>1.,-width=>-10,-relheight=>.5,-height=>($graphy/2)-5-$temp->reqheight(), + -x=>5,-y=>5+$temp->reqheight,-anchor=>'nw'); + + +my$tworesize=$temp=$graph_shell->Checkbutton(-text=>"rescale",-variable=>\$twocrop, + -command=>[sub{draw_graph();}])-> + place(-rely=>1.,-y=>5,-anchor=>'nw',-in=>$one); +my$two=$graph_shell->Canvas()-> + place(-relwidth=>1.,-relheight=>1.,-rely=>1.,-y=>5+$temp->reqheight(),-anchor=>'nw',-in=>$one); + +scan_directory(); + +my%onestate; +my%twostate; +my @data; + +$onestate{"canvas"}=$one; +$onestate{"vars"}=\@panel_onevars; +$twostate{"canvas"}=$two; +$twostate{"vars"}=\@panel_twovars; + +$graph_slider->configure(-command=>[sub{load_graph()}]); +load_graph(); +$toplevel->bind('MainWindow','<Configure>',[sub{$toplevel->update(); + draw_graph()}]); + +Tk::MainLoop(); + +sub load_graph{ + + scan_directory()if(!defined($panel_count)); + + @data=undef; + + for(my$i=0;$i<$panel_count;$i++){ + my$filename=$panel_keys[$i]."_$fileno.m"; + if(open F, "$filename"){ + $data[$i]=[(<F>)]; + close F; + } + } + draw_graph(); +} + +sub graphhelper{ + my($graph)=@_; + my$count=0; + my@colors=("#ff0000","#00df00","#0000ff","#ffff00","#ff00ff","#00ffff","#ffffff", + "#9f0000","#007f00","#00009f","#8f8f00","#8f008f","#008f8f","#000000"); + + my$w=$graph->{"canvas"}; + my$rescale=0; + + Status("Plotting $fileno"); + $w->delete('foo'); + $w->delete('legend'); + $w->delete('lines'); + + # count range + for(my$i=0;$i<$panel_count;$i++){ + if($graph->{"vars"}->[$i]){ + if(defined($data[$i])){ + if(!defined($graph->{"minx"})){ + $data[$i]->[0]=~m/^\s*(-?[0-9\.]*)[ ,]+(-?[0-9\.]*)/; + $graph->{"maxx"}=$1; + $graph->{"minx"}=$1; + $graph->{"maxy"}=$2; + $graph->{"miny"}=$2; + $rescale=1; + } + + for(my$j=0;$j<=$#{$data[$i]};$j++){ + $data[$i]->[$j]=~m/^\s*(-?[0-9\.]*)[ ,]+(-?[0-9\.]*)/; + $rescale=1 if($1>$graph->{"maxx"}); + $rescale=1 if($1<$graph->{"minx"}); + $rescale=1 if($2>$graph->{"maxy"}); + $rescale=1 if($2<$graph->{"miny"}); + $graph->{"maxx"}=$1 if($1>$graph->{"maxx"}); + $graph->{"minx"}=$1 if($1<$graph->{"minx"}); + $graph->{"maxy"}=$2 if($2>$graph->{"maxy"}); + $graph->{"miny"}=$2 if($2<$graph->{"miny"}); + } + } + $count++; + } + } + + my$width=$w->width(); + my$height=$w->height(); + + $rescale=1 if(!defined($graph->{"width"}) || + $width!=$graph->{"width"} || + $height!=$graph->{"height"}); + + $graph->{"width"}=$width; + $graph->{"height"}=$height; + + if(defined($graph->{"maxx"})){ + # draw axes, labels + # look for appropriate axis scales + + if($rescale){ + + $w->delete('ylabel'); + $w->delete('xlabel'); + $w->delete('axes'); + + my$yscale=1.; + my$xscale=1.; + my$iyscale=1.; + my$ixscale=1.; + while(($graph->{"maxx"}-$graph->{"minx"})*$xscale>15){$xscale*=.1;$ixscale*=10.;} + while(($graph->{"maxy"}-$graph->{"miny"})*$yscale>15){$yscale*=.1;$iyscale*=10.;} + + while(($graph->{"maxx"}-$graph->{"minx"})*$xscale<3){$xscale*=10.;$ixscale*=.1;} + while(($graph->{"maxy"}-$graph->{"miny"})*$yscale<3){$yscale*=10.;$iyscale*=.1;} + + # how tall are the x axis labels? + $w->createText(-1,-1,-anchor=>'se',-tags=>['foo'],-text=>"0123456789."); + my($x1,$y1,$x2,$y2)=$w->bbox('foo'); + $w->delete('foo'); + my$maxlabelheight=$y2-$y1; + my$useabley=$height-$maxlabelheight-3; + my$pixelpery=$useabley/($graph->{"maxy"}-$graph->{"miny"}); + + # place y axis labels at proper spacing/height + my$lasty=-$maxlabelheight/2; + my$topyval=int($graph->{"maxy"}*$yscale+1.)*$iyscale; + + for(my$i=0;;$i++){ + my$yval= $topyval-$i*$iyscale; + my$y= ($graph->{"maxy"}-$yval)*$pixelpery; + last if($y>$useabley); + if($y-$maxlabelheight>=$lasty){ + $w->createText(0,$y,-anchor=>'e',-tags=>['ylabel'],-text=>"$yval"); + $lasty=$y; + } + } + + # get the max ylabel width and place them at proper x + ($x1,$y1,$x2,$y2)=$w->bbox('ylabel'); + my$maxylabelwidth=$x2-$x1; + $w->move('ylabel',$maxylabelwidth,0); + + my$beginx=$maxylabelwidth+3; + my$useablex=$width-$beginx; + + # draw basic axes + $w->createLine($beginx,0,$beginx,$useabley,$width,$useabley, + -tags=>['axes'],-width=>2); + # draw y tix + $lasty=-$maxlabelheight/2; + for(my$i=0;;$i++){ + my$yval= $topyval-$i*$iyscale; + my$y= ($graph->{"maxy"}-$yval)*$pixelpery; + last if($y>$useabley); + if($yval==0){ + $w->createLine($beginx,$y,$width,$y, + -tags=>['axes'],-width=>1); + }else{ + if($y-$maxlabelheight>=$lasty){ + $w->createLine($beginx,$y,$width,$y, + -tags=>['axes'],-width=>1, + -stipple=>'gray50'); + + $lasty=$y; + } + } + } + + # place x axis labels at proper spacing + my$topxval=int($graph->{"maxx"}*$xscale+1.)*$ixscale; + my$pixelperx=$useablex/($graph->{"maxx"}-$graph->{"minx"}); + + for(my$i=0;;$i++){ + my$xval= $topxval-$i*$ixscale; + my$x= $width-($graph->{"maxx"}-$xval)*$pixelperx; + + last if($x<$beginx); + # bounding boxen are hard. place temp labels. + $w->createText(-1,-1,-anchor=>'e',-tags=>['foo'],-text=>"$xval"); + } + + ($x1,$y1,$x2,$y2)=$w->bbox('foo'); + my$maxxlabelwidth=$x2-$x1; + $w->delete('foo'); + my$lastx=$width; + + for(my$i=0;;$i++){ + my$xval= $topxval-$i*$ixscale; + my$x= $width-($graph->{"maxx"}-$xval)*$pixelperx; + + last if($x-$maxxlabelwidth/2<0 || $x<$beginx); + if($xval==0 && $x<$width){ + $w->createLine($x,0,$x,$useabley,-tags=>['axes'],-width=>1); + } + + if($x+$maxxlabelwidth<=$lastx){ + $w->createText($x,$height-1,-anchor=>'s',-tags=>['xlabel'],-text=>"$xval"); + $w->createLine($x,0,$x,$useabley,-tags=>['axes'],-width=>1,-stipple=>"gray50"); + $lastx=$x; + } + } + $graph->{"labelheight"}=$maxlabelheight; + $graph->{"xo"}=$beginx; + $graph->{"ppx"}=$pixelperx; + $graph->{"ppy"}=$pixelpery; + } + + # plot the files + $count=0; + my$legendy=$graph->{"labelheight"}/2; + for(my$i=0;$i<$panel_count;$i++){ + if($graph->{"vars"}->[$i]){ + $count++; # count here for legend color selection stability + if(defined($data[$i])){ + # place a legend placard; + my$color=$colors[($count-1)%($#colors+1)]; + $w->createText($width,$legendy,-anchor=>'e',-tags=>['legend'], + -fill=>$color,-text=>$panel_keys[$i]); + $legendy+=$graph->{"labelheight"}; + + # plot the lines + my@pairs=map{if(/^\s*(-?[0-9\.]*)[ ,]+(-?[0-9\.]*)/){ + (($1-$graph->{"minx"})*$graph->{"ppx"}+$graph->{"xo"}, + (-$2+$graph->{"maxy"})*$graph->{"ppy"})}} (@{$data[$i]}); + + $w->createLine((@pairs),-fill=>$color,-tags=>['lines']); + } + } + } + } +} + +sub draw_graph{ + + if($onecrop){ + $onestate{"minx"}=undef; + $onestate{"miny"}=undef; + $onestate{"maxx"}=undef; + $onestate{"maxy"}=undef; + } + if($twocrop){ + $twostate{"minx"}=undef; + $twostate{"miny"}=undef; + $twostate{"maxx"}=undef; + $twostate{"maxy"}=undef; + } + + for(my$i=0;$i<$panel_count;$i++){ + if($twostate{"vars"}->[$i]){ + + #re-place the canvases + + $oneresize->place(-x=>5,-y=>5,-anchor=>'nw'); + + $one->place(-relwidth=>1.,-width=>-10,-relheight=>.5, + -height=>($graphy/2)-5-$oneresize->reqheight(), + -x=>5,-y=>5+$oneresize->reqheight,-anchor=>'nw'); + + $tworesize->place(-rely=>1.,-y=>5,-anchor=>'nw',-in=>$one); + $two->place(-relwidth=>1.,-relheight=>1.,-rely=>1., + -y=>5+$tworesize->reqheight(),-anchor=>'nw',-in=>$one); + + graphhelper(\%onestate); + graphhelper(\%twostate); + return; + } + } + + $oneresize->place(-x=>5,-y=>5,-anchor=>'nw'); + + $one->place(-relwidth=>1.,-width=>-10,-relheight=>1., + -height=>$graphy-5-$oneresize->reqheight(), + -x=>5,-y=>5+$oneresize->reqheight,-anchor=>'nw'); + + $tworesize->placeForget(); + $two->placeForget(); + + graphhelper(\%onestate); +} + +sub depopulate_panel{ + my $win; + foreach $win (@panel_labels){ + $win->destroy(); + } + @panel_labels=(); + foreach $win (@panel_ones){ + $win->destroy(); + } + @panel_ones=(); + foreach $win (@panel_twos){ + $win->destroy(); + } + @panel_twos=(); + @panel_keys=(); +} + +sub populate_panel{ + my $localy=$panely; + my $key; + my $i=0; + foreach $key (sort (keys %bases)){ + $panel_keys[$i]=$key; + if(!defined($panel_onevars[$i])){ + $panel_onevars[$i]=0; + $panel_twovars[$i]=0; + } + + my $temp=$panel_twos[$i]=$panel_shell-> + Checkbutton(-variable=>\$panel_twovars[$i],-command=>['main::draw_graph'],-text=>'2')-> + place(-y=>$localy,-x=>-5,-anchor=>"ne",-relx=>1.); + my $oney=$temp->reqheight(); + my $onex=$temp->reqwidth()+15; + + $temp=$panel_ones[$i]=$panel_shell-> + Checkbutton(-variable=>\$panel_onevars[$i],-command=>['main::draw_graph'],-text=>'1')-> + place(-y=>0,-x=>0,-anchor=>"ne",-in=>$temp,-bordermode=>'outside'); + $oney=$temp->reqheight() if ($oney<$temp->reqheight()); + $onex+=$temp->reqwidth(); + + $temp=$panel_labels[$i]=$panel_shell->Label(-text=>$key,-class=>'Field',-justify=>'left')-> + place(-y=>$localy,-x=>5,-anchor=>"nw",-relwidth=>1.,-width=>-$onex, + -bordermode=>'outside'); + $oney=$temp->reqheight() if ($oney<$temp->reqheight()); + + $localy+=$oney+2; + $i++; + } + $panel_count=$i; + + $localy+=$panel_quit->reqheight()+50; + my $geometry=$panel->geometry(); + $geometry=~/^(\d+)/; + + $panel->configure(-height=>$localy); + $panel->configure(-width=>$1); +} + +sub Shutdown{ + Tk::exit(); +} + +sub Status{ + my$text=shift @_; + $graph_status->configure(-text=>"$text"); + $toplevel->update(); +} + +sub scan_directory{ + + %bases=(); + my$count=0; + + $first_file=undef; + $last_file=undef; + + if(opendir(D,".")){ + my$file; + while(defined($file=readdir(D))){ + if($file=~m/^(\S*)_(\d+).m/){ + $bases{"$1"}="0"; + $first_file=$2 if(!defined($first_file) || $2<$first_file); + $last_file=$2 if(!defined($last_file) || $2>$last_file); + $count++; + + Status("Reading... $count")if($count%117==0); + } + } + closedir(D); + } + Status("Done Reading: $count files"); + depopulate_panel(); + populate_panel(); + + $fileno=$first_file if($fileno<$first_file); + $fileno=$last_file if($fileno>$last_file); + + $graph_slider->configure(-from=>$first_file,-to=>$last_file); + +} + + + + + diff --git a/vorbis/examples/seeking_example.c b/vorbis/examples/seeking_example.c new file mode 100644 index 0000000..d039b0d --- /dev/null +++ b/vorbis/examples/seeking_example.c @@ -0,0 +1,277 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: illustrate seeking, and test it too + + ********************************************************************/ + +#include <stdlib.h> +#include <stdio.h> +#include "vorbis/codec.h" +#include "vorbis/vorbisfile.h" + +#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */ +# include <io.h> +# include <fcntl.h> +#endif + +void _verify(OggVorbis_File *ov, + ogg_int64_t val,ogg_int64_t pcmval,double timeval, + ogg_int64_t pcmlength, + char *bigassbuffer){ + off_t i; + int j; + long bread; + char buffer[4096]; + int dummy; + ogg_int64_t pos; + int hs = ov_halfrate_p(ov); + + /* verify the raw position, the pcm position and position decode */ + if(val!=-1 && ov_raw_tell(ov)<val){ + fprintf(stderr,"raw position out of tolerance: requested %ld, got %ld\n", + (long)val,(long)ov_raw_tell(ov)); + exit(1); + } + if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){ + fprintf(stderr,"pcm position out of tolerance: requested %ld, got %ld\n", + (long)pcmval,(long)ov_pcm_tell(ov)); + exit(1); + } + if(timeval!=-1 && ov_time_tell(ov)>timeval){ + fprintf(stderr,"time position out of tolerance: requested %f, got %f\n", + timeval,ov_time_tell(ov)); + exit(1); + } + pos=ov_pcm_tell(ov); + if(pos<0 || pos>pcmlength){ + fprintf(stderr,"pcm position out of bounds: got %ld\n",(long)pos); + exit(1); + } + bread=ov_read(ov,buffer,4096,1,1,1,&dummy); + for(j=0;j<bread;j++){ + if(buffer[j]!=bigassbuffer[j+((pos>>hs)*2)]){ + fprintf(stderr,"data after seek doesn't match declared pcm position %ld\n",(long)pos); + + for(i=0;i<(pcmlength>>hs)*2-bread;i++){ + for(j=0;j<bread;j++) + if(buffer[j] != bigassbuffer[i+j])break; + if(j==bread){ + fprintf(stderr,"data after seek appears to match position %ld\n",(long)((i/2)<<hs)); + } + } + { + FILE *f=fopen("a.m","w"); + for(j=0;j<bread;j++)fprintf(f,"%d %d\n",j,(int)buffer[j]); + fclose(f); + f=fopen("b.m","w"); + for(j=-4096;j<bread+4096;j++) + if(j+((pos*2)>>hs)>=0 && (j+((pos*2)>>hs))<(pcmlength>>hs)*2) + fprintf(f,"%d %d\n",j,(int)bigassbuffer[j+((pos*2)>>hs)]); + fclose(f); + } + + exit(1); + } + } +} + +int main(){ + OggVorbis_File ov; + int i,ret; + ogg_int64_t pcmlength; + double timelength; + char *bigassbuffer; + int dummy; + int hs=0; + +#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */ + _setmode( _fileno( stdin ), _O_BINARY ); +#endif + + + /* open the file/pipe on stdin */ + if(ov_open_callbacks(stdin,&ov,NULL,-1,OV_CALLBACKS_NOCLOSE)<0){ + fprintf(stderr,"Could not open input as an OggVorbis file.\n\n"); + exit(1); + } + +#if 0 /*enable this code to test seeking with halfrate decode */ + if(ov_halfrate(&ov,1)){ + fprintf(stderr,"Sorry; unable to set half-rate decode.\n\n"); + exit(1); + }else + hs=1; +#endif + + if(ov_seekable(&ov)){ + + /* to simplify our own lives, we want to assume the whole file is + stereo. Verify this to avoid potentially mystifying users + (pissing them off is OK, just don't confuse them) */ + for(i=0;i<ov.links;i++){ + vorbis_info *vi=ov_info(&ov,i); + if(vi->channels!=2){ + fprintf(stderr,"Sorry; right now seeking_test can only use Vorbis files\n" + "that are entirely stereo.\n\n"); + exit(1); + } + } + + /* because we want to do sample-level verification that the seek + does what it claimed, decode the entire file into memory */ + pcmlength=ov_pcm_total(&ov,-1); + timelength=ov_time_total(&ov,-1); + bigassbuffer=malloc((pcmlength>>hs)*2); /* w00t */ + i=0; + while(i<(pcmlength>>hs)*2){ + int ret=ov_read(&ov,bigassbuffer+i,((pcmlength>>hs)*2)-i,1,1,1,&dummy); + if(ret<0){ + fprintf(stderr,"Error reading file.\n"); + exit(1); + } + if(ret){ + i+=ret; + }else{ + pcmlength=(i/2)<<hs; + } + fprintf(stderr,"\rloading.... [%ld left] ", + (long)((pcmlength>>hs)*2-i)); + } + + { + ogg_int64_t length=ov.end; + fprintf(stderr,"\rtesting raw seeking to random places in %ld bytes....\n", + (long)length); + + for(i=0;i<1000;i++){ + ogg_int64_t val=(double)rand()/RAND_MAX*length; + fprintf(stderr,"\r\t%d [raw position %ld]... ",i,(long)val); + ret=ov_raw_seek(&ov,val); + if(ret<0){ + fprintf(stderr,"seek failed: %d\n",ret); + exit(1); + } + + _verify(&ov,val,-1,-1.,pcmlength,bigassbuffer); + + } + } + + fprintf(stderr,"\r"); + { + fprintf(stderr,"testing pcm page seeking to random places in %ld samples....\n", + (long)pcmlength); + + for(i=0;i<1000;i++){ + ogg_int64_t val= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength; + fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val); + ret=ov_pcm_seek_page(&ov,val); + if(ret<0){ + fprintf(stderr,"seek failed: %d\n",ret); + exit(1); + } + + _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer); + + } + } + + fprintf(stderr,"\r"); + { + fprintf(stderr,"testing pcm exact seeking to random places in %f seconds....\n", + timelength); + for(i=0;i<1000;i++){ + ogg_int64_t val= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength; + fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val); + ret=ov_pcm_seek(&ov,val); + if(ret<0){ + fprintf(stderr,"seek failed: %d\n",ret); + exit(1); + } + if(ov_pcm_tell(&ov)!=((val>>hs)<<hs)){ + fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n", + (long)val,(long)ov_pcm_tell(&ov)); + exit(1); + } + + _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer); + + } + } + + fprintf(stderr,"\r"); + { + fprintf(stderr,"testing time page seeking to random places in %f seconds....\n", + timelength); + + for(i=0;i<1000;i++){ + double val=(double)rand()/RAND_MAX*timelength; + fprintf(stderr,"\r\t%d [time position %f]... ",i,val); + ret=ov_time_seek_page(&ov,val); + if(ret<0){ + fprintf(stderr,"seek failed: %d\n",ret); + exit(1); + } + + _verify(&ov,-1,-1,val,pcmlength,bigassbuffer); + + } + } + + fprintf(stderr,"\r"); + { + fprintf(stderr,"testing time exact seeking to random places in %f seconds....\n", + timelength); + + for(i=0;i<1000;i++){ + double val=(double)rand()/RAND_MAX*timelength; + fprintf(stderr,"\r\t%d [time position %f]... ",i,val); + ret=ov_time_seek(&ov,val); + if(ret<0){ + fprintf(stderr,"seek failed: %d\n",ret); + exit(1); + } + if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){ + fprintf(stderr,"Declared position didn't perfectly match request: %f != %f\n", + val,ov_time_tell(&ov)); + exit(1); + } + + _verify(&ov,-1,-1,val,pcmlength,bigassbuffer); + + } + } + + fprintf(stderr,"\r \nOK.\n\n"); + + + }else{ + fprintf(stderr,"Standard input was not seekable.\n"); + } + + ov_clear(&ov); + return 0; +} + + + + + + + + + + + + + diff --git a/vorbis/examples/vorbisfile_example.c b/vorbis/examples/vorbisfile_example.c new file mode 100644 index 0000000..d15bc4c --- /dev/null +++ b/vorbis/examples/vorbisfile_example.c @@ -0,0 +1,91 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: simple example decoder using vorbisfile + + ********************************************************************/ + +/* Takes a vorbis bitstream from stdin and writes raw stereo PCM to + stdout using vorbisfile. Using vorbisfile is much simpler than + dealing with libvorbis. */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <vorbis/codec.h> +#include <vorbis/vorbisfile.h> + +#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */ +#include <io.h> +#include <fcntl.h> +#endif + +char pcmout[4096]; /* take 4k out of the data segment, not the stack */ + +int main(){ + OggVorbis_File vf; + int eof=0; + int current_section; + +#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */ + /* Beware the evil ifdef. We avoid these where we can, but this one we + cannot. Don't add any more, you'll probably go to hell if you do. */ + _setmode( _fileno( stdin ), _O_BINARY ); + _setmode( _fileno( stdout ), _O_BINARY ); +#endif + + if(ov_open_callbacks(stdin, &vf, NULL, 0, OV_CALLBACKS_NOCLOSE) < 0) { + fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n"); + exit(1); + } + + /* Throw the comments plus a few lines about the bitstream we're + decoding */ + { + char **ptr=ov_comment(&vf,-1)->user_comments; + vorbis_info *vi=ov_info(&vf,-1); + while(*ptr){ + fprintf(stderr,"%s\n",*ptr); + ++ptr; + } + fprintf(stderr,"\nBitstream is %d channel, %ldHz\n",vi->channels,vi->rate); + fprintf(stderr,"\nDecoded length: %ld samples\n", + (long)ov_pcm_total(&vf,-1)); + fprintf(stderr,"Encoded by: %s\n\n",ov_comment(&vf,-1)->vendor); + } + + while(!eof){ + long ret=ov_read(&vf,pcmout,sizeof(pcmout),0,2,1,¤t_section); + if (ret == 0) { + /* EOF */ + eof=1; + } else if (ret < 0) { + if(ret==OV_EBADLINK){ + fprintf(stderr,"Corrupt bitstream section! Exiting.\n"); + exit(1); + } + + /* some other error in the stream. Not a problem, just reporting it in + case we (the app) cares. In this case, we don't. */ + } else { + /* we don't bother dealing with sample rate changes, etc, but + you'll have to*/ + fwrite(pcmout,1,ret,stdout); + } + } + + /* cleanup */ + ov_clear(&vf); + + fprintf(stderr,"Done.\n"); + return(0); +} |