Repair BPM setter

This commit is contained in:
2024-04-20 03:06:23 +02:00
parent 605db460e5
commit 1824a345fc
10 changed files with 51 additions and 48 deletions

View File

@ -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(/<anonymous>:(\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) => {

View File

@ -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;

View File

@ -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;

View File

@ -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);
};

View File

@ -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");

View File

@ -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;

View File

@ -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);
}

View File

@ -48,7 +48,6 @@ export class ClockNode extends AudioWorkletNode {
}
setBPM(bpm) {
console.log("Changement du bpm")
this.port.postMessage({ type: "bpm", value: bpm });
}

View File

@ -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") {

View File

@ -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],