@grame/faustwasm 0.4.6 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +4 -4
  2. package/assets/standalone/create-node.js +78 -0
  3. package/assets/standalone/faustwasm/index.js +12 -32
  4. package/assets/standalone/faustwasm/index.js.map +2 -2
  5. package/assets/standalone/index-template.html +17 -0
  6. package/assets/standalone/index-template.js +48 -0
  7. package/assets/standalone/index.html +4 -3
  8. package/assets/standalone/index.js +14 -71
  9. package/assets/standalone/manifest.json +5 -6
  10. package/assets/standalone/service-worker.js +51 -27
  11. package/dist/cjs/index.js +12 -32
  12. package/dist/cjs/index.js.map +2 -2
  13. package/dist/cjs-bundle/index.js +12 -32
  14. package/dist/cjs-bundle/index.js.map +2 -2
  15. package/dist/esm/index.js +12 -32
  16. package/dist/esm/index.js.map +2 -2
  17. package/dist/esm-bundle/index.js +12 -32
  18. package/dist/esm-bundle/index.js.map +2 -2
  19. package/fileutils.js +19 -21
  20. package/package.json +1 -1
  21. package/scripts/faust2wasm.js +10 -5
  22. package/src/FaustAudioWorkletNode.ts +5 -14
  23. package/src/FaustScriptProcessorNode.ts +5 -14
  24. package/src/copyWebStandaloneAssets.d.ts +2 -2
  25. package/src/copyWebStandaloneAssets.js +30 -19
  26. package/src/faust2wasmFiles.js +5 -5
  27. package/test/faustlive-wasm/faustwasm/index.js +12 -32
  28. package/test/faustlive-wasm/faustwasm/index.js.map +2 -2
  29. package/assets/standalone/index-poly.js +0 -234
  30. package/assets/standalone/service-worker-poly.js +0 -98
  31. package/assets/standalone/template-poly.html +0 -60
  32. package/assets/standalone/template.html +0 -50
  33. package/assets/standalone/template.js +0 -63
  34. package/assets/standalone/types.d.ts +0 -9
  35. package/node +0 -0
  36. package/src/instantiateFaustModule.js +0 -82
package/fileutils.js CHANGED
@@ -15,7 +15,10 @@ const __filename = fileURLToPath(import.meta.url);
15
15
  * @param {string} dest - The destination path.
16
16
  */
