@grame/faustwasm 0.7.3 → 0.7.4
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/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/test/max_bug/create-node.js +140 -0
- package/test/max_bug/dsp-meta.json +247 -0
- package/test/max_bug/dsp-module.wasm +0 -0
- package/test/max_bug/faust-ui/index.css +442 -0
- package/test/max_bug/faust-ui/index.css.map +1 -0
- package/test/max_bug/faust-ui/index.d.ts +1 -0
- package/test/max_bug/faust-ui/index.js +3844 -0
- package/test/max_bug/faust-ui/index.js.map +1 -0
- package/test/max_bug/faustwasm/index.d.ts +1585 -0
- package/test/max_bug/faustwasm/index.js +4646 -0
- package/test/max_bug/faustwasm/index.js.map +7 -0
- package/test/max_bug/icon.png +0 -0
- package/test/max_bug/index.html +76 -0
- package/test/max_bug/index.js +149 -0
- package/test/max_bug/manifest.json +17 -0
- package/test/max_bug/service-worker.js +73 -0
- package/test/max_bug.dsp +13 -0
|
Binary file
|
|
@@ -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,149 @@
|
|
|
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
|
+
(async () => {
|
|
33
|
+
|
|
34
|
+
const { createFaustNode } = await import("./create-node.js");
|
|
35
|
+
// To test the ScriptProcessorNode mode
|
|
36
|
+
//const { faustNode, dspMeta: { name } } = await createFaustNode(audioContext, "osc", FAUST_DSP_VOICES, true, 512);
|
|
37
|
+
const { faustNode, dspMeta: { name } } = await createFaustNode(audioContext, "osc", FAUST_DSP_VOICES);
|
|
38
|
+
if (!faustNode) throw new Error("Faust DSP not compiled");
|
|
39
|
+
|
|
40
|
+
// Create the Faust UI
|
|
41
|
+
const { createFaustUI } = await import("./create-node.js");
|
|
42
|
+
await createFaustUI($divFaustUI, faustNode);
|
|
43
|
+
|
|
44
|
+
// Connect the Faust node to the audio output
|
|
45
|
+
faustNode.connect(audioContext.destination);
|
|
46
|
+
|
|
47
|
+
// Connect the Faust node to the audio input
|
|
48
|
+
if (faustNode.numberOfInputs > 0) {
|
|
49
|
+
const { connectToAudioInput } = await import("./create-node.js");
|
|
50
|
+
await connectToAudioInput(audioContext, null, faustNode, null);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Function to start MIDI
|
|
54
|
+
function startMIDI() {
|
|
55
|
+
// Check if the browser supports the Web MIDI API
|
|
56
|
+
if (navigator.requestMIDIAccess) {
|
|
57
|
+
navigator.requestMIDIAccess().then(
|
|
58
|
+
midiAccess => {
|
|
59
|
+
console.log("MIDI Access obtained.");
|
|
60
|
+
for (let input of midiAccess.inputs.values()) {
|
|
61
|
+
input.onmidimessage = (event) => faustNode.midiMessage(event.data);
|
|
62
|
+
console.log(`Connected to input: ${input.name}`);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
() => console.error("Failed to access MIDI devices.")
|
|
66
|
+
);
|
|
67
|
+
} else {
|
|
68
|
+
console.log("Web MIDI API is not supported in this browser.");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Function to stop MIDI
|
|
73
|
+
function stopMIDI() {
|
|
74
|
+
// Check if the browser supports the Web MIDI API
|
|
75
|
+
if (navigator.requestMIDIAccess) {
|
|
76
|
+
navigator.requestMIDIAccess().then(
|
|
77
|
+
midiAccess => {
|
|
78
|
+
console.log("MIDI Access obtained.");
|
|
79
|
+
for (let input of midiAccess.inputs.values()) {
|
|
80
|
+
input.onmidimessage = null;
|
|
81
|
+
console.log(`Disconnected from input: ${input.name}`);
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
() => console.error("Failed to access MIDI devices.")
|
|
85
|
+
);
|
|
86
|
+
} else {
|
|
87
|
+
console.log("Web MIDI API is not supported in this browser.");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let sensorHandlersBound = false;
|
|
92
|
+
let midiHandlersBound = false;
|
|
93
|
+
|
|
94
|
+
// Function to resume AudioContext, activate MIDI and Sensors on user interaction
|
|
95
|
+
async function activateAudioMIDISensors() {
|
|
96
|
+
|
|
97
|
+
// Resume the AudioContext
|
|
98
|
+
if (audioContext.state === 'suspended') {
|
|
99
|
+
await audioContext.resume();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Activate sensor listeners
|
|
103
|
+
if (!sensorHandlersBound) {
|
|
104
|
+
await faustNode.startSensors();
|
|
105
|
+
sensorHandlersBound = true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Initialize the MIDI setup
|
|
109
|
+
if (!midiHandlersBound && FAUST_DSP_VOICES > 0) {
|
|
110
|
+
startMIDI();
|
|
111
|
+
midiHandlersBound = true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Function to suspend AudioContext, deactivate MIDI and Sensors on user interaction
|
|
116
|
+
async function deactivateAudioMIDISensors() {
|
|
117
|
+
|
|
118
|
+
// Suspend the AudioContext
|
|
119
|
+
if (audioContext.state === 'running') {
|
|
120
|
+
await audioContext.suspend();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Deactivate sensor listeners
|
|
124
|
+
if (sensorHandlersBound) {
|
|
125
|
+
faustNode.stopSensors();
|
|
126
|
+
sensorHandlersBound = false;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Deactivate the MIDI setup
|
|
130
|
+
if (midiHandlersBound && FAUST_DSP_VOICES > 0) {
|
|
131
|
+
stopMIDI();
|
|
132
|
+
midiHandlersBound = false;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Add event listeners for user interactions
|
|
137
|
+
|
|
138
|
+
// Activate AudioContext, MIDI and Sensors on user interaction
|
|
139
|
+
window.addEventListener('click', activateAudioMIDISensors);
|
|
140
|
+
window.addEventListener('touchstart', activateAudioMIDISensors);
|
|
141
|
+
|
|
142
|
+
// Deactivate AudioContext, MIDI and Sensors on user interaction
|
|
143
|
+
window.addEventListener('visibilitychange', function () {
|
|
144
|
+
if (window.visibilityState === 'hidden') {
|
|
145
|
+
deactivateAudioMIDISensors();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
})();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Faust max_bug",
|
|
3
|
+
"short_name": "max_bug",
|
|
4
|
+
"start_url": "./index.html",
|
|
5
|
+
"description": "Progressive Web App for max_bug",
|
|
6
|
+
"display": "standalone",
|
|
7
|
+
"background_color": "#ffffff",
|
|
8
|
+
"theme_color": "#000000",
|
|
9
|
+
"orientation": "portrait",
|
|
10
|
+
"icons": [
|
|
11
|
+
{
|
|
12
|
+
"src": "./icon.png",
|
|
13
|
+
"sizes": "390x390",
|
|
14
|
+
"type": "image/png"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/// <reference lib="webworker" />
|
|
2
|
+
|
|
3
|
+
// Set to > 0 if the DSP is polyphonic
|
|
4
|
+
const FAUST_DSP_VOICES = 0;
|
|
5
|
+
// Set to true if the DSP has an effect
|
|
6
|
+
const FAUST_DSP_HAS_EFFECT = false;
|
|
7
|
+
|
|
8
|
+
const CACHE_NAME = "max_bug-static"; // Cache name without versioning
|
|
9
|
+
|
|
10
|
+
const MONO_RESOURCES = [
|
|
11
|
+
"./index.html",
|
|
12
|
+
"./index.js",
|
|
13
|
+
"./create-node.js",
|
|
14
|
+
"./faust-ui/index.js",
|
|
15
|
+
"./faust-ui/index.css",
|
|
16
|
+
"./faustwasm/index.js",
|
|
17
|
+
"./dsp-module.wasm",
|
|
18
|
+
"./dsp-meta.json"
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const POLY_RESOURCES = [
|
|
22
|
+
...MONO_RESOURCES,
|
|
23
|
+
"./mixer-module.wasm",
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const POLY_EFFECT_RESOURCES = [
|
|
27
|
+
...POLY_RESOURCES,
|
|
28
|
+
"./effect-module.wasm",
|
|
29
|
+
"./effect-meta.json",
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
/**@type {ServiceWorkerGlobalScope} */
|
|
33
|
+
const serviceWorkerGlobalScope = self;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Install the service worker and cache the resources
|
|
37
|
+
*/
|
|
38
|
+
serviceWorkerGlobalScope.addEventListener("install", (event) => {
|
|
39
|
+
console.log("Service worker installed");
|
|
40
|
+
event.waitUntil((async () => {
|
|
41
|
+
const cache = await caches.open(CACHE_NAME);
|
|
42
|
+
const resources = (FAUST_DSP_VOICES && FAUST_DSP_HAS_EFFECT) ? POLY_EFFECT_RESOURCES : FAUST_DSP_VOICES ? POLY_RESOURCES : MONO_RESOURCES;
|
|
43
|
+
try {
|
|
44
|
+
return cache.addAll(resources);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error("Failed to cache resources during install:", error);
|
|
47
|
+
}
|
|
48
|
+
})());
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
serviceWorkerGlobalScope.addEventListener("activate", () => console.log("Service worker activated"));
|
|
52
|
+
|
|
53
|
+
serviceWorkerGlobalScope.addEventListener("fetch", (event) => {
|
|
54
|
+
event.respondWith((async () => {
|
|
55
|
+
const cache = await caches.open(CACHE_NAME);
|
|
56
|
+
const cachedResponse = await cache.match(event.request);
|
|
57
|
+
if (cachedResponse) {
|
|
58
|
+
return cachedResponse;
|
|
59
|
+
} else {
|
|
60
|
+
try {
|
|
61
|
+
const fetchResponse = await fetch(event.request);
|
|
62
|
+
// Ensure the response is valid before caching it
|
|
63
|
+
if (event.request.method === "GET" && fetchResponse && fetchResponse.status === 200 && fetchResponse.type === "basic") {
|
|
64
|
+
cache.put(event.request, fetchResponse.clone());
|
|
65
|
+
}
|
|
66
|
+
return fetchResponse;
|
|
67
|
+
} catch (e) {
|
|
68
|
+
// Network access failure
|
|
69
|
+
console.log("Network access error", e);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
})());
|
|
73
|
+
});
|
package/test/max_bug.dsp
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import("stdfaust.lib");
|
|
2
|
+
freqs = (100.00, 300.00, 500.00, 1000.00, 1500.00, 2000.00, 2700.00, 3500.00, 5000.00, 6000.00, 8000.00);
|
|
3
|
+
N = 12;
|
|
4
|
+
split(signal) = signal : fi.filterbank(1, freqs);
|
|
5
|
+
display_peak(i, x) = attach(x, x : abs : vbargraph("h:peaks/%2i", 0, 1));
|
|
6
|
+
peak_bands(signal) = split(signal) : par(i, N, _ : display_peak(i));
|
|
7
|
+
|
|
8
|
+
calc_max(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) = max(v2, max(v3, max(v4, max(v5, max(v6, max(v7, max(v8, max(v9, max(v10, v11)))))))));
|
|
9
|
+
|
|
10
|
+
process(signal, side) = mono with {
|
|
11
|
+
side_bands = peak_bands(side);
|
|
12
|
+
mono = side_bands : calc_max : hbargraph("max", 0, 2);
|
|
13
|
+
};
|