Added new immediate mode for Ziffers evaluation using Ctrl+Shift+Enter.
This commit is contained in:
@ -44,7 +44,7 @@
|
|||||||
"tone": "^14.8.49",
|
"tone": "^14.8.49",
|
||||||
"unique-names-generator": "^4.7.1",
|
"unique-names-generator": "^4.7.1",
|
||||||
"vite-plugin-markdown": "^2.1.0",
|
"vite-plugin-markdown": "^2.1.0",
|
||||||
"zifferjs": "^0.0.58",
|
"zifferjs": "^0.0.59",
|
||||||
"zyklus": "^0.1.4",
|
"zyklus": "^0.1.4",
|
||||||
"zzfx": "^1.2.0"
|
"zzfx": "^1.2.0"
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/API.ts
25
src/API.ts
@ -800,18 +800,27 @@ export class UserAPI {
|
|||||||
|
|
||||||
if (typeof input === "string" &&
|
if (typeof input === "string" &&
|
||||||
player.input !== input &&
|
player.input !== input &&
|
||||||
player.atTheBeginning()) {
|
(player.atTheBeginning() || this.forceEvaluator)) {
|
||||||
replace = true;
|
replace = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((typeof input !== "string" || validSyntax) && (!player || replace)) {
|
if ((typeof input !== "string" || validSyntax) && (!player || replace)) {
|
||||||
const newPlayer = new Player(input, options, this.app, zid);
|
if(typeof input === "string" && player && this.forceEvaluator) {
|
||||||
if (newPlayer.isValid()) {
|
// If pattern change is forced in the middle of the cycle
|
||||||
player = newPlayer
|
if(!player.updatePattern(input, options)) {
|
||||||
this.patternCache.set(key, player);
|
this.logOnce(`Invalid syntax: ${input}`);
|
||||||
} else if (typeof input === "string") {
|
};
|
||||||
this.invalidPatterns[input] = true;
|
this.forceEvaluator = false;
|
||||||
|
} else {
|
||||||
|
// If pattern is not in cache or is to be replaced
|
||||||
|
const newPlayer = player ? new Player(input, options, this.app, zid, player.nextEndTime()) : new Player(input, options, this.app, zid);
|
||||||
|
if (newPlayer.isValid()) {
|
||||||
|
player = newPlayer
|
||||||
|
this.patternCache.set(key, player);
|
||||||
|
} else if (typeof input === "string") {
|
||||||
|
this.invalidPatterns[input] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { MidiEvent, MidiParams } from "./MidiEvent";
|
|||||||
import { RestEvent } from "./RestEvent";
|
import { RestEvent } from "./RestEvent";
|
||||||
import { arrayOfObjectsToObjectWithArrays, isGenerator } from "../Utils/Generic";
|
import { arrayOfObjectsToObjectWithArrays, isGenerator } from "../Utils/Generic";
|
||||||
import { TonnetzSpaces } from "zifferjs/src/tonnetz";
|
import { TonnetzSpaces } from "zifferjs/src/tonnetz";
|
||||||
|
import { safeMod } from "zifferjs/src/utils";
|
||||||
|
|
||||||
export type InputOptions = { [key: string]: string | number };
|
export type InputOptions = { [key: string]: string | number };
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ export class Player extends AbstractEvent {
|
|||||||
options: InputOptions,
|
options: InputOptions,
|
||||||
public app: Editor,
|
public app: Editor,
|
||||||
zid: string = "",
|
zid: string = "",
|
||||||
|
waitTime: number = 0,
|
||||||
) {
|
) {
|
||||||
super(app);
|
super(app);
|
||||||
this.options = options;
|
this.options = options;
|
||||||
@ -46,9 +48,24 @@ export class Player extends AbstractEvent {
|
|||||||
} else {
|
} else {
|
||||||
throw new Error("Invalid input");
|
throw new Error("Invalid input");
|
||||||
}
|
}
|
||||||
|
if(waitTime) this.waitTime = waitTime;
|
||||||
this.zid = zid;
|
this.zid = zid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updatePattern(input: string, options: InputOptions): boolean {
|
||||||
|
const oldIndex = this.ziffers.index;
|
||||||
|
const newPattern = new Ziffers(input, options);
|
||||||
|
if(newPattern.values.length > 0) {
|
||||||
|
this.ziffers = newPattern;
|
||||||
|
this.ziffers.update();
|
||||||
|
this.ziffers.index = oldIndex;
|
||||||
|
this.input = input;
|
||||||
|
this.options = options;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
isValid() {
|
isValid() {
|
||||||
return this.ziffers.values.length > 0;
|
return this.ziffers.values.length > 0;
|
||||||
}
|
}
|
||||||
@ -417,10 +434,8 @@ export class Player extends AbstractEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rotate(amount: number = 1) {
|
rotate(amount: number = 1) {
|
||||||
// TODO: Only works for evaluated patterns (setRedo). Fix this for generative patterns. Mod by current cycle?
|
|
||||||
if (this.atTheBeginning()) {
|
if (this.atTheBeginning()) {
|
||||||
this.ziffers.setRedo(0);
|
this.ziffers.rotate(amount+safeMod(this.ziffers.cycleIndex,this.ziffers.evaluated.length));
|
||||||
this.ziffers.rotate(amount);
|
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,6 +85,7 @@ z1("s A=(0 (1,4)) B~(2 (3,8)) A B A B A")
|
|||||||
* <ic>deal(amount: number): Shuffle the generated pattern and deal given number of elements
|
* <ic>deal(amount: number): Shuffle the generated pattern and deal given number of elements
|
||||||
* <ic>retrograde()</ic> Reverse the generated pattern
|
* <ic>retrograde()</ic> Reverse the generated pattern
|
||||||
* <ic>invert()</ic> Invert the generated pattern
|
* <ic>invert()</ic> Invert the generated pattern
|
||||||
|
* <ic>rotate(amount: number)</ic> Rotate the generated pattern by given amount
|
||||||
* <ic>between(start: number, end: number)</ic> Select a range of elements from the generated pattern
|
* <ic>between(start: number, end: number)</ic> Select a range of elements from the generated pattern
|
||||||
* <ic>from(start: number)</ic> Select a range of elements from the start index to the end of the pattern
|
* <ic>from(start: number)</ic> Select a range of elements from the start index to the end of the pattern
|
||||||
* <ic>to(end: number)</ic> Select a range of elements from the beginning of the pattern to the end index
|
* <ic>to(end: number)</ic> Select a range of elements from the beginning of the pattern to the end index
|
||||||
|
|||||||
@ -32,6 +32,10 @@ z4('1/4 kick kick snare kick').sound().gain(1).cutoff(osci).out()
|
|||||||
true,
|
true,
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
## Evaluation
|
||||||
|
|
||||||
|
Evaluation of live coded Ziffers patterns can be done in 3 different ways. Normal evaluation using <ic>Ctrl+Enter</ic> updates the pattern after the current cycle is finished. Evaluation using <ic>Ctrl+Shift+Enter</ic> updates the pattern immediately keeping the current position, which enables to modify future events even within the current cycle. Evaluation using <ic>Ctrl+Shift+Backspace</ic> resets the current pattern and starts from the beginning immediately.
|
||||||
|
|
||||||
## Notation
|
## Notation
|
||||||
|
|
||||||
The basic Ziffer notation is entirely written in JavaScript strings (_e.g_ <ic>"0 1 2"</ic>). It consists mostly of numbers and letters. The whitespace character is used as a separator. Instead of note names, Ziffer is using numbers to represent musical pitch and letters to represent musical durations. Alternatively, _floating point numbers_ can also be used to represent durations.
|
The basic Ziffer notation is entirely written in JavaScript strings (_e.g_ <ic>"0 1 2"</ic>). It consists mostly of numbers and letters. The whitespace character is used as a separator. Instead of note names, Ziffer is using numbers to represent musical pitch and letters to represent musical durations. Alternatively, _floating point numbers_ can also be used to represent durations.
|
||||||
|
|||||||
@ -4033,10 +4033,10 @@ yaml@^2.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b"
|
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b"
|
||||||
integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==
|
integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==
|
||||||
|
|
||||||
zifferjs@^0.0.58:
|
zifferjs@^0.0.59:
|
||||||
version "0.0.58"
|
version "0.0.59"
|
||||||
resolved "https://registry.yarnpkg.com/zifferjs/-/zifferjs-0.0.58.tgz#206f52479807c6c965b77ec8ff9961847a7f6108"
|
resolved "https://registry.yarnpkg.com/zifferjs/-/zifferjs-0.0.59.tgz#e18ad4f967f98092f6782abbe0a38c5a148c2bac"
|
||||||
integrity sha512-7CTrQkJrlVqmq5CzGK2OAQ0Fof/yLcloRBNPsprZbPQGE7bEUtupnvpFFFKFtt77pUzzbxUG56zyZsjj/HENlA==
|
integrity sha512-bssE9Vtgmcoz2d6390pnX6YWQxsewtXi+3HWdNAmzoM+0bupOGOvpGat79fQ5FqXhV5jjrZl2JzDzLCfcwnM5w==
|
||||||
|
|
||||||
zyklus@^0.1.4:
|
zyklus@^0.1.4:
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
|
|||||||
Reference in New Issue
Block a user