READY: LIGHT TIMING (flash and FX cues against the drum hits); auto-fix on for testing
- LIGHT TIMING: every blinder flash / FX cue is timed against the Drums (Live) stem under it (deactivated clips count) on the Tracks Mac; cues a strong hit is more than 25 ms away from are named with song and bar - Settings Overview: "Auto-fix on for testing" for 15 min to 2 h, outside the hours and over a pause; the AUTO-FIX key says TESTING, and it goes back to the hours by itself Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+51
-1
@@ -434,6 +434,56 @@ class TestWavesTune(unittest.TestCase):
|
||||
self.assertEqual(msgs(rd.eval_tune(RC, keyed(GOOD), ableton())), ["NO TUNE CLIPS"])
|
||||
|
||||
|
||||
def with_cues(al=None):
|
||||
"""Flashes over Can't Help But Praise's drums (beats 100-190 of the fixture, at 151 BPM there)."""
|
||||
al = al or ableton()
|
||||
al["summary"]["tracks"].append(track("25", "42-Drums (Live)", group="20", clips=((100, 190, None),)))
|
||||
al["summary"]["cues"] = [[104, 30], [104, 36], [108, 31], [112, 35], [116, 30], [120, 99]]
|
||||
al["summary"]["hit_src"] = [["25", 100, 190, "/Projects/NA/261018 NA Project/MultiTracks/Drums (Live).wav", False, 0.0]]
|
||||
al["light_names"] = {"30": "Blinder Flash 1", "31": "Blinder Flash 2", "35": "Blinder FX 1", "36": "Blinder FX 2"}
|
||||
return al
|
||||
|
||||
|
||||
class TestLightTiming(unittest.TestCase):
|
||||
def test_cue_times_in_the_stem(self):
|
||||
cues = rd.cue_times(RC, with_cues()["summary"])
|
||||
self.assertEqual([(c[0], c[1], c[2]) for c in cues], [(104, 30, "CAN'T HELP BUT PRAISE"), (108, 31, "CAN'T HELP BUT PRAISE"),
|
||||
(112, 35, "CAN'T HELP BUT PRAISE"), (116, 30, "CAN'T HELP BUT PRAISE")])
|
||||
tempo = with_cues()["summary"]["tempo"]
|
||||
self.assertAlmostEqual(cues[0][4], rd.seconds_at(tempo, 104) - rd.seconds_at(tempo, 100))
|
||||
self.assertAlmostEqual(cues[0][5], 0.45 * 60 / 151 / 4, places=4) # under half a 16th at 151 BPM
|
||||
|
||||
def test_off_cues_are_named(self):
|
||||
# [hit - cue (s), the hit's strength, strength under the cue]
|
||||
hits = [[0.005, 5000, 5000], # on time
|
||||
[0.037, 5200, 2000], # 37 ms early, a strong hit, little under the cue
|
||||
[-0.053, 900, 300], # off, but a weak hit for this song: left alone
|
||||
[0.040, 5100, 4800]] # off, but the cue already sits on a hit as strong: left alone
|
||||
line = rd.eval_light_timing(RC, with_cues(), hits)
|
||||
self.assertEqual(msgs(line), ["CUE OFF 28.1.1"])
|
||||
self.assertEqual(line.as_dict()["details"], ["CAN'T HELP BUT PRAISE bar 28.1.1: Blinder Flash 2 is 37 ms before the hit"])
|
||||
self.assertEqual(line.info, "3 CUES ON TIME")
|
||||
|
||||
def test_several_off(self):
|
||||
hits = [[-0.04, 5000, 0], [0.037, 5200, 2000], [0.0, 5000, 5000], [0.0, 5000, 5000]]
|
||||
line = rd.eval_light_timing(RC, with_cues(), hits)
|
||||
self.assertEqual(msgs(line), ["2 CUES OFF"])
|
||||
self.assertEqual(len(line.as_dict()["details"]), 2)
|
||||
self.assertIn("Blinder Flash 1 is 40 ms after the hit", line.as_dict()["details"][0])
|
||||
|
||||
def test_a_stem_it_cannot_read(self):
|
||||
line = rd.eval_light_timing(RC, with_cues(), ["unknown format: 3"] * 4)
|
||||
self.assertEqual(msgs(line), [])
|
||||
self.assertEqual(line.as_dict()["details"], ["could not read Drums (Live).wav"])
|
||||
|
||||
def test_bars_as_live_shows_them(self):
|
||||
self.assertEqual(rd.bar_of(1315.75), "329.4.4")
|
||||
self.assertEqual(rd.bar_of(0), "1.1.1")
|
||||
|
||||
def test_the_listener_runs(self):
|
||||
compile(rd.HIT_SCRIPT % json.dumps({"cues": [["/x.wav", 1.5, 0.05]]}), "remote", "exec")
|
||||
|
||||
|
||||
class TestTimecode(unittest.TestCase):
|
||||
def test_seconds_through_the_tempo_map(self):
|
||||
tempo = ableton()["summary"]["tempo"]
|
||||
@@ -567,7 +617,7 @@ class TestLook(unittest.TestCase):
|
||||
cfg["ready"].pop(k)
|
||||
cfg["ready"]["prop_url"] = ""
|
||||
r = rd.look(cfg, now=WEDNESDAY, sources=self.sources())
|
||||
self.assertEqual(sorted(r["items"]), ["ears", "keys", "lights", "mics", "mix_foh", "routing", "timecode", "tracks", "tune"]) # LTC: tracks vs PCO
|
||||
self.assertEqual(sorted(r["items"]), ["ears", "keys", "light_timing", "lights", "mics", "mix_foh", "routing", "timecode", "tracks", "tune"]) # LTC: tracks vs PCO
|
||||
engine, snap = sp.Engine(cfg, None), sp.Snapshot()
|
||||
snap.ready = r
|
||||
tiles = engine.step(snap, WEDNESDAY)
|
||||
|
||||
Reference in New Issue
Block a user