X-Git-Url: https://svn.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/440ca0ba93966e89b68dc54207c461afc0d56264..f1f94803668061f90a5ce88bf06ee72bba8e41a5:/interpretor/signal.ml diff --git a/interpretor/signal.ml b/interpretor/signal.ml index b493b6c..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,17 +59,17 @@ 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 - method private add_memory : int -> unit = + method add_memory : int -> unit = fun (length : int) -> assert (length >= 0); if memory_length >= length then () @@ -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