Changeset 502

Show
Ignore:
Timestamp:
09/03/07 17:16:41 (1 year ago)
Author:
shans
Message:

Added ladspa tree implementation and demonstration in ladspa_test. This
is probably not going to be the final abstraction for ladspa.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • ocaml-remix/trunk/Makefile

    r501 r502  
    22 
    33COMPONENTS = remix time volume sound tone wave envelope transparency layer \ 
    4                         track instrument 
     4                        track instrument ladspa 
    55TESTS = sound_test_sin layer_test_sins track_test_sins instrument_test \ 
    66                        ladspa_test 
    77INCLUDES=-I +extlib 
    8 OBJECTS=extLib unix oss 
     8OBJECTS=extLib unix oss ladspa_raw 
    99 
    1010INTERFACES = $(patsubst %, %.mli, $(COMPONENTS)) 
     
    2626remix.cma: $(INTERFACES) $(SOURCES) oss.cma ladspa_raw.cma 
    2727        ocamlc -c $(OCAMLCARGS) $(INTERFACES) $(SOURCES) 
    28         ocamlc -a -g -o remix.cma $(SOURCES) ladspa_raw.cma 
     28        ocamlc -a -g -o remix.cma $(SOURCES) oss.cma ladspa_raw.cma 
    2929 
    30 remix.cmxa: $(INTERFACES) $(SOURCES) oss.cmxa ladspa_raw.cmx 
     30remix.cmxa: $(INTERFACES) $(SOURCES) oss.cmxa ladspa_raw.cmxa 
    3131        ocamlopt -c $(OCAMLOPTARGS) $(INTERFACES) $(SOURCES) 
    32         ocamlopt -a -o remix.cmxa $(SOURCES) ladspa_raw.cmx ladspa_impl.o 
     32        ocamlopt -a -o remix.cmxa $(SOURCES) 
    3333 
    3434oss.cma: oss.mli oss.ml oss_impl.c 
     
    4242                                                        -o ladspa_raw.cma 
    4343 
    44 ladspa_raw.cmx: ladspa_raw.mli ladspa_raw.ml ladspa_impl.c 
     44ladspa_raw.cmxa: ladspa_raw.mli ladspa_raw.ml ladspa_impl.c 
    4545        ocamlopt ladspa_impl.c ladspa_raw.mli ladspa_raw.ml -a \ 
    4646                                                        -o ladspa_raw.cmxa 
  • ocaml-remix/trunk/ladspa.ml

    r500 r502  
    1 type plugin;; 
     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 *) 
     4type mapping = (int * int) list;; 
    25 
    3 type portDirection = Input | Output;; 
    4 type portType = Control | Audio;; 
     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 *) 
     10type tree =  
     11  | Control of float 
     12  | Audio of Sound.sound 
     13  | Plugin of (string * (tree * mapping) list * bool * int list) 
     14  | EmptySlot;; 
    515 
    6 external open_plugin : string -> plugin = "c_ex_ladspa_open";; 
    7 external port_count : plugin -> int = "c_ex_ladspa_port_count";; 
    8 external port_descriptor : plugin -> int -> (portDirection * portType) =  
    9                                               "c_ex_ladspa_port_descriptor";; 
     16exception InvalidChannel;; 
    1017 
    11 let direction_to_string d = match d with 
    12   | Input  -> "Input" 
    13   | Output -> "Output";; 
     18let 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;; 
    1435 
    15 let type_to_string t = match t with 
    16   | Control -> "Control" 
    17   | Audio   -> "Audio";; 
     36let 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, s_l) (r_s, r_l) in 
     45        Ladspa_raw.raw_sound_to_buffers rs channels 
     46      ) 
     47    | Plugin (name, trees, adding, outputs) -> 
     48      ( 
     49        let p = Ladspa_raw.open_plugin name in 
     50        let h = Ladspa_raw.instantiate p (Remix.samplerate remix) in 
     51        let n_channels = Ladspa_raw.port_count p in 
     52        let outs = List.map (fun (a,b) -> _render_tree a, b) trees in 
     53        let lmax2 l = List.fold_right (fun (a,b) m -> max b m) l 0 in 
     54        let omax = (List.fold_right (fun (a,b) m -> max (lmax2 b) m) outs 0) + 1 
     55        in 
     56        let oarray = Array.init omax (perform_mapping outs length_in_samples) in 
     57        Array.iteri  
     58          (fun n b -> if n < n_channels then Ladspa_raw.connect_port p h n b)  
     59          oarray;  
     60        Ladspa_raw.activate p h; 
     61        if adding  
     62        then Ladspa_raw.run_adding p h length_in_samples 
     63        else Ladspa_raw.run p h length_in_samples; 
     64        Array.init (List.length outputs)  
     65          (fun pos -> let o = List.nth outputs pos in oarray.(o))  
     66      ) in 
     67  let result = _render_tree tree in 
     68  Ladspa_raw.buffers_to_raw_sound result length_in_samples;; 
  • ocaml-remix/trunk/ladspa.mli

    r500 r502  
    1 type plugin;; 
     1type mapping = (int * int) list;; 
    22 
    3 type portDirection = Input | Output;; 
    4 type portType = Control | Audio;; 
     3(* a plugin has a list of trees which plug into the input/output slots, and  
     4   an int list which refers to the output slots which the tree represents.  If 
     5   the output slots are not empty, then their trees are rendered and added 
     6   to *) 
     7type tree =  
     8  | Control of float 
     9  | Audio of Sound.sound 
     10  | Plugin of (string * (tree * mapping) list * bool * int list) 
     11  | EmptySlot;; 
    512 
    6 val open_plugin : string -> plugin;; 
    7 val port_count : plugin -> int;; 
    8 val port_descriptor : plugin -> int -> (portDirection * portType);; 
    9  
    10 val direction_to_string : portDirection -> string;; 
    11 val type_to_string : portType -> string;; 
     13val render_tree : tree -> Sound.sound;; 
  • ocaml-remix/trunk/ladspa_impl.c

    r501 r502  
    251251   
    252252  int size = Int_val(ml_size); 
    253   LADSPA_Data *data = malloc(sizeof(LADSPA_Data) * size); 
    254    
     253  LADSPA_Data *data = calloc(sizeof(LADSPA_Data), size); 
     254  
    255255  CAMLlocal1(block); 
    256256  block = alloc(1, Abstract_tag); 
     
    269269   
    270270  int port = Int_val(ml_port); 
    271   
     271 
    272272  ld->connect_port(h, port, data); 
    273273   
  • ocaml-remix/trunk/ladspa_test.ml

    r501 r502  
    2525let s = Ladspa_raw.buffers_to_raw_sound [| b; b |] 44000;; 
    2626Sound.raw_preview r s;;  
     27 
     28let t = Ladspa.Plugin ("noise:noise_white", 
     29        [(Ladspa.Control 1.0, [(0, 0)]); (Ladspa.EmptySlot, [(0, 1)])], 
     30        false, [1; 1]);; 
     31 
     32Sound.preview r (Ladspa.render_tree t) (Time.Seconds 0., Time.Seconds 1.) 
     33  (Time.Seconds 0., Time.Seconds 1.);; 
     34