Implement stdin, stdout and stderr to Faustine.
authorWANG <wang@wang-OptiPlex-780.(none)>
Fri, 27 Sep 2013 13:14:52 +0000 (15:14 +0200)
committerWANG <wang@wang-OptiPlex-780.(none)>
Fri, 27 Sep 2013 13:14:52 +0000 (15:14 +0200)
Tested by examples/sinwave/sin.dsp.

12 files changed:
examples/fft/Makefile
examples/fft/fft.png
examples/fft/sin_1378Hz_0.005_ampli_128samples.wav [deleted file]
examples/fft/sin_16536Hz_0.005_ampli_128samples.wav [deleted file]
examples/fft/sin_2067Hz_0.005_ampli_128samples.wav [deleted file]
examples/fft/sin_22000Hz_0.005_ampli_128samples.wav [deleted file]
examples/fft/sinsum.dsp
interpreter/aux.ml
interpreter/faustio.ml
interpreter/main.ml
interpreter/signal.ml
interpreter/types.ml

index cbe38a6..6d41558 100644 (file)
@@ -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) *~
index 6e8739e..eec0f4b 100644 (file)
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 (file)
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 (file)
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 (file)
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 (file)
index 93556f1..0000000
Binary files a/examples/fft/sin_22000Hz_0.005_ampli_128samples.wav and /dev/null differ
index 0ee1d5b..3299928 100644 (file)
@@ -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;
+
index 7c21a61..5321349 100644 (file)
@@ -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));;
index 7df74a6..47e07ce 100644 (file)
@@ -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) ->
index 54c7f1a..2f102f3 100644 (file)
@@ -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
        ();;
 
index 66089e9..0701ffc 100644 (file)
@@ -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
index 7024eeb..da486f2 100644 (file)
@@ -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;;