root/ocaml-remix/trunk/track.ml

Revision 529, 5.2 kB (checked in by shans, 4 years ago)

Replacing sound implementation - WAS ocaml int arrays, IS native float
arrays. This has not yet been completely been debugged!

Line 
1 type tcache_elem = {
2     tce_raw_start: Time.raw_time;
3     tce_start: Time.time;
4     tce_length:Time.time;
5     tce_transparency: Transparency.transparency};;
6
7 type track = {mutable tr_layers :
8                 (Layer.layer * (tcache_elem list * Remix.remix) option) array};;
9
10 let gen_tcache_elem remix (start, length) trans =
11   {tce_raw_start = Time.time_to_raw_time remix start;
12    tce_start = start;
13    tce_length = length;
14    tce_transparency = trans};;
15
16 let regen_tcache track idx remix =
17   let _ttr (extent, trans) = gen_tcache_elem remix extent trans in
18   let _cmp a b = compare a.tce_raw_start b.tce_raw_start in
19   let (layer, _) = track.tr_layers.(idx) in
20     track.tr_layers.(idx) <-
21      (layer, Some (List.sort _cmp
22         (List.map _ttr (Layer.transparency_list layer)), remix))
23
24 let maybe_gen_tcache track idx remix = match track.tr_layers.(idx) with
25   | (_, None) -> regen_tcache track idx remix
26   | (_, Some (_, r)) -> if r != remix then regen_tcache track idx remix
27
28 exception CantStrip;;
29
30 let strip x = match x with
31   | None -> raise CantStrip
32   | Some a -> a;;
33
34 let empty _ = {tr_layers=[||]};;
35
36 let add_layer track layer =
37   track.tr_layers <- Array.append track.tr_layers [|(layer, None)|];;
38
39 exception OutOfBounds;;
40 let apply_transparency sound1 extent1 sound2 extent2 transparency text
41       remix start rext =
42   let raw_sound1 = sound1 remix extent1 rext in
43   let raw_sound2 = sound2 remix extent2 rext in
44   let raw_trans = transparency remix text rext in
45   FB.transparency raw_sound2 raw_sound1 raw_trans;;
46
47 (*
48  * render by transparencies, and gaps between.  Here are our 6 cases:
49  *
50  * 1. render window completely before first transparency:
51  *    <--render-->                   start=render.start   trans=None     DONE
52  *                   <--trans-->     length=render.length
53  *
54  * 2. render window overlaps with first transparency:
55  *   <--render-------...             start=render.start   trans=None     ITER
56  *              <----trans-->        length=trans.start - render.start
57  *
58  * 3. render window starts with transparency and ends before:
59  *  <-----render---->                start=render.start   trans=Trans    DONE
60  *  <--------trans--------->         length=render.length
61  *
62  * 4. render window starts with transparency and ends after:
63  *  <---------render------...        start=render.start   trans=Trans    ITER
64  *  <---trans--->                    length=trans.length
65  *
66  * 5. render window starts after transparency and ends before:
67  *        <--render-->              start=render.start    trans=Trans    DONE
68  *  <--------trans----------->      length=render.length
69  *
70  * 6. render window starts after transparency and ends after:
71  *        <----------render----...  start=render.start    trans=Trans    ITER
72  *  <----trans---->                 length=trans.start+trans.length-render.start
73  *
74  * generalising: start=render.start
75  * trans.end = trans.start+trans.length
76  * render.end = render.start+render.length
77  * case 1,2: length=min(trans.start-render.start, render.length)
78  * case 3,4,5,6: length=min(trans.end, render.end)-start
79  *)
80 let to_note track undersound remix extent (start, length)  =
81   let layers = track.tr_layers in
82   let rec _render_at pos remix extent (start, length) =
83     maybe_gen_tcache track pos remix;
84     let olayer = Layer.empty () in
85     let _add_s_to_out sound raw_start raw_length = Layer.add_note olayer
86                             (Note.from_sound sound)
87                           (Time.Samples raw_start, Time.Samples raw_length) in
88     let (layer, pretrans) = layers.(pos) in
89     let (translist, _) = strip pretrans in
90     let rec _render_at_2 raw_start raw_length l =
91       if raw_length == 0 then () else match l with
92       | [] -> (
93         let sound2 = _render_at (pos + 1) in
94         let sound1 = Layer.to_note layer sound2 in
95         _add_s_to_out sound1 raw_start raw_length
96         (*_add_l_to_out layer raw_start raw_length*)
97       )
98       | elem::r -> (
99           if raw_start < elem.tce_raw_start then (
100             (* case 1,2 *)
101             let diff = min (elem.tce_raw_start - raw_start) raw_length in
102             let sound2 = _render_at (pos + 1) in
103             let sound1 = Layer.to_note layer sound2 in
104             _add_s_to_out sound1 raw_start diff;
105             (* _add_l_to_out layer raw_start diff; *)
106             _render_at_2 elem.tce_raw_start (raw_length - diff) (elem::r)
107           ) else (
108             (* case 3,4,5,6 *)
109             let ext = Time.overlap remix (elem.tce_start, elem.tce_length)
110                         (Time.Samples raw_start, Time.Samples raw_length) in
111             let sound2 = _render_at (pos + 1) in
112             let sound1 = (Layer.to_note layer sound2) in
113             let trans = elem.tce_transparency in
114             let raw_start, l = Time.extent_to_raw_time remix ext in
115             _add_s_to_out (apply_transparency sound1 (fst ext) sound2 (fst ext)
116                 trans (elem.tce_start, elem.tce_length)) raw_start l;
117             _render_at_2 (raw_start + l) (raw_length - l) r
118           )
119         ) in
120     let raw_start = Time.time_to_raw_time remix start in
121     let raw_length = Time.time_to_raw_time remix length in
122     _render_at_2 raw_start raw_length translist;
123     Layer.to_note olayer undersound remix extent (start, length) in
124   _render_at 0 remix extent (start,length);;
125      
126            
Note: See TracBrowser for help on using the browser.