The events to reshape.
The groove template, from extractGrooveTemplate.
The time signature, used to compute the bar length.
Reshaped copies of events, in input order.
import { extractGrooveTemplate, applyGrooveTemplate, parseTimeSignature } from '@libraz/libcantus';
const ts = parseTimeSignature('4/4');
// Learn the feel from a loosely played performance...
const groovy = [
{ pitch: 36, startBeat: 0.02, durationBeat: 1, velocity: 100 },
{ pitch: 38, startBeat: 1.06, durationBeat: 1, velocity: 70 },
];
const template = extractGrooveTemplate(groovy, ts, 4);
// ...then impose it on stiff, quantized events.
const quantized = [{ pitch: 36, startBeat: 0, durationBeat: 1, velocity: 80 }];
applyGrooveTemplate(quantized, template, ts); // events nudged toward the captured feel
Apply a groove template to a set of (typically quantized) note events: each event is snapped to its grid slot and then offset by that slot's recorded timing deviation, pushing stiff timing toward the template's feel. Velocity is set to the slot's recorded average when it recorded one (a non-
nullvelocity, including a genuine 0); otherwise the event's own velocity is left untouched.If the template carries a time signature (see GrooveTemplate.ts) it must match
ts, since a differing bar length would misalign the per-bar grid and drift the feel; a mismatch throws rather than corrupting timing silently.