@marmooo/midy 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.
- package/esm/midy-GM1.d.ts +3 -0
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +115 -53
- package/esm/midy-GM2.d.ts +16 -4
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +255 -159
- package/esm/midy-GMLite.d.ts +2 -0
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +109 -53
- package/esm/midy.d.ts +34 -11
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +352 -223
- package/package.json +3 -2
- package/script/midy-GM1.d.ts +3 -0
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +115 -53
- package/script/midy-GM2.d.ts +16 -4
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +255 -159
- package/script/midy-GMLite.d.ts +2 -0
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +109 -53
- package/script/midy.d.ts +34 -11
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +352 -223
package/script/midy-GMLite.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export class MidyGMLite extends EventTarget {
|
|
|
25
25
|
voiceCounter: Map<any, any>;
|
|
26
26
|
voiceCache: Map<any, any>;
|
|
27
27
|
realtimeVoiceCache: Map<any, any>;
|
|
28
|
+
decodeMethod: string;
|
|
28
29
|
isPlaying: boolean;
|
|
29
30
|
isPausing: boolean;
|
|
30
31
|
isPaused: boolean;
|
|
@@ -71,6 +72,7 @@ export class MidyGMLite extends EventTarget {
|
|
|
71
72
|
merger: any;
|
|
72
73
|
};
|
|
73
74
|
createChannels(audioContext: any): any[];
|
|
75
|
+
decodeOggVorbis(sample: any): Promise<any>;
|
|
74
76
|
createAudioBuffer(voiceParams: any): Promise<any>;
|
|
75
77
|
createBufferSource(channel: any, voiceParams: any, audioBuffer: any): any;
|
|
76
78
|
scheduleTimelineEvents(scheduleTime: any, queueIndex: any): any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAiIA;IAwCE;;;;;;;;;MASE;IAEF,+BAgBC;IA9DD,gCAAgC;IAChC,aAAa;IACb,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,0BAAuD;IACvD,4BAAyB;IACzB,0BAAuB;IACvB,kCAA+B;IAC/B,qBAAqC;IACrC,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iCAEG;IACH,cAAU;IACV,cAAa;IACb,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IACrC,+BAEE;IAeA,kBAAgC;IAChC,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF,uBAAmD;IACnD;;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,gBAAiD;IAMnD,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCASC;IAED,sBA6BC;IAED,8DAeC;IAED;;;;MAeC;IAED,yCAaC;IAED,2CAsBC;IAED,kDA6BC;IAED,0EAUC;IAED,gEAsDC;IAED,mCASC;IAED,uBAUC;IAED,yDAqCC;IAED,2BA0EC;IAED,uDAEC;IAED,wDAEC;IAED,qCAKC;IAED;;;MAwDC;IAED,kGAeC;IAED,mGAeC;IAED,wEAQC;IAED,uBAMC;IAED,sBAIC;IAED,uBAMC;IAED,wBAIC;IAED,0BAKC;IAED,8BAMC;IAED,wBAYC;IAED,sBAIC;IAED,kEAWC;IAED,kFAYC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,wCAIC;IAED,2DAIC;IAED,6CAEC;IAED,sDAeC;IAED,4DASC;IAED,qDAkBC;IAED,6CAIC;IAED,sDA6BC;IAED,kEAqBC;IAED,4GAkCC;IAED,uEA6CC;IAED,0EAiBC;IAED,8EAiBC;IAED,oEAUC;IAED,0FAwBC;IAED,gCASC;IAED,iEAwBC;IAED,4FAsBC;IAED,6CAUC;IAED,qDAUC;IAED,qFAeC;IAED,+BAmBC;IAED,kDAOC;IAED,sFA2BC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAYC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;;MAoCC;IAED,oFAMC;IAED,6EA2BC;IAED,qCAeC;IAED,+FAYC;IAED,wDAUC;IAED,4EAKC;IAED,mEAKC;IAED;;;MAMC;IAED,gEAKC;IAED,uEAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAWC;IAED,kFAeC;IAED,uDAcC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,gFAGC;IAED,6CAqBC;IAGD,8EAgCC;IAED,gFAGC;IAED,+EAgBC;IAED,qCAUC;IAED,4EAaC;IAED,4DAGC;IAED,qDAKC;IAED,gDAYC;IAGD,6DAgBC;CACF"}
|
package/script/midy-GMLite.js
CHANGED
|
@@ -3,6 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MidyGMLite = void 0;
|
|
4
4
|
const midi_file_1 = require("midi-file");
|
|
5
5
|
const soundfont_parser_1 = require("@marmooo/soundfont-parser");
|
|
6
|
+
const ogg_vorbis_1 = require("@wasm-audio-decoders/ogg-vorbis");
|
|
7
|
+
let decoderPromise = null;
|
|
8
|
+
let decoderQueue = Promise.resolve();
|
|
9
|
+
function initDecoder() {
|
|
10
|
+
if (!decoderPromise) {
|
|
11
|
+
const instance = new ogg_vorbis_1.OggVorbisDecoderWebWorker();
|
|
12
|
+
decoderPromise = instance.ready.then(() => instance);
|
|
13
|
+
}
|
|
14
|
+
return decoderPromise;
|
|
15
|
+
}
|
|
6
16
|
class Note {
|
|
7
17
|
constructor(noteNumber, velocity, startTime) {
|
|
8
18
|
Object.defineProperty(this, "voice", {
|
|
@@ -41,37 +51,37 @@ class Note {
|
|
|
41
51
|
writable: true,
|
|
42
52
|
value: void 0
|
|
43
53
|
});
|
|
44
|
-
Object.defineProperty(this, "
|
|
54
|
+
Object.defineProperty(this, "filterEnvelopeNode", {
|
|
45
55
|
enumerable: true,
|
|
46
56
|
configurable: true,
|
|
47
57
|
writable: true,
|
|
48
58
|
value: void 0
|
|
49
59
|
});
|
|
50
|
-
Object.defineProperty(this, "
|
|
60
|
+
Object.defineProperty(this, "volumeEnvelopeNode", {
|
|
51
61
|
enumerable: true,
|
|
52
62
|
configurable: true,
|
|
53
63
|
writable: true,
|
|
54
64
|
value: void 0
|
|
55
65
|
});
|
|
56
|
-
Object.defineProperty(this, "
|
|
66
|
+
Object.defineProperty(this, "modLfo", {
|
|
57
67
|
enumerable: true,
|
|
58
68
|
configurable: true,
|
|
59
69
|
writable: true,
|
|
60
70
|
value: void 0
|
|
61
|
-
});
|
|
62
|
-
Object.defineProperty(this, "
|
|
71
|
+
}); // CC#1 modulation LFO
|
|
72
|
+
Object.defineProperty(this, "modLfoToPitch", {
|
|
63
73
|
enumerable: true,
|
|
64
74
|
configurable: true,
|
|
65
75
|
writable: true,
|
|
66
76
|
value: void 0
|
|
67
77
|
});
|
|
68
|
-
Object.defineProperty(this, "
|
|
78
|
+
Object.defineProperty(this, "modLfoToFilterFc", {
|
|
69
79
|
enumerable: true,
|
|
70
80
|
configurable: true,
|
|
71
81
|
writable: true,
|
|
72
82
|
value: void 0
|
|
73
83
|
});
|
|
74
|
-
Object.defineProperty(this, "
|
|
84
|
+
Object.defineProperty(this, "modLfoToVolume", {
|
|
75
85
|
enumerable: true,
|
|
76
86
|
configurable: true,
|
|
77
87
|
writable: true,
|
|
@@ -271,6 +281,12 @@ class MidyGMLite extends EventTarget {
|
|
|
271
281
|
writable: true,
|
|
272
282
|
value: new Map()
|
|
273
283
|
});
|
|
284
|
+
Object.defineProperty(this, "decodeMethod", {
|
|
285
|
+
enumerable: true,
|
|
286
|
+
configurable: true,
|
|
287
|
+
writable: true,
|
|
288
|
+
value: "wasm-audio-decoders"
|
|
289
|
+
});
|
|
274
290
|
Object.defineProperty(this, "isPlaying", {
|
|
275
291
|
enumerable: true,
|
|
276
292
|
configurable: true,
|
|
@@ -438,14 +454,6 @@ class MidyGMLite extends EventTarget {
|
|
|
438
454
|
voiceCounter.set(audioBufferId, (voiceCounter.get(audioBufferId) ?? 0) + 1);
|
|
439
455
|
break;
|
|
440
456
|
}
|
|
441
|
-
case "controller":
|
|
442
|
-
if (event.controllerType === 0) {
|
|
443
|
-
this.setBankMSB(event.channel, event.value);
|
|
444
|
-
}
|
|
445
|
-
else if (event.controllerType === 32) {
|
|
446
|
-
this.setBankLSB(event.channel, event.value);
|
|
447
|
-
}
|
|
448
|
-
break;
|
|
449
457
|
case "programChange":
|
|
450
458
|
this.setProgramChange(event.channel, event.programNumber, event.startTime);
|
|
451
459
|
}
|
|
@@ -503,11 +511,57 @@ class MidyGMLite extends EventTarget {
|
|
|
503
511
|
});
|
|
504
512
|
return channels;
|
|
505
513
|
}
|
|
514
|
+
decodeOggVorbis(sample) {
|
|
515
|
+
const task = decoderQueue.then(async () => {
|
|
516
|
+
const decoder = await initDecoder();
|
|
517
|
+
const slice = sample.data.slice();
|
|
518
|
+
const { channelData, sampleRate, errors } = await decoder.decodeFile(slice);
|
|
519
|
+
if (0 < errors.length) {
|
|
520
|
+
throw new Error(errors.join(", "));
|
|
521
|
+
}
|
|
522
|
+
const audioBuffer = new AudioBuffer({
|
|
523
|
+
numberOfChannels: channelData.length,
|
|
524
|
+
length: channelData[0].length,
|
|
525
|
+
sampleRate,
|
|
526
|
+
});
|
|
527
|
+
for (let ch = 0; ch < channelData.length; ch++) {
|
|
528
|
+
audioBuffer.getChannelData(ch).set(channelData[ch]);
|
|
529
|
+
}
|
|
530
|
+
return audioBuffer;
|
|
531
|
+
});
|
|
532
|
+
decoderQueue = task.catch(() => { });
|
|
533
|
+
return task;
|
|
534
|
+
}
|
|
506
535
|
async createAudioBuffer(voiceParams) {
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
536
|
+
const sample = voiceParams.sample;
|
|
537
|
+
if (sample.type === "compressed") {
|
|
538
|
+
switch (this.decodeMethod) {
|
|
539
|
+
case "decodeAudioData": {
|
|
540
|
+
// https://jakearchibald.com/2016/sounds-fun/
|
|
541
|
+
// https://github.com/WebAudio/web-audio-api/issues/1091
|
|
542
|
+
// decodeAudioData() has priming issues on Safari
|
|
543
|
+
const arrayBuffer = sample.data.slice().buffer;
|
|
544
|
+
return await this.audioContext.decodeAudioData(arrayBuffer);
|
|
545
|
+
}
|
|
546
|
+
case "wasm-audio-decoders":
|
|
547
|
+
return await this.decodeOggVorbis(sample);
|
|
548
|
+
default:
|
|
549
|
+
throw new Error(`Unknown decodeMethod: ${this.decodeMethod}`);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
else {
|
|
553
|
+
const data = sample.data;
|
|
554
|
+
const end = data.length + voiceParams.end;
|
|
555
|
+
const subarray = data.subarray(voiceParams.start, end);
|
|
556
|
+
const pcm = sample.decodePCM(subarray);
|
|
557
|
+
const audioBuffer = new AudioBuffer({
|
|
558
|
+
numberOfChannels: 1,
|
|
559
|
+
length: pcm.length,
|
|
560
|
+
sampleRate: sample.sampleHeader.sampleRate,
|
|
561
|
+
});
|
|
562
|
+
audioBuffer.getChannelData(0).set(pcm);
|
|
563
|
+
return audioBuffer;
|
|
564
|
+
}
|
|
511
565
|
}
|
|
512
566
|
createBufferSource(channel, voiceParams, audioBuffer) {
|
|
513
567
|
const bufferSource = new AudioBufferSourceNode(this.audioContext);
|
|
@@ -575,7 +629,7 @@ class MidyGMLite extends EventTarget {
|
|
|
575
629
|
const channels = this.channels;
|
|
576
630
|
for (let ch = 0; ch < channels.length; ch++) {
|
|
577
631
|
channels[ch].scheduledNotes = [];
|
|
578
|
-
this.resetChannelStates(
|
|
632
|
+
this.resetChannelStates(ch);
|
|
579
633
|
}
|
|
580
634
|
}
|
|
581
635
|
updateStates(queueIndex, nextQueueIndex) {
|
|
@@ -956,7 +1010,7 @@ class MidyGMLite extends EventTarget {
|
|
|
956
1010
|
const modHold = modAttack + voiceParams.modHold;
|
|
957
1011
|
const decayDuration = voiceParams.modDecay;
|
|
958
1012
|
note.adjustedBaseFreq = adjustedBaseFreq;
|
|
959
|
-
note.
|
|
1013
|
+
note.filterEnvelopeNode.frequency
|
|
960
1014
|
.cancelScheduledValues(scheduleTime)
|
|
961
1015
|
.setValueAtTime(adjustedBaseFreq, startTime)
|
|
962
1016
|
.setValueAtTime(adjustedBaseFreq, modDelay)
|
|
@@ -967,23 +1021,23 @@ class MidyGMLite extends EventTarget {
|
|
|
967
1021
|
startModulation(channel, note, scheduleTime) {
|
|
968
1022
|
const audioContext = this.audioContext;
|
|
969
1023
|
const { voiceParams } = note;
|
|
970
|
-
note.
|
|
1024
|
+
note.modLfo = new OscillatorNode(audioContext, {
|
|
971
1025
|
frequency: this.centToHz(voiceParams.freqModLFO),
|
|
972
1026
|
});
|
|
973
|
-
note.
|
|
1027
|
+
note.modLfoToFilterFc = new GainNode(audioContext, {
|
|
974
1028
|
gain: voiceParams.modLfoToFilterFc,
|
|
975
1029
|
});
|
|
976
|
-
note.
|
|
1030
|
+
note.modLfoToPitch = new GainNode(audioContext);
|
|
977
1031
|
this.setModLfoToPitch(channel, note, scheduleTime);
|
|
978
|
-
note.
|
|
1032
|
+
note.modLfoToVolume = new GainNode(audioContext);
|
|
979
1033
|
this.setModLfoToVolume(note, scheduleTime);
|
|
980
|
-
note.
|
|
981
|
-
note.
|
|
982
|
-
note.
|
|
983
|
-
note.
|
|
984
|
-
note.
|
|
985
|
-
note.
|
|
986
|
-
note.
|
|
1034
|
+
note.modLfo.start(note.startTime + voiceParams.delayModLFO);
|
|
1035
|
+
note.modLfo.connect(note.modLfoToFilterFc);
|
|
1036
|
+
note.modLfoToFilterFc.connect(note.filterEnvelopeNode.frequency);
|
|
1037
|
+
note.modLfo.connect(note.modLfoToPitch);
|
|
1038
|
+
note.modLfoToPitch.connect(note.bufferSource.detune);
|
|
1039
|
+
note.modLfo.connect(note.modLfoToVolume);
|
|
1040
|
+
note.modLfoToVolume.connect(note.volumeEnvelopeNode.gain);
|
|
987
1041
|
}
|
|
988
1042
|
async getAudioBuffer(channel, noteNumber, velocity, voiceParams, realtime) {
|
|
989
1043
|
const audioBufferId = this.getVoiceId(channel, noteNumber, velocity);
|
|
@@ -1024,7 +1078,7 @@ class MidyGMLite extends EventTarget {
|
|
|
1024
1078
|
const audioBuffer = await this.getAudioBuffer(channel, noteNumber, velocity, voiceParams, realtime);
|
|
1025
1079
|
note.bufferSource = this.createBufferSource(channel, voiceParams, audioBuffer);
|
|
1026
1080
|
note.volumeEnvelopeNode = new GainNode(audioContext);
|
|
1027
|
-
note.
|
|
1081
|
+
note.filterEnvelopeNode = new BiquadFilterNode(audioContext, {
|
|
1028
1082
|
type: "lowpass",
|
|
1029
1083
|
Q: voiceParams.initialFilterQ / 10, // dB
|
|
1030
1084
|
});
|
|
@@ -1035,8 +1089,8 @@ class MidyGMLite extends EventTarget {
|
|
|
1035
1089
|
if (0 < state.modulationDepthMSB) {
|
|
1036
1090
|
this.startModulation(channel, note, now);
|
|
1037
1091
|
}
|
|
1038
|
-
note.bufferSource.connect(note.
|
|
1039
|
-
note.
|
|
1092
|
+
note.bufferSource.connect(note.filterEnvelopeNode);
|
|
1093
|
+
note.filterEnvelopeNode.connect(note.volumeEnvelopeNode);
|
|
1040
1094
|
if (voiceParams.sample.type === "compressed") {
|
|
1041
1095
|
const offset = voiceParams.start / audioBuffer.sampleRate;
|
|
1042
1096
|
note.bufferSource.start(startTime, offset);
|
|
@@ -1118,19 +1172,19 @@ class MidyGMLite extends EventTarget {
|
|
|
1118
1172
|
}
|
|
1119
1173
|
disconnectNote(note) {
|
|
1120
1174
|
note.bufferSource.disconnect();
|
|
1121
|
-
note.
|
|
1175
|
+
note.filterEnvelopeNode.disconnect();
|
|
1122
1176
|
note.volumeEnvelopeNode.disconnect();
|
|
1123
|
-
if (note.
|
|
1124
|
-
note.
|
|
1125
|
-
note.
|
|
1126
|
-
note.
|
|
1177
|
+
if (note.modLfoToPitch) {
|
|
1178
|
+
note.modLfoToVolume.disconnect();
|
|
1179
|
+
note.modLfoToPitch.disconnect();
|
|
1180
|
+
note.modLfo.stop();
|
|
1127
1181
|
}
|
|
1128
1182
|
}
|
|
1129
1183
|
releaseNote(channel, note, endTime) {
|
|
1130
1184
|
endTime ??= this.audioContext.currentTime;
|
|
1131
1185
|
const volDuration = note.voiceParams.volRelease;
|
|
1132
1186
|
const volRelease = endTime + volDuration;
|
|
1133
|
-
note.
|
|
1187
|
+
note.filterEnvelopeNode.frequency
|
|
1134
1188
|
.cancelScheduledValues(endTime)
|
|
1135
1189
|
.setTargetAtTime(note.adjustedBaseFreq, endTime, note.voiceParams.modRelease * releaseCurve);
|
|
1136
1190
|
note.volumeEnvelopeNode.gain
|
|
@@ -1262,12 +1316,12 @@ class MidyGMLite extends EventTarget {
|
|
|
1262
1316
|
this.applyVoiceParams(channel, 14, scheduleTime);
|
|
1263
1317
|
}
|
|
1264
1318
|
setModLfoToPitch(channel, note, scheduleTime) {
|
|
1265
|
-
if (note.
|
|
1319
|
+
if (note.modLfoToPitch) {
|
|
1266
1320
|
const modLfoToPitch = note.voiceParams.modLfoToPitch;
|
|
1267
1321
|
const baseDepth = Math.abs(modLfoToPitch) +
|
|
1268
1322
|
channel.state.modulationDepthMSB;
|
|
1269
1323
|
const depth = baseDepth * Math.sign(modLfoToPitch);
|
|
1270
|
-
note.
|
|
1324
|
+
note.modLfoToPitch.gain
|
|
1271
1325
|
.cancelScheduledValues(scheduleTime)
|
|
1272
1326
|
.setValueAtTime(depth, scheduleTime);
|
|
1273
1327
|
}
|
|
@@ -1277,29 +1331,29 @@ class MidyGMLite extends EventTarget {
|
|
|
1277
1331
|
}
|
|
1278
1332
|
setModLfoToFilterFc(note, scheduleTime) {
|
|
1279
1333
|
const modLfoToFilterFc = note.voiceParams.modLfoToFilterFc;
|
|
1280
|
-
note.
|
|
1334
|
+
note.modLfoToFilterFc.gain
|
|
1281
1335
|
.cancelScheduledValues(scheduleTime)
|
|
1282
1336
|
.setValueAtTime(modLfoToFilterFc, scheduleTime);
|
|
1283
1337
|
}
|
|
1284
1338
|
setModLfoToVolume(note, scheduleTime) {
|
|
1285
1339
|
const modLfoToVolume = note.voiceParams.modLfoToVolume;
|
|
1286
1340
|
const baseDepth = cbToRatio(Math.abs(modLfoToVolume)) - 1;
|
|
1287
|
-
const
|
|
1288
|
-
note.
|
|
1341
|
+
const depth = baseDepth * Math.sign(modLfoToVolume);
|
|
1342
|
+
note.modLfoToVolume.gain
|
|
1289
1343
|
.cancelScheduledValues(scheduleTime)
|
|
1290
|
-
.setValueAtTime(
|
|
1344
|
+
.setValueAtTime(depth, scheduleTime);
|
|
1291
1345
|
}
|
|
1292
1346
|
setDelayModLFO(note, scheduleTime) {
|
|
1293
1347
|
const startTime = note.startTime;
|
|
1294
1348
|
if (startTime < scheduleTime)
|
|
1295
1349
|
return;
|
|
1296
|
-
note.
|
|
1297
|
-
note.
|
|
1298
|
-
note.
|
|
1350
|
+
note.modLfo.stop(scheduleTime);
|
|
1351
|
+
note.modLfo.start(startTime + note.voiceParams.delayModLFO);
|
|
1352
|
+
note.modLfo.connect(note.modLfoToFilterFc);
|
|
1299
1353
|
}
|
|
1300
1354
|
setFreqModLFO(note, scheduleTime) {
|
|
1301
1355
|
const freqModLFO = note.voiceParams.freqModLFO;
|
|
1302
|
-
note.
|
|
1356
|
+
note.modLfo.frequency
|
|
1303
1357
|
.cancelScheduledValues(scheduleTime)
|
|
1304
1358
|
.setValueAtTime(freqModLFO, scheduleTime);
|
|
1305
1359
|
}
|
|
@@ -1396,6 +1450,8 @@ class MidyGMLite extends EventTarget {
|
|
|
1396
1450
|
return handlers;
|
|
1397
1451
|
}
|
|
1398
1452
|
setControlChange(channelNumber, controllerType, value, scheduleTime) {
|
|
1453
|
+
if (!(0 <= scheduleTime))
|
|
1454
|
+
scheduleTime = this.audioContext.currentTime;
|
|
1399
1455
|
const handler = this.controlChangeHandlers[controllerType];
|
|
1400
1456
|
if (handler) {
|
|
1401
1457
|
handler.call(this, channelNumber, value, scheduleTime);
|
|
@@ -1410,8 +1466,8 @@ class MidyGMLite extends EventTarget {
|
|
|
1410
1466
|
const depth = channel.state.modulationDepthMSB *
|
|
1411
1467
|
channel.modulationDepthRange;
|
|
1412
1468
|
this.processScheduledNotes(channel, (note) => {
|
|
1413
|
-
if (note.
|
|
1414
|
-
note.
|
|
1469
|
+
if (note.modLfoToPitch) {
|
|
1470
|
+
note.modLfoToPitch.gain.setValueAtTime(depth, scheduleTime);
|
|
1415
1471
|
}
|
|
1416
1472
|
else {
|
|
1417
1473
|
this.startModulation(channel, note, scheduleTime);
|
package/script/midy.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ export class Midy extends EventTarget {
|
|
|
49
49
|
voiceCounter: Map<any, any>;
|
|
50
50
|
voiceCache: Map<any, any>;
|
|
51
51
|
realtimeVoiceCache: Map<any, any>;
|
|
52
|
+
decodeMethod: string;
|
|
52
53
|
isPlaying: boolean;
|
|
53
54
|
isPausing: boolean;
|
|
54
55
|
isPaused: boolean;
|
|
@@ -71,6 +72,9 @@ export class Midy extends EventTarget {
|
|
|
71
72
|
channelToNotes: Map<any, any>;
|
|
72
73
|
noteToChannel: Map<any, any>;
|
|
73
74
|
};
|
|
75
|
+
decoder: OggVorbisDecoderWebWorker;
|
|
76
|
+
decoderReady: Promise<void>;
|
|
77
|
+
decoderQueue: Promise<void>;
|
|
74
78
|
audioContext: any;
|
|
75
79
|
masterVolume: any;
|
|
76
80
|
scheduler: any;
|
|
@@ -91,6 +95,7 @@ export class Midy extends EventTarget {
|
|
|
91
95
|
};
|
|
92
96
|
controlChangeHandlers: any[];
|
|
93
97
|
keyBasedControllerHandlers: any[];
|
|
98
|
+
effectHandlers: any[];
|
|
94
99
|
channels: any[];
|
|
95
100
|
reverbEffect: {
|
|
96
101
|
input: any;
|
|
@@ -118,6 +123,7 @@ export class Midy extends EventTarget {
|
|
|
118
123
|
};
|
|
119
124
|
resetChannelTable(channel: any): void;
|
|
120
125
|
createChannels(audioContext: any): any[];
|
|
126
|
+
decodeOggVorbis(sample: any): Promise<any>;
|
|
121
127
|
createAudioBuffer(voiceParams: any): Promise<any>;
|
|
122
128
|
isLoopDrum(channel: any, noteNumber: any): boolean;
|
|
123
129
|
createBufferSource(channel: any, noteNumber: any, voiceParams: any, audioBuffer: any): any;
|
|
@@ -184,6 +190,7 @@ export class Midy extends EventTarget {
|
|
|
184
190
|
getPitchIncrementSpeed(value: any): number;
|
|
185
191
|
setPortamentoVolumeEnvelope(channel: any, note: any, scheduleTime: any): void;
|
|
186
192
|
setVolumeEnvelope(channel: any, note: any, scheduleTime: any): void;
|
|
193
|
+
setVolumeNode(channel: any, note: any, scheduleTime: any): void;
|
|
187
194
|
setPortamentoDetune(channel: any, note: any, scheduleTime: any): void;
|
|
188
195
|
setDetune(channel: any, note: any, scheduleTime: any): void;
|
|
189
196
|
setPortamentoPitchEnvelope(channel: any, note: any, scheduleTime: any): void;
|
|
@@ -253,6 +260,7 @@ export class Midy extends EventTarget {
|
|
|
253
260
|
updatePortamento(channel: any, scheduleTime: any): void;
|
|
254
261
|
setPortamentoTime(channelNumber: any, value: any, scheduleTime: any): void;
|
|
255
262
|
setVolume(channelNumber: any, value: any, scheduleTime: any): void;
|
|
263
|
+
applyVolume(channel: any, scheduleTime: any): void;
|
|
256
264
|
panToGain(pan: any): {
|
|
257
265
|
gainLeft: number;
|
|
258
266
|
gainRight: number;
|
|
@@ -270,7 +278,6 @@ export class Midy extends EventTarget {
|
|
|
270
278
|
getSoftPedalFactor(channel: any, note: any): number;
|
|
271
279
|
setSoftPedal(channelNumber: any, softPedal: any, scheduleTime: any): void;
|
|
272
280
|
setFilterResonance(channelNumber: any, ccValue: any, scheduleTime: any): void;
|
|
273
|
-
getRelativeKeyBasedValue(channel: any, note: any, controllerType: any): any;
|
|
274
281
|
setReleaseTime(channelNumber: any, releaseTime: any, scheduleTime: any): void;
|
|
275
282
|
setAttackTime(channelNumber: any, attackTime: any, scheduleTime: any): void;
|
|
276
283
|
setBrightness(channelNumber: any, brightness: any, scheduleTime: any): void;
|
|
@@ -340,23 +347,38 @@ export class Midy extends EventTarget {
|
|
|
340
347
|
getChannelBitmap(data: any): any[];
|
|
341
348
|
handleScaleOctaveTuning1ByteFormatSysEx(data: any, realtime: any, scheduleTime: any): void;
|
|
342
349
|
handleScaleOctaveTuning2ByteFormatSysEx(data: any, realtime: any, scheduleTime: any): void;
|
|
350
|
+
calcEffectValue(channel: any, note: any, destination: any): number;
|
|
351
|
+
calcChannelEffectValue(channel: any, destination: any): number;
|
|
352
|
+
calcControlChangeEffectValue(channel: any, destination: any): number;
|
|
353
|
+
calcChannelPressureEffectValue(channel: any, destination: any): number;
|
|
354
|
+
calcNoteEffectValue(channel: any, note: any, destination: any): number;
|
|
355
|
+
getChannelPitchControl(channel: any): number;
|
|
356
|
+
getNotePitchControl(channel: any, note: any): number;
|
|
343
357
|
getPitchControl(channel: any, note: any): number;
|
|
344
358
|
getFilterCutoffControl(channel: any, note: any): number;
|
|
359
|
+
getChannelAmplitudeControl(channel: any): number;
|
|
360
|
+
getNoteAmplitudeControl(channel: any, note: any): number;
|
|
345
361
|
getAmplitudeControl(channel: any, note: any): number;
|
|
346
362
|
getLFOPitchDepth(channel: any, note: any): number;
|
|
347
363
|
getLFOFilterDepth(channel: any, note: any): number;
|
|
348
364
|
getLFOAmplitudeDepth(channel: any, note: any): number;
|
|
349
|
-
|
|
365
|
+
createEffectHandlers(): any[];
|
|
366
|
+
setControlChangeEffects(channel: any, note: any, scheduleTime: any): void;
|
|
367
|
+
setChannelPressureEffects(channel: any, note: any, scheduleTime: any): void;
|
|
368
|
+
setPolyphonicKeyPressureEffects(channel: any, note: any, scheduleTime: any): void;
|
|
369
|
+
setPressureEffects(channel: any, note: any, tableName: any, scheduleTime: any): void;
|
|
370
|
+
handleChannelPressureSysEx(data: any, scheduleTime: any): void;
|
|
371
|
+
handlePolyphonicKeyPressureSysEx(data: any, scheduleTime: any): void;
|
|
350
372
|
handlePressureSysEx(data: any, tableName: any, scheduleTime: any): void;
|
|
351
|
-
initControlTable(): Int8Array<ArrayBuffer>;
|
|
352
|
-
setControlChangeEffects(channel: any, controllerType: any, scheduleTime: any): void;
|
|
353
373
|
handleControlChangeSysEx(data: any, scheduleTime: any): void;
|
|
374
|
+
getRelativeKeyBasedValue(channel: any, keyNumber: any, controllerType: any): any;
|
|
354
375
|
getKeyBasedValue(channel: any, keyNumber: any, controllerType: any): any;
|
|
355
376
|
createKeyBasedControllerHandlers(): any[];
|
|
356
377
|
handleKeyBasedInstrumentControlSysEx(data: any, scheduleTime: any): void;
|
|
357
378
|
handleSysEx(data: any, scheduleTime: any): void;
|
|
358
379
|
scheduleTask(callback: any, scheduleTime: any): Promise<any>;
|
|
359
380
|
}
|
|
381
|
+
import { OggVorbisDecoderWebWorker } from "@wasm-audio-decoders/ogg-vorbis";
|
|
360
382
|
declare class Note {
|
|
361
383
|
constructor(noteNumber: any, velocity: any, startTime: any);
|
|
362
384
|
voice: any;
|
|
@@ -365,14 +387,15 @@ declare class Note {
|
|
|
365
387
|
index: number;
|
|
366
388
|
ending: boolean;
|
|
367
389
|
bufferSource: any;
|
|
368
|
-
|
|
369
|
-
filterDepth: any;
|
|
390
|
+
filterEnvelopeNode: any;
|
|
370
391
|
volumeEnvelopeNode: any;
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
392
|
+
volumeNode: any;
|
|
393
|
+
modLfo: any;
|
|
394
|
+
modLfoToPitch: any;
|
|
395
|
+
modLfoToFilterFc: any;
|
|
396
|
+
modLfoToVolume: any;
|
|
397
|
+
vibLfo: any;
|
|
398
|
+
vibLfoToPitch: any;
|
|
376
399
|
reverbSend: any;
|
|
377
400
|
chorusSend: any;
|
|
378
401
|
portamentoNoteNumber: number;
|
package/script/midy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}
|