liquidsoap-prettier 1.8.2 → 1.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/check-formatting.yml +32 -0
- package/README.md +31 -5
- package/package.json +1 -1
- package/src/cli.js +104 -9
- package/tests/liq/audio.liq +460 -0
- package/tests/liq/autocue.liq +1081 -0
- package/tests/liq/clock.liq +14 -0
- package/tests/liq/cron.liq +74 -0
- package/tests/liq/error.liq +48 -0
- package/tests/liq/extra/audio.liq +677 -0
- package/tests/liq/extra/audioscrobbler.liq +482 -0
- package/tests/liq/extra/deprecations.liq +976 -0
- package/tests/liq/extra/externals.liq +196 -0
- package/tests/liq/extra/fades.liq +260 -0
- package/tests/liq/extra/file.liq +66 -0
- package/tests/liq/extra/http.liq +160 -0
- package/tests/liq/extra/interactive.liq +917 -0
- package/tests/liq/extra/metadata.liq +75 -0
- package/tests/liq/extra/native.liq +201 -0
- package/tests/liq/extra/openai.liq +150 -0
- package/tests/liq/extra/server.liq +177 -0
- package/tests/liq/extra/source.liq +476 -0
- package/tests/liq/extra/spinitron.liq +272 -0
- package/tests/liq/extra/telnet.liq +266 -0
- package/tests/liq/extra/video.liq +59 -0
- package/tests/liq/extra/visualization.liq +68 -0
- package/tests/liq/fades.liq +941 -0
- package/tests/liq/ffmpeg.liq +605 -0
- package/tests/liq/file.liq +387 -0
- package/tests/liq/getter.liq +74 -0
- package/tests/liq/hls.liq +329 -0
- package/tests/liq/http.liq +1048 -0
- package/tests/liq/http_codes.liq +447 -0
- package/tests/liq/icecast.liq +58 -0
- package/tests/liq/io.liq +106 -0
- package/tests/liq/liquidsoap.liq +31 -0
- package/tests/liq/list.liq +440 -0
- package/tests/liq/log.liq +47 -0
- package/tests/liq/lufs.liq +295 -0
- package/tests/liq/math.liq +23 -0
- package/tests/liq/medialib.liq +752 -0
- package/tests/liq/metadata.liq +253 -0
- package/tests/liq/nfo.liq +258 -0
- package/tests/liq/null.liq +71 -0
- package/tests/liq/playlist.liq +1347 -0
- package/tests/liq/predicate.liq +106 -0
- package/tests/liq/process.liq +93 -0
- package/tests/liq/profiler.liq +5 -0
- package/tests/liq/protocols.liq +1139 -0
- package/tests/liq/ref.liq +28 -0
- package/tests/liq/replaygain.liq +135 -0
- package/tests/liq/request.liq +467 -0
- package/tests/liq/resolvers.liq +33 -0
- package/tests/liq/runtime.liq +70 -0
- package/tests/liq/server.liq +99 -0
- package/tests/liq/settings.liq +41 -0
- package/tests/liq/socket.liq +33 -0
- package/tests/liq/source.liq +362 -0
- package/tests/liq/sqlite.liq +161 -0
- package/tests/liq/stdlib.liq +172 -0
- package/tests/liq/string.liq +476 -0
- package/tests/liq/switches.liq +197 -0
- package/tests/liq/testing.liq +37 -0
- package/tests/liq/thread.liq +161 -0
- package/tests/liq/tracks.liq +100 -0
- package/tests/liq/utils.liq +81 -0
- package/tests/liq/video.liq +918 -0
|
@@ -0,0 +1,941 @@
|
|
|
1
|
+
fade = ()
|
|
2
|
+
|
|
3
|
+
let settings.fade =
|
|
4
|
+
settings.make.void(
|
|
5
|
+
"Settings for the fade in/out operators"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
let settings.fade.in =
|
|
9
|
+
settings.make.void(
|
|
10
|
+
"Settings for fade.in operators"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
let settings.fade.in.duration =
|
|
14
|
+
settings.make(
|
|
15
|
+
description="Default fade.in duration",
|
|
16
|
+
3.
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
let settings.fade.in.type =
|
|
20
|
+
settings.make(
|
|
21
|
+
description="Default fade.in type",
|
|
22
|
+
"lin"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
let settings.fade.in.curve =
|
|
26
|
+
settings.make(
|
|
27
|
+
description="Default fade.in curve",
|
|
28
|
+
10.
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
let settings.fade.out =
|
|
32
|
+
settings.make.void(
|
|
33
|
+
"Settings for fade.out operators"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
let settings.fade.out.duration =
|
|
37
|
+
settings.make(
|
|
38
|
+
description="Default fade.out duration",
|
|
39
|
+
3.
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
let settings.fade.out.type =
|
|
43
|
+
settings.make(
|
|
44
|
+
description="Default fade.out type",
|
|
45
|
+
"lin"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
let settings.fade.out.curve =
|
|
49
|
+
settings.make(
|
|
50
|
+
description="Default fade.out curve",
|
|
51
|
+
10.
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# Make a fade function based on a source's clock.
|
|
55
|
+
# @category Source / Fade
|
|
56
|
+
# @param ~curve Fade curve for `"log"` and `"exp"` shapes. If `null`, depends on the type of fade. \
|
|
57
|
+
# The higher the value, the shaper the curve.
|
|
58
|
+
# @param ~type Fade shape. One of: `"sin"`, `"exp"`, `"log"`, `"lin"`
|
|
59
|
+
# @param ~start Start value.
|
|
60
|
+
# @param ~stop Stop value.
|
|
61
|
+
# @param ~delay Initial delay before starting fade.
|
|
62
|
+
# @param ~duration Duration in seconds.
|
|
63
|
+
# @param ~on_done Function to execute when the fade is finished
|
|
64
|
+
def mkfade(
|
|
65
|
+
~curve=null,
|
|
66
|
+
~type="lin",
|
|
67
|
+
~start=0.,
|
|
68
|
+
~stop=1.,
|
|
69
|
+
~delay=0.,
|
|
70
|
+
~duration=3.,
|
|
71
|
+
~on_done={()},
|
|
72
|
+
s
|
|
73
|
+
) =
|
|
74
|
+
def log(x) =
|
|
75
|
+
log(label="mkfade", x)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Shape functions must map 0. -> 0. and 1. -> 1.
|
|
79
|
+
pi = acos(-1.)
|
|
80
|
+
|
|
81
|
+
def sin_shape(x) =
|
|
82
|
+
(1. + sin((x - 0.5) * pi)) / 2.
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
exp_curve = curve ?? 3.
|
|
86
|
+
m = exp(exp_curve - 1.) - exp(-1.)
|
|
87
|
+
|
|
88
|
+
def exp_shape(x) =
|
|
89
|
+
(exp((exp_curve * x) - 1.) - exp(-1.)) / m
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
ln_curve = curve ?? 10.
|
|
93
|
+
m = ln(1. + ln_curve)
|
|
94
|
+
|
|
95
|
+
def log_shape(x) =
|
|
96
|
+
ln(1. + ln_curve * x) / m
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def lin_shape(x) =
|
|
100
|
+
x
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
shape =
|
|
104
|
+
if
|
|
105
|
+
type == "sin"
|
|
106
|
+
then
|
|
107
|
+
sin_shape
|
|
108
|
+
elsif
|
|
109
|
+
type == "exp"
|
|
110
|
+
then
|
|
111
|
+
exp_shape
|
|
112
|
+
elsif
|
|
113
|
+
type == "log"
|
|
114
|
+
then
|
|
115
|
+
log_shape
|
|
116
|
+
elsif
|
|
117
|
+
type == "lin"
|
|
118
|
+
then
|
|
119
|
+
lin_shape
|
|
120
|
+
else
|
|
121
|
+
log(
|
|
122
|
+
"Invalid type #{type}, using \"lin\""
|
|
123
|
+
)
|
|
124
|
+
lin_shape
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
start_time = ref(-1.)
|
|
128
|
+
increasing_fade = start <= stop
|
|
129
|
+
|
|
130
|
+
def fade() =
|
|
131
|
+
if start_time() < 0. then start_time := source.time(s) end
|
|
132
|
+
|
|
133
|
+
t = source.time(s) - start_time() - delay
|
|
134
|
+
if
|
|
135
|
+
0. < duration and t <= 0.
|
|
136
|
+
then
|
|
137
|
+
start
|
|
138
|
+
elsif
|
|
139
|
+
t >= duration
|
|
140
|
+
then
|
|
141
|
+
on_done()
|
|
142
|
+
stop
|
|
143
|
+
else
|
|
144
|
+
if
|
|
145
|
+
increasing_fade
|
|
146
|
+
then
|
|
147
|
+
start + shape(t / duration) * (stop - start)
|
|
148
|
+
else
|
|
149
|
+
stop + shape(1. - t / duration) * (start - stop)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
fade
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Scale source during fading.
|
|
158
|
+
# @category Source / Fade
|
|
159
|
+
# @flag hidden
|
|
160
|
+
def fade.scale(~id="fade.scale", x, s) =
|
|
161
|
+
amplify(id=id, override=null, x, s)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Fade the end of tracks.
|
|
165
|
+
# @category Source / Fade
|
|
166
|
+
# @param ~id Force the value of the source ID.
|
|
167
|
+
# @param ~duration Duration of the fading. This value can be set on a per-file basis using the metadata field passed as override. Defaults to `settings.fade.out.curve` if `null`.
|
|
168
|
+
# @param ~delay Initial delay before starting fade. Defaults to `settings.fade.out.delay` if `null`.
|
|
169
|
+
# @param ~curve Fade curve. Defaults to `settings.fade.out.curve` if `null`.
|
|
170
|
+
# @param ~override_duration Metadata field which, if present and containing a float, overrides the 'duration' parameter for the current track.
|
|
171
|
+
# @param ~override_type Metadata field which, if present and correct, overrides the 'type' parameter for the current track.
|
|
172
|
+
# @param ~override_curve Metadata field which, if presents and correct, overrides the `curve` parameter for the current track. Use `"default"` \
|
|
173
|
+
# to set to default value.
|
|
174
|
+
# @param ~override_delay Metadata field which, if presents and correct, overrides the initial fade delay.
|
|
175
|
+
# @param ~persist_overrides Keep duration and type overrides on track change.
|
|
176
|
+
# @param ~track_sensitive Be track sensitive (if `false` we only fade ou once at the beginning of the track).
|
|
177
|
+
# @param ~initial_metadata Initial metadata.
|
|
178
|
+
# @param ~type Fader shape. One of: "lin"", "sin", "log" or "exp". Defaults to `settings.fade.out.type` if `null`.
|
|
179
|
+
def fade.out(
|
|
180
|
+
~id="fade.out",
|
|
181
|
+
~duration=null,
|
|
182
|
+
~delay=0.,
|
|
183
|
+
~curve=null,
|
|
184
|
+
~override_duration="liq_fade_out",
|
|
185
|
+
~override_type="liq_fade_out_type",
|
|
186
|
+
~override_curve="liq_fade_out_curve",
|
|
187
|
+
~override_delay="liq_fade_out_delay",
|
|
188
|
+
~persist_overrides=false,
|
|
189
|
+
~track_sensitive=false,
|
|
190
|
+
~initial_metadata=[],
|
|
191
|
+
~type=null,
|
|
192
|
+
s
|
|
193
|
+
) =
|
|
194
|
+
def log(~level=4, x) =
|
|
195
|
+
log(label=source.id(s), level=level, x)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
fn = ref(fun () -> 1.)
|
|
199
|
+
original_type = type ?? settings.fade.out.type()
|
|
200
|
+
type = ref(original_type)
|
|
201
|
+
original_curve = (curve ?? settings.fade.out.curve() : float?)
|
|
202
|
+
curve = ref(original_curve)
|
|
203
|
+
original_duration = duration ?? settings.fade.out.duration()
|
|
204
|
+
duration = ref(original_duration)
|
|
205
|
+
original_delay = delay
|
|
206
|
+
delay = ref(original_delay)
|
|
207
|
+
start_time = ref(-1.)
|
|
208
|
+
started = ref(false)
|
|
209
|
+
last_metadata = ref(initial_metadata)
|
|
210
|
+
|
|
211
|
+
def start_fade(d, _) =
|
|
212
|
+
curve_log =
|
|
213
|
+
if null.defined(curve()) then string(null.get(curve())) else "default" end
|
|
214
|
+
|
|
215
|
+
start_time := source.time(s)
|
|
216
|
+
let (delay, duration) =
|
|
217
|
+
if
|
|
218
|
+
d < delay() + duration()
|
|
219
|
+
then
|
|
220
|
+
if
|
|
221
|
+
d < duration()
|
|
222
|
+
then
|
|
223
|
+
(0., d)
|
|
224
|
+
else
|
|
225
|
+
(max(0., d - duration()), duration())
|
|
226
|
+
end
|
|
227
|
+
else
|
|
228
|
+
(delay(), duration())
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
log(
|
|
232
|
+
"Fading out with type: #{type()}, curve: #{curve_log}, delay: #{delay}s, \
|
|
233
|
+
duration: #{duration}s and #{d}s remaining."
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
fn :=
|
|
237
|
+
mkfade(
|
|
238
|
+
start=1.,
|
|
239
|
+
stop=0.,
|
|
240
|
+
type=type(),
|
|
241
|
+
curve=curve(),
|
|
242
|
+
delay=delay,
|
|
243
|
+
duration=duration,
|
|
244
|
+
s
|
|
245
|
+
)
|
|
246
|
+
started := true
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def apply() =
|
|
250
|
+
fn = fn()
|
|
251
|
+
fn()
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def stop_fade(_) =
|
|
255
|
+
if
|
|
256
|
+
started()
|
|
257
|
+
then
|
|
258
|
+
fn := fun () -> 1.
|
|
259
|
+
started := false
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def update_fade(m) =
|
|
264
|
+
if
|
|
265
|
+
m[override_duration] != ""
|
|
266
|
+
then
|
|
267
|
+
old_duration = duration()
|
|
268
|
+
duration := float_of_string(default=duration(), m[override_duration])
|
|
269
|
+
|
|
270
|
+
if
|
|
271
|
+
duration() != old_duration
|
|
272
|
+
then
|
|
273
|
+
log(
|
|
274
|
+
"New fade out duration: #{duration()}s."
|
|
275
|
+
)
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
if
|
|
280
|
+
m[override_delay] != ""
|
|
281
|
+
then
|
|
282
|
+
old_delay = delay()
|
|
283
|
+
delay := float_of_string(default=0., m[override_delay])
|
|
284
|
+
|
|
285
|
+
if
|
|
286
|
+
delay() != old_delay
|
|
287
|
+
then
|
|
288
|
+
log(
|
|
289
|
+
"New fade out delay: #{delay()}s."
|
|
290
|
+
)
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
if
|
|
295
|
+
m[override_curve] != ""
|
|
296
|
+
then
|
|
297
|
+
old_curve = curve()
|
|
298
|
+
|
|
299
|
+
if
|
|
300
|
+
m[override_curve] == "default"
|
|
301
|
+
then
|
|
302
|
+
curve := null
|
|
303
|
+
else
|
|
304
|
+
try
|
|
305
|
+
curve := float_of_string(m[override_curve])
|
|
306
|
+
catch _ do
|
|
307
|
+
curve := null
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
if
|
|
312
|
+
curve() != old_curve
|
|
313
|
+
then
|
|
314
|
+
log(
|
|
315
|
+
"New fade out curve: #{curve()}."
|
|
316
|
+
)
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
if
|
|
321
|
+
m[override_type] != ""
|
|
322
|
+
then
|
|
323
|
+
old_type = type()
|
|
324
|
+
type := m[override_type]
|
|
325
|
+
|
|
326
|
+
if
|
|
327
|
+
type() != old_type
|
|
328
|
+
then
|
|
329
|
+
log(
|
|
330
|
+
"New fade out type: #{type()}."
|
|
331
|
+
)
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
update_fade(last_metadata())
|
|
337
|
+
|
|
338
|
+
def reset_overrides(_) =
|
|
339
|
+
if
|
|
340
|
+
not persist_overrides
|
|
341
|
+
then
|
|
342
|
+
log(
|
|
343
|
+
"Setting fade out to default duration: #{original_duration}s, delay: #{
|
|
344
|
+
original_delay
|
|
345
|
+
}s, type: #{original_type}, curve: #{original_curve}"
|
|
346
|
+
)
|
|
347
|
+
duration := original_duration
|
|
348
|
+
delay := original_delay
|
|
349
|
+
type := original_type
|
|
350
|
+
curve := original_curve
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
s = source.methods(s)
|
|
355
|
+
s.on_track(synchronous=true, reset_overrides)
|
|
356
|
+
s.on_metadata(synchronous=true, update_fade)
|
|
357
|
+
if track_sensitive then s.on_track(synchronous=true, stop_fade) end
|
|
358
|
+
|
|
359
|
+
d = source.dynamic(memoize({s}))
|
|
360
|
+
|
|
361
|
+
if
|
|
362
|
+
track_sensitive
|
|
363
|
+
then
|
|
364
|
+
d.on_position(
|
|
365
|
+
synchronous=true,
|
|
366
|
+
remaining=true,
|
|
367
|
+
position=duration,
|
|
368
|
+
start_fade
|
|
369
|
+
)
|
|
370
|
+
else
|
|
371
|
+
d.on_frame(
|
|
372
|
+
synchronous=true,
|
|
373
|
+
before=false,
|
|
374
|
+
memoize({start_fade(source.remaining(s), [])})
|
|
375
|
+
)
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
# Make sure we generate a frame before starting the fade
|
|
379
|
+
# to ensure that we catch all the initial metadata.
|
|
380
|
+
d.on_frame(
|
|
381
|
+
synchronous=true,
|
|
382
|
+
before=true,
|
|
383
|
+
memoize({if s.is_ready() then s.generate_frame() end})
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
fade.scale(id=id, apply, d).{
|
|
387
|
+
fade_duration = {duration()},
|
|
388
|
+
fade_type = {type()}
|
|
389
|
+
}
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
# Fade when the metadata trigger is received and then skip.
|
|
393
|
+
# @flag extra
|
|
394
|
+
# @category Source / Fade
|
|
395
|
+
# @flag extra
|
|
396
|
+
# @param ~id Force the value of the source ID.
|
|
397
|
+
# @param ~duration Duration of the fading. This value can be set on a per-file basis using the metadata field passed as override.
|
|
398
|
+
# @param ~delay Initial delay before starting fade.
|
|
399
|
+
# @param ~curve Fade curve. Default if `null`.
|
|
400
|
+
# @param ~override_duration Metadata field which, if present and containing a float, overrides the 'duration' parameter for the current track.
|
|
401
|
+
# @param ~override_type Metadata field which, if present and correct, overrides the 'type' parameter for the current track.
|
|
402
|
+
# @param ~override_curve Metadata field which, if presents and correct, overrides the `curve` parameter for the current track. Use `"default"` \
|
|
403
|
+
# to set to default value.
|
|
404
|
+
# @param ~override_skip Metadata field which, when present and set to "true", will trigger the fade
|
|
405
|
+
# @param ~persist_overrides Keep duration and type overrides on track change.
|
|
406
|
+
# @param ~initial_metadata Initial metadata.
|
|
407
|
+
# @param ~type Fader shape (lin|sin|log|exp): linear, sinusoidal, logarithmic or exponential.
|
|
408
|
+
def fade.skip(
|
|
409
|
+
~id="fade.skip",
|
|
410
|
+
~duration=5.,
|
|
411
|
+
~delay=0.,
|
|
412
|
+
~curve=null,
|
|
413
|
+
~override_duration="liq_fade_skip",
|
|
414
|
+
~override_type="liq_fade_skip_type",
|
|
415
|
+
~override_curve="liq_fade_skip_curve",
|
|
416
|
+
~persist_overrides=false,
|
|
417
|
+
~override_skip="liq_skip_meta",
|
|
418
|
+
~initial_metadata=[],
|
|
419
|
+
~type="lin",
|
|
420
|
+
s
|
|
421
|
+
) =
|
|
422
|
+
def log(x) =
|
|
423
|
+
log(label=source.id(s), level=4, x)
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
fn = ref(fun () -> 1.)
|
|
427
|
+
original_type = type
|
|
428
|
+
type = ref(type)
|
|
429
|
+
original_curve = curve
|
|
430
|
+
curve = ref(curve)
|
|
431
|
+
original_duration = duration
|
|
432
|
+
duration = ref(duration)
|
|
433
|
+
original_delay = delay
|
|
434
|
+
delay = ref(original_delay)
|
|
435
|
+
last_metadata = ref(initial_metadata)
|
|
436
|
+
|
|
437
|
+
def apply() =
|
|
438
|
+
fn = fn()
|
|
439
|
+
fn()
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
def stop_fade(_) =
|
|
443
|
+
fn := fun () -> 1.
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
def skip() =
|
|
447
|
+
log(
|
|
448
|
+
"Fade finished executing. Calling skip now"
|
|
449
|
+
)
|
|
450
|
+
source.skip(s)
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
def update_fade(m) =
|
|
454
|
+
if
|
|
455
|
+
m[override_skip] == "true"
|
|
456
|
+
then
|
|
457
|
+
remaining = source.remaining(s)
|
|
458
|
+
duration = if remaining < duration() then remaining else duration() end
|
|
459
|
+
log(
|
|
460
|
+
"Skip fade executed for: #{duration}s"
|
|
461
|
+
)
|
|
462
|
+
fn :=
|
|
463
|
+
mkfade(
|
|
464
|
+
start=1.,
|
|
465
|
+
stop=0.,
|
|
466
|
+
type=type(),
|
|
467
|
+
curve=curve(),
|
|
468
|
+
duration=duration,
|
|
469
|
+
delay=delay(),
|
|
470
|
+
on_done=skip,
|
|
471
|
+
s
|
|
472
|
+
)
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
if
|
|
476
|
+
m[override_duration] != ""
|
|
477
|
+
then
|
|
478
|
+
old_duration = duration()
|
|
479
|
+
duration := float_of_string(default=duration(), m[override_duration])
|
|
480
|
+
|
|
481
|
+
if
|
|
482
|
+
duration() != old_duration
|
|
483
|
+
then
|
|
484
|
+
log(
|
|
485
|
+
"New fade skip duration: #{duration()}s."
|
|
486
|
+
)
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
if
|
|
491
|
+
m[override_curve] != ""
|
|
492
|
+
then
|
|
493
|
+
old_curve = curve()
|
|
494
|
+
|
|
495
|
+
if
|
|
496
|
+
m[override_curve] == "default"
|
|
497
|
+
then
|
|
498
|
+
curve := null
|
|
499
|
+
else
|
|
500
|
+
try
|
|
501
|
+
curve := float_of_string(m[override_curve])
|
|
502
|
+
catch _ do
|
|
503
|
+
curve := null
|
|
504
|
+
end
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
if
|
|
508
|
+
curve() != old_curve
|
|
509
|
+
then
|
|
510
|
+
log(
|
|
511
|
+
"New fade skip curve: #{curve()}."
|
|
512
|
+
)
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
if
|
|
517
|
+
m[override_type] != ""
|
|
518
|
+
then
|
|
519
|
+
old_type = type()
|
|
520
|
+
type := m[override_type]
|
|
521
|
+
|
|
522
|
+
if
|
|
523
|
+
type() != old_type
|
|
524
|
+
then
|
|
525
|
+
log(
|
|
526
|
+
"New fade skip type: #{type()}."
|
|
527
|
+
)
|
|
528
|
+
end
|
|
529
|
+
end
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
update_fade(last_metadata())
|
|
533
|
+
|
|
534
|
+
def reset_overrides(_) =
|
|
535
|
+
if
|
|
536
|
+
not persist_overrides
|
|
537
|
+
then
|
|
538
|
+
log(
|
|
539
|
+
"Setting fade skip to default duration: #{original_duration}s, delay: #{
|
|
540
|
+
original_delay
|
|
541
|
+
}s, type: #{original_type}, curve: #{original_curve}"
|
|
542
|
+
)
|
|
543
|
+
duration := original_duration
|
|
544
|
+
type := original_type
|
|
545
|
+
curve := original_curve
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
s = source.methods(s)
|
|
550
|
+
s.on_track(synchronous=true, reset_overrides)
|
|
551
|
+
s.on_metadata(synchronous=true, update_fade)
|
|
552
|
+
s.on_track(synchronous=true, stop_fade)
|
|
553
|
+
|
|
554
|
+
fade.scale(id=id, apply, s).{
|
|
555
|
+
fade_duration = {duration()},
|
|
556
|
+
fade_type = {type()}
|
|
557
|
+
}
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
# Fade the beginning of tracks.
|
|
561
|
+
# @category Source / Fade
|
|
562
|
+
# @param ~id Force the value of the source ID.
|
|
563
|
+
# @param ~duration Duration of the fading. This value can be set on a per-file basis using the metadata field passed as override. Defaults to `settings.fade.in.duration` if `null`.
|
|
564
|
+
# @param ~delay Initial delay before starting fade.
|
|
565
|
+
# @param ~curve Fade curve. Defaults to `settings.fade.in.curve` if `null`.
|
|
566
|
+
# @param ~override_duration Metadata field which, if present and containing a float, overrides the 'duration' parameter for the current track.
|
|
567
|
+
# @param ~override_type Metadata field which, if present and correct, overrides the 'type' parameter for the current track.
|
|
568
|
+
# @param ~override_curve Metadata field which, if presents and correct, overrides the `curve` parameter for the current track. Use `"default"` \
|
|
569
|
+
# to set to default value.
|
|
570
|
+
# @param ~override_delay Metadata field which, if presents and correct, overrides the initial fade delay.
|
|
571
|
+
# @param ~persist_overrides Keep duration and type overrides on track change.
|
|
572
|
+
# @param ~track_sensitive Be track sensitive (if `false` we only fade in once at the beginning of the track).
|
|
573
|
+
# @param ~initial_metadata Initial metadata.
|
|
574
|
+
# @param ~type Fader shape. One of: "lin"", "sin", "log" or "exp". Defaults to `settings.fade.in.type` if `null`.
|
|
575
|
+
def fade.in(
|
|
576
|
+
~id="fade.in",
|
|
577
|
+
~duration=null,
|
|
578
|
+
~delay=0.,
|
|
579
|
+
~curve=null,
|
|
580
|
+
~override_duration="liq_fade_in",
|
|
581
|
+
~override_type="liq_fade_in_type",
|
|
582
|
+
~override_curve="liq_fade_in_curve",
|
|
583
|
+
~override_delay="liq_fade_in_delay",
|
|
584
|
+
~persist_overrides=false,
|
|
585
|
+
~track_sensitive=false,
|
|
586
|
+
~initial_metadata=[],
|
|
587
|
+
~type=null,
|
|
588
|
+
s
|
|
589
|
+
) =
|
|
590
|
+
def log(~level=4, x) =
|
|
591
|
+
log(label=source.id(s), level=level, x)
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
fn = ref(fun () -> 0.)
|
|
595
|
+
original_duration = duration ?? settings.fade.in.duration()
|
|
596
|
+
duration = ref(original_duration)
|
|
597
|
+
original_delay = delay
|
|
598
|
+
delay = ref(original_delay)
|
|
599
|
+
original_type = type ?? settings.fade.in.type()
|
|
600
|
+
type = ref(original_type)
|
|
601
|
+
original_curve = curve ?? settings.fade.in.curve()
|
|
602
|
+
curve = ref(curve)
|
|
603
|
+
last_metadata = ref(initial_metadata)
|
|
604
|
+
|
|
605
|
+
def apply() =
|
|
606
|
+
fn = fn()
|
|
607
|
+
fn()
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
def start_fade(_) =
|
|
611
|
+
curve_log =
|
|
612
|
+
if null.defined(curve()) then string(null.get(curve())) else "default" end
|
|
613
|
+
|
|
614
|
+
duration =
|
|
615
|
+
if
|
|
616
|
+
source.remaining(s) < duration()
|
|
617
|
+
then
|
|
618
|
+
source.remaining(s)
|
|
619
|
+
else
|
|
620
|
+
duration()
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
log(
|
|
624
|
+
"Fading in with type: #{type()}, curve: #{curve_log}, delay: #{delay()}s \
|
|
625
|
+
and duration: #{duration}s."
|
|
626
|
+
)
|
|
627
|
+
|
|
628
|
+
# Note: delay here must match the add delay via blank to make the curve also match
|
|
629
|
+
fn :=
|
|
630
|
+
mkfade(
|
|
631
|
+
start=0.,
|
|
632
|
+
stop=1.,
|
|
633
|
+
type=type(),
|
|
634
|
+
curve=curve(),
|
|
635
|
+
delay=delay(),
|
|
636
|
+
duration=duration,
|
|
637
|
+
s
|
|
638
|
+
)
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
def update_fade(m) =
|
|
642
|
+
if
|
|
643
|
+
m[override_duration] != ""
|
|
644
|
+
then
|
|
645
|
+
old_duration = duration()
|
|
646
|
+
duration := float_of_string(default=duration(), m[override_duration])
|
|
647
|
+
|
|
648
|
+
if
|
|
649
|
+
duration() != old_duration
|
|
650
|
+
then
|
|
651
|
+
log(
|
|
652
|
+
"New fade in duration: #{duration()}s."
|
|
653
|
+
)
|
|
654
|
+
end
|
|
655
|
+
end
|
|
656
|
+
|
|
657
|
+
if
|
|
658
|
+
m[override_delay] != ""
|
|
659
|
+
then
|
|
660
|
+
old_delay = delay()
|
|
661
|
+
delay := float_of_string(default=0., m[override_delay])
|
|
662
|
+
|
|
663
|
+
if
|
|
664
|
+
delay() != old_delay
|
|
665
|
+
then
|
|
666
|
+
log(
|
|
667
|
+
"New fade in delay: #{delay()}s."
|
|
668
|
+
)
|
|
669
|
+
end
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
if
|
|
673
|
+
m[override_curve] != ""
|
|
674
|
+
then
|
|
675
|
+
old_curve = curve()
|
|
676
|
+
|
|
677
|
+
if
|
|
678
|
+
m[override_curve] == "default"
|
|
679
|
+
then
|
|
680
|
+
curve := null
|
|
681
|
+
else
|
|
682
|
+
try
|
|
683
|
+
curve := float_of_string(m[override_curve])
|
|
684
|
+
catch _ do
|
|
685
|
+
curve := null
|
|
686
|
+
end
|
|
687
|
+
end
|
|
688
|
+
|
|
689
|
+
if
|
|
690
|
+
curve() != old_curve
|
|
691
|
+
then
|
|
692
|
+
log(
|
|
693
|
+
"New fade in curve: #{curve()}."
|
|
694
|
+
)
|
|
695
|
+
end
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
if
|
|
699
|
+
m[override_type] != ""
|
|
700
|
+
then
|
|
701
|
+
old_type = type()
|
|
702
|
+
type := m[override_type]
|
|
703
|
+
|
|
704
|
+
if
|
|
705
|
+
type() != old_type
|
|
706
|
+
then
|
|
707
|
+
log(
|
|
708
|
+
"New fade in type: #{type()}."
|
|
709
|
+
)
|
|
710
|
+
end
|
|
711
|
+
end
|
|
712
|
+
end
|
|
713
|
+
|
|
714
|
+
update_fade(last_metadata())
|
|
715
|
+
|
|
716
|
+
def reset_overrides(_) =
|
|
717
|
+
if
|
|
718
|
+
not persist_overrides
|
|
719
|
+
then
|
|
720
|
+
log(
|
|
721
|
+
"Setting fade in to default duration: #{original_duration}s, delay: #{
|
|
722
|
+
original_delay
|
|
723
|
+
}s, type: #{original_type}, curve: #{original_curve}"
|
|
724
|
+
)
|
|
725
|
+
duration := original_duration
|
|
726
|
+
delay := original_delay
|
|
727
|
+
type := original_type
|
|
728
|
+
curve := original_curve
|
|
729
|
+
end
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
s = source.methods(s)
|
|
733
|
+
s.on_track(synchronous=true, reset_overrides)
|
|
734
|
+
s.on_metadata(synchronous=true, update_fade)
|
|
735
|
+
|
|
736
|
+
# Register start_fade on the inner source so it fires before the amplify
|
|
737
|
+
# operator processes the new track head.
|
|
738
|
+
if track_sensitive then s.on_track(synchronous=true, start_fade) end
|
|
739
|
+
|
|
740
|
+
# Initial duration for fade.in should be computed after fetching the initial
|
|
741
|
+
# frame from s to make sure any initial metadata is taken into account
|
|
742
|
+
prepare = ref(fun (_) -> ())
|
|
743
|
+
s =
|
|
744
|
+
source.dynamic(
|
|
745
|
+
memoize(
|
|
746
|
+
fun () ->
|
|
747
|
+
begin
|
|
748
|
+
prepare = prepare()
|
|
749
|
+
prepare(s)
|
|
750
|
+
if s.is_active() then s.generate_frame() end
|
|
751
|
+
delay = delay()
|
|
752
|
+
if
|
|
753
|
+
delay > 0.
|
|
754
|
+
then
|
|
755
|
+
effective_source = source.methods(source.effective(s))
|
|
756
|
+
if
|
|
757
|
+
s.is_active()
|
|
758
|
+
then
|
|
759
|
+
log(
|
|
760
|
+
level=2,
|
|
761
|
+
"Active source #{effective_source.id()} is faded in after an \
|
|
762
|
+
initial delay of #{delay}s. This will result is initial data \
|
|
763
|
+
loss since the source will be animated while the delay \
|
|
764
|
+
expires."
|
|
765
|
+
)
|
|
766
|
+
end
|
|
767
|
+
sequence(merge=true, [blank(duration=delay), s])
|
|
768
|
+
else
|
|
769
|
+
s
|
|
770
|
+
end
|
|
771
|
+
end
|
|
772
|
+
)
|
|
773
|
+
)
|
|
774
|
+
|
|
775
|
+
s = fade.scale(id=id, apply, s)
|
|
776
|
+
|
|
777
|
+
if
|
|
778
|
+
not track_sensitive
|
|
779
|
+
then
|
|
780
|
+
s.on_frame(synchronous=true, before=false, memoize({start_fade([])}))
|
|
781
|
+
end
|
|
782
|
+
s.{fade_duration = {duration()}, fade_delay = {delay()}, fade_type = {type()}}
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
# Simple transition for crossfade
|
|
786
|
+
# @category Source / Fade
|
|
787
|
+
# @param ~log Logging utility
|
|
788
|
+
# @param ~fade_in Fade-in duration, if any.
|
|
789
|
+
# @param ~fade_out Fade-out duration, if any.
|
|
790
|
+
# @param ~initial_fade_in_metadata Initial fade-in metadata
|
|
791
|
+
# @param ~initial_fade_out_metadata Initial fade-out metadata
|
|
792
|
+
# @param ~ending_map Optional mapping for the ending track
|
|
793
|
+
# @param ~starting_map Optional mapping for the starting track
|
|
794
|
+
# @param a Ending track
|
|
795
|
+
# @param b Starting track
|
|
796
|
+
def cross.simple(
|
|
797
|
+
~log=(fun (s) -> log(label="cross.simple", level=3, s)),
|
|
798
|
+
~fade_in=3.,
|
|
799
|
+
~fade_out=3.,
|
|
800
|
+
~initial_fade_in_metadata=[],
|
|
801
|
+
~initial_fade_out_metadata=[],
|
|
802
|
+
~ending_map=fun (s) -> s,
|
|
803
|
+
~starting_map=fun (s) -> s,
|
|
804
|
+
a,
|
|
805
|
+
b
|
|
806
|
+
) =
|
|
807
|
+
fade_out_start_next =
|
|
808
|
+
if
|
|
809
|
+
list.assoc.mem("liq_fade_out_start_next", initial_fade_out_metadata)
|
|
810
|
+
then
|
|
811
|
+
float_of_string(initial_fade_out_metadata["liq_fade_out_start_next"])
|
|
812
|
+
else
|
|
813
|
+
0.
|
|
814
|
+
end
|
|
815
|
+
|
|
816
|
+
fade_in_delay =
|
|
817
|
+
if
|
|
818
|
+
list.assoc.mem("liq_fade_in_delay", initial_fade_in_metadata)
|
|
819
|
+
then
|
|
820
|
+
float_of_string(initial_fade_in_metadata["liq_fade_in_delay"])
|
|
821
|
+
else
|
|
822
|
+
fade_out_start_next
|
|
823
|
+
end
|
|
824
|
+
|
|
825
|
+
fade_in_delay =
|
|
826
|
+
if
|
|
827
|
+
source.duration(b) < source.duration(a)
|
|
828
|
+
then
|
|
829
|
+
delay = source.duration(a) - source.duration(b)
|
|
830
|
+
log(
|
|
831
|
+
"Adding #{delay} of fade_in_delay to match ending source"
|
|
832
|
+
)
|
|
833
|
+
fade_in_delay + delay
|
|
834
|
+
else
|
|
835
|
+
fade_in_delay
|
|
836
|
+
end
|
|
837
|
+
|
|
838
|
+
def fade.out(s) =
|
|
839
|
+
fade.out(
|
|
840
|
+
type="sin",
|
|
841
|
+
persist_overrides=true,
|
|
842
|
+
duration=fade_out,
|
|
843
|
+
initial_metadata=initial_fade_out_metadata,
|
|
844
|
+
s
|
|
845
|
+
)
|
|
846
|
+
end
|
|
847
|
+
|
|
848
|
+
def fade.in(s) =
|
|
849
|
+
fade.in(
|
|
850
|
+
type="sin",
|
|
851
|
+
persist_overrides=true,
|
|
852
|
+
duration=fade_in,
|
|
853
|
+
initial_metadata=[
|
|
854
|
+
...list.assoc.remove("liq_fade_in_delay", initial_fade_in_metadata),
|
|
855
|
+
("liq_fade_in_delay", "#{fade_in_delay}")
|
|
856
|
+
],
|
|
857
|
+
s
|
|
858
|
+
)
|
|
859
|
+
end
|
|
860
|
+
|
|
861
|
+
add = fun (a, b) -> add(normalize=false, [starting_map(b), ending_map(a)])
|
|
862
|
+
add(fade.out(a), fade.in(b))
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
# @docof cross
|
|
866
|
+
# @param ~deduplicate Crossfade transitions can generate duplicate metadata. When `true`, the operator \
|
|
867
|
+
# removes duplicate metadata from the returned source.
|
|
868
|
+
def replaces cross(%argsof(cross), ~deduplicate=true, transition, s) =
|
|
869
|
+
if
|
|
870
|
+
not deduplicate
|
|
871
|
+
then
|
|
872
|
+
cross(%argsof(cross), transition, s)
|
|
873
|
+
else
|
|
874
|
+
s = cross(%argsof(cross[!id]), transition, s)
|
|
875
|
+
dedup = metadata.deduplicate(s)
|
|
876
|
+
|
|
877
|
+
dedup.{
|
|
878
|
+
buffered = s.buffered,
|
|
879
|
+
duration = s.duration,
|
|
880
|
+
cross_duration = s.cross_duration
|
|
881
|
+
}
|
|
882
|
+
end
|
|
883
|
+
end
|
|
884
|
+
|
|
885
|
+
# Crossfade between tracks, taking the respective volume levels into account in
|
|
886
|
+
# the choice of the transition.
|
|
887
|
+
# @category Source / Fade
|
|
888
|
+
# @argsof cross[id,duration,override_duration,persist_override,width]
|
|
889
|
+
# @param ~deduplicate Crossfade transitions can generate duplicate metadata. When `true`, the operator \
|
|
890
|
+
# removes duplicate metadata from the returned source.
|
|
891
|
+
# @param s The input source.
|
|
892
|
+
def crossfade(
|
|
893
|
+
%argsof(cross[id,duration,override_duration,persist_override,width]),
|
|
894
|
+
~fade_in=3.,
|
|
895
|
+
~fade_out=3.,
|
|
896
|
+
~deduplicate=true,
|
|
897
|
+
s
|
|
898
|
+
) =
|
|
899
|
+
id = string.id.default(default="crossfade", id)
|
|
900
|
+
|
|
901
|
+
def log(~level=3, x) =
|
|
902
|
+
log(label=id, level=level, x)
|
|
903
|
+
end
|
|
904
|
+
|
|
905
|
+
def transition(a, b) =
|
|
906
|
+
list.iter(
|
|
907
|
+
fun (x) ->
|
|
908
|
+
log(
|
|
909
|
+
level=4,
|
|
910
|
+
"Before: #{x}"
|
|
911
|
+
),
|
|
912
|
+
a.metadata
|
|
913
|
+
)
|
|
914
|
+
|
|
915
|
+
list.iter(
|
|
916
|
+
fun (x) ->
|
|
917
|
+
log(
|
|
918
|
+
level=4,
|
|
919
|
+
"After : #{x}"
|
|
920
|
+
),
|
|
921
|
+
b.metadata
|
|
922
|
+
)
|
|
923
|
+
|
|
924
|
+
cross.simple(
|
|
925
|
+
log=log,
|
|
926
|
+
fade_in=fade_in,
|
|
927
|
+
fade_out=fade_out,
|
|
928
|
+
initial_fade_in_metadata=b.metadata,
|
|
929
|
+
initial_fade_out_metadata=a.metadata,
|
|
930
|
+
a.source,
|
|
931
|
+
b.source
|
|
932
|
+
)
|
|
933
|
+
end
|
|
934
|
+
|
|
935
|
+
cross(
|
|
936
|
+
%argsof(cross[id,duration,override_duration,persist_override,width]),
|
|
937
|
+
deduplicate=deduplicate,
|
|
938
|
+
transition,
|
|
939
|
+
s
|
|
940
|
+
)
|
|
941
|
+
end
|