Repair BPM setter
This commit is contained in:
@ -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) => {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
@ -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");
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -133,6 +133,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 {
|
||||
/**
|
||||
* Converts a pulse to a second.
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -48,7 +48,6 @@ export class ClockNode extends AudioWorkletNode {
|
||||
}
|
||||
|
||||
setBPM(bpm) {
|
||||
console.log("Changement du bpm")
|
||||
this.port.postMessage({ type: "bpm", value: bpm });
|
||||
}
|
||||
|
||||
|
||||
@ -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") {
|
||||
|
||||
@ -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],
|
||||
|
||||
Reference in New Issue
Block a user