]> CRI, Mines Paris - PSL - Faustine.git/blobdiff - interpreter/signal.ml
Rename interpretor to interpreter.
[Faustine.git] / interpreter / signal.ml
diff --git a/interpreter/signal.ml b/interpreter/signal.ml
new file mode 100644 (file)
index 0000000..66089e9
--- /dev/null
@@ -0,0 +1,289 @@
+(**
+       Module: Signal  
+       Description: signal definition and operations.
+       @author WANG Haisheng   
+       Created: 03/06/2013     Modified: 03/06/2013
+*)
+
+open Types;;
+open Basic;;
+open Value;;
+
+exception Signal_operation of string;;
+
+let delay_memory_length = 10000;;
+
+class rate : int -> int -> rate_type = 
+  fun (num_init : int) ->
+    fun (denom_init : int) ->
+      let rec pgcd : int -> int -> int = 
+       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
+      object (self)
+       val _num = num_corrected
+       val _denom = denom_corrected
+       method num = _num
+       method denom = _denom
+       method to_int = 
+         self#num / self#denom
+       method to_float = 
+         (float_of_int self#num) /. (float_of_int self#denom)
+       method to_string = 
+         (string_of_int self#num) ^ "/" ^ (string_of_int self#denom)
+       method equal : rate_type -> bool = 
+         fun (r : rate_type) -> (self#num = r#num) && (self#denom = r#denom)
+       method mul : int -> rate_type = 
+         fun (i : int) -> new rate (self#num * i) self#denom
+       method div : int -> rate_type = 
+         fun (i : int) -> new rate self#num (self#denom * i)
+      end
+         
+
+class signal : rate_type -> (time -> value_type) -> signal_type = 
+  fun (freq_init : rate_type) ->
+    fun (func_init : time -> value_type) ->
+      object (self)
+       val mutable signal_func = func_init
+       val mutable memory_length = 0
+       method frequency = freq_init
+       method at = signal_func
+
+       method private check_freq : signal_type list -> rate_type = 
+         fun (sl : signal_type list) ->
+           let check : rate_type -> signal_type -> rate_type = 
+             fun (f : rate_type) ->
+               fun (s : signal_type) ->
+                 if f#equal s#frequency || s#frequency#num = 0 then f
+                 else if f#num = 0 then s#frequency
+                 else raise (Signal_operation "frequency not matched.") in
+           List.fold_left check self#frequency sl
+
+       method add_memory : int -> unit = 
+         fun (length : int) ->
+           assert (length >= 0);
+           if memory_length >= length then ()
+           else
+             let memory = Hashtbl.create length in
+             let func : time -> value = 
+               fun (t : time) ->
+                 try Hashtbl.find memory t
+                 with Not_found ->
+                   let result = func_init t in
+                   let () = Hashtbl.replace memory t result in
+                   let () = 
+                     if (t - length) >= 0 then
+                       Hashtbl.remove memory (t - length)
+                     else () in
+                   result in
+             memory_length <- length;
+             signal_func <- func
+
+       method private delay_by : int -> time -> value = 
+         fun i -> fun t ->
+           if (t - i) >= 0 then
+             self#at (t - i)
+           else if t >= 0 && (t - i) < 0 then
+             (self#at 0)#zero
+           else raise (Signal_operation "Delay time < 0.")
+
+       method private prim1 : 
+           (time -> value_type) -> signal_type = 
+             fun (func : time -> value_type) ->
+               let freq = self#frequency in
+               new signal freq func 
+
+       method private prim2 : 
+           (time -> value_type -> value_type) -> signal_type -> signal_type = 
+         fun (func_binary : time -> value_type -> value_type) ->
+           fun (s : signal_type) ->
+             let freq = self#check_freq [s] in
+             let func = fun t -> (func_binary t) (s#at t) in
+             new signal freq func
+
+       method neg = self#prim1 (fun t -> (self#at t)#neg)
+       method floor = self#prim1 (fun t -> (self#at t)#floor)
+       method ceil = self#prim1 (fun t -> (self#at t)#ceil)
+       method rint = self#prim1 (fun t -> (self#at t)#rint)
+       method sin = self#prim1 (fun t -> (self#at t)#sin)
+       method asin = self#prim1 (fun t -> (self#at t)#asin)
+       method cos = self#prim1 (fun t -> (self#at t)#cos)
+       method acos = self#prim1 (fun t -> (self#at t)#acos)
+       method tan = self#prim1 (fun t -> (self#at t)#tan)
+       method atan = self#prim1 (fun t -> (self#at t)#atan)
+       method exp = self#prim1 (fun t -> (self#at t)#exp)
+       method sqrt = self#prim1 (fun t -> (self#at t)#sqrt)
+       method ln = self#prim1 (fun t -> (self#at t)#ln)
+       method lg = self#prim1 (fun t -> (self#at t)#lg)
+       method int = self#prim1 (fun t -> (self#at t)#int)
+       method float = self#prim1 (fun t -> (self#at t)#float)
+       method abs = self#prim1 (fun t -> (self#at t)#abs)
+
+       method add = self#prim2 (fun t -> (self#at t)#add)
+       method sub = self#prim2 (fun t -> (self#at t)#sub)
+       method mul = self#prim2 (fun t -> (self#at t)#mul)
+       method div = self#prim2 (fun t -> (self#at t)#div)
+       method power = self#prim2 (fun t -> (self#at t)#power)
+       method _and = self#prim2 (fun t -> (self#at t)#_and)
+       method _or = self#prim2 (fun t -> (self#at t)#_or)
+       method _xor = self#prim2 (fun t -> (self#at t)#_xor)
+       method atan2 = self#prim2 (fun t -> (self#at t)#atan2)
+       method _mod = self#prim2 (fun t -> (self#at t)#_mod)
+       method fmod = self#prim2 (fun t -> (self#at t)#fmod)
+       method remainder = self#prim2 (fun t -> (self#at t)#remainder)
+       method gt = self#prim2 (fun t -> (self#at t)#gt)
+       method lt = self#prim2 (fun t -> (self#at t)#lt)
+       method geq = self#prim2 (fun t -> (self#at t)#geq)
+       method leq = self#prim2 (fun t -> (self#at t)#leq)
+       method eq = self#prim2 (fun t -> (self#at t)#eq)
+       method neq = self#prim2 (fun t -> (self#at t)#neq)
+       method max = self#prim2 (fun t -> (self#at t)#max)
+       method min = self#prim2 (fun t -> (self#at t)#min)
+       method shl = self#prim2 (fun t -> (self#at t)#shl)
+       method shr = self#prim2 (fun t -> (self#at t)#shr)
+
+       method delay : signal_type -> signal_type =
+         fun (s : signal_type) ->
+           let freq = self#check_freq [s] in
+           let () = self#add_memory delay_memory_length in
+           let func : time -> value_type = 
+             fun (t : time) ->
+               let i = (s#at t)#to_int in
+               self#delay_by i t  in
+           new signal freq func
+
+       method mem : signal_type = 
+         let freq = self#frequency in
+         let () = self#add_memory 1 in
+         let func = fun (t : time) -> self#delay_by 1 t in
+         new signal freq func
+
+       method rdtable : signal_type -> signal_type -> signal_type = 
+         fun (s_size : signal_type) ->
+           fun (s_index : signal_type) ->
+             let freq = self#check_freq [s_index] in
+             let () = self#add_memory ((s_size#at 0)#to_int) in
+             let func : time -> value_type = fun t -> 
+               self#at ((s_index#at t)#to_int) in
+             new signal freq func
+
+       method rwtable : signal_type -> signal_type -> 
+         signal_type -> signal_type -> signal_type = 
+           fun init -> fun wstream -> fun windex -> fun rindex ->
+             let freq = self#check_freq [init; wstream; windex; rindex] in
+             let () = init#add_memory ((self#at 0)#to_int) in
+             let () = wstream#add_memory ((self#at 0)#to_int) in
+             let func : time -> value_type = fun (ti : time) -> 
+               let rec table : time -> index -> value_type = 
+                 fun t -> fun i -> 
+                   if t > 0 then
+                     (if i = (windex#at t)#to_int then (wstream#at t)
+                     else table (t - 1) i)
+                   else if t = 0 then
+                     (if i = (windex#at 0)#to_int then (wstream#at 0)
+                     else init#at i)
+                   else raise (Signal_operation "signal time should be > 0") in
+               table ti ((rindex#at ti)#to_int) in
+             new signal freq func
+
+       method select2 : signal_type -> signal_type -> signal_type =
+         fun s_first -> 
+           fun s_second ->
+             let freq = self#check_freq [s_first; s_second] in
+             let func : time -> value_type = 
+               fun t -> let i = (self#at t)#to_int in
+               if i = 0 then s_first#at t
+               else if i = 1 then s_second#at t
+               else raise (Signal_operation "select2 index 0|1.") in
+             new signal freq func
+
+       method select3 : 
+           signal_type -> signal_type -> signal_type -> signal_type =
+             fun s_first -> fun s_second -> fun s_third ->
+               let freq = self#check_freq [s_first; s_second; s_third] in
+               let func : time -> value_type = 
+                 fun t -> let i = (self#at t)#to_int in
+                 if i = 0 then s_first#at t
+                 else if i = 1 then s_second#at t
+                 else if i = 2 then s_third#at t
+                 else raise (Signal_operation "select2 index 0|1.") in
+               new signal freq func    
+                   
+       method prefix : signal_type -> signal_type =
+           fun (s_init : signal_type) ->
+             let () = self#add_memory 1 in
+             let func : time -> value_type = 
+               fun t ->
+                 if t = 0 then s_init#at 0
+                 else if t > 0 then self#at (t - 1) 
+                 else raise (Signal_operation "prefix time < 0.") in
+             new signal self#frequency func
+
+
+       method vectorize : signal_type -> signal_type =
+         fun s_size ->
+           let size = (s_size#at 0)#to_int in
+           if size <= 0 then      
+             raise (Signal_operation "Vectorize: size <= 0.")
+           else 
+             let freq = self#frequency#div size in
+             let func : time -> value_type = 
+               fun t ->
+                 let vec = fun i -> (self#at (size * t + i))#get in
+                 new value (Vec (new vector size vec)) in
+             new signal freq func
+
+
+       method serialize : signal_type = 
+         let size = 
+           match (self#at 0)#get with
+           | Vec vec -> vec#size
+           | _ -> raise (Signal_operation "Serialize: scalar input.") in
+         let freq = self#frequency#mul size in
+         let func : time -> value_type = 
+           fun t -> 
+             match (self#at (t/size))#get with
+             | Vec vec -> new value (vec#nth (t mod size))
+             | _ -> raise (Signal_operation 
+                             "Serialize: signal type not consistent.") in
+         new signal freq func
+
+       method vconcat : signal_type -> signal_type = 
+         fun s ->
+           let freq = self#check_freq [s] in
+           let func : time -> value_type = 
+             fun t ->
+               match ((self#at t)#get, (s#at t)#get) with
+               | (Vec vec1, Vec vec2) ->
+                   let size1 = vec1#size in
+                   let size2 = vec2#size in
+                   let size = size1 + size2 in
+                   let vec = fun i -> 
+                     if i < size1 then vec1#nth i
+                     else vec2#nth (i - size1) in
+                   new value (Vec (new vector size vec))
+               | _ -> raise (Signal_operation "Vconcat: scalar.") in
+           new signal freq func
+
+       method vpick : signal_type -> signal_type = 
+         fun s_index ->
+           let freq = self#check_freq [s_index] in
+           let func : time -> value_type = 
+             fun t -> 
+               let i = (s_index#at t)#to_int in
+               match (self#at t)#get with
+               | Vec vec -> new value (vec#nth i)
+               | _ -> raise (Signal_operation "Vpick: scalar.") in
+           new signal freq func
+
+      end;;