+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) ->