Bug fixed for unix error "readlink /proc/self/fd/0" on MacOS.
[Faustine.git] / interpreter / main.ml
1 (**
2 Module: Interpreter
3 Description: Input wave -> interpretation -> output wave
4 @author WANG Haisheng
5 Created: 15/05/2013 Modified: 14/08/2013
6 *)
7
8 open Aux;;
9 open Beam;;
10 open Process;;
11 open Faustio;;
12
13 exception Missing_Expression;;
14
15 let version = "Faustine: 0.0.1";;
16
17 let set_GC () =
18 let _ = Gc.set { (Gc.get())
19 with Gc.minor_heap_size = 0xFFFFFF } in
20 let _ = Gc.set { (Gc.get())
21 with Gc.major_heap_increment = 0xFFFFFF } in
22 let _ = Gc.set { (Gc.get())
23 with Gc.space_overhead = 100 } in
24 let _ = Gc.set { (Gc.get())
25 with Gc.max_overhead = 0xFFF } in
26 let _ = Gc.set { (Gc.get())
27 with Gc.stack_limit = 0xFFFFF } in
28 let _ = Gc.set { (Gc.get())
29 with Gc.allocation_policy = 1 } in
30 () ;;
31
32 let path_dsp = ref "";;
33 let size_input = ref 0;;
34 let inputs = ref [];;
35 let time_max = ref 0xFFFF;;
36 let dir_output = ref "";;
37 let format_output = ref "";;
38 let basename_output = ref "";;
39 let stdout_filename = ref "";;
40
41 let option_usage = "usage: " ^ Sys.argv.(0)
42 ^ " [-f dsp_src] [-i input] [-l length] [--odir dir] [--oformat wav/csv/nst] [--obasename name]";;
43
44 let option_unknown =
45 fun x -> raise (Arg.Bad ("Bad argument : " ^ x))
46
47 let speclist = [
48 ("-f", Arg.String (fun s -> path_dsp := s), ": faust .dsp source file");
49 ("-i", Arg.String (fun s -> incr size_input; inputs := !inputs @ [s]), ": set input file");
50 ("-l", Arg.Int (fun i -> time_max := i), ": maximun number of output samples");
51 ("--odir", Arg.String (fun s -> dir_output := s), ": set output directory");
52 ("--oformat", Arg.String (fun s -> format_output := s), ": set output format wav/csv/nst");
53 ("--obasename", Arg.String (fun s -> basename_output := s), ": set output basename");
54 ];;
55
56 let file_of_path : string -> string =
57 fun (path : string) ->
58 let fragments = Str.split (Str.regexp "/") path in
59 let n = List.length fragments in
60 List.nth fragments (n - 1);;
61
62 let get_extension : string -> string =
63 fun (file : string) ->
64 let fragments = Str.split (Str.regexp "\.") file in
65 let n = List.length fragments in
66 List.nth fragments (n - 1);;
67
68 let chk_extension : string -> bool =
69 fun (file : string) ->
70 let extension = get_extension file in
71 if extension = "csv" || extension = "wav" || extension = "nst" then true
72 else false;;
73
74 let chk_input_path : string -> bool =
75 fun (path : string) ->
76 let file_in = file_of_path path in
77 chk_extension file_in;;
78
79 let stdinput = fun (x : unit) ->
80 let path = Unix.readlink "/dev/fd/0" in
81 if chk_input_path path then
82 ( incr size_input;
83 inputs := !inputs @ [path] )
84 else ();;
85
86 let chk_output_path : string -> bool =
87 fun (path : string) ->
88 let fragments = Str.split (Str.regexp "/") path in
89 let location = List.nth fragments 0 in
90 if location = "dev" then false
91 else true;;
92
93 let stdoutput = fun (x : unit) ->
94 let path = Unix.readlink "/dev/fd/1" in
95 if chk_output_path path then stdout_filename := path
96 else ();;
97
98 let stdio = fun (x : unit) ->
99 stdinput ();
100 stdoutput ();;
101
102 let main () =
103
104 let () = Arg.parse speclist option_unknown option_usage in
105 let () = stdio () in
106 let _ = Sys.signal Sys.sigalrm Sys.Signal_ignore in
107 let _ = set_GC () in
108 let io = new iomanager in
109 let () = io#set !stdout_filename !dir_output !format_output !basename_output in
110
111
112 let () = output_string stderr ("\n Faustine -> Reading input ...") in
113 let tic0 = Unix.time () in
114 let input : beam = io#read !inputs in
115 let toc0 = Unix.time () in
116 let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc0 -. tic0)) ^ "s.)\n") in
117
118
119 let () = output_string stderr (" Faustine -> Preprocessing...") in
120 let tic1 = Unix.time () in
121 let faust_core = Preprocess.preprocess !path_dsp in
122 let toc1 = Unix.time () in
123 let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc1 -. tic1)) ^ "s.)\n") in
124
125
126 let () = output_string stderr (" Faustine -> Constructing process...") in
127 let tic2 = Unix.time () in
128 let faust_exp = exp_of_string faust_core in
129 let proc = (new proc_factory)#make faust_exp in
130 let toc2 = Unix.time () in
131 let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc2 -. tic2)) ^ "s.)\n") in
132
133
134 let () = output_string stderr (" Faustine -> Constructing signals...") in
135 let tic3 = Unix.time () in
136 let output : beam = proc#eval input in
137 let toc3 = Unix.time () in
138 let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc3 -. tic3)) ^ "s.)\n") in
139
140
141 if (!stdout_filename = "" && !format_output = "") || (!format_output = "nst")
142 || (!stdout_filename <> "" && (get_extension !stdout_filename) = "nst") then (
143 let () = output_string stderr (" Faustine -> Evaluating...") in
144 let tic4 = Unix.time () in
145 let raws = output#output_values !time_max in
146 let rates = output#frequency in
147 let toc4 = Unix.time () in
148 let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc4 -. tic4)) ^ "s.)\n") in
149
150
151 let () = output_string stderr (" Faustine -> Writing output...") in
152 let tic5 = Unix.time () in
153 let output_paths = io#write_nst rates raws in
154 let toc5 = Unix.time () in
155 let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc5 -. tic5)) ^ "s.)\n") in
156
157 let _ = Array.map (output_string stderr) (Array.map decorate output_paths) in
158 ()
159 )
160
161 else (
162 let () = output_string stderr (" Faustine -> Evaluating...") in
163 let tic6 = Unix.time () in
164 let data = output#output !time_max in
165 let rates = output#frequency in
166 let toc6 = Unix.time () in
167 let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc6 -. tic6)) ^ "s.)\n") in
168
169
170 let () = output_string stderr (" Faustine -> Writing output...") in
171 let tic7 = Unix.time () in
172 let output_paths = io#write rates data in
173 let toc7 = Unix.time () in
174 let () = output_string stderr (" Done. (duration: " ^ (string_of_float (toc7 -. tic7)) ^ "s.)\n") in
175
176 let _ = Array.map (output_string stderr) (Array.map decorate output_paths) in
177 ()
178 );;
179
180 main();;
181