spessasynth_lib 4.0.19 → 4.1.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 +28 -35
- package/dist/index.d.ts +43 -13
- package/dist/index.js +247 -156
- package/dist/index.js.map +1 -1
- package/dist/spessasynth_processor.min.js +13 -12
- package/dist/spessasynth_processor.min.js.map +4 -4
- package/package.json +17 -4
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { KeyModifier } from "spessasynth_core";
|
|
|
5
5
|
function fillWithDefaults(obj, defObj) {
|
|
6
6
|
return {
|
|
7
7
|
...defObj,
|
|
8
|
-
...obj
|
|
8
|
+
...obj
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -147,13 +147,13 @@ var SoundBankManager = class {
|
|
|
147
147
|
);
|
|
148
148
|
await this.awaitResponse();
|
|
149
149
|
const found = this.soundBankList.find((s) => s.id === id);
|
|
150
|
-
if (found
|
|
151
|
-
found.bankOffset = bankOffset;
|
|
152
|
-
} else {
|
|
150
|
+
if (found === void 0) {
|
|
153
151
|
this.soundBankList.push({
|
|
154
152
|
id,
|
|
155
153
|
bankOffset
|
|
156
154
|
});
|
|
155
|
+
} else {
|
|
156
|
+
found.bankOffset = bankOffset;
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
// noinspection JSUnusedGlobalSymbols
|
|
@@ -168,7 +168,7 @@ var SoundBankManager = class {
|
|
|
168
168
|
);
|
|
169
169
|
return;
|
|
170
170
|
}
|
|
171
|
-
if (this.soundBankList.
|
|
171
|
+
if (!this.soundBankList.some((s) => s.id === id)) {
|
|
172
172
|
SpessaSynthCoreUtils.SpessaSynthWarn(
|
|
173
173
|
`No sound banks with id of "${id}" found. Aborting!`
|
|
174
174
|
);
|
|
@@ -264,20 +264,21 @@ var SynthEventHandler = class {
|
|
|
264
264
|
/**
|
|
265
265
|
* Calls the given event.
|
|
266
266
|
* INTERNAL USE ONLY!
|
|
267
|
+
* @internal
|
|
267
268
|
*/
|
|
268
269
|
callEventInternal(name, eventData) {
|
|
269
270
|
const eventList = this.events[name];
|
|
270
271
|
const callback = () => {
|
|
271
|
-
eventList.
|
|
272
|
+
for (const callback2 of eventList.values()) {
|
|
272
273
|
try {
|
|
273
274
|
callback2(eventData);
|
|
274
|
-
} catch (
|
|
275
|
+
} catch (error) {
|
|
275
276
|
console.error(
|
|
276
277
|
`Error while executing an event callback for ${name}:`,
|
|
277
|
-
|
|
278
|
+
error
|
|
278
279
|
);
|
|
279
280
|
}
|
|
280
|
-
}
|
|
281
|
+
}
|
|
281
282
|
};
|
|
282
283
|
if (this.timeDelay > 0) {
|
|
283
284
|
setTimeout(callback.bind(this), this.timeDelay * 1e3);
|
|
@@ -525,7 +526,10 @@ var ReverbProcessor = class extends BasicEffectsProcessor {
|
|
|
525
526
|
};
|
|
526
527
|
|
|
527
528
|
// src/synthesizer/basic/snapshot.ts
|
|
528
|
-
import {
|
|
529
|
+
import {
|
|
530
|
+
ChannelSnapshot,
|
|
531
|
+
SynthesizerSnapshot
|
|
532
|
+
} from "spessasynth_core";
|
|
529
533
|
var LibSynthesizerSnapshot = class extends SynthesizerSnapshot {
|
|
530
534
|
/**
|
|
531
535
|
* Chorus configuration of this synthesizer.
|
|
@@ -590,8 +594,10 @@ var BasicSynthesizer = class {
|
|
|
590
594
|
presetList = [];
|
|
591
595
|
/**
|
|
592
596
|
* INTERNAL USE ONLY!
|
|
597
|
+
* @internal
|
|
598
|
+
* All sequencer callbacks
|
|
593
599
|
*/
|
|
594
|
-
|
|
600
|
+
sequencers = new Array();
|
|
595
601
|
/**
|
|
596
602
|
* Resolves when the synthesizer is ready.
|
|
597
603
|
*/
|
|
@@ -608,6 +614,7 @@ var BasicSynthesizer = class {
|
|
|
608
614
|
chorusProcessor;
|
|
609
615
|
/**
|
|
610
616
|
* INTERNAL USE ONLY!
|
|
617
|
+
* @internal
|
|
611
618
|
*/
|
|
612
619
|
post;
|
|
613
620
|
worklet;
|
|
@@ -1191,10 +1198,25 @@ var BasicSynthesizer = class {
|
|
|
1191
1198
|
* INTERNAL USE ONLY!
|
|
1192
1199
|
* @param type INTERNAL USE ONLY!
|
|
1193
1200
|
* @param resolve INTERNAL USE ONLY!
|
|
1201
|
+
* @internal
|
|
1194
1202
|
*/
|
|
1195
1203
|
awaitWorkerResponse(type, resolve) {
|
|
1196
1204
|
this.resolveMap.set(type, resolve);
|
|
1197
1205
|
}
|
|
1206
|
+
/**
|
|
1207
|
+
* INTERNAL USE ONLY!
|
|
1208
|
+
* @param callback the sequencer callback
|
|
1209
|
+
* @internal
|
|
1210
|
+
*/
|
|
1211
|
+
assignNewSequencer(callback) {
|
|
1212
|
+
this.post({
|
|
1213
|
+
channelNumber: -1,
|
|
1214
|
+
type: "requestNewSequencer",
|
|
1215
|
+
data: null
|
|
1216
|
+
});
|
|
1217
|
+
this.sequencers.push(callback);
|
|
1218
|
+
return this.sequencers.length - 1;
|
|
1219
|
+
}
|
|
1198
1220
|
assignProgressTracker(type, progressFunction) {
|
|
1199
1221
|
if (this.renderingProgressTracker.get(type)) {
|
|
1200
1222
|
throw new Error("Something is already being rendered!");
|
|
@@ -1226,24 +1248,29 @@ var BasicSynthesizer = class {
|
|
|
1226
1248
|
*/
|
|
1227
1249
|
handleMessage(m) {
|
|
1228
1250
|
switch (m.type) {
|
|
1229
|
-
case "eventCall":
|
|
1251
|
+
case "eventCall": {
|
|
1230
1252
|
this.eventHandler.callEventInternal(m.data.type, m.data.data);
|
|
1231
1253
|
break;
|
|
1232
|
-
|
|
1233
|
-
|
|
1254
|
+
}
|
|
1255
|
+
case "sequencerReturn": {
|
|
1256
|
+
this.sequencers[m.data.id](m.data);
|
|
1234
1257
|
break;
|
|
1235
|
-
|
|
1258
|
+
}
|
|
1259
|
+
case "isFullyInitialized": {
|
|
1236
1260
|
this.workletResponds(m.data.type, m.data.data);
|
|
1237
1261
|
break;
|
|
1238
|
-
|
|
1262
|
+
}
|
|
1263
|
+
case "soundBankError": {
|
|
1239
1264
|
util.SpessaSynthWarn(m.data);
|
|
1240
1265
|
this.eventHandler.callEventInternal("soundBankError", m.data);
|
|
1241
1266
|
break;
|
|
1242
|
-
|
|
1267
|
+
}
|
|
1268
|
+
case "renderingProgress": {
|
|
1243
1269
|
this.renderingProgressTracker.get(m.data.type)?.(
|
|
1244
1270
|
// @ts-expect-error I can't use generics with map
|
|
1245
1271
|
m.data.data
|
|
1246
1272
|
);
|
|
1273
|
+
}
|
|
1247
1274
|
}
|
|
1248
1275
|
}
|
|
1249
1276
|
addNewChannelInternal(post) {
|
|
@@ -1282,7 +1309,7 @@ var WorkletSynthesizer = class extends BasicSynthesizer {
|
|
|
1282
1309
|
*/
|
|
1283
1310
|
constructor(context, config = DEFAULT_SYNTH_CONFIG) {
|
|
1284
1311
|
const synthConfig = fillWithDefaults(config, DEFAULT_SYNTH_CONFIG);
|
|
1285
|
-
let outputChannelCount = Array(18).fill(2);
|
|
1312
|
+
let outputChannelCount = new Array(18).fill(2);
|
|
1286
1313
|
let numberOfOutputs = 18;
|
|
1287
1314
|
if (synthConfig.oneOutput) {
|
|
1288
1315
|
outputChannelCount = [36];
|
|
@@ -1301,8 +1328,8 @@ var WorkletSynthesizer = class extends BasicSynthesizer {
|
|
|
1301
1328
|
enableEventSystem: synthConfig.enableEventSystem
|
|
1302
1329
|
}
|
|
1303
1330
|
});
|
|
1304
|
-
} catch (
|
|
1305
|
-
console.error(
|
|
1331
|
+
} catch (error) {
|
|
1332
|
+
console.error(error);
|
|
1306
1333
|
throw new Error(
|
|
1307
1334
|
"Could not create the AudioWorkletNode. Did you forget to addModule()?"
|
|
1308
1335
|
);
|
|
@@ -1466,7 +1493,8 @@ var DEFAULT_WORKER_RENDER_AUDIO_OPTIONS = {
|
|
|
1466
1493
|
loopCount: 0,
|
|
1467
1494
|
progressCallback: void 0,
|
|
1468
1495
|
preserveSynthParams: true,
|
|
1469
|
-
enableEffects: true
|
|
1496
|
+
enableEffects: true,
|
|
1497
|
+
sequencerID: 0
|
|
1470
1498
|
};
|
|
1471
1499
|
var RENDER_BLOCKS_PER_PROGRESS = 64;
|
|
1472
1500
|
var BLOCK_SIZE = 128;
|
|
@@ -1475,20 +1503,20 @@ function renderAudioWorker(sampleRate, options) {
|
|
|
1475
1503
|
enableEventSystem: false
|
|
1476
1504
|
});
|
|
1477
1505
|
const rendererSeq = new SpessaSynthSequencer(rendererSynth);
|
|
1478
|
-
this.synthesizer.soundBankManager.soundBankList
|
|
1479
|
-
|
|
1506
|
+
for (const entry of this.synthesizer.soundBankManager.soundBankList)
|
|
1507
|
+
rendererSynth.soundBankManager.addSoundBank(
|
|
1480
1508
|
entry.soundBank,
|
|
1481
1509
|
entry.id,
|
|
1482
1510
|
entry.bankOffset
|
|
1483
|
-
)
|
|
1484
|
-
);
|
|
1511
|
+
);
|
|
1485
1512
|
rendererSynth.soundBankManager.priorityOrder = this.synthesizer.soundBankManager.priorityOrder;
|
|
1486
1513
|
this.stopAudioLoop();
|
|
1487
|
-
const
|
|
1514
|
+
const seq = this.sequencers[options.sequencerID];
|
|
1515
|
+
const parsedMid = seq.midiData;
|
|
1488
1516
|
if (!parsedMid) {
|
|
1489
1517
|
throw new Error("No MIDI is loaded!");
|
|
1490
1518
|
}
|
|
1491
|
-
const playbackRate =
|
|
1519
|
+
const playbackRate = seq.playbackRate;
|
|
1492
1520
|
const loopStartAbsolute = parsedMid.midiTicksToSeconds(parsedMid.loop.start) / playbackRate;
|
|
1493
1521
|
const loopEndAbsolute = parsedMid.midiTicksToSeconds(parsedMid.loop.end) / playbackRate;
|
|
1494
1522
|
const loopDuration = loopEndAbsolute - loopStartAbsolute;
|
|
@@ -1496,15 +1524,12 @@ function renderAudioWorker(sampleRate, options) {
|
|
|
1496
1524
|
const sampleDuration = sampleRate * duration;
|
|
1497
1525
|
rendererSeq.loopCount = options.loopCount;
|
|
1498
1526
|
if (options.preserveSynthParams) {
|
|
1499
|
-
rendererSeq.playbackRate =
|
|
1527
|
+
rendererSeq.playbackRate = seq.playbackRate;
|
|
1500
1528
|
const snapshot = this.synthesizer.getSnapshot();
|
|
1501
1529
|
rendererSynth.applySynthesizerSnapshot(snapshot);
|
|
1502
1530
|
}
|
|
1503
1531
|
rendererSeq.loadNewSongList([parsedMid]);
|
|
1504
1532
|
rendererSeq.play();
|
|
1505
|
-
const progressCallback = (progress) => {
|
|
1506
|
-
this.postProgress("renderAudio", progress);
|
|
1507
|
-
};
|
|
1508
1533
|
const reverb = [
|
|
1509
1534
|
new Float32Array(sampleDuration),
|
|
1510
1535
|
new Float32Array(sampleDuration)
|
|
@@ -1554,7 +1579,7 @@ function renderAudioWorker(sampleRate, options) {
|
|
|
1554
1579
|
);
|
|
1555
1580
|
index += BLOCK_SIZE;
|
|
1556
1581
|
}
|
|
1557
|
-
|
|
1582
|
+
this.postProgress("renderAudio", index / sampleDuration);
|
|
1558
1583
|
}
|
|
1559
1584
|
} else {
|
|
1560
1585
|
const dry = [
|
|
@@ -1587,7 +1612,7 @@ function renderAudioWorker(sampleRate, options) {
|
|
|
1587
1612
|
);
|
|
1588
1613
|
index += BLOCK_SIZE;
|
|
1589
1614
|
}
|
|
1590
|
-
|
|
1615
|
+
this.postProgress("renderAudio", index / sampleDuration);
|
|
1591
1616
|
}
|
|
1592
1617
|
}
|
|
1593
1618
|
}
|
|
@@ -1596,7 +1621,8 @@ function renderAudioWorker(sampleRate, options) {
|
|
|
1596
1621
|
var DEFAULT_BANK_WRITE_OPTIONS = {
|
|
1597
1622
|
trim: true,
|
|
1598
1623
|
bankID: "",
|
|
1599
|
-
writeEmbeddedSoundBank: true
|
|
1624
|
+
writeEmbeddedSoundBank: true,
|
|
1625
|
+
sequencerID: 0
|
|
1600
1626
|
};
|
|
1601
1627
|
var DEFAULT_SF2_WRITE_OPTIONS = {
|
|
1602
1628
|
...DEFAULT_BANK_WRITE_OPTIONS,
|
|
@@ -1645,7 +1671,7 @@ var WorkerSynthesizer = class extends BasicSynthesizer {
|
|
|
1645
1671
|
context,
|
|
1646
1672
|
PLAYBACK_WORKLET_PROCESSOR_NAME,
|
|
1647
1673
|
{
|
|
1648
|
-
outputChannelCount: Array(18).fill(2),
|
|
1674
|
+
outputChannelCount: new Array(18).fill(2),
|
|
1649
1675
|
numberOfOutputs: 18,
|
|
1650
1676
|
processorOptions: {
|
|
1651
1677
|
oneOutput: synthConfig.oneOutput,
|
|
@@ -1653,8 +1679,8 @@ var WorkerSynthesizer = class extends BasicSynthesizer {
|
|
|
1653
1679
|
}
|
|
1654
1680
|
}
|
|
1655
1681
|
);
|
|
1656
|
-
} catch (
|
|
1657
|
-
console.error(
|
|
1682
|
+
} catch (error) {
|
|
1683
|
+
console.error(error);
|
|
1658
1684
|
throw new Error(
|
|
1659
1685
|
"Could not create the AudioWorkletNode. Did you forget to registerPlaybackWorklet()?"
|
|
1660
1686
|
);
|
|
@@ -1955,11 +1981,7 @@ var MIDIData = class _MIDIData extends BasicMIDI {
|
|
|
1955
1981
|
super();
|
|
1956
1982
|
super.copyMetadataFrom(mid);
|
|
1957
1983
|
this.tracks = mid.tracks.map((t) => new MIDIDataTrack(t));
|
|
1958
|
-
|
|
1959
|
-
this.embeddedSoundBankSize = mid.embeddedSoundBankSize;
|
|
1960
|
-
} else {
|
|
1961
|
-
this.embeddedSoundBankSize = mid?.embeddedSoundBank?.byteLength;
|
|
1962
|
-
}
|
|
1984
|
+
this.embeddedSoundBankSize = mid instanceof _MIDIData ? mid.embeddedSoundBankSize : mid?.embeddedSoundBank?.byteLength;
|
|
1963
1985
|
}
|
|
1964
1986
|
};
|
|
1965
1987
|
|
|
@@ -1976,7 +1998,7 @@ var songChangeType = {
|
|
|
1976
1998
|
// src/synthesizer/basic/basic_synthesizer_core.ts
|
|
1977
1999
|
var BasicSynthesizerCore = class {
|
|
1978
2000
|
synthesizer;
|
|
1979
|
-
|
|
2001
|
+
sequencers = new Array();
|
|
1980
2002
|
post;
|
|
1981
2003
|
/**
|
|
1982
2004
|
* Indicates if the processor is alive.
|
|
@@ -1985,7 +2007,6 @@ var BasicSynthesizerCore = class {
|
|
|
1985
2007
|
alive = false;
|
|
1986
2008
|
constructor(sampleRate, options, postMessage) {
|
|
1987
2009
|
this.synthesizer = new SpessaSynthProcessor2(sampleRate, options);
|
|
1988
|
-
this.sequencer = new SpessaSynthSequencer2(this.synthesizer);
|
|
1989
2010
|
this.post = postMessage;
|
|
1990
2011
|
this.synthesizer.onEventCall = (event) => {
|
|
1991
2012
|
this.post({
|
|
@@ -1994,7 +2015,12 @@ var BasicSynthesizerCore = class {
|
|
|
1994
2015
|
currentTime: this.synthesizer.currentSynthTime
|
|
1995
2016
|
});
|
|
1996
2017
|
};
|
|
1997
|
-
|
|
2018
|
+
}
|
|
2019
|
+
createNewSequencer() {
|
|
2020
|
+
const sequencer = new SpessaSynthSequencer2(this.synthesizer);
|
|
2021
|
+
const sequencerID = this.sequencers.length;
|
|
2022
|
+
this.sequencers.push(sequencer);
|
|
2023
|
+
sequencer.onEventCall = (e) => {
|
|
1998
2024
|
if (e.type === "songListChange") {
|
|
1999
2025
|
const songs = e.data.newSongList;
|
|
2000
2026
|
const midiDatas = songs.map((s) => {
|
|
@@ -2004,7 +2030,8 @@ var BasicSynthesizerCore = class {
|
|
|
2004
2030
|
type: "sequencerReturn",
|
|
2005
2031
|
data: {
|
|
2006
2032
|
type: e.type,
|
|
2007
|
-
data: { newSongList: midiDatas }
|
|
2033
|
+
data: { newSongList: midiDatas },
|
|
2034
|
+
id: sequencerID
|
|
2008
2035
|
},
|
|
2009
2036
|
currentTime: this.synthesizer.currentSynthTime
|
|
2010
2037
|
});
|
|
@@ -2012,7 +2039,7 @@ var BasicSynthesizerCore = class {
|
|
|
2012
2039
|
}
|
|
2013
2040
|
this.post({
|
|
2014
2041
|
type: "sequencerReturn",
|
|
2015
|
-
data: e,
|
|
2042
|
+
data: { ...e, id: sequencerID },
|
|
2016
2043
|
currentTime: this.synthesizer.currentSynthTime
|
|
2017
2044
|
});
|
|
2018
2045
|
};
|
|
@@ -2058,7 +2085,7 @@ var BasicSynthesizerCore = class {
|
|
|
2058
2085
|
}
|
|
2059
2086
|
}
|
|
2060
2087
|
switch (m.type) {
|
|
2061
|
-
case "midiMessage":
|
|
2088
|
+
case "midiMessage": {
|
|
2062
2089
|
this.synthesizer.processMessage(
|
|
2063
2090
|
m.data.messageData,
|
|
2064
2091
|
m.data.channelOffset,
|
|
@@ -2066,20 +2093,23 @@ var BasicSynthesizerCore = class {
|
|
|
2066
2093
|
m.data.options
|
|
2067
2094
|
);
|
|
2068
2095
|
break;
|
|
2069
|
-
|
|
2096
|
+
}
|
|
2097
|
+
case "customCcChange": {
|
|
2070
2098
|
channelObject?.setCustomController(
|
|
2071
2099
|
m.data.ccNumber,
|
|
2072
2100
|
m.data.ccValue
|
|
2073
2101
|
);
|
|
2074
2102
|
break;
|
|
2075
|
-
|
|
2103
|
+
}
|
|
2104
|
+
case "ccReset": {
|
|
2076
2105
|
if (channel === ALL_CHANNELS_OR_DIFFERENT_ACTION2) {
|
|
2077
2106
|
this.synthesizer.resetAllControllers();
|
|
2078
2107
|
} else {
|
|
2079
2108
|
channelObject?.resetControllers();
|
|
2080
2109
|
}
|
|
2081
2110
|
break;
|
|
2082
|
-
|
|
2111
|
+
}
|
|
2112
|
+
case "setChannelVibrato": {
|
|
2083
2113
|
if (channel === ALL_CHANNELS_OR_DIFFERENT_ACTION2) {
|
|
2084
2114
|
for (const chan of this.synthesizer.midiChannels) {
|
|
2085
2115
|
if (m.data.rate === ALL_CHANNELS_OR_DIFFERENT_ACTION2) {
|
|
@@ -2102,32 +2132,36 @@ var BasicSynthesizerCore = class {
|
|
|
2102
2132
|
);
|
|
2103
2133
|
}
|
|
2104
2134
|
break;
|
|
2105
|
-
|
|
2135
|
+
}
|
|
2136
|
+
case "stopAll": {
|
|
2106
2137
|
if (channel === ALL_CHANNELS_OR_DIFFERENT_ACTION2) {
|
|
2107
2138
|
this.synthesizer.stopAllChannels(m.data === 1);
|
|
2108
2139
|
} else {
|
|
2109
2140
|
channelObject?.stopAllNotes(m.data === 1);
|
|
2110
2141
|
}
|
|
2111
2142
|
break;
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
break;
|
|
2115
|
-
case "muteChannel":
|
|
2143
|
+
}
|
|
2144
|
+
case "muteChannel": {
|
|
2116
2145
|
channelObject?.muteChannel(m.data);
|
|
2117
2146
|
break;
|
|
2118
|
-
|
|
2147
|
+
}
|
|
2148
|
+
case "addNewChannel": {
|
|
2119
2149
|
this.synthesizer.createMIDIChannel();
|
|
2120
2150
|
break;
|
|
2121
|
-
|
|
2151
|
+
}
|
|
2152
|
+
case "setMasterParameter": {
|
|
2122
2153
|
this.synthesizer.setMasterParameter(m.data.type, m.data.data);
|
|
2123
2154
|
break;
|
|
2124
|
-
|
|
2155
|
+
}
|
|
2156
|
+
case "setDrums": {
|
|
2125
2157
|
channelObject?.setDrums(m.data);
|
|
2126
2158
|
break;
|
|
2127
|
-
|
|
2159
|
+
}
|
|
2160
|
+
case "transposeChannel": {
|
|
2128
2161
|
channelObject?.transposeChannel(m.data.semitones, m.data.force);
|
|
2129
2162
|
break;
|
|
2130
|
-
|
|
2163
|
+
}
|
|
2164
|
+
case "lockController": {
|
|
2131
2165
|
if (m.data.controllerNumber === ALL_CHANNELS_OR_DIFFERENT_ACTION2) {
|
|
2132
2166
|
channelObject?.setPresetLock(m.data.isLocked);
|
|
2133
2167
|
} else {
|
|
@@ -2137,16 +2171,18 @@ var BasicSynthesizerCore = class {
|
|
|
2137
2171
|
channelObject.lockedControllers[m.data.controllerNumber] = m.data.isLocked;
|
|
2138
2172
|
}
|
|
2139
2173
|
break;
|
|
2174
|
+
}
|
|
2140
2175
|
case "sequencerSpecific": {
|
|
2141
|
-
|
|
2176
|
+
const seq = this.sequencers[m.data.id];
|
|
2177
|
+
if (!seq) {
|
|
2142
2178
|
return;
|
|
2143
2179
|
}
|
|
2144
|
-
const seq = this.sequencer;
|
|
2145
2180
|
const seqMsg = m.data;
|
|
2146
2181
|
switch (seqMsg.type) {
|
|
2147
|
-
default:
|
|
2182
|
+
default: {
|
|
2148
2183
|
break;
|
|
2149
|
-
|
|
2184
|
+
}
|
|
2185
|
+
case "loadNewSongList": {
|
|
2150
2186
|
try {
|
|
2151
2187
|
const sList = seqMsg.data;
|
|
2152
2188
|
const songMap = sList.map((s) => {
|
|
@@ -2159,53 +2195,64 @@ var BasicSynthesizerCore = class {
|
|
|
2159
2195
|
);
|
|
2160
2196
|
});
|
|
2161
2197
|
seq.loadNewSongList(songMap);
|
|
2162
|
-
} catch (
|
|
2163
|
-
console.error(
|
|
2198
|
+
} catch (error) {
|
|
2199
|
+
console.error(error);
|
|
2164
2200
|
this.post({
|
|
2165
2201
|
type: "sequencerReturn",
|
|
2166
2202
|
data: {
|
|
2167
2203
|
type: "midiError",
|
|
2168
|
-
data:
|
|
2204
|
+
data: error,
|
|
2205
|
+
id: m.data.id
|
|
2169
2206
|
},
|
|
2170
2207
|
currentTime: this.synthesizer.currentSynthTime
|
|
2171
2208
|
});
|
|
2172
2209
|
}
|
|
2173
2210
|
break;
|
|
2174
|
-
|
|
2211
|
+
}
|
|
2212
|
+
case "pause": {
|
|
2175
2213
|
seq.pause();
|
|
2176
2214
|
break;
|
|
2177
|
-
|
|
2215
|
+
}
|
|
2216
|
+
case "play": {
|
|
2178
2217
|
seq.play();
|
|
2179
2218
|
break;
|
|
2180
|
-
|
|
2219
|
+
}
|
|
2220
|
+
case "setTime": {
|
|
2181
2221
|
seq.currentTime = seqMsg.data;
|
|
2182
2222
|
break;
|
|
2183
|
-
|
|
2223
|
+
}
|
|
2224
|
+
case "changeMIDIMessageSending": {
|
|
2184
2225
|
seq.externalMIDIPlayback = seqMsg.data;
|
|
2185
2226
|
break;
|
|
2186
|
-
|
|
2227
|
+
}
|
|
2228
|
+
case "setPlaybackRate": {
|
|
2187
2229
|
seq.playbackRate = seqMsg.data;
|
|
2188
2230
|
break;
|
|
2189
|
-
|
|
2231
|
+
}
|
|
2232
|
+
case "setLoopCount": {
|
|
2190
2233
|
seq.loopCount = seqMsg.data;
|
|
2191
2234
|
break;
|
|
2192
|
-
|
|
2235
|
+
}
|
|
2236
|
+
case "changeSong": {
|
|
2193
2237
|
switch (seqMsg.data.changeType) {
|
|
2194
|
-
case songChangeType.shuffleOff:
|
|
2238
|
+
case songChangeType.shuffleOff: {
|
|
2195
2239
|
seq.shuffleMode = false;
|
|
2196
2240
|
break;
|
|
2197
|
-
|
|
2241
|
+
}
|
|
2242
|
+
case songChangeType.shuffleOn: {
|
|
2198
2243
|
seq.shuffleMode = true;
|
|
2199
2244
|
break;
|
|
2200
|
-
|
|
2245
|
+
}
|
|
2246
|
+
case songChangeType.index: {
|
|
2201
2247
|
if (seqMsg.data.data !== void 0) {
|
|
2202
|
-
console.log("INDEX", seqMsg.data);
|
|
2203
2248
|
seq.songIndex = seqMsg.data.data;
|
|
2204
2249
|
}
|
|
2205
2250
|
break;
|
|
2251
|
+
}
|
|
2206
2252
|
}
|
|
2207
2253
|
break;
|
|
2208
|
-
|
|
2254
|
+
}
|
|
2255
|
+
case "getMIDI": {
|
|
2209
2256
|
if (!seq.midiData) {
|
|
2210
2257
|
throw new Error("No MIDI is loaded!");
|
|
2211
2258
|
}
|
|
@@ -2213,24 +2260,27 @@ var BasicSynthesizerCore = class {
|
|
|
2213
2260
|
type: "sequencerReturn",
|
|
2214
2261
|
data: {
|
|
2215
2262
|
type: "getMIDI",
|
|
2216
|
-
data: seq.midiData
|
|
2263
|
+
data: seq.midiData,
|
|
2264
|
+
id: m.data.id
|
|
2217
2265
|
},
|
|
2218
2266
|
currentTime: this.synthesizer.currentSynthTime
|
|
2219
2267
|
});
|
|
2220
2268
|
break;
|
|
2221
|
-
|
|
2269
|
+
}
|
|
2270
|
+
case "setSkipToFirstNote": {
|
|
2222
2271
|
seq.skipToFirstNoteOn = seqMsg.data;
|
|
2223
2272
|
break;
|
|
2273
|
+
}
|
|
2224
2274
|
}
|
|
2225
2275
|
break;
|
|
2226
2276
|
}
|
|
2227
|
-
case "soundBankManager":
|
|
2277
|
+
case "soundBankManager": {
|
|
2228
2278
|
try {
|
|
2229
2279
|
const sfManager = this.synthesizer.soundBankManager;
|
|
2230
2280
|
const sfManMsg = m.data;
|
|
2231
2281
|
let font;
|
|
2232
2282
|
switch (sfManMsg.type) {
|
|
2233
|
-
case "addSoundBank":
|
|
2283
|
+
case "addSoundBank": {
|
|
2234
2284
|
font = SoundBankLoader.fromArrayBuffer(
|
|
2235
2285
|
sfManMsg.data.soundBankBuffer
|
|
2236
2286
|
);
|
|
@@ -2241,43 +2291,51 @@ var BasicSynthesizerCore = class {
|
|
|
2241
2291
|
);
|
|
2242
2292
|
this.postReady("soundBankManager", null);
|
|
2243
2293
|
break;
|
|
2244
|
-
|
|
2294
|
+
}
|
|
2295
|
+
case "deleteSoundBank": {
|
|
2245
2296
|
sfManager.deleteSoundBank(sfManMsg.data);
|
|
2246
2297
|
this.postReady("soundBankManager", null);
|
|
2247
2298
|
break;
|
|
2248
|
-
|
|
2299
|
+
}
|
|
2300
|
+
case "rearrangeSoundBanks": {
|
|
2249
2301
|
sfManager.priorityOrder = sfManMsg.data;
|
|
2250
2302
|
this.postReady("soundBankManager", null);
|
|
2303
|
+
}
|
|
2251
2304
|
}
|
|
2252
|
-
} catch (
|
|
2305
|
+
} catch (error) {
|
|
2253
2306
|
this.post({
|
|
2254
2307
|
type: "soundBankError",
|
|
2255
|
-
data:
|
|
2308
|
+
data: error,
|
|
2256
2309
|
currentTime: this.synthesizer.currentSynthTime
|
|
2257
2310
|
});
|
|
2258
2311
|
}
|
|
2259
2312
|
break;
|
|
2313
|
+
}
|
|
2260
2314
|
case "keyModifierManager": {
|
|
2261
2315
|
const kmMsg = m.data;
|
|
2262
2316
|
const man = this.synthesizer.keyModifierManager;
|
|
2263
2317
|
switch (kmMsg.type) {
|
|
2264
|
-
default:
|
|
2318
|
+
default: {
|
|
2265
2319
|
return;
|
|
2266
|
-
|
|
2320
|
+
}
|
|
2321
|
+
case "addMapping": {
|
|
2267
2322
|
man.addMapping(
|
|
2268
2323
|
kmMsg.data.channel,
|
|
2269
2324
|
kmMsg.data.midiNote,
|
|
2270
2325
|
kmMsg.data.mapping
|
|
2271
2326
|
);
|
|
2272
2327
|
break;
|
|
2273
|
-
|
|
2328
|
+
}
|
|
2329
|
+
case "clearMappings": {
|
|
2274
2330
|
man.clearMappings();
|
|
2275
2331
|
break;
|
|
2276
|
-
|
|
2332
|
+
}
|
|
2333
|
+
case "deleteMapping": {
|
|
2277
2334
|
man.deleteMapping(
|
|
2278
2335
|
kmMsg.data.channel,
|
|
2279
2336
|
kmMsg.data.midiNote
|
|
2280
2337
|
);
|
|
2338
|
+
}
|
|
2281
2339
|
}
|
|
2282
2340
|
break;
|
|
2283
2341
|
}
|
|
@@ -2286,21 +2344,28 @@ var BasicSynthesizerCore = class {
|
|
|
2286
2344
|
this.postReady("synthesizerSnapshot", snapshot);
|
|
2287
2345
|
break;
|
|
2288
2346
|
}
|
|
2289
|
-
case "
|
|
2347
|
+
case "requestNewSequencer": {
|
|
2348
|
+
this.createNewSequencer();
|
|
2349
|
+
break;
|
|
2350
|
+
}
|
|
2351
|
+
case "setLogLevel": {
|
|
2290
2352
|
SpessaSynthLogging(
|
|
2291
2353
|
m.data.enableInfo,
|
|
2292
2354
|
m.data.enableWarning,
|
|
2293
2355
|
m.data.enableGroup
|
|
2294
2356
|
);
|
|
2295
2357
|
break;
|
|
2296
|
-
|
|
2358
|
+
}
|
|
2359
|
+
case "destroyWorklet": {
|
|
2297
2360
|
this.alive = false;
|
|
2298
2361
|
this.synthesizer.destroySynthProcessor();
|
|
2299
2362
|
this.destroy();
|
|
2300
2363
|
break;
|
|
2301
|
-
|
|
2364
|
+
}
|
|
2365
|
+
default: {
|
|
2302
2366
|
util2.SpessaSynthWarn("Unrecognized event!", m);
|
|
2303
2367
|
break;
|
|
2368
|
+
}
|
|
2304
2369
|
}
|
|
2305
2370
|
}
|
|
2306
2371
|
};
|
|
@@ -2320,14 +2385,15 @@ async function writeSF2Worker(opts) {
|
|
|
2320
2385
|
});
|
|
2321
2386
|
throw e;
|
|
2322
2387
|
}
|
|
2388
|
+
const sq = this.sequencers[opts.sequencerID];
|
|
2323
2389
|
if (opts.trim) {
|
|
2324
|
-
if (!
|
|
2390
|
+
if (!sq.midiData) {
|
|
2325
2391
|
throw new Error(
|
|
2326
2392
|
"Sound bank MIDI trimming is enabled but no MIDI is loaded!"
|
|
2327
2393
|
);
|
|
2328
2394
|
}
|
|
2329
2395
|
const sfCopy = BasicSoundBank.copyFrom(sf);
|
|
2330
|
-
sfCopy.trimSoundBank(
|
|
2396
|
+
sfCopy.trimSoundBank(sq.midiData);
|
|
2331
2397
|
sf = sfCopy;
|
|
2332
2398
|
}
|
|
2333
2399
|
let compressionFunction;
|
|
@@ -2357,14 +2423,15 @@ async function writeSF2Worker(opts) {
|
|
|
2357
2423
|
}
|
|
2358
2424
|
async function writeDLSWorker(opts) {
|
|
2359
2425
|
let sf = this.getBank(opts);
|
|
2426
|
+
const sq = this.sequencers[opts.sequencerID];
|
|
2360
2427
|
if (opts.trim) {
|
|
2361
|
-
if (!
|
|
2428
|
+
if (!sq.midiData) {
|
|
2362
2429
|
throw new Error(
|
|
2363
2430
|
"Sound bank MIDI trimming is enabled but no MIDI is loaded!"
|
|
2364
2431
|
);
|
|
2365
2432
|
}
|
|
2366
2433
|
const sfCopy = BasicSoundBank.copyFrom(sf);
|
|
2367
|
-
sfCopy.trimSoundBank(
|
|
2434
|
+
sfCopy.trimSoundBank(sq.midiData);
|
|
2368
2435
|
sf = sfCopy;
|
|
2369
2436
|
}
|
|
2370
2437
|
const b = await sf.writeDLS({
|
|
@@ -2387,7 +2454,8 @@ async function writeDLSWorker(opts) {
|
|
|
2387
2454
|
// src/synthesizer/worker/write_rmi_worker.ts
|
|
2388
2455
|
import { BasicMIDI as BasicMIDI3 } from "spessasynth_core";
|
|
2389
2456
|
async function writeRMIDIWorker(opts) {
|
|
2390
|
-
|
|
2457
|
+
const sq = this.sequencers[opts.sequencerID];
|
|
2458
|
+
if (!sq.midiData) {
|
|
2391
2459
|
throw new Error("No MIDI is loaded!");
|
|
2392
2460
|
}
|
|
2393
2461
|
let sf;
|
|
@@ -2401,7 +2469,7 @@ async function writeRMIDIWorker(opts) {
|
|
|
2401
2469
|
sfBin = bin.binary;
|
|
2402
2470
|
sf = bin.bank;
|
|
2403
2471
|
}
|
|
2404
|
-
const mid = BasicMIDI3.copyFrom(
|
|
2472
|
+
const mid = BasicMIDI3.copyFrom(sq.midiData);
|
|
2405
2473
|
return mid.writeRMIDI(sfBin, {
|
|
2406
2474
|
soundBank: sf,
|
|
2407
2475
|
...opts
|
|
@@ -2449,21 +2517,21 @@ var WorkerSynthesizerCore = class extends BasicSynthesizerCore {
|
|
|
2449
2517
|
*/
|
|
2450
2518
|
handleMessage(m) {
|
|
2451
2519
|
switch (m.type) {
|
|
2452
|
-
case "renderAudio":
|
|
2520
|
+
case "renderAudio": {
|
|
2453
2521
|
const rendered = renderAudioWorker.call(
|
|
2454
2522
|
this,
|
|
2455
2523
|
m.data.sampleRate,
|
|
2456
2524
|
m.data.options
|
|
2457
2525
|
);
|
|
2458
2526
|
const transferable = [];
|
|
2459
|
-
rendered.reverb
|
|
2460
|
-
rendered.chorus
|
|
2461
|
-
rendered.dry
|
|
2462
|
-
|
|
2463
|
-
);
|
|
2527
|
+
for (const r of rendered.reverb) transferable.push(r.buffer);
|
|
2528
|
+
for (const c of rendered.chorus) transferable.push(c.buffer);
|
|
2529
|
+
for (const d of rendered.dry)
|
|
2530
|
+
transferable.push(...d.map((c) => c.buffer));
|
|
2464
2531
|
this.postReady("renderAudio", rendered, transferable);
|
|
2465
2532
|
break;
|
|
2466
|
-
|
|
2533
|
+
}
|
|
2534
|
+
case "writeRMIDI": {
|
|
2467
2535
|
this.stopAudioLoop();
|
|
2468
2536
|
void writeRMIDIWorker.call(this, m.data).then((data) => {
|
|
2469
2537
|
this.postReady(
|
|
@@ -2477,7 +2545,8 @@ var WorkerSynthesizerCore = class extends BasicSynthesizerCore {
|
|
|
2477
2545
|
this.startAudioLoop();
|
|
2478
2546
|
});
|
|
2479
2547
|
break;
|
|
2480
|
-
|
|
2548
|
+
}
|
|
2549
|
+
case "writeSF2": {
|
|
2481
2550
|
this.stopAudioLoop();
|
|
2482
2551
|
void writeSF2Worker.call(this, m.data).then((data) => {
|
|
2483
2552
|
this.postReady(
|
|
@@ -2491,7 +2560,8 @@ var WorkerSynthesizerCore = class extends BasicSynthesizerCore {
|
|
|
2491
2560
|
this.startAudioLoop();
|
|
2492
2561
|
});
|
|
2493
2562
|
break;
|
|
2494
|
-
|
|
2563
|
+
}
|
|
2564
|
+
case "writeDLS": {
|
|
2495
2565
|
this.stopAudioLoop();
|
|
2496
2566
|
void writeDLSWorker.call(this, m.data).then((data) => {
|
|
2497
2567
|
this.postReady(
|
|
@@ -2505,20 +2575,17 @@ var WorkerSynthesizerCore = class extends BasicSynthesizerCore {
|
|
|
2505
2575
|
this.startAudioLoop();
|
|
2506
2576
|
});
|
|
2507
2577
|
break;
|
|
2508
|
-
|
|
2578
|
+
}
|
|
2579
|
+
default: {
|
|
2509
2580
|
super.handleMessage(m);
|
|
2581
|
+
}
|
|
2510
2582
|
}
|
|
2511
2583
|
}
|
|
2512
2584
|
getBank(opts) {
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
);
|
|
2518
|
-
} else
|
|
2519
|
-
sf = this.synthesizer.soundBankManager.soundBankList.find(
|
|
2520
|
-
(b) => b.id === opts.bankID
|
|
2521
|
-
)?.soundBank;
|
|
2585
|
+
const sq = this.sequencers[opts.sequencerID];
|
|
2586
|
+
const sf = opts.writeEmbeddedSoundBank && sq.midiData?.embeddedSoundBank ? SoundBankLoader2.fromArrayBuffer(sq.midiData.embeddedSoundBank) : this.synthesizer.soundBankManager.soundBankList.find(
|
|
2587
|
+
(b) => b.id === opts.bankID
|
|
2588
|
+
)?.soundBank;
|
|
2522
2589
|
if (!sf) {
|
|
2523
2590
|
const e = new Error(
|
|
2524
2591
|
`${opts.bankID} does not exist in the sound bank list!`
|
|
@@ -2534,7 +2601,9 @@ var WorkerSynthesizerCore = class extends BasicSynthesizerCore {
|
|
|
2534
2601
|
}
|
|
2535
2602
|
stopAudioLoop() {
|
|
2536
2603
|
this.synthesizer.stopAllChannels(true);
|
|
2537
|
-
this.
|
|
2604
|
+
for (const seq of this.sequencers) {
|
|
2605
|
+
seq.pause();
|
|
2606
|
+
}
|
|
2538
2607
|
this.alive = false;
|
|
2539
2608
|
}
|
|
2540
2609
|
startAudioLoop() {
|
|
@@ -2570,7 +2639,9 @@ var WorkerSynthesizerCore = class extends BasicSynthesizerCore {
|
|
|
2570
2639
|
const dryR = new Float32Array(data.buffer, byteOffset, BLOCK_SIZE2);
|
|
2571
2640
|
dry.push([dryL, dryR]);
|
|
2572
2641
|
}
|
|
2573
|
-
this.
|
|
2642
|
+
for (const seq of this.sequencers) {
|
|
2643
|
+
seq.processTick();
|
|
2644
|
+
}
|
|
2574
2645
|
this.synthesizer.renderAudioSplit(rev, chr, dry);
|
|
2575
2646
|
this.workletMessagePort.postMessage(data, [data.buffer]);
|
|
2576
2647
|
}
|
|
@@ -2627,20 +2698,21 @@ var SeqEventHandler = class {
|
|
|
2627
2698
|
/**
|
|
2628
2699
|
* Calls the given event.
|
|
2629
2700
|
* Internal use only.
|
|
2701
|
+
* @internal
|
|
2630
2702
|
*/
|
|
2631
2703
|
callEventInternal(name, eventData) {
|
|
2632
2704
|
const eventList = this.events[name];
|
|
2633
2705
|
const callback = () => {
|
|
2634
|
-
eventList.
|
|
2706
|
+
for (const callback2 of eventList.values()) {
|
|
2635
2707
|
try {
|
|
2636
2708
|
callback2(eventData);
|
|
2637
|
-
} catch (
|
|
2709
|
+
} catch (error) {
|
|
2638
2710
|
console.error(
|
|
2639
2711
|
`Error while executing a sequencer event callback for ${name}:`,
|
|
2640
|
-
|
|
2712
|
+
error
|
|
2641
2713
|
);
|
|
2642
2714
|
}
|
|
2643
|
-
}
|
|
2715
|
+
}
|
|
2644
2716
|
};
|
|
2645
2717
|
if (this.timeDelay > 0) {
|
|
2646
2718
|
setTimeout(callback.bind(this), this.timeDelay * 1e3);
|
|
@@ -2688,6 +2760,10 @@ var Sequencer = class {
|
|
|
2688
2760
|
* Absolute playback startTime, bases on the synth's time.
|
|
2689
2761
|
*/
|
|
2690
2762
|
absoluteStartTime;
|
|
2763
|
+
/**
|
|
2764
|
+
* For sending the messages to the correct SpessaSynthSequencer in core
|
|
2765
|
+
*/
|
|
2766
|
+
sequencerID;
|
|
2691
2767
|
/**
|
|
2692
2768
|
* Creates a new MIDI sequencer for playing back MIDI files.
|
|
2693
2769
|
* @param synth synth to send events to.
|
|
@@ -2696,7 +2772,9 @@ var Sequencer = class {
|
|
|
2696
2772
|
constructor(synth, options = DEFAULT_SEQUENCER_OPTIONS) {
|
|
2697
2773
|
this.synth = synth;
|
|
2698
2774
|
this.absoluteStartTime = this.synth.currentTime;
|
|
2699
|
-
this.
|
|
2775
|
+
this.sequencerID = this.synth.assignNewSequencer(
|
|
2776
|
+
this.handleMessage.bind(this)
|
|
2777
|
+
);
|
|
2700
2778
|
this._skipToFirstNoteOn = options?.skipToFirstNoteOn ?? true;
|
|
2701
2779
|
if (options?.initialPlaybackRate !== 1) {
|
|
2702
2780
|
this.playbackRate = options?.initialPlaybackRate ?? 1;
|
|
@@ -2916,16 +2994,15 @@ var Sequencer = class {
|
|
|
2916
2994
|
}
|
|
2917
2995
|
handleMessage(m) {
|
|
2918
2996
|
switch (m.type) {
|
|
2919
|
-
case "midiMessage":
|
|
2997
|
+
case "midiMessage": {
|
|
2920
2998
|
const midiEventData = m.data.message;
|
|
2921
|
-
if (this.midiOut) {
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
return;
|
|
2925
|
-
}
|
|
2999
|
+
if (this.midiOut && midiEventData[0] >= 128) {
|
|
3000
|
+
this.midiOut.send(midiEventData);
|
|
3001
|
+
return;
|
|
2926
3002
|
}
|
|
2927
3003
|
break;
|
|
2928
|
-
|
|
3004
|
+
}
|
|
3005
|
+
case "songChange": {
|
|
2929
3006
|
this._songIndex = m.data.songIndex;
|
|
2930
3007
|
const songChangeData = this.songListData[this._songIndex];
|
|
2931
3008
|
this.midiData = songChangeData;
|
|
@@ -2933,35 +3010,41 @@ var Sequencer = class {
|
|
|
2933
3010
|
this.absoluteStartTime = 0;
|
|
2934
3011
|
this.callEventInternal("songChange", songChangeData);
|
|
2935
3012
|
break;
|
|
2936
|
-
|
|
3013
|
+
}
|
|
3014
|
+
case "timeChange": {
|
|
2937
3015
|
const time = m.data.newTime;
|
|
2938
3016
|
this.recalculateStartTime(time);
|
|
2939
3017
|
this.callEventInternal("timeChange", time);
|
|
2940
3018
|
break;
|
|
2941
|
-
|
|
3019
|
+
}
|
|
3020
|
+
case "pause": {
|
|
2942
3021
|
this.pausedTime = this.currentTime;
|
|
2943
3022
|
this.isFinished = m.data.isFinished;
|
|
2944
3023
|
if (this.isFinished) {
|
|
2945
3024
|
this.callEventInternal("songEnded", null);
|
|
2946
3025
|
}
|
|
2947
3026
|
break;
|
|
2948
|
-
|
|
3027
|
+
}
|
|
3028
|
+
case "midiError": {
|
|
2949
3029
|
this.callEventInternal("midiError", m.data);
|
|
2950
3030
|
throw new Error(`MIDI parsing error: ${m.data}`);
|
|
2951
|
-
|
|
3031
|
+
}
|
|
3032
|
+
case "getMIDI": {
|
|
2952
3033
|
if (this.getMIDICallback) {
|
|
2953
3034
|
this.getMIDICallback(BasicMIDI4.copyFrom(m.data));
|
|
2954
3035
|
}
|
|
2955
3036
|
break;
|
|
2956
|
-
|
|
3037
|
+
}
|
|
3038
|
+
case "metaEvent": {
|
|
2957
3039
|
const event = m.data.event;
|
|
2958
3040
|
switch (event.statusByte) {
|
|
2959
|
-
case midiMessageTypes2.setTempo:
|
|
3041
|
+
case midiMessageTypes2.setTempo: {
|
|
2960
3042
|
this._currentTempo = 6e7 / SpessaSynthCoreUtils4.readBytesAsUintBigEndian(
|
|
2961
3043
|
event.data,
|
|
2962
3044
|
3
|
|
2963
3045
|
);
|
|
2964
3046
|
break;
|
|
3047
|
+
}
|
|
2965
3048
|
case midiMessageTypes2.text:
|
|
2966
3049
|
case midiMessageTypes2.lyric:
|
|
2967
3050
|
case midiMessageTypes2.copyright:
|
|
@@ -2969,7 +3052,7 @@ var Sequencer = class {
|
|
|
2969
3052
|
case midiMessageTypes2.marker:
|
|
2970
3053
|
case midiMessageTypes2.cuePoint:
|
|
2971
3054
|
case midiMessageTypes2.instrumentName:
|
|
2972
|
-
case midiMessageTypes2.programName:
|
|
3055
|
+
case midiMessageTypes2.programName: {
|
|
2973
3056
|
if (!this.midiData) {
|
|
2974
3057
|
break;
|
|
2975
3058
|
}
|
|
@@ -2995,25 +3078,30 @@ var Sequencer = class {
|
|
|
2995
3078
|
lyricsIndex
|
|
2996
3079
|
});
|
|
2997
3080
|
break;
|
|
3081
|
+
}
|
|
2998
3082
|
}
|
|
2999
3083
|
this.callEventInternal("metaEvent", {
|
|
3000
3084
|
event: m.data.event,
|
|
3001
3085
|
trackNumber: m.data.trackIndex
|
|
3002
3086
|
});
|
|
3003
3087
|
break;
|
|
3004
|
-
|
|
3088
|
+
}
|
|
3089
|
+
case "loopCountChange": {
|
|
3005
3090
|
this._loopCount = m.data.newCount;
|
|
3006
3091
|
if (this._loopCount === 0) {
|
|
3007
3092
|
}
|
|
3008
3093
|
break;
|
|
3009
|
-
|
|
3094
|
+
}
|
|
3095
|
+
case "songListChange": {
|
|
3010
3096
|
this.songListData = m.data.newSongList.map(
|
|
3011
3097
|
(m2) => new MIDIData(m2)
|
|
3012
3098
|
);
|
|
3013
3099
|
this.midiData = this.songListData[this._songIndex];
|
|
3014
3100
|
break;
|
|
3015
|
-
|
|
3101
|
+
}
|
|
3102
|
+
default: {
|
|
3016
3103
|
break;
|
|
3104
|
+
}
|
|
3017
3105
|
}
|
|
3018
3106
|
}
|
|
3019
3107
|
callEventInternal(type, data) {
|
|
@@ -3042,7 +3130,8 @@ var Sequencer = class {
|
|
|
3042
3130
|
type: "sequencerSpecific",
|
|
3043
3131
|
data: {
|
|
3044
3132
|
type: messageType,
|
|
3045
|
-
data: messageData
|
|
3133
|
+
data: messageData,
|
|
3134
|
+
id: this.sequencerID
|
|
3046
3135
|
}
|
|
3047
3136
|
});
|
|
3048
3137
|
}
|
|
@@ -3105,9 +3194,11 @@ var LibMIDIInput = class extends LibMIDIPort {
|
|
|
3105
3194
|
connectedSynths = /* @__PURE__ */ new Set();
|
|
3106
3195
|
constructor(input) {
|
|
3107
3196
|
super(input);
|
|
3108
|
-
input.onmidimessage = (e) =>
|
|
3109
|
-
|
|
3110
|
-
|
|
3197
|
+
input.onmidimessage = (e) => {
|
|
3198
|
+
for (const s of this.connectedSynths) {
|
|
3199
|
+
if (e.data) s.sendMessage(e.data);
|
|
3200
|
+
}
|
|
3201
|
+
};
|
|
3111
3202
|
}
|
|
3112
3203
|
// noinspection JSUnusedGlobalSymbols
|
|
3113
3204
|
/**
|
|
@@ -3159,12 +3250,12 @@ var MIDIDeviceHandler = class _MIDIDeviceHandler {
|
|
|
3159
3250
|
*/
|
|
3160
3251
|
outputs = /* @__PURE__ */ new Map();
|
|
3161
3252
|
constructor(access) {
|
|
3162
|
-
access.inputs.
|
|
3253
|
+
for (const [key, value] of access.inputs.entries()) {
|
|
3163
3254
|
this.inputs.set(key, new LibMIDIInput(value));
|
|
3164
|
-
}
|
|
3165
|
-
access.outputs.
|
|
3255
|
+
}
|
|
3256
|
+
for (const [key, value] of access.outputs.entries()) {
|
|
3166
3257
|
this.outputs.set(key, new LibMIDIOutput(value));
|
|
3167
|
-
}
|
|
3258
|
+
}
|
|
3168
3259
|
}
|
|
3169
3260
|
/**
|
|
3170
3261
|
* Attempts to initialize the MIDI Device Handler.
|
|
@@ -3183,9 +3274,9 @@ var MIDIDeviceHandler = class _MIDIDeviceHandler {
|
|
|
3183
3274
|
consoleColors.recognized
|
|
3184
3275
|
);
|
|
3185
3276
|
return new _MIDIDeviceHandler(response);
|
|
3186
|
-
} catch (
|
|
3187
|
-
util3.SpessaSynthWarn(`Could not get MIDI Devices:`,
|
|
3188
|
-
throw
|
|
3277
|
+
} catch (error) {
|
|
3278
|
+
util3.SpessaSynthWarn(`Could not get MIDI Devices:`, error);
|
|
3279
|
+
throw error;
|
|
3189
3280
|
}
|
|
3190
3281
|
} else {
|
|
3191
3282
|
util3.SpessaSynthWarn(
|
|
@@ -3214,7 +3305,7 @@ var WebMIDILinkHandler = class {
|
|
|
3214
3305
|
return;
|
|
3215
3306
|
}
|
|
3216
3307
|
data.shift();
|
|
3217
|
-
const midiData = data.map((byte) => parseInt(byte, 16));
|
|
3308
|
+
const midiData = data.map((byte) => Number.parseInt(byte, 16));
|
|
3218
3309
|
synth.sendMessage(midiData);
|
|
3219
3310
|
});
|
|
3220
3311
|
SpessaSynthCoreUtils5.SpessaSynthInfo(
|