mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-24 05:57:17 -04:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 95ecd73d49 | |||
| a9995d185f | |||
| 5da2085436 | |||
| ae9820b39f |
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[](https://github.com/tidalcycles/strudel/actions)
|
[](https://github.com/tidalcycles/strudel/actions)
|
||||||
|
|
||||||
An experiment in making a [Tidal](https://github.com/tidalcycles/tidal/) using web technologies. This software is slowly stabilising, but please continue to tread carefully.
|
An experiment in making a [Tidal](https://github.com/tidalcycles/tidal/) using web technologies. This is unstable software, please tread carefully.
|
||||||
|
|
||||||
- Try it here: <https://strudel.tidalcycles.org/>
|
- Try it here: <https://strudel.tidalcycles.org/>
|
||||||
- Tutorial: <https://strudel.tidalcycles.org/tutorial/>
|
- Tutorial: <https://strudel.tidalcycles.org/tutorial/>
|
||||||
|
|||||||
Generated
+48
-274
@@ -2243,10 +2243,6 @@
|
|||||||
"resolved": "packages/serial",
|
"resolved": "packages/serial",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
"node_modules/@strudel.cycles/soundfonts": {
|
|
||||||
"resolved": "packages/soundfonts",
|
|
||||||
"link": true
|
|
||||||
},
|
|
||||||
"node_modules/@strudel.cycles/tonal": {
|
"node_modules/@strudel.cycles/tonal": {
|
||||||
"resolved": "packages/tonal",
|
"resolved": "packages/tonal",
|
||||||
"link": true
|
"link": true
|
||||||
@@ -3951,15 +3947,6 @@
|
|||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/data-uri-to-buffer": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dateformat": {
|
"node_modules/dateformat": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
|
||||||
@@ -4968,29 +4955,6 @@
|
|||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fetch-blob": {
|
|
||||||
"version": "3.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.5.tgz",
|
|
||||||
"integrity": "sha512-N64ZpKqoLejlrwkIAnb9iLSA3Vx/kjgzpcDhygcqJ2KKjky8nCgUQ+dzXtbrLaWZGZNmNfQTsiQ0weZ1svglHg==",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/jimmywarting"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "paypal",
|
|
||||||
"url": "https://paypal.me/jimmywarting"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"node-domexception": "^1.0.0",
|
|
||||||
"web-streams-polyfill": "^3.0.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^12.20 || >= 14.13"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/figures": {
|
"node_modules/figures": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
|
||||||
@@ -5170,18 +5134,6 @@
|
|||||||
"node": ">= 0.12"
|
"node": ">= 0.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/formdata-polyfill": {
|
|
||||||
"version": "4.0.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
|
||||||
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"fetch-blob": "^3.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12.20.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fraction.js": {
|
"node_modules/fraction.js": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
|
||||||
@@ -7067,9 +7019,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/marked": {
|
"node_modules/marked": {
|
||||||
"version": "4.0.17",
|
"version": "4.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz",
|
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.14.tgz",
|
||||||
"integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA==",
|
"integrity": "sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"marked": "bin/marked.js"
|
"marked": "bin/marked.js"
|
||||||
},
|
},
|
||||||
@@ -7630,25 +7582,6 @@
|
|||||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/node-domexception": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/jimmywarting"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://paypal.me/jimmywarting"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10.5.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/node-fetch": {
|
"node_modules/node-fetch": {
|
||||||
"version": "2.6.7",
|
"version": "2.6.7",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
@@ -8504,31 +8437,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/peggy": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/peggy/-/peggy-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-mBqfmdUAOVn7RILpXTbcRBhLfTR4Go0SresSnivGDdRylBOyVFJncFiVyCNNpPWq8HmgeRleXHs/Go4o8kQVXA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"commander": "^9.3.0",
|
|
||||||
"source-map-generator": "0.8.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"peggy": "bin/peggy.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/peggy/node_modules/commander": {
|
|
||||||
"version": "9.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-9.3.0.tgz",
|
|
||||||
"integrity": "sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": "^12.20.0 || >=14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/performance-now": {
|
"node_modules/performance-now": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||||
@@ -9926,15 +9834,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/source-map-generator": {
|
|
||||||
"version": "0.8.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/source-map-generator/-/source-map-generator-0.8.0.tgz",
|
|
||||||
"integrity": "sha512-psgxdGMwl5MZM9S3FWee4EgsEaIjahYV5AzGnwUvPhWeITz/j6rKpysQHlQ4USdxvINlb8lKfWGIXwfkrgtqkA==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||||
@@ -10920,15 +10819,6 @@
|
|||||||
"defaults": "^1.0.3"
|
"defaults": "^1.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/web-streams-polyfill": {
|
|
||||||
"version": "3.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
|
|
||||||
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/WebDirt": {
|
"node_modules/WebDirt": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "git+ssh://git@github.com/dktr0/WebDirt.git#425dc8fd023440d9c61ffdb8642e44e2710faea0",
|
"resolved": "git+ssh://git@github.com/dktr0/WebDirt.git#425dc8fd023440d9c61ffdb8642e44e2710faea0",
|
||||||
@@ -11373,7 +11263,7 @@
|
|||||||
},
|
},
|
||||||
"packages/core": {
|
"packages/core": {
|
||||||
"name": "@strudel.cycles/core",
|
"name": "@strudel.cycles/core",
|
||||||
"version": "0.1.2",
|
"version": "0.1.0",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bjork": "^0.0.1",
|
"bjork": "^0.0.1",
|
||||||
@@ -11385,15 +11275,15 @@
|
|||||||
},
|
},
|
||||||
"packages/embed": {
|
"packages/embed": {
|
||||||
"name": "@strudel.cycles/embed",
|
"name": "@strudel.cycles/embed",
|
||||||
"version": "0.1.1",
|
"version": "0.1.0",
|
||||||
"license": "AGPL-3.0-or-later"
|
"license": "AGPL-3.0-or-later"
|
||||||
},
|
},
|
||||||
"packages/eval": {
|
"packages/eval": {
|
||||||
"name": "@strudel.cycles/eval",
|
"name": "@strudel.cycles/eval",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"estraverse": "^5.3.0",
|
"estraverse": "^5.3.0",
|
||||||
"shift-ast": "^6.1.0",
|
"shift-ast": "^6.1.0",
|
||||||
"shift-codegen": "^7.0.3",
|
"shift-codegen": "^7.0.3",
|
||||||
@@ -11417,30 +11307,27 @@
|
|||||||
},
|
},
|
||||||
"packages/midi": {
|
"packages/midi": {
|
||||||
"name": "@strudel.cycles/midi",
|
"name": "@strudel.cycles/midi",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/tone": "^0.1.3",
|
"@strudel.cycles/tone": "^0.1.1",
|
||||||
"tone": "^14.7.77",
|
"tone": "^14.7.77",
|
||||||
"webmidi": "^2.5.2"
|
"webmidi": "^2.5.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/mini": {
|
"packages/mini": {
|
||||||
"name": "@strudel.cycles/mini",
|
"name": "@strudel.cycles/mini",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"@strudel.cycles/eval": "^0.1.3",
|
"@strudel.cycles/eval": "^0.1.1",
|
||||||
"@strudel.cycles/tone": "^0.1.3"
|
"@strudel.cycles/tone": "^0.1.1"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"peggy": "^2.0.1"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/osc": {
|
"packages/osc": {
|
||||||
"name": "@strudel.cycles/osc",
|
"name": "@strudel.cycles/osc",
|
||||||
"version": "0.1.1",
|
"version": "0.1.0",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"osc-js": "^2.3.2"
|
"osc-js": "^2.3.2"
|
||||||
@@ -11448,14 +11335,14 @@
|
|||||||
},
|
},
|
||||||
"packages/react": {
|
"packages/react": {
|
||||||
"name": "@strudel.cycles/react",
|
"name": "@strudel.cycles/react",
|
||||||
"version": "0.1.4",
|
"version": "0.1.2",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/lang-javascript": "^0.19.0",
|
"@codemirror/lang-javascript": "^0.19.0",
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "*",
|
||||||
"@strudel.cycles/eval": "^0.1.3",
|
"@strudel.cycles/eval": "^0.1.1",
|
||||||
"@strudel.cycles/tone": "^0.1.3",
|
"@strudel.cycles/tone": "^0.1.1",
|
||||||
"react-codemirror6": "^1.1.0",
|
"react-codemirror6": "^1.1.0",
|
||||||
"react-hook-inview": "^4.5.0"
|
"react-hook-inview": "^4.5.0"
|
||||||
},
|
},
|
||||||
@@ -11524,45 +11411,15 @@
|
|||||||
},
|
},
|
||||||
"packages/serial": {
|
"packages/serial": {
|
||||||
"name": "@strudel.cycles/serial",
|
"name": "@strudel.cycles/serial",
|
||||||
"version": "0.1.3",
|
"version": "0.1.0",
|
||||||
"license": "AGPL-3.0-or-later"
|
"license": "AGPL-3.0-or-later"
|
||||||
},
|
},
|
||||||
"packages/soundfonts": {
|
|
||||||
"name": "@strudel.cycles/soundfonts",
|
|
||||||
"version": "0.1.1",
|
|
||||||
"license": "AGPL-3.0-or-later",
|
|
||||||
"dependencies": {
|
|
||||||
"@strudel.cycles/core": "*",
|
|
||||||
"@strudel.cycles/webaudio": "^0.1.4"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"node-fetch": "^3.2.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packages/soundfonts/node_modules/node-fetch": {
|
|
||||||
"version": "3.2.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.6.tgz",
|
|
||||||
"integrity": "sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"data-uri-to-buffer": "^4.0.0",
|
|
||||||
"fetch-blob": "^3.1.4",
|
|
||||||
"formdata-polyfill": "^4.0.10"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/node-fetch"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packages/tonal": {
|
"packages/tonal": {
|
||||||
"name": "@strudel.cycles/tonal",
|
"name": "@strudel.cycles/tonal",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"@tonaljs/tonal": "^4.6.5",
|
"@tonaljs/tonal": "^4.6.5",
|
||||||
"webmidi": "^3.0.15"
|
"webmidi": "^3.0.15"
|
||||||
}
|
}
|
||||||
@@ -11584,10 +11441,10 @@
|
|||||||
},
|
},
|
||||||
"packages/tone": {
|
"packages/tone": {
|
||||||
"name": "@strudel.cycles/tone",
|
"name": "@strudel.cycles/tone",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"@tonejs/piano": "^0.2.1",
|
"@tonejs/piano": "^0.2.1",
|
||||||
"chord-voicings": "^0.0.1",
|
"chord-voicings": "^0.0.1",
|
||||||
"tone": "^14.7.77"
|
"tone": "^14.7.77"
|
||||||
@@ -11595,27 +11452,27 @@
|
|||||||
},
|
},
|
||||||
"packages/webaudio": {
|
"packages/webaudio": {
|
||||||
"name": "@strudel.cycles/webaudio",
|
"name": "@strudel.cycles/webaudio",
|
||||||
"version": "0.1.4",
|
"version": "0.1.1",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2"
|
"@strudel.cycles/core": "^0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/webdirt": {
|
"packages/webdirt": {
|
||||||
"name": "@strudel.cycles/webdirt",
|
"name": "@strudel.cycles/webdirt",
|
||||||
"version": "0.1.2",
|
"version": "0.1.0",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"WebDirt": "github:dktr0/WebDirt"
|
"WebDirt": "github:dktr0/WebDirt"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/xen": {
|
"packages/xen": {
|
||||||
"name": "@strudel.cycles/xen",
|
"name": "@strudel.cycles/xen",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2"
|
"@strudel.cycles/core": "^0.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -13430,7 +13287,7 @@
|
|||||||
"@strudel.cycles/eval": {
|
"@strudel.cycles/eval": {
|
||||||
"version": "file:packages/eval",
|
"version": "file:packages/eval",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"estraverse": "^5.3.0",
|
"estraverse": "^5.3.0",
|
||||||
"shift-ast": "^6.1.0",
|
"shift-ast": "^6.1.0",
|
||||||
"shift-codegen": "^7.0.3",
|
"shift-codegen": "^7.0.3",
|
||||||
@@ -13442,7 +13299,7 @@
|
|||||||
"@strudel.cycles/midi": {
|
"@strudel.cycles/midi": {
|
||||||
"version": "file:packages/midi",
|
"version": "file:packages/midi",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@strudel.cycles/tone": "^0.1.3",
|
"@strudel.cycles/tone": "^0.1.1",
|
||||||
"tone": "^14.7.77",
|
"tone": "^14.7.77",
|
||||||
"webmidi": "^2.5.2"
|
"webmidi": "^2.5.2"
|
||||||
}
|
}
|
||||||
@@ -13450,10 +13307,9 @@
|
|||||||
"@strudel.cycles/mini": {
|
"@strudel.cycles/mini": {
|
||||||
"version": "file:packages/mini",
|
"version": "file:packages/mini",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"@strudel.cycles/eval": "^0.1.3",
|
"@strudel.cycles/eval": "^0.1.1",
|
||||||
"@strudel.cycles/tone": "^0.1.3",
|
"@strudel.cycles/tone": "^0.1.1"
|
||||||
"peggy": "^2.0.1"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@strudel.cycles/osc": {
|
"@strudel.cycles/osc": {
|
||||||
@@ -13466,9 +13322,9 @@
|
|||||||
"version": "file:packages/react",
|
"version": "file:packages/react",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@codemirror/lang-javascript": "^0.19.0",
|
"@codemirror/lang-javascript": "^0.19.0",
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "*",
|
||||||
"@strudel.cycles/eval": "^0.1.3",
|
"@strudel.cycles/eval": "^0.1.1",
|
||||||
"@strudel.cycles/tone": "^0.1.3",
|
"@strudel.cycles/tone": "^0.1.1",
|
||||||
"@types/react": "^17.0.2",
|
"@types/react": "^17.0.2",
|
||||||
"@types/react-dom": "^17.0.2",
|
"@types/react-dom": "^17.0.2",
|
||||||
"@vitejs/plugin-react": "^1.3.0",
|
"@vitejs/plugin-react": "^1.3.0",
|
||||||
@@ -13528,31 +13384,10 @@
|
|||||||
"@strudel.cycles/serial": {
|
"@strudel.cycles/serial": {
|
||||||
"version": "file:packages/serial"
|
"version": "file:packages/serial"
|
||||||
},
|
},
|
||||||
"@strudel.cycles/soundfonts": {
|
|
||||||
"version": "file:packages/soundfonts",
|
|
||||||
"requires": {
|
|
||||||
"@strudel.cycles/core": "*",
|
|
||||||
"@strudel.cycles/webaudio": "^0.1.4",
|
|
||||||
"node-fetch": "^3.2.6"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"node-fetch": {
|
|
||||||
"version": "3.2.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.6.tgz",
|
|
||||||
"integrity": "sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"data-uri-to-buffer": "^4.0.0",
|
|
||||||
"fetch-blob": "^3.1.4",
|
|
||||||
"formdata-polyfill": "^4.0.10"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@strudel.cycles/tonal": {
|
"@strudel.cycles/tonal": {
|
||||||
"version": "file:packages/tonal",
|
"version": "file:packages/tonal",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"@tonaljs/tonal": "^4.6.5",
|
"@tonaljs/tonal": "^4.6.5",
|
||||||
"webmidi": "^3.0.15"
|
"webmidi": "^3.0.15"
|
||||||
},
|
},
|
||||||
@@ -13572,7 +13407,7 @@
|
|||||||
"@strudel.cycles/tone": {
|
"@strudel.cycles/tone": {
|
||||||
"version": "file:packages/tone",
|
"version": "file:packages/tone",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"@tonejs/piano": "^0.2.1",
|
"@tonejs/piano": "^0.2.1",
|
||||||
"chord-voicings": "^0.0.1",
|
"chord-voicings": "^0.0.1",
|
||||||
"tone": "^14.7.77"
|
"tone": "^14.7.77"
|
||||||
@@ -13581,20 +13416,20 @@
|
|||||||
"@strudel.cycles/webaudio": {
|
"@strudel.cycles/webaudio": {
|
||||||
"version": "file:packages/webaudio",
|
"version": "file:packages/webaudio",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@strudel.cycles/core": "^0.1.2"
|
"@strudel.cycles/core": "^0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@strudel.cycles/webdirt": {
|
"@strudel.cycles/webdirt": {
|
||||||
"version": "file:packages/webdirt",
|
"version": "file:packages/webdirt",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"WebDirt": "github:dktr0/WebDirt"
|
"WebDirt": "github:dktr0/WebDirt"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@strudel.cycles/xen": {
|
"@strudel.cycles/xen": {
|
||||||
"version": "file:packages/xen",
|
"version": "file:packages/xen",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@strudel.cycles/core": "^0.1.2"
|
"@strudel.cycles/core": "^0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@tonaljs/abc-notation": {
|
"@tonaljs/abc-notation": {
|
||||||
@@ -14973,12 +14808,6 @@
|
|||||||
"assert-plus": "^1.0.0"
|
"assert-plus": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"data-uri-to-buffer": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"dateformat": {
|
"dateformat": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
|
||||||
@@ -15652,16 +15481,6 @@
|
|||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fetch-blob": {
|
|
||||||
"version": "3.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.5.tgz",
|
|
||||||
"integrity": "sha512-N64ZpKqoLejlrwkIAnb9iLSA3Vx/kjgzpcDhygcqJ2KKjky8nCgUQ+dzXtbrLaWZGZNmNfQTsiQ0weZ1svglHg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"node-domexception": "^1.0.0",
|
|
||||||
"web-streams-polyfill": "^3.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"figures": {
|
"figures": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
|
||||||
@@ -15790,15 +15609,6 @@
|
|||||||
"mime-types": "^2.1.12"
|
"mime-types": "^2.1.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"formdata-polyfill": {
|
|
||||||
"version": "4.0.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
|
||||||
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"fetch-blob": "^3.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fraction.js": {
|
"fraction.js": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
|
||||||
@@ -17248,9 +17058,9 @@
|
|||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"marked": {
|
"marked": {
|
||||||
"version": "4.0.17",
|
"version": "4.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz",
|
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.14.tgz",
|
||||||
"integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA=="
|
"integrity": "sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ=="
|
||||||
},
|
},
|
||||||
"mdurl": {
|
"mdurl": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
@@ -17675,12 +17485,6 @@
|
|||||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node-domexception": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node-fetch": {
|
"node-fetch": {
|
||||||
"version": "2.6.7",
|
"version": "2.6.7",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
@@ -18330,24 +18134,6 @@
|
|||||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"peggy": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/peggy/-/peggy-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-mBqfmdUAOVn7RILpXTbcRBhLfTR4Go0SresSnivGDdRylBOyVFJncFiVyCNNpPWq8HmgeRleXHs/Go4o8kQVXA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"commander": "^9.3.0",
|
|
||||||
"source-map-generator": "0.8.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"commander": {
|
|
||||||
"version": "9.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-9.3.0.tgz",
|
|
||||||
"integrity": "sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"performance-now": {
|
"performance-now": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||||
@@ -18600,9 +18386,9 @@
|
|||||||
"version": "file:packages/react",
|
"version": "file:packages/react",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@codemirror/lang-javascript": "^0.19.0",
|
"@codemirror/lang-javascript": "^0.19.0",
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "*",
|
||||||
"@strudel.cycles/eval": "^0.1.3",
|
"@strudel.cycles/eval": "^0.1.1",
|
||||||
"@strudel.cycles/tone": "^0.1.3",
|
"@strudel.cycles/tone": "^0.1.1",
|
||||||
"@types/react": "^17.0.2",
|
"@types/react": "^17.0.2",
|
||||||
"@types/react-dom": "^17.0.2",
|
"@types/react-dom": "^17.0.2",
|
||||||
"@vitejs/plugin-react": "^1.3.0",
|
"@vitejs/plugin-react": "^1.3.0",
|
||||||
@@ -19466,12 +19252,6 @@
|
|||||||
"is-plain-obj": "^2.0.0"
|
"is-plain-obj": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"source-map-generator": {
|
|
||||||
"version": "0.8.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/source-map-generator/-/source-map-generator-0.8.0.tgz",
|
|
||||||
"integrity": "sha512-psgxdGMwl5MZM9S3FWee4EgsEaIjahYV5AzGnwUvPhWeITz/j6rKpysQHlQ4USdxvINlb8lKfWGIXwfkrgtqkA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"source-map-js": {
|
"source-map-js": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||||
@@ -20249,12 +20029,6 @@
|
|||||||
"defaults": "^1.0.3"
|
"defaults": "^1.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"web-streams-polyfill": {
|
|
||||||
"version": "3.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
|
|
||||||
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"WebDirt": {
|
"WebDirt": {
|
||||||
"version": "git+ssh://git@github.com/dktr0/WebDirt.git#425dc8fd023440d9c61ffdb8642e44e2710faea0",
|
"version": "git+ssh://git@github.com/dktr0/WebDirt.git#425dc8fd023440d9c61ffdb8642e44e2710faea0",
|
||||||
"from": "WebDirt@github:dktr0/WebDirt"
|
"from": "WebDirt@github:dktr0/WebDirt"
|
||||||
|
|||||||
+1
-3
@@ -6,11 +6,9 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "npm run test --workspaces --if-present && cd repl && npm run test",
|
"test": "npm run test --workspaces --if-present && cd repl && npm run test",
|
||||||
"bootstrap": "lerna bootstrap",
|
"bootstrap": "lerna bootstrap",
|
||||||
"setup": "npm i && npm run bootstrap && cd repl && npm i && cd ../tutorial && npm i",
|
"setup": "npm i && npm run bootstrap && cd repl && npm i",
|
||||||
"snapshot": "cd repl && npm run snapshot",
|
|
||||||
"repl": "cd repl && npm run dev",
|
"repl": "cd repl && npm run dev",
|
||||||
"osc": "cd packages/osc && npm run server",
|
"osc": "cd packages/osc && npm run server",
|
||||||
"sampler": "cd ./repl/public/samples && node ../../packages/webaudio/sample-server.js",
|
|
||||||
"build": "rm -rf out && cd repl && npm run build && cd ../tutorial && npm run build",
|
"build": "rm -rf out && cd repl && npm run build && cd ../tutorial && npm run build",
|
||||||
"preview": "npx serve ./out",
|
"preview": "npx serve ./out",
|
||||||
"deploy": "gh-pages -d out",
|
"deploy": "gh-pages -d out",
|
||||||
|
|||||||
@@ -744,30 +744,25 @@ const generic_params = [
|
|||||||
['f', 'uid', ''],
|
['f', 'uid', ''],
|
||||||
['f', 'val', ''],
|
['f', 'val', ''],
|
||||||
['f', 'cps', ''],
|
['f', 'cps', ''],
|
||||||
['f', 'clip', ''],
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// TODO: slice / splice https://www.youtube.com/watch?v=hKhPdO0RKDQ&list=PL2lW1zNIIwj3bDkh-Y3LUGDuRcoUigoDs&index=13
|
// TODO: slice / splice https://www.youtube.com/watch?v=hKhPdO0RKDQ&list=PL2lW1zNIIwj3bDkh-Y3LUGDuRcoUigoDs&index=13
|
||||||
|
|
||||||
const _name = (name, ...pats) => sequence(...pats).withValue((x) => ({ [name]: x }));
|
const _name = (name, ...pats) => sequence(...pats).withValue((x) => ({ [name]: x }));
|
||||||
|
|
||||||
const _setter = (func, name) =>
|
const _setter = (func) =>
|
||||||
function (...pats) {
|
function (...pats) {
|
||||||
if (!pats.length) {
|
|
||||||
return this.fmap((value) => ({ [name]: value }));
|
|
||||||
}
|
|
||||||
return this.set(func(...pats));
|
return this.set(func(...pats));
|
||||||
};
|
};
|
||||||
|
|
||||||
generic_params.forEach(([type, name, description]) => {
|
generic_params.forEach(([type, name, description]) => {
|
||||||
controls[name] = (...pats) => _name(name, ...pats);
|
controls[name] = (...pats) => _name(name, ...pats);
|
||||||
Pattern.prototype[name] = _setter(controls[name], name);
|
Pattern.prototype[name] = _setter(controls[name]);
|
||||||
});
|
});
|
||||||
|
|
||||||
// create custom param
|
// create custom param
|
||||||
controls.createParam = (name) => {
|
controls.createParam = (name) => {
|
||||||
const func = (...pats) => _name(name, ...pats);
|
Pattern.prototype[name] = _setter(controls[name]);
|
||||||
Pattern.prototype[name] = _setter(func, name);
|
|
||||||
return (...pats) => _name(name, ...pats);
|
return (...pats) => _name(name, ...pats);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+92
-10
@@ -4,9 +4,87 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
|||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Fraction from 'fraction.js';
|
// import Fraction from 'fraction.js';
|
||||||
import { TimeSpan } from './timespan.mjs';
|
import { TimeSpan } from './timespan.mjs';
|
||||||
|
|
||||||
|
let instances = 0;
|
||||||
|
let strings = 0;
|
||||||
|
let fractions = 0;
|
||||||
|
let numbers = 0;
|
||||||
|
setInterval(() => {
|
||||||
|
console.log(`${instances} calls = ${numbers} numbers + ${fractions} fractions + ${strings} strings`);
|
||||||
|
instances = 0;
|
||||||
|
strings = 0;
|
||||||
|
fractions = 0;
|
||||||
|
numbers = 0;
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
// http://localhost:3000/#c3RhY2soCiAgImUzLGJiMyxkNCIuc3RydWN0KCJ4KDMsOCwtMSkiKS5vZmYoMS84LHg9PngudHJhbnNwb3NlKDEyKS52ZWxvY2l0eSguMikpLAogICJjMiIuc3RydWN0KCJ4KDQsOCwtMikiKSwKICAiYzMiLnN0cnVjdCgieCgzLDgsLTIpIi5mYXN0KDIpKQopLnNsb3coMikKIC5lY2hvKDQsLjEyNSwuOCkKIC52ZWxvY2l0eShzaW5lLnN0cnVjdCgieCo4IikuYWRkKDMvNSkubXVsKDIvNSkuZmFzdCg4KSkKIC8vIC5waWFub3JvbGwoKQovLyBzdHJ1ZGVsIGRpc2FibGUtaGlnaGxpZ2h0aW5n
|
||||||
|
// ~400k/s
|
||||||
|
|
||||||
|
// this is a "mock" for fraction.js, using just floats without any rational arithmetic
|
||||||
|
// to test if the performance gets better without fraction.js
|
||||||
|
// result: it seems to get better but not by much
|
||||||
|
// the main jankyness remains for some complicated patterns
|
||||||
|
|
||||||
|
class Fraction {
|
||||||
|
value; // number
|
||||||
|
constructor(value) {
|
||||||
|
instances++;
|
||||||
|
if (value instanceof Fraction) {
|
||||||
|
// TODO: return this?
|
||||||
|
this.value = value.value;
|
||||||
|
fractions++;
|
||||||
|
} else if (typeof value === 'string') {
|
||||||
|
const [n, d] = value.split('/');
|
||||||
|
this.value = n / (d || 1);
|
||||||
|
strings++;
|
||||||
|
} else if (typeof value !== 'number' || isNaN(value)) {
|
||||||
|
console.warn('Fraction got NaN', value);
|
||||||
|
} else {
|
||||||
|
numbers++;
|
||||||
|
this.value = Number(value);
|
||||||
|
if (isNaN(this.value)) {
|
||||||
|
console.warn('Fraction parsed NaN from', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add(other) {
|
||||||
|
return new Fraction(this.value + other);
|
||||||
|
}
|
||||||
|
sub(other) {
|
||||||
|
return new Fraction(this.value - other);
|
||||||
|
}
|
||||||
|
mul(other) {
|
||||||
|
return new Fraction(this.value * other);
|
||||||
|
}
|
||||||
|
div(other) {
|
||||||
|
return new Fraction(this.value / other);
|
||||||
|
}
|
||||||
|
toString() {
|
||||||
|
return this.value + '';
|
||||||
|
}
|
||||||
|
valueOf() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
floor() {
|
||||||
|
return new Fraction(Math.floor(this.value));
|
||||||
|
}
|
||||||
|
abs() {
|
||||||
|
return new Fraction(Math.abs(this.value));
|
||||||
|
}
|
||||||
|
inverse() {
|
||||||
|
return new Fraction(1 / this.value);
|
||||||
|
}
|
||||||
|
compare(other) {
|
||||||
|
return this.value - other;
|
||||||
|
}
|
||||||
|
equals(other) {
|
||||||
|
return this.value.valueOf() === other.valueOf();
|
||||||
|
}
|
||||||
|
// TODO: toFraction
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the start of the cycle.
|
// Returns the start of the cycle.
|
||||||
Fraction.prototype.sam = function () {
|
Fraction.prototype.sam = function () {
|
||||||
return this.floor();
|
return this.floor();
|
||||||
@@ -14,12 +92,16 @@ Fraction.prototype.sam = function () {
|
|||||||
|
|
||||||
// Returns the start of the next cycle.
|
// Returns the start of the next cycle.
|
||||||
Fraction.prototype.nextSam = function () {
|
Fraction.prototype.nextSam = function () {
|
||||||
|
// return new Fraction(Math.floor(this.value) + 1);
|
||||||
return this.sam().add(1);
|
return this.sam().add(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a TimeSpan representing the begin and end of the Time value's cycle
|
// Returns a TimeSpan representing the begin and end of the Time value's cycle
|
||||||
Fraction.prototype.wholeCycle = function () {
|
Fraction.prototype.wholeCycle = function () {
|
||||||
return new TimeSpan(this.sam(), this.nextSam());
|
return new TimeSpan(this.sam(), this.nextSam());
|
||||||
|
/* const begin = Math.floor(this.value);
|
||||||
|
const end = begin + 1;
|
||||||
|
return new TimeSpan(begin, end); */
|
||||||
};
|
};
|
||||||
|
|
||||||
// The position of a time value relative to the start of its cycle.
|
// The position of a time value relative to the start of its cycle.
|
||||||
@@ -63,20 +145,20 @@ Fraction.prototype.or = function (other) {
|
|||||||
return this.eq(0) ? other : this;
|
return this.eq(0) ? other : this;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fraction = (n) => {
|
/* const fraction = (n) => {
|
||||||
if (typeof n === 'number') {
|
if (typeof n === 'number') {
|
||||||
/*
|
// https://github.com/infusion/Fraction.js/#doubles
|
||||||
https://github.com/infusion/Fraction.js/#doubles
|
// „If you pass a double as it is, Fraction.js will perform a number analysis based on Farey Sequences."
|
||||||
„If you pass a double as it is, Fraction.js will perform a number analysis based on Farey Sequences."
|
// „If you want to keep the number as it is, convert it to a string, as the string parser will not perform any further observations“
|
||||||
„If you want to keep the number as it is, convert it to a string, as the string parser will not perform any further observations“
|
|
||||||
|
|
||||||
-> those farey sequences turn out to make pattern querying ~20 times slower! always use strings!
|
// -> those farey sequences turn out to make pattern querying ~20 times slower! always use strings!
|
||||||
-> still, some optimizations could be done: .mul .div .add .sub calls still use numbers
|
// -> still, some optimizations could be done: .mul .div .add .sub calls still use numbers
|
||||||
*/
|
|
||||||
n = String(n);
|
n = String(n);
|
||||||
}
|
}
|
||||||
return Fraction(n);
|
return Fraction(n);
|
||||||
};
|
}; */
|
||||||
|
|
||||||
|
const fraction = (n) => new Fraction(n);
|
||||||
|
|
||||||
export const gcd = (...fractions) => {
|
export const gcd = (...fractions) => {
|
||||||
return fractions.reduce((gcd, fraction) => gcd.gcd(fraction), fraction(1));
|
return fractions.reduce((gcd, fraction) => gcd.gcd(fraction), fraction(1));
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ This program is free software: you can redistribute it and/or modify it under th
|
|||||||
|
|
||||||
// this is a shortcut to eval code from a gist
|
// this is a shortcut to eval code from a gist
|
||||||
// why? to be able to shorten strudel code + e.g. be able to change instruments after links have been generated
|
// why? to be able to shorten strudel code + e.g. be able to change instruments after links have been generated
|
||||||
export default (route, cache = true) =>
|
export default (route) =>
|
||||||
fetch(`https://gist.githubusercontent.com/${route}?cachebust=${cache ? '' : Date.now()}`)
|
fetch(`https://gist.githubusercontent.com/${route}?cachebust=${Date.now()}`)
|
||||||
.then((res) => res.text())
|
.then((res) => res.text())
|
||||||
.then((code) => eval(code));
|
.then((code) => eval(code));
|
||||||
|
|||||||
@@ -86,9 +86,11 @@ export class Hap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showWhole() {
|
showWhole() {
|
||||||
return `${this.whole == undefined ? '~' : this.whole.show()}: ${
|
return `${this.whole == undefined ? '~' : this.whole.show()}: ${this.value}`;
|
||||||
typeof this.value === 'object' ? JSON.stringify(this.value) : this.value
|
}
|
||||||
}`;
|
|
||||||
|
showWhole() {
|
||||||
|
return `${this.whole == undefined ? '~' : this.whole.show()}: ${this.value}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
combineContext(b) {
|
combineContext(b) {
|
||||||
|
|||||||
+2
-16
@@ -15,19 +15,5 @@ export * from './state.mjs';
|
|||||||
export * from './timespan.mjs';
|
export * from './timespan.mjs';
|
||||||
export * from './util.mjs';
|
export * from './util.mjs';
|
||||||
export * from './speak.mjs';
|
export * from './speak.mjs';
|
||||||
export { default as gist } from './gist.js';
|
export * as gist from './gist.js';
|
||||||
// below won't work with runtime.mjs (json import fails)
|
// export * from './value.mjs';
|
||||||
/* import * as p from './package.json';
|
|
||||||
export const version = p.version; */
|
|
||||||
console.log(
|
|
||||||
'%c // 🌀 @strudel.cycles/core loaded 🌀', // keep "//" for runnable snapshot source..
|
|
||||||
'background-color: black;color:white;padding:4px;border-radius:15px',
|
|
||||||
);
|
|
||||||
if (globalThis._strudelLoaded) {
|
|
||||||
console.warn(
|
|
||||||
`@strudel.cycles/core was loaded more than once...
|
|
||||||
This might happen when you have multiple versions of strudel installed.
|
|
||||||
Please check with "npm ls @strudel.cycles/core".`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
globalThis._strudelLoaded = true;
|
|
||||||
|
|||||||
Generated
+3
-3
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/core",
|
"name": "@strudel.cycles/core",
|
||||||
"version": "0.1.2",
|
"version": "0.1.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@strudel.cycles/core",
|
"name": "@strudel.cycles/core",
|
||||||
"version": "0.1.0",
|
"version": "0.0.3",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bjork": "^0.0.1",
|
"bjork": "^0.0.1",
|
||||||
"fraction.js": "^4.2.0"
|
"fraction.js": "^4.2.0"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/core",
|
"name": "@strudel.cycles/core",
|
||||||
"version": "0.1.2",
|
"version": "0.1.0",
|
||||||
"description": "Port of Tidal Cycles to JavaScript",
|
"description": "Port of Tidal Cycles to JavaScript",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import drawLine from './drawLine.mjs';
|
|||||||
|
|
||||||
/** @class Class representing a pattern. */
|
/** @class Class representing a pattern. */
|
||||||
export class Pattern {
|
export class Pattern {
|
||||||
_Pattern = true; // this property is used to detect if a pattern that fails instanceof Pattern is an instance of another Pattern
|
|
||||||
/**
|
/**
|
||||||
* Create a pattern. As an end user, you will most likely not create a Pattern directly.
|
* Create a pattern. As an end user, you will most likely not create a Pattern directly.
|
||||||
*
|
*
|
||||||
@@ -1050,9 +1049,6 @@ export class Pattern {
|
|||||||
.unit('c')
|
.unit('c')
|
||||||
.slow(factor);
|
.slow(factor);
|
||||||
}
|
}
|
||||||
onTrigger(onTrigger) {
|
|
||||||
return this._withHap((hap) => hap.setContext({ ...hap.context, onTrigger }));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - adopt value.mjs fully..
|
// TODO - adopt value.mjs fully..
|
||||||
@@ -1213,15 +1209,7 @@ export function pure(value) {
|
|||||||
|
|
||||||
export function isPattern(thing) {
|
export function isPattern(thing) {
|
||||||
// thing?.constructor?.name !== 'Pattern' // <- this will fail when code is mangled
|
// thing?.constructor?.name !== 'Pattern' // <- this will fail when code is mangled
|
||||||
const is = thing instanceof Pattern || thing._Pattern;
|
return thing instanceof Pattern;
|
||||||
if (!thing instanceof Pattern) {
|
|
||||||
console.warn(
|
|
||||||
`Found Pattern that fails "instanceof Pattern" check.
|
|
||||||
This may happen if you are using multiple versions of @strudel.cycles/core.
|
|
||||||
Please check by running "npm ls @strudel.cycles/core".`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return is;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function reify(thing) {
|
export function reify(thing) {
|
||||||
@@ -1398,7 +1386,6 @@ export function pr(args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const add = curry((a, pat) => pat.add(a));
|
export const add = curry((a, pat) => pat.add(a));
|
||||||
export const chop = curry((a, pat) => pat.chop(a));
|
|
||||||
export const chunk = curry((a, pat) => pat.chunk(a));
|
export const chunk = curry((a, pat) => pat.chunk(a));
|
||||||
export const chunkBack = curry((a, pat) => pat.chunkBack(a));
|
export const chunkBack = curry((a, pat) => pat.chunkBack(a));
|
||||||
export const div = curry((a, pat) => pat.div(a));
|
export const div = curry((a, pat) => pat.div(a));
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const tokenizeNote = (note) => {
|
|||||||
if (typeof note !== 'string') {
|
if (typeof note !== 'string') {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const [pc, acc = '', oct] = note.match(/^([a-gA-G])([#bs]*)([0-9])?$/)?.slice(1) || [];
|
const [pc, acc = '', oct] = note.match(/^([a-gA-G])([#b]*)([0-9])?$/)?.slice(1) || [];
|
||||||
if (!pc) {
|
if (!pc) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ export const toMidi = (note) => {
|
|||||||
throw new Error('not a note: "' + note + '"');
|
throw new Error('not a note: "' + note + '"');
|
||||||
}
|
}
|
||||||
const chroma = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 }[pc.toLowerCase()];
|
const chroma = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 }[pc.toLowerCase()];
|
||||||
const offset = acc?.split('').reduce((o, char) => o + { '#': 1, b: -1, s: 1 }[char], 0) || 0;
|
const offset = acc?.split('').reduce((o, char) => o + { '#': 1, b: -1 }[char], 0) || 0;
|
||||||
return (Number(oct) + 1) * 12 + chroma + offset;
|
return (Number(oct) + 1) * 12 + chroma + offset;
|
||||||
};
|
};
|
||||||
export const fromMidi = (n) => {
|
export const fromMidi = (n) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/embed",
|
"name": "@strudel.cycles/embed",
|
||||||
"version": "0.1.1",
|
"version": "0.1.0",
|
||||||
"description": "Embeddable Web Component to load a Strudel REPL into an iframe",
|
"description": "Embeddable Web Component to load a Strudel REPL into an iframe",
|
||||||
"main": "embed.js",
|
"main": "embed.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -15,11 +15,9 @@ npm i @strudel.cycles/eval --save
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
import { evaluate, extend } from '@strudel.cycles/eval';
|
import { evaluate, extend } from '@strudel.cycles/eval';
|
||||||
|
import * as strudel from '@strudel.cycles/core';
|
||||||
|
|
||||||
evalScope(
|
extend(strudel); // add strudel to eval scope
|
||||||
import('@strudel.cycles/core'),
|
|
||||||
// import other strudel packages here
|
|
||||||
); // add strudel to eval scope
|
|
||||||
|
|
||||||
async function run(code) {
|
async function run(code) {
|
||||||
const { pattern } = await evaluate(code);
|
const { pattern } = await evaluate(code);
|
||||||
|
|||||||
Generated
+3
-3
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/eval",
|
"name": "@strudel.cycles/eval",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@strudel.cycles/eval",
|
"name": "@strudel.cycles/eval",
|
||||||
"version": "0.1.1",
|
"version": "0.0.3",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"estraverse": "^5.3.0",
|
"estraverse": "^5.3.0",
|
||||||
"shift-ast": "^6.1.0",
|
"shift-ast": "^6.1.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/eval",
|
"name": "@strudel.cycles/eval",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"description": "Code evaluator for strudel",
|
"description": "Code evaluator for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"estraverse": "^5.3.0",
|
"estraverse": "^5.3.0",
|
||||||
"shift-ast": "^6.1.0",
|
"shift-ast": "^6.1.0",
|
||||||
"shift-codegen": "^7.0.3",
|
"shift-codegen": "^7.0.3",
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ export default (_code) => {
|
|||||||
|
|
||||||
const isMarkable = isPatternArg(parents) || hasModifierCall(parent);
|
const isMarkable = isPatternArg(parents) || hasModifierCall(parent);
|
||||||
// add to location to pure(x) calls
|
// add to location to pure(x) calls
|
||||||
if (node.type === 'CallExpression' && node.callee.name === 'pure') {
|
if (addLocations && node.type === 'CallExpression' && node.callee.name === 'pure') {
|
||||||
const literal = node.arguments[0];
|
const literal = node.arguments[0];
|
||||||
// const value = literal[{ LiteralNumericExpression: 'value', LiteralStringExpression: 'name' }[literal.type]];
|
// const value = literal[{ LiteralNumericExpression: 'value', LiteralStringExpression: 'name' }[literal.type]];
|
||||||
return reifyWithLocation(literal, node.arguments[0], ast.locations, artificialNodes);
|
return reifyWithLocation(literal, node.arguments[0], ast.locations, artificialNodes);
|
||||||
|
|||||||
Generated
+3
-3
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/midi",
|
"name": "@strudel.cycles/midi",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@strudel.cycles/midi",
|
"name": "@strudel.cycles/midi",
|
||||||
"version": "0.1.1",
|
"version": "0.0.4",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tone": "^14.7.77",
|
"tone": "^14.7.77",
|
||||||
"webmidi": "^2.5.2"
|
"webmidi": "^2.5.2"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/midi",
|
"name": "@strudel.cycles/midi",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"description": "Midi API for strudel",
|
"description": "Midi API for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/tone": "^0.1.3",
|
"@strudel.cycles/tone": "^0.1.1",
|
||||||
"tone": "^14.7.77",
|
"tone": "^14.7.77",
|
||||||
"webmidi": "^2.5.2"
|
"webmidi": "^2.5.2"
|
||||||
}
|
}
|
||||||
|
|||||||
+133
-139
@@ -1,4 +1,10 @@
|
|||||||
// Generated by Peggy 2.0.1.
|
/*
|
||||||
|
krill-parser.js - <short description TODO>
|
||||||
|
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/mini/krill-parser.js>
|
||||||
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Generated by Peggy 1.2.0.
|
||||||
//
|
//
|
||||||
// https://peggyjs.org/
|
// https://peggyjs.org/
|
||||||
|
|
||||||
@@ -10,7 +16,6 @@ function peg$subclass(child, parent) {
|
|||||||
|
|
||||||
function peg$SyntaxError(message, expected, found, location) {
|
function peg$SyntaxError(message, expected, found, location) {
|
||||||
var self = Error.call(this, message);
|
var self = Error.call(this, message);
|
||||||
// istanbul ignore next Check is a necessary evil to support older environments
|
|
||||||
if (Object.setPrototypeOf) {
|
if (Object.setPrototypeOf) {
|
||||||
Object.setPrototypeOf(self, peg$SyntaxError.prototype);
|
Object.setPrototypeOf(self, peg$SyntaxError.prototype);
|
||||||
}
|
}
|
||||||
@@ -46,15 +51,14 @@ peg$SyntaxError.prototype.format = function(sources) {
|
|||||||
var loc = this.location.source + ":" + s.line + ":" + s.column;
|
var loc = this.location.source + ":" + s.line + ":" + s.column;
|
||||||
if (src) {
|
if (src) {
|
||||||
var e = this.location.end;
|
var e = this.location.end;
|
||||||
var filler = peg$padEnd("", s.line.toString().length, ' ');
|
var filler = peg$padEnd("", s.line.toString().length);
|
||||||
var line = src[s.line - 1];
|
var line = src[s.line - 1];
|
||||||
var last = s.line === e.line ? e.column : line.length + 1;
|
var last = s.line === e.line ? e.column : line.length + 1;
|
||||||
var hatLen = (last - s.column) || 1;
|
|
||||||
str += "\n --> " + loc + "\n"
|
str += "\n --> " + loc + "\n"
|
||||||
+ filler + " |\n"
|
+ filler + " |\n"
|
||||||
+ s.line + " | " + line + "\n"
|
+ s.line + " | " + line + "\n"
|
||||||
+ filler + " | " + peg$padEnd("", s.column - 1, ' ')
|
+ filler + " | " + peg$padEnd("", s.column - 1)
|
||||||
+ peg$padEnd("", hatLen, "^");
|
+ peg$padEnd("", last - s.column, "^");
|
||||||
} else {
|
} else {
|
||||||
str += "\n at " + loc;
|
str += "\n at " + loc;
|
||||||
}
|
}
|
||||||
@@ -75,7 +79,7 @@ peg$SyntaxError.buildMessage = function(expected, found) {
|
|||||||
: classEscape(part);
|
: classEscape(part);
|
||||||
});
|
});
|
||||||
|
|
||||||
return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]";
|
return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";
|
||||||
},
|
},
|
||||||
|
|
||||||
any: function() {
|
any: function() {
|
||||||
@@ -181,32 +185,31 @@ function peg$parse(input, options) {
|
|||||||
var peg$c7 = "#";
|
var peg$c7 = "#";
|
||||||
var peg$c8 = "^";
|
var peg$c8 = "^";
|
||||||
var peg$c9 = "_";
|
var peg$c9 = "_";
|
||||||
var peg$c10 = ":";
|
var peg$c10 = "[";
|
||||||
var peg$c11 = "[";
|
var peg$c11 = "]";
|
||||||
var peg$c12 = "]";
|
var peg$c12 = "<";
|
||||||
var peg$c13 = "<";
|
var peg$c13 = ">";
|
||||||
var peg$c14 = ">";
|
var peg$c14 = "@";
|
||||||
var peg$c15 = "@";
|
var peg$c15 = "!";
|
||||||
var peg$c16 = "!";
|
var peg$c16 = "(";
|
||||||
var peg$c17 = "(";
|
var peg$c17 = ")";
|
||||||
var peg$c18 = ")";
|
var peg$c18 = "/";
|
||||||
var peg$c19 = "/";
|
var peg$c19 = "*";
|
||||||
var peg$c20 = "*";
|
var peg$c20 = "%";
|
||||||
var peg$c21 = "%";
|
var peg$c21 = "struct";
|
||||||
var peg$c22 = "struct";
|
var peg$c22 = "target";
|
||||||
var peg$c23 = "target";
|
var peg$c23 = "euclid";
|
||||||
var peg$c24 = "euclid";
|
var peg$c24 = "slow";
|
||||||
var peg$c25 = "slow";
|
var peg$c25 = "rotL";
|
||||||
var peg$c26 = "rotL";
|
var peg$c26 = "rotR";
|
||||||
var peg$c27 = "rotR";
|
var peg$c27 = "fast";
|
||||||
var peg$c28 = "fast";
|
var peg$c28 = "scale";
|
||||||
var peg$c29 = "scale";
|
var peg$c29 = "//";
|
||||||
var peg$c30 = "//";
|
var peg$c30 = "cat";
|
||||||
var peg$c31 = "cat";
|
var peg$c31 = "$";
|
||||||
var peg$c32 = "$";
|
var peg$c32 = "setcps";
|
||||||
var peg$c33 = "setcps";
|
var peg$c33 = "setbpm";
|
||||||
var peg$c34 = "setbpm";
|
var peg$c34 = "hush";
|
||||||
var peg$c35 = "hush";
|
|
||||||
|
|
||||||
var peg$r0 = /^[1-9]/;
|
var peg$r0 = /^[1-9]/;
|
||||||
var peg$r1 = /^[eE]/;
|
var peg$r1 = /^[eE]/;
|
||||||
@@ -232,33 +235,32 @@ function peg$parse(input, options) {
|
|||||||
var peg$e14 = peg$literalExpectation("#", false);
|
var peg$e14 = peg$literalExpectation("#", false);
|
||||||
var peg$e15 = peg$literalExpectation("^", false);
|
var peg$e15 = peg$literalExpectation("^", false);
|
||||||
var peg$e16 = peg$literalExpectation("_", false);
|
var peg$e16 = peg$literalExpectation("_", false);
|
||||||
var peg$e17 = peg$literalExpectation(":", false);
|
var peg$e17 = peg$literalExpectation("[", false);
|
||||||
var peg$e18 = peg$literalExpectation("[", false);
|
var peg$e18 = peg$literalExpectation("]", false);
|
||||||
var peg$e19 = peg$literalExpectation("]", false);
|
var peg$e19 = peg$literalExpectation("<", false);
|
||||||
var peg$e20 = peg$literalExpectation("<", false);
|
var peg$e20 = peg$literalExpectation(">", false);
|
||||||
var peg$e21 = peg$literalExpectation(">", false);
|
var peg$e21 = peg$literalExpectation("@", false);
|
||||||
var peg$e22 = peg$literalExpectation("@", false);
|
var peg$e22 = peg$literalExpectation("!", false);
|
||||||
var peg$e23 = peg$literalExpectation("!", false);
|
var peg$e23 = peg$literalExpectation("(", false);
|
||||||
var peg$e24 = peg$literalExpectation("(", false);
|
var peg$e24 = peg$literalExpectation(")", false);
|
||||||
var peg$e25 = peg$literalExpectation(")", false);
|
var peg$e25 = peg$literalExpectation("/", false);
|
||||||
var peg$e26 = peg$literalExpectation("/", false);
|
var peg$e26 = peg$literalExpectation("*", false);
|
||||||
var peg$e27 = peg$literalExpectation("*", false);
|
var peg$e27 = peg$literalExpectation("%", false);
|
||||||
var peg$e28 = peg$literalExpectation("%", false);
|
var peg$e28 = peg$literalExpectation("struct", false);
|
||||||
var peg$e29 = peg$literalExpectation("struct", false);
|
var peg$e29 = peg$literalExpectation("target", false);
|
||||||
var peg$e30 = peg$literalExpectation("target", false);
|
var peg$e30 = peg$literalExpectation("euclid", false);
|
||||||
var peg$e31 = peg$literalExpectation("euclid", false);
|
var peg$e31 = peg$literalExpectation("slow", false);
|
||||||
var peg$e32 = peg$literalExpectation("slow", false);
|
var peg$e32 = peg$literalExpectation("rotL", false);
|
||||||
var peg$e33 = peg$literalExpectation("rotL", false);
|
var peg$e33 = peg$literalExpectation("rotR", false);
|
||||||
var peg$e34 = peg$literalExpectation("rotR", false);
|
var peg$e34 = peg$literalExpectation("fast", false);
|
||||||
var peg$e35 = peg$literalExpectation("fast", false);
|
var peg$e35 = peg$literalExpectation("scale", false);
|
||||||
var peg$e36 = peg$literalExpectation("scale", false);
|
var peg$e36 = peg$literalExpectation("//", false);
|
||||||
var peg$e37 = peg$literalExpectation("//", false);
|
var peg$e37 = peg$classExpectation(["\n"], true, false);
|
||||||
var peg$e38 = peg$classExpectation(["\n"], true, false);
|
var peg$e38 = peg$literalExpectation("cat", false);
|
||||||
var peg$e39 = peg$literalExpectation("cat", false);
|
var peg$e39 = peg$literalExpectation("$", false);
|
||||||
var peg$e40 = peg$literalExpectation("$", false);
|
var peg$e40 = peg$literalExpectation("setcps", false);
|
||||||
var peg$e41 = peg$literalExpectation("setcps", false);
|
var peg$e41 = peg$literalExpectation("setbpm", false);
|
||||||
var peg$e42 = peg$literalExpectation("setbpm", false);
|
var peg$e42 = peg$literalExpectation("hush", false);
|
||||||
var peg$e43 = peg$literalExpectation("hush", false);
|
|
||||||
|
|
||||||
var peg$f0 = function() { return parseFloat(text()); };
|
var peg$f0 = function() { return parseFloat(text()); };
|
||||||
var peg$f1 = function(chars) { return chars.join("") };
|
var peg$f1 = function(chars) { return chars.join("") };
|
||||||
@@ -292,6 +294,7 @@ function peg$parse(input, options) {
|
|||||||
var peg$f29 = function(v) { return new CommandStub("setcps", { value: v})};
|
var peg$f29 = function(v) { return new CommandStub("setcps", { value: v})};
|
||||||
var peg$f30 = function(v) { return new CommandStub("setcps", { value: (v/120/2)})};
|
var peg$f30 = function(v) { return new CommandStub("setcps", { value: (v/120/2)})};
|
||||||
var peg$f31 = function() { return new CommandStub("hush")};
|
var peg$f31 = function() { return new CommandStub("hush")};
|
||||||
|
|
||||||
var peg$currPos = 0;
|
var peg$currPos = 0;
|
||||||
var peg$savedPos = 0;
|
var peg$savedPos = 0;
|
||||||
var peg$posDetailsCache = [{ line: 1, column: 1 }];
|
var peg$posDetailsCache = [{ line: 1, column: 1 }];
|
||||||
@@ -807,15 +810,6 @@ function peg$parse(input, options) {
|
|||||||
s0 = peg$FAILED;
|
s0 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e16); }
|
if (peg$silentFails === 0) { peg$fail(peg$e16); }
|
||||||
}
|
}
|
||||||
if (s0 === peg$FAILED) {
|
|
||||||
if (input.charCodeAt(peg$currPos) === 58) {
|
|
||||||
s0 = peg$c10;
|
|
||||||
peg$currPos++;
|
|
||||||
} else {
|
|
||||||
s0 = peg$FAILED;
|
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e17); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -858,11 +852,11 @@ function peg$parse(input, options) {
|
|||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
s1 = peg$parsews();
|
s1 = peg$parsews();
|
||||||
if (input.charCodeAt(peg$currPos) === 91) {
|
if (input.charCodeAt(peg$currPos) === 91) {
|
||||||
s2 = peg$c11;
|
s2 = peg$c10;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s2 = peg$FAILED;
|
s2 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e18); }
|
if (peg$silentFails === 0) { peg$fail(peg$e17); }
|
||||||
}
|
}
|
||||||
if (s2 !== peg$FAILED) {
|
if (s2 !== peg$FAILED) {
|
||||||
s3 = peg$parsews();
|
s3 = peg$parsews();
|
||||||
@@ -870,11 +864,11 @@ function peg$parse(input, options) {
|
|||||||
if (s4 !== peg$FAILED) {
|
if (s4 !== peg$FAILED) {
|
||||||
s5 = peg$parsews();
|
s5 = peg$parsews();
|
||||||
if (input.charCodeAt(peg$currPos) === 93) {
|
if (input.charCodeAt(peg$currPos) === 93) {
|
||||||
s6 = peg$c12;
|
s6 = peg$c11;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s6 = peg$FAILED;
|
s6 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e19); }
|
if (peg$silentFails === 0) { peg$fail(peg$e18); }
|
||||||
}
|
}
|
||||||
if (s6 !== peg$FAILED) {
|
if (s6 !== peg$FAILED) {
|
||||||
s7 = peg$parsews();
|
s7 = peg$parsews();
|
||||||
@@ -902,11 +896,11 @@ function peg$parse(input, options) {
|
|||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
s1 = peg$parsews();
|
s1 = peg$parsews();
|
||||||
if (input.charCodeAt(peg$currPos) === 60) {
|
if (input.charCodeAt(peg$currPos) === 60) {
|
||||||
s2 = peg$c13;
|
s2 = peg$c12;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s2 = peg$FAILED;
|
s2 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e20); }
|
if (peg$silentFails === 0) { peg$fail(peg$e19); }
|
||||||
}
|
}
|
||||||
if (s2 !== peg$FAILED) {
|
if (s2 !== peg$FAILED) {
|
||||||
s3 = peg$parsews();
|
s3 = peg$parsews();
|
||||||
@@ -914,11 +908,11 @@ function peg$parse(input, options) {
|
|||||||
if (s4 !== peg$FAILED) {
|
if (s4 !== peg$FAILED) {
|
||||||
s5 = peg$parsews();
|
s5 = peg$parsews();
|
||||||
if (input.charCodeAt(peg$currPos) === 62) {
|
if (input.charCodeAt(peg$currPos) === 62) {
|
||||||
s6 = peg$c14;
|
s6 = peg$c13;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s6 = peg$FAILED;
|
s6 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e21); }
|
if (peg$silentFails === 0) { peg$fail(peg$e20); }
|
||||||
}
|
}
|
||||||
if (s6 !== peg$FAILED) {
|
if (s6 !== peg$FAILED) {
|
||||||
s7 = peg$parsews();
|
s7 = peg$parsews();
|
||||||
@@ -982,11 +976,11 @@ function peg$parse(input, options) {
|
|||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.charCodeAt(peg$currPos) === 64) {
|
if (input.charCodeAt(peg$currPos) === 64) {
|
||||||
s1 = peg$c15;
|
s1 = peg$c14;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e22); }
|
if (peg$silentFails === 0) { peg$fail(peg$e21); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsenumber();
|
s2 = peg$parsenumber();
|
||||||
@@ -1010,11 +1004,11 @@ function peg$parse(input, options) {
|
|||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.charCodeAt(peg$currPos) === 33) {
|
if (input.charCodeAt(peg$currPos) === 33) {
|
||||||
s1 = peg$c16;
|
s1 = peg$c15;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e23); }
|
if (peg$silentFails === 0) { peg$fail(peg$e22); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsenumber();
|
s2 = peg$parsenumber();
|
||||||
@@ -1038,11 +1032,11 @@ function peg$parse(input, options) {
|
|||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.charCodeAt(peg$currPos) === 40) {
|
if (input.charCodeAt(peg$currPos) === 40) {
|
||||||
s1 = peg$c17;
|
s1 = peg$c16;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e24); }
|
if (peg$silentFails === 0) { peg$fail(peg$e23); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
@@ -1066,11 +1060,11 @@ function peg$parse(input, options) {
|
|||||||
}
|
}
|
||||||
s12 = peg$parsews();
|
s12 = peg$parsews();
|
||||||
if (input.charCodeAt(peg$currPos) === 41) {
|
if (input.charCodeAt(peg$currPos) === 41) {
|
||||||
s13 = peg$c18;
|
s13 = peg$c17;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s13 = peg$FAILED;
|
s13 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e25); }
|
if (peg$silentFails === 0) { peg$fail(peg$e24); }
|
||||||
}
|
}
|
||||||
if (s13 !== peg$FAILED) {
|
if (s13 !== peg$FAILED) {
|
||||||
peg$savedPos = s0;
|
peg$savedPos = s0;
|
||||||
@@ -1104,11 +1098,11 @@ function peg$parse(input, options) {
|
|||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.charCodeAt(peg$currPos) === 47) {
|
if (input.charCodeAt(peg$currPos) === 47) {
|
||||||
s1 = peg$c19;
|
s1 = peg$c18;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e26); }
|
if (peg$silentFails === 0) { peg$fail(peg$e25); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsenumber();
|
s2 = peg$parsenumber();
|
||||||
@@ -1132,11 +1126,11 @@ function peg$parse(input, options) {
|
|||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.charCodeAt(peg$currPos) === 42) {
|
if (input.charCodeAt(peg$currPos) === 42) {
|
||||||
s1 = peg$c20;
|
s1 = peg$c19;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e27); }
|
if (peg$silentFails === 0) { peg$fail(peg$e26); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsenumber();
|
s2 = peg$parsenumber();
|
||||||
@@ -1160,11 +1154,11 @@ function peg$parse(input, options) {
|
|||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.charCodeAt(peg$currPos) === 37) {
|
if (input.charCodeAt(peg$currPos) === 37) {
|
||||||
s1 = peg$c21;
|
s1 = peg$c20;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e28); }
|
if (peg$silentFails === 0) { peg$fail(peg$e27); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsenumber();
|
s2 = peg$parsenumber();
|
||||||
@@ -1338,12 +1332,12 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1, s2, s3;
|
var s0, s1, s2, s3;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 6) === peg$c22) {
|
if (input.substr(peg$currPos, 6) === peg$c21) {
|
||||||
s1 = peg$c22;
|
s1 = peg$c21;
|
||||||
peg$currPos += 6;
|
peg$currPos += 6;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e29); }
|
if (peg$silentFails === 0) { peg$fail(peg$e28); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
@@ -1367,12 +1361,12 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1, s2, s3, s4, s5;
|
var s0, s1, s2, s3, s4, s5;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 6) === peg$c23) {
|
if (input.substr(peg$currPos, 6) === peg$c22) {
|
||||||
s1 = peg$c23;
|
s1 = peg$c22;
|
||||||
peg$currPos += 6;
|
peg$currPos += 6;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e30); }
|
if (peg$silentFails === 0) { peg$fail(peg$e29); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
@@ -1408,12 +1402,12 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1, s2, s3, s4, s5, s6, s7;
|
var s0, s1, s2, s3, s4, s5, s6, s7;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 6) === peg$c24) {
|
if (input.substr(peg$currPos, 6) === peg$c23) {
|
||||||
s1 = peg$c24;
|
s1 = peg$c23;
|
||||||
peg$currPos += 6;
|
peg$currPos += 6;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e31); }
|
if (peg$silentFails === 0) { peg$fail(peg$e30); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
@@ -1449,12 +1443,12 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1, s2, s3;
|
var s0, s1, s2, s3;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 4) === peg$c25) {
|
if (input.substr(peg$currPos, 4) === peg$c24) {
|
||||||
s1 = peg$c25;
|
s1 = peg$c24;
|
||||||
peg$currPos += 4;
|
peg$currPos += 4;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e32); }
|
if (peg$silentFails === 0) { peg$fail(peg$e31); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
@@ -1478,12 +1472,12 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1, s2, s3;
|
var s0, s1, s2, s3;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 4) === peg$c26) {
|
if (input.substr(peg$currPos, 4) === peg$c25) {
|
||||||
s1 = peg$c26;
|
s1 = peg$c25;
|
||||||
peg$currPos += 4;
|
peg$currPos += 4;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e33); }
|
if (peg$silentFails === 0) { peg$fail(peg$e32); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
@@ -1507,12 +1501,12 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1, s2, s3;
|
var s0, s1, s2, s3;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 4) === peg$c27) {
|
if (input.substr(peg$currPos, 4) === peg$c26) {
|
||||||
s1 = peg$c27;
|
s1 = peg$c26;
|
||||||
peg$currPos += 4;
|
peg$currPos += 4;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e34); }
|
if (peg$silentFails === 0) { peg$fail(peg$e33); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
@@ -1536,12 +1530,12 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1, s2, s3;
|
var s0, s1, s2, s3;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 4) === peg$c28) {
|
if (input.substr(peg$currPos, 4) === peg$c27) {
|
||||||
s1 = peg$c28;
|
s1 = peg$c27;
|
||||||
peg$currPos += 4;
|
peg$currPos += 4;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e35); }
|
if (peg$silentFails === 0) { peg$fail(peg$e34); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
@@ -1565,12 +1559,12 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1, s2, s3, s4, s5;
|
var s0, s1, s2, s3, s4, s5;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 5) === peg$c29) {
|
if (input.substr(peg$currPos, 5) === peg$c28) {
|
||||||
s1 = peg$c29;
|
s1 = peg$c28;
|
||||||
peg$currPos += 5;
|
peg$currPos += 5;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e36); }
|
if (peg$silentFails === 0) { peg$fail(peg$e35); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
@@ -1615,12 +1609,12 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1, s2, s3;
|
var s0, s1, s2, s3;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 2) === peg$c30) {
|
if (input.substr(peg$currPos, 2) === peg$c29) {
|
||||||
s1 = peg$c30;
|
s1 = peg$c29;
|
||||||
peg$currPos += 2;
|
peg$currPos += 2;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e37); }
|
if (peg$silentFails === 0) { peg$fail(peg$e36); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = [];
|
s2 = [];
|
||||||
@@ -1629,7 +1623,7 @@ function peg$parse(input, options) {
|
|||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s3 = peg$FAILED;
|
s3 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e38); }
|
if (peg$silentFails === 0) { peg$fail(peg$e37); }
|
||||||
}
|
}
|
||||||
while (s3 !== peg$FAILED) {
|
while (s3 !== peg$FAILED) {
|
||||||
s2.push(s3);
|
s2.push(s3);
|
||||||
@@ -1638,7 +1632,7 @@ function peg$parse(input, options) {
|
|||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s3 = peg$FAILED;
|
s3 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e38); }
|
if (peg$silentFails === 0) { peg$fail(peg$e37); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s1 = [s1, s2];
|
s1 = [s1, s2];
|
||||||
@@ -1655,21 +1649,21 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
|
var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 3) === peg$c31) {
|
if (input.substr(peg$currPos, 3) === peg$c30) {
|
||||||
s1 = peg$c31;
|
s1 = peg$c30;
|
||||||
peg$currPos += 3;
|
peg$currPos += 3;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e39); }
|
if (peg$silentFails === 0) { peg$fail(peg$e38); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
if (input.charCodeAt(peg$currPos) === 91) {
|
if (input.charCodeAt(peg$currPos) === 91) {
|
||||||
s3 = peg$c11;
|
s3 = peg$c10;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s3 = peg$FAILED;
|
s3 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e18); }
|
if (peg$silentFails === 0) { peg$fail(peg$e17); }
|
||||||
}
|
}
|
||||||
if (s3 !== peg$FAILED) {
|
if (s3 !== peg$FAILED) {
|
||||||
s4 = peg$parsews();
|
s4 = peg$parsews();
|
||||||
@@ -1711,11 +1705,11 @@ function peg$parse(input, options) {
|
|||||||
}
|
}
|
||||||
s7 = peg$parsews();
|
s7 = peg$parsews();
|
||||||
if (input.charCodeAt(peg$currPos) === 93) {
|
if (input.charCodeAt(peg$currPos) === 93) {
|
||||||
s8 = peg$c12;
|
s8 = peg$c11;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s8 = peg$FAILED;
|
s8 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e19); }
|
if (peg$silentFails === 0) { peg$fail(peg$e18); }
|
||||||
}
|
}
|
||||||
if (s8 !== peg$FAILED) {
|
if (s8 !== peg$FAILED) {
|
||||||
peg$savedPos = s0;
|
peg$savedPos = s0;
|
||||||
@@ -1776,11 +1770,11 @@ function peg$parse(input, options) {
|
|||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
if (input.charCodeAt(peg$currPos) === 36) {
|
if (input.charCodeAt(peg$currPos) === 36) {
|
||||||
s3 = peg$c32;
|
s3 = peg$c31;
|
||||||
peg$currPos++;
|
peg$currPos++;
|
||||||
} else {
|
} else {
|
||||||
s3 = peg$FAILED;
|
s3 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e40); }
|
if (peg$silentFails === 0) { peg$fail(peg$e39); }
|
||||||
}
|
}
|
||||||
if (s3 !== peg$FAILED) {
|
if (s3 !== peg$FAILED) {
|
||||||
s4 = peg$parsews();
|
s4 = peg$parsews();
|
||||||
@@ -1858,12 +1852,12 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1, s2, s3;
|
var s0, s1, s2, s3;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 6) === peg$c33) {
|
if (input.substr(peg$currPos, 6) === peg$c32) {
|
||||||
s1 = peg$c33;
|
s1 = peg$c32;
|
||||||
peg$currPos += 6;
|
peg$currPos += 6;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e41); }
|
if (peg$silentFails === 0) { peg$fail(peg$e40); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
@@ -1887,12 +1881,12 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1, s2, s3;
|
var s0, s1, s2, s3;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 6) === peg$c34) {
|
if (input.substr(peg$currPos, 6) === peg$c33) {
|
||||||
s1 = peg$c34;
|
s1 = peg$c33;
|
||||||
peg$currPos += 6;
|
peg$currPos += 6;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e42); }
|
if (peg$silentFails === 0) { peg$fail(peg$e41); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
s2 = peg$parsews();
|
s2 = peg$parsews();
|
||||||
@@ -1916,12 +1910,12 @@ function peg$parse(input, options) {
|
|||||||
var s0, s1;
|
var s0, s1;
|
||||||
|
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
if (input.substr(peg$currPos, 4) === peg$c35) {
|
if (input.substr(peg$currPos, 4) === peg$c34) {
|
||||||
s1 = peg$c35;
|
s1 = peg$c34;
|
||||||
peg$currPos += 4;
|
peg$currPos += 4;
|
||||||
} else {
|
} else {
|
||||||
s1 = peg$FAILED;
|
s1 = peg$FAILED;
|
||||||
if (peg$silentFails === 0) { peg$fail(peg$e43); }
|
if (peg$silentFails === 0) { peg$fail(peg$e42); }
|
||||||
}
|
}
|
||||||
if (s1 !== peg$FAILED) {
|
if (s1 !== peg$FAILED) {
|
||||||
peg$savedPos = s0;
|
peg$savedPos = s0;
|
||||||
@@ -1974,6 +1968,7 @@ function peg$parse(input, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
peg$result = peg$startRuleFunction();
|
peg$result = peg$startRuleFunction();
|
||||||
|
|
||||||
if (peg$result !== peg$FAILED && peg$currPos === input.length) {
|
if (peg$result !== peg$FAILED && peg$currPos === input.length) {
|
||||||
@@ -1995,6 +1990,5 @@ function peg$parse(input, options) {
|
|||||||
|
|
||||||
export {
|
export {
|
||||||
peg$SyntaxError as SyntaxError,
|
peg$SyntaxError as SyntaxError,
|
||||||
|
|
||||||
peg$parse as parse
|
peg$parse as parse
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ quote = '"' / "'"
|
|||||||
// ------------------ steps and cycles ---------------------------
|
// ------------------ steps and cycles ---------------------------
|
||||||
|
|
||||||
// single step definition (e.g bd)
|
// single step definition (e.g bd)
|
||||||
step_char = [0-9a-zA-Z~] / "-" / "#" / "." / "^" / "_" / ":"
|
step_char = [0-9a-zA-Z~] / "-" / "#" / "." / "^" / "_"
|
||||||
step = ws chars:step_char+ ws { return chars.join("") }
|
step = ws chars:step_char+ ws { return chars.join("") }
|
||||||
|
|
||||||
// define a sub cycle e.g. [1 2, 3 [4]]
|
// define a sub cycle e.g. [1 2, 3 [4]]
|
||||||
|
|||||||
Generated
-1031
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/mini",
|
"name": "@strudel.cycles/mini",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"description": "Mini notation for strudel",
|
"description": "Mini notation for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha --colors",
|
"test": "mocha --colors"
|
||||||
"build:parser": "peggy -o krill-parser.js --format es ./krill.pegjs"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -26,11 +25,8 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"@strudel.cycles/eval": "^0.1.3",
|
"@strudel.cycles/eval": "^0.1.1",
|
||||||
"@strudel.cycles/tone": "^0.1.3"
|
"@strudel.cycles/tone": "^0.1.1"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"peggy": "^2.0.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,15 +22,13 @@ let startedAt = -1;
|
|||||||
*/
|
*/
|
||||||
Pattern.prototype.osc = function () {
|
Pattern.prototype.osc = function () {
|
||||||
return this._withHap((hap) => {
|
return this._withHap((hap) => {
|
||||||
const onTrigger = (time, hap, currentTime, cps) => {
|
const onTrigger = (time, hap, currentTime, cps, cycle, delta) => {
|
||||||
const cycle = hap.wholeOrPart().begin.valueOf();
|
|
||||||
const delta = hap.duration.valueOf();
|
|
||||||
// time should be audio time of onset
|
// time should be audio time of onset
|
||||||
// currentTime should be current time of audio context (slightly before time)
|
// currentTime should be current time of audio context (slightly before time)
|
||||||
if (startedAt < 0) {
|
if (startedAt < 0) {
|
||||||
startedAt = Date.now() - currentTime * 1000;
|
startedAt = Date.now() - currentTime * 1000;
|
||||||
}
|
}
|
||||||
const controls = Object.assign({}, { cps, cycle, delta }, hap.value);
|
const controls = Object.assign({}, { cps: cps, cycle: cycle, delta: delta }, hap.value);
|
||||||
const keyvals = Object.entries(controls).flat();
|
const keyvals = Object.entries(controls).flat();
|
||||||
const ts = Math.floor(startedAt + (time + latency) * 1000);
|
const ts = Math.floor(startedAt + (time + latency) * 1000);
|
||||||
const message = new OSC.Message('/dirt/play', ...keyvals);
|
const message = new OSC.Message('/dirt/play', ...keyvals);
|
||||||
|
|||||||
Generated
+3
-3
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/osc",
|
"name": "@strudel.cycles/osc",
|
||||||
"version": "0.1.1",
|
"version": "0.1.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@strudel.cycles/osc",
|
"name": "@strudel.cycles/osc",
|
||||||
"version": "0.1.0",
|
"version": "0.0.1",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"osc-js": "^2.3.2"
|
"osc-js": "^2.3.2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/osc",
|
"name": "@strudel.cycles/osc",
|
||||||
"version": "0.1.1",
|
"version": "0.1.0",
|
||||||
"description": "OSC messaging for strudel",
|
"description": "OSC messaging for strudel",
|
||||||
"main": "osc.mjs",
|
"main": "osc.mjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+10
-35
@@ -145,37 +145,6 @@ const materialPalenightHighlightStyle = HighlightStyle.define([
|
|||||||
// : Extension
|
// : Extension
|
||||||
const materialPalenight = [materialPalenightTheme, materialPalenightHighlightStyle];
|
const materialPalenight = [materialPalenightTheme, materialPalenightHighlightStyle];
|
||||||
|
|
||||||
const setFlash = StateEffect.define();
|
|
||||||
const flashField = StateField.define({
|
|
||||||
create() {
|
|
||||||
return Decoration.none;
|
|
||||||
},
|
|
||||||
update(flash2, tr) {
|
|
||||||
try {
|
|
||||||
for (let e of tr.effects) {
|
|
||||||
if (e.is(setFlash)) {
|
|
||||||
if (e.value) {
|
|
||||||
const mark = Decoration.mark({ attributes: { style: `background-color: #FFCA2880` } });
|
|
||||||
flash2 = Decoration.set([mark.range(0, tr.newDoc.length)]);
|
|
||||||
} else {
|
|
||||||
flash2 = Decoration.set([]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flash2;
|
|
||||||
} catch (err) {
|
|
||||||
console.warn("flash error", err);
|
|
||||||
return flash2;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
provide: (f) => EditorView.decorations.from(f)
|
|
||||||
});
|
|
||||||
const flash = (view) => {
|
|
||||||
view.dispatch({ effects: setFlash.of(true) });
|
|
||||||
setTimeout(() => {
|
|
||||||
view.dispatch({ effects: setFlash.of(false) });
|
|
||||||
}, 200);
|
|
||||||
};
|
|
||||||
const setHighlights = StateEffect.define();
|
const setHighlights = StateEffect.define();
|
||||||
const highlightField = StateField.define({
|
const highlightField = StateField.define({
|
||||||
create() {
|
create() {
|
||||||
@@ -218,8 +187,7 @@ function CodeMirror({ value, onChange, onViewChanged, onCursor, options, editorD
|
|||||||
extensions: [
|
extensions: [
|
||||||
javascript(),
|
javascript(),
|
||||||
materialPalenight,
|
materialPalenight,
|
||||||
highlightField,
|
highlightField
|
||||||
flashField
|
|
||||||
]
|
]
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -372,7 +340,14 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw: onDrawP
|
|||||||
/* console.warn('no instrument chosen', event);
|
/* console.warn('no instrument chosen', event);
|
||||||
throw new Error(`no instrument chosen for ${JSON.stringify(event)}`); */
|
throw new Error(`no instrument chosen for ${JSON.stringify(event)}`); */
|
||||||
} else {
|
} else {
|
||||||
onTrigger(time, event, currentTime, 1 /* cps */);
|
onTrigger(
|
||||||
|
time,
|
||||||
|
event,
|
||||||
|
currentTime,
|
||||||
|
1 /* cps */,
|
||||||
|
event.wholeOrPart().begin.valueOf(),
|
||||||
|
event.duration.valueOf(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn(err);
|
console.warn(err);
|
||||||
@@ -648,4 +623,4 @@ function useWebMidi(props) {
|
|||||||
return { loading, outputs, outputByName };
|
return { loading, outputs, outputByName };
|
||||||
}
|
}
|
||||||
|
|
||||||
export { CodeMirror, MiniRepl, cx, flash, useCycle, useHighlighting, usePostMessage, useRepl, useWebMidi };
|
export { CodeMirror, MiniRepl, cx, useCycle, useHighlighting, usePostMessage, useRepl, useWebMidi };
|
||||||
|
|||||||
Generated
-3984
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/react",
|
"name": "@strudel.cycles/react",
|
||||||
"version": "0.1.4",
|
"version": "0.1.2",
|
||||||
"description": "React components for strudel",
|
"description": "React components for strudel",
|
||||||
"main": "dist/index.cjs.js",
|
"main": "dist/index.cjs.js",
|
||||||
"module": "dist/index.es.js",
|
"module": "dist/index.es.js",
|
||||||
@@ -38,9 +38,9 @@
|
|||||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/lang-javascript": "^0.19.0",
|
"@codemirror/lang-javascript": "^0.19.0",
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "*",
|
||||||
"@strudel.cycles/eval": "^0.1.3",
|
"@strudel.cycles/eval": "^0.1.1",
|
||||||
"@strudel.cycles/tone": "^0.1.3",
|
"@strudel.cycles/tone": "^0.1.1",
|
||||||
"react-codemirror6": "^1.1.0",
|
"react-codemirror6": "^1.1.0",
|
||||||
"react-hook-inview": "^4.5.0"
|
"react-hook-inview": "^4.5.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,39 +7,6 @@ import { javascript } from '@codemirror/lang-javascript';
|
|||||||
// import { materialPalenight } from 'codemirror6-themes';
|
// import { materialPalenight } from 'codemirror6-themes';
|
||||||
import { materialPalenight } from '../themes/material-palenight';
|
import { materialPalenight } from '../themes/material-palenight';
|
||||||
|
|
||||||
export const setFlash = StateEffect.define();
|
|
||||||
const flashField = StateField.define({
|
|
||||||
create() {
|
|
||||||
return Decoration.none;
|
|
||||||
},
|
|
||||||
update(flash, tr) {
|
|
||||||
try {
|
|
||||||
for (let e of tr.effects) {
|
|
||||||
if (e.is(setFlash)) {
|
|
||||||
if (e.value) {
|
|
||||||
const mark = Decoration.mark({ attributes: { style: `background-color: #FFCA2880` } });
|
|
||||||
flash = Decoration.set([mark.range(0, tr.newDoc.length)]);
|
|
||||||
} else {
|
|
||||||
flash = Decoration.set([]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flash;
|
|
||||||
} catch (err) {
|
|
||||||
console.warn('flash error', err);
|
|
||||||
return flash;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
provide: (f) => EditorView.decorations.from(f),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const flash = (view) => {
|
|
||||||
view.dispatch({ effects: setFlash.of(true) });
|
|
||||||
setTimeout(() => {
|
|
||||||
view.dispatch({ effects: setFlash.of(false) });
|
|
||||||
}, 200);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setHighlights = StateEffect.define();
|
export const setHighlights = StateEffect.define();
|
||||||
const highlightField = StateField.define({
|
const highlightField = StateField.define({
|
||||||
create() {
|
create() {
|
||||||
@@ -94,7 +61,6 @@ export default function CodeMirror({ value, onChange, onViewChanged, onCursor, o
|
|||||||
javascript(),
|
javascript(),
|
||||||
materialPalenight,
|
materialPalenight,
|
||||||
highlightField,
|
highlightField,
|
||||||
flashField,
|
|
||||||
// theme, language, ...
|
// theme, language, ...
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -57,7 +57,14 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw: onDrawP
|
|||||||
/* console.warn('no instrument chosen', event);
|
/* console.warn('no instrument chosen', event);
|
||||||
throw new Error(`no instrument chosen for ${JSON.stringify(event)}`); */
|
throw new Error(`no instrument chosen for ${JSON.stringify(event)}`); */
|
||||||
} else {
|
} else {
|
||||||
onTrigger(time, event, currentTime, 1 /* cps */);
|
onTrigger(
|
||||||
|
time,
|
||||||
|
event,
|
||||||
|
currentTime,
|
||||||
|
1 /* cps */,
|
||||||
|
event.wholeOrPart().begin.valueOf(),
|
||||||
|
event.duration.valueOf(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn(err);
|
console.warn(err);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// import 'tailwindcss/tailwind.css';
|
// import 'tailwindcss/tailwind.css';
|
||||||
|
|
||||||
export { default as CodeMirror, flash } from './components/CodeMirror6';
|
export { default as CodeMirror } from './components/CodeMirror6';
|
||||||
export * from './components/MiniRepl';
|
export * from './components/MiniRepl';
|
||||||
export { default as useCycle } from './hooks/useCycle';
|
export { default as useCycle } from './hooks/useCycle';
|
||||||
export { default as useHighlighting } from './hooks/useHighlighting';
|
export { default as useHighlighting } from './hooks/useHighlighting';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/serial",
|
"name": "@strudel.cycles/serial",
|
||||||
"version": "0.1.3",
|
"version": "0.1.0",
|
||||||
"description": "Webserial API for strudel",
|
"description": "Webserial API for strudel",
|
||||||
"main": "serial.mjs",
|
"main": "serial.mjs",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { Pattern, isPattern } from '@strudel.cycles/core';
|
|||||||
var serialWriter;
|
var serialWriter;
|
||||||
var choosing = false;
|
var choosing = false;
|
||||||
|
|
||||||
export async function getWriter(br=38400) {
|
export async function getWriter(br=115200) {
|
||||||
if (choosing) {
|
if (choosing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,8 @@ export async function getWriter(br=38400) {
|
|||||||
|
|
||||||
const latency = 0.1;
|
const latency = 0.1;
|
||||||
|
|
||||||
Pattern.prototype.serial = function (...args) {
|
// Pattern.prototype.midi = function (output: string | number, channel = 1) {
|
||||||
|
Pattern.prototype.serial = async function (...args) {
|
||||||
return this._withHap((hap) => {
|
return this._withHap((hap) => {
|
||||||
if (!serialWriter) {
|
if (!serialWriter) {
|
||||||
getWriter(...args);
|
getWriter(...args);
|
||||||
@@ -42,29 +43,10 @@ Pattern.prototype.serial = function (...args) {
|
|||||||
const onTrigger = (time, hap, currentTime) => {
|
const onTrigger = (time, hap, currentTime) => {
|
||||||
var message = "";
|
var message = "";
|
||||||
if (typeof hap.value === 'object') {
|
if (typeof hap.value === 'object') {
|
||||||
if ('action' in hap.value) {
|
for (const [key, val] of Object.entries(hap.value).flat()) {
|
||||||
message += hap.value['action'] + '(';
|
|
||||||
var first = true;
|
|
||||||
for (const [key, val] of Object.entries(hap.value)) {
|
|
||||||
if (key === 'action') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (first) {
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
message +=',';
|
|
||||||
}
|
|
||||||
message += `${key}:${val}`
|
|
||||||
}
|
|
||||||
message += ')';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (const [key, val] of Object.entries(hap.value)) {
|
|
||||||
message += `${key}:${val};`
|
message += `${key}:${val};`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
message = hap.value;
|
message = hap.value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
// this script converts a soundfont into a json file, it has not been not used yet
|
|
||||||
import fetch from 'node-fetch';
|
|
||||||
|
|
||||||
const name = '0000_JCLive';
|
|
||||||
|
|
||||||
const js = await fetch(`https://felixroos.github.io/webaudiofontdata/sound/${name}_sf2_file.js`).then((res) =>
|
|
||||||
res.text(),
|
|
||||||
);
|
|
||||||
// console.log(js);
|
|
||||||
|
|
||||||
let [_, data] = js.split('_sf2_file=');
|
|
||||||
data = eval(data);
|
|
||||||
console.log(JSON.stringify(data));
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
let loadCache = {};
|
|
||||||
async function loadFont(name) {
|
|
||||||
if (loadCache[name]) {
|
|
||||||
return loadCache[name];
|
|
||||||
}
|
|
||||||
const load = async () => {
|
|
||||||
// TODO: make soundfont source configurable
|
|
||||||
const url = `https://felixroos.github.io/webaudiofontdata/sound/${name}.js`;
|
|
||||||
console.log('load font', name, url);
|
|
||||||
const preset = await fetch(url).then((res) => res.text());
|
|
||||||
let [_, data] = preset.split('={');
|
|
||||||
return eval('{' + data);
|
|
||||||
};
|
|
||||||
loadCache[name] = load();
|
|
||||||
return loadCache[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getFontBufferSource(name, pitch, ac) {
|
|
||||||
if (typeof pitch === 'string') {
|
|
||||||
pitch = toMidi(pitch);
|
|
||||||
}
|
|
||||||
const { buffer, zone } = await getFontPitch(name, pitch, ac);
|
|
||||||
const src = ac.createBufferSource();
|
|
||||||
src.buffer = buffer;
|
|
||||||
const baseDetune = zone.originalPitch - 100.0 * zone.coarseTune - zone.fineTune;
|
|
||||||
const playbackRate = 1.0 * Math.pow(2, (100.0 * pitch - baseDetune) / 1200.0);
|
|
||||||
// src detune?
|
|
||||||
src.playbackRate.value = playbackRate;
|
|
||||||
const loop = zone.loopStart > 1 && zone.loopStart < zone.loopEnd;
|
|
||||||
if (!loop) {
|
|
||||||
/* const waveDuration = duration + this.afterTime;
|
|
||||||
if (waveDuration > zone.buffer.duration / playbackRate) {
|
|
||||||
waveDuration = zone.buffer.duration / playbackRate;
|
|
||||||
// TODO: do sth with waveduration
|
|
||||||
} */
|
|
||||||
} else {
|
|
||||||
src.loop = true;
|
|
||||||
src.loopStart = zone.loopStart / zone.sampleRate;
|
|
||||||
src.loopEnd = zone.loopEnd / zone.sampleRate;
|
|
||||||
//+ (zone.delay ? zone.delay : 0);
|
|
||||||
}
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
let bufferCache = {};
|
|
||||||
export async function getFontPitch(name, pitch, ac) {
|
|
||||||
const key = `${name}:::${pitch}`;
|
|
||||||
if (bufferCache[key]) {
|
|
||||||
return bufferCache[key];
|
|
||||||
}
|
|
||||||
// console.log('load buffer', key);
|
|
||||||
const load = async () => {
|
|
||||||
const preset = await loadFont(name);
|
|
||||||
if (!preset) {
|
|
||||||
throw new Error(`Could not load soundfont ${name}`);
|
|
||||||
}
|
|
||||||
const zone = findZone(preset, pitch);
|
|
||||||
if (!zone) {
|
|
||||||
throw new Error('no soundfont zone found for preset ', name, 'pitch', pitch);
|
|
||||||
}
|
|
||||||
const buffer = await getBuffer(zone, ac);
|
|
||||||
if (!buffer) {
|
|
||||||
throw new Error(`no soundfont buffer found for preset ${name}, pitch: ${pitch}`);
|
|
||||||
}
|
|
||||||
return { buffer, zone };
|
|
||||||
};
|
|
||||||
bufferCache[key] = load(); // dont await here to cache promise immediately!
|
|
||||||
return bufferCache[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
function findZone(preset, pitch) {
|
|
||||||
return preset.find((zone) => {
|
|
||||||
return zone.keyRangeLow <= pitch && zone.keyRangeHigh + 1 >= pitch;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// promisified version of https://github.com/felixroos/webaudiofont/blob/c6f97249b60dcfafc20fca5bb381294a6b2f8f51/npm/dist/WebAudioFontPlayer.js#L740
|
|
||||||
async function getBuffer(zone, audioContext) {
|
|
||||||
if (zone.sample) {
|
|
||||||
console.warn('zone.sample untested!');
|
|
||||||
const decoded = atob(zone.sample);
|
|
||||||
zone.buffer = audioContext.createBuffer(1, decoded.length / 2, zone.sampleRate);
|
|
||||||
const float32Array = zone.buffer.getChannelData(0);
|
|
||||||
let b1, b2, n;
|
|
||||||
for (var i = 0; i < decoded.length / 2; i++) {
|
|
||||||
b1 = decoded.charCodeAt(i * 2);
|
|
||||||
b2 = decoded.charCodeAt(i * 2 + 1);
|
|
||||||
if (b1 < 0) {
|
|
||||||
b1 = 256 + b1;
|
|
||||||
}
|
|
||||||
if (b2 < 0) {
|
|
||||||
b2 = 256 + b2;
|
|
||||||
}
|
|
||||||
n = b2 * 256 + b1;
|
|
||||||
if (n >= 65536 / 2) {
|
|
||||||
n = n - 65536;
|
|
||||||
}
|
|
||||||
float32Array[i] = n / 65536.0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (zone.file) {
|
|
||||||
const datalen = zone.file.length;
|
|
||||||
const arraybuffer = new ArrayBuffer(datalen);
|
|
||||||
const view = new Uint8Array(arraybuffer);
|
|
||||||
const decoded = atob(zone.file);
|
|
||||||
let b;
|
|
||||||
for (let i = 0; i < decoded.length; i++) {
|
|
||||||
b = decoded.charCodeAt(i);
|
|
||||||
view[i] = b;
|
|
||||||
}
|
|
||||||
return new Promise((resolve) => audioContext.decodeAudioData(arraybuffer, resolve));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import { getFontBufferSource } from './fontloader.mjs';
|
|
||||||
import * as soundfontList from './list.mjs';
|
|
||||||
|
|
||||||
globalThis.getFontBufferSource = getFontBufferSource;
|
|
||||||
globalThis.soundfontList = soundfontList;
|
|
||||||
globalThis.soundfontList = soundfontList;
|
|
||||||
File diff suppressed because it is too large
Load Diff
Generated
-301
@@ -1,301 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@strudel.cycles/soundfonts",
|
|
||||||
"version": "0.1.1",
|
|
||||||
"lockfileVersion": 2,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"name": "@strudel.cycles/soundfonts",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"license": "AGPL-3.0-or-later",
|
|
||||||
"dependencies": {
|
|
||||||
"webaudiofont": "^3.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/balanced-match": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
|
||||||
},
|
|
||||||
"node_modules/brace-expansion": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
|
||||||
"dependencies": {
|
|
||||||
"balanced-match": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fs.realpath": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
|
||||||
},
|
|
||||||
"node_modules/glob": {
|
|
||||||
"version": "8.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
|
|
||||||
"integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"fs.realpath": "^1.0.0",
|
|
||||||
"inflight": "^1.0.4",
|
|
||||||
"inherits": "2",
|
|
||||||
"minimatch": "^5.0.1",
|
|
||||||
"once": "^1.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/inflight": {
|
|
||||||
"version": "1.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
|
||||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
|
||||||
"dependencies": {
|
|
||||||
"once": "^1.3.0",
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/inherits": {
|
|
||||||
"version": "2.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
|
||||||
},
|
|
||||||
"node_modules/jsonc-parser": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA=="
|
|
||||||
},
|
|
||||||
"node_modules/lunr": {
|
|
||||||
"version": "2.3.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
|
|
||||||
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="
|
|
||||||
},
|
|
||||||
"node_modules/marked": {
|
|
||||||
"version": "4.0.17",
|
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz",
|
|
||||||
"integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA==",
|
|
||||||
"bin": {
|
|
||||||
"marked": "bin/marked.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/minimatch": {
|
|
||||||
"version": "5.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
|
|
||||||
"integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
|
|
||||||
"dependencies": {
|
|
||||||
"brace-expansion": "^2.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/once": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
|
||||||
"dependencies": {
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/shiki": {
|
|
||||||
"version": "0.10.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz",
|
|
||||||
"integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==",
|
|
||||||
"dependencies": {
|
|
||||||
"jsonc-parser": "^3.0.0",
|
|
||||||
"vscode-oniguruma": "^1.6.1",
|
|
||||||
"vscode-textmate": "5.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/typedoc": {
|
|
||||||
"version": "0.22.17",
|
|
||||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.17.tgz",
|
|
||||||
"integrity": "sha512-h6+uXHVVCPDaANzjwzdsj9aePBjZiBTpiMpBBeyh1zcN2odVsDCNajz8zyKnixF93HJeGpl34j/70yoEE5BfNg==",
|
|
||||||
"dependencies": {
|
|
||||||
"glob": "^8.0.3",
|
|
||||||
"lunr": "^2.3.9",
|
|
||||||
"marked": "^4.0.16",
|
|
||||||
"minimatch": "^5.1.0",
|
|
||||||
"shiki": "^0.10.1"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"typedoc": "bin/typedoc"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 12.10.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x || 4.7.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/typescript": {
|
|
||||||
"version": "4.7.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
|
|
||||||
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
|
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
|
||||||
"tsc": "bin/tsc",
|
|
||||||
"tsserver": "bin/tsserver"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vscode-oniguruma": {
|
|
||||||
"version": "1.6.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz",
|
|
||||||
"integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA=="
|
|
||||||
},
|
|
||||||
"node_modules/vscode-textmate": {
|
|
||||||
"version": "5.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz",
|
|
||||||
"integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ=="
|
|
||||||
},
|
|
||||||
"node_modules/webaudiofont": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/webaudiofont/-/webaudiofont-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-PwqbR4OdvzbW8/TLTitSU/rw4mxMKyAGTKV42mePCgMoUGLJoQj8HDLWVqtNOpUZ0ghPNhNE6cRFEv6HFFEBQA==",
|
|
||||||
"dependencies": {
|
|
||||||
"typedoc": "^0.22.14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/wrappy": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"balanced-match": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
|
||||||
},
|
|
||||||
"brace-expansion": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
|
||||||
"requires": {
|
|
||||||
"balanced-match": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fs.realpath": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
|
||||||
},
|
|
||||||
"glob": {
|
|
||||||
"version": "8.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
|
|
||||||
"integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==",
|
|
||||||
"requires": {
|
|
||||||
"fs.realpath": "^1.0.0",
|
|
||||||
"inflight": "^1.0.4",
|
|
||||||
"inherits": "2",
|
|
||||||
"minimatch": "^5.0.1",
|
|
||||||
"once": "^1.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"inflight": {
|
|
||||||
"version": "1.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
|
||||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
|
||||||
"requires": {
|
|
||||||
"once": "^1.3.0",
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"inherits": {
|
|
||||||
"version": "2.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
|
||||||
},
|
|
||||||
"jsonc-parser": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA=="
|
|
||||||
},
|
|
||||||
"lunr": {
|
|
||||||
"version": "2.3.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
|
|
||||||
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="
|
|
||||||
},
|
|
||||||
"marked": {
|
|
||||||
"version": "4.0.17",
|
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz",
|
|
||||||
"integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA=="
|
|
||||||
},
|
|
||||||
"minimatch": {
|
|
||||||
"version": "5.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
|
|
||||||
"integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
|
|
||||||
"requires": {
|
|
||||||
"brace-expansion": "^2.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"once": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
|
||||||
"requires": {
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"shiki": {
|
|
||||||
"version": "0.10.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz",
|
|
||||||
"integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==",
|
|
||||||
"requires": {
|
|
||||||
"jsonc-parser": "^3.0.0",
|
|
||||||
"vscode-oniguruma": "^1.6.1",
|
|
||||||
"vscode-textmate": "5.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"typedoc": {
|
|
||||||
"version": "0.22.17",
|
|
||||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.17.tgz",
|
|
||||||
"integrity": "sha512-h6+uXHVVCPDaANzjwzdsj9aePBjZiBTpiMpBBeyh1zcN2odVsDCNajz8zyKnixF93HJeGpl34j/70yoEE5BfNg==",
|
|
||||||
"requires": {
|
|
||||||
"glob": "^8.0.3",
|
|
||||||
"lunr": "^2.3.9",
|
|
||||||
"marked": "^4.0.16",
|
|
||||||
"minimatch": "^5.1.0",
|
|
||||||
"shiki": "^0.10.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"typescript": {
|
|
||||||
"version": "4.7.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
|
|
||||||
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"vscode-oniguruma": {
|
|
||||||
"version": "1.6.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz",
|
|
||||||
"integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA=="
|
|
||||||
},
|
|
||||||
"vscode-textmate": {
|
|
||||||
"version": "5.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz",
|
|
||||||
"integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ=="
|
|
||||||
},
|
|
||||||
"webaudiofont": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/webaudiofont/-/webaudiofont-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-PwqbR4OdvzbW8/TLTitSU/rw4mxMKyAGTKV42mePCgMoUGLJoQj8HDLWVqtNOpUZ0ghPNhNE6cRFEv6HFFEBQA==",
|
|
||||||
"requires": {
|
|
||||||
"typedoc": "^0.22.14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"wrappy": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@strudel.cycles/soundfonts",
|
|
||||||
"version": "0.1.1",
|
|
||||||
"description": "Soundsfont support for strudel",
|
|
||||||
"main": "index.mjs",
|
|
||||||
"type": "module",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/tidalcycles/strudel.git"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"tidalcycles",
|
|
||||||
"strudel",
|
|
||||||
"pattern",
|
|
||||||
"livecoding",
|
|
||||||
"algorave"
|
|
||||||
],
|
|
||||||
"author": "Felix Roos <flix91@gmail.com>",
|
|
||||||
"license": "AGPL-3.0-or-later",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/tidalcycles/strudel/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
|
||||||
"dependencies": {
|
|
||||||
"@strudel.cycles/core": "*",
|
|
||||||
"@strudel.cycles/webaudio": "^0.1.4"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"node-fetch": "^3.2.6"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
+3
-3
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/tonal",
|
"name": "@strudel.cycles/tonal",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@strudel.cycles/tonal",
|
"name": "@strudel.cycles/tonal",
|
||||||
"version": "0.1.1",
|
"version": "0.0.3",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tonaljs/tonal": "^4.6.5",
|
"@tonaljs/tonal": "^4.6.5",
|
||||||
"webmidi": "^3.0.15"
|
"webmidi": "^3.0.15"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/tonal",
|
"name": "@strudel.cycles/tonal",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"description": "Tonal functions for strudel",
|
"description": "Tonal functions for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"@tonaljs/tonal": "^4.6.5",
|
"@tonaljs/tonal": "^4.6.5",
|
||||||
"webmidi": "^3.0.15"
|
"webmidi": "^3.0.15"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ Pattern.prototype.draw = function (callback, { from, to, onQuery }) {
|
|||||||
const begin = currentCycle + from;
|
const begin = currentCycle + from;
|
||||||
const end = currentCycle + to;
|
const end = currentCycle + to;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
events = this.query(new State(new TimeSpan(begin, end)))
|
events = this._asNumber(true) // true = silent error
|
||||||
|
.query(new State(new TimeSpan(begin, end)))
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.filter((event) => event.part.begin.equals(event.whole.begin));
|
.filter((event) => event.part.begin.equals(event.whole.begin));
|
||||||
onQuery?.(events);
|
onQuery?.(events);
|
||||||
|
|||||||
Generated
+3
-3
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/tone",
|
"name": "@strudel.cycles/tone",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@strudel.cycles/tone",
|
"name": "@strudel.cycles/tone",
|
||||||
"version": "0.1.1",
|
"version": "0.0.4",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tonejs/piano": "^0.2.1",
|
"@tonejs/piano": "^0.2.1",
|
||||||
"chord-voicings": "^0.0.1",
|
"chord-voicings": "^0.0.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/tone",
|
"name": "@strudel.cycles/tone",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"description": "Tone.js API for strudel",
|
"description": "Tone.js API for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"@tonejs/piano": "^0.2.1",
|
"@tonejs/piano": "^0.2.1",
|
||||||
"chord-voicings": "^0.0.1",
|
"chord-voicings": "^0.0.1",
|
||||||
"tone": "^14.7.77"
|
"tone": "^14.7.77"
|
||||||
|
|||||||
@@ -7,13 +7,6 @@ This program is free software: you can redistribute it and/or modify it under th
|
|||||||
import { Pattern } from '@strudel.cycles/core';
|
import { Pattern } from '@strudel.cycles/core';
|
||||||
|
|
||||||
const scale = (normalized, min, max) => normalized * (max - min) + min;
|
const scale = (normalized, min, max) => normalized * (max - min) + min;
|
||||||
const getValue = (e) => {
|
|
||||||
let value = typeof e.value === 'object' ? e.value.note ?? e.value.n : e.value;
|
|
||||||
if (typeof value === 'string') {
|
|
||||||
value = toMidi(value);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
|
|
||||||
Pattern.prototype.pianoroll = function ({
|
Pattern.prototype.pianoroll = function ({
|
||||||
cycles = 4,
|
cycles = 4,
|
||||||
@@ -82,9 +75,9 @@ Pattern.prototype.pianoroll = function ({
|
|||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
const timePx = scale((event.whole.begin - (flipTime ? to : from)) / timeExtent, ...timeRange);
|
const timePx = scale((event.whole.begin - (flipTime ? to : from)) / timeExtent, ...timeRange);
|
||||||
let durationPx = scale(event.duration / timeExtent, 0, timeAxis);
|
let durationPx = scale(event.duration / timeExtent, 0, timeAxis);
|
||||||
const value = getValue(event);
|
|
||||||
const valuePx = scale(
|
const valuePx = scale(
|
||||||
fold ? foldValues.indexOf(value) / foldValues.length : (Number(value) - minMidi) / valueExtent,
|
fold ? foldValues.indexOf(event.value) / foldValues.length : (Number(event.value) - minMidi) / valueExtent,
|
||||||
...valueRange,
|
...valueRange,
|
||||||
);
|
);
|
||||||
let margin = 0;
|
let margin = 0;
|
||||||
@@ -112,6 +105,7 @@ Pattern.prototype.pianoroll = function ({
|
|||||||
from: from - overscan,
|
from: from - overscan,
|
||||||
to: to + overscan,
|
to: to + overscan,
|
||||||
onQuery: (events) => {
|
onQuery: (events) => {
|
||||||
|
const getValue = (e) => Number(e.value);
|
||||||
const { min, max, values } = events.reduce(
|
const { min, max, values } = events.reduce(
|
||||||
({ min, max, values }, e) => {
|
({ min, max, values }, e) => {
|
||||||
const v = getValue(e);
|
const v = getValue(e);
|
||||||
|
|||||||
@@ -7,5 +7,3 @@ This program is free software: you can redistribute it and/or modify it under th
|
|||||||
export * from './clockworker.mjs';
|
export * from './clockworker.mjs';
|
||||||
export * from './scheduler.mjs';
|
export * from './scheduler.mjs';
|
||||||
export * from './webaudio.mjs';
|
export * from './webaudio.mjs';
|
||||||
export * from './sampler.mjs';
|
|
||||||
export * from './prebake.mjs';
|
|
||||||
|
|||||||
Generated
+3666
-864
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/webaudio",
|
"name": "@strudel.cycles/webaudio",
|
||||||
"version": "0.1.4",
|
"version": "0.1.1",
|
||||||
"description": "Web Audio helpers for Strudel",
|
"description": "Web Audio helpers for Strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -28,11 +28,6 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2"
|
"@strudel.cycles/core": "^0.1.0"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"koa": "^2.13.4",
|
|
||||||
"koa-static": "^5.0.0",
|
|
||||||
"@koa/cors": "^3.3.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
import { Pattern, toMidi } from '@strudel.cycles/core';
|
|
||||||
import { samples } from '.';
|
|
||||||
|
|
||||||
let baking;
|
|
||||||
|
|
||||||
export function prebake(props) {
|
|
||||||
if (baking) {
|
|
||||||
return baking;
|
|
||||||
}
|
|
||||||
baking = prebaker(props);
|
|
||||||
return baking;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function prebaker(props = {}) {
|
|
||||||
const { baseURL = './samples' } = props; // http://localhost:1234
|
|
||||||
try {
|
|
||||||
samples(
|
|
||||||
{
|
|
||||||
piano: {
|
|
||||||
A0: 'A0v8.mp3',
|
|
||||||
C1: 'C1v8.mp3',
|
|
||||||
Ds1: 'Ds1v8.mp3',
|
|
||||||
Fs1: 'Fs1v8.mp3',
|
|
||||||
A1: 'A1v8.mp3',
|
|
||||||
C2: 'C2v8.mp3',
|
|
||||||
Ds2: 'Ds2v8.mp3',
|
|
||||||
Fs2: 'Fs2v8.mp3',
|
|
||||||
A2: 'A2v8.mp3',
|
|
||||||
C3: 'C3v8.mp3',
|
|
||||||
Ds3: 'Ds3v8.mp3',
|
|
||||||
Fs3: 'Fs3v8.mp3',
|
|
||||||
A3: 'A3v8.mp3',
|
|
||||||
C4: 'C4v8.mp3',
|
|
||||||
Ds4: 'Ds4v8.mp3',
|
|
||||||
Fs4: 'Fs4v8.mp3',
|
|
||||||
A4: 'A4v8.mp3',
|
|
||||||
C5: 'C5v8.mp3',
|
|
||||||
Ds4: 'Ds4v8.mp3',
|
|
||||||
Fs5: 'Fs5v8.mp3',
|
|
||||||
A5: 'A5v8.mp3',
|
|
||||||
C6: 'C6v8.mp3',
|
|
||||||
Ds6: 'Ds6v8.mp3',
|
|
||||||
Fs6: 'Fs6v8.mp3',
|
|
||||||
A6: 'A6v8.mp3',
|
|
||||||
C7: 'C7v8.mp3',
|
|
||||||
Ds7: 'Ds7v8.mp3',
|
|
||||||
Fs7: 'Fs7v8.mp3',
|
|
||||||
A7: 'A7v8.mp3',
|
|
||||||
C8: 'C8v8.mp3',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// https://archive.org/details/SalamanderGrandPianoV3
|
|
||||||
// License: CC-by http://creativecommons.org/licenses/by/3.0/ Author: Alexander Holm
|
|
||||||
baseURL + '/piano/',
|
|
||||||
);
|
|
||||||
|
|
||||||
const maxPan = toMidi('C8');
|
|
||||||
const panwidth = (pan, width) => pan * width + (1 - width) / 2;
|
|
||||||
|
|
||||||
Pattern.prototype.piano = function () {
|
|
||||||
return this.clip(1)
|
|
||||||
.s('piano')
|
|
||||||
.fmap((value) => {
|
|
||||||
// pan by pitch
|
|
||||||
const pan = panwidth(Math.min(toMidi(value.note) / maxPan, 1), 0.5);
|
|
||||||
return { ...value, pan: (value.pan || 1) * pan };
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// ping sample server
|
|
||||||
/* await fetch(samplerURL)
|
|
||||||
.then(() => {
|
|
||||||
console.log(`prebake: Using samples from "${baseURL}"`);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
throw new Error(
|
|
||||||
`sample server not running at "${samplerURL}"... run "npm run sampler" from the strudel project root.`,
|
|
||||||
);
|
|
||||||
}); */
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('prebake error', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
// "sampler": "cd ./repl/public/samples && node ../../../packages/webaudio/sample-server.js",
|
|
||||||
// "sampler": "http-server ./repl/public",
|
|
||||||
|
|
||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
import Koa from 'koa'; // CJS: require('koa');
|
|
||||||
import cors from '@koa/cors';
|
|
||||||
import serve from 'koa-static'; // CJS: require('koa-static')
|
|
||||||
const cwd = process.cwd();
|
|
||||||
const yellow = '\x1b[33m%s\x1b[0m';
|
|
||||||
|
|
||||||
// get array of all folders in cwd:
|
|
||||||
const banks = fs.readdirSync(cwd).filter((f) => fs.statSync(path.join(cwd, f)).isDirectory());
|
|
||||||
const app = new Koa();
|
|
||||||
|
|
||||||
app.use(cors());
|
|
||||||
app.use(serve(cwd));
|
|
||||||
app.use((ctx, next) => {
|
|
||||||
return next().then(() => {
|
|
||||||
if (ctx.path === '/') {
|
|
||||||
ctx.body = 'banks: ' + banks.join(', ');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
const port = 1234;
|
|
||||||
app.listen(port);
|
|
||||||
|
|
||||||
console.log(yellow, `strudel sampler running at http://localhost:${port}`);
|
|
||||||
|
|
||||||
// node: get current working directory
|
|
||||||
console.log(yellow, 'cwd: ' + cwd);
|
|
||||||
|
|
||||||
console.log('found banks:');
|
|
||||||
banks.map((c) => console.log(yellow, c));
|
|
||||||
@@ -10,20 +10,18 @@ import { State, TimeSpan } from '@strudel.cycles/core';
|
|||||||
export class Scheduler {
|
export class Scheduler {
|
||||||
worker;
|
worker;
|
||||||
pattern;
|
pattern;
|
||||||
constructor({ audioContext, interval = 0.2, onEvent, latency = 0.2 }) {
|
constructor({ audioContext, interval = 0.2, onEvent }) {
|
||||||
this.worker = new ClockWorker(
|
this.worker = new ClockWorker(
|
||||||
audioContext,
|
audioContext,
|
||||||
(begin, end) => {
|
(begin, end) => {
|
||||||
this.pattern.query(new State(new TimeSpan(begin + latency, end + latency))).forEach((e) => {
|
this.pattern.query(new State(new TimeSpan(begin, end))).forEach((e) => {
|
||||||
if (!e.part.begin.equals(e.whole.begin)) {
|
if (!e.part.begin.equals(e.whole.begin)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.context.onTrigger) {
|
|
||||||
// TODO: kill first param, as it's contained in e
|
|
||||||
e.context.onTrigger(e.whole.begin, e, audioContext.currentTime, 1 /* cps */);
|
|
||||||
}
|
|
||||||
if (onEvent) {
|
if (onEvent) {
|
||||||
onEvent?.(e);
|
onEvent?.(e);
|
||||||
|
} else {
|
||||||
|
console.warn('unplayable event: no audio node nor onEvent callback', e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
+56
-233
@@ -6,11 +6,8 @@ This program is free software: you can redistribute it and/or modify it under th
|
|||||||
|
|
||||||
// import { Pattern, getFrequency, patternify2 } from '@strudel.cycles/core';
|
// import { Pattern, getFrequency, patternify2 } from '@strudel.cycles/core';
|
||||||
import * as strudel from '@strudel.cycles/core';
|
import * as strudel from '@strudel.cycles/core';
|
||||||
import { fromMidi, toMidi } from '@strudel.cycles/core';
|
import { Tone } from '@strudel.cycles/tone';
|
||||||
import { loadBuffer } from './sampler.mjs';
|
const { Pattern, getFrequency, patternify2 } = strudel;
|
||||||
const { Pattern } = strudel;
|
|
||||||
|
|
||||||
// export const getAudioContext = () => Tone.getContext().rawContext;
|
|
||||||
|
|
||||||
let audioContext;
|
let audioContext;
|
||||||
export const getAudioContext = () => {
|
export const getAudioContext = () => {
|
||||||
@@ -20,15 +17,9 @@ export const getAudioContext = () => {
|
|||||||
return audioContext;
|
return audioContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFilter = (type, frequency, Q) => {
|
const lookahead = 0.2;
|
||||||
const filter = getAudioContext().createBiquadFilter();
|
|
||||||
filter.type = type;
|
|
||||||
filter.frequency.value = frequency;
|
|
||||||
filter.Q.value = Q;
|
|
||||||
return filter;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getADSR = (attack, decay, sustain, release, velocity, begin, end) => {
|
const adsr = (attack, decay, sustain, release, velocity, begin, end) => {
|
||||||
const gainNode = getAudioContext().createGain();
|
const gainNode = getAudioContext().createGain();
|
||||||
gainNode.gain.setValueAtTime(0, begin);
|
gainNode.gain.setValueAtTime(0, begin);
|
||||||
gainNode.gain.linearRampToValueAtTime(velocity, begin + attack); // attack
|
gainNode.gain.linearRampToValueAtTime(velocity, begin + attack); // attack
|
||||||
@@ -39,233 +30,65 @@ const getADSR = (attack, decay, sustain, release, velocity, begin, end) => {
|
|||||||
return gainNode;
|
return gainNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOscillator = ({ s, freq, t, duration, release }) => {
|
Pattern.prototype.withAudioNode = function (createAudioNode) {
|
||||||
// make oscillator
|
return this._withHap((hap) => {
|
||||||
const o = getAudioContext().createOscillator();
|
return hap.setContext({
|
||||||
o.type = s || 'triangle';
|
...hap.context,
|
||||||
o.frequency.value = Number(freq);
|
createAudioNode: (t, e) => createAudioNode(t, e, hap.context.createAudioNode?.(t, hap)),
|
||||||
o.start(t);
|
});
|
||||||
o.stop(t + duration + release);
|
});
|
||||||
return o;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSoundfontKey = (s) => {
|
Pattern.prototype._wave = function (type) {
|
||||||
if (!globalThis.soundfontList) {
|
return this.withAudioNode((t, e) => {
|
||||||
// soundfont package not loaded
|
const osc = getAudioContext().createOscillator();
|
||||||
return false;
|
osc.type = type;
|
||||||
}
|
const f = getFrequency(e);
|
||||||
if (globalThis.soundfontList?.instruments?.includes(s)) {
|
osc.frequency.value = f; // expects frequency..
|
||||||
return s;
|
const begin = t ?? e.whole.begin.valueOf() + lookahead;
|
||||||
}
|
const end = begin + e.duration.valueOf();
|
||||||
// check if s is one of the soundfonts, which are loaded into globalThis, to avoid coupling both packages
|
osc.start(begin);
|
||||||
const nameIndex = globalThis.soundfontList?.instrumentNames?.indexOf(s);
|
osc.stop(end); // release?
|
||||||
// convert number nameIndex (0-128) to 3 digit string (001-128)
|
return osc;
|
||||||
const name = nameIndex < 10 ? `00${nameIndex}` : nameIndex < 100 ? `0${nameIndex}` : nameIndex;
|
});
|
||||||
if (nameIndex !== -1) {
|
};
|
||||||
// TODO: indices of instrumentNames do not seem to match instruments
|
Pattern.prototype.adsr = function (a = 0.01, d = 0.05, s = 1, r = 0.01) {
|
||||||
return globalThis.soundfontList.instruments.find((instrument) => instrument.startsWith(name));
|
return this.withAudioNode((t, e, node) => {
|
||||||
}
|
const velocity = e.context?.velocity || 1;
|
||||||
return;
|
const begin = t ?? e.whole.begin.valueOf() + lookahead;
|
||||||
|
const end = begin + e.duration.valueOf() + lookahead;
|
||||||
|
const envelope = adsr(a, d, s, r, velocity, begin, end);
|
||||||
|
node?.connect(envelope);
|
||||||
|
return envelope;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Pattern.prototype._filter = function (type = 'lowpass', frequency = 1000) {
|
||||||
|
return this.withAudioNode((t, e, node) => {
|
||||||
|
const filter = getAudioContext().createBiquadFilter();
|
||||||
|
filter.type = type;
|
||||||
|
filter.frequency.value = frequency;
|
||||||
|
node?.connect(filter);
|
||||||
|
return filter;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSampleBufferSource = async (s, n, note) => {
|
Pattern.prototype.filter = function (type, frequency) {
|
||||||
let transpose = 0;
|
return patternify2(Pattern.prototype._filter)(reify(type), reify(frequency), this);
|
||||||
if (note) {
|
|
||||||
transpose = toMidi(note) - 36; // C3 is middle C
|
|
||||||
}
|
|
||||||
const ac = getAudioContext();
|
|
||||||
// is sample from loaded samples(..)
|
|
||||||
const samples = getLoadedSamples();
|
|
||||||
if (!samples) {
|
|
||||||
throw new Error('no samples loaded');
|
|
||||||
}
|
|
||||||
const bank = samples?.[s];
|
|
||||||
if (!bank) {
|
|
||||||
throw new Error('sample not found:', s, 'try one of ' + Object.keys(samples));
|
|
||||||
}
|
|
||||||
if (typeof bank !== 'object') {
|
|
||||||
throw new Error('wrong format for sample bank:', s);
|
|
||||||
}
|
|
||||||
let sampleUrl;
|
|
||||||
if (Array.isArray(bank)) {
|
|
||||||
sampleUrl = bank[n % bank.length];
|
|
||||||
} else {
|
|
||||||
if (!note) {
|
|
||||||
throw new Error('no note(...) set for sound', s);
|
|
||||||
}
|
|
||||||
const midiDiff = (noteA) => toMidi(noteA) - toMidi(note);
|
|
||||||
// object format will expect keys as notes
|
|
||||||
const closest = Object.keys(bank)
|
|
||||||
.filter((k) => !k.startsWith('_'))
|
|
||||||
.reduce(
|
|
||||||
(closest, key, j) => (!closest || Math.abs(midiDiff(key)) < Math.abs(midiDiff(closest)) ? key : closest),
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
transpose = -midiDiff(closest); // semitones to repitch
|
|
||||||
sampleUrl = bank[closest][n % bank[closest].length];
|
|
||||||
}
|
|
||||||
const buffer = await loadBuffer(sampleUrl, ac);
|
|
||||||
const bufferSource = ac.createBufferSource();
|
|
||||||
bufferSource.buffer = buffer;
|
|
||||||
const playbackRate = 1.0 * Math.pow(2, transpose / 12);
|
|
||||||
// bufferSource.playbackRate.value = Math.pow(2, transpose / 12);
|
|
||||||
bufferSource.playbackRate.value = playbackRate;
|
|
||||||
return bufferSource;
|
|
||||||
};
|
|
||||||
|
|
||||||
const splitSN = (s, n) => {
|
|
||||||
if (!s.includes(':')) {
|
|
||||||
return [s, n];
|
|
||||||
}
|
|
||||||
let [s2, n2] = s.split(':');
|
|
||||||
if (isNaN(Number(n2))) {
|
|
||||||
return [s, n];
|
|
||||||
}
|
|
||||||
return [s2, n2];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Pattern.prototype.out = function () {
|
Pattern.prototype.out = function () {
|
||||||
return this.onTrigger(async (t, hap, ct) => {
|
const master = getAudioContext().createGain();
|
||||||
const ac = getAudioContext();
|
master.gain.value = 0.1;
|
||||||
// calculate correct time (tone.js workaround)
|
master.connect(getAudioContext().destination);
|
||||||
t = ac.currentTime + t - ct;
|
return this.withAudioNode((t, e, node) => {
|
||||||
// destructure value
|
if (!node) {
|
||||||
let {
|
console.warn('out: no source! call .osc() first');
|
||||||
freq,
|
|
||||||
s,
|
|
||||||
sf,
|
|
||||||
clip = 0, // if 1, samples will be cut off when the hap ends
|
|
||||||
n = 0,
|
|
||||||
note,
|
|
||||||
gain = 1,
|
|
||||||
cutoff,
|
|
||||||
resonance = 1,
|
|
||||||
hcutoff,
|
|
||||||
hresonance = 1,
|
|
||||||
bandf,
|
|
||||||
bandq = 1,
|
|
||||||
pan,
|
|
||||||
attack = 0.001,
|
|
||||||
decay = 0.05,
|
|
||||||
sustain = 0.5,
|
|
||||||
release = 0.001,
|
|
||||||
speed = 1, // sample playback speed
|
|
||||||
begin = 0,
|
|
||||||
end = 1,
|
|
||||||
} = hap.value;
|
|
||||||
const { velocity = 1 } = hap.context;
|
|
||||||
gain *= velocity; // legacy fix for velocity
|
|
||||||
// the chain will hold all audio nodes that connect to each other
|
|
||||||
const chain = [];
|
|
||||||
if (typeof s === 'string') {
|
|
||||||
[s, n] = splitSN(s, n);
|
|
||||||
}
|
}
|
||||||
if (typeof note === 'string') {
|
node?.connect(master);
|
||||||
[note, n] = splitSN(note, n);
|
})._withHap((hap) => {
|
||||||
}
|
const onTrigger = (time, e) => e.context?.createAudioNode?.(time, e);
|
||||||
if (!s || ['sine', 'square', 'triangle', 'sawtooth'].includes(s)) {
|
return hap.setContext({ ...hap.context, onTrigger });
|
||||||
// with synths, n and note are the same thing
|
|
||||||
n = note || n;
|
|
||||||
if (typeof n === 'string') {
|
|
||||||
n = toMidi(n); // e.g. c3 => 48
|
|
||||||
}
|
|
||||||
// get frequency
|
|
||||||
if (!freq && typeof n === 'number') {
|
|
||||||
freq = fromMidi(n); // + 48);
|
|
||||||
}
|
|
||||||
// make oscillator
|
|
||||||
const o = getOscillator({ t, s, freq, duration: hap.duration, release });
|
|
||||||
chain.push(o);
|
|
||||||
// level down oscillators as they are really loud compared to samples i've tested
|
|
||||||
const g = ac.createGain();
|
|
||||||
g.gain.value = 0.3;
|
|
||||||
chain.push(g);
|
|
||||||
// TODO: make adsr work with samples without pops
|
|
||||||
// envelope
|
|
||||||
const adsr = getADSR(attack, decay, sustain, release, 1, t, t + hap.duration);
|
|
||||||
chain.push(adsr);
|
|
||||||
} else {
|
|
||||||
// load sample
|
|
||||||
if (speed === 0) {
|
|
||||||
// no playback
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!s) {
|
|
||||||
console.warn('no sample specified');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const soundfont = getSoundfontKey(s);
|
|
||||||
let bufferSource;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (soundfont) {
|
|
||||||
// is soundfont
|
|
||||||
bufferSource = await globalThis.getFontBufferSource(soundfont, note || n, ac);
|
|
||||||
} else {
|
|
||||||
// is sample from loaded samples(..)
|
|
||||||
bufferSource = await getSampleBufferSource(s, n, note);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.warn(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// asny stuff above took too long?
|
|
||||||
if (ac.currentTime > t) {
|
|
||||||
console.warn('sample still loading:', s, n);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!bufferSource) {
|
|
||||||
console.warn('no buffer source');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bufferSource.playbackRate.value = Math.abs(speed) * bufferSource.playbackRate.value;
|
|
||||||
// TODO: nudge, unit, cut, loop
|
|
||||||
let duration = soundfont || clip ? hap.duration : bufferSource.buffer.duration;
|
|
||||||
// let duration = bufferSource.buffer.duration;
|
|
||||||
const offset = begin * duration;
|
|
||||||
duration = ((end - begin) * duration) / Math.abs(speed);
|
|
||||||
if (soundfont || clip) {
|
|
||||||
bufferSource.start(t, offset); // duration does not work here for some reason
|
|
||||||
} else {
|
|
||||||
bufferSource.start(t, offset, duration);
|
|
||||||
}
|
|
||||||
chain.push(bufferSource);
|
|
||||||
if (soundfont || clip) {
|
|
||||||
const env = ac.createGain();
|
|
||||||
const releaseLength = 0.1;
|
|
||||||
env.gain.value = 0.6;
|
|
||||||
env.gain.setValueAtTime(env.gain.value, t + duration);
|
|
||||||
env.gain.linearRampToValueAtTime(0, t + duration + releaseLength);
|
|
||||||
// env.gain.linearRampToValueAtTime(0, t + duration + releaseLength);
|
|
||||||
chain.push(env);
|
|
||||||
bufferSource.stop(t + duration + releaseLength);
|
|
||||||
} else {
|
|
||||||
bufferSource.stop(t + duration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// master out
|
|
||||||
const master = ac.createGain();
|
|
||||||
master.gain.value = gain;
|
|
||||||
chain.push(master);
|
|
||||||
|
|
||||||
// filters
|
|
||||||
cutoff !== undefined && chain.push(getFilter('lowpass', cutoff, resonance));
|
|
||||||
hcutoff !== undefined && chain.push(getFilter('highpass', hcutoff, hresonance));
|
|
||||||
bandf !== undefined && chain.push(getFilter('bandpass', bandf, bandq));
|
|
||||||
// TODO vowel
|
|
||||||
// TODO delay / delaytime / delayfeedback
|
|
||||||
// panning
|
|
||||||
if (pan !== undefined) {
|
|
||||||
const panner = ac.createStereoPanner();
|
|
||||||
panner.pan.value = 2 * pan - 1;
|
|
||||||
chain.push(panner);
|
|
||||||
}
|
|
||||||
// master out
|
|
||||||
/* const master = ac.createGain();
|
|
||||||
master.gain.value = 0.8 * gain;
|
|
||||||
chain.push(master); */
|
|
||||||
chain.push(ac.destination);
|
|
||||||
// connect chain elements together
|
|
||||||
chain.slice(1).reduce((last, current) => last.connect(current), chain[0]);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Pattern.prototype.define('wave', (type, pat) => pat.wave(type), { patternified: true });
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
export * from './webdirt.mjs';
|
export * from './webdirt.mjs';
|
||||||
|
export * from './sampler.mjs';
|
||||||
|
|||||||
Generated
-28
@@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@strudel.cycles/webdirt",
|
|
||||||
"version": "0.1.2",
|
|
||||||
"lockfileVersion": 2,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"name": "@strudel.cycles/webdirt",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"license": "AGPL-3.0-or-later",
|
|
||||||
"dependencies": {
|
|
||||||
"WebDirt": "github:dktr0/WebDirt"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/WebDirt": {
|
|
||||||
"name": "webdirt",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "git+ssh://git@github.com/dktr0/WebDirt.git#425dc8fd023440d9c61ffdb8642e44e2710faea0",
|
|
||||||
"license": "ISC"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"WebDirt": {
|
|
||||||
"version": "git+ssh://git@github.com/dktr0/WebDirt.git#425dc8fd023440d9c61ffdb8642e44e2710faea0",
|
|
||||||
"from": "WebDirt@github:dktr0/WebDirt"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/webdirt",
|
"name": "@strudel.cycles/webdirt",
|
||||||
"version": "0.1.2",
|
"version": "0.1.0",
|
||||||
"description": "WebDirt integration for Strudel",
|
"description": "WebDirt integration for Strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2",
|
"@strudel.cycles/core": "^0.1.0",
|
||||||
"WebDirt": "github:dktr0/WebDirt"
|
"WebDirt": "github:dktr0/WebDirt"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
const bufferCache = {}; // string: Promise<ArrayBuffer>
|
const bufferCache = {}; // string: Promise<ArrayBuffer>
|
||||||
const loadCache = {}; // string: Promise<ArrayBuffer>
|
const loadCache = {}; // string: Promise<ArrayBuffer>
|
||||||
|
|
||||||
export const getCachedBuffer = (url) => bufferCache[url];
|
|
||||||
|
|
||||||
export const loadBuffer = (url, ac) => {
|
export const loadBuffer = (url, ac) => {
|
||||||
if (!loadCache[url]) {
|
if (!loadCache[url]) {
|
||||||
loadCache[url] = fetch(url)
|
loadCache[url] = fetch(url)
|
||||||
@@ -93,32 +91,16 @@ export const loadGithubSamples = async (path, nameFn) => {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const samples = (sampleMap, baseUrl = sampleMap._base || '') => {
|
export const samples = (sampleMap, baseUrl = '') => {
|
||||||
sampleCache.current = {
|
sampleCache.current = {
|
||||||
...sampleCache.current,
|
...sampleCache.current,
|
||||||
...Object.fromEntries(
|
...Object.fromEntries(
|
||||||
Object.entries(sampleMap).map(([key, value]) => {
|
Object.entries(sampleMap).map(([key, value]) => [
|
||||||
if (typeof value === 'string') {
|
|
||||||
value = [value];
|
|
||||||
}
|
|
||||||
if (typeof value !== 'object') {
|
|
||||||
throw new Error('wrong sample map format for ' + key);
|
|
||||||
}
|
|
||||||
baseUrl = value._base || baseUrl;
|
|
||||||
const replaceUrl = (v) => (baseUrl + v).replace('github:', 'https://raw.githubusercontent.com/');
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
return [key, value.map(replaceUrl)];
|
|
||||||
}
|
|
||||||
// must be object
|
|
||||||
return [
|
|
||||||
key,
|
key,
|
||||||
Object.fromEntries(
|
(typeof value === 'string' ? [value] : value).map((v) =>
|
||||||
Object.entries(value).map(([note, samples]) => {
|
(baseUrl + v).replace('github:', 'https://raw.githubusercontent.com/'),
|
||||||
return [note, (typeof samples === 'string' ? [samples] : samples).map(replaceUrl)];
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
];
|
]),
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as strudel from '@strudel.cycles/core';
|
import * as strudel from '@strudel.cycles/core';
|
||||||
const { Pattern } = strudel;
|
const { Pattern } = strudel;
|
||||||
import * as WebDirt from 'WebDirt';
|
import * as WebDirt from 'WebDirt';
|
||||||
import { getLoadedSamples, loadBuffer, getLoadedBuffer } from '@strudel.cycles/webaudio';
|
import { getLoadedSamples, loadBuffer, getLoadedBuffer } from './sampler.mjs';
|
||||||
|
|
||||||
let webDirt;
|
let webDirt;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@strudel.cycles/xen",
|
"name": "@strudel.cycles/xen",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"description": "Xenharmonic API for strudel",
|
"description": "Xenharmonic API for strudel",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -24,6 +24,6 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "^0.1.2"
|
"@strudel.cycles/core": "^0.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,5 +22,3 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
oldtunes.mjs
|
|
||||||
Generated
+10
-506
@@ -8,8 +8,6 @@
|
|||||||
"name": "@strudel.cycles/repl",
|
"name": "@strudel.cycles/repl",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@supabase/supabase-js": "^1.35.3",
|
|
||||||
"nanoid": "^4.0.0",
|
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2"
|
"react-dom": "^17.0.2"
|
||||||
},
|
},
|
||||||
@@ -511,59 +509,6 @@
|
|||||||
"node": ">= 8.0.0"
|
"node": ">= 8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@supabase/functions-js": {
|
|
||||||
"version": "1.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-1.3.3.tgz",
|
|
||||||
"integrity": "sha512-35vO9niHRtzGe1QSvXKdOfvGPiX2KC44dGpWU6y0/gZCfTIgog/soU9HqABzQC/maVowO3hGLWfez5aN0MKfow==",
|
|
||||||
"dependencies": {
|
|
||||||
"cross-fetch": "^3.1.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@supabase/gotrue-js": {
|
|
||||||
"version": "1.22.16",
|
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/gotrue-js/-/gotrue-js-1.22.16.tgz",
|
|
||||||
"integrity": "sha512-t/tR87anihvyc9ePk53NF2CG8yzTDiWOt0ReZpr7sRKV91sHNLbghVMsMDwPONWnVQ9V2/qfKutuAvPGTB/Dew==",
|
|
||||||
"dependencies": {
|
|
||||||
"cross-fetch": "^3.0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@supabase/postgrest-js": {
|
|
||||||
"version": "0.37.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-0.37.3.tgz",
|
|
||||||
"integrity": "sha512-Iqwv9D80YGkCi60Zl2lsV04WxOmjFqxpFmxoZ5xUqsVZHvIoAbJ9tMM3+0F7VkZZbsjnaYHrpJ58xLxU7cgy2w==",
|
|
||||||
"dependencies": {
|
|
||||||
"cross-fetch": "^3.1.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@supabase/realtime-js": {
|
|
||||||
"version": "1.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-1.7.2.tgz",
|
|
||||||
"integrity": "sha512-DMUaFIKj7KszGtWTTQbhMmUzZf7UnwYqySsmY+G8HgYxvY3ZaVa+DZD0I6ofgr4OLNr0po/ODM2a4lf5m5GNBg==",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/phoenix": "^1.5.4",
|
|
||||||
"websocket": "^1.0.34"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@supabase/storage-js": {
|
|
||||||
"version": "1.7.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-1.7.1.tgz",
|
|
||||||
"integrity": "sha512-0ZlKlGgB3Qzhu07fts5pr2Y+c4xW58d7sDOB9m6nSfltS6SSfBPmqtdhU0zV9vy3vAjC74XeqUcpMhHP5E+aoA==",
|
|
||||||
"dependencies": {
|
|
||||||
"cross-fetch": "^3.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@supabase/supabase-js": {
|
|
||||||
"version": "1.35.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-1.35.3.tgz",
|
|
||||||
"integrity": "sha512-uwO8OVdMFsGZNZ1xQhFz22+PSW0EWYZ5xVq+jQeGz8nhabEu+Q9Uyep/bcNzOpyPJRzbGfxSPRzgAdAxfJgFhw==",
|
|
||||||
"dependencies": {
|
|
||||||
"@supabase/functions-js": "^1.3.3",
|
|
||||||
"@supabase/gotrue-js": "^1.22.14",
|
|
||||||
"@supabase/postgrest-js": "^0.37.2",
|
|
||||||
"@supabase/realtime-js": "^1.7.2",
|
|
||||||
"@supabase/storage-js": "^1.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@tailwindcss/typography": {
|
"node_modules/@tailwindcss/typography": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.2.tgz",
|
||||||
@@ -578,11 +523,6 @@
|
|||||||
"tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || insiders"
|
"tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || insiders"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/phoenix": {
|
|
||||||
"version": "1.5.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.5.4.tgz",
|
|
||||||
"integrity": "sha512-L5eZmzw89eXBKkiqVBcJfU1QGx9y+wurRIEgt0cuLH0hwNtVUxtx+6cu0R2STwWj468sjXyBYPYDtGclUd1kjQ=="
|
|
||||||
},
|
|
||||||
"node_modules/@vitejs/plugin-react": {
|
"node_modules/@vitejs/plugin-react": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-1.3.2.tgz",
|
||||||
@@ -748,18 +688,6 @@
|
|||||||
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/bufferutil": {
|
|
||||||
"version": "4.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz",
|
|
||||||
"integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"dependencies": {
|
|
||||||
"node-gyp-build": "^4.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.14.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/camelcase-css": {
|
"node_modules/camelcase-css": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
|
||||||
@@ -862,14 +790,6 @@
|
|||||||
"safe-buffer": "~5.1.1"
|
"safe-buffer": "~5.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cross-fetch": {
|
|
||||||
"version": "3.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
|
|
||||||
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
|
|
||||||
"dependencies": {
|
|
||||||
"node-fetch": "2.6.7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cssesc": {
|
"node_modules/cssesc": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||||
@@ -882,15 +802,6 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/d": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
|
|
||||||
"dependencies": {
|
|
||||||
"es5-ext": "^0.10.50",
|
|
||||||
"type": "^1.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||||
@@ -949,39 +860,6 @@
|
|||||||
"integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==",
|
"integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/es5-ext": {
|
|
||||||
"version": "0.10.61",
|
|
||||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.61.tgz",
|
|
||||||
"integrity": "sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"dependencies": {
|
|
||||||
"es6-iterator": "^2.0.3",
|
|
||||||
"es6-symbol": "^3.1.3",
|
|
||||||
"next-tick": "^1.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/es6-iterator": {
|
|
||||||
"version": "2.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
|
|
||||||
"integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
|
|
||||||
"dependencies": {
|
|
||||||
"d": "1",
|
|
||||||
"es5-ext": "^0.10.35",
|
|
||||||
"es6-symbol": "^3.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/es6-symbol": {
|
|
||||||
"version": "3.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
|
|
||||||
"integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
|
|
||||||
"dependencies": {
|
|
||||||
"d": "^1.0.1",
|
|
||||||
"ext": "^1.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/esbuild": {
|
"node_modules/esbuild": {
|
||||||
"version": "0.14.39",
|
"version": "0.14.39",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.39.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.39.tgz",
|
||||||
@@ -1361,19 +1239,6 @@
|
|||||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/ext": {
|
|
||||||
"version": "1.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz",
|
|
||||||
"integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==",
|
|
||||||
"dependencies": {
|
|
||||||
"type": "^2.5.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ext/node_modules/type": {
|
|
||||||
"version": "2.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz",
|
|
||||||
"integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ=="
|
|
||||||
},
|
|
||||||
"node_modules/fast-glob": {
|
"node_modules/fast-glob": {
|
||||||
"version": "3.2.11",
|
"version": "3.2.11",
|
||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
|
||||||
@@ -1561,11 +1426,6 @@
|
|||||||
"node": ">=0.12.0"
|
"node": ">=0.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-typedarray": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
|
|
||||||
},
|
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
@@ -1668,48 +1528,15 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "4.0.0",
|
"version": "3.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
|
||||||
"integrity": "sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg==",
|
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
|
||||||
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"nanoid": "bin/nanoid.js"
|
"nanoid": "bin/nanoid.cjs"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^14 || ^16 || >=18"
|
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/next-tick": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
|
|
||||||
},
|
|
||||||
"node_modules/node-fetch": {
|
|
||||||
"version": "2.6.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
|
||||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"whatwg-url": "^5.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "4.x || >=6.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"encoding": "^0.1.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"encoding": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/node-gyp-build": {
|
|
||||||
"version": "4.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz",
|
|
||||||
"integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==",
|
|
||||||
"bin": {
|
|
||||||
"node-gyp-build": "bin.js",
|
|
||||||
"node-gyp-build-optional": "optional.js",
|
|
||||||
"node-gyp-build-test": "build-test.js"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-releases": {
|
"node_modules/node-releases": {
|
||||||
@@ -1887,18 +1714,6 @@
|
|||||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
|
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/postcss/node_modules/nanoid": {
|
|
||||||
"version": "3.3.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
|
|
||||||
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
|
|
||||||
"dev": true,
|
|
||||||
"bin": {
|
|
||||||
"nanoid": "bin/nanoid.cjs"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/queue-microtask": {
|
"node_modules/queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
@@ -2165,36 +1980,6 @@
|
|||||||
"node": ">=8.0"
|
"node": ">=8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tr46": {
|
|
||||||
"version": "0.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
|
||||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
|
||||||
},
|
|
||||||
"node_modules/type": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
|
|
||||||
},
|
|
||||||
"node_modules/typedarray-to-buffer": {
|
|
||||||
"version": "3.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
|
|
||||||
"integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"is-typedarray": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/utf-8-validate": {
|
|
||||||
"version": "5.0.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz",
|
|
||||||
"integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==",
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"dependencies": {
|
|
||||||
"node-gyp-build": "^4.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.14.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
@@ -2238,49 +2023,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/webidl-conversions": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
|
||||||
},
|
|
||||||
"node_modules/websocket": {
|
|
||||||
"version": "1.0.34",
|
|
||||||
"resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz",
|
|
||||||
"integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"bufferutil": "^4.0.1",
|
|
||||||
"debug": "^2.2.0",
|
|
||||||
"es5-ext": "^0.10.50",
|
|
||||||
"typedarray-to-buffer": "^3.1.5",
|
|
||||||
"utf-8-validate": "^5.0.2",
|
|
||||||
"yaeti": "^0.0.6"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/websocket/node_modules/debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"dependencies": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/websocket/node_modules/ms": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
|
||||||
},
|
|
||||||
"node_modules/whatwg-url": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
|
||||||
"dependencies": {
|
|
||||||
"tr46": "~0.0.3",
|
|
||||||
"webidl-conversions": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/xtend": {
|
"node_modules/xtend": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||||
@@ -2290,14 +2032,6 @@
|
|||||||
"node": ">=0.4"
|
"node": ">=0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/yaeti": {
|
|
||||||
"version": "0.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
|
|
||||||
"integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.32"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/yaml": {
|
"node_modules/yaml": {
|
||||||
"version": "1.10.2",
|
"version": "1.10.2",
|
||||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
||||||
@@ -2668,59 +2402,6 @@
|
|||||||
"picomatch": "^2.2.2"
|
"picomatch": "^2.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@supabase/functions-js": {
|
|
||||||
"version": "1.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-1.3.3.tgz",
|
|
||||||
"integrity": "sha512-35vO9niHRtzGe1QSvXKdOfvGPiX2KC44dGpWU6y0/gZCfTIgog/soU9HqABzQC/maVowO3hGLWfez5aN0MKfow==",
|
|
||||||
"requires": {
|
|
||||||
"cross-fetch": "^3.1.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@supabase/gotrue-js": {
|
|
||||||
"version": "1.22.16",
|
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/gotrue-js/-/gotrue-js-1.22.16.tgz",
|
|
||||||
"integrity": "sha512-t/tR87anihvyc9ePk53NF2CG8yzTDiWOt0ReZpr7sRKV91sHNLbghVMsMDwPONWnVQ9V2/qfKutuAvPGTB/Dew==",
|
|
||||||
"requires": {
|
|
||||||
"cross-fetch": "^3.0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@supabase/postgrest-js": {
|
|
||||||
"version": "0.37.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-0.37.3.tgz",
|
|
||||||
"integrity": "sha512-Iqwv9D80YGkCi60Zl2lsV04WxOmjFqxpFmxoZ5xUqsVZHvIoAbJ9tMM3+0F7VkZZbsjnaYHrpJ58xLxU7cgy2w==",
|
|
||||||
"requires": {
|
|
||||||
"cross-fetch": "^3.1.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@supabase/realtime-js": {
|
|
||||||
"version": "1.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-1.7.2.tgz",
|
|
||||||
"integrity": "sha512-DMUaFIKj7KszGtWTTQbhMmUzZf7UnwYqySsmY+G8HgYxvY3ZaVa+DZD0I6ofgr4OLNr0po/ODM2a4lf5m5GNBg==",
|
|
||||||
"requires": {
|
|
||||||
"@types/phoenix": "^1.5.4",
|
|
||||||
"websocket": "^1.0.34"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@supabase/storage-js": {
|
|
||||||
"version": "1.7.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-1.7.1.tgz",
|
|
||||||
"integrity": "sha512-0ZlKlGgB3Qzhu07fts5pr2Y+c4xW58d7sDOB9m6nSfltS6SSfBPmqtdhU0zV9vy3vAjC74XeqUcpMhHP5E+aoA==",
|
|
||||||
"requires": {
|
|
||||||
"cross-fetch": "^3.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@supabase/supabase-js": {
|
|
||||||
"version": "1.35.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-1.35.3.tgz",
|
|
||||||
"integrity": "sha512-uwO8OVdMFsGZNZ1xQhFz22+PSW0EWYZ5xVq+jQeGz8nhabEu+Q9Uyep/bcNzOpyPJRzbGfxSPRzgAdAxfJgFhw==",
|
|
||||||
"requires": {
|
|
||||||
"@supabase/functions-js": "^1.3.3",
|
|
||||||
"@supabase/gotrue-js": "^1.22.14",
|
|
||||||
"@supabase/postgrest-js": "^0.37.2",
|
|
||||||
"@supabase/realtime-js": "^1.7.2",
|
|
||||||
"@supabase/storage-js": "^1.7.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@tailwindcss/typography": {
|
"@tailwindcss/typography": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.2.tgz",
|
||||||
@@ -2732,11 +2413,6 @@
|
|||||||
"lodash.merge": "^4.6.2"
|
"lodash.merge": "^4.6.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/phoenix": {
|
|
||||||
"version": "1.5.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.5.4.tgz",
|
|
||||||
"integrity": "sha512-L5eZmzw89eXBKkiqVBcJfU1QGx9y+wurRIEgt0cuLH0hwNtVUxtx+6cu0R2STwWj468sjXyBYPYDtGclUd1kjQ=="
|
|
||||||
},
|
|
||||||
"@vitejs/plugin-react": {
|
"@vitejs/plugin-react": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-1.3.2.tgz",
|
||||||
@@ -2843,14 +2519,6 @@
|
|||||||
"picocolors": "^1.0.0"
|
"picocolors": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bufferutil": {
|
|
||||||
"version": "4.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz",
|
|
||||||
"integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==",
|
|
||||||
"requires": {
|
|
||||||
"node-gyp-build": "^4.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"camelcase-css": {
|
"camelcase-css": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
|
||||||
@@ -2925,29 +2593,12 @@
|
|||||||
"safe-buffer": "~5.1.1"
|
"safe-buffer": "~5.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cross-fetch": {
|
|
||||||
"version": "3.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
|
|
||||||
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
|
|
||||||
"requires": {
|
|
||||||
"node-fetch": "2.6.7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cssesc": {
|
"cssesc": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"d": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
|
|
||||||
"requires": {
|
|
||||||
"es5-ext": "^0.10.50",
|
|
||||||
"type": "^1.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||||
@@ -2992,35 +2643,6 @@
|
|||||||
"integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==",
|
"integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"es5-ext": {
|
|
||||||
"version": "0.10.61",
|
|
||||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.61.tgz",
|
|
||||||
"integrity": "sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA==",
|
|
||||||
"requires": {
|
|
||||||
"es6-iterator": "^2.0.3",
|
|
||||||
"es6-symbol": "^3.1.3",
|
|
||||||
"next-tick": "^1.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"es6-iterator": {
|
|
||||||
"version": "2.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
|
|
||||||
"integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
|
|
||||||
"requires": {
|
|
||||||
"d": "1",
|
|
||||||
"es5-ext": "^0.10.35",
|
|
||||||
"es6-symbol": "^3.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"es6-symbol": {
|
|
||||||
"version": "3.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
|
|
||||||
"integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
|
|
||||||
"requires": {
|
|
||||||
"d": "^1.0.1",
|
|
||||||
"ext": "^1.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"esbuild": {
|
"esbuild": {
|
||||||
"version": "0.14.39",
|
"version": "0.14.39",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.39.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.39.tgz",
|
||||||
@@ -3207,21 +2829,6 @@
|
|||||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ext": {
|
|
||||||
"version": "1.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz",
|
|
||||||
"integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==",
|
|
||||||
"requires": {
|
|
||||||
"type": "^2.5.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"type": {
|
|
||||||
"version": "2.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz",
|
|
||||||
"integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fast-glob": {
|
"fast-glob": {
|
||||||
"version": "3.2.11",
|
"version": "3.2.11",
|
||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
|
||||||
@@ -3358,11 +2965,6 @@
|
|||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-typedarray": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
|
|
||||||
},
|
|
||||||
"js-tokens": {
|
"js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
@@ -3441,27 +3043,10 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"nanoid": {
|
"nanoid": {
|
||||||
"version": "4.0.0",
|
"version": "3.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
|
||||||
"integrity": "sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg=="
|
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
|
||||||
},
|
"dev": true
|
||||||
"next-tick": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
|
|
||||||
},
|
|
||||||
"node-fetch": {
|
|
||||||
"version": "2.6.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
|
||||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
|
||||||
"requires": {
|
|
||||||
"whatwg-url": "^5.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node-gyp-build": {
|
|
||||||
"version": "4.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz",
|
|
||||||
"integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ=="
|
|
||||||
},
|
},
|
||||||
"node-releases": {
|
"node-releases": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
@@ -3519,14 +3104,6 @@
|
|||||||
"nanoid": "^3.3.3",
|
"nanoid": "^3.3.3",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.0.0",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"nanoid": {
|
|
||||||
"version": "3.3.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
|
|
||||||
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"postcss-js": {
|
"postcss-js": {
|
||||||
@@ -3748,32 +3325,6 @@
|
|||||||
"is-number": "^7.0.0"
|
"is-number": "^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tr46": {
|
|
||||||
"version": "0.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
|
||||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
|
|
||||||
},
|
|
||||||
"typedarray-to-buffer": {
|
|
||||||
"version": "3.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
|
|
||||||
"integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
|
|
||||||
"requires": {
|
|
||||||
"is-typedarray": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"utf-8-validate": {
|
|
||||||
"version": "5.0.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz",
|
|
||||||
"integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==",
|
|
||||||
"requires": {
|
|
||||||
"node-gyp-build": "^4.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"util-deprecate": {
|
"util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
@@ -3793,59 +3344,12 @@
|
|||||||
"rollup": "^2.59.0"
|
"rollup": "^2.59.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"webidl-conversions": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
|
||||||
},
|
|
||||||
"websocket": {
|
|
||||||
"version": "1.0.34",
|
|
||||||
"resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz",
|
|
||||||
"integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==",
|
|
||||||
"requires": {
|
|
||||||
"bufferutil": "^4.0.1",
|
|
||||||
"debug": "^2.2.0",
|
|
||||||
"es5-ext": "^0.10.50",
|
|
||||||
"typedarray-to-buffer": "^3.1.5",
|
|
||||||
"utf-8-validate": "^5.0.2",
|
|
||||||
"yaeti": "^0.0.6"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"whatwg-url": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
|
||||||
"requires": {
|
|
||||||
"tr46": "~0.0.3",
|
|
||||||
"webidl-conversions": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"xtend": {
|
"xtend": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"yaeti": {
|
|
||||||
"version": "0.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
|
|
||||||
"integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug=="
|
|
||||||
},
|
|
||||||
"yaml": {
|
"yaml": {
|
||||||
"version": "1.10.2",
|
"version": "1.10.2",
|
||||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
||||||
|
|||||||
+1
-3
@@ -3,7 +3,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --host",
|
"dev": "vite",
|
||||||
"start": "vite",
|
"start": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
@@ -15,8 +15,6 @@
|
|||||||
"static": "npx serve ../docs"
|
"static": "npx serve ../docs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@supabase/supabase-js": "^1.35.3",
|
|
||||||
"nanoid": "^4.0.0",
|
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2"
|
"react-dom": "^17.0.2"
|
||||||
},
|
},
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+12
-91
@@ -6,24 +6,14 @@ This program is free software: you can redistribute it and/or modify it under th
|
|||||||
|
|
||||||
import controls from '@strudel.cycles/core/controls.mjs';
|
import controls from '@strudel.cycles/core/controls.mjs';
|
||||||
import { evalScope, evaluate } from '@strudel.cycles/eval';
|
import { evalScope, evaluate } from '@strudel.cycles/eval';
|
||||||
import { CodeMirror, cx, flash, useHighlighting, useRepl, useWebMidi } from '@strudel.cycles/react';
|
import { CodeMirror, cx, useHighlighting, useRepl, useWebMidi } from '@strudel.cycles/react';
|
||||||
import { getDefaultSynth, cleanupDraw, cleanupUi, Tone } from '@strudel.cycles/tone';
|
import { getDefaultSynth, cleanupDraw, cleanupUi, Tone } from '@strudel.cycles/tone';
|
||||||
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
import logo from './logo.svg';
|
import logo from './logo.svg';
|
||||||
import * as tunes from './tunes.mjs';
|
import * as tunes from './tunes.mjs';
|
||||||
import { prebake } from './prebake.mjs';
|
|
||||||
import * as WebDirt from 'WebDirt';
|
import * as WebDirt from 'WebDirt';
|
||||||
import { loadWebDirt } from '@strudel.cycles/webdirt';
|
import { loadWebDirt, resetLoadedSamples } from '@strudel.cycles/webdirt';
|
||||||
import { resetLoadedSamples, getAudioContext } from '@strudel.cycles/webaudio';
|
|
||||||
import { createClient } from '@supabase/supabase-js';
|
|
||||||
import { nanoid } from 'nanoid';
|
|
||||||
|
|
||||||
// Create a single supabase client for interacting with your database
|
|
||||||
const supabase = createClient(
|
|
||||||
'https://pidxdsxphlhzjnzmifth.supabase.co',
|
|
||||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBpZHhkc3hwaGxoempuem1pZnRoIiwicm9sZSI6ImFub24iLCJpYXQiOjE2NTYyMzA1NTYsImV4cCI6MTk3MTgwNjU1Nn0.bqlw7802fsWRnqU5BLYtmXk_k-D1VFmbkHMywWc15NM',
|
|
||||||
);
|
|
||||||
|
|
||||||
evalScope(
|
evalScope(
|
||||||
Tone,
|
Tone,
|
||||||
@@ -39,7 +29,6 @@ evalScope(
|
|||||||
import('@strudel.cycles/osc'),
|
import('@strudel.cycles/osc'),
|
||||||
import('@strudel.cycles/webdirt'),
|
import('@strudel.cycles/webdirt'),
|
||||||
import('@strudel.cycles/serial'),
|
import('@strudel.cycles/serial'),
|
||||||
import('@strudel.cycles/soundfonts'),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
loadWebDirt({
|
loadWebDirt({
|
||||||
@@ -47,37 +36,13 @@ loadWebDirt({
|
|||||||
sampleFolder: 'EmuSP12',
|
sampleFolder: 'EmuSP12',
|
||||||
});
|
});
|
||||||
|
|
||||||
prebake();
|
const initialUrl = window.location.href;
|
||||||
|
const codeParam = window.location.href.split('#')[1];
|
||||||
async function initCode() {
|
let decoded;
|
||||||
// load code from url hash (either short hash from database or decode long hash)
|
try {
|
||||||
try {
|
decoded = atob(decodeURIComponent(codeParam || ''));
|
||||||
const initialUrl = window.location.href;
|
} catch (err) {
|
||||||
const hash = initialUrl.split('?')[1]?.split('#')?.[0];
|
|
||||||
const codeParam = window.location.href.split('#')[1];
|
|
||||||
// looking like https://strudel.tidalcycles.org/?J01s5i1J0200 (fixed hash length)
|
|
||||||
if (codeParam) {
|
|
||||||
console.log('decode hash from url');
|
|
||||||
// looking like https://strudel.tidalcycles.org/#ImMzIGUzIg%3D%3D (hash length depends on code length)
|
|
||||||
return atob(decodeURIComponent(codeParam || ''));
|
|
||||||
} else if (hash) {
|
|
||||||
return supabase
|
|
||||||
.from('code')
|
|
||||||
.select('code')
|
|
||||||
.eq('hash', hash)
|
|
||||||
.then(({ data, error }) => {
|
|
||||||
if (error) {
|
|
||||||
console.warn('failed to load hash', err);
|
|
||||||
}
|
|
||||||
if (data.length) {
|
|
||||||
console.log('load hash from database', hash);
|
|
||||||
return data[0].code;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.warn('failed to decode', err);
|
console.warn('failed to decode', err);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomTune() {
|
function getRandomTune() {
|
||||||
@@ -92,7 +57,6 @@ const isEmbedded = window.location !== window.parent.location;
|
|||||||
function App() {
|
function App() {
|
||||||
// const [editor, setEditor] = useState();
|
// const [editor, setEditor] = useState();
|
||||||
const [view, setView] = useState();
|
const [view, setView] = useState();
|
||||||
const [lastShared, setLastShared] = useState();
|
|
||||||
const {
|
const {
|
||||||
setCode,
|
setCode,
|
||||||
setPattern,
|
setPattern,
|
||||||
@@ -109,12 +73,9 @@ function App() {
|
|||||||
pushLog,
|
pushLog,
|
||||||
pending,
|
pending,
|
||||||
} = useRepl({
|
} = useRepl({
|
||||||
tune: '// LOADING...',
|
tune: decoded || randomTune,
|
||||||
defaultSynth,
|
defaultSynth,
|
||||||
});
|
});
|
||||||
useEffect(() => {
|
|
||||||
initCode().then((decoded) => setCode(decoded || randomTune));
|
|
||||||
}, []);
|
|
||||||
const logBox = useRef();
|
const logBox = useRef();
|
||||||
// scroll log box to bottom when log changes
|
// scroll log box to bottom when log changes
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
@@ -130,7 +91,6 @@ function App() {
|
|||||||
if (e.ctrlKey || e.altKey) {
|
if (e.ctrlKey || e.altKey) {
|
||||||
if (e.code === 'Enter') {
|
if (e.code === 'Enter') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
flash(view);
|
|
||||||
await activateCode();
|
await activateCode();
|
||||||
} else if (e.code === 'Period') {
|
} else if (e.code === 'Period') {
|
||||||
cycle.stop();
|
cycle.stop();
|
||||||
@@ -140,7 +100,7 @@ function App() {
|
|||||||
};
|
};
|
||||||
window.addEventListener('keydown', handleKeyPress, true);
|
window.addEventListener('keydown', handleKeyPress, true);
|
||||||
return () => window.removeEventListener('keydown', handleKeyPress, true);
|
return () => window.removeEventListener('keydown', handleKeyPress, true);
|
||||||
}, [pattern, code, activateCode, cycle, view]);
|
}, [pattern, code, activateCode, cycle]);
|
||||||
|
|
||||||
useHighlighting({ view, pattern, active: cycle.started && !activeCode?.includes('strudel disable-highlighting') });
|
useHighlighting({ view, pattern, active: cycle.started && !activeCode?.includes('strudel disable-highlighting') });
|
||||||
|
|
||||||
@@ -179,13 +139,7 @@ function App() {
|
|||||||
<h1 className={isEmbedded ? 'text-l' : 'text-xl'}>Strudel {isEmbedded ? 'Mini ' : ''}REPL</h1>
|
<h1 className={isEmbedded ? 'text-l' : 'text-xl'}>Strudel {isEmbedded ? 'Mini ' : ''}REPL</h1>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<button
|
<button onClick={() => togglePlay()} className={cx('hover:bg-gray-300', !isEmbedded ? 'p-2' : 'px-2')}>
|
||||||
onClick={() => {
|
|
||||||
getAudioContext().resume(); // fixes no sound in ios webkit
|
|
||||||
togglePlay();
|
|
||||||
}}
|
|
||||||
className={cx('hover:bg-gray-300', !isEmbedded ? 'p-2' : 'px-2')}
|
|
||||||
>
|
|
||||||
{!pending ? (
|
{!pending ? (
|
||||||
<span className={cx('flex items-center', isEmbedded ? 'w-16' : 'w-16')}>
|
<span className={cx('flex items-center', isEmbedded ? 'w-16' : 'w-16')}>
|
||||||
{cycle.started ? (
|
{cycle.started ? (
|
||||||
@@ -221,7 +175,6 @@ function App() {
|
|||||||
cleanupDraw();
|
cleanupDraw();
|
||||||
cleanupUi();
|
cleanupUi();
|
||||||
resetLoadedSamples();
|
resetLoadedSamples();
|
||||||
prebake();
|
|
||||||
const parsed = await evaluate(_code);
|
const parsed = await evaluate(_code);
|
||||||
setPattern(parsed.pattern);
|
setPattern(parsed.pattern);
|
||||||
setActiveCode(_code);
|
setActiveCode(_code);
|
||||||
@@ -235,38 +188,6 @@ function App() {
|
|||||||
<a href="./tutorial">📚 tutorial</a>
|
<a href="./tutorial">📚 tutorial</a>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{!isEmbedded && (
|
|
||||||
<button
|
|
||||||
className={cx('cursor-pointer hover:bg-gray-300', !isEmbedded ? 'p-2' : 'px-2')}
|
|
||||||
onClick={async () => {
|
|
||||||
const codeToShare = activeCode || code;
|
|
||||||
if (lastShared === codeToShare) {
|
|
||||||
// alert('Link already generated!');
|
|
||||||
pushLog(`Link already generated!`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// generate uuid in the browser
|
|
||||||
const hash = nanoid(12);
|
|
||||||
const { data, error } = await supabase.from('code').insert([{ code: codeToShare, hash }]);
|
|
||||||
if (!error) {
|
|
||||||
setLastShared(activeCode || code);
|
|
||||||
const shareUrl = window.location.origin + '?' + hash;
|
|
||||||
// copy shareUrl to clipboard
|
|
||||||
navigator.clipboard.writeText(shareUrl);
|
|
||||||
const message = `Link copied to clipboard: ${shareUrl}`;
|
|
||||||
// alert(message);
|
|
||||||
pushLog(message);
|
|
||||||
} else {
|
|
||||||
console.log('error', error);
|
|
||||||
const message = `Error: ${error.message}`;
|
|
||||||
// alert(message);
|
|
||||||
pushLog(message);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
📣 share{lastShared && lastShared === (activeCode || code) ? 'd!' : ''}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
{isEmbedded && (
|
{isEmbedded && (
|
||||||
<button className={cx('hover:bg-gray-300 px-2')}>
|
<button className={cx('hover:bg-gray-300 px-2')}>
|
||||||
<a href={window.location.href} target="_blank" rel="noopener noreferrer" title="Open in REPL">
|
<a href={window.location.href} target="_blank" rel="noopener noreferrer" title="Open in REPL">
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
import { Pattern, toMidi } from '@strudel.cycles/core';
|
|
||||||
import { samples } from '@strudel.cycles/webaudio';
|
|
||||||
|
|
||||||
export function prebake() {
|
|
||||||
samples(
|
|
||||||
{
|
|
||||||
piano: {
|
|
||||||
A0: 'A0v8.mp3',
|
|
||||||
C1: 'C1v8.mp3',
|
|
||||||
Ds1: 'Ds1v8.mp3',
|
|
||||||
Fs1: 'Fs1v8.mp3',
|
|
||||||
A1: 'A1v8.mp3',
|
|
||||||
C2: 'C2v8.mp3',
|
|
||||||
Ds2: 'Ds2v8.mp3',
|
|
||||||
Fs2: 'Fs2v8.mp3',
|
|
||||||
A2: 'A2v8.mp3',
|
|
||||||
C3: 'C3v8.mp3',
|
|
||||||
Ds3: 'Ds3v8.mp3',
|
|
||||||
Fs3: 'Fs3v8.mp3',
|
|
||||||
A3: 'A3v8.mp3',
|
|
||||||
C4: 'C4v8.mp3',
|
|
||||||
Ds4: 'Ds4v8.mp3',
|
|
||||||
Fs4: 'Fs4v8.mp3',
|
|
||||||
A4: 'A4v8.mp3',
|
|
||||||
C5: 'C5v8.mp3',
|
|
||||||
Ds4: 'Ds4v8.mp3',
|
|
||||||
Fs5: 'Fs5v8.mp3',
|
|
||||||
A5: 'A5v8.mp3',
|
|
||||||
C6: 'C6v8.mp3',
|
|
||||||
Ds6: 'Ds6v8.mp3',
|
|
||||||
Fs6: 'Fs6v8.mp3',
|
|
||||||
A6: 'A6v8.mp3',
|
|
||||||
C7: 'C7v8.mp3',
|
|
||||||
Ds7: 'Ds7v8.mp3',
|
|
||||||
Fs7: 'Fs7v8.mp3',
|
|
||||||
A7: 'A7v8.mp3',
|
|
||||||
C8: 'C8v8.mp3',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// https://archive.org/details/SalamanderGrandPianoV3
|
|
||||||
// License: CC-by http://creativecommons.org/licenses/by/3.0/ Author: Alexander Holm
|
|
||||||
'./piano/',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxPan = toMidi('C8');
|
|
||||||
const panwidth = (pan, width) => pan * width + (1 - width) / 2;
|
|
||||||
|
|
||||||
Pattern.prototype.piano = function () {
|
|
||||||
return this.clip(1)
|
|
||||||
.s('piano')
|
|
||||||
.fmap((value) => {
|
|
||||||
// pan by pitch
|
|
||||||
const pan = panwidth(Math.min(toMidi(value.note) / maxPan, 1), 0.5);
|
|
||||||
return { ...value, pan: (value.pan || 1) * pan };
|
|
||||||
});
|
|
||||||
};
|
|
||||||
+1
-12
@@ -6,8 +6,6 @@
|
|||||||
import { evaluate } from '@strudel.cycles/eval';
|
import { evaluate } from '@strudel.cycles/eval';
|
||||||
import { extend } from '@strudel.cycles/eval';
|
import { extend } from '@strudel.cycles/eval';
|
||||||
import * as strudel from '@strudel.cycles/core';
|
import * as strudel from '@strudel.cycles/core';
|
||||||
import * as webaudio from '@strudel.cycles/webaudio';
|
|
||||||
import controls from '@strudel.cycles/core/controls.mjs';
|
|
||||||
// import gist from '@strudel.cycles/core/gist.js';
|
// import gist from '@strudel.cycles/core/gist.js';
|
||||||
import { mini } from '@strudel.cycles/mini/mini.mjs';
|
import { mini } from '@strudel.cycles/mini/mini.mjs';
|
||||||
// import { Tone } from '@strudel.cycles/tone';
|
// import { Tone } from '@strudel.cycles/tone';
|
||||||
@@ -31,8 +29,6 @@ import '@strudel.cycles/xen/xen.mjs';
|
|||||||
// import '@strudel.cycles/serial/serial.mjs';
|
// import '@strudel.cycles/serial/serial.mjs';
|
||||||
// import controls from '@strudel.cycles/core/controls.mjs';
|
// import controls from '@strudel.cycles/core/controls.mjs';
|
||||||
|
|
||||||
import { prebake } from './prebake.mjs';
|
|
||||||
|
|
||||||
class MockedNode {
|
class MockedNode {
|
||||||
chain() {
|
chain() {
|
||||||
return this;
|
return this;
|
||||||
@@ -87,9 +83,6 @@ const toneHelpersMocked = {
|
|||||||
strudel.Pattern.prototype.tone = function () {
|
strudel.Pattern.prototype.tone = function () {
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
strudel.Pattern.prototype.webdirt = function () {
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
// draw mock
|
// draw mock
|
||||||
strudel.Pattern.prototype.pianoroll = function () {
|
strudel.Pattern.prototype.pianoroll = function () {
|
||||||
@@ -123,8 +116,6 @@ const uiHelpersMocked = {
|
|||||||
backgroundImage: id,
|
backgroundImage: id,
|
||||||
};
|
};
|
||||||
|
|
||||||
prebake();
|
|
||||||
|
|
||||||
// TODO: refactor to evalScope
|
// TODO: refactor to evalScope
|
||||||
extend(
|
extend(
|
||||||
// Tone,
|
// Tone,
|
||||||
@@ -132,8 +123,6 @@ extend(
|
|||||||
strudel.Pattern.prototype.bootstrap(),
|
strudel.Pattern.prototype.bootstrap(),
|
||||||
toneHelpersMocked,
|
toneHelpersMocked,
|
||||||
uiHelpersMocked,
|
uiHelpersMocked,
|
||||||
controls,
|
|
||||||
webaudio,
|
|
||||||
/* controls,
|
/* controls,
|
||||||
toneHelpers,
|
toneHelpers,
|
||||||
voicingHelpers,
|
voicingHelpers,
|
||||||
@@ -192,6 +181,6 @@ export const testCycles = {
|
|||||||
randomBells: 24,
|
randomBells: 24,
|
||||||
waa: 16,
|
waa: 16,
|
||||||
waar: 16,
|
waar: 16,
|
||||||
hyperpop: 10,
|
hyperpop: 60,
|
||||||
festivalOfFingers3: 16,
|
festivalOfFingers3: 16,
|
||||||
};
|
};
|
||||||
|
|||||||
+55
-258
@@ -444,7 +444,7 @@ export const barryHarris = `backgroundImage(
|
|||||||
.scale('C bebop major')
|
.scale('C bebop major')
|
||||||
.transpose("<0 1 2 1>/8")
|
.transpose("<0 1 2 1>/8")
|
||||||
.slow(2)
|
.slow(2)
|
||||||
.note().piano().out()
|
.tone((await piano()).toDestination())
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const blippyRhodes = `const delay = new FeedbackDelay(1/12, .4).chain(vol(0.3), out());
|
export const blippyRhodes = `const delay = new FeedbackDelay(1/12, .4).chain(vol(0.3), out());
|
||||||
@@ -551,7 +551,7 @@ export const risingEnemy = `stack(
|
|||||||
.transpose("<0 1 2 1>/2".early(0.5))
|
.transpose("<0 1 2 1>/2".early(0.5))
|
||||||
.transpose(5)
|
.transpose(5)
|
||||||
.fast(2 / 3)
|
.fast(2 / 3)
|
||||||
.note().piano().out()`;
|
.tone((await piano()).toDestination())`;
|
||||||
|
|
||||||
export const festivalOfFingers = `const chords = "<Cm7 Fm7 G7 F#7>";
|
export const festivalOfFingers = `const chords = "<Cm7 Fm7 G7 F#7>";
|
||||||
stack(
|
stack(
|
||||||
@@ -563,7 +563,7 @@ stack(
|
|||||||
.scaleTranspose("0 4 0 6".early(".125 .5")).layer(scaleTranspose("0,<2 [4,6] [5,7]>/4"))
|
.scaleTranspose("0 4 0 6".early(".125 .5")).layer(scaleTranspose("0,<2 [4,6] [5,7]>/4"))
|
||||||
).slow(2)
|
).slow(2)
|
||||||
.velocity(sine.struct("x*8").add(3/5).mul(2/5).fast(8))
|
.velocity(sine.struct("x*8").add(3/5).mul(2/5).fast(8))
|
||||||
.note().piano().out()`;
|
.tone((await piano()).chain(out()))`;
|
||||||
|
|
||||||
export const festivalOfFingers2 = `const chords = "<Cm7 Fm7 G7 F#7 >";
|
export const festivalOfFingers2 = `const chords = "<Cm7 Fm7 G7 F#7 >";
|
||||||
const scales = cat('C minor','F dorian','G dorian','F# mixolydian')
|
const scales = cat('C minor','F dorian','G dorian','F# mixolydian')
|
||||||
@@ -577,35 +577,36 @@ stack(
|
|||||||
).slow(2).transpose(-1)
|
).slow(2).transpose(-1)
|
||||||
.legato(cosine.struct("x*8").add(4/5).mul(4/5).fast(8))
|
.legato(cosine.struct("x*8").add(4/5).mul(4/5).fast(8))
|
||||||
.velocity(sine.struct("x*8").add(3/5).mul(2/5).fast(8))
|
.velocity(sine.struct("x*8").add(3/5).mul(2/5).fast(8))
|
||||||
.note().piano().out().fast(3/4)`;
|
.tone((await piano()).chain(out())).fast(3/4)`;
|
||||||
|
|
||||||
// iter, echo, echoWith
|
// iter, stut, stutWith
|
||||||
export const undergroundPlumber = `backgroundImage('https://images.nintendolife.com/news/2016/08/video_exploring_the_funky_inspiration_for_the_super_mario_bros_underground_theme/large.jpg',{ className:'darken' })
|
export const undergroundPlumber = `backgroundImage('https://images.nintendolife.com/news/2016/08/video_exploring_the_funky_inspiration_for_the_super_mario_bros_underground_theme/large.jpg',{ className:'darken' })
|
||||||
|
|
||||||
samples({ bd: 'bd/BT0A0D0.wav', sn: 'sn/ST0T0S3.wav', hh: 'hh/000_hh3closedhh.wav', cp: 'cp/HANDCLP0.wav',
|
const drums = await players({
|
||||||
|
bd: 'bd/BT0A0D0.wav',
|
||||||
|
sn: 'sn/ST0T0S3.wav',
|
||||||
|
hh: 'hh/000_hh3closedhh.wav',
|
||||||
|
cp: 'cp/HANDCLP0.wav',
|
||||||
}, 'https://loophole-letters.vercel.app/samples/tidal/')
|
}, 'https://loophole-letters.vercel.app/samples/tidal/')
|
||||||
|
|
||||||
const h = x=>x.transpose("<0@2 5 0 7 5 0 -5>/2")
|
|
||||||
|
|
||||||
stack(
|
stack(
|
||||||
s("<<bd*2 bd> sn> hh").fast(2).gain(.7),
|
"<<bd*2 bd> sn> hh".fast(4).slow(2).tone(drums.chain(vol(.5),out())),
|
||||||
|
stack(
|
||||||
"[c2 a1 bb1 ~] ~"
|
"[c2 a1 bb1 ~] ~"
|
||||||
.echo(2, 1/16, 1)
|
.stut(2, .6, 1/16)
|
||||||
.legato(.4)
|
.legato(.4)
|
||||||
.slow(2)
|
.slow(2)
|
||||||
.layer(h)
|
.tone(synth({...osc('sawtooth7'),...adsr(0,.3,0)}).chain(out())),
|
||||||
.note().s('square')
|
|
||||||
.cutoff(400).decay(.12).sustain(0)
|
|
||||||
,
|
|
||||||
"[g2,[c3 eb3]]".iter(4)
|
"[g2,[c3 eb3]]".iter(4)
|
||||||
.echoWith(4, 1/8, (x,n)=>x.transpose(n*12).velocity(Math.pow(.4,n)))
|
.stutWith(4, 1/8, (x,n)=>x.transpose(n*12).velocity(Math.pow(.4,n)))
|
||||||
.legato(.1)
|
.legato(.1)
|
||||||
.layer(h).note()
|
)
|
||||||
).out()
|
.transpose("<0@2 5 0 7 5 0 -5>/2")
|
||||||
.fast(2/3)
|
|
||||||
.pianoroll({})`;
|
|
||||||
|
|
||||||
export const bridgeIsOver = `samples({mad:'https://freesound.org/data/previews/22/22274_109943-lq.mp3'})
|
)
|
||||||
|
.fast(2/3)
|
||||||
|
.pianoroll({minMidi:21,maxMidi:180, background:'transparent',inactive:'#3F8F90',active:'#DE3123'})`;
|
||||||
|
|
||||||
|
export const bridgeIsOver = `const breaks = (await players({mad:'https://freesound.org/data/previews/22/22274_109943-lq.mp3'})).chain(out())
|
||||||
stack(
|
stack(
|
||||||
stack(
|
stack(
|
||||||
"c3*2 [[c3@1.4 bb2] ab2] gb2*2 <[[gb2@1.4 ab2] bb2] gb2>".legato(".5 1".fast(2)).velocity(.8),
|
"c3*2 [[c3@1.4 bb2] ab2] gb2*2 <[[gb2@1.4 ab2] bb2] gb2>".legato(".5 1".fast(2)).velocity(.8),
|
||||||
@@ -617,11 +618,9 @@ stack(
|
|||||||
.velocity(.7)
|
.velocity(.7)
|
||||||
.legato(.5)
|
.legato(.5)
|
||||||
.stut(3, .5, 1/8)
|
.stut(3, .5, 1/8)
|
||||||
).transpose(-1).note().piano(),
|
).transpose(-1).tone((await piano()).chain(out())),
|
||||||
s("mad").slow(2)
|
"mad".slow(2).tone(breaks)
|
||||||
).cpm(78).slow(4)
|
).cpm(78).slow(4).pianoroll()
|
||||||
.out()
|
|
||||||
.pianoroll()
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const goodTimes = `const scale = cat('C3 dorian','Bb2 major').slow(4);
|
export const goodTimes = `const scale = cat('C3 dorian','Bb2 major').slow(4);
|
||||||
@@ -638,9 +637,10 @@ stack(
|
|||||||
.legato("2")
|
.legato("2")
|
||||||
.scale(scale)
|
.scale(scale)
|
||||||
.scaleTranspose("<0>".slow(4))
|
.scaleTranspose("<0>".slow(4))
|
||||||
.transpose(5)
|
.tone((await piano()).chain(out()))
|
||||||
.note().piano().out()
|
//.midi()
|
||||||
.velocity(.8)
|
.velocity(.8)
|
||||||
|
.transpose(5)
|
||||||
.slow(2)
|
.slow(2)
|
||||||
.pianoroll({maxMidi:100,minMidi:20})`;
|
.pianoroll({maxMidi:100,minMidi:20})`;
|
||||||
|
|
||||||
@@ -651,7 +651,7 @@ export const echoPiano = `"<0 2 [4 6](3,4,1) 3*2>"
|
|||||||
.off(1/2, x=>x.scaleTranspose(6).color('steelblue'))
|
.off(1/2, x=>x.scaleTranspose(6).color('steelblue'))
|
||||||
.legato(.5)
|
.legato(.5)
|
||||||
.echo(4, 1/8, .5)
|
.echo(4, 1/8, .5)
|
||||||
.note().piano().out()
|
.tone((await piano()).chain(out()))
|
||||||
.pianoroll()`;
|
.pianoroll()`;
|
||||||
|
|
||||||
export const sml1 = `
|
export const sml1 = `
|
||||||
@@ -687,7 +687,7 @@ stack(
|
|||||||
f3!2 e3!2 ab3!2 ~!2
|
f3!2 e3!2 ab3!2 ~!2
|
||||||
>\`
|
>\`
|
||||||
.legato(.5)
|
.legato(.5)
|
||||||
).fast(2) // .note().piano().out()`;
|
).fast(2) //.tone((await piano()).chain(out()))`;
|
||||||
|
|
||||||
export const speakerman = `backgroundImage('https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fi.ytimg.com%2Fvi%2FXR0rKqW3VwY%2Fmaxresdefault.jpg&f=1&nofb=1',
|
export const speakerman = `backgroundImage('https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fi.ytimg.com%2Fvi%2FXR0rKqW3VwY%2Fmaxresdefault.jpg&f=1&nofb=1',
|
||||||
{ className:'darken', style:'background-size:cover'})
|
{ className:'darken', style:'background-size:cover'})
|
||||||
@@ -728,7 +728,7 @@ bell = bell.chain(vol(0.6).connect(delay),out());
|
|||||||
.slow(6)
|
.slow(6)
|
||||||
.pianoroll({minMidi:20,maxMidi:120,background:'transparent'})`;
|
.pianoroll({minMidi:20,maxMidi:120,background:'transparent'})`;
|
||||||
|
|
||||||
/* export const waa = `n("a4 [a3 c3] a3 c3")
|
export const waa = `"a4 [a3 c3] a3 c3"
|
||||||
.sub("<7 12>/2")
|
.sub("<7 12>/2")
|
||||||
.off(1/8, add("12"))
|
.off(1/8, add("12"))
|
||||||
.off(1/4, add("7"))
|
.off(1/4, add("7"))
|
||||||
@@ -736,37 +736,23 @@ bell = bell.chain(vol(0.6).connect(delay),out());
|
|||||||
.slow(2)
|
.slow(2)
|
||||||
.wave("sawtooth square")
|
.wave("sawtooth square")
|
||||||
.filter('lowpass', "<2000 1000 500>")
|
.filter('lowpass', "<2000 1000 500>")
|
||||||
.out()`; */
|
.out()`;
|
||||||
|
|
||||||
export const waa = `n(
|
export const waar = `"a4 [a3 c3] a3 c3".color('#F9D649')
|
||||||
"a4 [a3 c3] a3 c3"
|
.sub("<7 12 5 12>".slow(2))
|
||||||
.sub("<7 12>/2")
|
.off(1/4,x=>x.add(7).color("#FFFFFF #0C3AA1 #C63928"))
|
||||||
.off(1/8, add("12"))
|
.off(1/8,x=>x.add(12).color('#215CB6'))
|
||||||
.off(1/4, add("7"))
|
.slow(2)
|
||||||
)
|
.legato(sine.range(0.3, 2).slow(28))
|
||||||
.legato(.5)
|
.wave("sawtooth square".fast(2))
|
||||||
.slow(2)
|
.filter('lowpass', cosine.range(500,4000).slow(16))
|
||||||
.s("sawtooth square")
|
.out()
|
||||||
.cutoff("<2000 1000 500>")
|
.pianoroll({minMidi:20,maxMidi:120,background:'#202124'})`;
|
||||||
.out()
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const waa2 = `n(
|
|
||||||
"a4 [a3 c3] a3 c3"
|
|
||||||
.sub("<7 12 5 12>".slow(2))
|
|
||||||
.off(1/4,x=>x.add(7))
|
|
||||||
.off(1/8,x=>x.add(12))
|
|
||||||
)
|
|
||||||
.slow(2)
|
|
||||||
.legato(sine.range(0.3, 2).slow(28))
|
|
||||||
.s("sawtooth square".fast(2))
|
|
||||||
.cutoff(cosine.range(500,4000).slow(16))
|
|
||||||
.out()`;
|
|
||||||
|
|
||||||
export const hyperpop = `const lfo = cosine.slow(15);
|
export const hyperpop = `const lfo = cosine.slow(15);
|
||||||
const lfo2 = sine.slow(16);
|
const lfo2 = sine.slow(16);
|
||||||
const filter1 = x=>x.cutoff(lfo2.range(300,3000));
|
const filter1 = x=>x.filter('lowpass', lfo2.range(300,3000));
|
||||||
const filter2 = x=>x.hcutoff(lfo.range(1000,6000)).cutoff(4000)
|
const filter2 = x=>x.filter('highpass', lfo.range(1000,6000)).filter('lowpass',4000)
|
||||||
const scales = cat('D3 major', 'G3 major').slow(8)
|
const scales = cat('D3 major', 'G3 major').slow(8)
|
||||||
|
|
||||||
const drums = await players({
|
const drums = await players({
|
||||||
@@ -779,30 +765,24 @@ const drums = await players({
|
|||||||
|
|
||||||
stack(
|
stack(
|
||||||
"-7 0 -7 7".struct("x(5,8,2)").fast(2).sub(7)
|
"-7 0 -7 7".struct("x(5,8,2)").fast(2).sub(7)
|
||||||
.scale(scales)
|
.scale(scales).wave("sawtooth,square").velocity(.3).adsr(0.01,0.1,.5,0)
|
||||||
.n()
|
|
||||||
.s("sawtooth,square")
|
|
||||||
.gain(.3).attack(0.01).decay(0.1).sustain(.5)
|
|
||||||
.apply(filter1),
|
.apply(filter1),
|
||||||
"~@3 [<2 3>,<4 5>]"
|
"~@3 [<2 3>,<4 5>]"
|
||||||
.echo(4,1/16,.7)
|
.echo(8,1/16,.7)
|
||||||
.scale(scales)
|
.scale(scales)
|
||||||
.n()
|
.wave('square').velocity(.7).adsr(0.01,0.1,0).apply(filter1),
|
||||||
.s('square').gain(.7)
|
"6 5 4".add(14)
|
||||||
.attack(0.01).decay(0.1).sustain(0)
|
|
||||||
.apply(filter1),
|
|
||||||
"6 4 2".add(14)
|
|
||||||
.superimpose(sub("5"))
|
.superimpose(sub("5"))
|
||||||
.fast(1).euclidLegato(3,8)
|
.fast(1).euclidLegato(3,8)
|
||||||
.mask("<1 0@7>")
|
.mask("<1 0@7>")
|
||||||
.fast(2)
|
.fast(2)
|
||||||
.echo(32, 1/8, .8)
|
.echo(32, 1/8, .9)
|
||||||
.scale(scales)
|
.scale(scales)
|
||||||
.n()
|
.wave("sawtooth")
|
||||||
.s("sawtooth")
|
.velocity(.2)
|
||||||
.gain(sine.range(.1,.4).slow(8))
|
.adsr(.01,.5,0)
|
||||||
.attack(.001).decay(.2).sustain(0)
|
|
||||||
.apply(filter2)
|
.apply(filter2)
|
||||||
|
//.echo(4,1/16,.5)
|
||||||
).out().stack(
|
).out().stack(
|
||||||
stack(
|
stack(
|
||||||
"bd <~@7 [~ bd]>".fast(2),
|
"bd <~@7 [~ bd]>".fast(2),
|
||||||
@@ -827,7 +807,7 @@ export const festivalOfFingers3 = `"[-7*3],0,2,6,[8 7]"
|
|||||||
.scale(cat('D dorian','G mixolydian','C dorian','F mixolydian'))
|
.scale(cat('D dorian','G mixolydian','C dorian','F mixolydian'))
|
||||||
.legato(1)
|
.legato(1)
|
||||||
.slow(2)
|
.slow(2)
|
||||||
.note().piano().out()
|
.tone((await piano()).toDestination())
|
||||||
//.pianoroll({maxMidi:160})`;
|
//.pianoroll({maxMidi:160})`;
|
||||||
|
|
||||||
export const bossa = `
|
export const bossa = `
|
||||||
@@ -835,187 +815,4 @@ const scales = sequence('C minor', ['D locrian', 'G phrygian'], 'Bb2 minor', ['C
|
|||||||
stack(
|
stack(
|
||||||
"<Cm7 [Dm7b5 G7b9] Bbm7 [Cm7b5 F7b9]>".fast(2).struct("x ~ x@3 x ~ x ~ ~ ~ x ~ x@3".late(1/8)).early(1/8).slow(2).voicings(),
|
"<Cm7 [Dm7b5 G7b9] Bbm7 [Cm7b5 F7b9]>".fast(2).struct("x ~ x@3 x ~ x ~ ~ ~ x ~ x@3".late(1/8)).early(1/8).slow(2).voicings(),
|
||||||
"[~ [0 ~]] 0 [~ [4 ~]] 4".sub(7).restart(scales).scale(scales).early(.25)
|
"[~ [0 ~]] 0 [~ [4 ~]] 4".sub(7).restart(scales).scale(scales).early(.25)
|
||||||
).note().piano().out().slow(2)`;
|
).tone((await piano()).toDestination()).slow(2)`;
|
||||||
|
|
||||||
export const customTrigger = `stack(
|
|
||||||
freq("55 [110,165] 110 [220,275]".mul("<1 <3/4 2/3>>").struct("x(3,8)").layer(x=>x.mul("1.006,.995"))),
|
|
||||||
freq("440(5,8)".legato(.18).mul("<1 3/4 2 2/3>")).gain(perlin.range(.2,.8))
|
|
||||||
).s("<sawtooth square>/2")
|
|
||||||
.onTrigger((t,hap,ct)=>{
|
|
||||||
const ac = Tone.getContext().rawContext;
|
|
||||||
t = ac.currentTime + t - ct;
|
|
||||||
const { freq, s, gain = 1 } = hap.value;
|
|
||||||
const master = ac.createGain();
|
|
||||||
master.gain.value = 0.1 * gain;
|
|
||||||
master.connect(ac.destination);
|
|
||||||
const o = ac.createOscillator();
|
|
||||||
o.type = s || 'triangle';
|
|
||||||
o.frequency.value = Number(freq);
|
|
||||||
o.connect(master);
|
|
||||||
o.start(t);
|
|
||||||
o.stop(t + hap.duration);
|
|
||||||
}).stack(s("bd(3,8),hh*4,~ sd").webdirt())`;
|
|
||||||
|
|
||||||
export const bornagain = `stack(
|
|
||||||
freq("55 [110,165] 110 [220,275]".mul("<1 <3/4 2/3>>").struct("x(3,8)")
|
|
||||||
.layer(x=>x.mul("1.006,.995"))), // detune
|
|
||||||
freq("440(5,8)".legato(.18).mul("<1 3/4 2 2/3>")).gain(perlin.range(.2,.8))
|
|
||||||
).s("<sawtooth square>/2")
|
|
||||||
.cutoff(perlin.range(100,4000).slow(4))
|
|
||||||
.jux(rev)
|
|
||||||
.out()
|
|
||||||
.stack(s("bd(3,8),hh*4,~ sd").webdirt())`;
|
|
||||||
|
|
||||||
export const meltingsubmarine = `samples({
|
|
||||||
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav','bd/BT0A0DA.wav','bd/BT0A0D3.wav','bd/BT0A0D0.wav','bd/BT0A0A7.wav'],
|
|
||||||
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
|
|
||||||
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
|
|
||||||
}, 'github:tidalcycles/Dirt-Samples/master/');
|
|
||||||
stack(
|
|
||||||
s("bd,[~ <sd!3 sd(3,4,2)>],hh(3,4)") // drums
|
|
||||||
.speed(perlin.range(.7,.9)) // random sample speed variation
|
|
||||||
//.hush()
|
|
||||||
,"<a1 b1*2 a1(3,8) e2>" // bassline
|
|
||||||
.off(1/8,x=>x.add(12).degradeBy(.5)) // random octave jumps
|
|
||||||
.add(perlin.range(0,.5)) // random pitch variation
|
|
||||||
.superimpose(add(.05)) // add second, slightly detuned voice
|
|
||||||
.n() // wrap in "n"
|
|
||||||
.decay(.15).sustain(0) // make each note of equal length
|
|
||||||
.s('sawtooth') // waveform
|
|
||||||
.gain(.4) // turn down
|
|
||||||
.cutoff(sine.slow(7).range(300,5000)) // automate cutoff
|
|
||||||
//.hush()
|
|
||||||
,"<Am7!3 <Em7 E7b13 Em7 Ebm7b5>>".voicings() // chords
|
|
||||||
.superimpose(x=>x.add(.04)) // add second, slightly detuned voice
|
|
||||||
.add(perlin.range(0,.5)) // random pitch variation
|
|
||||||
.n() // wrap in "n"
|
|
||||||
.s('sawtooth') // waveform
|
|
||||||
.gain(.16) // turn down
|
|
||||||
.cutoff(500) // fixed cutoff
|
|
||||||
.attack(1) // slowly fade in
|
|
||||||
//.hush()
|
|
||||||
,"a4 c5 <e6 a6>".struct("x(5,8)")
|
|
||||||
.superimpose(x=>x.add(.04)) // add second, slightly detuned voice
|
|
||||||
.add(perlin.range(0,.5)) // random pitch variation
|
|
||||||
.n() // wrap in "n"
|
|
||||||
.decay(.1).sustain(0) // make notes short
|
|
||||||
.s('triangle') // waveform
|
|
||||||
.degradeBy(perlin.range(0,.5)) // randomly controlled random removal :)
|
|
||||||
.echoWith(4,.125,(x,n)=>x.gain(.15*1/(n+1))) // echo notes
|
|
||||||
//.hush()
|
|
||||||
)
|
|
||||||
.out()
|
|
||||||
.slow(3/2)`;
|
|
||||||
|
|
||||||
export const swimmingWithSoundfonts = `stack(
|
|
||||||
n(
|
|
||||||
"~",
|
|
||||||
"~",
|
|
||||||
"~",
|
|
||||||
"A5 [F5@2 C5] [D5@2 F5] F5",
|
|
||||||
"[C5@2 F5] [F5@2 C6] A5 G5",
|
|
||||||
"A5 [F5@2 C5] [D5@2 F5] F5",
|
|
||||||
"[C5@2 F5] [Bb5 A5 G5] F5@2",
|
|
||||||
"A5 [F5@2 C5] [D5@2 F5] F5",
|
|
||||||
"[C5@2 F5] [F5@2 C6] A5 G5",
|
|
||||||
"A5 [F5@2 C5] [D5@2 F5] F5",
|
|
||||||
"[C5@2 F5] [Bb5 A5 G5] F5@2",
|
|
||||||
"A5 [F5@2 C5] A5 F5",
|
|
||||||
"Ab5 [F5@2 Ab5] G5@2",
|
|
||||||
"A5 [F5@2 C5] A5 F5",
|
|
||||||
"Ab5 [F5@2 C5] C6@2",
|
|
||||||
"A5 [F5@2 C5] [D5@2 F5] F5",
|
|
||||||
"[C5@2 F5] [Bb5 A5 G5] F5@2"
|
|
||||||
).s('Sitar: Ethnic'),
|
|
||||||
n(
|
|
||||||
"[F4,Bb4,D5] [[D4,G4,Bb4]@2 [Bb3,D4,F4]] [[G3,C4,E4]@2 [[Ab3,F4] [A3,Gb4]]] [Bb3,E4,G4]",
|
|
||||||
"[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, Bb3, Db3] [F3, Bb3, Db3]]",
|
|
||||||
"[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]",
|
|
||||||
"[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]",
|
|
||||||
"[~ [A3, C4, E4] [A3, C4, E4]] [~ [Ab3, C4, Eb4] [Ab3, C4, Eb4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [G3, C4, E4] [G3, C4, E4]]",
|
|
||||||
"[~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]",
|
|
||||||
"[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]",
|
|
||||||
"[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]",
|
|
||||||
"[~ [A3, C4, E4] [A3, C4, E4]] [~ [Ab3, C4, Eb4] [Ab3, C4, Eb4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [G3, C4, E4] [G3, C4, E4]]",
|
|
||||||
"[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]",
|
|
||||||
"[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]",
|
|
||||||
"[~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [A3, C4, F4] [A3, C4, F4]] [~ [A3, C4, F4] [A3, C4, F4]]",
|
|
||||||
"[~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [G3, Bb3, F4] [G3, Bb3, F4]] [~ [G3, Bb3, E4] [G3, Bb3, E4]]",
|
|
||||||
"[~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [A3, C4, F4] [A3, C4, F4]] [~ [A3, C4, F4] [A3, C4, F4]]",
|
|
||||||
"[~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [G3, Bb3, F4] [G3, Bb3, F4]] [~ [G3, Bb3, E4] [G3, Bb3, E4]]",
|
|
||||||
"[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]",
|
|
||||||
"[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]"
|
|
||||||
).s('Kalimba: Ethnic'),
|
|
||||||
n(
|
|
||||||
"[G3 G3 C3 E3]",
|
|
||||||
"[F2 D2 G2 C2]",
|
|
||||||
"[F2 D2 G2 C2]",
|
|
||||||
"[F2 A2 Bb2 B2]",
|
|
||||||
"[A2 Ab2 G2 C2]",
|
|
||||||
"[F2 A2 Bb2 B2]",
|
|
||||||
"[G2 C2 F2 F2]",
|
|
||||||
"[F2 A2 Bb2 B2]",
|
|
||||||
"[A2 Ab2 G2 C2]",
|
|
||||||
"[F2 A2 Bb2 B2]",
|
|
||||||
"[G2 C2 F2 F2]",
|
|
||||||
"[Bb2 Bb2 A2 A2]",
|
|
||||||
"[Ab2 Ab2 G2 [C2 D2 E2]]",
|
|
||||||
"[Bb2 Bb2 A2 A2]",
|
|
||||||
"[Ab2 Ab2 G2 [C2 D2 E2]]",
|
|
||||||
"[F2 A2 Bb2 B2]",
|
|
||||||
"[G2 C2 F2 F2]"
|
|
||||||
).s('Acoustic Bass: Bass')
|
|
||||||
).slow(51)
|
|
||||||
.out()`;
|
|
||||||
|
|
||||||
export const outroMusic = `samples({
|
|
||||||
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav','bd/BT0A0DA.wav','bd/BT0A0D3.wav','bd/BT0A0D0.wav','bd/BT0A0A7.wav'],
|
|
||||||
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
|
|
||||||
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
|
|
||||||
perc: ['perc/002_perc2.wav'],
|
|
||||||
}, 'github:tidalcycles/Dirt-Samples/master/');
|
|
||||||
|
|
||||||
"C^7 Am7 Dm7 G7".slow(2).voicings()
|
|
||||||
.stack("0@6 [<1 2> <2 0> 1]@2".scale('C5 major'))
|
|
||||||
.n().slow(4)
|
|
||||||
.s('0040_FluidR3_GM_sf2_file')
|
|
||||||
.color('steelblue')
|
|
||||||
.stack(
|
|
||||||
"<-7 ~@2 [~@2 -7] -9 ~@2 [~@2 -9] -10!2 ~ [~@2 -10] -5 ~ [-3 -2 -10]@2>*2".scale('C3 major')
|
|
||||||
.n().s('sawtooth').color('brown')
|
|
||||||
)
|
|
||||||
.attack(0.05).decay(.1).sustain(.7)
|
|
||||||
.cutoff(perlin.range(800,2000))
|
|
||||||
.gain(.3)
|
|
||||||
.stack(
|
|
||||||
s("<bd!3 [bd ~ bd]> sd,hh*3,~@5 <perc perc*3>")
|
|
||||||
.speed(perlin.range(.9,1.1))
|
|
||||||
.n(3).color('gray')
|
|
||||||
).slow(3/2)
|
|
||||||
//.pianoroll({autorange:1,vertical:1,fold:0})
|
|
||||||
.out()`;
|
|
||||||
|
|
||||||
export const bassFuge = `samples({ flbass: ['00_c2_finger_long_neck.wav','01_c2_finger_short_neck.wav','02_c2_finger_long_bridge.wav','03_c2_finger_short_bridge.wav','04_c2_pick_long.wav','05_c2_pick_short.wav','06_c2_palm_mute.wav'] },
|
|
||||||
'github:cleary/samples-flbass/main/')
|
|
||||||
samples({
|
|
||||||
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav','bd/BT0A0DA.wav','bd/BT0A0D3.wav','bd/BT0A0D0.wav','bd/BT0A0A7.wav'],
|
|
||||||
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
|
|
||||||
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
|
|
||||||
}, 'github:tidalcycles/Dirt-Samples/master/');
|
|
||||||
|
|
||||||
note("<8(3,8) <7 7*2> [4 5@3] 8>".sub(1) // sub 1 -> 1-indexed
|
|
||||||
.layer(
|
|
||||||
x=>x,
|
|
||||||
x=>x.add(7).color('steelblue')
|
|
||||||
.off(1/8,x=>x.add("2,4").off(1/8,x=>x.add(5).echo(4,.125,.5)))
|
|
||||||
.slow(2),
|
|
||||||
).scale('A1 minor'))
|
|
||||||
.s("flbass").n(0)
|
|
||||||
.gain(.3)
|
|
||||||
.cutoff(sine.slow(7).range(200,4000))
|
|
||||||
.resonance(10)
|
|
||||||
//.hcutoff(400)
|
|
||||||
.clip(1)
|
|
||||||
.stack(s("bd:1*2,~ sd:0,[~ hh:0]*2"))
|
|
||||||
.out()
|
|
||||||
.pianoroll({vertical:1})`;
|
|
||||||
|
|||||||
+13
-20
File diff suppressed because one or more lines are too long
@@ -0,0 +1,61 @@
|
|||||||
|
# study: why are there so many calls?
|
||||||
|
|
||||||
|
- `pure('c3')` => 746 calls per second...
|
||||||
|
- shapeshifted: `(async()=>{return reify("c3").withLocation([1,5,20],[1,9,24])})()`Ï => same # of calls with or without shapeshifting
|
||||||
|
- without highlighting (// strudel disable-highlighting), there are only 15 calls
|
||||||
|
|
||||||
|
## call stack
|
||||||
|
|
||||||
|
this is how the ~15 calls are made for the first query:
|
||||||
|
|
||||||
|
- keypress -> activateCode -> evaluate -> safeEval -> pure -> new Pattern (pretty simple)
|
||||||
|
- query 0
|
||||||
|
- const timespan = new TimeSpan(0,1)
|
||||||
|
- Fraction(0), Fraction(1)
|
||||||
|
- onQuery(new State(timespan))
|
||||||
|
- pattern.query(state)
|
||||||
|
- pure.query(state)
|
||||||
|
- state.span.spanCycles
|
||||||
|
- end.sam() -> this.floor -> new Fraction
|
||||||
|
- begin.sam -> this.floor -> new Fraction
|
||||||
|
- begin.nextSam
|
||||||
|
- begin.sam -> this.floor -> new Fraction
|
||||||
|
- .add(1) -> new Fraction
|
||||||
|
- Fraction(0).wholeCycle -> new TimeSpan(0, 1)
|
||||||
|
- this.sam -> new Fraction(0)
|
||||||
|
- this.nextSam -> new Fraction(1)
|
||||||
|
- new Hap(TimeSpan(0,1), TimeSpan(0,1), 'c3')
|
||||||
|
- Tone.getTransport().cancel(0);
|
||||||
|
- queryNextTime = 0.5
|
||||||
|
- t = 0.6
|
||||||
|
|
||||||
|
## from simple to complicated
|
||||||
|
|
||||||
|
(all without highlighting)
|
||||||
|
|
||||||
|
- `pure('c3')`: 15 calls
|
||||||
|
- `pure('c3').fast(1)`: 74 calls
|
||||||
|
- `pure('c3').fast(1).fast(1)`: 133 calls
|
||||||
|
- `pure('c3').fast(1).fast(1).fast(1)`: 192 calls
|
||||||
|
- `pure('c3').fast(1).fast(1).fast(1).fast(1)`: 251 calls
|
||||||
|
- `pure('c3').fast(1).fast(1).fast(1).fast(1).fast(1)`: 310 calls
|
||||||
|
- `pure('c3').fast(2)`: 94 calls
|
||||||
|
- `pure('c3').fast(2).fast(2)`: 264 calls
|
||||||
|
- `pure('c3').fast(2).fast(2).fast(2)`: 636 calls
|
||||||
|
- `pure('c3').fast(4)`: 134 calls
|
||||||
|
|
||||||
|
## WIL
|
||||||
|
|
||||||
|
- Fraction.wholeCycle: returns a timespan for the whole cycle the given fraction is in. Fraction(n).wholeCycle -> TimeSpan(n.floor, n.floor+1)
|
||||||
|
- e.g. `Fraction(0.5).wholeCycle` -> `TimeSpan(0, 1)`
|
||||||
|
- TimeSpan.spanCycles: returns an array of whole cycle timespans that intersect with the given timespan
|
||||||
|
- e.g. `TimeSpan(0.5, 1.5)` -> `[TimeSpan(0, 1), TimeSpan(1, 2)]`
|
||||||
|
- pure: returns one Hap for spanCycles of query span. Hap will get wholeCycle as whole and query span as part
|
||||||
|
- reify: turns non patterns into patterns using pure. makes sure you get a pattern
|
||||||
|
|
||||||
|
## notes
|
||||||
|
|
||||||
|
- slowcat -> sequence -> fastcat -> slowcat is a somewhat hidden recursion
|
||||||
|
- slowcat -> pat_n can be negative and will then return an empty array. is that good? shouldn't pat_n be always a positive index?
|
||||||
|
- slowcat offset: how to think about this?
|
||||||
|
- slowcat: why add offset and sub it from the query span?
|
||||||
Reference in New Issue
Block a user