diff --git a/dev-dist/sw.js b/dev-dist/sw.js index 11a041c..84c4be9 100644 --- a/dev-dist/sw.js +++ b/dev-dist/sw.js @@ -21,22 +21,20 @@ if (!self.define) { const singleRequire = (uri, parentUri) => { uri = new URL(uri + ".js", parentUri).href; - return registry[uri] || ( - - new Promise(resolve => { - if ("document" in self) { - const script = document.createElement("script"); - script.src = uri; - script.onload = resolve; - document.head.appendChild(script); - } else { - nextDefineUri = uri; - importScripts(uri); - resolve(); - } - }) - - .then(() => { + return ( + registry[uri] || + new Promise((resolve) => { + if ("document" in self) { + const script = document.createElement("script"); + script.src = uri; + script.onload = resolve; + document.head.appendChild(script); + } else { + nextDefineUri = uri; + importScripts(uri); + resolve(); + } + }).then(() => { let promise = registry[uri]; if (!promise) { throw new Error(`Module ${uri} didn’t register its module`); @@ -47,27 +45,31 @@ if (!self.define) { }; self.define = (depsNames, factory) => { - const uri = nextDefineUri || ("document" in self ? document.currentScript.src : "") || location.href; + const uri = + nextDefineUri || + ("document" in self ? document.currentScript.src : "") || + location.href; if (registry[uri]) { // Module is already loading or loaded. return; } let exports = {}; - const require = depUri => singleRequire(depUri, uri); + const require = (depUri) => singleRequire(depUri, uri); const specialDeps = { module: { uri }, exports, - require + require, }; - registry[uri] = Promise.all(depsNames.map( - depName => specialDeps[depName] || require(depName) - )).then(deps => { + registry[uri] = Promise.all( + depsNames.map((depName) => specialDeps[depName] || require(depName)) + ).then((deps) => { factory(...deps); return exports; }); }; } -define(['./workbox-b7fccfec'], (function (workbox) { 'use strict'; +define(["./workbox-b7fccfec"], function (workbox) { + "use strict"; self.skipWaiting(); workbox.clientsClaim(); @@ -77,28 +79,44 @@ define(['./workbox-b7fccfec'], (function (workbox) { 'use strict'; * requests for URLs in the manifest. * See https://goo.gl/S9QRab */ - workbox.precacheAndRoute([{ - "url": "registerSW.js", - "revision": "3ca0b8505b4bec776b69afdba2768812" - }, { - "url": "index.html", - "revision": "0.djkmkn674mo" - }], {}); + workbox.precacheAndRoute( + [ + { + url: "registerSW.js", + revision: "3ca0b8505b4bec776b69afdba2768812", + }, + { + url: "index.html", + revision: "0.djkmkn674mo", + }, + ], + {} + ); workbox.cleanupOutdatedCaches(); - workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { - allowlist: [/^\/$/] - })); - workbox.registerRoute(({ - url - }) => [/^https:\/\/raw\.githubusercontent\.com\/.*/i, /^https:\/\/shabda\.ndre\.gr\/.*/i].some(regex => regex.test(url)), new workbox.CacheFirst({ - "cacheName": "external-samples", - plugins: [new workbox.ExpirationPlugin({ - maxEntries: 5000, - maxAgeSeconds: 2592000 - }), new workbox.CacheableResponsePlugin({ - statuses: [0, 200] - })] - }), 'GET'); - -})); + workbox.registerRoute( + new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { + allowlist: [/^\/$/], + }) + ); + workbox.registerRoute( + ({ url }) => + [ + /^https:\/\/raw\.githubusercontent\.com\/.*/i, + /^https:\/\/shabda\.ndre\.gr\/.*/i, + ].some((regex) => regex.test(url)), + new workbox.CacheFirst({ + cacheName: "external-samples", + plugins: [ + new workbox.ExpirationPlugin({ + maxEntries: 5000, + maxAgeSeconds: 2592000, + }), + new workbox.CacheableResponsePlugin({ + statuses: [0, 200], + }), + ], + }), + "GET" + ); +}); //# sourceMappingURL=sw.js.map diff --git a/dev-dist/sw.js.map b/dev-dist/sw.js.map index 24a7f0e..66a28bf 100644 --- a/dev-dist/sw.js.map +++ b/dev-dist/sw.js.map @@ -1 +1 @@ -{"version":3,"file":"sw.js","sources":["../../../private/var/folders/zq/nwpwzg_s2rq87xq7zggqfvhw0000gn/T/c998952bf0d3f0867ef8942fa27558f7/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/bubo/Topos/node_modules/workbox-routing/registerRoute.mjs';\nimport {ExpirationPlugin as workbox_expiration_ExpirationPlugin} from '/Users/bubo/Topos/node_modules/workbox-expiration/ExpirationPlugin.mjs';\nimport {CacheableResponsePlugin as workbox_cacheable_response_CacheableResponsePlugin} from '/Users/bubo/Topos/node_modules/workbox-cacheable-response/CacheableResponsePlugin.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/Users/bubo/Topos/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/bubo/Topos/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/Users/bubo/Topos/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from '/Users/bubo/Topos/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/Users/bubo/Topos/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/Users/bubo/Topos/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"registerSW.js\",\n \"revision\": \"3ca0b8505b4bec776b69afdba2768812\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"0.djkmkn674mo\"\n }\n], {});\nworkbox_precaching_cleanupOutdatedCaches();\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"index.html\"), {\n allowlist: [/^\\/$/],\n \n}));\n\n\nworkbox_routing_registerRoute(({ url }) => [\n /^https:\\/\\/raw\\.githubusercontent\\.com\\/.*/i,\n /^https:\\/\\/shabda\\.ndre\\.gr\\/.*/i\n ].some((regex) => regex.test(url)), new workbox_strategies_CacheFirst({ \"cacheName\":\"external-samples\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 5000, maxAgeSeconds: 2592000 }), new workbox_cacheable_response_CacheableResponsePlugin({ statuses: [ 0, 200 ] })] }), 'GET');\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","workbox_precaching_cleanupOutdatedCaches","workbox_routing_registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","allowlist","url","some","regex","test","workbox_strategies_CacheFirst","plugins","workbox_expiration_ExpirationPlugin","maxEntries","maxAgeSeconds","workbox_cacheable_response_CacheableResponsePlugin","statuses"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"sw.js","sources":["../../../private/var/folders/zq/nwpwzg_s2rq87xq7zggqfvhw0000gn/T/c998952bf0d3f0867ef8942fa27558f7/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/bubo/Topos/node_modules/workbox-routing/registerRoute.mjs';\nimport {ExpirationPlugin as workbox_expiration_ExpirationPlugin} from '/Users/bubo/Topos/node_modules/workbox-expiration/ExpirationPlugin.mjs';\nimport {CacheableResponsePlugin as workbox_cacheable_response_CacheableResponsePlugin} from '/Users/bubo/Topos/node_modules/workbox-cacheable-response/CacheableResponsePlugin.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/Users/bubo/Topos/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/bubo/Topos/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/Users/bubo/Topos/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from '/Users/bubo/Topos/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/Users/bubo/Topos/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/Users/bubo/Topos/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"registerSW.js\",\n \"revision\": \"3ca0b8505b4bec776b69afdba2768812\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"0.djkmkn674mo\"\n }\n], {});\nworkbox_precaching_cleanupOutdatedCaches();\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"index.html\"), {\n allowlist: [/^\\/$/],\n \n}));\n\n\nworkbox_routing_registerRoute(({ url }) => [\n /^https:\\/\\/raw\\.githubusercontent\\.com\\/.*/i,\n /^https:\\/\\/shabda\\.ndre\\.gr\\/.*/i\n ].some((regex) => regex.test(url)), new workbox_strategies_CacheFirst({ \"cacheName\":\"external-samples\", plugins: [new workbox_expiration_ExpirationPlugin({ maxEntries: 5000, maxAgeSeconds: 2592000 }), new workbox_cacheable_response_CacheableResponsePlugin({ statuses: [ 0, 200 ] })] }), 'GET');\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","workbox_precaching_cleanupOutdatedCaches","workbox_routing_registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","allowlist","url","some","regex","test","workbox_strategies_CacheFirst","plugins","workbox_expiration_ExpirationPlugin","maxEntries","maxAgeSeconds","workbox_cacheable_response_CacheableResponsePlugin","statuses"],"mappings":"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"} diff --git a/package.json b/package.json index 369d5a1..154226c 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "autoprefixer": "^10.4.14", "codemirror": "^6.0.1", "fflate": "^0.8.0", + "jisg": "^0.9.7", "lru-cache": "^10.0.1", "marked": "^7.0.3", "postcss": "^8.4.27", @@ -41,7 +42,7 @@ "tone": "^14.8.49", "unique-names-generator": "^4.7.1", "vite-plugin-markdown": "^2.1.0", - "zifferjs": "^0.0.34", + "zifferjs": "^0.0.35", "zzfx": "^1.2.0" } } diff --git a/src/API.ts b/src/API.ts index ad8d2af..3c94853 100644 --- a/src/API.ts +++ b/src/API.ts @@ -1,5 +1,5 @@ import { EditorView } from "@codemirror/view"; -import { getAllScaleNotes, seededRandom } from "zifferjs"; +import { getAllScaleNotes, nearScales, seededRandom } from "zifferjs"; import { MidiCCEvent, MidiConnection, @@ -25,7 +25,7 @@ import { soundMap, // @ts-ignore } from "superdough"; -import { Speaker } from "./StringExtensions"; +import { Speaker } from "./extensions/StringExtensions"; import { getScaleNotes } from "zifferjs"; import { OscilloscopeConfig, blinkScript } from "./AudioVisualisation"; import { SkipEvent } from "./classes/SkipEvent"; @@ -681,8 +681,12 @@ export class UserAPI { this.patternCache.forEach((player) => (player as Player).reset()); }; + public removePatternFromCache = (id: string): void => { + this.patternCache.delete(id); + }; + public z = ( - input: string, + input: string | Generator, options: InputOptions = {}, id: number | string = "" ): Player => { @@ -693,7 +697,7 @@ export class UserAPI { if (this.app.api.patternCache.has(key)) { player = this.app.api.patternCache.get(key) as Player; - if (player.input !== input) { + if (typeof input === "string" && player.input !== input) { player = undefined; } } @@ -703,6 +707,10 @@ export class UserAPI { this.app.api.patternCache.set(key, player); } + if(player.ziffers.generator && player.ziffers.generatorDone) { + this.removePatternFromCache(key); + } + if (typeof id === "number") player.zid = zid; player.updateLastCallTime(); @@ -1832,6 +1840,8 @@ export class UserAPI { scale = getScaleNotes; + nearScales = nearScales; + rate = (rate: number): void => { rate = rate; // TODO: Implement this. This function should change the rate at which the global script diff --git a/src/StringExtensions.ts b/src/StringExtensions.ts deleted file mode 100644 index 31d68d1..0000000 --- a/src/StringExtensions.ts +++ /dev/null @@ -1,230 +0,0 @@ -import { noteNameToMidi } from "zifferjs"; -import { type UserAPI } from "./API"; -import { Player } from "./classes/ZPlayer"; -export { }; - -// Extend String prototype -declare global { - interface String { - speak(): void; - rate(speed: number): string; - pitch(pitch: number): string; - volume(volume: number): string; - voice(voice: number): string; - lang(language: string): string; - options(): SpeechOptions; - z(): Player; - z0(): Player; - z1(): Player; - z2(): Player; - z3(): Player; - z4(): Player; - z5(): Player; - z6(): Player; - z7(): Player; - z8(): Player; - z9(): Player; - z10(): Player; - z11(): Player; - z12(): Player; - z13(): Player; - z14(): Player; - z15(): Player; - z16(): Player; - note(): number; - } -} - -const isJsonString = (str: string): boolean => { - return str[0] === '{' && str[str.length - 1] === '}' -} - -const stringObject = (str: string, params: object) => { - if (isJsonString(str)) { - const obj = JSON.parse(str); - return JSON.stringify({ ...obj, ...params }); - } else { - return JSON.stringify({ ...params, text: str }); - } -} - -export const makeStringExtensions = (api: UserAPI) => { - String.prototype.speak = function() { - const options = JSON.parse(this.valueOf()); - new Speaker({ ...options, text: options.text }).speak().then(() => { - // Done - }).catch((e) => { - console.log("Error speaking:", e); - }); - }; - - String.prototype.rate = function(speed: number) { - return stringObject(this.valueOf(), { rate: speed }); - }; - - String.prototype.pitch = function(pitch: number) { - return stringObject(this.valueOf(), { pitch: pitch }); - }; - - String.prototype.lang = function(language: string) { - return stringObject(this.valueOf(), { lang: language }); - }; - - String.prototype.volume = function(volume: number) { - return stringObject(this.valueOf(), { volume: volume }); - }; - - String.prototype.voice = function(voice: number) { - return stringObject(this.valueOf(), { voice: voice }); - }; - - String.prototype.z = function(options: { [key: string]: any } = {}) { - return api.z(this.valueOf(), options); - }; - - String.prototype.z0 = function(options: { [key: string]: any } = {}) { - return api.z0(this.valueOf(), options); - }; - - String.prototype.z1 = function(options: { [key: string]: any } = {}) { - return api.z1(this.valueOf(), options); - }; - - String.prototype.z2 = function(options: { [key: string]: any } = {}) { - return api.z2(this.valueOf(), options); - }; - - String.prototype.z3 = function(options: { [key: string]: any } = {}) { - return api.z3(this.valueOf(), options); - }; - - String.prototype.z4 = function(options: { [key: string]: any } = {}) { - return api.z4(this.valueOf(), options); - }; - - String.prototype.z5 = function(options: { [key: string]: any } = {}) { - return api.z5(this.valueOf(), options); - }; - - String.prototype.z6 = function(options: { [key: string]: any } = {}) { - return api.z6(this.valueOf(), options); - }; - - String.prototype.z7 = function(options: { [key: string]: any } = {}) { - return api.z7(this.valueOf(), options); - }; - - String.prototype.z8 = function(options: { [key: string]: any } = {}) { - return api.z8(this.valueOf(), options); - }; - - String.prototype.z9 = function(options: { [key: string]: any } = {}) { - return api.z9(this.valueOf(), options); - }; - - String.prototype.z10 = function(options: { [key: string]: any } = {}) { - return api.z10(this.valueOf(), options); - }; - - String.prototype.z11 = function(options: { [key: string]: any } = {}) { - return api.z11(this.valueOf(), options); - }; - - String.prototype.z12 = function(options: { [key: string]: any } = {}) { - return api.z12(this.valueOf(), options); - }; - - String.prototype.z13 = function(options: { [key: string]: any } = {}) { - return api.z13(this.valueOf(), options); - }; - - String.prototype.z14 = function(options: { [key: string]: any } = {}) { - return api.z14(this.valueOf(), options); - }; - - String.prototype.z15 = function(options: { [key: string]: any } = {}) { - return api.z15(this.valueOf(), options); - }; - - String.prototype.z16 = function(options: { [key: string]: any } = {}) { - return api.z16(this.valueOf(), options); - }; - - String.prototype.note = function() { - try { - return parseInt(this.valueOf()); - } catch (e) { - return noteNameToMidi(this.valueOf()); - } - }; -} - -type SpeechOptions = { - text?: string; - rate?: number; - pitch?: number; - volume?: number; - voice?: number; - lang?: string; -} - -let speakerTimeout: number; - -export class Speaker { - constructor( - public options: SpeechOptions - ) { } - - speak = () => { - return new Promise((resolve, reject) => { - if (this.options.text) { - const synth = window.speechSynthesis; - if (synth.speaking) synth.cancel(); - - const utterance = new SpeechSynthesisUtterance(this.options.text); - utterance.rate = this.options.rate || 1; - utterance.pitch = this.options.pitch || 1; - utterance.volume = this.options.volume || 1; - if (this.options.voice) { - utterance.voice = synth.getVoices()[this.options.voice]; - } - if (this.options.lang) { - // Check if language has country code - if (this.options.lang.length === 2) { - utterance.lang = `${this.options.lang}-${this.options.lang.toUpperCase()}` - } else if (this.options.lang.length === 5) { - utterance.lang = this.options.lang; - } else { - // Fallback to en us - utterance.lang = 'en-US'; - } - } - - utterance.onend = () => { - resolve(); - }; - - utterance.onerror = (error) => { - reject(error); - }; - - if (synth.speaking) { - // Cancel again? - synth.cancel(); - // Set timeout - if (speakerTimeout) clearTimeout(speakerTimeout); - // @ts-ignore - speakerTimeout = setTimeout(() => { - synth.speak(utterance); - }, 200); - } else { - synth.speak(utterance); - } - - } else { - reject("No text provided"); - } - - }); - } -} diff --git a/src/classes/ZPlayer.ts b/src/classes/ZPlayer.ts index 43ea493..b698010 100644 --- a/src/classes/ZPlayer.ts +++ b/src/classes/ZPlayer.ts @@ -10,7 +10,7 @@ import { arrayOfObjectsToObjectWithArrays } from "../Utils/Generic"; export type InputOptions = { [key: string]: string | number }; export class Player extends Event { - input: string; + input: string|number; ziffers: Ziffers; initCallTime: number = 0; startCallTime: number = 0; @@ -25,15 +25,23 @@ export class Player extends Event { skipIndex = 0; constructor( - input: string, + input: string|number|Generator, options: InputOptions, public app: Editor, zid: string = "" ) { super(app); - this.input = input; this.options = options; - this.ziffers = new Ziffers(input, options); + if (typeof input === "string") { + this.input = input; + this.ziffers = new Ziffers(input, options); + } else if (typeof input === "number") { + this.input = input; + this.ziffers = Ziffers.fromNumber(input,options); + } else { + this.ziffers = Ziffers.fromGenerator(input,options); + this.input = this.ziffers.input; + } this.zid = zid; } @@ -236,6 +244,16 @@ export class Player extends Event { return this; } + tonnetz(transform: string) { + if (this.atTheBeginning()) this.ziffers.tonnetzTransformation(transform); + return this; + } + + tonnetzChord(chord: string) { + if (this.atTheBeginning()) this.ziffers.tonnetzChords(chord); + return this; + } + voiceleading() { if (this.atTheBeginning()) this.ziffers.lead(); return this; diff --git a/src/documentation/patterns.ts b/src/documentation/patterns.ts index d727073..a2b94b5 100644 --- a/src/documentation/patterns.ts +++ b/src/documentation/patterns.ts @@ -196,6 +196,19 @@ beat(1)::snd('sine').sustain(0.1).freq([100,100,100,100,200].unique().beat()).ou true )} + - pitch(): convert a list of integers to pitch classes + +${makeExample( + "Converting a list of integers to pitch classes using key and scale", + ` + beat(0.25) :: snd('sine') + .pitch([0,1,2,3,4,6,7,8].beat(0.125)) + .key(["F4","F3"].beat(2.0)) + .scale("minor").out() +`, + true + )} + - scale(scale: string, base note: number): Map each element of the list to the closest note of the slected scale. [0, 2, 3, 5 ].scale("major", 50) returns [50, 52, 54, 55]. You can use western scale names like (Major, Minor, Minor pentatonic ...) or [zeitler](https://ianring.com/musictheory/scales/traditions/zeitler) scale names. Alternatively you can also use the integers as used by Ian Ring in his [study of scales](https://ianring.com/musictheory/scales/). ${makeExample( diff --git a/src/ArrayExtensions.ts b/src/extensions/ArrayExtensions.ts similarity index 99% rename from src/ArrayExtensions.ts rename to src/extensions/ArrayExtensions.ts index 01abdb8..1f4982d 100644 --- a/src/ArrayExtensions.ts +++ b/src/extensions/ArrayExtensions.ts @@ -1,4 +1,4 @@ -import { type UserAPI } from "./API"; +import { type UserAPI } from "../API"; import { safeScale, stepsToScale } from "zifferjs"; export { }; diff --git a/src/extensions/NumberExtensions.ts b/src/extensions/NumberExtensions.ts new file mode 100644 index 0000000..cbe743a --- /dev/null +++ b/src/extensions/NumberExtensions.ts @@ -0,0 +1,98 @@ +import { type UserAPI } from "../API"; +import { Player } from "../classes/ZPlayer"; + +declare global { + interface Number { + z(): Player; + z0(): Player; + z1(): Player; + z2(): Player; + z3(): Player; + z4(): Player; + z5(): Player; + z6(): Player; + z7(): Player; + z8(): Player; + z9(): Player; + z10(): Player; + z11(): Player; + z12(): Player; + z13(): Player; + z14(): Player; + z15(): Player; + z16(): Player; + note(): number; + } +} + +export const makeNumberExtensions = (api: UserAPI) => { + + Number.prototype.z0 = function (options: {[key: string]: any} = {}) { + return api.z0(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z1 = function (options: {[key: string]: any} = {}) { + return api.z1(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z2 = function (options: {[key: string]: any} = {}) { + return api.z2(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z3 = function (options: {[key: string]: any} = {}) { + return api.z3(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z4 = function (options: {[key: string]: any} = {}) { + return api.z4(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z5 = function (options: {[key: string]: any} = {}) { + return api.z5(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z6 = function (options: {[key: string]: any} = {}) { + return api.z6(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z7 = function (options: {[key: string]: any} = {}) { + return api.z7(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z8 = function (options: {[key: string]: any} = {}) { + return api.z8(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z9 = function (options: {[key: string]: any} = {}) { + return api.z9(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z10 = function (options: {[key: string]: any} = {}) { + return api.z10(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z11 = function (options: {[key: string]: any} = {}) { + return api.z11(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z12 = function (options: {[key: string]: any} = {}) { + return api.z12(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z13 = function (options: {[key: string]: any} = {}) { + return api.z13(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z14 = function (options: {[key: string]: any} = {}) { + return api.z14(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z15 = function (options: {[key: string]: any} = {}) { + return api.z15(this.valueOf().toString().split("").join(), options); + }; + + Number.prototype.z16 = function (options: {[key: string]: any} = {}) { + return api.z16(this.valueOf().toString().split("").join(), options); + }; + +} \ No newline at end of file diff --git a/src/extensions/StringExtensions.ts b/src/extensions/StringExtensions.ts new file mode 100644 index 0000000..f184e70 --- /dev/null +++ b/src/extensions/StringExtensions.ts @@ -0,0 +1,230 @@ +import { noteNameToMidi } from "zifferjs"; +import { type UserAPI } from "../API"; +import { Player } from "../classes/ZPlayer"; +export {}; + +// Extend String prototype +declare global { + interface String { + speak(): void; + rate(speed: number): string; + pitch(pitch: number): string; + volume(volume: number): string; + voice(voice: number): string; + lang(language: string): string; + options(): SpeechOptions; + z(): Player; + z0(): Player; + z1(): Player; + z2(): Player; + z3(): Player; + z4(): Player; + z5(): Player; + z6(): Player; + z7(): Player; + z8(): Player; + z9(): Player; + z10(): Player; + z11(): Player; + z12(): Player; + z13(): Player; + z14(): Player; + z15(): Player; + z16(): Player; + note(): number; + } +} + +const isJsonString = (str: string):boolean => { + return str[0] === '{' && str[str.length - 1] === '}' +} + +const stringObject = (str: string, params: object) => { + if(isJsonString(str)) { + const obj = JSON.parse(str); + return JSON.stringify({...obj, ...params}); + } else { + return JSON.stringify({...params, text: str}); + } +} + +export const makeStringExtensions = (api: UserAPI) => { + String.prototype.speak = function () { + const options = JSON.parse(this.valueOf()); + new Speaker({ ...options, text: options.text }).speak().then(() => { + // Done + }).catch((e) => { + console.log("Error speaking:", e); + }); + }; + + String.prototype.rate = function (speed: number) { + return stringObject(this.valueOf(), {rate: speed}); + }; + + String.prototype.pitch = function (pitch: number) { + return stringObject(this.valueOf(), {pitch: pitch}); + }; + + String.prototype.lang = function (language: string) { + return stringObject(this.valueOf(),{lang: language}); + }; + + String.prototype.volume = function (volume: number) { + return stringObject(this.valueOf(), {volume: volume}); + }; + + String.prototype.voice = function (voice: number) { + return stringObject(this.valueOf(), {voice: voice}); + }; + + String.prototype.z = function (options: {[key: string]: any} = {}) { + return api.z(this.valueOf(), options); + }; + + String.prototype.z0 = function (options: {[key: string]: any} = {}) { + return api.z0(this.valueOf(), options); + }; + + String.prototype.z1 = function (options: {[key: string]: any} = {}) { + return api.z1(this.valueOf(), options); + }; + + String.prototype.z2 = function (options: {[key: string]: any} = {}) { + return api.z2(this.valueOf(), options); + }; + + String.prototype.z3 = function (options: {[key: string]: any} = {}) { + return api.z3(this.valueOf(), options); + }; + + String.prototype.z4 = function (options: {[key: string]: any} = {}) { + return api.z4(this.valueOf(), options); + }; + + String.prototype.z5 = function (options: {[key: string]: any} = {}) { + return api.z5(this.valueOf(), options); + }; + + String.prototype.z6 = function (options: {[key: string]: any} = {}) { + return api.z6(this.valueOf(), options); + }; + + String.prototype.z7 = function (options: {[key: string]: any} = {}) { + return api.z7(this.valueOf(), options); + }; + + String.prototype.z8 = function (options: {[key: string]: any} = {}) { + return api.z8(this.valueOf(), options); + }; + + String.prototype.z9 = function (options: {[key: string]: any} = {}) { + return api.z9(this.valueOf(), options); + }; + + String.prototype.z10 = function (options: {[key: string]: any} = {}) { + return api.z10(this.valueOf(), options); + }; + + String.prototype.z11 = function (options: {[key: string]: any} = {}) { + return api.z11(this.valueOf(), options); + }; + + String.prototype.z12 = function (options: {[key: string]: any} = {}) { + return api.z12(this.valueOf(), options); + }; + + String.prototype.z13 = function (options: {[key: string]: any} = {}) { + return api.z13(this.valueOf(), options); + }; + + String.prototype.z14 = function (options: {[key: string]: any} = {}) { + return api.z14(this.valueOf(), options); + }; + + String.prototype.z15 = function (options: {[key: string]: any} = {}) { + return api.z15(this.valueOf(), options); + }; + + String.prototype.z16 = function (options: {[key: string]: any} = {}) { + return api.z16(this.valueOf(), options); + }; + + String.prototype.note = function () { + try { + return parseInt(this.valueOf()); + } catch (e) { + return noteNameToMidi(this.valueOf()); + } + }; +} + +type SpeechOptions = { + text?: string; + rate?: number; + pitch?: number; + volume?: number; + voice?: number; + lang?: string; +} + +let speakerTimeout: number; + +export class Speaker { + constructor( + public options: SpeechOptions + ) {} + + speak = () => { + return new Promise((resolve, reject) => { + if (this.options.text) { + const synth = window.speechSynthesis; + if(synth.speaking) synth.cancel(); + + const utterance = new SpeechSynthesisUtterance(this.options.text); + utterance.rate = this.options.rate || 1; + utterance.pitch = this.options.pitch || 1; + utterance.volume = this.options.volume || 1; + if (this.options.voice) { + utterance.voice = synth.getVoices()[this.options.voice]; + } + if(this.options.lang) { + // Check if language has country code + if (this.options.lang.length === 2) { + utterance.lang = `${this.options.lang}-${this.options.lang.toUpperCase()}` + } else if (this.options.lang.length === 5) { + utterance.lang = this.options.lang; + } else { + // Fallback to en us + utterance.lang = 'en-US'; + } + } + + utterance.onend = () => { + resolve(); + }; + + utterance.onerror = (error) => { + reject(error); + }; + + if(synth.speaking) { + // Cancel again? + synth.cancel(); + // Set timeout + if(speakerTimeout) clearTimeout(speakerTimeout); + // @ts-ignore + speakerTimeout = setTimeout(() => { + synth.speak(utterance); + }, 200); + } else { + synth.speak(utterance); + } + + } else { + reject("No text provided"); + } + + }); + } +} diff --git a/src/main.ts b/src/main.ts index 5409a66..ca1e040 100644 --- a/src/main.ts +++ b/src/main.ts @@ -16,16 +16,19 @@ import { documentation_factory } from "./Documentation"; import { EditorView } from "codemirror"; import { Clock } from "./Clock"; import { loadSamples, UserAPI } from "./API"; -import { makeArrayExtensions } from "./ArrayExtensions"; +import * as oeis from 'jisg' +import * as zpatterns from 'zifferjs/src/patterns.ts' +import { makeArrayExtensions } from "./extensions/ArrayExtensions"; import "./style.css"; import { Universes, File, template_universes } from "./FileManagement"; import { tryEvaluate } from "./Evaluator"; // @ts-ignore import showdown from "showdown"; -import { makeStringExtensions } from "./StringExtensions"; +import { makeStringExtensions } from "./extensions/StringExtensions"; import { installInterfaceLogic } from "./InterfaceLogic"; import { installWindowBehaviors, saveBeforeExit } from "./WindowBehavior"; import { drawEmptyBlinkers } from "./AudioVisualisation"; +import { makeNumberExtensions } from "./extensions/NumberExtensions"; // @ts-ignore import { registerSW } from "virtual:pwa-register"; @@ -130,12 +133,23 @@ export class Editor { this.api = new UserAPI(this); makeArrayExtensions(this.api); makeStringExtensions(this.api); + makeNumberExtensions(this.api); // Passing the API to the User Object.entries(this.api).forEach(([name, value]) => { (globalThis as Record)[name] = value; }); + // Passing OEIS generators to the User + Object.entries(oeis).forEach(([name, value]) => { + (globalThis as Record)[name] = value; + }); + + // Passing ziffers sequences to the User + Object.entries(zpatterns).forEach(([name, value]) => { + (globalThis as Record)[name] = value; + }); + // ================================================================================ // Building Documentation // ================================================================================ diff --git a/yarn.lock b/yarn.lock index ce8ab00..321a64c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2595,6 +2595,11 @@ iterate-object@^1.3.2: resolved "https://registry.yarnpkg.com/iterate-object/-/iterate-object-1.3.4.tgz#fa50b1d9e58e340a7dd6b4c98c8a5e182e790096" integrity sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw== +jisg@^0.9.7: + version "0.9.7" + resolved "https://registry.yarnpkg.com/jisg/-/jisg-0.9.7.tgz#d080655808d1f30ec22eb2be070e8a10d8ee097f" + integrity sha512-JWoGHGgU3xxJnPCNm6FpgMl0791xYFZq2PsejV8guCbhNJGsMvImAENx9pMhp7HbqhJgkM4ZV5lRbh5zbmF9xw== + jake@^10.8.5: version "10.8.7" resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" @@ -3877,10 +3882,10 @@ yaml@^2.1.1: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== -zifferjs@^0.0.34: - version "0.0.34" - resolved "https://registry.yarnpkg.com/zifferjs/-/zifferjs-0.0.34.tgz#887fb2db1ec2aff21ff1742cbbbbc4621838588f" - integrity sha512-q2eFi+j+yXkPTXU53at3Agrh67JmBJ5zloZ13kc5ObT9R8R9L/if21mbnFxpDJC6Sjugql40aM0Ko4p/zBTs4w== +zifferjs@^0.0.35: + version "0.0.35" + resolved "https://registry.yarnpkg.com/zifferjs/-/zifferjs-0.0.35.tgz#0518a84d031d2ef19417bc1084c21b08666df067" + integrity sha512-vtvyEO/hIPRboGinkb1IhqJu4iU5DdbkzrQX8Xg7n096fDi/PU72b5Nwxt0xt29D37CfOI99sjaLbtYPab1NoA== zzfx@^1.2.0: version "1.2.0"