| 1 |
(* map a set of output buffers from a tree to a set of input ports. Outputs |
|---|
| 2 |
can be ignored and also duplicated. Input ports past the valid port range |
|---|
| 3 |
have buffers copied across directly *) |
|---|
| 4 |
type mapping = (int * int) list;; |
|---|
| 5 |
|
|---|
| 6 |
(* a plugin has a list of trees which plug into the input/output slots, and |
|---|
| 7 |
an int list which refers to the output slots which the tree represents. If |
|---|
| 8 |
the output slots are not empty, then their trees are rendered and added |
|---|
| 9 |
to *) |
|---|
| 10 |
type tree = |
|---|
| 11 |
| Control of float |
|---|
| 12 |
| Audio of Sound.sound |
|---|
| 13 |
| Plugin of (string * (tree * mapping) list * bool * int list) |
|---|
| 14 |
| EmptySlot;; |
|---|
| 15 |
|
|---|
| 16 |
exception InvalidChannel;; |
|---|
| 17 |
|
|---|
| 18 |
let rec perform_mapping arrmaplist len pos = |
|---|
| 19 |
let rec perform_inner_mapping oarray map pos = match map with |
|---|
| 20 |
| (frompos, topos)::rest -> |
|---|
| 21 |
( |
|---|
| 22 |
if topos = pos |
|---|
| 23 |
then Some oarray.(frompos) |
|---|
| 24 |
else perform_inner_mapping oarray rest pos |
|---|
| 25 |
) |
|---|
| 26 |
| [] -> None in |
|---|
| 27 |
match arrmaplist with |
|---|
| 28 |
| (oarray, map)::rest -> |
|---|
| 29 |
( |
|---|
| 30 |
match (perform_inner_mapping oarray map pos) with |
|---|
| 31 |
| Some v -> v |
|---|
| 32 |
| None -> perform_mapping rest len pos |
|---|
| 33 |
) |
|---|
| 34 |
| [] -> Ladspa_raw.empty_buffer len;; |
|---|
| 35 |
|
|---|
| 36 |
let render_tree tree remix (s_s, s_l) (r_s, r_l) = |
|---|
| 37 |
let length_in_samples = Time.time_to_raw_samples remix r_l in |
|---|
| 38 |
let rec _render_tree tree = match tree with |
|---|
| 39 |
| EmptySlot -> [| Ladspa_raw.empty_buffer length_in_samples |] |
|---|
| 40 |
| Control f -> [| Ladspa_raw.control_value_to_buffer f |] |
|---|
| 41 |
| Audio s -> |
|---|
| 42 |
( |
|---|
| 43 |
let channels = Remix.channels remix in |
|---|
| 44 |
let rs = s remix s_s (r_s, r_l) in |
|---|
| 45 |
let len = (Array.length rs) / channels in |
|---|
| 46 |
let out_arr = |
|---|
| 47 |
Array.init channels (fun _ -> Ladspa_raw.empty_buffer len) in |
|---|
| 48 |
Ladspa_raw.raw_sound_to_buffers rs out_arr len; |
|---|
| 49 |
out_arr |
|---|
| 50 |
) |
|---|
| 51 |
| Plugin (name, trees, adding, outputs) -> |
|---|
| 52 |
( |
|---|
| 53 |
let p = Ladspa_raw.open_plugin name in |
|---|
| 54 |
let h = Ladspa_raw.instantiate p (Remix.samplerate remix) in |
|---|
| 55 |
let n_channels = Ladspa_raw.port_count p in |
|---|
| 56 |
let outs = List.map (fun (a,b) -> _render_tree a, b) trees in |
|---|
| 57 |
let lmax2 l = List.fold_right (fun (a,b) m -> max b m) l 0 in |
|---|
| 58 |
let omax = (List.fold_right (fun (a,b) m -> max (lmax2 b) m) outs 0) + 1 |
|---|
| 59 |
in |
|---|
| 60 |
let oarray = Array.init omax (perform_mapping outs length_in_samples) in |
|---|
| 61 |
Array.iteri |
|---|
| 62 |
(fun n b -> if n < n_channels then Ladspa_raw.connect_port p h n b) |
|---|
| 63 |
oarray; |
|---|
| 64 |
Ladspa_raw.activate p h; |
|---|
| 65 |
if adding |
|---|
| 66 |
then Ladspa_raw.run_adding p h length_in_samples |
|---|
| 67 |
else Ladspa_raw.run p h length_in_samples; |
|---|
| 68 |
Array.init (List.length outputs) |
|---|
| 69 |
(fun pos -> let o = List.nth outputs pos in oarray.(o)) |
|---|
| 70 |
) in |
|---|
| 71 |
let result = _render_tree tree in |
|---|
| 72 |
Ladspa_raw.buffers_to_raw_sound result length_in_samples;; |
|---|
| 73 |
|
|---|
| 74 |
(* compiled pipeline approach. What's a compiled ladpsa pipeline look like? |
|---|
| 75 |
* |
|---|
| 76 |
* We'll need a list of input buffers to fill, a list of plugins to run in |
|---|
| 77 |
* order, a list of output buffers to return, and a maximum length in samples. |
|---|
| 78 |
* We'll also need a list of all used buffers for deallocation and cleanup |
|---|
| 79 |
* purposes. |
|---|
| 80 |
*) |
|---|
| 81 |
type compiledPipeline = |
|---|
| 82 |
{ inputs : Ladspa_raw.buffer list; |
|---|
| 83 |
plugins : Ladspa_raw.plugin list; |
|---|
| 84 |
handles : Ladspa_raw.handle list; |
|---|
| 85 |
outputs : Ladspa_raw.buffer list; |
|---|
| 86 |
maxlength : int; |
|---|
| 87 |
samplerate : int option; |
|---|
| 88 |
allbuffers : Ladspa_raw.buffer list |
|---|
| 89 |
};; |
|---|
| 90 |
|
|---|
| 91 |
(*let run_compiled_pipeline pipeline rawsoundlist =*) |
|---|
| 92 |
|
|---|