import { type Editor } from "../main"; import { freqToMidi, resolvePitchBend, getScale, isScale, parseScala, } from "zifferjs"; export abstract class Event { seedValue: string | undefined = undefined; randomGen: Function = Math.random; app: Editor; values: { [key: string]: any } = {}; constructor(app: Editor) { this.app = app; if (this.app.api.currentSeed) { this.randomGen = this.app.api.randomGen; } } odds = (probability: number, func: Function): Event => { if (this.randomGen() < probability) { return this.modify(func); } return this; }; almostNever = (func: Function): Event => { return this.odds(0.025, func); }; rarely = (func: Function): Event => { return this.odds(0.1, func); }; scarcely = (func: Function): Event => { return this.odds(0.25, func); }; sometimes = (func: Function): Event => { return this.odds(0.5, func); }; often = (func: Function): Event => { return this.odds(0.75, func); }; frequently = (func: Function): Event => { return this.odds(0.9, func); }; almostAlways = (func: Function): Event => { return this.odds(0.985, func); }; modify = (func: Function): Event => { return func(this); }; seed = (value: string | number): Event => { this.seedValue = value.toString(); this.randomGen = this.app.api.localSeededRandom(this.seedValue); return this; }; clear = (): Event => { this.app.api.clearLocalSeed(this.seedValue); return this; }; apply = (func: Function): Event => { return this.modify(func); }; length = (value: number): Event => { this.values["length"] = value; return this; }; } export abstract class AudibleEvent extends Event { constructor(app: Editor) { super(app); } octave = (value: number): this => { this.values["octave"] = value; this.update(); return this; }; key = (value: string): this => { this.values["key"] = value; this.update(); return this; }; scale = (value: string): this => { if (!isScale(value)) { this.values.parsedScale = parseScala(value) as number[]; } else { this.values.scaleName = value; this.values.parsedScale = getScale(value) as number[]; } this.update(); return this; }; freq = (value: number): this => { this.values["freq"] = value; const midiNote = freqToMidi(value); if (midiNote % 1 !== 0) { this.values["note"] = Math.floor(midiNote); this.values["bend"] = resolvePitchBend(midiNote)[1]; } else { this.values["note"] = midiNote; } return this; }; update = (): void => { // Overwrite in subclasses }; }