@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-GMLite.js
CHANGED
|
@@ -168,12 +168,14 @@ class MidyGMLite {
|
|
|
168
168
|
addSoundFont(soundFont) {
|
|
169
169
|
const index = this.soundFonts.length;
|
|
170
170
|
this.soundFonts.push(soundFont);
|
|
171
|
-
soundFont.parsed.presetHeaders
|
|
171
|
+
const presetHeaders = soundFont.parsed.presetHeaders;
|
|
172
|
+
for (let i = 0; i < presetHeaders.length; i++) {
|
|
173
|
+
const presetHeader = presetHeaders[i];
|
|
172
174
|
if (!presetHeader.presetName.startsWith("\u0000")) { // TODO: Only SF3 generated by PolyPone?
|
|
173
175
|
const banks = this.soundFontTable[presetHeader.preset];
|
|
174
176
|
banks.set(presetHeader.bank, index);
|
|
175
177
|
}
|
|
176
|
-
}
|
|
178
|
+
}
|
|
177
179
|
}
|
|
178
180
|
async loadSoundFont(soundFontUrl) {
|
|
179
181
|
const response = await fetch(soundFontUrl);
|
|
@@ -218,27 +220,25 @@ class MidyGMLite {
|
|
|
218
220
|
return channels;
|
|
219
221
|
}
|
|
220
222
|
async createNoteBuffer(instrumentKey, isSF3) {
|
|
223
|
+
const sampleStart = instrumentKey.start;
|
|
221
224
|
const sampleEnd = instrumentKey.sample.length + instrumentKey.end;
|
|
222
225
|
if (isSF3) {
|
|
223
|
-
const sample =
|
|
224
|
-
sample.set(instrumentKey.sample);
|
|
226
|
+
const sample = instrumentKey.sample.slice(sampleStart, sampleEnd);
|
|
225
227
|
const audioBuffer = await this.audioContext.decodeAudioData(sample.buffer);
|
|
226
|
-
for (let channel = 0; channel < audioBuffer.numberOfChannels; channel++) {
|
|
227
|
-
const channelData = audioBuffer.getChannelData(channel);
|
|
228
|
-
channelData.set(channelData.subarray(0, sampleEnd));
|
|
229
|
-
}
|
|
230
228
|
return audioBuffer;
|
|
231
229
|
}
|
|
232
230
|
else {
|
|
233
|
-
const sample = instrumentKey.sample.subarray(
|
|
234
|
-
const floatSample = this.convertToFloat32Array(sample);
|
|
231
|
+
const sample = instrumentKey.sample.subarray(sampleStart, sampleEnd);
|
|
235
232
|
const audioBuffer = new AudioBuffer({
|
|
236
233
|
numberOfChannels: 1,
|
|
237
234
|
length: sample.length,
|
|
238
235
|
sampleRate: instrumentKey.sampleRate,
|
|
239
236
|
});
|
|
240
237
|
const channelData = audioBuffer.getChannelData(0);
|
|
241
|
-
|
|
238
|
+
const int16Array = new Int16Array(sample.buffer);
|
|
239
|
+
for (let i = 0; i < int16Array.length; i++) {
|
|
240
|
+
channelData[i] = int16Array[i] / 32768;
|
|
241
|
+
}
|
|
242
242
|
return audioBuffer;
|
|
243
243
|
}
|
|
244
244
|
}
|
|
@@ -254,14 +254,6 @@ class MidyGMLite {
|
|
|
254
254
|
}
|
|
255
255
|
return bufferSource;
|
|
256
256
|
}
|
|
257
|
-
convertToFloat32Array(uint8Array) {
|
|
258
|
-
const int16Array = new Int16Array(uint8Array.buffer);
|
|
259
|
-
const float32Array = new Float32Array(int16Array.length);
|
|
260
|
-
for (let i = 0; i < int16Array.length; i++) {
|
|
261
|
-
float32Array[i] = int16Array[i] / 32768;
|
|
262
|
-
}
|
|
263
|
-
return float32Array;
|
|
264
|
-
}
|
|
265
257
|
async scheduleTimelineEvents(t, offset, queueIndex) {
|
|
266
258
|
while (queueIndex < this.timeline.length) {
|
|
267
259
|
const event = this.timeline[queueIndex];
|
|
@@ -372,9 +364,11 @@ class MidyGMLite {
|
|
|
372
364
|
bank: this.channels[i].bank,
|
|
373
365
|
};
|
|
374
366
|
}
|
|
375
|
-
midi.tracks.
|
|
367
|
+
for (let i = 0; i < midi.tracks.length; i++) {
|
|
368
|
+
const track = midi.tracks[i];
|
|
376
369
|
let currentTicks = 0;
|
|
377
|
-
track.
|
|
370
|
+
for (let j = 0; j < track.length; j++) {
|
|
371
|
+
const event = track[j];
|
|
378
372
|
currentTicks += event.deltaTime;
|
|
379
373
|
event.ticks = currentTicks;
|
|
380
374
|
switch (event.type) {
|
|
@@ -394,8 +388,8 @@ class MidyGMLite {
|
|
|
394
388
|
}
|
|
395
389
|
delete event.deltaTime;
|
|
396
390
|
timeline.push(event);
|
|
397
|
-
}
|
|
398
|
-
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
399
393
|
const priority = {
|
|
400
394
|
controller: 0,
|
|
401
395
|
sysEx: 1,
|
|
@@ -420,7 +414,7 @@ class MidyGMLite {
|
|
|
420
414
|
}
|
|
421
415
|
return { instruments, timeline };
|
|
422
416
|
}
|
|
423
|
-
async stopChannelNotes(channelNumber, velocity,
|
|
417
|
+
async stopChannelNotes(channelNumber, velocity, force) {
|
|
424
418
|
const now = this.audioContext.currentTime;
|
|
425
419
|
const channel = this.channels[channelNumber];
|
|
426
420
|
channel.scheduledNotes.forEach((noteList) => {
|
|
@@ -428,16 +422,16 @@ class MidyGMLite {
|
|
|
428
422
|
const note = noteList[i];
|
|
429
423
|
if (!note)
|
|
430
424
|
continue;
|
|
431
|
-
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now,
|
|
425
|
+
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, force);
|
|
432
426
|
this.notePromises.push(promise);
|
|
433
427
|
}
|
|
434
428
|
});
|
|
435
429
|
channel.scheduledNotes.clear();
|
|
436
430
|
await Promise.all(this.notePromises);
|
|
437
431
|
}
|
|
438
|
-
stopNotes(velocity,
|
|
432
|
+
stopNotes(velocity, force) {
|
|
439
433
|
for (let i = 0; i < this.channels.length; i++) {
|
|
440
|
-
this.stopChannelNotes(i, velocity,
|
|
434
|
+
this.stopChannelNotes(i, velocity, force);
|
|
441
435
|
}
|
|
442
436
|
return Promise.all(this.notePromises);
|
|
443
437
|
}
|
|
@@ -613,7 +607,7 @@ class MidyGMLite {
|
|
|
613
607
|
note.volumeNode = new GainNode(this.audioContext);
|
|
614
608
|
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
615
609
|
type: "lowpass",
|
|
616
|
-
Q: instrumentKey.initialFilterQ / 10
|
|
610
|
+
Q: instrumentKey.initialFilterQ / 10, // dB
|
|
617
611
|
});
|
|
618
612
|
this.setVolumeEnvelope(note);
|
|
619
613
|
this.setFilterEnvelope(note);
|
|
@@ -626,7 +620,7 @@ class MidyGMLite {
|
|
|
626
620
|
}
|
|
627
621
|
note.bufferSource.connect(note.filterNode);
|
|
628
622
|
note.filterNode.connect(note.volumeNode);
|
|
629
|
-
note.bufferSource.start(startTime
|
|
623
|
+
note.bufferSource.start(startTime);
|
|
630
624
|
return note;
|
|
631
625
|
}
|
|
632
626
|
async scheduleNoteOn(channelNumber, noteNumber, velocity, startTime) {
|
|
@@ -655,9 +649,38 @@ class MidyGMLite {
|
|
|
655
649
|
const now = this.audioContext.currentTime;
|
|
656
650
|
return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
|
|
657
651
|
}
|
|
658
|
-
|
|
652
|
+
stopNote(stopTime, endTime, scheduledNotes, index) {
|
|
653
|
+
const note = scheduledNotes[index];
|
|
654
|
+
note.volumeNode.gain
|
|
655
|
+
.cancelScheduledValues(stopTime)
|
|
656
|
+
.linearRampToValueAtTime(0, endTime);
|
|
657
|
+
note.ending = true;
|
|
658
|
+
this.scheduleTask(() => {
|
|
659
|
+
note.bufferSource.loop = false;
|
|
660
|
+
}, endTime);
|
|
661
|
+
return new Promise((resolve) => {
|
|
662
|
+
note.bufferSource.onended = () => {
|
|
663
|
+
scheduledNotes[index] = null;
|
|
664
|
+
note.bufferSource.disconnect();
|
|
665
|
+
note.volumeNode.disconnect();
|
|
666
|
+
note.filterNode.disconnect();
|
|
667
|
+
if (note.modulationDepth) {
|
|
668
|
+
note.volumeDepth.disconnect();
|
|
669
|
+
note.modulationDepth.disconnect();
|
|
670
|
+
note.modulationLFO.stop();
|
|
671
|
+
}
|
|
672
|
+
if (note.vibratoDepth) {
|
|
673
|
+
note.vibratoDepth.disconnect();
|
|
674
|
+
note.vibratoLFO.stop();
|
|
675
|
+
}
|
|
676
|
+
resolve();
|
|
677
|
+
};
|
|
678
|
+
note.bufferSource.stop(endTime);
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, force) {
|
|
659
682
|
const channel = this.channels[channelNumber];
|
|
660
|
-
if (
|
|
683
|
+
if (!force && channel.sustainPedal)
|
|
661
684
|
return;
|
|
662
685
|
if (!channel.scheduledNotes.has(noteNumber))
|
|
663
686
|
return;
|
|
@@ -669,32 +692,11 @@ class MidyGMLite {
|
|
|
669
692
|
if (note.ending)
|
|
670
693
|
continue;
|
|
671
694
|
const volEndTime = stopTime + note.instrumentKey.volRelease;
|
|
672
|
-
note.volumeNode.gain
|
|
673
|
-
.cancelScheduledValues(stopTime)
|
|
674
|
-
.linearRampToValueAtTime(0, volEndTime);
|
|
675
695
|
const modRelease = stopTime + note.instrumentKey.modRelease;
|
|
676
696
|
note.filterNode.frequency
|
|
677
697
|
.cancelScheduledValues(stopTime)
|
|
678
698
|
.linearRampToValueAtTime(0, modRelease);
|
|
679
|
-
|
|
680
|
-
this.scheduleTask(() => {
|
|
681
|
-
note.bufferSource.loop = false;
|
|
682
|
-
}, stopTime);
|
|
683
|
-
return new Promise((resolve) => {
|
|
684
|
-
note.bufferSource.onended = () => {
|
|
685
|
-
scheduledNotes[i] = null;
|
|
686
|
-
note.bufferSource.disconnect();
|
|
687
|
-
note.volumeNode.disconnect();
|
|
688
|
-
note.filterNode.disconnect();
|
|
689
|
-
if (note.modulationDepth) {
|
|
690
|
-
note.volumeDepth.disconnect();
|
|
691
|
-
note.modulationDepth.disconnect();
|
|
692
|
-
note.modulationLFO.stop();
|
|
693
|
-
}
|
|
694
|
-
resolve();
|
|
695
|
-
};
|
|
696
|
-
note.bufferSource.stop(volEndTime);
|
|
697
|
-
});
|
|
699
|
+
this.stopNote(stopTime, volEndTime, scheduledNotes, i);
|
|
698
700
|
}
|
|
699
701
|
}
|
|
700
702
|
releaseNote(channelNumber, noteNumber, velocity) {
|
|
@@ -803,7 +805,7 @@ class MidyGMLite {
|
|
|
803
805
|
setVolume(channelNumber, volume) {
|
|
804
806
|
const channel = this.channels[channelNumber];
|
|
805
807
|
channel.volume = volume / 127;
|
|
806
|
-
this.
|
|
808
|
+
this.updateChannelVolume(channel);
|
|
807
809
|
}
|
|
808
810
|
panToGain(pan) {
|
|
809
811
|
const theta = Math.PI / 2 * Math.max(0, pan - 1) / 126;
|
|
@@ -815,18 +817,18 @@ class MidyGMLite {
|
|
|
815
817
|
setPan(channelNumber, pan) {
|
|
816
818
|
const channel = this.channels[channelNumber];
|
|
817
819
|
channel.pan = pan;
|
|
818
|
-
this.
|
|
820
|
+
this.updateChannelVolume(channel);
|
|
819
821
|
}
|
|
820
822
|
setExpression(channelNumber, expression) {
|
|
821
823
|
const channel = this.channels[channelNumber];
|
|
822
824
|
channel.expression = expression / 127;
|
|
823
|
-
this.
|
|
825
|
+
this.updateChannelVolume(channel);
|
|
824
826
|
}
|
|
825
827
|
dataEntryLSB(channelNumber, value) {
|
|
826
828
|
this.channels[channelNumber].dataLSB = value;
|
|
827
829
|
this.handleRPN(channelNumber);
|
|
828
830
|
}
|
|
829
|
-
|
|
831
|
+
updateChannelVolume(channel) {
|
|
830
832
|
const now = this.audioContext.currentTime;
|
|
831
833
|
const volume = channel.volume * channel.expression;
|
|
832
834
|
const { gainLeft, gainRight } = this.panToGain(channel.pan);
|
|
@@ -921,11 +923,12 @@ class MidyGMLite {
|
|
|
921
923
|
}
|
|
922
924
|
}
|
|
923
925
|
GM1SystemOn() {
|
|
924
|
-
this.channels.
|
|
926
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
927
|
+
const channel = this.channels[i];
|
|
925
928
|
channel.bankMSB = 0;
|
|
926
929
|
channel.bankLSB = 0;
|
|
927
930
|
channel.bank = 0;
|
|
928
|
-
}
|
|
931
|
+
}
|
|
929
932
|
this.channels[9].bankMSB = 1;
|
|
930
933
|
this.channels[9].bank = 128;
|
|
931
934
|
}
|
package/script/midy.d.ts
CHANGED
|
@@ -159,7 +159,7 @@ export class Midy {
|
|
|
159
159
|
createChannels(audioContext: any): any[];
|
|
160
160
|
createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
|
|
161
161
|
createNoteBufferNode(instrumentKey: any, isSF3: any): Promise<any>;
|
|
162
|
-
|
|
162
|
+
findPortamentoTarget(queueIndex: any): any;
|
|
163
163
|
scheduleTimelineEvents(t: any, offset: any, queueIndex: any): Promise<any>;
|
|
164
164
|
getQueueIndex(second: any): number;
|
|
165
165
|
playNotes(): Promise<any>;
|
|
@@ -169,8 +169,8 @@ export class Midy {
|
|
|
169
169
|
instruments: Set<any>;
|
|
170
170
|
timeline: any[];
|
|
171
171
|
};
|
|
172
|
-
stopChannelNotes(channelNumber: any, velocity: any,
|
|
173
|
-
stopNotes(velocity: any,
|
|
172
|
+
stopChannelNotes(channelNumber: any, velocity: any, force: any): Promise<void>;
|
|
173
|
+
stopNotes(velocity: any, force: any): Promise<any[]>;
|
|
174
174
|
start(): Promise<void>;
|
|
175
175
|
stop(): void;
|
|
176
176
|
pause(): void;
|
|
@@ -206,18 +206,21 @@ export class Midy {
|
|
|
206
206
|
centToHz(cent: any): number;
|
|
207
207
|
calcSemitoneOffset(channel: any): any;
|
|
208
208
|
calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
|
|
209
|
+
setPortamentoStartVolumeEnvelope(channel: any, note: any): void;
|
|
209
210
|
setVolumeEnvelope(channel: any, note: any): void;
|
|
210
211
|
setPitch(note: any, semitoneOffset: any): void;
|
|
211
212
|
clampCutoffFrequency(frequency: any): number;
|
|
213
|
+
setPortamentoStartFilterEnvelope(channel: any, note: any): void;
|
|
212
214
|
setFilterEnvelope(channel: any, note: any): void;
|
|
213
215
|
startModulation(channel: any, note: any, startTime: any): void;
|
|
214
216
|
startVibrato(channel: any, note: any, startTime: any): void;
|
|
215
|
-
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
217
|
+
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, portamento: any, isSF3: any): Promise<Note>;
|
|
216
218
|
calcBank(channel: any, channelNumber: any): any;
|
|
217
|
-
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
218
|
-
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
219
|
-
|
|
220
|
-
|
|
219
|
+
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any, portamento: any): Promise<void>;
|
|
220
|
+
noteOn(channelNumber: any, noteNumber: any, velocity: any, portamento: any): Promise<void>;
|
|
221
|
+
stopNote(stopTime: any, endTime: any, scheduledNotes: any, index: any): Promise<any>;
|
|
222
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, portamentoNoteNumber: any, force: any): Promise<any> | undefined;
|
|
223
|
+
releaseNote(channelNumber: any, noteNumber: any, velocity: any, portamentoNoteNumber: any): Promise<any> | undefined;
|
|
221
224
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
222
225
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
|
|
223
226
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
|
|
@@ -276,7 +279,7 @@ export class Midy {
|
|
|
276
279
|
setExpression(channelNumber: any, expression: any): void;
|
|
277
280
|
setBankLSB(channelNumber: any, lsb: any): void;
|
|
278
281
|
dataEntryLSB(channelNumber: any, value: any): void;
|
|
279
|
-
|
|
282
|
+
updateChannelVolume(channel: any): void;
|
|
280
283
|
setSustainPedal(channelNumber: any, value: any): void;
|
|
281
284
|
setPortamento(channelNumber: any, value: any): void;
|
|
282
285
|
setReverbSendLevel(channelNumber: any, reverbSendLevel: any): void;
|
package/script/midy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAwBA;IAkCE;;;;;;;;;;;;;;;;;;;;;;;;;MAyBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAgCF;;;;;OAYC;IA5HD,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;IAmDlB;;;;;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.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}
|