43 lines
1.8 KiB
TypeScript
43 lines
1.8 KiB
TypeScript
import { test, expect } from "bun:test";
|
|
import { quantize, snapTicks } from "../../src/pipeline/quantize.ts";
|
|
import type { TimedNote } from "../../src/core/types.ts";
|
|
|
|
const t = (onset: number, offset: number, pitch: number): TimedNote => ({ onset, offset, pitch });
|
|
const g = { bpm: 120, firstDownbeat: 0.1, beatsPerBar: 4 };
|
|
|
|
test("snaps onsets and durations to the 16th grid relative to the first downbeat", () => {
|
|
const q = quantize([t(0.1 + 0.5 + 0.02, 0.1 + 1.0, 60), t(0.1 + 0.75 - 0.015, 0.1 + 1.0, 64)], g);
|
|
expect(q.map((n) => [n.tick, n.dur, n.pitch])).toEqual([[960, 960, 60], [1440, 480, 64]]);
|
|
});
|
|
|
|
test("drops notes before the first downbeat", () => {
|
|
const q = quantize([t(0.0, 0.3, 60), t(0.1, 0.4, 62)], g);
|
|
expect(q.map((n) => n.pitch)).toEqual([62]);
|
|
});
|
|
|
|
test("merges chord notes within 35 ms, with one consistent duration", () => {
|
|
const q = quantize([t(0.6, 1.6, 60), t(0.625, 1.1, 64), t(0.63, 1.6, 67)], g);
|
|
expect(new Set(q.map((n) => n.tick)).size).toBe(1);
|
|
expect(new Set(q.map((n) => n.dur)).size).toBe(1);
|
|
expect(q).toHaveLength(3);
|
|
});
|
|
|
|
test("collapses exact duplicates, enforces min duration", () => {
|
|
const q = quantize([t(0.1, 0.101, 60), t(0.1, 0.101, 60), t(0.225, 3, 62)], g);
|
|
expect(q.map((n) => [n.tick, n.pitch])).toEqual([[0, 60], [240, 62]]);
|
|
expect(q[0]!.dur).toBe(240);
|
|
for (const n of q) {
|
|
expect(n.tick % 240).toBe(0);
|
|
expect(n.dur % 240).toBe(0);
|
|
expect(n.dur).toBeGreaterThanOrEqual(240);
|
|
}
|
|
});
|
|
|
|
|
|
test("snapTicks matches quantize ticks, incl. chord clusters and adjacent repeated pitches", () => {
|
|
// two same-pitch notes 20 ms apart merge; the next repeat is on the adjacent 16th (125 ms at 120 bpm)
|
|
const notes = [t(0.1, 0.2, 60), t(0.12, 0.2, 60), t(0.225, 0.3, 60)];
|
|
expect(snapTicks(notes, g)).toEqual([0, 0, 240]);
|
|
expect(quantize(notes, g).map((n) => n.tick)).toEqual([0, 240]);
|
|
});
|