Commit 831d3f14 by PLN (Algolia)

fix(foundry): the cheat sheet printed 133 bpm over loops cut at 132.5

`loopAt` is exact, so a rounded tempo is a stretched loop — and the cheat sheet is
where the number gets typed. It reported ANGIE and BIG HEN as "133 bpm" over files cut
at 132.51, which plays every one of them 0.4% fast.

Two decimals now, and each kit prints its own `setcps` line rather than leaving the
÷60÷4 to the reader: `loopAt` squeezes the file into N bars of the *current* cps, so
the cps is half the instruction and omitting it is what makes the rounding bite.

Same fix in La Cale's UI, where the transport read 123.05 next to a row reading
123.0 — one `fmtBpm` for the transport, the rack header and every row, because the
same tempo printed two ways reads as a disagreement in the data.
parent ebcd5664
......@@ -476,9 +476,12 @@ def cheatsheet(cuts: list[CutLoop]) -> str:
lines = ["-- fred kits — generated by engine.stempack; n indices are sort order", ""]
for kit in sorted({c.kit for c in cuts}):
items = sorted((c for c in cuts if c.kit == kit), key=lambda c: c.name)
bpms = {round(c.bpm) for c in items if c.bpm}
# NOT rounded to an integer. This is the number someone types into `setcps`,
# and ANGIE is 132.5 — printing "133 bpm" over loops cut at 132.5 makes every
# one of them play 0.4% fast, because `loopAt` is exact.
bpms = {round(c.bpm, 2) for c in items if c.bpm}
lines.append(f"-- {kit} ({len(items)} samples"
+ (f", {'/'.join(str(b) for b in sorted(bpms))} bpm)" if bpms else ")"))
+ (f", {'/'.join(f'{b:g}' for b in sorted(bpms))} bpm)" if bpms else ")"))
for i, c in enumerate(items):
inst = (c.tags.get("instrument") or [("", 0)])[0][0]
how = f"loopAt {c.bars}" if c.bars > 0 else f"one-shot {c.dur_s:.2f}s"
......@@ -486,6 +489,11 @@ def cheatsheet(cuts: list[CutLoop]) -> str:
f"{c.stem_role}{(' · ' + inst) if inst else ''}")
ex = items[0]
if ex.bars > 0:
# `loopAt` squeezes the file into N bars of the CURRENT cps, so the cps is
# half the instruction. Printing the bpm and leaving the arithmetic to the
# reader is how a 132.5 kit ends up played at 133.
if ex.bpm:
lines.append(f"-- setcps ({ex.bpm / 60 / 4:.4f}) -- {ex.bpm:g} bpm")
lines.append(f'-- d1 $ loopAt {ex.bars} $ chop 8 $ s "{kit}" # n 0')
else:
lines.append(f'-- d1 $ s "{kit}*4" # n (irand {len(items)})')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment