From 1824a345fcb8946dc21a08ef591d6ec868a59a2f Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Sat, 20 Apr 2024 03:06:23 +0200 Subject: [PATCH] Repair BPM setter --- src/API/API.ts | 16 ++++++++-------- src/API/Time/Filters.ts | 8 ++++---- src/API/Time/Transport.ts | 26 ++++++-------------------- src/API/Time/Warp.ts | 4 ++-- src/DOM/Visuals/Blinkers.ts | 2 +- src/classes/ZPlayer.ts | 18 +++++++++--------- src/clock/Clock.ts | 18 +++++++++++++++++- src/clock/ClockNode.js | 1 - src/clock/ClockProcessor.js | 2 ++ src/extensions/ArrayExtensions.ts | 4 ++-- 10 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/API/API.ts b/src/API/API.ts index c89b3cd..960cc7a 100644 --- a/src/API/API.ts +++ b/src/API/API.ts @@ -21,7 +21,7 @@ import { type SkipEvent } from '../Classes/SkipEvent'; import { OscilloscopeConfig } from "../DOM/Visuals/Oscilloscope"; import { Player } from "../Classes/ZPlayer"; import { InputOptions } from "../Classes/ZPlayer"; -import { type ShapeObject } from "../DOM/Visuals/CanvasVisuals"; +import { type ShapeObject } from "../API/DOM/Canvas"; import { nearScales } from "zifferjs"; import { MidiConnection } from "../IO/MidiConnection"; import { evaluateOnce } from "../Evaluator"; @@ -112,7 +112,6 @@ export class UserAPI { noteX: () => number; noteY: () => number; tempo: (n?: number | undefined) => number; - bpb: (n?: number | undefined) => number; ppqn: (n?: number | undefined) => number; time_signature: (numerator: number, denominator: number) => void; theme: (color_scheme: string) => void; @@ -282,7 +281,6 @@ export class UserAPI { this.stop = Transport.stop(this); this.silence = Transport.silence(this); this.tempo = Transport.tempo(this.app); - this.bpb = Transport.bpb(this.app); this.ppqn = Transport.ppqn(this.app); this.time_signature = Transport.time_signature(this.app); this.mouseX = Mouse.mouseX(this.app); @@ -527,8 +525,10 @@ export class UserAPI { const match = line.match(/:(\d+):(\d+)/); if (match as RegExpMatchArray) return { + // @ts-ignore line: parseInt(match[1], 10), - column: parseInt(match[2], 10), + // @ts-ignore + column: parseInt(match[2]!, 10), }; } } @@ -583,13 +583,13 @@ export class UserAPI { if (quantization.length === 0) { return value; } - let closest = quantization[0]; + let closest: number | undefined = quantization[0]; quantization.forEach((q) => { - if (Math.abs(q - value) < Math.abs(closest - value)) { + if (Math.abs(q - value) < Math.abs(closest! - value)) { closest = q; } }); - return closest; + return closest!; }; quant = this.quantize; @@ -621,7 +621,7 @@ export class UserAPI { public cue = (functionName: string | Function): void => { functionName = typeof functionName === "function" ? functionName.name : functionName; - this.cueTimes[functionName] = this.app.clock.pulses_since_origin; + this.cueTimes[functionName] = this.app.clock.grain; }; onmousemove = (e: MouseEvent) => { diff --git a/src/API/Time/Filters.ts b/src/API/Time/Filters.ts index df10e7d..2b4ab16 100644 --- a/src/API/Time/Filters.ts +++ b/src/API/Time/Filters.ts @@ -65,7 +65,7 @@ export const bar = (app: Editor) => (n: number | number[] = 1, nudge: number = 0 const nudgeInPulses = Math.floor(nudge * barLength); const results: boolean[] = nArray.map( (value) => - (app.clock.pulses_since_origin - nudgeInPulses) % + (app.clock.grain - nudgeInPulses) % Math.floor(value * barLength) === 0, ); return results.some((value) => value === true); @@ -74,7 +74,7 @@ export const bar = (app: Editor) => (n: number | number[] = 1, nudge: number = 0 export const pulse = (app: Editor) => (n: number | number[] = 1, nudge: number = 0): boolean => { const nArray = Array.isArray(n) ? n : [n]; const results: boolean[] = nArray.map( - (value) => (app.clock.pulses_since_origin - nudge) % value === 0, + (value) => (app.clock.grain - nudge) % value === 0, ); return results.some((value) => value === true); }; @@ -95,7 +95,7 @@ export const dur = (app: Editor) => (n: number | number[]): boolean => { export const flip = (app: Editor) => (chunk: number, ratio: number = 50): boolean => { let realChunk = chunk * 2; - const time_pos = app.clock.pulses_since_origin; + const time_pos = app.clock.grain; const full_chunk = Math.floor(realChunk * app.clock.ppqn); const threshold = Math.floor((ratio / 100) * full_chunk); const pos_within_chunk = time_pos % full_chunk; @@ -137,7 +137,7 @@ export const onbeat = (api: UserAPI) => (...beat: number[]): boolean => { export const oncount = (app: Editor) => (beats: number[] | number, count: number): boolean => { if (typeof beats === "number") beats = [beats]; - const origin = app.clock.pulses_since_origin; + const origin = app.clock.grain; let final_pulses: boolean[] = []; beats.forEach((b) => { b = b < 1 ? 0 : b - 1; diff --git a/src/API/Time/Transport.ts b/src/API/Time/Transport.ts index 975aefe..4faa7b9 100644 --- a/src/API/Time/Transport.ts +++ b/src/API/Time/Transport.ts @@ -39,20 +39,6 @@ export const tempo = (app: Editor) => (n?: number): number => { return n; }; -export const bpb = (app: Editor) => (n?: number): number => { - /** - * Sets or returns the number of beats per bar. - */ - if (n === undefined) return app.clock.time_signature[0] || 4; - - if (n >= 1) { - app.clock.time_signature[0] = n; - } else { - console.error("Beats per bar must be at least 1."); - } - return n; -}; - export const ppqn = (app: Editor) => (n?: number): number => { /** * Sets or returns the number of pulses per quarter note. @@ -74,7 +60,7 @@ export const time_signature = (app: Editor) => (numerator: number, denominator: if (numerator < 1 || denominator < 1) { console.error("Time signature values must be at least 1."); } else { - app.clock.time_signature = [numerator, denominator]; + app.clock.setSignature(numerator, denominator); } }; @@ -83,11 +69,11 @@ export const cbar = (app: Editor) => (): number => { }; export const ctick = (app: Editor) => (): number => { - return app.clock.tick + 1; + return app.clock.grain + 1; }; export const cpulse = (app: Editor) => (): number => { - return app.clock.time_position.pulse + 1; + return app.clock.time_position.tick + 1; }; export const cbeat = (app: Editor) => (): number => { @@ -99,15 +85,15 @@ export const ebeat = (app: Editor) => (): number => { }; export const epulse = (app: Editor) => (): number => { - return app.clock.pulses_since_origin + 1; + return app.clock.grain + 1; }; export const nominator = (app: Editor) => (): number => { - return app.clock.time_signature[0] || 4; + return app.clock.time_position.num; }; export const meter = (app: Editor) => (): number => { - return app.clock.time_signature[1] || 4; + return app.clock.time_position.den; }; export const denominator = meter; diff --git a/src/API/Time/Warp.ts b/src/API/Time/Warp.ts index 1d84e7e..fa58be8 100644 --- a/src/API/Time/Warp.ts +++ b/src/API/Time/Warp.ts @@ -4,7 +4,7 @@ export const warp = (app: Editor) => (n: number): void => { /** * Time-warp the clock by using the tick you wish to jump to. */ - app.clock.tick = n; + app.clock.time_position.tick = n; app.clock.time_position = app.clock.convertTicksToTimeposition(n); }; @@ -13,6 +13,6 @@ export const beat_warp = (app: Editor) => (beat: number): void => { * Time-warp the clock by using the tick you wish to jump to. */ const ticks = beat * app.clock.ppqn; - app.clock.tick = ticks; + app.clock.time_position.tick = ticks; app.clock.time_position = app.clock.convertTicksToTimeposition(ticks); }; diff --git a/src/DOM/Visuals/Blinkers.ts b/src/DOM/Visuals/Blinkers.ts index 6e3b58b..d637d4b 100644 --- a/src/DOM/Visuals/Blinkers.ts +++ b/src/DOM/Visuals/Blinkers.ts @@ -38,7 +38,7 @@ export const blinkScript = ( ) => { if (no !== undefined && no < 1 && no > 9) return; const blinkDuration = - (app.clock.bpm / 60 / app.clock.time_signature[1]!) * 200; + (app.clock.bpm / 60 / app.clock.time_position.num) * 200; // @ts-ignore const ctx = app.interface.feedback.getContext("2d"); diff --git a/src/classes/ZPlayer.ts b/src/classes/ZPlayer.ts index 943606a..8338165 100644 --- a/src/classes/ZPlayer.ts +++ b/src/classes/ZPlayer.ts @@ -93,7 +93,7 @@ export class Player extends AbstractEvent { updateLastCallTime(): void { if (this.notStarted() || this.played) { - this.lastCallTime = this.app.clock.pulses_since_origin; + this.lastCallTime = this.app.clock.grain; this.played = false; } } @@ -121,11 +121,11 @@ export class Player extends AbstractEvent { }; origin = (): number => { - return this.app.clock.pulses_since_origin + 1; + return this.app.clock.grain + 1; }; pulse = (): number => { - return this.app.clock.time_position.pulse; + return this.app.clock.time_position.tick; }; beat = (): number => { @@ -143,7 +143,7 @@ export class Player extends AbstractEvent { // Check if it's time to play the event areWeThereYet = (): boolean => { // If clock has stopped - if (this.app.clock.pulses_since_origin < this.lastCallTime) { + if (this.app.clock.grain < this.lastCallTime) { this.app.api.resetAllFromCache(); } @@ -171,11 +171,11 @@ export class Player extends AbstractEvent { this.index = areWeThereYet ? this.index + 1 : this.index; if (areWeThereYet && this.notStarted()) { - this.initCallTime = this.app.clock.pulses_since_origin; + this.initCallTime = this.app.clock.grain; } if (this.atTheBeginning()) { - this.startCallTime = this.app.clock.pulses_since_origin; + this.startCallTime = this.app.clock.grain; } return areWeThereYet; @@ -470,7 +470,7 @@ export class Player extends AbstractEvent { if(typeof value === "string") { const cueTime = this.app.api.cueTimes[value]; this.cueName = value; - if(cueTime && this.app.clock.pulses_since_origin <= cueTime) { + if(cueTime && this.app.clock.grain <= cueTime) { this.waitTime = cueTime; } else { this.waitTime = -1; @@ -485,7 +485,7 @@ export class Player extends AbstractEvent { if(typeof value === "string") { const cueTime = this.app.api.cueTimes[value]; this.cueName = value; - if(cueTime && this.app.clock.pulses_since_origin <= cueTime) { + if(cueTime && this.app.clock.grain <= cueTime) { this.waitTime = cueTime; } else if(this.atTheBeginning()){ this.waitTime = -1; @@ -521,7 +521,7 @@ export class Player extends AbstractEvent { return this; } if (this.atTheBeginning() && this.notStarted()) { - const origin = this.app.clock.pulses_since_origin; + const origin = this.app.clock.grain; if (origin > 0) { const syncName = typeof value === "function" ? value.name : value; const syncPattern = this.app.api.patternCache.get(syncName) as Player; diff --git a/src/clock/Clock.ts b/src/clock/Clock.ts index 2146a9b..c25572e 100644 --- a/src/clock/Clock.ts +++ b/src/clock/Clock.ts @@ -132,6 +132,22 @@ export class Clock { return remainingTime; } + + public convertTicksToTimeposition(n: number): TimePosition { + /** + * TODO: probably incorrect + */ + const ppqn = this.time_position.ppqn; + const bpm = this.time_position.bpm; + const num = this.time_position.num; + const den = this.time_position.den; + const tick = n % ppqn; + const grain = n; + const beat = Math.floor(n / ppqn) % num; + const bar = Math.floor(n / ppqn / num); + const time = n * this.pulse_duration; + return { bpm, ppqn, time, tick, beat, bar, num, den, grain }; + } public convertPulseToSecond(n: number): number { /** @@ -155,7 +171,7 @@ export class Clock { this.transportNode?.pause() } - public signature(num: number, den: number): void { + public setSignature(num: number, den: number): void { this.transportNode?.setSignature(num, den); } diff --git a/src/clock/ClockNode.js b/src/clock/ClockNode.js index 049f554..60cbcc3 100644 --- a/src/clock/ClockNode.js +++ b/src/clock/ClockNode.js @@ -48,7 +48,6 @@ export class ClockNode extends AudioWorkletNode { } setBPM(bpm) { - console.log("Changement du bpm") this.port.postMessage({ type: "bpm", value: bpm }); } diff --git a/src/clock/ClockProcessor.js b/src/clock/ClockProcessor.js index b922314..0dad628 100644 --- a/src/clock/ClockProcessor.js +++ b/src/clock/ClockProcessor.js @@ -37,6 +37,8 @@ class TransportProcessor extends AudioWorkletProcessor { this.currentPulsePosition = 0; } else if (message.data.type === "bpm") { this.bpm = message.data.value; + this.startTime = currentTime; + this.currentPulsePosition = 0; } else if (message.data.type === "ppqn") { this.ppqn = message.data.value; } else if (message.data.type === "timeSignature") { diff --git a/src/extensions/ArrayExtensions.ts b/src/extensions/ArrayExtensions.ts index d089862..516e035 100644 --- a/src/extensions/ArrayExtensions.ts +++ b/src/extensions/ArrayExtensions.ts @@ -162,7 +162,7 @@ export const makeArrayExtensions = (api: UserAPI) => { Array.prototype.beat = function(divisor: number = 1) { const chunk_size = divisor; - const timepos = api.app.clock.pulses_since_origin; + const timepos = api.app.clock.grain; const slice_count = Math.floor( timepos / Math.floor(chunk_size * api.ppqn()), ); @@ -171,7 +171,7 @@ export const makeArrayExtensions = (api: UserAPI) => { Array.prototype.b = Array.prototype.beat; Array.prototype.dur = function(...durations: number[]) { - const timepos = api.app.clock.pulses_since_origin; + const timepos = api.app.clock.grain; const ppqn = api.ppqn(); const adjustedDurations = this.map( (_, index) => durations[index % durations.length],