@marmooo/midy 0.0.3 → 0.0.4

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 CHANGED
@@ -137,6 +137,8 @@ export class MidyGM1 {
137
137
  connectNoteEffects(channel: any, gainNode: any): void;
138
138
  cbToRatio(cb: any): number;
139
139
  centToHz(cent: any): number;
140
+ calcSemitoneOffset(channel: any): any;
141
+ calcPlaybackRate(noteInfo: any, noteNumber: any, semitoneOffset: any): number;
140
142
  createNoteAudioChain(channel: any, noteInfo: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<{
141
143
  bufferSource: any;
142
144
  gainNode: any;
@@ -149,10 +151,9 @@ export class MidyGM1 {
149
151
  releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
150
152
  releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
151
153
  handleMIDIMessage(statusByte: any, data1: any, data2: any): void | any[] | Promise<any>;
152
- handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any): void;
153
154
  handleProgramChange(channelNumber: any, program: any): void;
154
- handleChannelPressure(channelNumber: any, pressure: any): void;
155
- handlePitchBend(channelNumber: any, lsb: any, msb: any): void;
155
+ handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
156
+ handlePitchBend(channelNumber: any, pitchBend: any): void;
156
157
  handleControlChange(channelNumber: any, controller: any, value: any): void | any[];
157
158
  setModulation(channelNumber: any, modulation: any): void;
158
159
  setVolume(channelNumber: any, volume: any): void;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAMA;IAmBE;;;;;;;;;;;;;;MAcE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAjDD,qBAAmB;IACnB,kBAAc;IACd,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;IA4BhB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;MAgBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;QAWC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,2EA4CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAyEC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,4CASC;IAED,gDAKC;IAED;;MAOC;IAED,sDAEC;IAED,2BAEC;IAED,4BAEC;IAED;;;;;OA6EC;IAED,kGAuCC;IAED,0EAGC;IAED,sIA4CC;IAED,0FAGC;IAED,kEAeC;IAED,wFAqBC;IAED,sFAeC;IAED,4DAGC;IAED,+DAEC;IAED,8DAGC;IAED,mFA+BC;IAED,yDAIC;IAED,iDAIC;IAED,2CAMC;IAED,yDAIC;IAED,sCAKC;IAED,sDAMC;IAED,gDAEC;IAED,gDAEC;IAED,+DAoBC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,sCAIC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}
1
+ {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AAMA;IAmBE;;;;;;;;;;;;;;MAcE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAjDD,qBAAmB;IACnB,kBAAc;IACd,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;IA4BhB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;MAgBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;QAWC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,2EA+CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAyEC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,4CASC;IAED,gDAKC;IAED;;MAOC;IAED,sDAEC;IAED,2BAEC;IAED,4BAEC;IAED,sCAGC;IAED,8EAEC;IAED;;;;;OA8EC;IAED,kGAuCC;IAED,0EAGC;IAED,sIA4CC;IAED,0FAGC;IAED,kEAeC;IAED,wFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,0DAiBC;IAED,mFA+BC;IAED,yDAIC;IAED,iDAIC;IAED,2CAMC;IAED,yDAIC;IAED,sCAKC;IAED,sDAMC;IAED,gDAEC;IAED,gDAEC;IAED,+DAoBC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,sCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}
package/esm/midy-GM1.js CHANGED
@@ -223,9 +223,6 @@ export class MidyGM1 {
223
223
  if (event.startTime > t + this.lookAhead)
224
224
  break;
225
225
  switch (event.type) {
226
- case "controller":
227
- this.handleControlChange(event.channel, event.controllerType, event.value);
228
- break;
229
226
  case "noteOn":
230
227
  if (event.velocity !== 0) {
231
228
  await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, event.startTime + this.startDelay - offset);
@@ -239,9 +236,15 @@ export class MidyGM1 {
239
236
  }
240
237
  break;
241
238
  }
239
+ case "controller":
240
+ this.handleControlChange(event.channel, event.controllerType, event.value);
241
+ break;
242
242
  case "programChange":
243
243
  this.handleProgramChange(event.channel, event.programNumber);
244
244
  break;
245
+ case "pitchBend":
246
+ this.handlePitchBend(event.channel, event.value);
247
+ break;
245
248
  case "sysEx":
246
249
  this.handleSysEx(event.data);
247
250
  }
@@ -478,13 +481,17 @@ export class MidyGM1 {
478
481
  centToHz(cent) {
479
482
  return 8.176 * Math.pow(2, cent / 1200);
480
483
  }
481
- async createNoteAudioChain(channel, noteInfo, noteNumber, velocity, startTime, isSF3) {
484
+ calcSemitoneOffset(channel) {
482
485
  const tuning = channel.coarseTuning + channel.fineTuning;
483
- const semitoneOffset = channel.pitchBend * channel.pitchBendRange + tuning;
484
- const playbackRate = noteInfo.playbackRate(noteNumber) *
485
- Math.pow(2, semitoneOffset / 12);
486
+ return channel.pitchBend * channel.pitchBendRange + tuning;
487
+ }
488
+ calcPlaybackRate(noteInfo, noteNumber, semitoneOffset) {
489
+ return noteInfo.playbackRate(noteNumber) * Math.pow(2, semitoneOffset / 12);
490
+ }
491
+ async createNoteAudioChain(channel, noteInfo, noteNumber, velocity, startTime, isSF3) {
486
492
  const bufferSource = await this.createNoteBufferNode(noteInfo, isSF3);
487
- bufferSource.playbackRate.value = playbackRate;
493
+ const semitoneOffset = this.calcSemitoneOffset(channel);
494
+ bufferSource.playbackRate.value = this.calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
488
495
  // volume envelope
489
496
  const gainNode = new GainNode(this.audioContext, {
490
497
  gain: 0,
@@ -650,46 +657,37 @@ export class MidyGM1 {
650
657
  return this.releaseNote(channelNumber, data1, data2);
651
658
  case 0x90:
652
659
  return this.noteOn(channelNumber, data1, data2);
653
- case 0xA0:
654
- return this.handlePolyphonicKeyPressure(channelNumber, data1, data2);
655
660
  case 0xB0:
656
661
  return this.handleControlChange(channelNumber, data1, data2);
657
662
  case 0xC0:
658
663
  return this.handleProgramChange(channelNumber, data1);
659
- case 0xD0:
660
- return this.handleChannelPressure(channelNumber, data1);
661
664
  case 0xE0:
662
- return this.handlePitchBend(channelNumber, data1, data2);
665
+ return this.handlePitchBendMessage(channelNumber, data1, data2);
663
666
  default:
664
667
  console.warn(`Unsupported MIDI message: ${messageType.toString(16)}`);
665
668
  }
666
669
  }
667
- handlePolyphonicKeyPressure(channelNumber, noteNumber, pressure) {
668
- const now = this.audioContext.currentTime;
669
- const channel = this.channels[channelNumber];
670
- const scheduledNotes = channel.scheduledNotes.get(noteNumber);
671
- pressure /= 127;
672
- if (scheduledNotes) {
673
- scheduledNotes.forEach((scheduledNote) => {
674
- if (scheduledNote) {
675
- const { initialAttenuation } = scheduledNote.noteInfo;
676
- const gain = this.cbToRatio(-initialAttenuation) * pressure;
677
- scheduledNote.gainNode.gain.cancelScheduledValues(now);
678
- scheduledNote.gainNode.gain.setValueAtTime(gain, now);
679
- }
680
- });
681
- }
682
- }
683
670
  handleProgramChange(channelNumber, program) {
684
671
  const channel = this.channels[channelNumber];
685
672
  channel.program = program;
686
673
  }
687
- handleChannelPressure(channelNumber, pressure) {
688
- this.channels[channelNumber].channelPressure = pressure;
674
+ handlePitchBendMessage(channelNumber, lsb, msb) {
675
+ const pitchBend = msb * 128 + lsb;
676
+ this.handlePitchBend(channelNumber, pitchBend);
689
677
  }
690
- handlePitchBend(channelNumber, lsb, msb) {
691
- const pitchBend = (msb * 128 + lsb - 8192) / 8192;
692
- this.channels[channelNumber].pitchBend = pitchBend;
678
+ handlePitchBend(channelNumber, pitchBend) {
679
+ const now = this.audioContext.currentTime;
680
+ const channel = this.channels[channelNumber];
681
+ channel.pitchBend = (pitchBend - 8192) / 8192;
682
+ const semitoneOffset = this.calcSemitoneOffset(channel);
683
+ const activeNotes = this.getActiveNotes(channel);
684
+ activeNotes.forEach((activeNote) => {
685
+ const { bufferSource, noteInfo, noteNumber } = activeNote;
686
+ const playbackRate = calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
687
+ bufferSource.playbackRate
688
+ .cancelScheduledValues(now)
689
+ .setValueAtTime(playbackRate * pressure, now);
690
+ });
693
691
  }
694
692
  handleControlChange(channelNumber, controller, value) {
695
693
  switch (controller) {
@@ -855,13 +853,18 @@ export class MidyGM1 {
855
853
  }
856
854
  }
857
855
  handleMasterVolumeSysEx(data) {
858
- const volume = (data[5] * 128 + data[4] - 8192) / 8192;
856
+ const volume = (data[5] * 128 + data[4]) / 16383;
859
857
  this.handleMasterVolume(volume);
860
858
  }
861
859
  handleMasterVolume(volume) {
862
- const now = this.audioContext.currentTime;
863
- this.masterGain.gain.cancelScheduledValues(now);
864
- this.masterGain.gain.setValueAtTime(volume * volume, now);
860
+ if (volume < 0 && 1 < volume) {
861
+ console.error("Master Volume is out of range");
862
+ }
863
+ else {
864
+ const now = this.audioContext.currentTime;
865
+ this.masterGain.gain.cancelScheduledValues(now);
866
+ this.masterGain.gain.setValueAtTime(volume * volume, now);
867
+ }
865
868
  }
866
869
  handleExclusiveMessage(data) {
867
870
  console.warn(`Unsupported Exclusive Message ${data}`);
package/esm/midy-GM2.d.ts CHANGED
@@ -32,6 +32,14 @@ export class MidyGM2 {
32
32
  channelPressure: number;
33
33
  pitchBendRange: number;
34
34
  };
35
+ static controllerDestinationSettings: {
36
+ pitchControl: number;
37
+ filterCutoffControl: number;
38
+ amplitudeControl: number;
39
+ lfoPitchDepth: number;
40
+ lfoFilterDepth: number;
41
+ lfoAmplitudeDepth: number;
42
+ };
35
43
  constructor(audioContext: any);
36
44
  ticksPerBeat: number;
37
45
  totalTime: number;
@@ -57,55 +65,7 @@ export class MidyGM2 {
57
65
  notePromises: any[];
58
66
  audioContext: any;
59
67
  masterGain: any;
60
- channels: {
61
- scheduledNotes: Map<any, any>;
62
- sostenutoNotes: Map<any, any>;
63
- gainNode: any;
64
- pannerNode: any;
65
- modulationEffect: {
66
- lfo: any;
67
- };
68
- reverbEffect: {
69
- convolverNode: any;
70
- dryGain: any;
71
- wetGain: any;
72
- };
73
- chorusEffect: {
74
- lfo: any;
75
- lfoGain: any;
76
- delayNodes: any[];
77
- chorusGains: any[];
78
- };
79
- expression: number;
80
- modulation: number;
81
- sustainPedal: boolean;
82
- portamento: boolean;
83
- sostenutoPedal: boolean;
84
- softPedal: number;
85
- rpnMSB: number;
86
- rpnLSB: number;
87
- channelPressure: number;
88
- pitchBendRange: number;
89
- currentBufferSource: null;
90
- volume: number;
91
- pan: number;
92
- portamentoTime: number;
93
- reverb: number;
94
- chorus: number;
95
- vibratoRate: number;
96
- vibratoDepth: number;
97
- vibratoDelay: number;
98
- bank: number;
99
- bankMSB: number;
100
- bankLSB: number;
101
- dataMSB: number;
102
- dataLSB: number;
103
- program: number;
104
- pitchBend: number;
105
- fineTuning: number;
106
- coarseTuning: number;
107
- modulationDepthRange: number;
108
- }[];
68
+ channels: any[];
109
69
  initSoundFontTable(): any[];
110
70
  addSoundFont(soundFont: any): void;
111
71
  loadSoundFont(soundFontUrl: any): Promise<void>;
@@ -128,55 +88,7 @@ export class MidyGM2 {
128
88
  chorusGains: any[];
129
89
  };
130
90
  };
131
- createChannels(audioContext: any): {
132
- scheduledNotes: Map<any, any>;
133
- sostenutoNotes: Map<any, any>;
134
- gainNode: any;
135
- pannerNode: any;
136
- modulationEffect: {
137
- lfo: any;
138
- };
139
- reverbEffect: {
140
- convolverNode: any;
141
- dryGain: any;
142
- wetGain: any;
143
- };
144
- chorusEffect: {
145
- lfo: any;
146
- lfoGain: any;
147
- delayNodes: any[];
148
- chorusGains: any[];
149
- };
150
- expression: number;
151
- modulation: number;
152
- sustainPedal: boolean;
153
- portamento: boolean;
154
- sostenutoPedal: boolean;
155
- softPedal: number;
156
- rpnMSB: number;
157
- rpnLSB: number;
158
- channelPressure: number;
159
- pitchBendRange: number;
160
- currentBufferSource: null;
161
- volume: number;
162
- pan: number;
163
- portamentoTime: number;
164
- reverb: number;
165
- chorus: number;
166
- vibratoRate: number;
167
- vibratoDepth: number;
168
- vibratoDelay: number;
169
- bank: number;
170
- bankMSB: number;
171
- bankLSB: number;
172
- dataMSB: number;
173
- dataLSB: number;
174
- program: number;
175
- pitchBend: number;
176
- fineTuning: number;
177
- coarseTuning: number;
178
- modulationDepthRange: number;
179
- }[];
91
+ createChannels(audioContext: any): any[];
180
92
  createNoteBuffer(noteInfo: any, isSF3: any): Promise<any>;
181
93
  createNoteBufferNode(noteInfo: any, isSF3: any): Promise<any>;
182
94
  convertToFloat32Array(uint8Array: any): Float32Array;
@@ -216,6 +128,8 @@ export class MidyGM2 {
216
128
  connectNoteEffects(channel: any, gainNode: any): void;
217
129
  cbToRatio(cb: any): number;
218
130
  centToHz(cent: any): number;
131
+ calcSemitoneOffset(channel: any): any;
132
+ calcPlaybackRate(noteInfo: any, noteNumber: any, semitoneOffset: any): number;
219
133
  createNoteAudioChain(channel: any, noteInfo: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<{
220
134
  bufferSource: any;
221
135
  gainNode: any;
@@ -230,10 +144,10 @@ export class MidyGM2 {
230
144
  releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
231
145
  releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
232
146
  handleMIDIMessage(statusByte: any, data1: any, data2: any): void | any[] | Promise<any>;
233
- handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any): void;
234
147
  handleProgramChange(channelNumber: any, program: any): void;
235
148
  handleChannelPressure(channelNumber: any, pressure: any): void;
236
- handlePitchBend(channelNumber: any, lsb: any, msb: any): void;
149
+ handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
150
+ handlePitchBend(channelNumber: any, pitchBend: any): void;
237
151
  handleControlChange(channelNumber: any, controller: any, value: any): void | any[];
238
152
  setBankMSB(channelNumber: any, msb: any): void;
239
153
  setModulation(channelNumber: any, modulation: any): void;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"AAMA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF,+BAMC;IAhED,qBAAmB;IACnB,kBAAc;IACd,qBAAmB;IACnB,yBAAqB;IACrB,2BAAuB;IACvB,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;IAsChB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;;;;MAuBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAWC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,2EA4CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA2GC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,4CASC;IAED,gDAKC;IAED;;MAOC;IAED;;;;MAoCC;IAED;;;;;MA2CC;IAED,sDA2BC;IAED,2BAEC;IAED,4BAEC;IAED;;;;;OAsFC;IAED,gDAQC;IAED,kGAgDC;IAED,0EAGC;IAED,sIA6CC;IAED,0FAGC;IAED,kEAeC;IAED,oEAYC;IAED,wFAqBC;IAED,sFAeC;IAED,4DAIC;IAED,+DAEC;IAED,8DAGC;IAED,mFAuDC;IAED,+CAEC;IAED,yDAIC;IAED,iEAEC;IAED,iDAIC;IAED,2CAMC;IAED,yDAIC;IAED,+CAEC;IAED,sCAKC;IAED,sDAMC;IAED,oDAEC;IAED,iDASC;IAED,iDAIC;IAED,wDAUC;IAED,uDAGC;IAED,gDAEC;IAED,gDAEC;IAED,+DAuBC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,gBAEC;IAED,eAEC;IAED,eAEC;IAED,eAEC;IAED,4DAmBC;IAED,oBAQC;IAED,oBAQC;IAED,yDAgDC;IAED,yCAGC;IAED,sCAIC;IAED,6CAGC;IAED,8CAMC;IAED,+CAGC;IAED,kDAMC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}
1
+ {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"AAMA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAzED,qBAAmB;IACnB,kBAAc;IACd,qBAAmB;IACnB,yBAAqB;IACrB,2BAAuB;IACvB,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;IA+ChB,kBAAgC;IAChC,gBAA4C;IAE5C,gBAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;;;;MAuBC;IAED,yCAcC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,2EAkDC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA2GC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,4CASC;IAED,gDAKC;IAED;;MAOC;IAED;;;;MAoCC;IAED;;;;;MA2CC;IAED,sDA2BC;IAED,2BAEC;IAED,4BAEC;IAED,sCAKC;IAED,8EAEC;IAED;;;;;OAqFC;IAED,gDAQC;IAED,kGAgDC;IAED,0EAGC;IAED,sIA6CC;IAED,0FAGC;IAED,kEAeC;IAED,oEAYC;IAED,wFAmBC;IAED,4DAIC;IAED,+DAcC;IAED,qEAGC;IAED,0DAiBC;IAED,mFAuDC;IAED,+CAEC;IAED,yDAIC;IAED,iEAEC;IAED,iDAIC;IAED,2CAMC;IAED,yDAIC;IAED,+CAEC;IAED,sCAKC;IAED,sDAMC;IAED,oDAEC;IAED,iDASC;IAED,iDAIC;IAED,wDAUC;IAED,uDAGC;IAED,gDAEC;IAED,gDAEC;IAED,+DAuBC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,gBAEC;IAED,eAEC;IAED,eAEC;IAED,eAEC;IAED,4DAmBC;IAED,oBAQC;IAED,oBAQC;IAED,yDAgDC;IAED,yCAGC;IAED,sCAQC;IAED,6CAGC;IAED,8CAMC;IAED,+CAGC;IAED,kDAMC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}
package/esm/midy-GM2.js CHANGED
@@ -201,11 +201,14 @@ export class MidyGM2 {
201
201
  createChannels(audioContext) {
202
202
  const channels = Array.from({ length: 16 }, () => {
203
203
  return {
204
- ...MidyGM2.channelSettings,
205
- ...MidyGM2.effectSettings,
204
+ ...Midy.channelSettings,
205
+ ...Midy.effectSettings,
206
206
  ...this.setChannelAudioNodes(audioContext),
207
207
  scheduledNotes: new Map(),
208
208
  sostenutoNotes: new Map(),
209
+ channelPressure: {
210
+ ...Midy.controllerDestinationSettings,
211
+ },
209
212
  };
210
213
  });
211
214
  return channels;
@@ -260,9 +263,6 @@ export class MidyGM2 {
260
263
  if (event.startTime > t + this.lookAhead)
261
264
  break;
262
265
  switch (event.type) {
263
- case "controller":
264
- this.handleControlChange(this.omni ? 0 : event.channel, event.controllerType, event.value);
265
- break;
266
266
  case "noteOn":
267
267
  if (event.velocity !== 0) {
268
268
  await this.scheduleNoteOn(event.channel, event.noteNumber, event.velocity, event.startTime + this.startDelay - offset);
@@ -276,9 +276,18 @@ export class MidyGM2 {
276
276
  }
277
277
  break;
278
278
  }
279
+ case "controller":
280
+ this.handleControlChange(this.omni ? 0 : event.channel, event.controllerType, event.value);
281
+ break;
279
282
  case "programChange":
280
283
  this.handleProgramChange(event.channel, event.programNumber);
281
284
  break;
285
+ case "channelAftertouch":
286
+ this.handleChannelPressure(event.channel, event.amount);
287
+ break;
288
+ case "pitchBend":
289
+ this.handlePitchBend(event.channel, event.value);
290
+ break;
282
291
  case "sysEx":
283
292
  this.handleSysEx(event.data);
284
293
  }
@@ -642,15 +651,19 @@ export class MidyGM2 {
642
651
  centToHz(cent) {
643
652
  return 8.176 * Math.pow(2, cent / 1200);
644
653
  }
645
- async createNoteAudioChain(channel, noteInfo, noteNumber, velocity, startTime, isSF3) {
654
+ calcSemitoneOffset(channel) {
646
655
  const masterTuning = this.masterCoarseTuning + this.masterFineTuning;
647
656
  const channelTuning = channel.coarseTuning + channel.fineTuning;
648
657
  const tuning = masterTuning + channelTuning;
649
- const semitoneOffset = channel.pitchBend * channel.pitchBendRange + tuning;
650
- const playbackRate = noteInfo.playbackRate(noteNumber) *
651
- Math.pow(2, semitoneOffset / 12);
658
+ return channel.pitchBend * channel.pitchBendRange + tuning;
659
+ }
660
+ calcPlaybackRate(noteInfo, noteNumber, semitoneOffset) {
661
+ return noteInfo.playbackRate(noteNumber) * Math.pow(2, semitoneOffset / 12);
662
+ }
663
+ async createNoteAudioChain(channel, noteInfo, noteNumber, velocity, startTime, isSF3) {
652
664
  const bufferSource = await this.createNoteBufferNode(noteInfo, isSF3);
653
- bufferSource.playbackRate.value = playbackRate;
665
+ const semitoneOffset = this.calcSemitoneOffset(channel);
666
+ bufferSource.playbackRate.value = this.calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
654
667
  // volume envelope
655
668
  const gainNode = new GainNode(this.audioContext, {
656
669
  gain: 0,
@@ -855,8 +868,6 @@ export class MidyGM2 {
855
868
  return this.releaseNote(channelNumber, data1, data2);
856
869
  case 0x90:
857
870
  return this.noteOn(channelNumber, data1, data2);
858
- case 0xA0:
859
- return this.handlePolyphonicKeyPressure(channelNumber, data1, data2);
860
871
  case 0xB0:
861
872
  return this.handleControlChange(channelNumber, data1, data2);
862
873
  case 0xC0:
@@ -864,38 +875,48 @@ export class MidyGM2 {
864
875
  case 0xD0:
865
876
  return this.handleChannelPressure(channelNumber, data1);
866
877
  case 0xE0:
867
- return this.handlePitchBend(channelNumber, data1, data2);
878
+ return this.handlePitchBendMessage(channelNumber, data1, data2);
868
879
  default:
869
880
  console.warn(`Unsupported MIDI message: ${messageType.toString(16)}`);
870
881
  }
871
882
  }
872
- handlePolyphonicKeyPressure(channelNumber, noteNumber, pressure) {
873
- const now = this.audioContext.currentTime;
874
- const channel = this.channels[channelNumber];
875
- const scheduledNotes = channel.scheduledNotes.get(noteNumber);
876
- pressure /= 127;
877
- if (scheduledNotes) {
878
- scheduledNotes.forEach((scheduledNote) => {
879
- if (scheduledNote) {
880
- const { initialAttenuation } = scheduledNote.noteInfo;
881
- const gain = this.cbToRatio(-initialAttenuation) * pressure;
882
- scheduledNote.gainNode.gain.cancelScheduledValues(now);
883
- scheduledNote.gainNode.gain.setValueAtTime(gain, now);
884
- }
885
- });
886
- }
887
- }
888
883
  handleProgramChange(channelNumber, program) {
889
884
  const channel = this.channels[channelNumber];
890
885
  channel.bank = channel.bankMSB * 128 + channel.bankLSB;
891
886
  channel.program = program;
892
887
  }
893
888
  handleChannelPressure(channelNumber, pressure) {
894
- this.channels[channelNumber].channelPressure = pressure;
889
+ const now = this.audioContext.currentTime;
890
+ const channel = this.channels[channelNumber];
891
+ pressure /= 64;
892
+ channel.channelPressure = pressure;
893
+ const activeNotes = this.getActiveNotes(channel);
894
+ if (channel.channelPressure.amplitudeControl !== 1) {
895
+ activeNotes.forEach((activeNote) => {
896
+ const gain = activeNote.gainNode.gain.value;
897
+ activeNote.gainNode.gain
898
+ .cancelScheduledValues(now)
899
+ .setValueAtTime(gain * pressure, now);
900
+ });
901
+ }
895
902
  }
896
- handlePitchBend(channelNumber, lsb, msb) {
897
- const pitchBend = (msb * 128 + lsb - 8192) / 8192;
898
- this.channels[channelNumber].pitchBend = pitchBend;
903
+ handlePitchBendMessage(channelNumber, lsb, msb) {
904
+ const pitchBend = msb * 128 + lsb;
905
+ this.handlePitchBend(channelNumber, pitchBend);
906
+ }
907
+ handlePitchBend(channelNumber, pitchBend) {
908
+ const now = this.audioContext.currentTime;
909
+ const channel = this.channels[channelNumber];
910
+ channel.pitchBend = (pitchBend - 8192) / 8192;
911
+ const semitoneOffset = this.calcSemitoneOffset(channel);
912
+ const activeNotes = this.getActiveNotes(channel);
913
+ activeNotes.forEach((activeNote) => {
914
+ const { bufferSource, noteInfo, noteNumber } = activeNote;
915
+ const playbackRate = calcPlaybackRate(noteInfo, noteNumber, semitoneOffset);
916
+ bufferSource.playbackRate
917
+ .cancelScheduledValues(now)
918
+ .setValueAtTime(playbackRate * pressure, now);
919
+ });
899
920
  }
900
921
  handleControlChange(channelNumber, controller, value) {
901
922
  switch (controller) {
@@ -1168,10 +1189,10 @@ export class MidyGM2 {
1168
1189
  switch (data[3]) {
1169
1190
  // case 1:
1170
1191
  // // TODO
1171
- // return this.handleChannelPressure();
1192
+ // return this.setChannelPressure();
1172
1193
  // case 3:
1173
1194
  // // TODO
1174
- // return this.handleControlChange();
1195
+ // return this.setControlChange();
1175
1196
  default:
1176
1197
  console.warn(`Unsupported Exclusive Message ${data}`);
1177
1198
  }
@@ -1190,20 +1211,25 @@ export class MidyGM2 {
1190
1211
  }
1191
1212
  }
1192
1213
  handleMasterVolumeSysEx(data) {
1193
- const volume = (data[5] * 128 + data[4] - 8192) / 8192;
1214
+ const volume = (data[5] * 128 + data[4]) / 16383;
1194
1215
  this.handleMasterVolume(volume);
1195
1216
  }
1196
1217
  handleMasterVolume(volume) {
1197
- const now = this.audioContext.currentTime;
1198
- this.masterGain.gain.cancelScheduledValues(now);
1199
- this.masterGain.gain.setValueAtTime(volume * volume, now);
1218
+ if (volume < 0 && 1 < volume) {
1219
+ console.error("Master Volume is out of range");
1220
+ }
1221
+ else {
1222
+ const now = this.audioContext.currentTime;
1223
+ this.masterGain.gain.cancelScheduledValues(now);
1224
+ this.masterGain.gain.setValueAtTime(volume * volume, now);
1225
+ }
1200
1226
  }
1201
1227
  handleMasterFineTuningSysEx(data) {
1202
1228
  const fineTuning = (data[5] * 128 + data[4] - 8192) / 8192;
1203
1229
  this.handleMasterFineTuning(fineTuning);
1204
1230
  }
1205
1231
  handleMasterFineTuning(fineTuning) {
1206
- if (fineTuning < 0 && 1 < fineTuning) {
1232
+ if (fineTuning < -1 && 1 < fineTuning) {
1207
1233
  console.error("Master Fine Tuning value is out of range");
1208
1234
  }
1209
1235
  else {
@@ -1290,3 +1316,16 @@ Object.defineProperty(MidyGM2, "effectSettings", {
1290
1316
  pitchBendRange: 2,
1291
1317
  }
1292
1318
  });
1319
+ Object.defineProperty(MidyGM2, "controllerDestinationSettings", {
1320
+ enumerable: true,
1321
+ configurable: true,
1322
+ writable: true,
1323
+ value: {
1324
+ pitchControl: 0,
1325
+ filterCutoffControl: 0,
1326
+ amplitudeControl: 1,
1327
+ lfoPitchDepth: 0,
1328
+ lfoFilterDepth: 0,
1329
+ lfoAmplitudeDepth: 0,
1330
+ }
1331
+ });
@@ -131,6 +131,8 @@ export class MidyGMLite {
131
131
  connectNoteEffects(channel: any, gainNode: any): void;
132
132
  cbToRatio(cb: any): number;
133
133
  centToHz(cent: any): number;
134
+ calcSemitoneOffset(channel: any): any;
135
+ calcPlaybackRate(noteInfo: any, noteNumber: any, semitoneOffset: any): number;
134
136
  createNoteAudioChain(channel: any, noteInfo: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<{
135
137
  bufferSource: any;
136
138
  gainNode: any;
@@ -143,10 +145,9 @@ export class MidyGMLite {
143
145
  releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
144
146
  releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
145
147
  handleMIDIMessage(statusByte: any, data1: any, data2: any): void | any[] | Promise<any>;
146
- handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any): void;
147
148
  handleProgramChange(channelNumber: any, program: any): void;
148
- handleChannelPressure(channelNumber: any, pressure: any): void;
149
- handlePitchBend(channelNumber: any, lsb: any, msb: any): void;
149
+ handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
150
+ handlePitchBend(channelNumber: any, pitchBend: any): void;
150
151
  handleControlChange(channelNumber: any, controller: any, value: any): void | any[];
151
152
  setModulation(channelNumber: any, modulation: any): void;
152
153
  setVolume(channelNumber: any, volume: any): void;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAMA;IAmBE;;;;;;;;;;;;MAYE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA/CD,qBAAmB;IACnB,kBAAc;IACd,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;IA0BhB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;MAgBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;QAWC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,2EA4CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAyEC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,4CASC;IAED,gDAKC;IAED;;MAOC;IAED,sDAEC;IAED,2BAEC;IAED,4BAEC;IAED;;;;;OA4EC;IAED,kGAuCC;IAED,0EAGC;IAED,sIA4CC;IAED,0FAGC;IAED,kEAeC;IAED,wFAqBC;IAED,sFAeC;IAED,4DAGC;IAED,+DAEC;IAED,8DAGC;IAED,mFA+BC;IAED,yDAIC;IAED,iDAIC;IAED,2CAMC;IAED,yDAIC;IAED,sCAKC;IAED,sDAMC;IAED,gDAEC;IAED,gDAEC;IAED,+DAcC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,sCAIC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}
1
+ {"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAMA;IAmBE;;;;;;;;;;;;MAYE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA/CD,qBAAmB;IACnB,kBAAc;IACd,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;IA0BhB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;MAgBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;QAWC;IAED,0DAyBC;IAED,8DAUC;IAED,qDAOC;IAED,2EA+CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAyEC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,4CASC;IAED,gDAKC;IAED;;MAOC;IAED,sDAEC;IAED,2BAEC;IAED,4BAEC;IAED,sCAEC;IAED,8EAEC;IAED;;;;;OA8EC;IAED,kGAuCC;IAED,0EAGC;IAED,sIA4CC;IAED,0FAGC;IAED,kEAeC;IAED,wFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,0DAiBC;IAED,mFA+BC;IAED,yDAIC;IAED,iDAIC;IAED,2CAMC;IAED,yDAIC;IAED,sCAKC;IAED,sDAMC;IAED,gDAEC;IAED,gDAEC;IAED,+DAcC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,sCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF"}