root/ocaml-remix/trunk/ladspa.ml

Revision 514, 3.5 kB (checked in by shans, 5 years ago)

Modified sounds to only accept start (not length as well). Makes shift and
repeat easier, and makes more sense overall.

Line 
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  
Note: See TracBrowser for help on using the browser.