Initial Commit
This commit is contained in:
120
packages/ui/react/react-audio/tests/fake-transport.ts
Normal file
120
packages/ui/react/react-audio/tests/fake-transport.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user