transpose (Array.sub container 0 !index)
| _ -> raise x
- method frequency : int array =
- let each_rate : signal -> int =
+ method frequency : rate_type array =
+ let each_rate : signal -> rate =
fun (s : signal) ->
let rate = s#frequency in
- if rate > 0 then rate
- else if rate = 0 then 44100
+ if rate#num > 0 then rate
+ else if rate#num = 0 then new rate 44100 1
else raise (Beam_matching "frequency error.") in
Array.map each_rate self#get
_basename <- basename; _dir <- dir
method virtual read : string array -> beam
- method virtual write : int array -> float array array array -> string array
+ method virtual write : rate array -> float array array array -> string array
method private concat : float array array array -> float array array =
fun (origin : float array array array) ->
let files = Array.map Sndfile.openfile paths in
let frames = Array.map Int64.to_int
(Array.map Sndfile.frames files) in
- let rates = Array.map Sndfile.samplerate files in
+ let make_rate =
+ fun (denom : int) ->
+ fun (num : int) ->
+ new rate num denom in
+ let nums = Array.map Sndfile.samplerate files in
+ let rates = Array.map (make_rate 1) nums in
let create_container = fun l -> Array.create l 1. in
let containers = Array.map create_container frames in
let _ = array_map2 Sndfile.read files containers in
array_map2 (new signal) rates (Array.map stream2func containers) in
new beam signals
- method write : int array -> float array array array -> string array =
- fun (rates : int array) ->
+ method write : rate array -> float array array array -> string array =
+ fun (rates : rate array) ->
fun (output : float array array array) ->
let n = Array.length output in
let paths = Array.init n (fun i ->
_dir ^ _basename ^ (string_of_int (i + 1)) ^ ".wav") in
+ let get_freq = fun (r : rate) -> r#to_int in
+ let freqs = Array.map get_freq rates in
let files =
let channels = self#channels output in
let file_format = Sndfile.format
Sndfile.MAJOR_WAV Sndfile.MINOR_PCM_16 in
- let openwr = fun path -> fun channel -> fun rate ->
- Sndfile.openfile ~info:(Sndfile.RDWR, file_format, channel, rate) path in
- array_map3 openwr paths channels rates in
+ let openwr = fun path -> fun channel -> fun freq ->
+ Sndfile.openfile ~info:(Sndfile.RDWR, file_format, channel, freq) path in
+ array_map3 openwr paths channels freqs in
let data = self#concat output in
let _ = array_map2 Sndfile.write files data in
let values =
let convertor = new value Zero in
Array.map (convertor#of_float_array) data in
- new signal 0 (Array.get values)
+ new signal (new rate 0 1) (Array.get values)
method read : string array -> beam =
fun (paths : string array) ->
let signals = Array.map self#csvread files in
new beam signals
- method write : int array -> float array array array -> string array =
- fun (rates : int array) ->
+ method write : rate array -> float array array array -> string array =
+ fun (rates : rate array) ->
fun (data : float array array array) ->
let paths =
let n = Array.length data in
wave#set _dir _basename;
csv#set _dir _basename
- method write : int array -> float array array array -> string array =
- fun (rates : int array) ->
+ method write : rate array -> float array array array -> string array =
+ fun (rates : rate array) ->
fun (data : float array array array) ->
if _format = "" then
raise (Invalid_argument "output format unset.")
method eval : beam_type -> beam_type =
fun (input : beam_type) ->
if input#get = [||] then
- new beam [| new signal 0 (fun t -> new value self#const)|]
+ new beam [| new signal (new rate 0 1)
+ (fun t -> new value self#const)|]
else
raise (Process_error "proc_const accepts no input.")
end;;
method eval : beam_type -> beam_type =
fun (input : beam_type) ->
let memory = Hashtbl.create self#delay in
- let rates = ref (Array.make self#dim#output 0) in
+ let rates = ref (Array.make self#dim#output (new rate 0 1)) in
let split : (time -> value_type array) -> (time -> value_type) array =
fun beam_at ->
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
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
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
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
object
method to_int : int
method to_float : float
+ method to_string : string
+ method num : int
+ method denom : int
method equal : rate_type -> bool
method mul : int -> rate_type
method div : int -> rate_type
class type signal_type =
object
- method frequency : int
+ method frequency : rate_type
method at : time -> value_type
method add_memory : int -> unit
method add : signal_type -> signal_type
method matching : int -> beam_type
method at : time -> value_type array
method output : int -> float array array array
- method frequency : int array
+ method frequency : rate_type array
end;;
object
method set : string -> string -> unit
method read : string array -> beam_type
- method write : int array -> float array array array -> string array
+ method write : rate_type array -> float array array array -> string array
end;;