@marmooo/midy 0.4.6 → 0.4.7
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 +13 -4
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +251 -157
- 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 +29 -11
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +328 -221
- 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 +13 -4
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +251 -157
- 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 +29 -11
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +328 -221
package/esm/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;
|
package/esm/midy-GMLite.d.ts.map
CHANGED
|
@@ -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/esm/midy-GMLite.js
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { parseMidi } from "midi-file";
|
|
2
2
|
import { parse, SoundFont } from "@marmooo/soundfont-parser";
|
|
3
|
+
import { OggVorbisDecoderWebWorker } from "@wasm-audio-decoders/ogg-vorbis";
|
|
4
|
+
let decoderPromise = null;
|
|
5
|
+
let decoderQueue = Promise.resolve();
|
|
6
|
+
function initDecoder() {
|
|
7
|
+
if (!decoderPromise) {
|
|
8
|
+
const instance = new OggVorbisDecoderWebWorker();
|
|
9
|
+
decoderPromise = instance.ready.then(() => instance);
|
|
10
|
+
}
|
|
11
|
+
return decoderPromise;
|
|
12
|
+
}
|
|
3
13
|
class Note {
|
|
4
14
|
constructor(noteNumber, velocity, startTime) {
|
|
5
15
|
Object.defineProperty(this, "voice", {
|
|
@@ -38,37 +48,37 @@ class Note {
|
|
|
38
48
|
writable: true,
|
|
39
49
|
value: void 0
|
|
40
50
|
});
|
|
41
|
-
Object.defineProperty(this, "
|
|
51
|
+
Object.defineProperty(this, "filterEnvelopeNode", {
|
|
42
52
|
enumerable: true,
|
|
43
53
|
configurable: true,
|
|
44
54
|
writable: true,
|
|
45
55
|
value: void 0
|
|
46
56
|
});
|
|
47
|
-
Object.defineProperty(this, "
|
|
57
|
+
Object.defineProperty(this, "volumeEnvelopeNode", {
|
|
48
58
|
enumerable: true,
|
|
49
59
|
configurable: true,
|
|
50
60
|
writable: true,
|
|
51
61
|
value: void 0
|
|
52
62
|
});
|
|
53
|
-
Object.defineProperty(this, "
|
|
63
|
+
Object.defineProperty(this, "modLfo", {
|
|
54
64
|
enumerable: true,
|
|
55
65
|
configurable: true,
|
|
56
66
|
writable: true,
|
|
57
67
|
value: void 0
|
|
58
|
-
});
|
|
59
|
-
Object.defineProperty(this, "
|
|
68
|
+
}); // CC#1 modulation LFO
|
|
69
|
+
Object.defineProperty(this, "modLfoToPitch", {
|
|
60
70
|
enumerable: true,
|
|
61
71
|
configurable: true,
|
|
62
72
|
writable: true,
|
|
63
73
|
value: void 0
|
|
64
74
|
});
|
|
65
|
-
Object.defineProperty(this, "
|
|
75
|
+
Object.defineProperty(this, "modLfoToFilterFc", {
|
|
66
76
|
enumerable: true,
|
|
67
77
|
configurable: true,
|
|
68
78
|
writable: true,
|
|
69
79
|
value: void 0
|
|
70
80
|
});
|
|
71
|
-
Object.defineProperty(this, "
|
|
81
|
+
Object.defineProperty(this, "modLfoToVolume", {
|
|
72
82
|
enumerable: true,
|
|
73
83
|
configurable: true,
|
|
74
84
|
writable: true,
|
|
@@ -268,6 +278,12 @@ export class MidyGMLite extends EventTarget {
|
|
|
268
278
|
writable: true,
|
|
269
279
|
value: new Map()
|
|
270
280
|
});
|
|
281
|
+
Object.defineProperty(this, "decodeMethod", {
|
|
282
|
+
enumerable: true,
|
|
283
|
+
configurable: true,
|
|
284
|
+
writable: true,
|
|
285
|
+
value: "wasm-audio-decoders"
|
|
286
|
+
});
|
|
271
287
|
Object.defineProperty(this, "isPlaying", {
|
|
272
288
|
enumerable: true,
|
|
273
289
|
configurable: true,
|
|
@@ -435,14 +451,6 @@ export class MidyGMLite extends EventTarget {
|
|
|
435
451
|
voiceCounter.set(audioBufferId, (voiceCounter.get(audioBufferId) ?? 0) + 1);
|
|
436
452
|
break;
|
|
437
453
|
}
|
|
438
|
-
case "controller":
|
|
439
|
-
if (event.controllerType === 0) {
|
|
440
|
-
this.setBankMSB(event.channel, event.value);
|
|
441
|
-
}
|
|
442
|
-
else if (event.controllerType === 32) {
|
|
443
|
-
this.setBankLSB(event.channel, event.value);
|
|
444
|
-
}
|
|
445
|
-
break;
|
|
446
454
|
case "programChange":
|
|
447
455
|
this.setProgramChange(event.channel, event.programNumber, event.startTime);
|
|
448
456
|
}
|
|
@@ -500,11 +508,57 @@ export class MidyGMLite extends EventTarget {
|
|
|
500
508
|
});
|
|
501
509
|
return channels;
|
|
502
510
|
}
|
|
511
|
+
decodeOggVorbis(sample) {
|
|
512
|
+
const task = decoderQueue.then(async () => {
|
|
513
|
+
const decoder = await initDecoder();
|
|
514
|
+
const slice = sample.data.slice();
|
|
515
|
+
const { channelData, sampleRate, errors } = await decoder.decodeFile(slice);
|
|
516
|
+
if (0 < errors.length) {
|
|
517
|
+
throw new Error(errors.join(", "));
|
|
518
|
+
}
|
|
519
|
+
const audioBuffer = new AudioBuffer({
|
|
520
|
+
numberOfChannels: channelData.length,
|
|
521
|
+
length: channelData[0].length,
|
|
522
|
+
sampleRate,
|
|
523
|
+
});
|
|
524
|
+
for (let ch = 0; ch < channelData.length; ch++) {
|
|
525
|
+
audioBuffer.getChannelData(ch).set(channelData[ch]);
|
|
526
|
+
}
|
|
527
|
+
return audioBuffer;
|
|
528
|
+
});
|
|
529
|
+
decoderQueue = task.catch(() => { });
|
|
530
|
+
return task;
|
|
531
|
+
}
|
|
503
532
|
async createAudioBuffer(voiceParams) {
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
533
|
+
const sample = voiceParams.sample;
|
|
534
|
+
if (sample.type === "compressed") {
|
|
535
|
+
switch (this.decodeMethod) {
|
|
536
|
+
case "decodeAudioData": {
|
|
537
|
+
// https://jakearchibald.com/2016/sounds-fun/
|
|
538
|
+
// https://github.com/WebAudio/web-audio-api/issues/1091
|
|
539
|
+
// decodeAudioData() has priming issues on Safari
|
|
540
|
+
const arrayBuffer = sample.data.slice().buffer;
|
|
541
|
+
return await this.audioContext.decodeAudioData(arrayBuffer);
|
|
542
|
+
}
|
|
543
|
+
case "wasm-audio-decoders":
|
|
544
|
+
return await this.decodeOggVorbis(sample);
|
|
545
|
+
default:
|
|
546
|
+
throw new Error(`Unknown decodeMethod: ${this.decodeMethod}`);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
const data = sample.data;
|
|
551
|
+
const end = data.length + voiceParams.end;
|
|
552
|
+
const subarray = data.subarray(voiceParams.start, end);
|
|
553
|
+
const pcm = sample.decodePCM(subarray);
|
|
554
|
+
const audioBuffer = new AudioBuffer({
|
|
555
|
+
numberOfChannels: 1,
|
|
556
|
+
length: pcm.length,
|
|
557
|
+
sampleRate: sample.sampleHeader.sampleRate,
|
|
558
|
+
});
|
|
559
|
+
audioBuffer.getChannelData(0).set(pcm);
|
|
560
|
+
return audioBuffer;
|
|
561
|
+
}
|
|
508
562
|
}
|
|
509
563
|
createBufferSource(channel, voiceParams, audioBuffer) {
|
|
510
564
|
const bufferSource = new AudioBufferSourceNode(this.audioContext);
|
|
@@ -572,7 +626,7 @@ export class MidyGMLite extends EventTarget {
|
|
|
572
626
|
const channels = this.channels;
|
|
573
627
|
for (let ch = 0; ch < channels.length; ch++) {
|
|
574
628
|
channels[ch].scheduledNotes = [];
|
|
575
|
-
this.resetChannelStates(
|
|
629
|
+
this.resetChannelStates(ch);
|
|
576
630
|
}
|
|
577
631
|
}
|
|
578
632
|
updateStates(queueIndex, nextQueueIndex) {
|
|
@@ -953,7 +1007,7 @@ export class MidyGMLite extends EventTarget {
|
|
|
953
1007
|
const modHold = modAttack + voiceParams.modHold;
|
|
954
1008
|
const decayDuration = voiceParams.modDecay;
|
|
955
1009
|
note.adjustedBaseFreq = adjustedBaseFreq;
|
|
956
|
-
note.
|
|
1010
|
+
note.filterEnvelopeNode.frequency
|
|
957
1011
|
.cancelScheduledValues(scheduleTime)
|
|
958
1012
|
.setValueAtTime(adjustedBaseFreq, startTime)
|
|
959
1013
|
.setValueAtTime(adjustedBaseFreq, modDelay)
|
|
@@ -964,23 +1018,23 @@ export class MidyGMLite extends EventTarget {
|
|
|
964
1018
|
startModulation(channel, note, scheduleTime) {
|
|
965
1019
|
const audioContext = this.audioContext;
|
|
966
1020
|
const { voiceParams } = note;
|
|
967
|
-
note.
|
|
1021
|
+
note.modLfo = new OscillatorNode(audioContext, {
|
|
968
1022
|
frequency: this.centToHz(voiceParams.freqModLFO),
|
|
969
1023
|
});
|
|
970
|
-
note.
|
|
1024
|
+
note.modLfoToFilterFc = new GainNode(audioContext, {
|
|
971
1025
|
gain: voiceParams.modLfoToFilterFc,
|
|
972
1026
|
});
|
|
973
|
-
note.
|
|
1027
|
+
note.modLfoToPitch = new GainNode(audioContext);
|
|
974
1028
|
this.setModLfoToPitch(channel, note, scheduleTime);
|
|
975
|
-
note.
|
|
1029
|
+
note.modLfoToVolume = new GainNode(audioContext);
|
|
976
1030
|
this.setModLfoToVolume(note, scheduleTime);
|
|
977
|
-
note.
|
|
978
|
-
note.
|
|
979
|
-
note.
|
|
980
|
-
note.
|
|
981
|
-
note.
|
|
982
|
-
note.
|
|
983
|
-
note.
|
|
1031
|
+
note.modLfo.start(note.startTime + voiceParams.delayModLFO);
|
|
1032
|
+
note.modLfo.connect(note.modLfoToFilterFc);
|
|
1033
|
+
note.modLfoToFilterFc.connect(note.filterEnvelopeNode.frequency);
|
|
1034
|
+
note.modLfo.connect(note.modLfoToPitch);
|
|
1035
|
+
note.modLfoToPitch.connect(note.bufferSource.detune);
|
|
1036
|
+
note.modLfo.connect(note.modLfoToVolume);
|
|
1037
|
+
note.modLfoToVolume.connect(note.volumeEnvelopeNode.gain);
|
|
984
1038
|
}
|
|
985
1039
|
async getAudioBuffer(channel, noteNumber, velocity, voiceParams, realtime) {
|
|
986
1040
|
const audioBufferId = this.getVoiceId(channel, noteNumber, velocity);
|
|
@@ -1021,7 +1075,7 @@ export class MidyGMLite extends EventTarget {
|
|
|
1021
1075
|
const audioBuffer = await this.getAudioBuffer(channel, noteNumber, velocity, voiceParams, realtime);
|
|
1022
1076
|
note.bufferSource = this.createBufferSource(channel, voiceParams, audioBuffer);
|
|
1023
1077
|
note.volumeEnvelopeNode = new GainNode(audioContext);
|
|
1024
|
-
note.
|
|
1078
|
+
note.filterEnvelopeNode = new BiquadFilterNode(audioContext, {
|
|
1025
1079
|
type: "lowpass",
|
|
1026
1080
|
Q: voiceParams.initialFilterQ / 10, // dB
|
|
1027
1081
|
});
|
|
@@ -1032,8 +1086,8 @@ export class MidyGMLite extends EventTarget {
|
|
|
1032
1086
|
if (0 < state.modulationDepthMSB) {
|
|
1033
1087
|
this.startModulation(channel, note, now);
|
|
1034
1088
|
}
|
|
1035
|
-
note.bufferSource.connect(note.
|
|
1036
|
-
note.
|
|
1089
|
+
note.bufferSource.connect(note.filterEnvelopeNode);
|
|
1090
|
+
note.filterEnvelopeNode.connect(note.volumeEnvelopeNode);
|
|
1037
1091
|
if (voiceParams.sample.type === "compressed") {
|
|
1038
1092
|
const offset = voiceParams.start / audioBuffer.sampleRate;
|
|
1039
1093
|
note.bufferSource.start(startTime, offset);
|
|
@@ -1115,19 +1169,19 @@ export class MidyGMLite extends EventTarget {
|
|
|
1115
1169
|
}
|
|
1116
1170
|
disconnectNote(note) {
|
|
1117
1171
|
note.bufferSource.disconnect();
|
|
1118
|
-
note.
|
|
1172
|
+
note.filterEnvelopeNode.disconnect();
|
|
1119
1173
|
note.volumeEnvelopeNode.disconnect();
|
|
1120
|
-
if (note.
|
|
1121
|
-
note.
|
|
1122
|
-
note.
|
|
1123
|
-
note.
|
|
1174
|
+
if (note.modLfoToPitch) {
|
|
1175
|
+
note.modLfoToVolume.disconnect();
|
|
1176
|
+
note.modLfoToPitch.disconnect();
|
|
1177
|
+
note.modLfo.stop();
|
|
1124
1178
|
}
|
|
1125
1179
|
}
|
|
1126
1180
|
releaseNote(channel, note, endTime) {
|
|
1127
1181
|
endTime ??= this.audioContext.currentTime;
|
|
1128
1182
|
const volDuration = note.voiceParams.volRelease;
|
|
1129
1183
|
const volRelease = endTime + volDuration;
|
|
1130
|
-
note.
|
|
1184
|
+
note.filterEnvelopeNode.frequency
|
|
1131
1185
|
.cancelScheduledValues(endTime)
|
|
1132
1186
|
.setTargetAtTime(note.adjustedBaseFreq, endTime, note.voiceParams.modRelease * releaseCurve);
|
|
1133
1187
|
note.volumeEnvelopeNode.gain
|
|
@@ -1259,12 +1313,12 @@ export class MidyGMLite extends EventTarget {
|
|
|
1259
1313
|
this.applyVoiceParams(channel, 14, scheduleTime);
|
|
1260
1314
|
}
|
|
1261
1315
|
setModLfoToPitch(channel, note, scheduleTime) {
|
|
1262
|
-
if (note.
|
|
1316
|
+
if (note.modLfoToPitch) {
|
|
1263
1317
|
const modLfoToPitch = note.voiceParams.modLfoToPitch;
|
|
1264
1318
|
const baseDepth = Math.abs(modLfoToPitch) +
|
|
1265
1319
|
channel.state.modulationDepthMSB;
|
|
1266
1320
|
const depth = baseDepth * Math.sign(modLfoToPitch);
|
|
1267
|
-
note.
|
|
1321
|
+
note.modLfoToPitch.gain
|
|
1268
1322
|
.cancelScheduledValues(scheduleTime)
|
|
1269
1323
|
.setValueAtTime(depth, scheduleTime);
|
|
1270
1324
|
}
|
|
@@ -1274,29 +1328,29 @@ export class MidyGMLite extends EventTarget {
|
|
|
1274
1328
|
}
|
|
1275
1329
|
setModLfoToFilterFc(note, scheduleTime) {
|
|
1276
1330
|
const modLfoToFilterFc = note.voiceParams.modLfoToFilterFc;
|
|
1277
|
-
note.
|
|
1331
|
+
note.modLfoToFilterFc.gain
|
|
1278
1332
|
.cancelScheduledValues(scheduleTime)
|
|
1279
1333
|
.setValueAtTime(modLfoToFilterFc, scheduleTime);
|
|
1280
1334
|
}
|
|
1281
1335
|
setModLfoToVolume(note, scheduleTime) {
|
|
1282
1336
|
const modLfoToVolume = note.voiceParams.modLfoToVolume;
|
|
1283
1337
|
const baseDepth = cbToRatio(Math.abs(modLfoToVolume)) - 1;
|
|
1284
|
-
const
|
|
1285
|
-
note.
|
|
1338
|
+
const depth = baseDepth * Math.sign(modLfoToVolume);
|
|
1339
|
+
note.modLfoToVolume.gain
|
|
1286
1340
|
.cancelScheduledValues(scheduleTime)
|
|
1287
|
-
.setValueAtTime(
|
|
1341
|
+
.setValueAtTime(depth, scheduleTime);
|
|
1288
1342
|
}
|
|
1289
1343
|
setDelayModLFO(note, scheduleTime) {
|
|
1290
1344
|
const startTime = note.startTime;
|
|
1291
1345
|
if (startTime < scheduleTime)
|
|
1292
1346
|
return;
|
|
1293
|
-
note.
|
|
1294
|
-
note.
|
|
1295
|
-
note.
|
|
1347
|
+
note.modLfo.stop(scheduleTime);
|
|
1348
|
+
note.modLfo.start(startTime + note.voiceParams.delayModLFO);
|
|
1349
|
+
note.modLfo.connect(note.modLfoToFilterFc);
|
|
1296
1350
|
}
|
|
1297
1351
|
setFreqModLFO(note, scheduleTime) {
|
|
1298
1352
|
const freqModLFO = note.voiceParams.freqModLFO;
|
|
1299
|
-
note.
|
|
1353
|
+
note.modLfo.frequency
|
|
1300
1354
|
.cancelScheduledValues(scheduleTime)
|
|
1301
1355
|
.setValueAtTime(freqModLFO, scheduleTime);
|
|
1302
1356
|
}
|
|
@@ -1393,6 +1447,8 @@ export class MidyGMLite extends EventTarget {
|
|
|
1393
1447
|
return handlers;
|
|
1394
1448
|
}
|
|
1395
1449
|
setControlChange(channelNumber, controllerType, value, scheduleTime) {
|
|
1450
|
+
if (!(0 <= scheduleTime))
|
|
1451
|
+
scheduleTime = this.audioContext.currentTime;
|
|
1396
1452
|
const handler = this.controlChangeHandlers[controllerType];
|
|
1397
1453
|
if (handler) {
|
|
1398
1454
|
handler.call(this, channelNumber, value, scheduleTime);
|
|
@@ -1407,8 +1463,8 @@ export class MidyGMLite extends EventTarget {
|
|
|
1407
1463
|
const depth = channel.state.modulationDepthMSB *
|
|
1408
1464
|
channel.modulationDepthRange;
|
|
1409
1465
|
this.processScheduledNotes(channel, (note) => {
|
|
1410
|
-
if (note.
|
|
1411
|
-
note.
|
|
1466
|
+
if (note.modLfoToPitch) {
|
|
1467
|
+
note.modLfoToPitch.gain.setValueAtTime(depth, scheduleTime);
|
|
1412
1468
|
}
|
|
1413
1469
|
else {
|
|
1414
1470
|
this.startModulation(channel, note, scheduleTime);
|
package/esm/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;
|
|
@@ -270,7 +277,6 @@ export class Midy extends EventTarget {
|
|
|
270
277
|
getSoftPedalFactor(channel: any, note: any): number;
|
|
271
278
|
setSoftPedal(channelNumber: any, softPedal: any, scheduleTime: any): void;
|
|
272
279
|
setFilterResonance(channelNumber: any, ccValue: any, scheduleTime: any): void;
|
|
273
|
-
getRelativeKeyBasedValue(channel: any, note: any, controllerType: any): any;
|
|
274
280
|
setReleaseTime(channelNumber: any, releaseTime: any, scheduleTime: any): void;
|
|
275
281
|
setAttackTime(channelNumber: any, attackTime: any, scheduleTime: any): void;
|
|
276
282
|
setBrightness(channelNumber: any, brightness: any, scheduleTime: any): void;
|
|
@@ -340,23 +346,34 @@ export class Midy extends EventTarget {
|
|
|
340
346
|
getChannelBitmap(data: any): any[];
|
|
341
347
|
handleScaleOctaveTuning1ByteFormatSysEx(data: any, realtime: any, scheduleTime: any): void;
|
|
342
348
|
handleScaleOctaveTuning2ByteFormatSysEx(data: any, realtime: any, scheduleTime: any): void;
|
|
349
|
+
calcEffectValue(channel: any, note: any, destination: any): number;
|
|
350
|
+
calcChannelEffectValue(channel: any, destination: any): number;
|
|
351
|
+
calcControlChangeEffectValue(channel: any, destination: any): number;
|
|
352
|
+
calcChannelPressureEffectValue(channel: any, destination: any): number;
|
|
353
|
+
calcNoteEffectValue(channel: any, note: any, destination: any): number;
|
|
354
|
+
getChannelPitchControl(channel: any): number;
|
|
355
|
+
getNotePitchControl(channel: any, note: any): number;
|
|
343
356
|
getPitchControl(channel: any, note: any): number;
|
|
344
357
|
getFilterCutoffControl(channel: any, note: any): number;
|
|
358
|
+
getChannelAmplitudeControl(channel: any): number;
|
|
359
|
+
getNoteAmplitudeControl(channel: any, note: any): number;
|
|
345
360
|
getAmplitudeControl(channel: any, note: any): number;
|
|
346
361
|
getLFOPitchDepth(channel: any, note: any): number;
|
|
347
362
|
getLFOFilterDepth(channel: any, note: any): number;
|
|
348
363
|
getLFOAmplitudeDepth(channel: any, note: any): number;
|
|
349
|
-
|
|
364
|
+
createEffectHandlers(): any[];
|
|
365
|
+
setControlChangeEffects(channel: any, note: any, scheduleTime: any): void;
|
|
366
|
+
setPressureEffects(channel: any, note: any, tableName: any, scheduleTime: any): void;
|
|
350
367
|
handlePressureSysEx(data: any, tableName: any, scheduleTime: any): void;
|
|
351
|
-
initControlTable(): Int8Array<ArrayBuffer>;
|
|
352
|
-
setControlChangeEffects(channel: any, controllerType: any, scheduleTime: any): void;
|
|
353
368
|
handleControlChangeSysEx(data: any, scheduleTime: any): void;
|
|
369
|
+
getRelativeKeyBasedValue(channel: any, keyNumber: any, controllerType: any): any;
|
|
354
370
|
getKeyBasedValue(channel: any, keyNumber: any, controllerType: any): any;
|
|
355
371
|
createKeyBasedControllerHandlers(): any[];
|
|
356
372
|
handleKeyBasedInstrumentControlSysEx(data: any, scheduleTime: any): void;
|
|
357
373
|
handleSysEx(data: any, scheduleTime: any): void;
|
|
358
374
|
scheduleTask(callback: any, scheduleTime: any): Promise<any>;
|
|
359
375
|
}
|
|
376
|
+
import { OggVorbisDecoderWebWorker } from "@wasm-audio-decoders/ogg-vorbis";
|
|
360
377
|
declare class Note {
|
|
361
378
|
constructor(noteNumber: any, velocity: any, startTime: any);
|
|
362
379
|
voice: any;
|
|
@@ -365,14 +382,15 @@ declare class Note {
|
|
|
365
382
|
index: number;
|
|
366
383
|
ending: boolean;
|
|
367
384
|
bufferSource: any;
|
|
368
|
-
|
|
369
|
-
filterDepth: any;
|
|
385
|
+
filterEnvelopeNode: any;
|
|
370
386
|
volumeEnvelopeNode: any;
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
387
|
+
volumeNode: any;
|
|
388
|
+
modLfo: any;
|
|
389
|
+
modLfoToPitch: any;
|
|
390
|
+
modLfoToFilterFc: any;
|
|
391
|
+
modLfoToVolume: any;
|
|
392
|
+
vibLfo: any;
|
|
393
|
+
vibLfoToPitch: any;
|
|
376
394
|
reverbSend: any;
|
|
377
395
|
chorusSend: any;
|
|
378
396
|
portamentoNoteNumber: number;
|
package/esm/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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"}
|