From 5ac8f4b0c458ae58c77afaede4d0a01adbf04013 Mon Sep 17 00:00:00 2001 From: Miika Alonen Date: Mon, 28 Aug 2023 15:13:43 +0300 Subject: [PATCH] Refactor ziffers to use z0-z16 methods --- package.json | 2 +- src/API.ts | 49 +++++++++++++++++++++++++++++++++++------- src/classes/ZPlayer.ts | 47 +++++++++++++++++++++++++++++++++------- yarn.lock | 7 +++--- 4 files changed, 84 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index f0e1838..0828600 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "tone": "^14.8.49", "unique-names-generator": "^4.7.1", "vite-plugin-markdown": "^2.1.0", - "zifferjs": "^0.0.14", + "zifferjs": "link:../zifferjs", "zzfx": "^1.2.0" } } diff --git a/src/API.ts b/src/API.ts index 1d65b41..4d19d45 100644 --- a/src/API.ts +++ b/src/API.ts @@ -7,7 +7,7 @@ import { Editor } from "./main"; import { SoundEvent } from "./classes/SoundEvent"; import { NoteEvent } from "./classes/MidiEvent"; import { LRUCache } from "lru-cache"; -import { Player } from "./classes/ZPlayer"; +import { InputOptions, Player } from "./classes/ZPlayer"; import { samples, initAudioOnFirstClick, @@ -300,26 +300,59 @@ export class UserAPI { // Ziffers related functions // ============================================================= + public generateCacheKey = (...args: any[]): string => { + return args.map((arg) => JSON.stringify(arg)).join(","); + }; + public z = ( input: string, - options: { [key: string]: string | number } = {} + options: InputOptions = {}, + id: number|string = "" ) => { - const generateCacheKey = (...args: any[]): string => { - return args.map((arg) => JSON.stringify(arg)).join(","); - }; - const key = generateCacheKey(input, options); + const zid = "z"+id.toString(); + const key = id==="" ? this.generateCacheKey(input, options) : zid; + let player; + if (this.app.api.patternCache.has(key)) { player = this.app.api.patternCache.get(key) as Player; - } else { + if(player.input!==input) { + player = undefined; + } + } + + if (!player) { player = new Player(input, options, this.app); this.app.api.patternCache.set(key, player); } - if(player) player.updateLastCallTime(); + + + if(typeof id === "number") player.zid = zid; + + player.updateLastCallTime(); + return player; }; + public z0 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 0); + public z1 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 1); + public z2 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 2); + public z3 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 3); + public z4 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 4); + public z5 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 5); + public z6 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 6); + public z7 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 7); + public z8 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 8); + public z9 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 9); + public z10 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 10); + public z11 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 11); + public z12 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 12); + public z13 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 13); + public z14 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 14); + public z15 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 15); + public z16 = (input: string, opts: InputOptions = {}) => this.z(input, opts, 16); + // ============================================================= // Counter and iteration // ============================================================= diff --git a/src/classes/ZPlayer.ts b/src/classes/ZPlayer.ts index ee4b9f9..9643f4f 100644 --- a/src/classes/ZPlayer.ts +++ b/src/classes/ZPlayer.ts @@ -6,10 +6,13 @@ import { SoundEvent } from "./SoundEvent"; import { NoteEvent } from "./MidiEvent"; import { RestEvent } from "./RestEvent"; +export type InputOptions = { [key: string]: string | number }; + export class Player extends Event { input: string; ziffers: Ziffers; - firstCallTime: number = 0; + initCallTime: number = 0; + startCallTime: number = 0; lastCallTime: number = 0; waitTime = 0; startBeat: number = 0; @@ -17,10 +20,13 @@ export class Player extends Event { current!: Pitch|Chord|ZRest; retro: boolean = false; index: number = -1; + zid: string|undefined = undefined; + options: InputOptions = {}; - constructor(input: string, options: object, public app: Editor) { + constructor(input: string, options: InputOptions, public app: Editor) { super(app); this.input = input; + this.options = options; this.ziffers = new Ziffers(input, options); } @@ -30,7 +36,7 @@ export class Player extends Event { } nextEndTime(): number { - return this.firstCallTime + this.ticks; + return this.startCallTime + this.ticks; } updateLastCallTime(): void { @@ -54,6 +60,26 @@ export class Player extends Event { return this.app.clock.convertPulseToSecond(pulse); } + firstRun = (): boolean => { + return this.origin()<=0 && this.notStarted(); + } + + atTheBeginning = (): boolean => { + return this.pulse()===0 && this.ziffers.index===0; + } + + origin = (): number => { + return this.app.clock.pulses_since_origin+1; + } + + pulse = (): number => { + return this.app.clock.time_position.pulse; + } + + nextBeat = (): number => { + return this.app.clock.next_beat_in_ticks; + } + // Check if it's time to play the event areWeThereYet = (): boolean => { // If clock has stopped @@ -68,14 +94,15 @@ export class Player extends Event { this.notStarted() && (this.app.clock.time_position.pulse === 1 || this.app.clock.pulses_since_origin+1 >= this.app.clock.next_beat_in_ticks) && - (this.app.clock.pulses_since_origin+1 >= this.firstCallTime+this.waitTime) + (this.app.clock.pulses_since_origin+1 >= this.waitTime) ) || ( // If pattern is already playing this.current && - this.pulseToSecond(this.app.clock.pulses_since_origin+1) >= + (this.pulseToSecond(this.app.clock.pulses_since_origin+1) >= this.pulseToSecond(this.lastCallTime) + - (this.current.duration*4) * this.pulseToSecond(this.app.api.ppqn()) + (this.current.duration*4) * this.pulseToSecond(this.app.api.ppqn())) && + (this.app.clock.pulses_since_origin+1 >= this.waitTime) ) ); @@ -83,7 +110,11 @@ export class Player extends Event { this.index = howAboutNow ? this.index+1 : this.index; if(howAboutNow && this.notStarted()) { - this.firstCallTime = this.app.clock.pulses_since_origin+1; + this.initCallTime = this.app.clock.pulses_since_origin+1; + } + + if(this.atTheBeginning()) { + this.startCallTime = this.app.clock.pulses_since_origin; } return howAboutNow; @@ -155,7 +186,7 @@ export class Player extends Event { } } */ - this.waitTime = Math.ceil(value*4*this.app.clock.ppqn); + this.waitTime = this.origin() + Math.ceil(value*4*this.app.clock.ppqn); } return this; diff --git a/yarn.lock b/yarn.lock index 347cbc0..50ca12a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1446,10 +1446,9 @@ yaml@^2.1.1: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== -zifferjs@^0.0.14: - version "0.0.14" - resolved "https://registry.yarnpkg.com/zifferjs/-/zifferjs-0.0.14.tgz#7876c799a08e799be7af22b65f4cb6f0b44f79ca" - integrity sha512-CpS3zTm8Btm8aTxd7sSUgVCF/S/jJ3hqwgp7uRzbZI8k6yJWhzo/rjMlEZoOmeBhs7Qy4XsVk7pfrLdS8AAIVA== +"zifferjs@link:../zifferjs": + version "0.0.0" + uid "" zzfx@^1.2.0: version "1.2.0"