From c55d1f23d06e85b0e21cdf5cbc5c8efb6ac3bc1a Mon Sep 17 00:00:00 2001 From: WANG Date: Fri, 27 Sep 2013 15:14:52 +0200 Subject: [PATCH] Implement stdin, stdout and stderr to Faustine. Tested by examples/sinwave/sin.dsp. --- examples/fft/Makefile | 11 +--- examples/fft/fft.png | Bin 28682 -> 22515 bytes .../fft/sin_1378Hz_0.005_ampli_128samples.wav | Bin 300 -> 0 bytes .../sin_16536Hz_0.005_ampli_128samples.wav | Bin 300 -> 0 bytes .../fft/sin_2067Hz_0.005_ampli_128samples.wav | Bin 300 -> 0 bytes .../sin_22000Hz_0.005_ampli_128samples.wav | Bin 300 -> 0 bytes examples/fft/sinsum.dsp | 7 +- interpreter/aux.ml | 2 +- interpreter/faustio.ml | 60 ++++++++++++------ interpreter/main.ml | 60 ++++++++++++------ interpreter/signal.ml | 20 ++---- interpreter/types.ml | 2 +- 12 files changed, 99 insertions(+), 63 deletions(-) delete mode 100644 examples/fft/sin_1378Hz_0.005_ampli_128samples.wav delete mode 100644 examples/fft/sin_16536Hz_0.005_ampli_128samples.wav delete mode 100644 examples/fft/sin_2067Hz_0.005_ampli_128samples.wav delete mode 100644 examples/fft/sin_22000Hz_0.005_ampli_128samples.wav 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 6e8739ea352247d601732f17722602e7bd233259..eec0f4b92371b1003ada7db3c283416928934e1c 100644 GIT binary patch literal 22515 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�#-6^; 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 literal 28682 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 Uy{stKpK4F2>)NXM%KrrX7uq)C5C8xG 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 7d4c8960f2666bafb701950f2f3622997033293c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 300 zcmXYs-AV#c7)6&oflp9l^cax{C3M?Gf74h4l9hB(3?p`5*d*OVe*}T1(nar(_8_4> zh`XJ1&ehp`>s$M5te4A6IoK*~t{t8xK_1BYu6{skJI5S(s&NuK@(EZW;*2(T^yu=& zJsIazSZ0x_el${FZ8dbFiX!dnNKM^18)+gbpvW#MS3J=%-Q|I65<=$-R!sD%cV%Xd z&4!9qoACn;%}-UZKlFTy#~I(@*}GEjEdKk48ra`7cVK^{x>CRY{A2qI?pbmF%-#-t hUU}h?20N6P_g}~QQct&L>h8bi9W`CJPv7~segPG>i8TNK 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 e48ffb6a768cb3ebbb03a0d6f40d233f04d9301d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 300 zcmYj~OAY}+07R?F>>a_vMI=aUE&M-`h@D_G;slss#ufZGZs=2Le3I$jbalO|DisTb zi~%aya=t&X=@bB?o4Wz4szCxN^t!gIFCB{}Ey#dJY-r%3&58cEJRszgGc@EIc)ViG zB*q`#z~@;!IaPk5PA{gveS7Sbk9_;<3&dNr=!*Aw(nh4)9Kpegmsp?C`=I=t3)I9U qw0#l(itU{c{IrXt_9Ok|9Ch*k{6l<)L-nuahkVFyXy3u|)At5A(}g<# 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 a8524b70c32ccb9cd4d6c786cf60d614dc3cd236..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 300 zcmX}mJxfAi7{>Ac=>yd16C}~@P;()e5WNfyCZX05GaXJ49c(Cqvf)r*BncWtZ@M)k z^Z_bpkDxhnkJ^K-ZkO(7yYGkVcg;^F5+e>Q#FCQ*KZv-1V=sOSValNom%JBvwz7$m zVVhGfX;G!jG{b!9QB9Rq(4z9%R6|et)(~@SaBM%@)Y&D)D8G7DOM5CQEl<9Vbf>QR ziLt@~XO?+RNRbH!dDp!TwXUp|EO}p7dee`_NK)a%GB2nRFl+v&o>kYDC1#Z~zo`fF yBh1*n=iks^$9hMtf6uR|sEn4irmFcL8erVa@ZT?)@6uJr`uUca)~fl}deI;Lb%!?q 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 93556f15c5f8d4c903a3f6dbad4097261d058b42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 300 zcmXZRF(^a<9LMqRV~~Y6NCslKMJbVz!63Z4WMH_v4Dxg-z_!an_R%L>nlM%;ZTN4(og#~ z1)o2a^Q#Je%(p7}QWc-7HZC8k;a#=7sg76G^P+~pvl@9)ghw^=pcd}Uom#n78#ih< z9bBuED|K-hx==Ug>g7xxr{+Xajy1rc201bZ8lt2aMa9_{4NXx{iuJGsO|zyMRyE7A=E<8SWvp|o1Y3qhWyvW=Rtx+C)+2>_ 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;; -- 2.20.1