17
17
  const cpSync = (src, dest) => {
18
- if (!fs.existsSync(src)) return;
18
+ if (!fs.existsSync(src)) {
19
+ console.error(`${src} does not exist.`)
20
+ return;
21
+ }
19
22
  if (fs.lstatSync(src).isDirectory()) {
20
23
  if (!fs.existsSync(dest)) fs.mkdirSync(dest);
21
24
  fs.readdirSync(src).forEach(child => cpSync(path.join(src, child), path.join(dest, child)));
@@ -27,29 +30,24 @@ const cpSync = (src, dest) => {
27
30
  /**
28
31
  * @param {string} src - The source path of the file to modify and copy.
29
32
  * @param {string} dest - The destination path.
30
- * @param {string} find - The string to find.
31
- * @param {string} replace - The string to replace.
33
+ * @param {string[]} findAndReplace - The string to find and to replace pairs.
32
34
  */
33
- const cpSyncModify = (src, dest, find, replace) => {
34
- fs.readFile(src, 'utf8', function (err, data) {
35
- if (err) {
36
- console.error(err);
37
- return;
38
- }
39
-
35
+ const cpSyncModify = (src, dest, ...findAndReplace) => {
36
+ if (!fs.existsSync(src)) {
37
+ console.error(`${src} does not exist.`)
38
+ return;
39
+ }
40
+ let data = fs.readFileSync(src, "utf-8");
41
+ for (let i = 0; i < findAndReplace.length; i += 2) {
42
+ const find = findAndReplace[i];
43
+ const replace = findAndReplace[i + 1];
40
44
  // Create a regular expression from the 'find' string
41
- const regex = new RegExp(find, 'g');
42
-
45
+ const regex = new RegExp(find, "g");
43
46
  // Replace 'find' with 'replace'
44
- let modifiedData = data.replace(regex, replace);
45
-
46
- // Write the modified data to a new file
47
- fs.writeFile(dest, modifiedData, 'utf8', function (err) {
48
- if (err) {
49
- console.error(err);
50
- }
51
- });
52
- });
47
+ data = data.replace(regex, replace);
48
+ }
49
+ // Write the modified data to a new file
50
+ fs.writeFileSync(dest, data, "utf-8");
53
51
  }
54
52
  /**
55
53
  * @param {string} dir - The directory to remove.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grame/faustwasm",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
4
4
  "description": "WebAssembly version of Faust Compiler",
5
5
  "main": "dist/cjs/index.js",
6
6
  "types": "dist/esm/index.d.ts",
@@ -8,7 +8,7 @@ const argv = process.argv.slice(2);
8
8
 
9
9
  if (argv[0] === "-help" || argv[0] === "-h") {
10
10
  console.log(`
11
- faust2wasm.js <file.dsp> <outputDir> [-poly] [-standalone]
11
+ faust2wasm.js <file.dsp> <outputDir> [-poly] [-standalone] [-no-template]
12
12
  Generates WebAssembly and metadata JSON files of a given Faust DSP.
13
13
  `);
14
14
  process.exit();
@@ -22,15 +22,20 @@ const $standalone = argv.indexOf("-standalone");
22
22
  const standalone = $standalone !== -1;
23
23
  if (standalone) argv.splice($standalone, 1);
24
24
 
25
+ const $noTemplate = argv.indexOf("-no-template");
26
+ const noTemplate = $noTemplate !== -1;
27
+ if (noTemplate) argv.splice($noTemplate, 1);
28
+
25
29
  const [inputFile, outputDir, ...argvFaust] = argv;
26
30
  const fileName = inputFile.split('/').pop();
31
+ if (!fileName) throw new Error("No input DSP file");
27
32
  const dspName = fileName.replace(/\.dsp$/, '');
28
33
 
29
34
  (async () => {
30
- await faust2wasmFiles(inputFile, outputDir, argvFaust, poly);
35
+ const { dspMeta, effectMeta } = await faust2wasmFiles(inputFile, outputDir, argvFaust, poly);
31
36
  if (standalone) {
32
- copyWebStandaloneAssets(outputDir, dspName, poly);
33
- } else {
34
- copyWebTemplateAssets(outputDir, dspName, poly);
37
+ copyWebStandaloneAssets(outputDir, dspName, poly, !!effectMeta);
38
+ } else if (!noTemplate) {
39
+ copyWebTemplateAssets(outputDir, dspName, poly, !!effectMeta);
35
40
  }
36
41
  })();
@@ -76,20 +76,11 @@ export class FaustAudioWorkletNode<Poly extends boolean = false> extends (global
76
76
  async listenSensors() {
77
77
  if (this.hasAccInput) {
78
78
  const isAndroid: boolean = /Android/i.test(navigator.userAgent);
79
- let handleDeviceMotion = null;
80
- if (isAndroid) {
81
- handleDeviceMotion = ({ accelerationIncludingGravity }: DeviceMotionEvent) => {
82
- if (!accelerationIncludingGravity) return;
83
- const { x, y, z } = accelerationIncludingGravity;
84
- this.propagateAcc({ x, y, z }, true);
85
- }
86
- } else {
87
- handleDeviceMotion = ({ accelerationIncludingGravity }: DeviceMotionEvent) => {
88
- if (!accelerationIncludingGravity) return;
89
- const { x, y, z } = accelerationIncludingGravity;
90
- this.propagateAcc({ x, y, z });
91
- }
92
- }
79
+ const handleDeviceMotion = ({ accelerationIncludingGravity }: DeviceMotionEvent) => {
80
+ if (!accelerationIncludingGravity) return;
81
+ const { x, y, z } = accelerationIncludingGravity;
82
+ this.propagateAcc({ x, y, z }, isAndroid);
83
+ };
93
84
  if (window.DeviceMotionEvent) {
94
85
  if (typeof (window.DeviceMotionEvent as any).requestPermission === "function") { // for iOS 13+
95
86
  try {
@@ -40,20 +40,11 @@ export class FaustScriptProcessorNode<Poly extends boolean = false> extends (glo
40
40
  async listenSensors() {
41
41
  if (this.hasAccInput) {
42
42
  const isAndroid: boolean = /Android/i.test(navigator.userAgent);
43
- let handleDeviceMotion = null;
44
- if (isAndroid) {
45
- handleDeviceMotion = ({ accelerationIncludingGravity }: DeviceMotionEvent) => {
46
- if (!accelerationIncludingGravity) return;
47
- const { x, y, z } = accelerationIncludingGravity;
48
- this.propagateAcc({ x, y, z }, true);
49
- }
50
- } else {
51
- handleDeviceMotion = ({ accelerationIncludingGravity }: DeviceMotionEvent) => {
52
- if (!accelerationIncludingGravity) return;
53
- const { x, y, z } = accelerationIncludingGravity;
54
- this.propagateAcc({ x, y, z });
55
- }
56
- }
43
+ const handleDeviceMotion = ({ accelerationIncludingGravity }: DeviceMotionEvent) => {
44
+ if (!accelerationIncludingGravity) return;
45
+ const { x, y, z } = accelerationIncludingGravity;
46
+ this.propagateAcc({ x, y, z }, isAndroid);
47
+ };
57
48
  if (window.DeviceMotionEvent) {
58
49
  if (typeof (window.DeviceMotionEvent as any).requestPermission === "function") { // for iOS 13+
59
50
  try {
@@ -1,4 +1,4 @@
1
- declare const copyWebStandaloneAssets: (outputDir: string, dspName: string, poly: boolean) => void;
2
- declare const copyWebTemplateAssets: (outputDir: string, dspName: string, poly: boolean) => void;
1
+ declare const copyWebStandaloneAssets: (outputDir: string, dspName: string, poly?: boolean, effect?: boolean) => void;
2
+ declare const copyWebTemplateAssets: (outputDir: string, dspName: string, poly?: boolean, effect?: boolean) => void;
3
3
 
4
4
  export { copyWebStandaloneAssets, copyWebTemplateAssets };
@@ -1,7 +1,7 @@
1
1
  //@ts-check
2
2
  import * as fs from "fs";
3
3
  import * as path from "path";
4
- import { cpSync, cpSyncModify, rmSync } from "../fileutils.js";
4
+ import { cpSync, cpSyncModify } from "../fileutils.js";
5
5
  import { fileURLToPath } from "url";
6
6
 
7
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -11,27 +11,30 @@ const __filename = fileURLToPath(import.meta.url);
11
11
  * @param {string} outputDir - The output directory.
12
12
  * @param {string} dspName - The name of the DSP to be loaded.
13
13
  * @param {boolean} [poly] - Whether the DSP is polyphonic.
14
+ * @param {boolean} [effect] - Whether the DSP has an effect module.
14
15
  */
15
- const copyWebStandaloneAssets = (outputDir, dspName, poly = false) => {
16
+ const copyWebStandaloneAssets = (outputDir, dspName, poly = false, effect = false) => {
16
17
  console.log(`Writing assets files.`)
17
18
  const assetsPath = path.join(__dirname, "../assets/standalone");
18
19
  if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir);
19
20
 
21
+ const findAndReplace = ["FAUST_DSP_NAME", dspName];
22
+ if (poly) findAndReplace.push("FAUST_DSP_VOICES = 0", "FAUST_DSP_VOICES = 16");
23
+ if (poly && effect) findAndReplace.push("FAUST_DSP_HAS_EFFECT = false", "FAUST_DSP_HAS_EFFECT = true");
24
+
20
25
  // Copy some files
21
- const templateJSPath = (poly) ? path.join(__dirname, "../assets/standalone/index-poly.js") : path.join(__dirname, "../assets/standalone/index.js");
22
- cpSyncModify(templateJSPath, outputDir + `/${dspName}.js`, "FAUST_DSP", dspName);
26
+ const createNodeJSPath = path.join(__dirname, "../assets/standalone/create-node.js");
27
+ cpSyncModify(createNodeJSPath, outputDir + `/create-node.js`, ...findAndReplace);
28
+
29
+ const templateJSPath = path.join(__dirname, "../assets/standalone/index.js");
30
+ cpSyncModify(templateJSPath, outputDir + `/index.js`, ...findAndReplace);
23
31
 
24
32
  const templateHTMLPath = path.join(__dirname, "../assets/standalone/index.html");
25
- //cpSyncModify(templateHTMLPath, outputDir + `/${dspName}.html`, "FAUST_DSP", dspName);
26
- cpSyncModify(templateHTMLPath, outputDir + `/index.html`, "FAUST_DSP", dspName);
33
+ //cpSyncModify(templateHTMLPath, outputDir + `/${dspName}.html`, "FAUST_DSP_NAME", dspName);
34
+ cpSyncModify(templateHTMLPath, outputDir + `/index.html`, ...findAndReplace);
27
35
 
28
- if (poly) {
29
- const templateWorkerPath = path.join(__dirname, "../assets/standalone/service-worker-poly.js");
30
- cpSyncModify(templateWorkerPath, outputDir + `/service-worker.js`, "FAUST_DSP", dspName);
31
- } else {
32
- const templateWorkerPath = path.join(__dirname, "../assets/standalone/service-worker.js");
33
- cpSyncModify(templateWorkerPath, outputDir + `/service-worker.js`, "FAUST_DSP", dspName);
34
- }
36
+ const templateWorkerPath = path.join(__dirname, "../assets/standalone/service-worker.js");
37
+ cpSyncModify(templateWorkerPath, outputDir + `/service-worker.js`, ...findAndReplace);
35
38
 
36
39
  const templateIconPath = path.join(__dirname, "../assets/standalone/icon.png");
37
40
  cpSync(templateIconPath, outputDir + `/icon.png`);
@@ -43,25 +46,33 @@ const copyWebStandaloneAssets = (outputDir, dspName, poly = false) => {
43
46
  cpSync(faustuiPath, outputDir + "/faust-ui");
44
47
 
45
48
  const templateManifestPath = path.join(__dirname, "../assets/standalone/manifest.json");
46
- cpSyncModify(templateManifestPath, outputDir + `/manifest.json`, "FAUST_DSP", dspName);
49
+ cpSyncModify(templateManifestPath, outputDir + `/manifest.json`, ...findAndReplace);
47
50
  };
48
51
 
49
52
  /**
50
53
  * @param {string} outputDir - The output directory.
51
54
  * @param {string} dspName - The name of the DSP to be loaded.
52
55
  * @param {boolean} [poly] - Whether the DSP is polyphonic.
56
+ * @param {boolean} [effect] - Whether the DSP has an effect module.
53
57
  */
54
- const copyWebTemplateAssets = (outputDir, dspName, poly = false) => {
58
+ const copyWebTemplateAssets = (outputDir, dspName, poly = false, effect = false) => {
55
59
 
56
60
  // Create output directory if it doesn't exist
57
61
  if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir);
58
62
 
63
+ const findAndReplace = ["FAUST_DSP_NAME", dspName];
64
+ if (poly) findAndReplace.push("FAUST_DSP_VOICES = 0", "FAUST_DSP_VOICES = 16");
65
+ if (poly && effect) findAndReplace.push("FAUST_DSP_HAS_EFFECT = false", "FAUST_DSP_HAS_EFFECT = true");
66
+
59
67
  // Copy some files
60
- const templateJSPath = path.join(__dirname, "../assets/standalone/template.js");
61
- cpSync(templateJSPath, outputDir + `/${dspName}.js`);
68
+ const createNodeJSPath = path.join(__dirname, "../assets/standalone/create-node.js");
69
+ cpSyncModify(createNodeJSPath, outputDir + `/create-node.js`, ...findAndReplace);
70
+
71
+ const templateJSPath = path.join(__dirname, "../assets/standalone/index-template.js");
72
+ cpSyncModify(templateJSPath, outputDir + `/index.js`, ...findAndReplace);
62
73
 
63
- const templateHTMLPath = (poly) ? path.join(__dirname, "../assets/standalone/template-poly.html") : path.join(__dirname, "../assets/standalone/template.html");
64
- cpSyncModify(templateHTMLPath, outputDir + `/${dspName}.html`, "FAUST_DSP", dspName);
74
+ const templateHTMLPath = path.join(__dirname, "../assets/standalone/index-template.html");
75
+ cpSyncModify(templateHTMLPath, outputDir + `/index.html`, "index-template.js", "index.js", ...findAndReplace);
65
76
 
66
77
  const faustwasmPath = path.join(__dirname, "../assets/standalone/faustwasm");
67
78
  cpSync(faustwasmPath, outputDir + "/faustwasm");
@@ -34,11 +34,11 @@ const faust2wasmFiles = async (inputFile, outputDir, argv = [], poly = false) =>
34
34
 
35
35
  if (!argv.find(a => a === "-I")) argv.push("-I", "libraries/");
36
36
  argv.push("-ftz", "2");
37
- const dspModulePath = path.join(outputDir, `${dspName}.wasm`);
38
- const dspMetaPath = path.join(outputDir, `${dspName}.json`);
39
- const effectModulePath = path.join(outputDir, `${dspName}_effect.wasm`);
40
- const effectMetaPath = path.join(outputDir, `${dspName}_effect.json`);
41
- const mixerModulePath = path.join(outputDir, "mixerModule.wasm");
37
+ const dspModulePath = path.join(outputDir, `dsp-module.wasm`);
38
+ const dspMetaPath = path.join(outputDir, `dsp-meta.json`);
39
+ const effectModulePath = path.join(outputDir, `effect-module.wasm`);
40
+ const effectMetaPath = path.join(outputDir, `effect-meta.json`);
41
+ const mixerModulePath = path.join(outputDir, "mixer-module.wasm");
42
42
  /** @type {Uint8Array} */
43
43
  let dspModule;
44
44
  /** @type {import("./types").FaustDspMeta} */
@@ -3719,22 +3719,12 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
3719
3719
  async listenSensors() {
3720
3720
  if (this.hasAccInput) {
3721
3721
  const isAndroid = /Android/i.test(navigator.userAgent);
3722
- let handleDeviceMotion = null;
3723
- if (isAndroid) {
3724
- handleDeviceMotion = ({ accelerationIncludingGravity }) => {
3725
- if (!accelerationIncludingGravity)
3726
- return;
3727
- const { x, y, z } = accelerationIncludingGravity;
3728
- this.propagateAcc({ x, y, z }, true);
3729
- };
3730
- } else {
3731
- handleDeviceMotion = ({ accelerationIncludingGravity }) => {
3732
- if (!accelerationIncludingGravity)
3733
- return;
3734
- const { x, y, z } = accelerationIncludingGravity;
3735
- this.propagateAcc({ x, y, z });
3736
- };
3737
- }
3722
+ const handleDeviceMotion = ({ accelerationIncludingGravity }) => {
3723
+ if (!accelerationIncludingGravity)
3724
+ return;
3725
+ const { x, y, z } = accelerationIncludingGravity;
3726
+ this.propagateAcc({ x, y, z }, isAndroid);
3727
+ };
3738
3728
  if (window.DeviceMotionEvent) {
3739
3729
  if (typeof window.DeviceMotionEvent.requestPermission === "function") {
3740
3730
  try {
@@ -3983,22 +3973,12 @@ var FaustScriptProcessorNode = class extends (globalThis.ScriptProcessorNode ||
3983
3973
  async listenSensors() {
3984
3974
  if (this.hasAccInput) {
3985
3975
  const isAndroid = /Android/i.test(navigator.userAgent);
3986
- let handleDeviceMotion = null;
3987
- if (isAndroid) {
3988
- handleDeviceMotion = ({ accelerationIncludingGravity }) => {
3989
- if (!accelerationIncludingGravity)
3990
- return;
3991
- const { x, y, z } = accelerationIncludingGravity;
3992
- this.propagateAcc({ x, y, z }, true);
3993
- };
3994
- } else {
3995
- handleDeviceMotion = ({ accelerationIncludingGravity }) => {
3996
- if (!accelerationIncludingGravity)
3997
- return;
3998
- const { x, y, z } = accelerationIncludingGravity;
3999
- this.propagateAcc({ x, y, z });
4000
- };
4001
- }
3976
+ const handleDeviceMotion = ({ accelerationIncludingGravity }) => {
3977
+ if (!accelerationIncludingGravity)
3978
+ return;
3979
+ const { x, y, z } = accelerationIncludingGravity;
3980
+ this.propagateAcc({ x, y, z }, isAndroid);
3981
+ };
4002
3982
  if (window.DeviceMotionEvent) {
4003
3983
  if (typeof window.DeviceMotionEvent.requestPermission === "function") {
4004
3984
  try {