Skip to content

Commit 7fadf7e

Browse files
committed
updated web build
1 parent 7b3a065 commit 7fadf7e

File tree

13 files changed

+7635
-266
lines changed

13 files changed

+7635
-266
lines changed

webbuild/MuseAudio.js

Lines changed: 6843 additions & 0 deletions
Large diffs are not rendered by default.

webbuild/MuseScoreStudio.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webbuild/MuseScoreStudio.wasm

100644100755
2.12 MB
Binary file not shown.
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
//import MuseAudio_entry from '../MuseAudio.js';
2+
3+
let MuseAudio = {
4+
preRun: [],
5+
postRun: [],
6+
locateFile: function(path, prefix) {
7+
var file = prefix + "../" + path;
8+
return file
9+
},
10+
setStatus: (function () {
11+
return function (text) {
12+
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
13+
console.info(text);
14+
};
15+
})(),
16+
onLogMessage: function (type, error) {
17+
debugLog(type + ": " + error)
18+
},
19+
inited: false,
20+
onRuntimeInitialized: function () {
21+
debugLog("onRuntimeInitialized MuseAudio: " + MuseAudio)
22+
try {
23+
//MuseAudio.ccall('Init', '', ['number'], [42]);
24+
MuseAudio._Init(42)
25+
MuseAudio.inited = true;
26+
globalThis.mainPort.postMessage({type: "DRIVER_INITED" });
27+
} catch (error) {
28+
debugLog("init ERROR: " + error)
29+
}
30+
}
31+
}
32+
33+
globalThis.self = {
34+
location: {
35+
href: ""
36+
}
37+
}
38+
39+
class MuseDriverProcessor extends AudioWorkletProcessor {
40+
41+
constructor(options) {
42+
super(options)
43+
44+
this.port.onmessage = this.onMessageFromMain.bind(this);
45+
46+
this.debugLog("end of constructor MuseDriverProcessor")
47+
48+
globalThis.mainPort = this.port;
49+
globalThis.debugLog = function(data) {
50+
globalThis.mainPort.postMessage(data)
51+
}
52+
}
53+
54+
init(data) {
55+
this.config = data.config;
56+
this.IS_USED_WORKER = this.config.MUSE_MODULE_AUDIO_WORKER == "ON";
57+
58+
59+
if (this.IS_USED_WORKER) {
60+
61+
this.workerPort = data.rpcPort
62+
this.workerPort.onmessage = this.onMessageFromWorker.bind(this);
63+
64+
this.workerBuffer = [];
65+
this.channel_inited = false;
66+
this.audio_requested = false;
67+
68+
} else {
69+
70+
// Rpc
71+
// main <=> worker
72+
MuseAudio.mainPort = data.rpcPort;
73+
MuseAudio.main_worker_rpcSend = function(data) {
74+
MuseAudio.mainPort.postMessage(data)
75+
}
76+
77+
MuseAudio.main_worker_rpcListen = function(data) {} // will be overridden
78+
MuseAudio.mainPort.onmessage = function(event) {
79+
MuseAudio.main_worker_rpcListen(event.data)
80+
}
81+
82+
// Init wasm
83+
try {
84+
MuseAudio_entry(MuseAudio);
85+
} catch (error) {
86+
this.debugLog("MuseAudio_entry ERROR:" + error)
87+
}
88+
89+
// Buffer
90+
this.wasmBuffer = {
91+
size: 0,
92+
ptr: null
93+
}
94+
95+
}
96+
}
97+
98+
sendToMain(data) {
99+
this.port.postMessage(data)
100+
}
101+
102+
onMessageFromMain(event) {
103+
if (event.data.type == "INITIALIZE_DRIVER") {
104+
this.init(event.data)
105+
}
106+
}
107+
108+
debugLog(msg) {
109+
this.sendToMain({type: "debug", msg: msg})
110+
}
111+
112+
sendToWorker(data) {
113+
this.workerPort.postMessage(data)
114+
}
115+
116+
onMessageFromWorker(event) {
117+
if (event.data.type == "response_audio") {
118+
this.onResponseAudio(event.data)
119+
} else if (event.data.type == "channel_inited") {
120+
this.channel_inited = true;
121+
}
122+
}
123+
124+
requestAudio() {
125+
if (!this.channel_inited) {
126+
return;
127+
}
128+
129+
if (this.audio_requested) {
130+
return;
131+
}
132+
133+
this.sendToWorker({type: "request_audio", samplesPerChannel: 1024})
134+
this.audio_requested = true;
135+
}
136+
137+
onResponseAudio(msg) {
138+
this.workerBuffer.push(...msg.data);
139+
this.audio_requested = false;
140+
}
141+
142+
process(inputs, outputs, parameters) {
143+
144+
// Direct wasm, not worker
145+
if (!this.IS_USED_WORKER) {
146+
if (!MuseAudio.inited) {
147+
// Wait for the WASM module to be loaded.
148+
return true;
149+
}
150+
151+
const output = outputs[0];
152+
const chCount = output.length;
153+
const samplesPerCh = output[0].length;
154+
const totalSamples = chCount * samplesPerCh;
155+
156+
const bufferSize = totalSamples * 4 /*float*/
157+
if (this.wasmBuffer.size < bufferSize) {
158+
MuseAudio._free(this.wasmBuffer.ptr);
159+
this.wasmBuffer.ptr = MuseAudio._malloc(bufferSize);
160+
this.wasmBuffer.size = bufferSize;
161+
}
162+
163+
MuseAudio._process(this.wasmBuffer.ptr, samplesPerCh);
164+
165+
const view = new Float32Array(MuseAudio.HEAPU8.buffer, this.wasmBuffer.ptr, totalSamples);
166+
167+
for (let ci = 0; ci < output.length; ++ci) {
168+
let channel = output[ci];
169+
for (let i = 0; i < channel.length; i++) {
170+
let index = i * 2 + ci;
171+
if (index < view.length) {
172+
channel[i] = view[i * 2 + ci];
173+
} else {
174+
channel[i] = 0;
175+
}
176+
}
177+
}
178+
}
179+
// use worker
180+
else {
181+
const output = outputs[0];
182+
183+
let totalWriten = 0;
184+
for (let ci = 0; ci < output.length; ++ci) {
185+
let channel = output[ci];
186+
for (let i = 0; i < channel.length; i++) {
187+
let index = i * 2 + ci;
188+
if (index < this.workerBuffer.length) {
189+
channel[i] = this.workerBuffer[i * 2 + ci];
190+
} else {
191+
channel[i] = 0;
192+
}
193+
}
194+
195+
totalWriten += Math.min(this.workerBuffer.length, channel.length);
196+
}
197+
198+
this.workerBuffer = this.workerBuffer.slice(totalWriten);
199+
200+
if (this.workerBuffer.length <= (totalWriten * 10)) {
201+
this.requestAudio()
202+
}
203+
}
204+
205+
return true;
206+
}
207+
}
208+
209+
registerProcessor('musedriver-processor', MuseDriverProcessor);

