Skip to content

Commit 54874c2

Browse files
authored
Add crossfade delay, tests and plot cababilities. (#3703)
1 parent a6da6e1 commit 54874c2

File tree

9 files changed

+1151
-178
lines changed

9 files changed

+1151
-178
lines changed

src/core/sources/blank.ml

+21-10
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,37 @@ open Mm
2424
open Source
2525

2626
class blank duration =
27-
let ticks = if duration < 0. then -1 else Frame.main_of_seconds duration in
27+
let ticks () =
28+
let d = duration () in
29+
if d < 0. then -1 else Frame.main_of_seconds d
30+
in
2831
object (self)
2932
inherit source ~name:"blank" ()
3033

3134
(** Remaining time, -1 for infinity. *)
32-
val mutable remaining = ticks
35+
val mutable remaining = None
36+
37+
method remaining =
38+
match remaining with
39+
| Some r -> r
40+
| None ->
41+
let r = ticks () in
42+
remaining <- Some r;
43+
r
3344

34-
method remaining = remaining
3545
method stype = `Infallible
3646
method private _is_ready ?frame:_ _ = true
3747
method self_sync = (`Static, false)
3848
method! seek x = x
3949
method seek_source = (self :> Source.source)
40-
method abort_track = remaining <- 0
50+
method abort_track = remaining <- Some 0
4151

4252
method get_frame ab =
4353
let position = Frame.position ab in
54+
let rem = self#remaining in
4455
let length =
45-
if remaining < 0 then Lazy.force Frame.size - position
46-
else min remaining (Lazy.force Frame.size - position)
56+
if rem < 0 then Lazy.force Frame.size - position
57+
else min rem (Lazy.force Frame.size - position)
4758
in
4859
let audio_pos = Frame.audio_of_main position in
4960
let audio_len = Frame.audio_of_main length in
@@ -73,8 +84,8 @@ class blank duration =
7384
self#content_type;
7485

7586
Frame.add_break ab (position + length);
76-
if Frame.is_partial ab then remaining <- ticks
77-
else if remaining > 0 then remaining <- remaining - length
87+
if Frame.is_partial ab then remaining <- None
88+
else if rem > 0 then remaining <- Some (rem - length)
7889
end
7990

8091
let blank =
@@ -83,12 +94,12 @@ let blank =
8394
~descr:"Produce silence and blank images." ~return_t
8495
[
8596
( "duration",
86-
Lang.float_t,
97+
Lang.getter_t Lang.float_t,
8798
Some (Lang.float (-1.)),
8899
Some
89100
"Duration of blank tracks in seconds, Negative value means forever."
90101
);
91102
]
92103
(fun p ->
93-
let d = Lang.to_float (List.assoc "duration" p) in
104+
let d = Lang.to_float_getter (List.assoc "duration" p) in
94105
(new blank d :> source))

src/libs/extra/fades.liq

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Plot the first crossfade transition. Used for visualizing and testing
2+
# crossfade transitions.
3+
# @flag extra
4+
def cross.plot(~png=null(), ~dir=null(), s) =
5+
dir =
6+
if
7+
null.defined(dir)
8+
then
9+
null.get(dir)
10+
else
11+
dir = file.temp_dir("plot")
12+
on_cleanup({file.rmdir(dir)})
13+
dir
14+
end
15+
16+
old_txt = path.concat(dir, "old.txt")
17+
new_txt = path.concat(dir, "new.txt")
18+
19+
def gnuplot_cmd(filename) =
20+
'set term png; set output "#{filename}"; plot "#{new_txt}" using 1:2 with \
21+
lines title "new track", "#{old_txt}" using 1:2 with lines title "old \
22+
track"'
23+
end
24+
25+
def store_rms(~id, s) =
26+
s = rms(duration=settings.frame.duration(), s)
27+
t0 = ref(null())
28+
29+
source.on_frame(
30+
s,
31+
{
32+
let t0 =
33+
if
34+
null.defined(t0())
35+
then
36+
null.get(t0())
37+
else
38+
t0 := source.time(s)
39+
null.get(t0())
40+
end
41+
let v = s.rms()
42+
let p = source.time(s) - t0
43+
fname = id == "old" ? old_txt : new_txt
44+
file.write(append=true, data="#{p}\t#{v}\n", fname)
45+
}
46+
)
47+
end
48+
49+
plotted = ref(false)
50+
51+
def transition(old, new) =
52+
old = store_rms(id="old", fade.out(old.source))
53+
new = store_rms(id="new", fade.in(new.source))
54+
55+
s = blank(duration=0.1)
56+
s =
57+
source.on_frame(
58+
s,
59+
{
60+
if
61+
null.defined(png) and not plotted()
62+
then
63+
ignore(
64+
process.run(
65+
"gnuplot -e #{process.quote(gnuplot_cmd(null.get(png)))}"
66+
)
67+
)
68+
end
69+
plotted := true
70+
}
71+
)
72+
73+
sequence(merge=true, [add(normalize=false, [new, old]), s])
74+
end
75+
76+
cross(transition, s)
77+
end

0 commit comments

Comments
 (0)