Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
/**
* Real `TransportLike` implementation backed by an in-memory event log.
* Mirrors the fixture shipped by `@suaveplan/audio-controllers/tests/
* fake-transport.ts`. Lives outside `src/` so it is excluded from
* coverage but available to every test in this package.
*/
import type {
BarsBeatsSixteenths,
SignalLike,
TransportCallback,
TransportLike,
TransportTime,
} from "@suaveplan/audio-transport";
interface ScheduledRepeat {
readonly id: number;
readonly callback: TransportCallback;
readonly interval: TransportTime;
}
interface ScheduledOnce {
readonly id: number;
readonly callback: TransportCallback;
readonly time: number;
}
const NOOP_BBS: BarsBeatsSixteenths = "0:0:0";
function makeFakeSignal(): SignalLike {
let v = 120;
const points: { time: number; value: number; type: "set" }[] = [];
const sig: SignalLike = {
get points() {
return points.slice();
},
get initialValue() {
return 120;
},
get value() {
return v;
},
setValueAtTime(value: number, time: number) {
v = value;
points.push({ time, value, type: "set" });
},
linearRampToValueAtTime(value: number) {
v = value;
},
exponentialRampToValueAtTime(value: number) {
v = value;
},
getValueAtTime() {
return v;
},
cancelScheduledValues() {
points.length = 0;
},
};
return sig;
}
export class FakeTransport implements TransportLike {
public bpm: SignalLike = makeFakeSignal();
public readonly ppq = 192;
public readonly timeSignature = 4;
public swing = 0;
public swingSubdivision: TransportTime = "8n";
public loop = false;
public loopStart: TransportTime = 0;
public loopEnd: TransportTime = 0;
public state: "stopped" | "playing" | "paused" = "stopped";
public position: BarsBeatsSixteenths = NOOP_BBS;
public ticks = 0;
public seconds = 0;
public readonly repeats = new Map<number, ScheduledRepeat>();
public readonly onces = new Map<number, ScheduledOnce>();
private nextId = 1;
start(): void {
this.state = "playing";
}
stop(): void {
this.state = "stopped";
}
pause(): void {
this.state = "paused";
}
schedule(callback: TransportCallback, time: TransportTime): number {
return this.scheduleOnce(callback, time);
}
scheduleOnce(callback: TransportCallback, time: TransportTime): number {
const id = this.nextId++;
const num = typeof time === "number" ? time : 0;
this.onces.set(id, { id, callback, time: num });
return id;
}
scheduleRepeat(
callback: TransportCallback,
interval: TransportTime
): number {
const id = this.nextId++;
this.repeats.set(id, { id, callback, interval });
return id;
}
cancel(eventId: number): void {
this.repeats.delete(eventId);
this.onces.delete(eventId);
}
cancelAfter(_time: TransportTime): void {
// unused
}
toSeconds(time: TransportTime): number {
return typeof time === "number" ? time / this.ppq : 0;
}
toTicks(time: TransportTime): number {
return typeof time === "number" ? time * this.ppq : 0;
}
}