#------------------------------------------------------------------------------ # vorbis: file(1) magic for Ogg/Vorbis files # # From Felix von Leitner # Extended by Beni Cherniavsky # Further extended by Greg Wooledge # # Most (everything but the number of channels and bitrate) is commented # out with `##' as it's not interesting to the average user. The most # probable things advanced users would want to uncomment are probably # the number of comments and the encoder version. # # --- Ogg Framing --- 0 string OggS Ogg data >4 byte !0 UNKNOWN REVISION %u ##>4 byte 0 revision 0 >4 byte 0 ##>>14 lelong x (Serial %lX) # --- First vorbis packet - general header --- >>28 string \x01vorbis \b, Vorbis audio, >>>35 lelong !0 UNKNOWN VERSION %lu, ##>>>35 lelong 0 version 0, >>>35 lelong 0 >>>>39 ubyte 1 mono, >>>>39 ubyte 2 stereo, >>>>39 ubyte >2 %u channels, >>>>40 lelong x %lu Hz # Minimal, nominal and maximal bitrates specified when encoding >>>>48 string <\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff \b, # The above tests if at least one of these is specified: >>>>>44 lelong !-1 # Vorbis RC2 has a bug which puts -1000 in the min/max bitrate fields # instead of -1. >>>>>>44 lelong !-1000 >>>>>>>44 lelong x >%lu >>>>>48 lelong !-1 >>>>>>48 lelong x ~%lu >>>>>52 lelong !-1 >>>>>>52 lelong !-1000 >>>>>>>52 lelong x <%lu >>>>>48 string <\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff kbps # -- Second vorbis header packet - the comments # A kludge to read the vendor string. It's a counted string, not a # zero-terminated one, so file(1) can't read it in a generic way. # libVorbis is the only one existing currently, so I detect specifically # it. The interesting value is the cvs date (8 digits decimal). # Post-RC1 Ogg files have the second header packet (and thus the version) # in a different place, so we must use an indirect offset. >>>(84.b+85) string \x03vorbis >>>>(84.b+96) string/c Xiphophorus\ libVorbis\ I \b, created by: Xiphophorus libVorbis I >>>>>(84.b+120) string >00000000 %.8s # Map to beta version numbers: >>>>>>(84.b+120) string <20000508 (>>>>>(84.b+120) string 20000508 (beta1/2) >>>>>>(84.b+120) string >20000508 >>>>>>>(84.b+120) string <20001031 (beta2-3) >>>>>>(84.b+120) string 20001031 (beta3) >>>>>>(84.b+120) string >20001031 >>>>>>>(84.b+120) string <20010225 (beta3-4) >>>>>>(84.b+120) string 20010225 (beta4) >>>>>>(84.b+120) string >20010225 >>>>>>>(84.b+120) string <20010615 (beta4-RC1) >>>>>>(84.b+120) string 20010615 (RC1) >>>>>>(84.b+120) string 20010813 (RC2) >>>>>>(84.b+120) string 20010816 (RC2 - Garf tuned v1) >>>>>>(84.b+120) string 20011014 (RC2 - Garf tuned v2) >>>>>>(84.b+120) string 20011217 (pre-RC3 CVS) >>>>>>(84.b+120) string 20011231 (RC3) # The string has not changed from beta1 to 2 - they are indistinguishable. # Then come the comments, again length-counted (and number-counted). # Some looping constructs and registers would allow reading them but now # it's impossible. However we can print the number of comments present # (skipping by the vendor string length): ##>>>>(109.l.113) lelong 0 \b, no comments ##>>>>(109.l+113) lelong >0 \b, %lu comments