@marmooo/midy 0.4.0 → 0.4.1
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 +2 -1
- package/esm/midy-GM1.d.ts +3 -3
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +43 -30
- package/esm/midy-GM2.d.ts +3 -3
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +49 -36
- package/esm/midy-GMLite.d.ts +3 -3
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +35 -23
- package/esm/midy.d.ts +10 -8
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +122 -52
- package/package.json +2 -2
- package/script/midy-GM1.d.ts +3 -3
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +43 -30
- package/script/midy-GM2.d.ts +3 -3
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +49 -36
- package/script/midy-GMLite.d.ts +3 -3
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +35 -23
- package/script/midy.d.ts +10 -8
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +122 -52
package/script/midy-GM1.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AA6FA;IA0BE;;;;;;;;;;;MAWE;IAEF,+BAeC;IArDD,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,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IAgBnC,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,sBAoCC;IAED,8DAWC;IAED;;;;MAeC;IAED,yCAaC;IAED,
|
|
1
|
+
{"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AA6FA;IA0BE;;;;;;;;;;;MAWE;IAEF,+BAeC;IArDD,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,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IAgBnC,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,sBAoCC;IAED,8DAWC;IAED;;;;MAeC;IAED,yCAaC;IAED,kDASC;IAED,4DASC;IAED,yEAoDC;IAED,mCAOC;IAED,uBASC;IAED,yDA2BC;IAED,2BA8CC;IAED,uDAEC;IAED,wDAEC;IAED,qCAKC;IAED;;;MAwDC;IAED,kGAeC;IAED,mGAeC;IAED,wEAMC;IAED,uBAMC;IAED,sBAKC;IAED,uBAQC;IAED,wBAKC;IAED,0BAKC;IAED,wBAOC;IAED,sBAIC;IAED,yDAQC;IAED,yEASC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAMC;IAED,2DAIC;IAED,+DAIC;IAED,sDAeC;IAED,qDAoBC;IAED,6CAIC;IAED,sDAsBC;IAED,kEAoBC;IAED,4GAkCC;IAED,uEAwCC;IAED,0EAiBC;IAED,oEASC;IAED,0FAwBC;IAED,gCASC;IAED,iEAqBC;IAED,gHAqBC;IAED,6CAUC;IAED,qDAUC;IAED,4GAeC;IAED,+BAmBC;IAED,kDAOC;IAED,sGA2BC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAYC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;MAiCC;IAED,oFAMC;IAED,6EA2BC;IAED,qCAeC;IAED,+FAWC;IAED,wDAUC;IAED,iFAKC;IAED,oEAKC;IAED;;;MAMC;IAED,8DAKC;IAED,4EAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAWC;IAED,kFAeC;IAED,2DAMC;IAED,uDAkBC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,iEAMC;IAED,uEAQC;IAED,mEAKC;IAED,yEAQC;IAED,gFAGC;IAED,6CAqBC;IAGD,8EAgCC;IAED,gFAGC;IAED,+EAgBC;IAED,qCASC;IAED,4EAaC;IAED,4DAGC;IAED,qDAKC;IAED,gDAYC;IAGD,6DAgBC;CACF"}
|
package/script/midy-GM1.js
CHANGED
|
@@ -89,11 +89,11 @@ const defaultControllerState = {
|
|
|
89
89
|
pitchWheel: { type: 14, defaultValue: 8192 / 16383 },
|
|
90
90
|
pitchWheelSensitivity: { type: 16, defaultValue: 2 / 128 },
|
|
91
91
|
link: { type: 127, defaultValue: 0 },
|
|
92
|
-
|
|
92
|
+
modulationDepthMSB: { type: 128 + 1, defaultValue: 0 },
|
|
93
93
|
// dataMSB: { type: 128 + 6, defaultValue: 0, },
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
volumeMSB: { type: 128 + 7, defaultValue: 100 / 127 },
|
|
95
|
+
panMSB: { type: 128 + 10, defaultValue: 64 / 127 },
|
|
96
|
+
expressionMSB: { type: 128 + 11, defaultValue: 1 },
|
|
97
97
|
// dataLSB: { type: 128 + 38, defaultValue: 0, },
|
|
98
98
|
sustainPedal: { type: 128 + 64, defaultValue: 0 },
|
|
99
99
|
// rpnLSB: { type: 128 + 100, defaultValue: 127 },
|
|
@@ -413,7 +413,7 @@ class MidyGM1 {
|
|
|
413
413
|
return soundFontIndex * (2 ** 32) + (instrument << 16) + sampleID;
|
|
414
414
|
}
|
|
415
415
|
createChannelAudioNodes(audioContext) {
|
|
416
|
-
const { gainLeft, gainRight } = this.panToGain(defaultControllerState.
|
|
416
|
+
const { gainLeft, gainRight } = this.panToGain(defaultControllerState.panMSB.defaultValue);
|
|
417
417
|
const gainL = new GainNode(audioContext, { gain: gainLeft });
|
|
418
418
|
const gainR = new GainNode(audioContext, { gain: gainRight });
|
|
419
419
|
const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
|
|
@@ -441,10 +441,9 @@ class MidyGM1 {
|
|
|
441
441
|
return channels;
|
|
442
442
|
}
|
|
443
443
|
async createAudioBuffer(voiceParams) {
|
|
444
|
-
const sample = voiceParams
|
|
445
|
-
const
|
|
446
|
-
const
|
|
447
|
-
const audioBuffer = await sample.toAudioBuffer(this.audioContext, sampleStart, sampleEnd);
|
|
444
|
+
const { sample, start, end } = voiceParams;
|
|
445
|
+
const sampleEnd = sample.data.length + end;
|
|
446
|
+
const audioBuffer = await sample.toAudioBuffer(this.audioContext, start, sampleEnd);
|
|
448
447
|
return audioBuffer;
|
|
449
448
|
}
|
|
450
449
|
createBufferSource(voiceParams, audioBuffer) {
|
|
@@ -472,9 +471,7 @@ class MidyGM1 {
|
|
|
472
471
|
await this.noteOn(event.channel, event.noteNumber, event.velocity, startTime);
|
|
473
472
|
break;
|
|
474
473
|
case "noteOff": {
|
|
475
|
-
|
|
476
|
-
if (notePromise)
|
|
477
|
-
this.notePromises.push(notePromise);
|
|
474
|
+
this.noteOff(event.channel, event.noteNumber, event.velocity, startTime, false);
|
|
478
475
|
break;
|
|
479
476
|
}
|
|
480
477
|
case "controller":
|
|
@@ -568,6 +565,12 @@ class MidyGM1 {
|
|
|
568
565
|
const waitTime = now + this.noteCheckInterval;
|
|
569
566
|
await this.scheduleTask(() => { }, waitTime);
|
|
570
567
|
}
|
|
568
|
+
if (this.timeline.length <= queueIndex) {
|
|
569
|
+
const now = this.audioContext.currentTime;
|
|
570
|
+
await this.stopNotes(0, true, now);
|
|
571
|
+
await this.audioContext.suspend();
|
|
572
|
+
finished = true;
|
|
573
|
+
}
|
|
571
574
|
if (finished) {
|
|
572
575
|
this.notePromises = [];
|
|
573
576
|
this.resetAllStates();
|
|
@@ -907,7 +910,13 @@ class MidyGM1 {
|
|
|
907
910
|
}
|
|
908
911
|
note.bufferSource.connect(note.filterNode);
|
|
909
912
|
note.filterNode.connect(note.volumeEnvelopeNode);
|
|
910
|
-
|
|
913
|
+
if (voiceParams.sample.type === "compressed") {
|
|
914
|
+
const offset = voiceParams.start / audioBuffer.sampleRate;
|
|
915
|
+
note.bufferSource.start(startTime, offset);
|
|
916
|
+
}
|
|
917
|
+
else {
|
|
918
|
+
note.bufferSource.start(startTime);
|
|
919
|
+
}
|
|
911
920
|
return note;
|
|
912
921
|
}
|
|
913
922
|
handleExclusiveClass(note, channelNumber, startTime) {
|
|
@@ -1009,7 +1018,9 @@ class MidyGM1 {
|
|
|
1009
1018
|
}
|
|
1010
1019
|
note.ending = true;
|
|
1011
1020
|
this.setNoteIndex(channel, index);
|
|
1012
|
-
this.releaseNote(channel, note, endTime);
|
|
1021
|
+
const promise = this.releaseNote(channel, note, endTime);
|
|
1022
|
+
this.notePromises.push(promise);
|
|
1023
|
+
return promise;
|
|
1013
1024
|
}
|
|
1014
1025
|
setNoteIndex(channel, index) {
|
|
1015
1026
|
let allEnds = true;
|
|
@@ -1107,11 +1118,12 @@ class MidyGM1 {
|
|
|
1107
1118
|
setModLfoToPitch(channel, note, scheduleTime) {
|
|
1108
1119
|
if (note.modulationDepth) {
|
|
1109
1120
|
const modLfoToPitch = note.voiceParams.modLfoToPitch;
|
|
1110
|
-
const baseDepth = Math.abs(modLfoToPitch) +
|
|
1111
|
-
|
|
1121
|
+
const baseDepth = Math.abs(modLfoToPitch) +
|
|
1122
|
+
channel.state.modulationDepthMSB;
|
|
1123
|
+
const depth = baseDepth * Math.sign(modLfoToPitch);
|
|
1112
1124
|
note.modulationDepth.gain
|
|
1113
1125
|
.cancelScheduledValues(scheduleTime)
|
|
1114
|
-
.setValueAtTime(
|
|
1126
|
+
.setValueAtTime(depth, scheduleTime);
|
|
1115
1127
|
}
|
|
1116
1128
|
else {
|
|
1117
1129
|
this.startModulation(channel, note, scheduleTime);
|
|
@@ -1148,18 +1160,18 @@ class MidyGM1 {
|
|
|
1148
1160
|
createVoiceParamsHandlers() {
|
|
1149
1161
|
return {
|
|
1150
1162
|
modLfoToPitch: (channel, note, scheduleTime) => {
|
|
1151
|
-
if (0 < channel.state.
|
|
1163
|
+
if (0 < channel.state.modulationDepthMSB) {
|
|
1152
1164
|
this.setModLfoToPitch(channel, note, scheduleTime);
|
|
1153
1165
|
}
|
|
1154
1166
|
},
|
|
1155
1167
|
vibLfoToPitch: (_channel, _note, _scheduleTime) => { },
|
|
1156
1168
|
modLfoToFilterFc: (channel, note, scheduleTime) => {
|
|
1157
|
-
if (0 < channel.state.
|
|
1169
|
+
if (0 < channel.state.modulationDepthMSB) {
|
|
1158
1170
|
this.setModLfoToFilterFc(note, scheduleTime);
|
|
1159
1171
|
}
|
|
1160
1172
|
},
|
|
1161
1173
|
modLfoToVolume: (channel, note, scheduleTime) => {
|
|
1162
|
-
if (0 < channel.state.
|
|
1174
|
+
if (0 < channel.state.modulationDepthMSB) {
|
|
1163
1175
|
this.setModLfoToVolume(note, scheduleTime);
|
|
1164
1176
|
}
|
|
1165
1177
|
},
|
|
@@ -1171,7 +1183,7 @@ class MidyGM1 {
|
|
|
1171
1183
|
}
|
|
1172
1184
|
},
|
|
1173
1185
|
freqModLFO: (_channel, note, scheduleTime) => {
|
|
1174
|
-
if (0 < channel.state.
|
|
1186
|
+
if (0 < channel.state.modulationDepthMSB) {
|
|
1175
1187
|
this.setFreqModLFO(note, scheduleTime);
|
|
1176
1188
|
}
|
|
1177
1189
|
},
|
|
@@ -1246,7 +1258,8 @@ class MidyGM1 {
|
|
|
1246
1258
|
}
|
|
1247
1259
|
}
|
|
1248
1260
|
updateModulation(channel, scheduleTime) {
|
|
1249
|
-
const depth = channel.state.
|
|
1261
|
+
const depth = channel.state.modulationDepthMSB *
|
|
1262
|
+
channel.modulationDepthRange;
|
|
1250
1263
|
this.processScheduledNotes(channel, (note) => {
|
|
1251
1264
|
if (note.modulationDepth) {
|
|
1252
1265
|
note.modulationDepth.gain.setValueAtTime(depth, scheduleTime);
|
|
@@ -1259,13 +1272,13 @@ class MidyGM1 {
|
|
|
1259
1272
|
setModulationDepth(channelNumber, modulation, scheduleTime) {
|
|
1260
1273
|
const channel = this.channels[channelNumber];
|
|
1261
1274
|
scheduleTime ??= this.audioContext.currentTime;
|
|
1262
|
-
channel.state.
|
|
1275
|
+
channel.state.modulationDepthMSB = modulation / 127;
|
|
1263
1276
|
this.updateModulation(channel, scheduleTime);
|
|
1264
1277
|
}
|
|
1265
1278
|
setVolume(channelNumber, volume, scheduleTime) {
|
|
1266
1279
|
scheduleTime ??= this.audioContext.currentTime;
|
|
1267
1280
|
const channel = this.channels[channelNumber];
|
|
1268
|
-
channel.state.
|
|
1281
|
+
channel.state.volumeMSB = volume / 127;
|
|
1269
1282
|
this.updateChannelVolume(channel, scheduleTime);
|
|
1270
1283
|
}
|
|
1271
1284
|
panToGain(pan) {
|
|
@@ -1278,13 +1291,13 @@ class MidyGM1 {
|
|
|
1278
1291
|
setPan(channelNumber, pan, scheduleTime) {
|
|
1279
1292
|
scheduleTime ??= this.audioContext.currentTime;
|
|
1280
1293
|
const channel = this.channels[channelNumber];
|
|
1281
|
-
channel.state.
|
|
1294
|
+
channel.state.panMSB = pan / 127;
|
|
1282
1295
|
this.updateChannelVolume(channel, scheduleTime);
|
|
1283
1296
|
}
|
|
1284
1297
|
setExpression(channelNumber, expression, scheduleTime) {
|
|
1285
1298
|
scheduleTime ??= this.audioContext.currentTime;
|
|
1286
1299
|
const channel = this.channels[channelNumber];
|
|
1287
|
-
channel.state.
|
|
1300
|
+
channel.state.expressionMSB = expression / 127;
|
|
1288
1301
|
this.updateChannelVolume(channel, scheduleTime);
|
|
1289
1302
|
}
|
|
1290
1303
|
dataEntryLSB(channelNumber, value, scheduleTime) {
|
|
@@ -1293,8 +1306,8 @@ class MidyGM1 {
|
|
|
1293
1306
|
}
|
|
1294
1307
|
updateChannelVolume(channel, scheduleTime) {
|
|
1295
1308
|
const state = channel.state;
|
|
1296
|
-
const volume = state.
|
|
1297
|
-
const { gainLeft, gainRight } = this.panToGain(state.
|
|
1309
|
+
const volume = state.volumeMSB * state.expressionMSB;
|
|
1310
|
+
const { gainLeft, gainRight } = this.panToGain(state.panMSB);
|
|
1298
1311
|
channel.gainL.gain
|
|
1299
1312
|
.cancelScheduledValues(scheduleTime)
|
|
1300
1313
|
.setValueAtTime(volume * gainLeft, scheduleTime);
|
|
@@ -1442,8 +1455,8 @@ class MidyGM1 {
|
|
|
1442
1455
|
resetAllControllers(channelNumber, _value, scheduleTime) {
|
|
1443
1456
|
const keys = [
|
|
1444
1457
|
"pitchWheel",
|
|
1445
|
-
"
|
|
1446
|
-
"
|
|
1458
|
+
"expressionMSB",
|
|
1459
|
+
"modulationDepthMSB",
|
|
1447
1460
|
"sustainPedal",
|
|
1448
1461
|
];
|
|
1449
1462
|
const channel = this.channels[channelNumber];
|
package/script/midy-GM2.d.ts
CHANGED
|
@@ -182,11 +182,11 @@ export class MidyGM2 {
|
|
|
182
182
|
noteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
183
183
|
disconnectNote(note: any): void;
|
|
184
184
|
releaseNote(channel: any, note: any, endTime: any): Promise<any>;
|
|
185
|
-
noteOff(channelNumber: any, noteNumber: any, velocity: any, endTime: any, force: any):
|
|
185
|
+
noteOff(channelNumber: any, noteNumber: any, velocity: any, endTime: any, force: any): Promise<any> | undefined;
|
|
186
186
|
setNoteIndex(channel: any, index: any): void;
|
|
187
187
|
findNoteOffIndex(channel: any, noteNumber: any): any;
|
|
188
|
-
releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any):
|
|
189
|
-
releaseSostenutoPedal(channelNumber: any, halfVelocity: any, scheduleTime: any):
|
|
188
|
+
releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): (Promise<any> | undefined)[];
|
|
189
|
+
releaseSostenutoPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): (Promise<any> | undefined)[];
|
|
190
190
|
createMessageHandlers(): any[];
|
|
191
191
|
handleMessage(data: any, scheduleTime: any): void;
|
|
192
192
|
activeSensing(): 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":"AAmJA;IA6CE;;;;;;;;;;;;;;MAcE;IAEF,+BAoBC;IAhFD,aAAa;IACb,yBAAqB;IACrB,2BAAuB;IACvB;;;;MAIE;IACF;;;;;;MAME;IACF,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAsB;IACtB,+BAA6B;IAC7B,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,0BAAuD;IACvD,4BAAyB;IACzB,0BAAuB;IACvB,kCAA+B;IAC/B,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IACrC,+BAEE;IAmBA,kBAAgC;IAChC,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF,uBAAmD;IACnD;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,kCAAyE;IACzE,gBAAiD;IACjD;;;kBAAyD;IACzD;;;;;;;;MAAyD;IAQ3D,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCASC;IAED,sBAoCC;IAED,8DAYC;IAED;;;;MAeC;IAED,sCAKC;IAED,yCAqBC;IAED,
|
|
1
|
+
{"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"AAmJA;IA6CE;;;;;;;;;;;;;;MAcE;IAEF,+BAoBC;IAhFD,aAAa;IACb,yBAAqB;IACrB,2BAAuB;IACvB;;;;MAIE;IACF;;;;;;MAME;IACF,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAsB;IACtB,+BAA6B;IAC7B,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,0BAAuD;IACvD,4BAAyB;IACzB,0BAAuB;IACvB,kCAA+B;IAC/B,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IACrC,+BAEE;IAmBA,kBAAgC;IAChC,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF,uBAAmD;IACnD;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,kCAAyE;IACzE,gBAAiD;IACjD;;;kBAAyD;IACzD;;;;;;;;MAAyD;IAQ3D,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCASC;IAED,sBAoCC;IAED,8DAYC;IAED;;;;MAeC;IAED,sCAKC;IAED,yCAqBC;IAED,kDASC;IAED,mDAIC;IAED,2FAWC;IAED,yEAuDC;IAED,mCAOC;IAED,uBASC;IAED,yDA2BC;IAED,2BAwDC;IAED,uDAEC;IAED,wDAEC;IAED,qCAMC;IAED;;;MAqFC;IAED,kGAeC;IAED,mGAeC;IAED,wEAMC;IAED,uBAMC;IAED,sBAKC;IAED,uBAQC;IAED,wBAKC;IAED,0BAKC;IAED,wBAOC;IAED,sBAIC;IAED,yDAQC;IAED,yEASC;IAED,kFAuBC;IAED;;;;MASC;IAED,gFAUC;IAED,mFAYC;IAED,sGAcC;IAID;;;MA8BC;IAED;;;kBA6BC;IAED;;;;;;;;MA0CC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAkBC;IAED,6CAEC;IAED,2DAIC;IAED,+DAgBC;IAED,mDAIC;IAED,2CAoDC;IAED,8EAWC;IAED,oEAgBC;IAED,+DAKC;IAED,qDAoBC;IAED,6CAIC;IAED,8EAoBC;IAED,oEAwBC;IAED,kEAoBC;IAED,+DAeC;IAED,4GAkCC;IAED,uEAgEC;IAED,0EAiBC;IAED,8EAoBC;IAED,oEAuBC;IAED,0FAyBC;IAED,gCAmBC;IAED,iEAqBC;IAED,gHA6BC;IAED,6CAUC;IAED,qDAUC;IAED,4GAeC;IAED,8GAkBC;IAED,+BAuBC;IAED,kDAOC;IAED,sBAEC;IAED,mFAcC;IAED,4EAgBC;IAED,wFAGC;IAED,sEAWC;IAED,mEAaC;IAED,mEAYC;IAED,sEAMC;IAED,oEAQC;IAED,gEAyBC;IAED,gEAyBC;IAED,gCAKC;IAED,kDAKC;IAED,gEAMC;IAED,8CAOC;IAED;;;;;;;;;;;MAiDC;IAED,oFAOC;IAED,6EA+BC;IAED,qCA2BC;IAED,+FAYC;IAED,+CAEC;IAED,wDAUC;IAED,iFAMC;IAED,wDAeC;IAED,oFAMC;IAED,oEAWC;IAED;;;MAMC;IAED,8DAWC;IAED,4EAKC;IAED,+CAEC;IAED,sEAGC;IAED,2DAUC;IAED,4EAoBC;IAED,yEAYC;IAED,+CAEC;IAED,uEAMC;IAED,2EAcC;IAED,oDAEC;IAED,0EAeC;IAED,sFAQC;IAED,sFAQC;IAED,kFAeC;IAED,2DAMC;IAED,uDAqBC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAWC;IAED,iEAMC;IAED,uEASC;IAED,mEAKC;IAED,yEASC;IAED,2EAKC;IAED,iFAMC;IAED,gFAGC;IAED,6CAwBC;IAGD,8EAoCC;IAED,gFAGC;IAED,iEAEC;IAED,gEAEC;IAED,gEAIC;IAED,gEAIC;IAED,+EAgCC;IAED,qCAYC;IAED,qCAYC;IAED,4EA4CC;IAED,4DAGC;IAED,qDAKC;IAED,gEAIC;IAED,yDAWC;IAED,kEAGC;IAED,2DAWC;IAED,sEAeC;IAED,4CAOC;IAED,+BAIC;IAED,qDAiBC;IAED,gCAGC;IAED,kCAEC;IA6BD,4CAEC;IAED,+DAaC;IAED,kDAiBC;IAED,2GAKC;IAED,sDAIC;IAED,qCAEC;IAED,uDAMC;IAED,sCAEC;IAED,uDASC;IAED,sCAEC;IAED,2DAqBC;IAED,0CAEC;IAED,mCAeC;IAED,2FAgBC;IAED,6CAMC;IAED,0CAMC;IAED,uCAMC;IAED,wCAMC;IAED,2CAMC;IAED,yEAgBC;IAED,wEAaC;IAED,2CAIC;IAED,oFAOC;IAED,6DAcC;IAED,yEAIC;IAED,0CAmBC;IAED,yEAcC;IAED,gDAYC;IAGD,6DAgBC;CACF"}
|
package/script/midy-GM2.js
CHANGED
|
@@ -154,12 +154,12 @@ const defaultControllerState = {
|
|
|
154
154
|
pitchWheelSensitivity: { type: 16, defaultValue: 2 / 128 },
|
|
155
155
|
link: { type: 127, defaultValue: 0 },
|
|
156
156
|
// bankMSB: { type: 128 + 0, defaultValue: 121, },
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
modulationDepthMSB: { type: 128 + 1, defaultValue: 0 },
|
|
158
|
+
portamentoTimeMSB: { type: 128 + 5, defaultValue: 0 },
|
|
159
159
|
// dataMSB: { type: 128 + 6, defaultValue: 0, },
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
volumeMSB: { type: 128 + 7, defaultValue: 100 / 127 },
|
|
161
|
+
panMSB: { type: 128 + 10, defaultValue: 64 / 127 },
|
|
162
|
+
expressionMSB: { type: 128 + 11, defaultValue: 1 },
|
|
163
163
|
// bankLSB: { type: 128 + 32, defaultValue: 0, },
|
|
164
164
|
// dataLSB: { type: 128 + 38, defaultValue: 0, },
|
|
165
165
|
sustainPedal: { type: 128 + 64, defaultValue: 0 },
|
|
@@ -549,7 +549,7 @@ class MidyGM2 {
|
|
|
549
549
|
return soundFontIndex * (2 ** 32) + (instrument << 16) + sampleID;
|
|
550
550
|
}
|
|
551
551
|
createChannelAudioNodes(audioContext) {
|
|
552
|
-
const { gainLeft, gainRight } = this.panToGain(defaultControllerState.
|
|
552
|
+
const { gainLeft, gainRight } = this.panToGain(defaultControllerState.panMSB.defaultValue);
|
|
553
553
|
const gainL = new GainNode(audioContext, { gain: gainLeft });
|
|
554
554
|
const gainR = new GainNode(audioContext, { gain: gainRight });
|
|
555
555
|
const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
|
|
@@ -590,10 +590,9 @@ class MidyGM2 {
|
|
|
590
590
|
return channels;
|
|
591
591
|
}
|
|
592
592
|
async createAudioBuffer(voiceParams) {
|
|
593
|
-
const sample = voiceParams
|
|
594
|
-
const
|
|
595
|
-
const
|
|
596
|
-
const audioBuffer = await sample.toAudioBuffer(this.audioContext, sampleStart, sampleEnd);
|
|
593
|
+
const { sample, start, end } = voiceParams;
|
|
594
|
+
const sampleEnd = sample.data.length + end;
|
|
595
|
+
const audioBuffer = await sample.toAudioBuffer(this.audioContext, start, sampleEnd);
|
|
597
596
|
return audioBuffer;
|
|
598
597
|
}
|
|
599
598
|
isLoopDrum(channel, noteNumber) {
|
|
@@ -628,9 +627,7 @@ class MidyGM2 {
|
|
|
628
627
|
await this.noteOn(event.channel, event.noteNumber, event.velocity, startTime);
|
|
629
628
|
break;
|
|
630
629
|
case "noteOff": {
|
|
631
|
-
|
|
632
|
-
if (notePromise)
|
|
633
|
-
this.notePromises.push(notePromise);
|
|
630
|
+
this.noteOff(event.channel, event.noteNumber, event.velocity, startTime, false);
|
|
634
631
|
break;
|
|
635
632
|
}
|
|
636
633
|
case "controller":
|
|
@@ -734,6 +731,12 @@ class MidyGM2 {
|
|
|
734
731
|
const waitTime = now + this.noteCheckInterval;
|
|
735
732
|
await this.scheduleTask(() => { }, waitTime);
|
|
736
733
|
}
|
|
734
|
+
if (this.timeline.length <= queueIndex) {
|
|
735
|
+
const now = this.audioContext.currentTime;
|
|
736
|
+
await this.stopNotes(0, true, now);
|
|
737
|
+
await this.audioContext.suspend();
|
|
738
|
+
finished = true;
|
|
739
|
+
}
|
|
737
740
|
if (finished) {
|
|
738
741
|
this.notePromises = [];
|
|
739
742
|
this.resetAllStates();
|
|
@@ -1142,7 +1145,7 @@ class MidyGM2 {
|
|
|
1142
1145
|
}
|
|
1143
1146
|
getPortamentoTime(channel, note) {
|
|
1144
1147
|
const deltaSemitone = Math.abs(note.noteNumber - note.portamentoNoteNumber);
|
|
1145
|
-
const value = Math.ceil(channel.state.
|
|
1148
|
+
const value = Math.ceil(channel.state.portamentoTimeMSB * 127);
|
|
1146
1149
|
return deltaSemitone / this.getPitchIncrementSpeed(value) / 10;
|
|
1147
1150
|
}
|
|
1148
1151
|
getPitchIncrementSpeed(value) {
|
|
@@ -1401,7 +1404,7 @@ class MidyGM2 {
|
|
|
1401
1404
|
if (0 < state.vibratoDepth) {
|
|
1402
1405
|
this.startVibrato(channel, note, now);
|
|
1403
1406
|
}
|
|
1404
|
-
if (0 < state.
|
|
1407
|
+
if (0 < state.modulationDepthMSB) {
|
|
1405
1408
|
this.startModulation(channel, note, now);
|
|
1406
1409
|
}
|
|
1407
1410
|
if (channel.mono && channel.currentBufferSource) {
|
|
@@ -1412,7 +1415,13 @@ class MidyGM2 {
|
|
|
1412
1415
|
note.filterNode.connect(note.volumeEnvelopeNode);
|
|
1413
1416
|
this.setChorusSend(channel, note, now);
|
|
1414
1417
|
this.setReverbSend(channel, note, now);
|
|
1415
|
-
|
|
1418
|
+
if (voiceParams.sample.type === "compressed") {
|
|
1419
|
+
const offset = voiceParams.start / audioBuffer.sampleRate;
|
|
1420
|
+
note.bufferSource.start(startTime, offset);
|
|
1421
|
+
}
|
|
1422
|
+
else {
|
|
1423
|
+
note.bufferSource.start(startTime);
|
|
1424
|
+
}
|
|
1416
1425
|
return note;
|
|
1417
1426
|
}
|
|
1418
1427
|
handleExclusiveClass(note, channelNumber, startTime) {
|
|
@@ -1570,7 +1579,9 @@ class MidyGM2 {
|
|
|
1570
1579
|
}
|
|
1571
1580
|
note.ending = true;
|
|
1572
1581
|
this.setNoteIndex(channel, index);
|
|
1573
|
-
this.releaseNote(channel, note, endTime);
|
|
1582
|
+
const promise = this.releaseNote(channel, note, endTime);
|
|
1583
|
+
this.notePromises.push(promise);
|
|
1584
|
+
return promise;
|
|
1574
1585
|
}
|
|
1575
1586
|
setNoteIndex(channel, index) {
|
|
1576
1587
|
let allEnds = true;
|
|
@@ -1702,7 +1713,8 @@ class MidyGM2 {
|
|
|
1702
1713
|
if (note.modulationDepth) {
|
|
1703
1714
|
const modLfoToPitch = note.voiceParams.modLfoToPitch +
|
|
1704
1715
|
this.getLFOPitchDepth(channel, note);
|
|
1705
|
-
const baseDepth = Math.abs(modLfoToPitch) +
|
|
1716
|
+
const baseDepth = Math.abs(modLfoToPitch) +
|
|
1717
|
+
channel.state.modulationDepthMSB;
|
|
1706
1718
|
const depth = baseDepth * Math.sign(modLfoToPitch);
|
|
1707
1719
|
note.modulationDepth.gain
|
|
1708
1720
|
.cancelScheduledValues(scheduleTime)
|
|
@@ -1834,7 +1846,7 @@ class MidyGM2 {
|
|
|
1834
1846
|
createVoiceParamsHandlers() {
|
|
1835
1847
|
return {
|
|
1836
1848
|
modLfoToPitch: (channel, note, scheduleTime) => {
|
|
1837
|
-
if (0 < channel.state.
|
|
1849
|
+
if (0 < channel.state.modulationDepthMSB) {
|
|
1838
1850
|
this.setModLfoToPitch(channel, note, scheduleTime);
|
|
1839
1851
|
}
|
|
1840
1852
|
},
|
|
@@ -1844,12 +1856,12 @@ class MidyGM2 {
|
|
|
1844
1856
|
}
|
|
1845
1857
|
},
|
|
1846
1858
|
modLfoToFilterFc: (channel, note, scheduleTime) => {
|
|
1847
|
-
if (0 < channel.state.
|
|
1859
|
+
if (0 < channel.state.modulationDepthMSB) {
|
|
1848
1860
|
this.setModLfoToFilterFc(channel, note, scheduleTime);
|
|
1849
1861
|
}
|
|
1850
1862
|
},
|
|
1851
1863
|
modLfoToVolume: (channel, note, scheduleTime) => {
|
|
1852
|
-
if (0 < channel.state.
|
|
1864
|
+
if (0 < channel.state.modulationDepthMSB) {
|
|
1853
1865
|
this.setModLfoToVolume(channel, note, scheduleTime);
|
|
1854
1866
|
}
|
|
1855
1867
|
},
|
|
@@ -1860,12 +1872,12 @@ class MidyGM2 {
|
|
|
1860
1872
|
this.setReverbSend(channel, note, scheduleTime);
|
|
1861
1873
|
},
|
|
1862
1874
|
delayModLFO: (_channel, note, _scheduleTime) => {
|
|
1863
|
-
if (0 < channel.state.
|
|
1875
|
+
if (0 < channel.state.modulationDepthMSB) {
|
|
1864
1876
|
this.setDelayModLFO(note);
|
|
1865
1877
|
}
|
|
1866
1878
|
},
|
|
1867
1879
|
freqModLFO: (_channel, note, scheduleTime) => {
|
|
1868
|
-
if (0 < channel.state.
|
|
1880
|
+
if (0 < channel.state.modulationDepthMSB) {
|
|
1869
1881
|
this.setFreqModLFO(note, scheduleTime);
|
|
1870
1882
|
}
|
|
1871
1883
|
},
|
|
@@ -1967,7 +1979,8 @@ class MidyGM2 {
|
|
|
1967
1979
|
this.channels[channelNumber].bankMSB = msb;
|
|
1968
1980
|
}
|
|
1969
1981
|
updateModulation(channel, scheduleTime) {
|
|
1970
|
-
const depth = channel.state.
|
|
1982
|
+
const depth = channel.state.modulationDepthMSB *
|
|
1983
|
+
channel.modulationDepthRange;
|
|
1971
1984
|
this.processScheduledNotes(channel, (note) => {
|
|
1972
1985
|
if (note.modulationDepth) {
|
|
1973
1986
|
note.modulationDepth.gain.setValueAtTime(depth, scheduleTime);
|
|
@@ -1982,7 +1995,7 @@ class MidyGM2 {
|
|
|
1982
1995
|
if (channel.isDrum)
|
|
1983
1996
|
return;
|
|
1984
1997
|
scheduleTime ??= this.audioContext.currentTime;
|
|
1985
|
-
channel.state.
|
|
1998
|
+
channel.state.modulationDepthMSB = modulation / 127;
|
|
1986
1999
|
this.updateModulation(channel, scheduleTime);
|
|
1987
2000
|
}
|
|
1988
2001
|
updatePortamento(channel, scheduleTime) {
|
|
@@ -2004,9 +2017,9 @@ class MidyGM2 {
|
|
|
2004
2017
|
});
|
|
2005
2018
|
}
|
|
2006
2019
|
setPortamentoTime(channelNumber, portamentoTime, scheduleTime) {
|
|
2007
|
-
const channel = this.channels[channelNumber];
|
|
2008
2020
|
scheduleTime ??= this.audioContext.currentTime;
|
|
2009
|
-
channel
|
|
2021
|
+
const channel = this.channels[channelNumber];
|
|
2022
|
+
channel.state.portamentoTimeMSB = portamentoTime / 127;
|
|
2010
2023
|
if (channel.isDrum)
|
|
2011
2024
|
return;
|
|
2012
2025
|
this.updatePortamento(channel, scheduleTime);
|
|
@@ -2014,7 +2027,7 @@ class MidyGM2 {
|
|
|
2014
2027
|
setVolume(channelNumber, volume, scheduleTime) {
|
|
2015
2028
|
scheduleTime ??= this.audioContext.currentTime;
|
|
2016
2029
|
const channel = this.channels[channelNumber];
|
|
2017
|
-
channel.state.
|
|
2030
|
+
channel.state.volumeMSB = volume / 127;
|
|
2018
2031
|
if (channel.isDrum) {
|
|
2019
2032
|
for (let i = 0; i < 128; i++) {
|
|
2020
2033
|
this.updateKeyBasedVolume(channel, i, scheduleTime);
|
|
@@ -2034,7 +2047,7 @@ class MidyGM2 {
|
|
|
2034
2047
|
setPan(channelNumber, pan, scheduleTime) {
|
|
2035
2048
|
scheduleTime ??= this.audioContext.currentTime;
|
|
2036
2049
|
const channel = this.channels[channelNumber];
|
|
2037
|
-
channel.state.
|
|
2050
|
+
channel.state.panMSB = pan / 127;
|
|
2038
2051
|
if (channel.isDrum) {
|
|
2039
2052
|
for (let i = 0; i < 128; i++) {
|
|
2040
2053
|
this.updateKeyBasedVolume(channel, i, scheduleTime);
|
|
@@ -2047,7 +2060,7 @@ class MidyGM2 {
|
|
|
2047
2060
|
setExpression(channelNumber, expression, scheduleTime) {
|
|
2048
2061
|
scheduleTime ??= this.audioContext.currentTime;
|
|
2049
2062
|
const channel = this.channels[channelNumber];
|
|
2050
|
-
channel.state.
|
|
2063
|
+
channel.state.expressionMSB = expression / 127;
|
|
2051
2064
|
this.updateChannelVolume(channel, scheduleTime);
|
|
2052
2065
|
}
|
|
2053
2066
|
setBankLSB(channelNumber, lsb) {
|
|
@@ -2059,8 +2072,8 @@ class MidyGM2 {
|
|
|
2059
2072
|
}
|
|
2060
2073
|
updateChannelVolume(channel, scheduleTime) {
|
|
2061
2074
|
const state = channel.state;
|
|
2062
|
-
const volume = state.
|
|
2063
|
-
const { gainLeft, gainRight } = this.panToGain(state.
|
|
2075
|
+
const volume = state.volumeMSB * state.expressionMSB;
|
|
2076
|
+
const { gainLeft, gainRight } = this.panToGain(state.panMSB);
|
|
2064
2077
|
channel.gainL.gain
|
|
2065
2078
|
.cancelScheduledValues(scheduleTime)
|
|
2066
2079
|
.setValueAtTime(volume * gainLeft, scheduleTime);
|
|
@@ -2074,8 +2087,8 @@ class MidyGM2 {
|
|
|
2074
2087
|
return;
|
|
2075
2088
|
const gainR = channel.keyBasedGainRs[keyNumber];
|
|
2076
2089
|
const state = channel.state;
|
|
2077
|
-
const defaultVolume = state.
|
|
2078
|
-
const defaultPan = state.
|
|
2090
|
+
const defaultVolume = state.volumeMSB * state.expressionMSB;
|
|
2091
|
+
const defaultPan = state.panMSB;
|
|
2079
2092
|
const keyBasedVolume = this.getKeyBasedValue(channel, keyNumber, 7);
|
|
2080
2093
|
const volume = (0 <= keyBasedVolume)
|
|
2081
2094
|
? defaultVolume * keyBasedVolume / 64
|
|
@@ -2326,8 +2339,8 @@ class MidyGM2 {
|
|
|
2326
2339
|
const keys = [
|
|
2327
2340
|
"channelPressure",
|
|
2328
2341
|
"pitchWheel",
|
|
2329
|
-
"
|
|
2330
|
-
"
|
|
2342
|
+
"expressionMSB",
|
|
2343
|
+
"modulationDepthMSB",
|
|
2331
2344
|
"sustainPedal",
|
|
2332
2345
|
"portamento",
|
|
2333
2346
|
"sostenutoPedal",
|
package/script/midy-GMLite.d.ts
CHANGED
|
@@ -112,13 +112,13 @@ export class MidyGMLite {
|
|
|
112
112
|
noteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
113
113
|
disconnectNote(note: any): void;
|
|
114
114
|
releaseNote(channel: any, note: any, endTime: any): Promise<any>;
|
|
115
|
-
noteOff(channelNumber: any, noteNumber: any, velocity: any, endTime: any, force: any):
|
|
115
|
+
noteOff(channelNumber: any, noteNumber: any, velocity: any, endTime: any, force: any): Promise<any> | undefined;
|
|
116
116
|
setNoteIndex(channel: any, index: any): void;
|
|
117
117
|
findNoteOffIndex(channel: any, noteNumber: any): any;
|
|
118
|
-
releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any):
|
|
118
|
+
releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): (Promise<any> | undefined)[];
|
|
119
119
|
createMessageHandlers(): any[];
|
|
120
120
|
handleMessage(data: any, scheduleTime: any): void;
|
|
121
|
-
handleChannelMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): void | Promise<
|
|
121
|
+
handleChannelMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): void | Promise<any>;
|
|
122
122
|
setProgramChange(channelNumber: any, programNumber: any, _scheduleTime: any): void;
|
|
123
123
|
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any, scheduleTime: any): void;
|
|
124
124
|
setPitchBend(channelNumber: any, value: any, scheduleTime: any): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AA2GA;IA6BE;;;;;;;;;MASE;IAEF,+BAeC;IAtDD,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,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IACrC,+BAEE;IAcA,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,sBAoCC;IAED,8DAWC;IAED;;;;MAeC;IAED,yCAaC;IAED,
|
|
1
|
+
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AA2GA;IA6BE;;;;;;;;;MASE;IAEF,+BAeC;IAtDD,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,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IACrC,+BAEE;IAcA,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,sBAoCC;IAED,8DAWC;IAED;;;;MAeC;IAED,yCAaC;IAED,kDASC;IAED,0EAUC;IAED,yEAoDC;IAED,mCAOC;IAED,uBASC;IAED,yDA2BC;IAED,2BA8CC;IAED,uDAEC;IAED,wDAEC;IAED,qCAKC;IAED;;;MAwDC;IAED,kGAeC;IAED,mGAeC;IAED,wEAMC;IAED,uBAMC;IAED,sBAKC;IAED,uBAQC;IAED,wBAKC;IAED,0BAKC;IAED,wBAOC;IAED,sBAIC;IAED,yDAQC;IAED,yEASC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,wCAIC;IAED,2DAIC;IAED,+DAIC;IAED,sDAeC;IAED,qDAoBC;IAED,6CAIC;IAED,sDAsBC;IAED,kEAoBC;IAED,4GAkCC;IAED,uEA4CC;IAED,0EAiBC;IAED,8EAiBC;IAED,oEAUC;IAED,0FAwBC;IAED,gCASC;IAED,iEAqBC;IAED,gHAwBC;IAED,6CAUC;IAED,qDAUC;IAED,4GAeC;IAED,+BAmBC;IAED,kDAOC;IAED,sGA2BC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAYC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;MAiCC;IAED,oFAMC;IAED,6EA2BC;IAED,qCAeC;IAED,+FAWC;IAED,wDASC;IAED,iFAKC;IAED,oEAKC;IAED;;;MAMC;IAED,8DAKC;IAED,4EAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAWC;IAED,kFAeC;IAED,uDAYC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,gFAGC;IAED,6CAqBC;IAGD,8EAgCC;IAED,gFAGC;IAED,+EAgBC;IAED,qCASC;IAED,4EAaC;IAED,4DAGC;IAED,qDAKC;IAED,gDAYC;IAGD,6DAgBC;CACF"}
|
package/script/midy-GMLite.js
CHANGED
|
@@ -102,11 +102,11 @@ const defaultControllerState = {
|
|
|
102
102
|
pitchWheel: { type: 14, defaultValue: 8192 / 16383 },
|
|
103
103
|
pitchWheelSensitivity: { type: 16, defaultValue: 2 / 128 },
|
|
104
104
|
link: { type: 127, defaultValue: 0 },
|
|
105
|
-
|
|
105
|
+
modulationDepthMSB: { type: 128 + 1, defaultValue: 0 },
|
|
106
106
|
// dataMSB: { type: 128 + 6, defaultValue: 0, },
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
volumeMSB: { type: 128 + 7, defaultValue: 100 / 127 },
|
|
108
|
+
panMSB: { type: 128 + 10, defaultValue: 64 / 127 },
|
|
109
|
+
expressionMSB: { type: 128 + 11, defaultValue: 1 },
|
|
110
110
|
// dataLSB: { type: 128 + 38, defaultValue: 0, },
|
|
111
111
|
sustainPedal: { type: 128 + 64, defaultValue: 0 },
|
|
112
112
|
// rpnLSB: { type: 128 + 100, defaultValue: 127 },
|
|
@@ -432,7 +432,7 @@ class MidyGMLite {
|
|
|
432
432
|
return soundFontIndex * (2 ** 32) + (instrument << 16) + sampleID;
|
|
433
433
|
}
|
|
434
434
|
createChannelAudioNodes(audioContext) {
|
|
435
|
-
const { gainLeft, gainRight } = this.panToGain(defaultControllerState.
|
|
435
|
+
const { gainLeft, gainRight } = this.panToGain(defaultControllerState.panMSB.defaultValue);
|
|
436
436
|
const gainL = new GainNode(audioContext, { gain: gainLeft });
|
|
437
437
|
const gainR = new GainNode(audioContext, { gain: gainRight });
|
|
438
438
|
const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
|
|
@@ -460,10 +460,9 @@ class MidyGMLite {
|
|
|
460
460
|
return channels;
|
|
461
461
|
}
|
|
462
462
|
async createAudioBuffer(voiceParams) {
|
|
463
|
-
const sample = voiceParams
|
|
464
|
-
const
|
|
465
|
-
const
|
|
466
|
-
const audioBuffer = await sample.toAudioBuffer(this.audioContext, sampleStart, sampleEnd);
|
|
463
|
+
const { sample, start, end } = voiceParams;
|
|
464
|
+
const sampleEnd = sample.data.length + end;
|
|
465
|
+
const audioBuffer = await sample.toAudioBuffer(this.audioContext, start, sampleEnd);
|
|
467
466
|
return audioBuffer;
|
|
468
467
|
}
|
|
469
468
|
createBufferSource(channel, voiceParams, audioBuffer) {
|
|
@@ -493,9 +492,7 @@ class MidyGMLite {
|
|
|
493
492
|
await this.noteOn(event.channel, event.noteNumber, event.velocity, startTime);
|
|
494
493
|
break;
|
|
495
494
|
case "noteOff": {
|
|
496
|
-
|
|
497
|
-
if (notePromise)
|
|
498
|
-
this.notePromises.push(notePromise);
|
|
495
|
+
this.noteOff(event.channel, event.noteNumber, event.velocity, startTime, false);
|
|
499
496
|
break;
|
|
500
497
|
}
|
|
501
498
|
case "controller":
|
|
@@ -589,6 +586,12 @@ class MidyGMLite {
|
|
|
589
586
|
const waitTime = now + this.noteCheckInterval;
|
|
590
587
|
await this.scheduleTask(() => { }, waitTime);
|
|
591
588
|
}
|
|
589
|
+
if (this.timeline.length <= queueIndex) {
|
|
590
|
+
const now = this.audioContext.currentTime;
|
|
591
|
+
await this.stopNotes(0, true, now);
|
|
592
|
+
await this.audioContext.suspend();
|
|
593
|
+
finished = true;
|
|
594
|
+
}
|
|
592
595
|
if (finished) {
|
|
593
596
|
this.notePromises = [];
|
|
594
597
|
this.resetAllStates();
|
|
@@ -921,12 +924,18 @@ class MidyGMLite {
|
|
|
921
924
|
this.setFilterEnvelope(note, now);
|
|
922
925
|
this.setPitchEnvelope(note, now);
|
|
923
926
|
this.updateDetune(channel, note, now);
|
|
924
|
-
if (0 < state.
|
|
927
|
+
if (0 < state.modulationDepthMSB) {
|
|
925
928
|
this.startModulation(channel, note, now);
|
|
926
929
|
}
|
|
927
930
|
note.bufferSource.connect(note.filterNode);
|
|
928
931
|
note.filterNode.connect(note.volumeEnvelopeNode);
|
|
929
|
-
|
|
932
|
+
if (voiceParams.sample.type === "compressed") {
|
|
933
|
+
const offset = voiceParams.start / audioBuffer.sampleRate;
|
|
934
|
+
note.bufferSource.start(startTime, offset);
|
|
935
|
+
}
|
|
936
|
+
else {
|
|
937
|
+
note.bufferSource.start(startTime);
|
|
938
|
+
}
|
|
930
939
|
return note;
|
|
931
940
|
}
|
|
932
941
|
handleExclusiveClass(note, channelNumber, startTime) {
|
|
@@ -1048,7 +1057,9 @@ class MidyGMLite {
|
|
|
1048
1057
|
}
|
|
1049
1058
|
note.ending = true;
|
|
1050
1059
|
this.setNoteIndex(channel, index);
|
|
1051
|
-
this.releaseNote(channel, note, endTime);
|
|
1060
|
+
const promise = this.releaseNote(channel, note, endTime);
|
|
1061
|
+
this.notePromises.push(promise);
|
|
1062
|
+
return promise;
|
|
1052
1063
|
}
|
|
1053
1064
|
setNoteIndex(channel, index) {
|
|
1054
1065
|
let allEnds = true;
|
|
@@ -1146,11 +1157,12 @@ class MidyGMLite {
|
|
|
1146
1157
|
setModLfoToPitch(channel, note, scheduleTime) {
|
|
1147
1158
|
if (note.modulationDepth) {
|
|
1148
1159
|
const modLfoToPitch = note.voiceParams.modLfoToPitch;
|
|
1149
|
-
const baseDepth = Math.abs(modLfoToPitch) +
|
|
1150
|
-
|
|
1160
|
+
const baseDepth = Math.abs(modLfoToPitch) +
|
|
1161
|
+
channel.state.modulationDepthMSB;
|
|
1162
|
+
const depth = baseDepth * Math.sign(modLfoToPitch);
|
|
1151
1163
|
note.modulationDepth.gain
|
|
1152
1164
|
.cancelScheduledValues(scheduleTime)
|
|
1153
|
-
.setValueAtTime(
|
|
1165
|
+
.setValueAtTime(depth, scheduleTime);
|
|
1154
1166
|
}
|
|
1155
1167
|
else {
|
|
1156
1168
|
this.startModulation(channel, note, scheduleTime);
|
|
@@ -1187,18 +1199,18 @@ class MidyGMLite {
|
|
|
1187
1199
|
createVoiceParamsHandlers() {
|
|
1188
1200
|
return {
|
|
1189
1201
|
modLfoToPitch: (channel, note, scheduleTime) => {
|
|
1190
|
-
if (0 < channel.state.
|
|
1202
|
+
if (0 < channel.state.modulationDepthMSB) {
|
|
1191
1203
|
this.setModLfoToPitch(channel, note, scheduleTime);
|
|
1192
1204
|
}
|
|
1193
1205
|
},
|
|
1194
1206
|
vibLfoToPitch: (_channel, _note, _scheduleTime) => { },
|
|
1195
1207
|
modLfoToFilterFc: (channel, note, scheduleTime) => {
|
|
1196
|
-
if (0 < channel.state.
|
|
1208
|
+
if (0 < channel.state.modulationDepthMSB) {
|
|
1197
1209
|
this.setModLfoToFilterFc(note, scheduleTime);
|
|
1198
1210
|
}
|
|
1199
1211
|
},
|
|
1200
1212
|
modLfoToVolume: (channel, note, scheduleTime) => {
|
|
1201
|
-
if (0 < channel.state.
|
|
1213
|
+
if (0 < channel.state.modulationDepthMSB) {
|
|
1202
1214
|
this.setModLfoToVolume(note, scheduleTime);
|
|
1203
1215
|
}
|
|
1204
1216
|
},
|
|
@@ -1436,8 +1448,8 @@ class MidyGMLite {
|
|
|
1436
1448
|
resetAllControllers(channelNumber, _value, scheduleTime) {
|
|
1437
1449
|
const keys = [
|
|
1438
1450
|
"pitchWheel",
|
|
1439
|
-
"
|
|
1440
|
-
"
|
|
1451
|
+
"expressionMSB",
|
|
1452
|
+
"modulationDepthMSB",
|
|
1441
1453
|
"sustainPedal",
|
|
1442
1454
|
];
|
|
1443
1455
|
const channel = this.channels[channelNumber];
|