Commit 66118d6e authored by Pierre Donat-Bouillud's avatar Pierre Donat-Bouillud

Adding map2

parent 07506009
......@@ -48,6 +48,7 @@ module type AUDIOSTREAM = sig
val make : defdomain -> (timestamp * Buffer.buffer) list -> stream
val make_f : defdomain -> streamfunction -> stream
val make_samplestream : defdomain -> float list -> stream
val make_bufferstream : defdomain -> Buffer.buffer list -> stream
val make_singleton : timestamp -> Buffer.buffer -> stream
val make_sample_periodic : int -> Buffer.period -> int -> float -> stream
val emptystream : stream
......@@ -61,9 +62,11 @@ module type AUDIOSTREAM = sig
val next : stream -> timestamp -> timestamp
val length : stream -> int
val prec : stream -> timestamp -> defdomain
val succ : stream -> timestamp -> defdomain
val concat : stream -> stream -> stream
val at : stream -> int -> timestamp
val substream : stream -> timestamp -> timestamp -> stream
val buffers : stream -> Buffer.buffer list
val unbufferize : timestamp -> Buffer.buffer -> stream
val phi : stream -> stream
......@@ -91,6 +94,10 @@ module AudioStream : AUDIOSTREAM = struct
(* Combine will raise if the two argument lists have different sizes *)
make defdomain (List.combine defdomain samplebuffers )
let make_bufferstream defdomain buffers =
assert (List.length defdomain = List.length buffers);
make defdomain (List.combine defdomain buffers)
let make_singleton (timestamp : timestamp) (buffer : Buffer.buffer) =
([timestamp], function (t : timestamp)-> buffer)
......@@ -165,6 +172,8 @@ module AudioStream : AUDIOSTREAM = struct
let new_defdomain = List.take_while (fun t' -> t' <= t2) (List.drop_while (fun t' -> t' >= t1) (dom s)) in
make_f new_defdomain (streamfunc s)
let buffers s = List.map (fun t -> (streamfunc s) t) (dom s)
(** Generates a stream from a timestampd and a buffer, where each sample in the buffer becomes an element in the stream *)
let unbufferize t b =
let latency = Buffer.latency b in
......
(** Stream operators *)
(* We will functorize that later... *)
open Audiostream
module type STREAMOPERATOR = sig
type operator = Buffer.buffer -> Buffer.buffer
type toperator = Buffer.buffer list -> Buffer.buffer list
type poperator = Buffer.buffer -> Buffer.buffer -> Buffer.buffer list
val map : AudioStream.stream -> operator -> AudioStream.stream
(** transforms a pair of streams into a list of streams *)
val map2 : AudioStream.stream * AudioStream.stream -> poperator -> AudioStream.stream list
end
module StreamOperator : STREAMOPERATOR = struct
type operator = Buffer.buffer -> Buffer.buffer
type toperator = Buffer.buffer list -> Buffer.buffer list
type poperator = Buffer.buffer -> Buffer.buffer -> Buffer.buffer list
let map s op = AudioStream.make_bufferstream (AudioStream.dom s) (List.map op (AudioStream.buffers s))
let map2 streams op =
let s1,s2 = streams in
let dom1 = AudioStream.dom s1 in
let dom2 = AudioStream.dom s2 in
(* It operates similarly to a merge operation between two lists, but keeping only the common timestamps. Return a domain and list of buffers. *)
let rec aux d1 d2 =
if not (AudioStream.is_empty s1) && not (AudioStream.is_empty s2) then
begin
let t1 = AudioStream.first d1 in
let t2 = AudioStream.first d2 in
if t1 = t2 then (t1, op ((AudioStream.streamfunc s1) t1) ((AudioStream.streamfunc s2) t2))::
(aux (AudioStream.succ s1 (AudioStream.next s1 t1)) (AudioStream.succ s2 (AudioStream.next s2 t1)))
else if t1 < t2 then aux (AudioStream.succ s1 (AudioStream.next s1 t1)) d2
else aux d1 (AudioStream.succ s2 (AudioStream.next s2 t1))
end
else (* There cannot be matching timestamps so we just stop iterating *)
([], [])
in
(* Get a list of list of buffers. We need to transform it into a list of streams *)
let domain, values = aux dom1 dom2 in
let values = Utils.reshape values in
List.map (AudioStream.make_bufferstream domain) values
end
\ No newline at end of file
......@@ -5,4 +5,16 @@ open Batteries
let extend l n e =
let len = List.length l in
l @ (if List.length l < n then (List.make (n - len ) e )
else [] )
\ No newline at end of file
else [] )
(** Transforms a list of list into a list of list, exchanging the dimensions. *)
let reshape = function
| [] -> []
| s::l ->
let nb_lists = List.length s in
let rec aux = function
| [] -> List.make nb_lists []
| s::l -> let tailLists = aux l in
List.map2 (fun bigList elem -> elem::bigList) tailLists s
in
aux (s::l)
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment