@marmooo/midy 0.1.5 → 0.1.6
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 +7 -7
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +62 -59
- package/esm/midy-GM2.d.ts +12 -9
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +156 -79
- package/esm/midy-GMLite.d.ts +7 -7
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +62 -59
- package/esm/midy.d.ts +12 -9
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +156 -83
- package/package.json +1 -1
- package/script/midy-GM1.d.ts +7 -7
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +62 -59
- package/script/midy-GM2.d.ts +12 -9
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +156 -79
- package/script/midy-GMLite.d.ts +7 -7
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +62 -59
- package/script/midy.d.ts +12 -9
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +156 -83
package/script/midy-GM1.js
CHANGED
|
@@ -180,12 +180,14 @@ class MidyGM1 {
|
|
|
180
180
|
addSoundFont(soundFont) {
|
|
181
181
|
const index = this.soundFonts.length;
|
|
182
182
|
this.soundFonts.push(soundFont);
|
|
183
|
-
soundFont.parsed.presetHeaders
|
|
183
|
+
const presetHeaders = soundFont.parsed.presetHeaders;
|
|
184
|
+
for (let i = 0; i < presetHeaders.length; i++) {
|
|
185
|
+
const presetHeader = presetHeaders[i];
|
|
184
186
|
if (!presetHeader.presetName.startsWith("\u0000")) { // TODO: Only SF3 generated by PolyPone?
|
|
185
187
|
const banks = this.soundFontTable[presetHeader.preset];
|
|
186
188
|
banks.set(presetHeader.bank, index);
|
|
187
189
|
}
|
|
188
|
-
}
|
|
190
|
+
}
|
|
189
191
|
}
|
|
190
192
|
async loadSoundFont(soundFontUrl) {
|
|
191
193
|
const response = await fetch(soundFontUrl);
|
|
@@ -230,27 +232,25 @@ class MidyGM1 {
|
|
|
230
232
|
return channels;
|
|
231
233
|
}
|
|
232
234
|
async createNoteBuffer(instrumentKey, isSF3) {
|
|
235
|
+
const sampleStart = instrumentKey.start;
|
|
233
236
|
const sampleEnd = instrumentKey.sample.length + instrumentKey.end;
|
|
234
237
|
if (isSF3) {
|
|
235
|
-
const sample =
|
|
236
|
-
sample.set(instrumentKey.sample);
|
|
238
|
+
const sample = instrumentKey.sample.slice(sampleStart, sampleEnd);
|
|
237
239
|
const audioBuffer = await this.audioContext.decodeAudioData(sample.buffer);
|
|
238
|
-
for (let channel = 0; channel < audioBuffer.numberOfChannels; channel++) {
|
|
239
|
-
const channelData = audioBuffer.getChannelData(channel);
|
|
240
|
-
channelData.set(channelData.subarray(0, sampleEnd));
|
|
241
|
-
}
|
|
242
240
|
return audioBuffer;
|
|
243
241
|
}
|
|
244
242
|
else {
|
|
245
|
-
const sample = instrumentKey.sample.subarray(
|
|
246
|
-
const floatSample = this.convertToFloat32Array(sample);
|
|
243
|
+
const sample = instrumentKey.sample.subarray(sampleStart, sampleEnd);
|
|
247
244
|
const audioBuffer = new AudioBuffer({
|
|
248
245
|
numberOfChannels: 1,
|
|
249
246
|
length: sample.length,
|
|
250
247
|
sampleRate: instrumentKey.sampleRate,
|
|
251
248
|
});
|
|
252
249
|
const channelData = audioBuffer.getChannelData(0);
|
|
253
|
-
|
|
250
|
+
const int16Array = new Int16Array(sample.buffer);
|
|
251
|
+
for (let i = 0; i < int16Array.length; i++) {
|
|
252
|
+
channelData[i] = int16Array[i] / 32768;
|
|
253
|
+
}
|
|
254
254
|
return audioBuffer;
|
|
255
255
|
}
|
|
256
256
|
}
|
|
@@ -266,14 +266,6 @@ class MidyGM1 {
|
|
|
266
266
|
}
|
|
267
267
|
return bufferSource;
|
|
268
268
|
}
|
|
269
|
-
convertToFloat32Array(uint8Array) {
|
|
270
|
-
const int16Array = new Int16Array(uint8Array.buffer);
|
|
271
|
-
const float32Array = new Float32Array(int16Array.length);
|
|
272
|
-
for (let i = 0; i < int16Array.length; i++) {
|
|
273
|
-
float32Array[i] = int16Array[i] / 32768;
|
|
274
|
-
}
|
|
275
|
-
return float32Array;
|
|
276
|
-
}
|
|
277
269
|
async scheduleTimelineEvents(t, offset, queueIndex) {
|
|
278
270
|
while (queueIndex < this.timeline.length) {
|
|
279
271
|
const event = this.timeline[queueIndex];
|
|
@@ -384,9 +376,11 @@ class MidyGM1 {
|
|
|
384
376
|
bank: this.channels[i].bank,
|
|
385
377
|
};
|
|
386
378
|
}
|
|
387
|
-
midi.tracks.
|
|
379
|
+
for (let i = 0; i < midi.tracks.length; i++) {
|
|
380
|
+
const track = midi.tracks[i];
|
|
388
381
|
let currentTicks = 0;
|
|
389
|
-
track.
|
|
382
|
+
for (let j = 0; j < track.length; j++) {
|
|
383
|
+
const event = track[j];
|
|
390
384
|
currentTicks += event.deltaTime;
|
|
391
385
|
event.ticks = currentTicks;
|
|
392
386
|
switch (event.type) {
|
|
@@ -406,8 +400,8 @@ class MidyGM1 {
|
|
|
406
400
|
}
|
|
407
401
|
delete event.deltaTime;
|
|
408
402
|
timeline.push(event);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
411
405
|
const priority = {
|
|
412
406
|
controller: 0,
|
|
413
407
|
sysEx: 1,
|
|
@@ -432,7 +426,7 @@ class MidyGM1 {
|
|
|
432
426
|
}
|
|
433
427
|
return { instruments, timeline };
|
|
434
428
|
}
|
|
435
|
-
async stopChannelNotes(channelNumber, velocity,
|
|
429
|
+
async stopChannelNotes(channelNumber, velocity, force) {
|
|
436
430
|
const now = this.audioContext.currentTime;
|
|
437
431
|
const channel = this.channels[channelNumber];
|
|
438
432
|
channel.scheduledNotes.forEach((noteList) => {
|
|
@@ -440,16 +434,16 @@ class MidyGM1 {
|
|
|
440
434
|
const note = noteList[i];
|
|
441
435
|
if (!note)
|
|
442
436
|
continue;
|
|
443
|
-
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now,
|
|
437
|
+
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, force);
|
|
444
438
|
this.notePromises.push(promise);
|
|
445
439
|
}
|
|
446
440
|
});
|
|
447
441
|
channel.scheduledNotes.clear();
|
|
448
442
|
await Promise.all(this.notePromises);
|
|
449
443
|
}
|
|
450
|
-
stopNotes(velocity,
|
|
444
|
+
stopNotes(velocity, force) {
|
|
451
445
|
for (let i = 0; i < this.channels.length; i++) {
|
|
452
|
-
this.stopChannelNotes(i, velocity,
|
|
446
|
+
this.stopChannelNotes(i, velocity, force);
|
|
453
447
|
}
|
|
454
448
|
return Promise.all(this.notePromises);
|
|
455
449
|
}
|
|
@@ -626,7 +620,7 @@ class MidyGM1 {
|
|
|
626
620
|
note.volumeNode = new GainNode(this.audioContext);
|
|
627
621
|
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
628
622
|
type: "lowpass",
|
|
629
|
-
Q: instrumentKey.initialFilterQ / 10
|
|
623
|
+
Q: instrumentKey.initialFilterQ / 10, // dB
|
|
630
624
|
});
|
|
631
625
|
this.setVolumeEnvelope(note);
|
|
632
626
|
this.setFilterEnvelope(note);
|
|
@@ -639,7 +633,7 @@ class MidyGM1 {
|
|
|
639
633
|
}
|
|
640
634
|
note.bufferSource.connect(note.filterNode);
|
|
641
635
|
note.filterNode.connect(note.volumeNode);
|
|
642
|
-
note.bufferSource.start(startTime
|
|
636
|
+
note.bufferSource.start(startTime);
|
|
643
637
|
return note;
|
|
644
638
|
}
|
|
645
639
|
async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime) {
|
|
@@ -668,9 +662,38 @@ class MidyGM1 {
|
|
|
668
662
|
const now = this.audioContext.currentTime;
|
|
669
663
|
return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
|
|
670
664
|
}
|
|
671
|
-
|
|
665
|
+
stopNote(stopTime, endTime, scheduledNotes, index) {
|
|
666
|
+
const note = scheduledNotes[index];
|
|
667
|
+
note.volumeNode.gain
|
|
668
|
+
.cancelScheduledValues(stopTime)
|
|
669
|
+
.linearRampToValueAtTime(0, endTime);
|
|
670
|
+
note.ending = true;
|
|
671
|
+
this.scheduleTask(() => {
|
|
672
|
+
note.bufferSource.loop = false;
|
|
673
|
+
}, endTime);
|
|
674
|
+
return new Promise((resolve) => {
|
|
675
|
+
note.bufferSource.onended = () => {
|
|
676
|
+
scheduledNotes[index] = null;
|
|
677
|
+
note.bufferSource.disconnect();
|
|
678
|
+
note.volumeNode.disconnect();
|
|
679
|
+
note.filterNode.disconnect();
|
|
680
|
+
if (note.modulationDepth) {
|
|
681
|
+
note.volumeDepth.disconnect();
|
|
682
|
+
note.modulationDepth.disconnect();
|
|
683
|
+
note.modulationLFO.stop();
|
|
684
|
+
}
|
|
685
|
+
if (note.vibratoDepth) {
|
|
686
|
+
note.vibratoDepth.disconnect();
|
|
687
|
+
note.vibratoLFO.stop();
|
|
688
|
+
}
|
|
689
|
+
resolve();
|
|
690
|
+
};
|
|
691
|
+
note.bufferSource.stop(endTime);
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, force) {
|
|
672
695
|
const channel = this.channels[channelNumber];
|
|
673
|
-
if (
|
|
696
|
+
if (!force && channel.sustainPedal)
|
|
674
697
|
return;
|
|
675
698
|
if (!channel.scheduledNotes.has(noteNumber))
|
|
676
699
|
return;
|
|
@@ -682,32 +705,11 @@ class MidyGM1 {
|
|
|
682
705
|
if (note.ending)
|
|
683
706
|
continue;
|
|
684
707
|
const volEndTime = stopTime + note.instrumentKey.volRelease;
|
|
685
|
-
note.volumeNode.gain
|
|
686
|
-
.cancelScheduledValues(stopTime)
|
|
687
|
-
.linearRampToValueAtTime(0, volEndTime);
|
|
688
708
|
const modRelease = stopTime + note.instrumentKey.modRelease;
|
|
689
709
|
note.filterNode.frequency
|
|
690
710
|
.cancelScheduledValues(stopTime)
|
|
691
711
|
.linearRampToValueAtTime(0, modRelease);
|
|
692
|
-
|
|
693
|
-
this.scheduleTask(() => {
|
|
694
|
-
note.bufferSource.loop = false;
|
|
695
|
-
}, stopTime);
|
|
696
|
-
return new Promise((resolve) => {
|
|
697
|
-
note.bufferSource.onended = () => {
|
|
698
|
-
scheduledNotes[i] = null;
|
|
699
|
-
note.bufferSource.disconnect();
|
|
700
|
-
note.volumeNode.disconnect();
|
|
701
|
-
note.filterNode.disconnect();
|
|
702
|
-
if (note.modulationDepth) {
|
|
703
|
-
note.volumeDepth.disconnect();
|
|
704
|
-
note.modulationDepth.disconnect();
|
|
705
|
-
note.modulationLFO.stop();
|
|
706
|
-
}
|
|
707
|
-
resolve();
|
|
708
|
-
};
|
|
709
|
-
note.bufferSource.stop(volEndTime);
|
|
710
|
-
});
|
|
712
|
+
this.stopNote(stopTime, volEndTime, scheduledNotes, i);
|
|
711
713
|
}
|
|
712
714
|
}
|
|
713
715
|
releaseNote(channelNumber, noteNumber, velocity) {
|
|
@@ -816,7 +818,7 @@ class MidyGM1 {
|
|
|
816
818
|
setVolume(channelNumber, volume) {
|
|
817
819
|
const channel = this.channels[channelNumber];
|
|
818
820
|
channel.volume = volume / 127;
|
|
819
|
-
this.
|
|
821
|
+
this.updateChannelVolume(channel);
|
|
820
822
|
}
|
|
821
823
|
panToGain(pan) {
|
|
822
824
|
const theta = Math.PI / 2 * Math.max(0, pan - 1) / 126;
|
|
@@ -828,18 +830,18 @@ class MidyGM1 {
|
|
|
828
830
|
setPan(channelNumber, pan) {
|
|
829
831
|
const channel = this.channels[channelNumber];
|
|
830
832
|
channel.pan = pan;
|
|
831
|
-
this.
|
|
833
|
+
this.updateChannelVolume(channel);
|
|
832
834
|
}
|
|
833
835
|
setExpression(channelNumber, expression) {
|
|
834
836
|
const channel = this.channels[channelNumber];
|
|
835
837
|
channel.expression = expression / 127;
|
|
836
|
-
this.
|
|
838
|
+
this.updateChannelVolume(channel);
|
|
837
839
|
}
|
|
838
840
|
dataEntryLSB(channelNumber, value) {
|
|
839
841
|
this.channels[channelNumber].dataLSB = value;
|
|
840
842
|
this.handleRPN(channelNumber, 0);
|
|
841
843
|
}
|
|
842
|
-
|
|
844
|
+
updateChannelVolume(channel) {
|
|
843
845
|
const now = this.audioContext.currentTime;
|
|
844
846
|
const volume = channel.volume * channel.expression;
|
|
845
847
|
const { gainLeft, gainRight } = this.panToGain(channel.pan);
|
|
@@ -992,11 +994,12 @@ class MidyGM1 {
|
|
|
992
994
|
}
|
|
993
995
|
}
|
|
994
996
|
GM1SystemOn() {
|
|
995
|
-
this.channels.
|
|
997
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
998
|
+
const channel = this.channels[i];
|
|
996
999
|
channel.bankMSB = 0;
|
|
997
1000
|
channel.bankLSB = 0;
|
|
998
1001
|
channel.bank = 0;
|
|
999
|
-
}
|
|
1002
|
+
}
|
|
1000
1003
|
this.channels[9].bankMSB = 1;
|
|
1001
1004
|
this.channels[9].bank = 128;
|
|
1002
1005
|
}
|
package/script/midy-GM2.d.ts
CHANGED
|
@@ -144,7 +144,7 @@ export class MidyGM2 {
|
|
|
144
144
|
createChannels(audioContext: any): any[];
|
|
145
145
|
createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
|
|
146
146
|
createNoteBufferNode(instrumentKey: any, isSF3: any): Promise<any>;
|
|
147
|
-
|
|
147
|
+
findPortamentoTarget(queueIndex: any): any;
|
|
148
148
|
scheduleTimelineEvents(t: any, offset: any, queueIndex: any): Promise<any>;
|
|
149
149
|
getQueueIndex(second: any): number;
|
|
150
150
|
playNotes(): Promise<any>;
|
|
@@ -154,8 +154,8 @@ export class MidyGM2 {
|
|
|
154
154
|
instruments: Set<any>;
|
|
155
155
|
timeline: any[];
|
|
156
156
|
};
|
|
157
|
-
stopChannelNotes(channelNumber: any, velocity: any,
|
|
158
|
-
stopNotes(velocity: any,
|
|
157
|
+
stopChannelNotes(channelNumber: any, velocity: any, force: any): Promise<void>;
|
|
158
|
+
stopNotes(velocity: any, force: any): Promise<any[]>;
|
|
159
159
|
start(): Promise<void>;
|
|
160
160
|
stop(): void;
|
|
161
161
|
pause(): void;
|
|
@@ -191,18 +191,21 @@ export class MidyGM2 {
|
|
|
191
191
|
centToHz(cent: any): number;
|
|
192
192
|
calcSemitoneOffset(channel: any): any;
|
|
193
193
|
calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
|
|
194
|
+
setPortamentoStartVolumeEnvelope(channel: any, note: any): void;
|
|
194
195
|
setVolumeEnvelope(note: any): void;
|
|
195
196
|
setPitch(note: any, semitoneOffset: any): void;
|
|
196
197
|
clampCutoffFrequency(frequency: any): number;
|
|
198
|
+
setPortamentoStartFilterEnvelope(channel: any, note: any): void;
|
|
197
199
|
setFilterEnvelope(channel: any, note: any): void;
|
|
198
200
|
startModulation(channel: any, note: any, startTime: any): void;
|
|
199
201
|
startVibrato(channel: any, note: any, startTime: any): void;
|
|
200
|
-
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
202
|
+
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, portamento: any, isSF3: any): Promise<Note>;
|
|
201
203
|
calcBank(channel: any, channelNumber: any): any;
|
|
202
|
-
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
203
|
-
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
204
|
-
|
|
205
|
-
|
|
204
|
+
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any, portamento: any): Promise<void>;
|
|
205
|
+
noteOn(channelNumber: any, noteNumber: any, velocity: any, portamento: any): Promise<void>;
|
|
206
|
+
stopNote(stopTime: any, endTime: any, scheduledNotes: any, index: any): Promise<any>;
|
|
207
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, portamentoNoteNumber: any, force: any): Promise<any> | undefined;
|
|
208
|
+
releaseNote(channelNumber: any, noteNumber: any, velocity: any, portamentoNoteNumber: any): Promise<any> | undefined;
|
|
206
209
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
207
210
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
|
|
208
211
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
|
|
@@ -250,7 +253,7 @@ export class MidyGM2 {
|
|
|
250
253
|
setExpression(channelNumber: any, expression: any): void;
|
|
251
254
|
setBankLSB(channelNumber: any, lsb: any): void;
|
|
252
255
|
dataEntryLSB(channelNumber: any, value: any): void;
|
|
253
|
-
|
|
256
|
+
updateChannelVolume(channel: any): void;
|
|
254
257
|
setSustainPedal(channelNumber: any, value: any): void;
|
|
255
258
|
setPortamento(channelNumber: any, value: any): void;
|
|
256
259
|
setReverbSendLevel(channelNumber: any, reverbSendLevel: any): void;
|
package/script/midy-GM2.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"AAwBA;IAkCE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAgCF;;;;;OAYC;IAvHD,qBAAmB;IACnB,kBAAc;IACd,yBAAqB;IACrB,2BAAuB;IACvB;;;MAGE;IACF;;;;;;MAME;IACF,cAAa;IACb,cAAa;IACb,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IA8ClB;;;;;MA4BE;IAGA,kBAAgC;IAChC;;;;;MAAqD;IACrD,gBAA4C;IAC5C;;;;;;;;;;;;;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IACjD;;;MAA8D;IAC9D;;;;;;;;MAAyD;IAO3D,4BAMC;IAED,
|
|
1
|
+
{"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"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"}
|