From: WANG Date: Fri, 27 Sep 2013 13:14:52 +0000 (+0200) Subject: Implement stdin, stdout and stderr to Faustine. X-Git-Url: https://scm.cri.mines-paristech.fr/git/Faustine.git/commitdiff_plain/c55d1f23d06e85b0e21cdf5cbc5c8efb6ac3bc1a?ds=inline Implement stdin, stdout and stderr to Faustine. Tested by examples/sinwave/sin.dsp. --- diff --git a/examples/fft/Makefile b/examples/fft/Makefile index cbe38a6..6d41558 100644 --- a/examples/fft/Makefile +++ b/examples/fft/Makefile @@ -8,12 +8,7 @@ SINSUM = sinsum.dsp WAV_BASENAME = $(SINSUM:.dsp=) WAV_FORMAT = wav WAVIN = $(WAV_BASENAME)1.$(WAV_FORMAT) - -INPUT1 = sin_1378Hz_0.005_ampli_128samples.wav -INPUT2 = sin_2067Hz_0.005_ampli_128samples.wav -INPUT3 = sin_16536Hz_0.005_ampli_128samples.wav -INPUT4 = sin_22000Hz_0.005_ampli_128samples.wav - +WAV_LENGTH = 128 all: $(IMGOUT) @@ -23,8 +18,8 @@ $(IMGOUT): $(CSVOUT) $(CSVOUT): $(SRC) $(WAVIN) faustine -f $(SRC) -i $(WAVIN) --oformat $(FORMAT) --obasename $(BASENAME) -$(WAVIN): $(SINS) $(INPUT1) $(INPUT2) $(INPUT3) $(INPUT4) - faustine -f $(SINSUM) -i $(INPUT1) -i $(INPUT2) -i $(INPUT3) -i $(INPUT4) --oformat $(WAV_FORMAT) --obasename $(WAV_BASENAME) +$(WAVIN): $(SINS) + faustine -f $(SINSUM) -l $(WAV_LENGTH) --oformat $(WAV_FORMAT) --obasename $(WAV_BASENAME) clean:: rm -f gmon.out $(CSVOUT) $(IMGOUT) $(WAVIN) *~ diff --git a/examples/fft/fft.png b/examples/fft/fft.png index 6e8739e..eec0f4b 100644 Binary files a/examples/fft/fft.png and b/examples/fft/fft.png differ diff --git a/examples/fft/sin_1378Hz_0.005_ampli_128samples.wav b/examples/fft/sin_1378Hz_0.005_ampli_128samples.wav deleted file mode 100644 index 7d4c896..0000000 Binary files a/examples/fft/sin_1378Hz_0.005_ampli_128samples.wav and /dev/null differ diff --git a/examples/fft/sin_16536Hz_0.005_ampli_128samples.wav b/examples/fft/sin_16536Hz_0.005_ampli_128samples.wav deleted file mode 100644 index e48ffb6..0000000 Binary files a/examples/fft/sin_16536Hz_0.005_ampli_128samples.wav and /dev/null differ diff --git a/examples/fft/sin_2067Hz_0.005_ampli_128samples.wav b/examples/fft/sin_2067Hz_0.005_ampli_128samples.wav deleted file mode 100644 index a8524b7..0000000 Binary files a/examples/fft/sin_2067Hz_0.005_ampli_128samples.wav and /dev/null differ diff --git a/examples/fft/sin_22000Hz_0.005_ampli_128samples.wav b/examples/fft/sin_22000Hz_0.005_ampli_128samples.wav deleted file mode 100644 index 93556f1..0000000 Binary files a/examples/fft/sin_22000Hz_0.005_ampli_128samples.wav and /dev/null differ diff --git a/examples/fft/sinsum.dsp b/examples/fft/sinsum.dsp index 0ee1d5b..3299928 100644 --- a/examples/fft/sinsum.dsp +++ b/examples/fft/sinsum.dsp @@ -1 +1,6 @@ -process = +, + : +; +import("math.lib"); +import("music.lib"); +samplerate = 44100; +process = (sinwave(1378) + sinwave(2067)) , (sinwave(16536) + sinwave(22000)) : + : /(4) ; +sinwave(f) = time*(2.0*PI)*f/samplerate : sin; + diff --git a/interpreter/aux.ml b/interpreter/aux.ml index 7c21a61..5321349 100644 --- a/interpreter/aux.ml +++ b/interpreter/aux.ml @@ -18,7 +18,7 @@ let array_map3 = fun f -> fun a -> fun b -> fun c -> if n1 = n2 && n1 = n3 then Array.init n1 (fun i -> f a.(i) b.(i) c.(i)) else raise (Invalid_argument "Array.map3 size not matched.");; -let decorate = fun s -> " Faustine -> " ^ s;; +let decorate = fun s -> " Faustine -> " ^ s ^ "\n";; let xor : bool -> bool -> bool = fun a -> fun b -> (a || b) && (not (a && b));; diff --git a/interpreter/faustio.ml b/interpreter/faustio.ml index 7df74a6..47e07ce 100644 --- a/interpreter/faustio.ml +++ b/interpreter/faustio.ml @@ -12,16 +12,20 @@ open Signal;; open Beam;; open Aux;; +exception Faustine_IO_Error of string;; + let csv_read_buffer_length = 0xFFFF;; class virtual io = object + val mutable _filename = "" val mutable _basename = "" val mutable _dir = "" - method set : string -> string -> unit = - fun (dir : string) -> - fun (basename : string) -> - _basename <- basename; _dir <- dir + method set : string -> string -> string -> unit = + fun (filename : string) -> + fun (dir : string) -> + fun (basename : string) -> + _filename <- filename; _basename <- basename; _dir <- dir method virtual read : string array -> beam method virtual write : rate array -> data -> string array @@ -70,11 +74,18 @@ class waveio : io_type = fun (rates : rate array) -> fun (output : data) -> let n = Array.length output in - let paths = Array.init n (fun i -> - _dir ^ _basename ^ (string_of_int (i + 1)) ^ ".wav") in + let paths = + if _filename = "" then + Array.init n (fun i -> + _dir ^ _basename ^ (string_of_int (i + 1)) ^ ".wav") + else if n = 1 then + let () = Unix.unlink "_filename" in [|(_filename ^ ".wav")|] + else raise (Faustine_IO_Error ("The process has several output signals, + however stdout supports only one output signal. Please remove + the '> " ^ _filename ^ "'.")) in let get_freq = fun (r : rate) -> r#to_int in let freqs = Array.map get_freq rates in - + let files = let channels = self#channels output in let file_format = Sndfile.format @@ -124,12 +135,16 @@ class csvio : io_type = method write : rate array -> data -> string array = fun (rates : rate array) -> fun (data : data) -> + let n = Array.length data in let paths = - let n = Array.length data in - let path_pattern = fun i -> - _dir ^ _basename ^ (string_of_int (i + 1)) ^ ".csv" in - Array.init n path_pattern in - + if _filename = "" then + Array.init n (fun i -> + _dir ^ _basename ^ (string_of_int (i + 1)) ^ ".csv") + else if n = 1 then + let () = Unix.unlink _filename in [|(_filename ^ ".csv")|] + else raise (Faustine_IO_Error ("The process has several output signals, + however stdout supports only one output signal. Please remove + the '> " ^ _filename ^ "'.")) in let files = Array.map open_out paths in let strings = let value2string : float array -> string = @@ -151,6 +166,7 @@ class iomanager = object (self) val wave = new waveio val csv = new csvio + val mutable _output_filename = "" val mutable _dir = "" val mutable _format = "" val mutable _basename = "" @@ -175,15 +191,17 @@ class iomanager = fun b1 -> fun b2 -> b1#append b2 in List.fold_left concat (new beam [||]) beams - method set : string -> string -> string -> unit = - fun (dir : string) -> - fun (format : string) -> - fun (basename : string) -> - _dir <- dir; - _format <- format; - _basename <- basename; - wave#set _dir _basename; - csv#set _dir _basename + method set : string -> string -> string -> string -> unit = + fun (filename : string) -> + fun (dir : string) -> + fun (format : string) -> + fun (basename : string) -> + _output_filename <- filename; + _dir <- dir; + _format <- format; + _basename <- basename; + wave#set _output_filename _dir _basename; + csv#set _output_filename _dir _basename method write : rate array -> data -> string array = fun (rates : rate array) -> diff --git a/interpreter/main.ml b/interpreter/main.ml index 54c7f1a..2f102f3 100644 --- a/interpreter/main.ml +++ b/interpreter/main.ml @@ -6,6 +6,7 @@ *) open Aux;; +open Beam;; open Process;; open Faustio;; @@ -33,8 +34,9 @@ let size_input = ref 0;; let inputs = ref [];; let time_max = ref 0xFFFF;; let dir_output = ref "";; -let format_output = ref "wav";; +let format_output = ref "csv";; let basename_output = ref "output";; +let output = ref "";; let option_usage = "usage: " ^ Sys.argv.(0) ^ " [-f dsp_src] [-i input] [-l length] [--odir dir] [--oformat wav/csv] [--obasename name]";; @@ -51,65 +53,87 @@ let speclist = [ ("--obasename", Arg.String (fun s -> basename_output := s), ": set output basename"); ];; +let file_of_path : string -> string = + fun (path : string) -> + let fragments = Str.split (Str.regexp "/") path in + let n = List.length fragments in + List.nth fragments (n - 1);; + +let stdinput = fun (x : unit) -> + let path = Unix.readlink "/proc/self/fd/0" in + if path <> "/dev/pts/4" then + ( incr size_input; + inputs := !inputs @ [path] ) + else ();; + +let stdoutput = fun (x : unit) -> + let path = Unix.readlink "/proc/self/fd/1" in + if path <> "/dev/pts/4" then output := path + else ();; + +let stdio = fun (x : unit) -> + stdinput (); + stdoutput ();; let main () = + (* - let () = print_endline (Scanf.Scanning.name_of_input (Scanf.Scanning.stdin)) in let () = print_endline (Unix.readlink "/proc/self/fd/0") in let () = print_endline (Unix.readlink "/proc/self/fd/1") in let () = print_endline (Unix.readlink "/proc/self/fd/2") in *) + let () = stdio () in let () = Arg.parse speclist option_unknown option_usage in let _ = Sys.signal Sys.sigalrm Sys.Signal_ignore in let _ = set_GC () in let io = new iomanager in - let () = io#set !dir_output !format_output !basename_output in + let () = io#set !output !dir_output !format_output !basename_output in - let () = print_string(" Faustine -> Reading input ...") in + let () = output_string stderr (" Faustine -> Reading input ...") in let tic0 = Unix.time () in - let input = io#read !inputs in + let input : beam = io#read !inputs in let toc0 = Unix.time () in - let () = print_endline(" Done. (duration: " ^ (string_of_float (toc0 -. tic0)) ^ "s.)") in + let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc0 -. tic0)) ^ "s.)\n") in - let () = print_string(" Faustine -> Preprocessing...") in + let () = output_string stderr (" Faustine -> Preprocessing...") in let tic1 = Unix.time () in let faust_core = Preprocess.preprocess !path_dsp in let toc1 = Unix.time () in - let () = print_endline(" Done. (duration: " ^ (string_of_float (toc1 -. tic1)) ^ "s.)") in + let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc1 -. tic1)) ^ "s.)\n") in - let () = print_string(" Faustine -> Constructing process...") in + let () = output_string stderr (" Faustine -> Constructing process...") in let tic2 = Unix.time () in let faust_exp = exp_of_string faust_core in let proc = (new proc_factory)#make faust_exp in let toc2 = Unix.time () in - let () = print_endline(" Done. (duration: " ^ (string_of_float (toc2 -. tic2)) ^ "s.)") in + let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc2 -. tic2)) ^ "s.)\n") in - let () = print_string(" Faustine -> Constructing signals...") in + let () = output_string stderr (" Faustine -> Constructing signals...") in let tic3 = Unix.time () in - let output = proc#eval input in + let output : beam = proc#eval input in let toc3 = Unix.time () in - let () = print_endline(" Done. (duration: " ^ (string_of_float (toc3 -. tic3)) ^ "s.)") in + let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc3 -. tic3)) ^ "s.)\n") in - let () = print_string(" Faustine -> Evaluating...") in + let () = output_string stderr (" Faustine -> Evaluating...") in let tic4 = Unix.time () in let data = output#output !time_max in let rates = output#frequency in let toc4 = Unix.time () in - let () = print_endline(" Done. (duration: " ^ (string_of_float (toc4 -. tic4)) ^ "s.)") in + let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc4 -. tic4)) ^ "s.)\n") in - let () = print_string(" Faustine -> Writing output...") in + let () = output_string stderr (" Faustine -> Writing output...") in let tic5 = Unix.time () in let output_paths = io#write rates data in let toc5 = Unix.time () in - let () = print_endline(" Done. (duration: " ^ (string_of_float (toc5 -. tic5)) ^ "s.)") in + let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc5 -. tic5)) ^ "s.)\n") in - let _ = Array.map print_endline + let _ = Array.map (output_string stderr) (Array.map decorate output_paths) in ();; diff --git a/interpreter/signal.ml b/interpreter/signal.ml index 66089e9..0701ffc 100644 --- a/interpreter/signal.ml +++ b/interpreter/signal.ml @@ -20,19 +20,14 @@ class rate : int -> int -> rate_type = fun i1 -> fun i2 -> let r = i1 mod i2 in if r = 0 then i2 else pgcd i2 r in - let num_positive = - if num_init >= 0 then num_init - else (-num_init) in - let denom_positive = - if denom_init > 0 then denom_init - else if denom_init < 0 then -denom_init - else raise (Signal_operation "sample rate denominater = 0.") in - let factor = pgcd num_positive denom_positive in - let num_corrected = num_init / factor in - let denom_corrected = denom_init / factor in + let factor = + if denom_init = 0 then + raise (Signal_operation "sample rate denominater = 0.") + else + pgcd (abs num_init) (abs denom_init) in object (self) - val _num = num_corrected - val _denom = denom_corrected + val _num = num_init / factor + val _denom = denom_init / factor method num = _num method denom = _denom method to_int = @@ -243,7 +238,6 @@ class signal : rate_type -> (time -> value_type) -> signal_type = new value (Vec (new vector size vec)) in new signal freq func - method serialize : signal_type = let size = match (self#at 0)#get with diff --git a/interpreter/types.ml b/interpreter/types.ml index 7024eeb..da486f2 100644 --- a/interpreter/types.ml +++ b/interpreter/types.ml @@ -253,7 +253,7 @@ class type process_type = class type io_type = object - method set : string -> string -> unit + method set : string -> string -> string -> unit method read : string array -> beam_type method write : rate_type array -> data -> string array end;;