Rewrite part of evaluation logic, run prettier
This commit is contained in:
@ -1,14 +1,10 @@
|
||||
import { type Editor } from "../main";
|
||||
import {
|
||||
freqToMidi,
|
||||
resolvePitchBend,
|
||||
safeScale
|
||||
} from "zifferjs";
|
||||
import { freqToMidi, resolvePitchBend, safeScale } from "zifferjs";
|
||||
|
||||
export type EventOperation<T> = (instance: T, ...args: any[]) => void;
|
||||
|
||||
export interface AbstractEvent {
|
||||
[key: string]: any
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export class AbstractEvent {
|
||||
@ -208,19 +204,26 @@ export class AbstractEvent {
|
||||
return this.modify(func);
|
||||
};
|
||||
|
||||
noteLength = (value: number | number[], ...kwargs: number[]): AbstractEvent => {
|
||||
noteLength = (
|
||||
value: number | number[],
|
||||
...kwargs: number[]
|
||||
): AbstractEvent => {
|
||||
/**
|
||||
* This function is used to set the note length of the Event.
|
||||
*/
|
||||
if(kwargs.length > 0) {
|
||||
value = (Array.isArray(value) ? value.concat(kwargs) : [value, ...kwargs]);
|
||||
if (kwargs.length > 0) {
|
||||
value = Array.isArray(value) ? value.concat(kwargs) : [value, ...kwargs];
|
||||
}
|
||||
if(Array.isArray(value)) {
|
||||
if (Array.isArray(value)) {
|
||||
this.values["noteLength"] = value;
|
||||
this.values.dur = value.map((v) => this.app.clock.convertPulseToSecond(v*4*this.app.clock.ppqn));
|
||||
this.values.dur = value.map((v) =>
|
||||
this.app.clock.convertPulseToSecond(v * 4 * this.app.clock.ppqn),
|
||||
);
|
||||
} else {
|
||||
this.values["noteLength"] = value;
|
||||
this.values.dur = this.app.clock.convertPulseToSecond(value*4*this.app.clock.ppqn);
|
||||
this.values.dur = this.app.clock.convertPulseToSecond(
|
||||
value * 4 * this.app.clock.ppqn,
|
||||
);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
@ -232,83 +235,95 @@ export abstract class AudibleEvent extends AbstractEvent {
|
||||
}
|
||||
|
||||
pitch = (value: number | number[], ...kwargs: number[]): this => {
|
||||
/*
|
||||
* This function is used to set the pitch of the Event.
|
||||
* @param value - The pitch value
|
||||
* @returns The Event
|
||||
*/
|
||||
if(kwargs.length > 0) {
|
||||
value = (Array.isArray(value) ? value.concat(kwargs) : [value, ...kwargs]);
|
||||
/*
|
||||
* This function is used to set the pitch of the Event.
|
||||
* @param value - The pitch value
|
||||
* @returns The Event
|
||||
*/
|
||||
if (kwargs.length > 0) {
|
||||
value = Array.isArray(value) ? value.concat(kwargs) : [value, ...kwargs];
|
||||
}
|
||||
this.values["pitch"] = value;
|
||||
if(this.values.key && this.values.parsedScale) this.update();
|
||||
if (this.values.key && this.values.parsedScale) this.update();
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
pc = this.pitch;
|
||||
|
||||
octave = (value: number | number[], ...kwargs: number[]): this => {
|
||||
/*
|
||||
* This function is used to set the octave of the Event.
|
||||
* @param value - The octave value
|
||||
* @returns The Event
|
||||
*/
|
||||
if(kwargs.length > 0) {
|
||||
value = (Array.isArray(value) ? value.concat(kwargs) : [value, ...kwargs]);
|
||||
* This function is used to set the octave of the Event.
|
||||
* @param value - The octave value
|
||||
* @returns The Event
|
||||
*/
|
||||
if (kwargs.length > 0) {
|
||||
value = Array.isArray(value) ? value.concat(kwargs) : [value, ...kwargs];
|
||||
}
|
||||
this.values["octave"] = value;
|
||||
if(this.values.key && (this.values.pitch || this.values.pitch === 0) && this.values.parsedScale) this.update();
|
||||
if (
|
||||
this.values.key &&
|
||||
(this.values.pitch || this.values.pitch === 0) &&
|
||||
this.values.parsedScale
|
||||
)
|
||||
this.update();
|
||||
return this;
|
||||
};
|
||||
|
||||
key = (value: string | string[], ...kwargs: string[]): this => {
|
||||
/*
|
||||
* This function is used to set the key of the Event.
|
||||
* @param value - The key value
|
||||
* @returns The Event
|
||||
*/
|
||||
if(kwargs.length > 0) {
|
||||
value = (Array.isArray(value) ? value.concat(kwargs) : [value, ...kwargs]);
|
||||
/*
|
||||
* This function is used to set the key of the Event.
|
||||
* @param value - The key value
|
||||
* @returns The Event
|
||||
*/
|
||||
if (kwargs.length > 0) {
|
||||
value = Array.isArray(value) ? value.concat(kwargs) : [value, ...kwargs];
|
||||
}
|
||||
this.values["key"] = value;
|
||||
if((this.values.pitch || this.values.pitch === 0) && this.values.parsedScale) this.update();
|
||||
if (
|
||||
(this.values.pitch || this.values.pitch === 0) &&
|
||||
this.values.parsedScale
|
||||
)
|
||||
this.update();
|
||||
return this;
|
||||
};
|
||||
|
||||
scale = (value: string | number | (number|string)[], ...kwargs: (string|number)[]): this => {
|
||||
scale = (
|
||||
value: string | number | (number | string)[],
|
||||
...kwargs: (string | number)[]
|
||||
): this => {
|
||||
/*
|
||||
* This function is used to set the scale of the Event.
|
||||
* @param value - The scale value
|
||||
* @returns The Event
|
||||
*/
|
||||
if(kwargs.length > 0) {
|
||||
value = (Array.isArray(value) ? value.concat(kwargs) : [value, ...kwargs]);
|
||||
* This function is used to set the scale of the Event.
|
||||
* @param value - The scale value
|
||||
* @returns The Event
|
||||
*/
|
||||
if (kwargs.length > 0) {
|
||||
value = Array.isArray(value) ? value.concat(kwargs) : [value, ...kwargs];
|
||||
}
|
||||
if (typeof value === "string" || typeof value === "number") {
|
||||
this.values.parsedScale = safeScale(value) as number[];
|
||||
} else if(Array.isArray(value)) {
|
||||
} else if (Array.isArray(value)) {
|
||||
this.values.parsedScale = value.map((v) => safeScale(v));
|
||||
}
|
||||
if(this.values.key && (this.values.pitch || this.values.pitch === 0)) {
|
||||
this.update();
|
||||
if (this.values.key && (this.values.pitch || this.values.pitch === 0)) {
|
||||
this.update();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
freq = (value: number | number[], ...kwargs: number[]): this => {
|
||||
/*
|
||||
* This function is used to set the frequency of the Event.
|
||||
* @param value - The frequency value
|
||||
* @returns The Event
|
||||
*/
|
||||
if(kwargs.length > 0) {
|
||||
value = (Array.isArray(value) ? value.concat(kwargs) : [value, ...kwargs]);
|
||||
* This function is used to set the frequency of the Event.
|
||||
* @param value - The frequency value
|
||||
* @returns The Event
|
||||
*/
|
||||
if (kwargs.length > 0) {
|
||||
value = Array.isArray(value) ? value.concat(kwargs) : [value, ...kwargs];
|
||||
}
|
||||
this.values["freq"] = value;
|
||||
if(Array.isArray(value)) {
|
||||
if (Array.isArray(value)) {
|
||||
this.values["note"] = [];
|
||||
this.values["bend"] = [];
|
||||
for(const v of value) {
|
||||
for (const v of value) {
|
||||
const midiNote = freqToMidi(v);
|
||||
if (midiNote % 1 !== 0) {
|
||||
this.values["note"].push(Math.floor(midiNote));
|
||||
@ -317,7 +332,7 @@ export abstract class AudibleEvent extends AbstractEvent {
|
||||
this.values["note"].push(midiNote);
|
||||
}
|
||||
}
|
||||
if(this.values.bend.length === 0) delete this.values.bend;
|
||||
if (this.values.bend.length === 0) delete this.values.bend;
|
||||
} else {
|
||||
const midiNote = freqToMidi(value);
|
||||
if (midiNote % 1 !== 0) {
|
||||
|
||||
@ -2,7 +2,11 @@ import { AudibleEvent } from "./AbstractEvents";
|
||||
import { type Editor } from "../main";
|
||||
import { MidiConnection } from "../IO/MidiConnection";
|
||||
import { noteFromPc, chord as parseChord } from "zifferjs";
|
||||
import { filterObject, arrayOfObjectsToObjectWithArrays, objectWithArraysToArrayOfObjects } from "../Utils/Generic";
|
||||
import {
|
||||
filterObject,
|
||||
arrayOfObjectsToObjectWithArrays,
|
||||
objectWithArraysToArrayOfObjects,
|
||||
} from "../Utils/Generic";
|
||||
|
||||
export type MidiParams = {
|
||||
note: number;
|
||||
@ -11,22 +15,25 @@ export type MidiParams = {
|
||||
port?: number;
|
||||
sustain?: number;
|
||||
velocity?: number;
|
||||
}
|
||||
};
|
||||
|
||||
export class MidiEvent extends AudibleEvent {
|
||||
midiConnection: MidiConnection;
|
||||
|
||||
constructor(input: MidiParams, public app: Editor) {
|
||||
constructor(
|
||||
input: MidiParams,
|
||||
public app: Editor,
|
||||
) {
|
||||
super(app);
|
||||
this.values = input;
|
||||
this.midiConnection = app.api.MidiConnection;
|
||||
}
|
||||
|
||||
public chord = (value: string) => {
|
||||
this.values.note = parseChord(value);
|
||||
return this;
|
||||
this.values.note = parseChord(value);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
note = (value: number | number[]): this => {
|
||||
this.values["note"] = value;
|
||||
return this;
|
||||
@ -40,7 +47,7 @@ export class MidiEvent extends AudibleEvent {
|
||||
velocity = (value: number | number[]): this => {
|
||||
this.values["velocity"] = value;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
channel = (value: number | number[]): this => {
|
||||
this.values["channel"] = value;
|
||||
@ -48,10 +55,12 @@ export class MidiEvent extends AudibleEvent {
|
||||
};
|
||||
|
||||
port = (value: number | string | number[] | string[]): this => {
|
||||
if(typeof value === "string"){
|
||||
if (typeof value === "string") {
|
||||
this.values["port"] = this.midiConnection.getMidiOutputIndex(value);
|
||||
} else if(Array.isArray(value)){
|
||||
this.values["port"] = value.map((v) => typeof v === "string" ? this.midiConnection.getMidiOutputIndex(v) : v);
|
||||
} else if (Array.isArray(value)) {
|
||||
this.values["port"] = value.map((v) =>
|
||||
typeof v === "string" ? this.midiConnection.getMidiOutputIndex(v) : v,
|
||||
);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
@ -86,25 +95,32 @@ export class MidiEvent extends AudibleEvent {
|
||||
|
||||
update = (): void => {
|
||||
// Get key, pitch, parsedScale and octave from this.values object
|
||||
const filteredValues = filterObject(this.values, ["key", "pitch", "parsedScale", "octave"]);
|
||||
|
||||
const events = objectWithArraysToArrayOfObjects(filteredValues,["parsedScale"]);
|
||||
const filteredValues = filterObject(this.values, [
|
||||
"key",
|
||||
"pitch",
|
||||
"parsedScale",
|
||||
"octave",
|
||||
]);
|
||||
|
||||
const events = objectWithArraysToArrayOfObjects(filteredValues, [
|
||||
"parsedScale",
|
||||
]);
|
||||
|
||||
events.forEach((event) => {
|
||||
const [note, bend] = noteFromPc(
|
||||
event.key as number || "C4",
|
||||
event.pitch as number || 0,
|
||||
event.parsedScale as number[] || event.scale || "MAJOR",
|
||||
event.octave as number || 0
|
||||
(event.key as number) || "C4",
|
||||
(event.pitch as number) || 0,
|
||||
(event.parsedScale as number[]) || event.scale || "MAJOR",
|
||||
(event.octave as number) || 0,
|
||||
);
|
||||
event.note = note;
|
||||
if(bend) event.bend = bend;
|
||||
if (bend) event.bend = bend;
|
||||
});
|
||||
|
||||
const newArrays = arrayOfObjectsToObjectWithArrays(events) as MidiParams;
|
||||
|
||||
this.values.note = newArrays.note;
|
||||
if(newArrays.bend) this.values.bend = newArrays.bend;
|
||||
if (newArrays.bend) this.values.bend = newArrays.bend;
|
||||
};
|
||||
|
||||
out = (): void => {
|
||||
@ -114,9 +130,7 @@ export class MidiEvent extends AudibleEvent {
|
||||
const note = params.note ? params.note : 60;
|
||||
|
||||
const sustain = params.sustain
|
||||
? params.sustain *
|
||||
event.app.clock.pulse_duration *
|
||||
event.app.api.ppqn()
|
||||
? params.sustain * event.app.clock.pulse_duration * event.app.api.ppqn()
|
||||
: event.app.clock.pulse_duration * event.app.api.ppqn();
|
||||
|
||||
const bend = params.bend ? params.bend : undefined;
|
||||
@ -124,22 +138,23 @@ export class MidiEvent extends AudibleEvent {
|
||||
const port = params.port
|
||||
? event.midiConnection.getMidiOutputIndex(params.port)
|
||||
: event.midiConnection.getCurrentMidiPortIndex() || 0;
|
||||
|
||||
|
||||
event.midiConnection.sendMidiNote(
|
||||
note,
|
||||
channel,
|
||||
velocity,
|
||||
sustain,
|
||||
port,
|
||||
bend
|
||||
bend,
|
||||
);
|
||||
}
|
||||
|
||||
const events = objectWithArraysToArrayOfObjects(this.values,["parsedScale"]) as MidiParams[];
|
||||
const events = objectWithArraysToArrayOfObjects(this.values, [
|
||||
"parsedScale",
|
||||
]) as MidiParams[];
|
||||
|
||||
events.forEach((p: MidiParams) => {
|
||||
play(this,p);
|
||||
play(this, p);
|
||||
});
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@ -11,10 +11,7 @@ export class RestEvent extends AbstractEvent {
|
||||
return RestEvent.createRestProxy(this.values["noteLength"], this.app);
|
||||
};
|
||||
|
||||
public static createRestProxy = (
|
||||
length: number,
|
||||
app: Editor
|
||||
): RestEvent => {
|
||||
public static createRestProxy = (length: number, app: Editor): RestEvent => {
|
||||
const instance = new RestEvent(length, app);
|
||||
return new Proxy(instance, {
|
||||
// @ts-ignore
|
||||
|
||||
@ -293,7 +293,10 @@ export class SoundEvent extends AudibleEvent {
|
||||
},
|
||||
};
|
||||
|
||||
constructor(sound: string | string[] | SoundParams, public app: Editor) {
|
||||
constructor(
|
||||
sound: string | string[] | SoundParams,
|
||||
public app: Editor,
|
||||
) {
|
||||
super(app);
|
||||
this.nudge = app.dough_nudge / 100;
|
||||
|
||||
@ -312,7 +315,7 @@ export class SoundEvent extends AudibleEvent {
|
||||
}
|
||||
|
||||
private processSound = (
|
||||
sound: string | string[] | SoundParams | SoundParams[]
|
||||
sound: string | string[] | SoundParams | SoundParams[],
|
||||
): SoundParams => {
|
||||
if (Array.isArray(sound) && typeof sound[0] === "string") {
|
||||
const s: string[] = [];
|
||||
@ -356,7 +359,7 @@ export class SoundEvent extends AudibleEvent {
|
||||
|
||||
private updateValue<T>(
|
||||
key: string,
|
||||
value: T | T[] | SoundParams[] | null
|
||||
value: T | T[] | SoundParams[] | null,
|
||||
): this {
|
||||
if (value == null) return this;
|
||||
this.values[key] = value;
|
||||
@ -392,7 +395,7 @@ export class SoundEvent extends AudibleEvent {
|
||||
(event.key as number) || "C4",
|
||||
(event.pitch as number) || 0,
|
||||
(event.parsedScale as number[]) || event.scale || "MAJOR",
|
||||
(event.octave as number) || 0
|
||||
(event.octave as number) || 0,
|
||||
);
|
||||
event.note = note;
|
||||
event.freq = midiToFreq(note);
|
||||
@ -412,7 +415,7 @@ export class SoundEvent extends AudibleEvent {
|
||||
public invert = (howMany: number = 0) => {
|
||||
if (this.values.chord) {
|
||||
let notes = this.values.chord.map(
|
||||
(obj: { [key: string]: number }) => obj.note
|
||||
(obj: { [key: string]: number }) => obj.note,
|
||||
);
|
||||
notes = howMany < 0 ? [...notes].reverse() : notes;
|
||||
for (let i = 0; i < Math.abs(howMany); i++) {
|
||||
@ -448,8 +451,14 @@ export class SoundEvent extends AudibleEvent {
|
||||
// const filteredEvent = filterObject(event, ["analyze","note","dur","freq","s"]);
|
||||
const filteredEvent = event;
|
||||
// No need for note if there is freq
|
||||
if (filteredEvent.freq) { delete filteredEvent.note; }
|
||||
superdough(filteredEvent, this.nudge - this.app.clock.deviation, filteredEvent.dur);
|
||||
if (filteredEvent.freq) {
|
||||
delete filteredEvent.note;
|
||||
}
|
||||
superdough(
|
||||
filteredEvent,
|
||||
this.nudge - this.app.clock.deviation,
|
||||
filteredEvent.dur,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import { TonnetzSpaces } from "zifferjs/src/tonnetz";
|
||||
export type InputOptions = { [key: string]: string | number };
|
||||
|
||||
export class Player extends AbstractEvent {
|
||||
input: string|number;
|
||||
input: string | number;
|
||||
ziffers: Ziffers;
|
||||
initCallTime: number = 0;
|
||||
startCallTime: number = 0;
|
||||
@ -26,7 +26,7 @@ export class Player extends AbstractEvent {
|
||||
skipIndex = 0;
|
||||
|
||||
constructor(
|
||||
input: string|number|Generator<number>,
|
||||
input: string | number | Generator<number>,
|
||||
options: InputOptions,
|
||||
public app: Editor,
|
||||
zid: string = ""
|
||||
@ -38,9 +38,9 @@ export class Player extends AbstractEvent {
|
||||
this.ziffers = new Ziffers(input, options);
|
||||
} else if (typeof input === "number") {
|
||||
this.input = input;
|
||||
this.ziffers = Ziffers.fromNumber(input,options);
|
||||
this.ziffers = Ziffers.fromNumber(input, options);
|
||||
} else {
|
||||
this.ziffers = Ziffers.fromGenerator(input,options);
|
||||
this.ziffers = Ziffers.fromGenerator(input, options);
|
||||
this.input = this.ziffers.input;
|
||||
}
|
||||
this.zid = zid;
|
||||
@ -246,6 +246,7 @@ export class Player extends AbstractEvent {
|
||||
}
|
||||
|
||||
tonnetz(transform: string, tonnetz: TonnetzSpaces = [3, 4, 5]) {
|
||||
// @ts-ignore
|
||||
if (this.atTheBeginning()) this.ziffers.tonnetz(transform, tonnetz);
|
||||
return this;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user