X-Git-Url: https://scm.cri.minesparis.psl.eu/git/Faustine.git/blobdiff_plain/14e4f8cd6102d273c520c2d2e0168a5221a7daeb..e775f23a10c4ba37fc1a762299f52cd0d71593b7:/interpretor/signal.ml

diff --git a/interpretor/signal.ml b/interpretor/signal.ml
index b8f0e68..00a1709 100644
--- a/interpretor/signal.ml
+++ b/interpretor/signal.ml
@@ -13,8 +13,45 @@ exception Signal_operation of string;;
 
 let delay_memory_length = 10000;;
 
-class signal : int -> (time -> value_type) -> signal_type = 
-  fun (freq_init : int) ->
+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
@@ -22,13 +59,13 @@ class signal : int -> (time -> value_type) -> signal_type =
 	method frequency = freq_init
 	method at = signal_func
 
-	method private check_freq : signal_type list -> int = 
+	method private check_freq : signal_type list -> rate_type = 
 	  fun (sl : signal_type list) ->
-	    let check : int -> signal_type -> int = 
-	      fun (f : int) ->
+	    let check : rate_type -> signal_type -> rate_type = 
+	      fun (f : rate_type) ->
 		fun (s : signal_type) ->
-		  if f = s#frequency || s#frequency = 0 then f
-		  else if f = 0 then s#frequency
+		  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
 
@@ -90,6 +127,8 @@ class signal : int -> (time -> value_type) -> signal_type =
 	method _mod = self#prim2 (fun t -> (self#at t)#_mod)
 	method larger = self#prim2 (fun t -> (self#at t)#larger)
 	method smaller = self#prim2 (fun t -> (self#at t)#smaller)
+	method max = self#prim2 (fun t -> (self#at t)#max)
+	method min = self#prim2 (fun t -> (self#at t)#min)
 
 	method delay : signal_type -> signal_type =
 	  fun (s : signal_type) ->
@@ -98,13 +137,13 @@ class signal : int -> (time -> value_type) -> signal_type =
 	    let func : time -> value_type = 
 	      fun (t : time) ->
 		let i = (s#at t)#to_int in
-		self#delay_by t i  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 t 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 = 
@@ -141,10 +180,11 @@ class signal : int -> (time -> value_type) -> signal_type =
 		    
 	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
+		  else if t > 0 then self#at (t - 1) 
 		  else raise (Signal_operation "prefix time < 0.") in
 	      new signal self#frequency func
 
@@ -155,7 +195,7 @@ class signal : int -> (time -> value_type) -> signal_type =
 	    if size <= 0 then      
 	      raise (Signal_operation "Vectorize: size <= 0.")
 	    else 
-	      let freq = self#frequency / size in
+	      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
@@ -168,7 +208,7 @@ class signal : int -> (time -> value_type) -> signal_type =
 	    match (self#at 0)#get with
 	    | Vec vec -> vec#size
 	    | _ -> raise (Signal_operation "Serialize: scalar input.") in
-	  let freq = self#frequency * size in
+	  let freq = self#frequency#mul size in
 	  let func : time -> value_type = 
 	    fun t -> 
 	      match (self#at (t/size))#get with