diff --git a/src/API.ts b/src/API.ts index 2cc48bf..a53ccc4 100644 --- a/src/API.ts +++ b/src/API.ts @@ -1,8 +1,6 @@ import { Editor } from "./main"; import { tryEvaluate } from "./Evaluator"; -import { BasicSynth, PercussionSynth } from "./WebSynth"; import { MidiConnection } from "./IO/MidiConnection"; -import * as Tone from 'tone'; // @ts-ignore import { ZZFX, zzfx } from "zzfx"; @@ -11,14 +9,42 @@ export class UserAPI { variables: { [key: string]: any } = {} MidiConnection: MidiConnection = new MidiConnection() - constructor(public app: Editor) { - } + constructor(public app: Editor) { } // ============================================================= // Utility functions // ============================================================= + log = console.log + rate(rate: number): void { + // TODO: Implement this. This function should change the rate at which the global script + // is evaluated. This is useful for slowing down the script, or speeding it up. The default + // would be 1.0, which is the current rate (very speedy). + } + r = this.rate + + script(...args: number[]): void { + args.forEach(arg => { tryEvaluate(this.app, this.app.universes[ + this.app.selected_universe].locals[arg]) }) + } + s = this.script + + clearscript(script: number): void { + this.app.universes[this.app.selected_universe].locals[script] = { + candidate: '', committed: '', evaluations: 0 + } + } + cs = this.clearscript + + copyscript(from: number, to: number): void { + // Copy a script to another script + this.app.universes[this.app.selected_universe].locals[to] = + this.app.universes[this.app.selected_universe].locals[from] + } + cps = this.copyscript + + // ============================================================= // MIDI related functions // ============================================================= @@ -57,12 +83,11 @@ export class UserAPI { this.MidiConnection.panic() } - // ============================================================= // Variable related functions // ============================================================= - public v(a: number | string, b?: any): any { + public variable(a: number | string, b?: any): any { if (typeof a === 'string' && b === undefined) { return this.variables[a] } else { @@ -70,21 +95,23 @@ export class UserAPI { return this.variables[a] } } + v = this.variable - public dv(name: string): void { + public delete_variable(name: string): void { delete this.variables[name] } + dv = this.delete_variable - public cv(): void { + public clear_variables(): void { this.variables = {} } + cv = this.clear_variables // ============================================================= // Small algorithmic functions // ============================================================= pick(...array: T[]): T { return array[Math.floor(Math.random() * array.length)] } - seqbeat(...array: T[]): T { return array[this.app.clock.time_position.beat % array.length] } seqbar(...array: T[]): T { return array[this.app.clock.time_position.bar % array.length] } seqpulse(...array: T[]): T { return array[this.app.clock.time_position.pulse % array.length] } @@ -101,11 +128,7 @@ export class UserAPI { // Quantification functions // ============================================================= - quantize(value: number, quantization: number[]): number { - // Takes a value, and a quantization array, and returns the closest value in the quantization array - // Example: quantize(0.7, [0, 0.5, 1]) => 0.5 - // If the quantization array is empty, return the value - + public quantize(value: number, quantization: number[]): number { if (quantization.length === 0) { return value } let closest = quantization[0] quantization.forEach(q => { @@ -113,20 +136,22 @@ export class UserAPI { }) return closest } + quant = this.quantize - clamp(value: number, min: number, max: number): number { + public clamp(value: number, min: number, max: number): number { return Math.min(Math.max(value, min), max) } + cmp = this.clamp // ============================================================= - // Time functions + // Transport functions // ============================================================= - bpm(bpm: number) { + bpm(bpm: number):void { this.app.clock.bpm = bpm } - time_signature(numerator: number, denominator: number) { + time_signature(numerator: number, denominator: number):void { this.app.clock.time_signature = [ numerator, denominator ] } @@ -134,13 +159,13 @@ export class UserAPI { // Probability functions // ============================================================= - almostNever() { return Math.random() > 0.9 } - sometimes() { return Math.random() > 0.5 } - rarely() { return Math.random() > 0.75 } - often() { return Math.random() > 0.25 } - almostAlways() { return Math.random() > 0.1 } - randInt(min: number, max: number) { return Math.floor(Math.random() * (max - min + 1)) + min } - dice(sides: number) { return Math.floor(Math.random() * sides) + 1 } + public almostNever() { return Math.random() > 0.9 } + public sometimes() { return Math.random() > 0.5 } + public rarely() { return Math.random() > 0.75 } + public often() { return Math.random() > 0.25 } + public almostAlways() { return Math.random() > 0.1 } + public randInt(min: number, max: number) { return Math.floor(Math.random() * (max - min + 1)) + min } + public dice(sides: number) { return Math.floor(Math.random() * sides) + 1 } // ============================================================= // Iterator functions (for loops, with evaluation count, etc...) @@ -156,19 +181,10 @@ export class UserAPI { get e7() { return this.app.universes[this.app.selected_universe].locals[6].evaluations } get e8() { return this.app.universes[this.app.selected_universe].locals[7].evaluations } get e9() { return this.app.universes[this.app.selected_universe].locals[8].evaluations } - e(index:number) { return this.app.universes[this.app.selected_universe].locals[index].evaluations } - - - // Script launcher: can launch any number of scripts - script(...args: number[]): void { - args.forEach(arg => { tryEvaluate(this.app, this.app.universes[this.app.selected_universe].locals[arg]) }) - } - s = this.script - - // Small ZZFX interface for playing with this synth - zzfx(...thing: number[]) { - zzfx(...thing); + public evaluations_number(index:number): number { + return this.app.universes[this.app.selected_universe].locals[index].evaluations } + e = this.evaluations_number // ============================================================= // Time markers @@ -177,6 +193,7 @@ export class UserAPI { get bar(): number { return this.app.clock.time_position.bar } get pulse(): number { return this.app.clock.time_position.pulse } get beat(): number { return this.app.clock.time_position.beat } + get beats_since_origin(): number { return this.app.clock.beats_since_origin } onbeat(...beat: number[]): boolean { return ( @@ -193,4 +210,12 @@ export class UserAPI { return pulse.some(p => this.app.clock.time_position.pulse % p === 0) } -} \ No newline at end of file + + // ============================================================= + // Trivial functions + // ============================================================= + + // Small ZZFX interface for playing with this synth + zzfx = (...thing: number[]) => zzfx(...thing); + +} diff --git a/src/Clock.ts b/src/Clock.ts index 3f7c55f..a4125f6 100644 --- a/src/Clock.ts +++ b/src/Clock.ts @@ -36,7 +36,7 @@ export class Clock { }) } - get pulses_per_beat(): number { return this.ppqn / this.time_signature[1]; } + get beats_per_bar(): number { return this.time_signature[0]; } start(): void { // Check if the clock is already running