feat: core types, time, rng, model fetch
Co-Authored-By: Claude Haiku 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
0a6ec1dc40
commit
bac4fbeb1d
@@ -0,0 +1,33 @@
|
||||
export interface Rng {
|
||||
/** Uniform in [0, 1). */
|
||||
next(): number;
|
||||
/** Uniform integer in [lo, hi], inclusive. */
|
||||
int(lo: number, hi: number): number;
|
||||
pick<T>(a: readonly T[]): T;
|
||||
chance(p: number): boolean;
|
||||
}
|
||||
|
||||
// mulberry32
|
||||
export function createRng(seed: number): Rng {
|
||||
let s = seed >>> 0;
|
||||
const next = (): number => {
|
||||
s = (s + 0x6d2b79f5) >>> 0;
|
||||
let t = s;
|
||||
t = Math.imul(t ^ (t >>> 15), t | 1);
|
||||
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
};
|
||||
return {
|
||||
next,
|
||||
int(lo, hi) {
|
||||
return lo + Math.floor(next() * (hi - lo + 1));
|
||||
},
|
||||
pick<T>(a: readonly T[]): T {
|
||||
if (a.length === 0) throw new Error("rng.pick: empty array");
|
||||
return a[Math.floor(next() * a.length)] as T;
|
||||
},
|
||||
chance(p) {
|
||||
return next() < p;
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { TPQ } from "./types.ts";
|
||||
|
||||
// One quarter note = TPQ ticks.
|
||||
export function ticksToSeconds(tick: number, bpm: number): number {
|
||||
return (tick / TPQ) * (60 / bpm);
|
||||
}
|
||||
|
||||
export function secondsToTicks(s: number, bpm: number): number {
|
||||
return s * (bpm / 60) * TPQ;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export type Role = "guitar" | "bass" | "keys" | "vocals" | "drums";
|
||||
export type FxPreset = "none" | "clean" | "clean-chorus" | "light-drive";
|
||||
// string numbering: 1 = highest-pitched string (alphaTex convention). Drums: pitch = GM drum number.
|
||||
export interface ScoreNote { tick: number; dur: number; pitch: number; string?: number; fret?: number }
|
||||
export interface Track { name: string; role: Role; program: number; tuning?: number[]; pan: number; fx: FxPreset; gainDb: number; notes: ScoreNote[] }
|
||||
export interface Song { title: string; tier: string; seed: number; bpm: number; timeSig: [number, number]; bars: number; key: string; tracks: Track[] }
|
||||
export interface TimedNote { onset: number; offset: number; pitch: number; velocity?: number; string?: number; fret?: number }
|
||||
export interface TruthTrack { name: string; role: Role; tuning?: number[]; notes: TimedNote[] }
|
||||
export interface Grid { bpm: number; firstDownbeat: number; beatsPerBar: number }
|
||||
export interface Audio { sampleRate: number; channels: Float32Array[] }
|
||||
export const TPQ = 960;
|
||||
export const GUITAR_STANDARD = [64, 59, 55, 50, 45, 40];
|
||||
export const BASS_STANDARD = [43, 38, 33, 28];
|
||||
Reference in New Issue
Block a user