Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

146 lines (134 sloc) 4.656 kB
(*
* Copyright 2003 Savonet team
*
* This file is part of OCaml-Vorbis.
*
* OCaml-Vorbis is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* OCaml-Vorbis is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OCaml-Vorbis; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*)
(**
* An wav to ogg converter using OCaml-Vorbis.
*
* @author Samuel Mimram, and many others...
*)
(* $Id$ *)
open Vorbis
open Unix
let src = ref ""
let dst = ref ""
let buflen = ref 1024
let input_string chan len =
let ans = String.create len in
(* TODO: check length *)
ignore (input chan ans 0 len) ;
ans
let input_int chan =
let buf = input_string chan 4 in
(int_of_char buf.[0])
+ (int_of_char buf.[1]) lsl 8
+ (int_of_char buf.[2]) lsl 16
+ (int_of_char buf.[3]) lsl 24
let input_short chan =
let buf = input_string chan 2 in
(int_of_char buf.[0]) + (int_of_char buf.[1]) lsl 8
let bitrate = ref 128000
let usage = "usage: wav2ogg [options] source destination"
let _ =
Arg.parse
[
"--bitrate", Arg.Int (fun b -> bitrate := b * 1000),
"Bitrate, in kilobits per second, defaults to 128kbps" ;
"--buflen", Arg.Int (fun i -> buflen := i),
"Size of chunks successively encoded"
]
(
let pnum = ref (-1) in
(fun s -> incr pnum; match !pnum with
| 0 -> src := s
| 1 -> dst := s
| _ -> Printf.eprintf "Error: too many arguments\n"; exit 1
)
) usage;
if !src = "" || !dst = "" then
(
Printf.printf "%s\n" usage;
exit 1
);
let ic = open_in_bin !src in
let oc = open_out_bin !dst in
(* TODO: improve! *)
if input_string ic 4 <> "RIFF" then invalid_arg "No RIFF tag";
ignore (input_string ic 4);
if input_string ic 4 <> "WAVE" then invalid_arg "No WAVE tag";
if input_string ic 4 <> "fmt " then invalid_arg "No fmt tag";
let _ = input_int ic in
let _ = input_short ic in (* TODO: should be 1 *)
let channels = input_short ic in
let infreq = input_int ic in
let _ = input_int ic in (* bytes / s *)
let _ = input_short ic in (* block align *)
let bits = input_short ic in
let fos buf =
let len = String.length buf / (2 * channels) in
let ans = Array.init channels (fun _ -> Array.create len 0.) in
for i = 0 to len - 1 do
for c = 0 to channels - 1 do
let n =
int_of_char buf.[2 * channels * i + 2 * c]
+ int_of_char buf.[2 * channels * i + 2 * c + 1] lsl 8
in
let n =
if n land 1 lsl 15 = 0 then
n
else
(n land 0b111111111111111) - 32768
in
ans.(c).(i) <- float n /. 32768.;
ans.(c).(i) <- max (-1.) (min 1. ans.(c).(i))
done;
done;
ans
in
let enc = Encoder.create channels infreq (-1) !bitrate (-1) in
let os = Ogg.Stream.create () in
let encode buf =
let fbuf = fos buf in
Encoder.encode_buffer_float enc os fbuf 0 (Array.length fbuf.(0))
in
let start = Unix.time () in
Printf.printf
"Input detected: PCM WAVE %d channels, %d Hz, %d bits\n%!"
channels infreq bits;
Printf.printf
"Encoding to: OGG %d channels, %d Hz, %d kbps\nPlease wait...\n%!"
channels infreq !bitrate;
Encoder.headerout enc os ["ARTIST", "test"];
if input_string ic 4 <> "data" then invalid_arg "No data tag";
(* This ensures the actual audio data will start on a new page, as per
* spec. *)
output_string oc (Ogg.Stream.flush os);
let buflen = !buflen in
let buf = String.create buflen in
begin try while true do
really_input ic buf 0 buflen;
encode buf;
output_string oc (Ogg.Stream.pagesout os);
done;
with End_of_file -> () end;
Encoder.end_of_stream enc os;
output_string oc (Ogg.Stream.pagesout os);
close_in ic;
close_out oc;
Printf.printf "Finished in %.0f seconds.\n" ((Unix.time ())-.start);
Gc.full_major ()
Jump to Line
Something went wrong with that request. Please try again.