type oogg64 = (int * int * int * int);; type oogg32 = (int * int);; type serialNo = oogg32;; type granulePos = oogg64 option;; type checksum = oogg32;; type sequenceNo = oogg32;; (* raw byte streams *) type stream = IO.input;; type outStream = unit IO.output;; (* * an oogg Page record *) type rawPage = { continued : bool ; bos : bool ; eos : bool ; last_packet_complete : bool ; granulepos : granulePos ; serialno : serialNo ; sequenceno : sequenceNo ; checksum : checksum ; packet_sizes : int list ; raw_data : string list ; };; (* media types *) type mediaType = Skeleton | CMML | Vorbis | Theora | Unknown;; type page = { raw : rawPage ; time : float option; identity : mediaType };; type rawPageStream = rawPage Stream.t;; type pageStream = page Stream.t;; (* the type of a media stream *) type mediaStream = { stream_serialno : serialNo ; stream_pages : rawPageStream ; stream_type : mediaType ; stream_time : (granulePos -> float option) };; let oogg32_to_int64 (a, b) = Int64.add (Int64.of_int b) (Int64.shift_left (Int64.of_int a) 16);; let oogg64_to_int64 (a,b,c,d) = if (a,b,c,d) = (65535, 65535, 65535, 65535) then -1L else Int64.add (oogg32_to_int64 (c,d)) (Int64.shift_left (oogg32_to_int64 (a,b)) 32);; let int64_to_oogg32 value = (Int64.to_int (Int64.shift_right value 16), Int64.to_int (Int64.logand value (Int64.of_int 0xFFFF)));; let int64_to_oogg64 value = let mask = Int64.of_int 0xFFFF in (Int64.to_int (Int64.shift_right value 48), Int64.to_int (Int64.logand (Int64.shift_right value 32) mask), Int64.to_int (Int64.logand (Int64.shift_right value 16) mask), Int64.to_int (Int64.logand value mask));; let oogg64_to_float (a,b,c,d) = if (a,b,c,d) = (65535, 65535, 65535, 65535) then -1.0 else float_of_int a *. (256. ** 6.) +. float_of_int b *. (256. ** 4.) +. float_of_int c *. (256. ** 2.) +. float_of_int d;; let oogg32_to_string value = Int64.to_string (oogg32_to_int64 value);; let print_oogg32 value = print_string (oogg32_to_string value) let print_oogg64 (a,b,c,d) = if a > 0 then Printf.printf "%x%04x%04x%04x" a b c d else if b > 0 then Printf.printf "%x%04x%04x" b c d else if c > 0 then Printf.printf "%x%04x" c d else Printf.printf "%x" d;; let print_granulepos gp = match gp with | None -> Printf.printf "None" | Some gp -> print_oogg64 gp;; let print_mediaType t = print_string (match t with | Skeleton -> "Skeleton" | CMML -> "CMML" | Vorbis -> "Vorbis" | Theora -> "Theora" | Unknown -> "Unknown!");; type packet = { p_data : string ; mutable p_granulepos : granulePos ; mutable p_time : float option ; p_pageno : int ; p_serialno : serialNo ; p_continued : bool ; p_continues : bool ; p_page_seq : sequenceNo ; p_identity : mediaType ; p_bos : bool ; p_eos : bool };; type packetStream = packet Stream.t;; let read_ui32 stream = let b = IO.read_ui16 stream in let a = IO.read_ui16 stream in Int64.add (Int64.shift_left (Int64.of_int a) 16) (Int64.of_int b);; let mask = Int64.of_int 0xFFFF let write_ui32 stream value = let a = Int64.to_int (Int64.shift_right value 16) in let b = Int64.to_int (Int64.logand value mask) in IO.write_ui16 stream b; IO.write_ui16 stream a;; let read_oogg64 stream = (IO.read_ui16 stream, IO.read_ui16 stream, IO.read_ui16 stream, IO.read_ui16 stream);; let write_oogg64 stream (a, b, c, d) = IO.write_ui16 stream d; IO.write_ui16 stream c; IO.write_ui16 stream b; IO.write_ui16 stream a;; let read_oogg32 stream = (IO.read_ui16 stream, IO.read_ui16 stream);; let write_oogg32 stream (a, b) = IO.write_ui16 stream b; IO.write_ui16 stream a;; let read_granulepos stream = let gp = read_oogg64 stream in if gp = (0xFFFF,0xFFFF,0xFFFF,0xFFFF) then None else Some gp;; let write_granulepos stream gp = match gp with | None -> write_oogg64 stream (0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) | Some gp -> write_oogg64 stream gp;; let extract_be_int32 str pos = let substr = IO.input_string (String.sub str pos 4) in let a = IO.read_byte substr in let b = IO.read_byte substr in let c = IO.read_byte substr in let d = IO.read_byte substr in let e = (a lsl 8) + b in let f = (c lsl 8) + d in Int64.add (Int64.shift_left (Int64.of_int e) 16) (Int64.of_int f);; let extract_le_int32 str pos = let substr = IO.input_string (String.sub str pos 4) in let d = IO.read_byte substr in let c = IO.read_byte substr in let b = IO.read_byte substr in let a = IO.read_byte substr in let e = (a lsl 8) + b in let f = (c lsl 8) + d in Int64.add (Int64.shift_left (Int64.of_int e) 16) (Int64.of_int f);; let extract_le_int64 str pos = let a = extract_le_int32 str pos in let b = extract_le_int32 str (pos + 4) in Int64.add (Int64.shift_left a 32) b;; let extract_int8 str pos = let substr = IO.input_string (String.sub str pos 1) in IO.read_byte substr;; let extract_le_oogg64 str pos = let substr = IO.input_string (String.sub str pos 8) in read_oogg64 substr;;