76 lines
2.4 KiB
Django/Jinja
76 lines
2.4 KiB
Django/Jinja
# Crossfade between tracks,
|
|
# taking the respective volume levels
|
|
# into account in the choice of the
|
|
# transition.
|
|
# @category Source / Track Processing
|
|
# @param ~start_next Crossing duration, if any.
|
|
# @param ~fade_in Fade-in duration, if any.
|
|
# @param ~fade_out Fade-out duration, if any.
|
|
# @param ~width Width of the volume analysis window.
|
|
# @param ~conservative Always prepare for
|
|
# a premature end-of-track.
|
|
# @param s The input source.
|
|
def smart_crossfade (~start_next=5.,~fade_in=3.,
|
|
~fade_out=3., ~width=2.,
|
|
~conservative=false,s)
|
|
high = -20.
|
|
medium = -32.
|
|
margin = 4.
|
|
fade.out = fade.out(type="sin",duration=fade_out)
|
|
fade.in = fade.in(type="sin",duration=fade_in)
|
|
add = fun (a,b) -> add(normalize=false,[b,a])
|
|
log = log(label="smart_crossfade")
|
|
def transition(a,b,ma,mb,sa,sb)
|
|
list.iter(fun(x)->
|
|
log(level=4,"Before: #{x}"),ma)
|
|
list.iter(fun(x)->
|
|
log(level=4,"After : #{x}"),mb)
|
|
if
|
|
# If A and B and not too loud and close,
|
|
# fully cross-fade them.
|
|
a <= medium and
|
|
b <= medium and
|
|
abs(a - b) <= margin
|
|
then
|
|
log("Transition: crossed, fade-in, fade-out.")
|
|
add(fade.out(sa),fade.in(sb))
|
|
elsif
|
|
# If B is significantly louder than A,
|
|
# only fade-out A.
|
|
# We don't want to fade almost silent things,
|
|
# ask for >medium.
|
|
b >= a + margin and a >= medium and b <= high
|
|
then
|
|
log("Transition: crossed, fade-out.")
|
|
add(fade.out(sa),sb)
|
|
elsif
|
|
# Do not fade if it's already very low.
|
|
b >= a + margin and a <= medium and b <= high
|
|
then
|
|
log("Transition: crossed, no fade-out.")
|
|
add(sa,sb)
|
|
elsif
|
|
# Opposite as the previous one.
|
|
a >= b + margin and b >= medium and a <= high
|
|
then
|
|
log("Transition: crossed, fade-in.")
|
|
add(sa,fade.in(sb))
|
|
# What to do with a loud end and
|
|
# a quiet beginning ?
|
|
# A good idea is to use a jingle to separate
|
|
# the two tracks, but that's another story.
|
|
else
|
|
# Otherwise, A and B are just too loud
|
|
# to overlap nicely, or the difference
|
|
# between them is too large and
|
|
# overlapping would completely mask one
|
|
# of them.
|
|
log("No transition: just sequencing.")
|
|
sequence([sa, sb])
|
|
end
|
|
end
|
|
cross(width=width, duration=start_next,
|
|
conservative=conservative,
|
|
transition,s)
|
|
end
|