@grame/faustwasm 0.4.9 → 0.5.0
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.
- package/README.md +20 -5
- package/assets/standalone/index-pwa.html +76 -0
- package/assets/standalone/index-pwa.js +133 -0
- package/build +25 -0
- package/dist/cjs-bundle/index.js +1 -1
- package/dist/esm-bundle/index.js +1 -1
- package/libfaust-wasm/libfaust-wasm.wasm +0 -0
- package/package.json +1 -1
- package/scripts/faust2wasm.js +8 -2
- package/src/copyWebStandaloneAssets.d.ts +2 -1
- package/src/copyWebStandaloneAssets.js +40 -3
package/README.md
CHANGED
|
@@ -59,17 +59,34 @@ node scripts/faust2wasm.js test/poly.dsp test/out -poly
|
|
|
59
59
|
```
|
|
60
60
|
will create a set of files: `index.js`, `dsp-module.wasm`, `dsp-meta.json`, `index.html` (and possibly `effect-module.wasm`, `effect-meta.json`) in the `out` folder.
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
#### Creating a Progressive Web Application of a Faust DSP
|
|
62
|
+
#### Creating a Progressive Web Application (PWA) of a Faust DSP
|
|
64
63
|
|
|
65
64
|
You can create a standalone Progressive Web Application using the same command line:
|
|
66
65
|
|
|
66
|
+
```bash
|
|
67
|
+
node scripts/faust2wasm.js test/rev.dsp test/rev -pwa
|
|
68
|
+
```
|
|
69
|
+
will create a set of files: `icon.png`, `service-worker.js`, `manifest.json`, `index.js`, `dsp-module.wasm`, `dsp-meta.json`, `index.html`, and the `faustwasm`, `faust-ui` folders in the `rev` folder.
|
|
70
|
+
|
|
71
|
+
The folder contains the necessary ressources to deploy the Faust application as a PWA on a server, to be installed and used offline. Note that audio files used by the `soundfile` primitives in the DSP code will have to be mannually added in the folder.
|
|
72
|
+
|
|
73
|
+
A standalone polyphonic and MIDI standalone Progressive Web Application can be created with:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
node scripts/faust2wasm.js test/organ1.dsp test/organ1 -poly -pwa
|
|
77
|
+
```
|
|
78
|
+
will create a set of files: `icon.png`, `service-worker.js`, `manifest.json`, `index.js`, `dsp-module.wasm`, `dsp-meta.json`, `effect-module.wasm`, `effect-meta.json`, `index.html`, and the `faustwasm`, `faust-ui` folders in the `organ1` folder.
|
|
79
|
+
|
|
80
|
+
#### Creating a standalone version of a Faust DSP, with audio and MIDI devices selector
|
|
81
|
+
|
|
82
|
+
You can create a standalone using the same command line:
|
|
83
|
+
|
|
67
84
|
```bash
|
|
68
85
|
node scripts/faust2wasm.js test/rev.dsp test/rev -standalone
|
|
69
86
|
```
|
|
70
87
|
will create a set of files: `icon.png`, `service-worker.js`, `manifest.json`, `index.js`, `dsp-module.wasm`, `dsp-meta.json`, `index.html`, and the `faustwasm`, `faust-ui` folders in the `rev` folder.
|
|
71
88
|
|
|
72
|
-
The folder contains the necessary ressources to deploy the Faust application as a PWA on a server, to be installed and used offline. Note that audio files used by the `soundfile` primitives in the DSP code will have to be mannually added in the folder.
|
|
89
|
+
The folder contains the necessary ressources to deploy the Faust application as a PWA on a server, to be installed and used offline. Note that audio files used by the `soundfile` primitives in the DSP code will have to be mannually added in the folder.
|
|
73
90
|
|
|
74
91
|
A standalone polyphonic and MIDI standalone Progressive Web Application can be created with:
|
|
75
92
|
|
|
@@ -78,8 +95,6 @@ node scripts/faust2wasm.js test/organ1.dsp test/organ1 -poly -standalone
|
|
|
78
95
|
```
|
|
79
96
|
will create a set of files: `icon.png`, `service-worker.js`, `manifest.json`, `index.js`, `dsp-module.wasm`, `dsp-meta.json`, `effect-module.wasm`, `effect-meta.json`, `index.html`, and the `faustwasm`, `faust-ui` folders in the `organ1` folder.
|
|
80
97
|
|
|
81
|
-
To test, be sure to launch a local web server at the `test` folder level, then go inside `test\organ1` folder.
|
|
82
|
-
|
|
83
98
|
#### Generate SVG Diagrams of a Faust DSP
|
|
84
99
|
|
|
85
100
|
For example:
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<link rel="manifest" href="./manifest.json">
|
|
5
|
+
|
|
6
|
+
<head>
|
|
7
|
+
<meta charset="UTF-8">
|
|
8
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
9
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
10
|
+
<title>Faust DSP</title>
|
|
11
|
+
<style>
|
|
12
|
+
body {
|
|
13
|
+
color: #b0b0b0;
|
|
14
|
+
background-color: #1f1f1f;
|
|
15
|
+
display: flex;
|
|
16
|
+
top: 0;
|
|
17
|
+
left: 0;
|
|
18
|
+
width: 100%;
|
|
19
|
+
height: 100%;
|
|
20
|
+
margin: 0;
|
|
21
|
+
position: absolute;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
main {
|
|
25
|
+
margin: 20px;
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
flex: 1 1 100%;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
main span {
|
|
32
|
+
position: relative;
|
|
33
|
+
display: flex;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
main span[hidden] {
|
|
37
|
+
display: none;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
main span span {
|
|
41
|
+
margin: 0px 10px;
|
|
42
|
+
flex: 1;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
main span select {
|
|
46
|
+
flex: 2;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#dsp-switch {
|
|
50
|
+
margin: 20px auto;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
#button-dsp {
|
|
54
|
+
padding: 10px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
#div-faust-ui {
|
|
58
|
+
flex: 1 1 auto;
|
|
59
|
+
display: flex;
|
|
60
|
+
position: relative;
|
|
61
|
+
flex-direction: column;
|
|
62
|
+
color: black;
|
|
63
|
+
}
|
|
64
|
+
</style>
|
|
65
|
+
<link rel="stylesheet" href="./faust-ui/index.css">
|
|
66
|
+
</head>
|
|
67
|
+
|
|
68
|
+
<body>
|
|
69
|
+
<main>
|
|
70
|
+
<div id="div-faust-ui">
|
|
71
|
+
</div>
|
|
72
|
+
</main>
|
|
73
|
+
<script src="./index.js"></script>
|
|
74
|
+
</body>
|
|
75
|
+
|
|
76
|
+
</html>
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Set to > 0 if the DSP is polyphonic
|
|
2
|
+
const FAUST_DSP_VOICES = 0;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import("./faustwasm").FaustAudioWorkletNode} FaustAudioWorkletNode
|
|
6
|
+
* @typedef {import("./faustwasm").FaustDspMeta} FaustDspMeta
|
|
7
|
+
* @typedef {import("./faustwasm").FaustUIDescriptor} FaustUIDescriptor
|
|
8
|
+
* @typedef {import("./faustwasm").FaustUIGroup} FaustUIGroup
|
|
9
|
+
* @typedef {import("./faustwasm").FaustUIItem} FaustUIItem
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Registers the service worker.
|
|
14
|
+
*/
|
|
15
|
+
if ("serviceWorker" in navigator) {
|
|
16
|
+
window.addEventListener("load", () => {
|
|
17
|
+
navigator.serviceWorker.register("./service-worker.js")
|
|
18
|
+
.then(reg => console.log("Service Worker registered", reg))
|
|
19
|
+
.catch(err => console.log("Service Worker registration failed", err));
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** @type {HTMLDivElement} */
|
|
24
|
+
const $divFaustUI = document.getElementById("div-faust-ui");
|
|
25
|
+
|
|
26
|
+
/** @type {typeof AudioContext} */
|
|
27
|
+
const AudioCtx = window.AudioContext || window.webkitAudioContext;
|
|
28
|
+
const audioContext = new AudioCtx({ latencyHint: 0.00001 });
|
|
29
|
+
audioContext.destination.channelInterpretation = "discrete";
|
|
30
|
+
audioContext.suspend();
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {FaustAudioWorkletNode} faustNode
|
|
34
|
+
*/
|
|
35
|
+
const createFaustUI = async (faustNode) => {
|
|
36
|
+
const { FaustUI } = await import("./faust-ui/index.js");
|
|
37
|
+
const $container = document.createElement("div");
|
|
38
|
+
$container.style.margin = "0";
|
|
39
|
+
$container.style.position = "absolute";
|
|
40
|
+
$container.style.overflow = "auto";
|
|
41
|
+
$container.style.display = "flex";
|
|
42
|
+
$container.style.flexDirection = "column";
|
|
43
|
+
$container.style.width = "100%";
|
|
44
|
+
$container.style.height = "100%";
|
|
45
|
+
$divFaustUI.appendChild($container);
|
|
46
|
+
const faustUI = new FaustUI({
|
|
47
|
+
ui: faustNode.getUI(),
|
|
48
|
+
root: $container,
|
|
49
|
+
listenWindowMessage: false,
|
|
50
|
+
listenWindowResize: true,
|
|
51
|
+
});
|
|
52
|
+
faustUI.paramChangeByUI = (path, value) => faustNode.setParamValue(path, value);
|
|
53
|
+
faustNode.setOutputParamHandler((path, value) => faustUI.paramChangeByDSP(path, value));
|
|
54
|
+
$container.style.minWidth = `${faustUI.minWidth}px`;
|
|
55
|
+
$container.style.minHeight = `${faustUI.minHeight}px`;
|
|
56
|
+
faustUI.resize();
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
(async () => {
|
|
60
|
+
|
|
61
|
+
const { default: createFaustNode } = await import("./create-node.js");
|
|
62
|
+
|
|
63
|
+
// To test the ScriptProcessorNode mode
|
|
64
|
+
// const { faustNode, dspMeta: { name } } = await createFaustNode(audioContext, "osc", FAUST_DSP_VOICES, true);
|
|
65
|
+
const { faustNode, dspMeta: { name } } = await createFaustNode(audioContext, "osc", FAUST_DSP_VOICES);
|
|
66
|
+
if (!faustNode) throw new Error("Faust DSP not compiled");
|
|
67
|
+
|
|
68
|
+
// Create the Faust UI
|
|
69
|
+
await createFaustUI(faustNode);
|
|
70
|
+
|
|
71
|
+
// Connect the Faust node to the audio context
|
|
72
|
+
faustNode.connect(audioContext.destination);
|
|
73
|
+
|
|
74
|
+
// Activate sensor listeners
|
|
75
|
+
await faustNode.listenSensors();
|
|
76
|
+
|
|
77
|
+
// Function to initialize MIDI
|
|
78
|
+
function initMIDI() {
|
|
79
|
+
// Check if the browser supports the Web MIDI API
|
|
80
|
+
if (navigator.requestMIDIAccess) {
|
|
81
|
+
navigator.requestMIDIAccess()
|
|
82
|
+
.then(onMIDISuccess, onMIDIFailure);
|
|
83
|
+
} else {
|
|
84
|
+
console.log("Web MIDI API is not supported in this browser.");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Success callback for requesting MIDI access
|
|
89
|
+
function onMIDISuccess(midiAccess) {
|
|
90
|
+
console.log("MIDI Access obtained.");
|
|
91
|
+
// Iterate through all available MIDI inputs
|
|
92
|
+
for (let input of midiAccess.inputs.values()) {
|
|
93
|
+
// Attach the event listener to each input
|
|
94
|
+
input.onmidimessage = handleMIDIMessage;
|
|
95
|
+
console.log(`Connected to input: ${input.name}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Failure callback for requesting MIDI access
|
|
100
|
+
function onMIDIFailure() {
|
|
101
|
+
console.error("Failed to access MIDI devices.");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Dummy event handler for MIDI messages
|
|
105
|
+
function handleMIDIMessage(event) {
|
|
106
|
+
faustNode.midiMessage(event.data);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Initialize the MIDI setup
|
|
110
|
+
if (FAUST_DSP_VOICES > 0) {
|
|
111
|
+
initMIDI();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
})();
|
|
115
|
+
|
|
116
|
+
// Function to resume AudioContext on user interaction
|
|
117
|
+
function resumeAudioContext() {
|
|
118
|
+
if (audioContext.state === 'suspended') {
|
|
119
|
+
audioContext.resume();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Add event listeners for user interactions
|
|
124
|
+
window.addEventListener('click', resumeAudioContext);
|
|
125
|
+
window.addEventListener('touchstart', resumeAudioContext);
|
|
126
|
+
|
|
127
|
+
// Optional: Remove event listeners once the context is resumed
|
|
128
|
+
audioContext.onstatechange = function () {
|
|
129
|
+
if (audioContext.state === 'running') {
|
|
130
|
+
window.removeEventListener('click', resumeAudioContext);
|
|
131
|
+
window.removeEventListener('touchstart', resumeAudioContext);
|
|
132
|
+
}
|
|
133
|
+
};
|
package/build
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
node scripts/faust2wasm.js /Users/letz/Developpements/GameLAN/atomicro/atomicro.dsp /Users/letz/Developpements/sletz.github.io/atomicro -pwa
|
|
2
|
+
|
|
3
|
+
node scripts/faust2wasm.js /Users/letz/Developpements/GameLAN/attackey/attackey.dsp /Users/letz/Developpements/sletz.github.io/attackey -pwa
|
|
4
|
+
|
|
5
|
+
node scripts/faust2wasm.js /Users/letz/Developpements/GameLAN/baliphone/baliphone.dsp /Users/letz/Developpements/sletz.github.io/baliphone -pwa
|
|
6
|
+
|
|
7
|
+
node scripts/faust2wasm.js /Users/letz/Developpements/GameLAN/drone/drone.dsp /Users/letz/Developpements/sletz.github.io/drone -pwa
|
|
8
|
+
|
|
9
|
+
node scripts/faust2wasm.js /Users/letz/Developpements/GameLAN/sequenceur/sequenceur.dsp /Users/letz/Developpements/sletz.github.io/sequenceur -pwa
|
|
10
|
+
|
|
11
|
+
node scripts/faust2wasm.js /Users/letz/Developpements/GameLAN/shakerxy/shakerxy.dsp /Users/letz/Developpements/sletz.github.io/shakerxy -pwa
|
|
12
|
+
|
|
13
|
+
node scripts/faust2wasm.js /Users/letz/Developpements/GameLAN/sinusoide/sinusoide.dsp /Users/letz/Developpements/sletz.github.io/sinusoide -pwa
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
#node scripts/faust2wasm.js /Users/letz/Developpements/GameLAN/test.dsp /Users/letz/Developpements/sletz.github.io/out -standalone
|
|
17
|
+
#node scripts/faust2wasm.js test/organ.dsp /Users/letz/Developpements/sletz.github.io/organ -poly -standalone
|
|
18
|
+
|
|
19
|
+
#node scripts/faust2wasm.js test/organ1.dsp /Users/letz/Developpements/sletz.github.io/organ1 -poly -standalone
|
|
20
|
+
|
|
21
|
+
#node scripts/faust2wasm.js test/osc2.dsp /Users/letz/Developpements/sletz.github.io/osc2 -standalone
|
|
22
|
+
|
|
23
|
+
#node scripts/faust2wasm.js /Users/letz/Developpements/faust-sampler/sampler.dsp /Users/letz/Developpements/sletz.github.io/sampler -poly -standalone
|
|
24
|
+
|
|
25
|
+
#node scripts/faust2wasm.js /Users/letz/Developpements/faust-sampler/piano.dsp /Users/letz/Developpements/sletz.github.io/piano -poly -standalone
|