webbuild/distr/audiodriver.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
2+
3+
async function URLFromFiles(files) {
4+
const promises = files.map(file =>
5+
fetch(file).then(response => response.text())
6+
);
7+
8+
const texts = await Promise.all(promises);
9+
const text = texts.join("");
10+
const blob = new Blob([text], { type: "application/javascript" });
11+
return URL.createObjectURL(blob);
12+
}
13+
14+
let AudioDriver = (function () {
15+
16+
let audioContext = null;
17+
let processor = null;
18+
19+
var api = {
20+
21+
inited: false,
22+
onInited: null,
23+
24+
setup: async function(config, rpcPort, audio_context) {
25+
26+
if (audio_context) {
27+
audioContext = audio_context
28+
} else {
29+
audioContext = new AudioContext()
30+
}
31+
32+
try {
33+
34+
const code = await URLFromFiles([
35+
'./MuseAudio.js',
36+
'./distr/audio_worklet_processor.js'
37+
]);
38+
39+
await audioContext.audioWorklet.addModule(code)
40+
processor = new AudioWorkletNode(audioContext, 'musedriver-processor', {
41+
numberOfInputs: 0,
42+
numberOfOutputs: 1,
43+
outputChannelCount: [2],
44+
});
45+
console.log("[processor-main] create AudioWorkletNode for audio_worklet_processor")
46+
47+
} catch (error) {
48+
console.error(error)
49+
}
50+
51+
// driver (processor) -> main
52+
processor.port.onmessage = function(event) {
53+
console.log("[processor]", event.data)
54+
55+
if (event.data.type == "DRIVER_INITED") {
56+
api.inited = true;
57+
if (api.onInited) {
58+
api.onInited();
59+
}
60+
}
61+
}
62+
63+
processor.port.postMessage({
64+
type: 'INITIALIZE_DRIVER',
65+
config: config,
66+
rpcPort: rpcPort,
67+
options: {}
68+
}, [rpcPort]);
69+
},
70+
71+
outputSpec: function() {
72+
return {
73+
sampleRate: audioContext.sampleRate,
74+
samplesPerChannel: Math.max(Math.round(audioContext.baseLatency * audioContext.sampleRate), 128),
75+
audioChannelCount: audioContext.destination.channelCount
76+
}
77+
},
78+
79+
open: function() {
80+
console.log("[driver]", "open")
81+
processor.connect(audioContext.destination)
82+
audioContext.resume()
83+
},
84+
85+
resume: function() {
86+
console.log("[driver]", "resume")
87+
audioContext.resume()
88+
},
89+
90+
suspend: function() {
91+
console.log("[driver]", "suspend")
92+
audioContext.suspend();
93+
},
94+
95+
close: function() {
96+
console.log("[driver]", "close")
97+
processor.disconnect()
98+
}
99+
}
100+
101+
return api;
102+
103+
})();
104+
105+
export default AudioDriver;

0 commit comments

Comments
 (0)