@marmooo/midy 0.5.0 → 0.5.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 CHANGED
@@ -94,9 +94,9 @@ midy.addEventListener("resumed", func);
94
94
  midy.addEventListener("seeked", func);
95
95
  ```
96
96
 
97
- ## Cache Mode
97
+ ### Cache Mode
98
98
 
99
- - "none" -for full real-time control (dynamic CC, LFO, pitch)
99
+ - "none" - for full real-time control (dynamic CC, LFO, pitch)
100
100
  - "ads" - for real-time playback with higher cache hit rate
101
101
  - "adsr" - for real-time playback with accurate release envelope
102
102
  - "note" - for efficient playback when note behavior is fixed
@@ -104,6 +104,21 @@ midy.addEventListener("seeked", func);
104
104
 
105
105
  ```
106
106
  const midy = new Midy(audioContext, { cacheMode: "note" });
107
+ midy.cacheMode = "audio";
108
+ ```
109
+
110
+ ### Reverb Mode
111
+
112
+ - "Convolution" - Convolution Reverb
113
+ - "Schroeder" - Schroeder (1962)
114
+ - "Moorer" - Moorer (1979)
115
+ - "FDN" - FDN (1992)
116
+ - "Dattorro" - Dattorro (1997)
117
+ - "Freeverb" - Freeverb (1999)
118
+ - "VelvetNoise" - Velvet Noise Reverb (2012)
119
+
120
+ ```
121
+ midy.setReverbEffect("FDN");
107
122
  ```
108
123
 
109
124
  ### MIDI Message
package/esm/midy-GM1.d.ts CHANGED
@@ -130,7 +130,7 @@ export class MidyGM1 extends EventTarget {
130
130
  getAudioBuffer(channel: any, note: any, realtime: any): Promise<any>;
131
131
  getAdsCachedBuffer(channel: any, note: any, audioBufferId: any, realtime: any): Promise<any>;
132
132
  getAdsrCachedBuffer(note: any, audioBufferId: any): Promise<any>;
133
- getFullCachedBuffer(note: any, audioBufferId: any): Promise<any>;
133
+ getFullCachedBuffer(channel: any, note: any, audioBufferId: any): Promise<any>;
134
134
  setNoteAudioNode(channel: any, note: any, realtime: any): Promise<any>;
135
135
  handleExclusiveClass(note: any, channelNumber: any, startTime: any): void;
136
136
  setNoteRouting(channelNumber: any, note: any, startTime: any): void;
@@ -209,7 +209,8 @@ export class MidyGM1 extends EventTarget {
209
209
  scheduleTask(callback: any, scheduleTime: any): Promise<any>;
210
210
  }
211
211
  declare class Channel {
212
- constructor(audioNodes: any, settings: any);
212
+ constructor(channelNumber: any, audioNodes: any, settings: any);
213
+ channelNumber: number;
213
214
  isDrum: boolean;
214
215
  programNumber: number;
215
216
  scheduleIndex: number;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AA0NA;IA6CE;;;;;;;;;;;MAWE;IAEF,6CAiBC;IAtED,gCAAgC;IAChC,aAAa;IACb,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,0BAAuD;IACvD,4BAAyB;IACzB,0BAAuB;IACvB,kCAA+B;IAC/B,qBAAqC;IACrC,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iCAA2C;IAC3C,cAAU;IACV,cAAa;IACb,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IAErC,8BAA2B;IAE3B,+BAA4B;IAC5B,4BAAyB;IACzB,8BAA2B;IAE3B,0BAA2B;IAC3B,qBAAoB;IACpB,4BAA6B;IAiB3B,kBAAgC;IAChC,eAAwD;IACxD,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF,uBAAmD;IACnD;;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,oBAAiD;IAMnD,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCAYC;IAED,6BAiIC;IAED,sBAgCC;IAED,6EAgBC;IAED;;;;MAWC;IAED,6CAMC;IAED,2CAsBC;IAED,kDA6BC;IAED,8DAoBC;IAED,gEAwDC;IAED,mCASC;IAED,uBAUC;IAED,yDAqCC;IAED,iCA4EC;IAED,2BA6EC;IAED,uDAEC;IAED,wDAEC;IAED,qCAKC;IAED;;;MAwDC;IAED,kGAeC;IAED,mGAeC;IAED,wEAQC;IAED,oCAiJC;IAED,uBAMC;IAED,sBAIC;IAED,uBAMC;IAED,wBAIC;IAED,0BAKC;IAED,8BAoBC;IAED,wBAYC;IAED,sBAOC;IAED,kEAWC;IAED,kFAYC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAMC;IAED,2DAKC;IAED,6CAEC;IAED,sDAgBC;IAED,4DAMC;IAED,qDAkBC;IAED,6CAIC;IAED,sDA8BC;IAED,kEAwBC;IAED,kHAoEC;IAED,oHAoGC;IAED,gIA0DC;IAED,qEAwBC;IAED,6FAqCC;IAED,iEA+CC;IAED,iEA0CC;IAED,uEAyDC;IAED,0EAiBC;IAED,oEAUC;IAED,yFAQC;IAED,qFAQC;IAED,uEA4BC;IAED,gCAUC;IAED,kCAWC;IAED,iEAuGC;IAED,4FAaC;IAED,6CAUC;IAED,qDAUC;IAED,qFAeC;IAED,+BAmBC;IAED,kDAOC;IAED,sFAsBC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAYC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;;MAoCC;IAED,oFAMC;IAED,6EA4BC;IAED,qCAeC;IAED,+FAYC;IAED,wDAWC;IAED,4EAKC;IAED,mEAKC;IAED;;;MAMC;IAED,gEAKC;IAED,uEAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAeC;IAED,kFAeC;IAED,2DAMC;IAED,uDAoBC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,iEAMC;IAED,uEAQC;IAED,mEAKC;IAED,yEAQC;IAED,gFAGC;IAED,6CAmBC;IAGD,8EAgCC;IAED,gFAGC;IAED,+EAgBC;IAED,qCAUC;IAED,4EAaC;IAED,4DAGC;IAED,qDAKC;IAED,gDAYC;IAGD,6DAgBC;CACF;AApkFD;IAgBE,4CAIC;IAnBD,gBAAe;IACf,sBAAkB;IAClB,sBAAkB;IAClB,eAAW;IACX,gBAAY;IACZ,gBAAY;IACZ,eAAa;IACb,eAAa;IACb,6BAA0B;IAC1B,mBAAe;IACf,qBAAiB;IACjB,sBAAoB;IACpB,oBAAkB;IAClB,0BAA2B;IAKzB,uBAAkC;IAGpC,mCAEC;CACF;AAuED;IAUE,oCASC;IAlBD,YAAO;IACP,YAAO;IACP,YAAO;IACP,iBAAY;IACZ,eAAU;IACV,kBAAa;IACb,kBAAa;IACb,qBAAgB;CAYjB;AA/ID;IAiBE,4DAOC;IAvBD,WAAM;IACN,iBAAY;IACZ,yBAAyB;IACzB,cAAW;IACX,gBAAe;IACf,kBAAa;IACb,oBAAqB;IACrB,qBAAsB;IACtB,uBAAwB;IACxB,wBAAmB;IACnB,wBAAmB;IACnB,YAAO;IACP,mBAAc;IACd,sBAAiB;IACjB,oBAAe;IAGb,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,oBAEE;IADA,mCAA2B;CAGhC;AAkDD;IACE,iCAA8B;CAa/B"}
1
+ {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"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"}
package/esm/midy-GM1.js CHANGED
@@ -160,7 +160,13 @@ class Note {
160
160
  }
161
161
  }
162
162
  class Channel {
163
- constructor(audioNodes, settings) {
163
+ constructor(channelNumber, audioNodes, settings) {
164
+ Object.defineProperty(this, "channelNumber", {
165
+ enumerable: true,
166
+ configurable: true,
167
+ writable: true,
168
+ value: 0
169
+ });
164
170
  Object.defineProperty(this, "isDrum", {
165
171
  enumerable: true,
166
172
  configurable: true,
@@ -245,6 +251,7 @@ class Channel {
245
251
  writable: true,
246
252
  value: null
247
253
  });
254
+ this.channelNumber = channelNumber;
248
255
  Object.assign(this, audioNodes);
249
256
  Object.assign(this, settings);
250
257
  this.state = new ControllerState();
@@ -874,6 +881,8 @@ export class MidyGM1 extends EventTarget {
874
881
  return;
875
882
  const soundFont = this.soundFonts[soundFontIndex];
876
883
  const voice = soundFont.getVoice(bank, programNumber, noteNumber, velocity);
884
+ if (!voice)
885
+ return;
877
886
  const { instrument, sampleID } = voice.generators;
878
887
  return soundFontIndex * (2 ** 31) + instrument * (2 ** 24) +
879
888
  (sampleID << 8);
@@ -890,7 +899,7 @@ export class MidyGM1 extends EventTarget {
890
899
  }
891
900
  createChannels(audioContext) {
892
901
  const settings = this.constructor.channelSettings;
893
- return Array.from({ length: this.numChannels }, () => new Channel(this.createChannelAudioNodes(audioContext), settings));
902
+ return Array.from({ length: this.numChannels }, (_, ch) => new Channel(ch, this.createChannelAudioNodes(audioContext), settings));
894
903
  }
895
904
  decodeOggVorbis(sample) {
896
905
  const task = decoderQueue.then(async () => {
@@ -1356,6 +1365,7 @@ export class MidyGM1 extends EventTarget {
1356
1365
  continue;
1357
1366
  const soundFont = this.soundFonts[soundFontIndex];
1358
1367
  const fakeChannel = {
1368
+ channelNumber: ch,
1359
1369
  state: { array: renderControllerStates[ch].slice() },
1360
1370
  programNumber,
1361
1371
  isDrum,
@@ -1674,25 +1684,29 @@ export class MidyGM1 extends EventTarget {
1674
1684
  const volHold = volAttack + voiceParams.volHold;
1675
1685
  const decayDuration = voiceParams.volDecay;
1676
1686
  const adsDuration = volHold + decayDuration * decayCurve * 5;
1677
- const loopStartTime = voiceParams.loopStart / voiceParams.sampleRate;
1678
- const loopDuration = isLoop
1687
+ const sampleLoopStart = voiceParams.loopStart / voiceParams.sampleRate;
1688
+ const sampleLoopDuration = isLoop
1679
1689
  ? (voiceParams.loopEnd - voiceParams.loopStart) / voiceParams.sampleRate
1680
1690
  : 0;
1681
- const loopCount = isLoop && adsDuration > loopStartTime
1682
- ? Math.ceil((adsDuration - loopStartTime) / loopDuration)
1691
+ const playbackRate = voiceParams.playbackRate;
1692
+ const outputLoopStart = sampleLoopStart / playbackRate;
1693
+ const outputLoopDuration = sampleLoopDuration / playbackRate;
1694
+ const loopCount = isLoop && adsDuration > outputLoopStart
1695
+ ? Math.ceil((adsDuration - outputLoopStart) / outputLoopDuration)
1683
1696
  : 0;
1684
- const alignedLoopStart = loopStartTime + loopCount * loopDuration;
1697
+ const alignedLoopStart = outputLoopStart + loopCount * outputLoopDuration;
1685
1698
  const renderDuration = isLoop
1686
- ? alignedLoopStart + loopDuration
1687
- : audioBuffer.duration;
1688
- const offlineContext = new OfflineAudioContext(audioBuffer.numberOfChannels, Math.ceil(renderDuration * this.audioContext.sampleRate), this.audioContext.sampleRate);
1699
+ ? alignedLoopStart + outputLoopDuration
1700
+ : audioBuffer.duration / playbackRate;
1701
+ const sampleRate = this.audioContext.sampleRate;
1702
+ const offlineContext = new OfflineAudioContext(audioBuffer.numberOfChannels, Math.ceil(renderDuration * sampleRate), sampleRate);
1689
1703
  const bufferSource = new AudioBufferSourceNode(offlineContext);
1690
1704
  bufferSource.buffer = audioBuffer;
1691
- bufferSource.playbackRate.value = voiceParams.playbackRate;
1705
+ bufferSource.playbackRate.value = playbackRate;
1692
1706
  bufferSource.loop = isLoop;
1693
1707
  if (isLoop) {
1694
- bufferSource.loopStart = loopStartTime;
1695
- bufferSource.loopEnd = loopStartTime + loopDuration;
1708
+ bufferSource.loopStart = sampleLoopStart;
1709
+ bufferSource.loopEnd = sampleLoopStart + sampleLoopDuration;
1696
1710
  }
1697
1711
  const initialFreq = this.clampCutoffFrequency(this.centToHz(voiceParams.initialFilterFc));
1698
1712
  const filterEnvelopeNode = new BiquadFilterNode(offlineContext, {
@@ -1724,7 +1738,7 @@ export class MidyGM1 extends EventTarget {
1724
1738
  isLoop,
1725
1739
  adsDuration,
1726
1740
  loopStart: alignedLoopStart,
1727
- loopDuration,
1741
+ loopDuration: outputLoopDuration,
1728
1742
  });
1729
1743
  }
1730
1744
  async createAdsrRenderedBuffer(note, voiceParams, audioBuffer, noteDuration) {
@@ -1822,7 +1836,7 @@ export class MidyGM1 extends EventTarget {
1822
1836
  }
1823
1837
  async createFullRenderedBuffer(channel, note, voiceParams, noteDuration, noteEvent = {}) {
1824
1838
  const { startTime: noteStartTime = 0, events: noteEvents = [] } = noteEvent;
1825
- const ch = note.channel ?? 0;
1839
+ const ch = channel.channelNumber;
1826
1840
  const releaseEndDuration = voiceParams.volRelease * releaseCurve * 5;
1827
1841
  const totalDuration = noteDuration + releaseEndDuration;
1828
1842
  const sampleRate = this.audioContext.sampleRate;
@@ -1871,7 +1885,7 @@ export class MidyGM1 extends EventTarget {
1871
1885
  const audioBufferId = this.getVoiceId(channel, noteNumber, velocity);
1872
1886
  if (!realtime) {
1873
1887
  if (cacheMode === "note") {
1874
- return await this.getFullCachedBuffer(note, audioBufferId);
1888
+ return await this.getFullCachedBuffer(channel, note, audioBufferId);
1875
1889
  }
1876
1890
  else if (cacheMode === "adsr") {
1877
1891
  return await this.getAdsrCachedBuffer(note, audioBufferId);
@@ -1962,7 +1976,7 @@ export class MidyGM1 extends EventTarget {
1962
1976
  durationMap.set(cacheKey, renderPromise);
1963
1977
  return await renderPromise;
1964
1978
  }
1965
- async getFullCachedBuffer(note, audioBufferId) {
1979
+ async getFullCachedBuffer(channel, note, audioBufferId) {
1966
1980
  const voiceParams = note.voiceParams;
1967
1981
  const timelineIndex = note.timelineIndex;
1968
1982
  const noteEvent = this.noteOnEvents.get(timelineIndex);
@@ -1987,7 +2001,7 @@ export class MidyGM1 extends EventTarget {
1987
2001
  }
1988
2002
  const renderPromise = (async () => {
1989
2003
  try {
1990
- const rendered = await this.createFullRenderedBuffer(this.channels[note.channel], note, voiceParams, noteDuration, noteEvent);
2004
+ const rendered = await this.createFullRenderedBuffer(channel, note, voiceParams, noteDuration, noteEvent);
1991
2005
  durationMap.set(cacheKey, rendered);
1992
2006
  return rendered;
1993
2007
  }
@@ -2014,7 +2028,6 @@ export class MidyGM1 extends EventTarget {
2014
2028
  note.renderedBuffer = isRendered ? audioBuffer : null;
2015
2029
  note.bufferSource = this.createBufferSource(voiceParams, audioBuffer);
2016
2030
  note.volumeNode = new GainNode(audioContext);
2017
- note.volumeNode.gain.setValueAtTime(1, now);
2018
2031
  const cacheMode = this.cacheMode;
2019
2032
  const isFullCached = isRendered && audioBuffer.isFull === true;
2020
2033
  if (cacheMode === "none") {
@@ -2091,9 +2104,6 @@ export class MidyGM1 extends EventTarget {
2091
2104
  startTime = this.audioContext.currentTime;
2092
2105
  const note = new Note(noteNumber, velocity, startTime);
2093
2106
  note.channel = channelNumber;
2094
- const channel = this.channels[channelNumber];
2095
- note.index = channel.scheduledNotes.length;
2096
- channel.scheduledNotes.push(note);
2097
2107
  return note;
2098
2108
  }
2099
2109
  async setupNote(channelNumber, note, startTime) {
@@ -2116,6 +2126,8 @@ export class MidyGM1 extends EventTarget {
2116
2126
  note.voice = soundFont.getVoice(bank, programNumber, note.noteNumber, note.velocity);
2117
2127
  if (!note.voice)
2118
2128
  return;
2129
+ note.index = channel.scheduledNotes.length;
2130
+ channel.scheduledNotes.push(note);
2119
2131
  await this.setNoteAudioNode(channel, note, realtime);
2120
2132
  this.setNoteRouting(channelNumber, note, startTime);
2121
2133
  note.resolveReady();
@@ -2161,18 +2173,8 @@ export class MidyGM1 extends EventTarget {
2161
2173
  const volRelease = endTime + volDuration;
2162
2174
  note.volumeNode.gain
2163
2175
  .cancelScheduledValues(endTime)
2164
- .setValueAtTime(1, endTime)
2165
2176
  .setTargetAtTime(0, endTime, volDuration * releaseCurve);
2166
- return new Promise((resolve) => {
2167
- this.scheduleTask(() => {
2168
- note.bufferSource.loop = false;
2169
- note.bufferSource.stop(volRelease);
2170
- this.disconnectNote(note);
2171
- channel.scheduledNotes[note.index] = undefined;
2172
- this.releaseFullCache(note);
2173
- resolve();
2174
- }, volRelease);
2175
- });
2177
+ note.bufferSource.stop(volRelease);
2176
2178
  }
2177
2179
  else {
2178
2180
  const now = this.audioContext.currentTime;
@@ -2182,15 +2184,16 @@ export class MidyGM1 extends EventTarget {
2182
2184
  this.releaseFullCache(note);
2183
2185
  return Promise.resolve();
2184
2186
  }
2185
- return new Promise((resolve) => {
2186
- this.scheduleTask(() => {
2187
- this.disconnectNote(note);
2188
- channel.scheduledNotes[note.index] = undefined;
2189
- this.releaseFullCache(note);
2190
- resolve();
2191
- }, naturalEndTime);
2192
- });
2187
+ note.bufferSource.stop(naturalEndTime);
2193
2188
  }
2189
+ return new Promise((resolve) => {
2190
+ note.bufferSource.onended = () => {
2191
+ this.disconnectNote(note);
2192
+ channel.scheduledNotes[note.index] = undefined;
2193
+ this.releaseFullCache(note);
2194
+ resolve();
2195
+ };
2196
+ });
2194
2197
  }
2195
2198
  const volDuration = note.voiceParams.volRelease;
2196
2199
  const volRelease = endTime + volDuration;
@@ -2211,45 +2214,33 @@ export class MidyGM1 extends EventTarget {
2211
2214
  const noteOffTime = note.startTime + (rb.noteDuration ?? 0);
2212
2215
  const isEarlyCut = endTime < noteOffTime;
2213
2216
  if (isEarlyCut) {
2214
- const volRelease = endTime + volDuration;
2215
2217
  note.volumeNode.gain
2216
2218
  .cancelScheduledValues(endTime)
2217
- .setValueAtTime(1, endTime)
2218
2219
  .setTargetAtTime(0, endTime, volDuration * releaseCurve);
2219
- return new Promise((resolve) => {
2220
- this.scheduleTask(() => {
2221
- note.bufferSource.stop(volRelease);
2222
- this.disconnectNote(note);
2223
- channel.scheduledNotes[note.index] = undefined;
2224
- resolve();
2225
- }, volRelease);
2226
- });
2220
+ note.bufferSource.stop(volRelease);
2227
2221
  }
2228
2222
  else {
2229
- return new Promise((resolve) => {
2230
- this.scheduleTask(() => {
2231
- note.bufferSource.stop();
2232
- this.disconnectNote(note);
2233
- channel.scheduledNotes[note.index] = undefined;
2234
- resolve();
2235
- }, naturalEndTime);
2236
- });
2223
+ note.bufferSource.stop(naturalEndTime);
2237
2224
  }
2225
+ return new Promise((resolve) => {
2226
+ note.bufferSource.onended = () => {
2227
+ this.disconnectNote(note);
2228
+ channel.scheduledNotes[note.index] = undefined;
2229
+ resolve();
2230
+ };
2231
+ });
2238
2232
  }
2239
2233
  note.volumeNode.gain
2240
2234
  .cancelScheduledValues(endTime)
2241
- .setValueAtTime(1, endTime)
2242
2235
  .setTargetAtTime(0, endTime, volDuration * releaseCurve);
2243
2236
  }
2237
+ note.bufferSource.stop(volRelease);
2244
2238
  return new Promise((resolve) => {
2245
- this.scheduleTask(() => {
2246
- const bufferSource = note.bufferSource;
2247
- bufferSource.loop = false;
2248
- bufferSource.stop(volRelease);
2239
+ note.bufferSource.onended = () => {
2249
2240
  this.disconnectNote(note);
2250
2241
  channel.scheduledNotes[note.index] = undefined;
2251
2242
  resolve();
2252
- }, volRelease);
2243
+ };
2253
2244
  });
2254
2245
  }
2255
2246
  noteOff(channelNumber, noteNumber, _velocity, endTime, force) {
@@ -2805,9 +2796,10 @@ export class MidyGM1 extends EventTarget {
2805
2796
  setMasterVolume(value, scheduleTime) {
2806
2797
  if (!(0 <= scheduleTime))
2807
2798
  scheduleTime = this.audioContext.currentTime;
2799
+ const timeConstant = this.perceptualSmoothingTime / 5; // 99.3% (5 * tau)
2808
2800
  this.masterVolume.gain
2809
- .cancelScheduledValues(scheduleTime)
2810
- .setValueAtTime(value * value, scheduleTime);
2801
+ .cancelAndHoldAtTime(scheduleTime)
2802
+ .setTargetAtTime(value * value, scheduleTime, timeConstant);
2811
2803
  }
2812
2804
  handleSysEx(data, scheduleTime) {
2813
2805
  switch (data[0]) {
package/esm/midy-GM2.d.ts CHANGED
@@ -94,7 +94,7 @@ export class MidyGM2 extends EventTarget {
94
94
  reverbEffect: {
95
95
  input: any;
96
96
  output: any;
97
- } | undefined;
97
+ };
98
98
  chorusEffect: {
99
99
  input: any;
100
100
  output: any;
@@ -116,7 +116,7 @@ export class MidyGM2 extends EventTarget {
116
116
  gainR: any;
117
117
  merger: any;
118
118
  };
119
- createChannels(audioContext: any): Channel[];
119
+ createChannels(): Channel[];
120
120
  decodeOggVorbis(sample: any): Promise<any>;
121
121
  createAudioBuffer(voiceParams: any): Promise<any>;
122
122
  isLoopDrum(channel: any, noteNumber: any): boolean;
@@ -148,24 +148,13 @@ export class MidyGM2 extends EventTarget {
148
148
  currentTime(): number;
149
149
  processScheduledNotes(channel: any, callback: any): Promise<void>;
150
150
  processActiveNotes(channel: any, scheduleTime: any, callback: any): Promise<void>;
151
- createConvolutionReverbImpulse(audioContext: any, decay: any, preDecay: any): any;
152
- createConvolutionReverb(audioContext: any, impulse: any): {
153
- input: any;
154
- output: any;
155
- convolverNode: any;
156
- };
157
- createCombFilter(audioContext: any, input: any, delay: any, feedback: any): any;
158
- createAllpassFilter(audioContext: any, input: any, delay: any, feedback: any): any;
159
151
  generateDistributedArray(center: any, count: any, varianceRatio?: number, randomness?: number): any[];
160
- createSchroederReverb(audioContext: any, combFeedbacks: any, combDelays: any, allpassFeedbacks: any, allpassDelays: any): {
152
+ setReverbEffect(algorithm: any): void;
153
+ createReverbEffect(algorithm: any): {
161
154
  input: any;
162
155
  output: any;
163
156
  };
164
- createReverbEffect(audioContext: any): {
165
- input: any;
166
- output: any;
167
- } | undefined;
168
- createChorusEffect(audioContext: any): {
157
+ createChorusEffect(): {
169
158
  input: any;
170
159
  output: any;
171
160
  sendGain: any;
@@ -200,7 +189,7 @@ export class MidyGM2 extends EventTarget {
200
189
  getAudioBuffer(channel: any, note: any, realtime: any): Promise<any>;
201
190
  getAdsCachedBuffer(channel: any, note: any, audioBufferId: any, realtime: any): Promise<any>;
202
191
  getAdsrCachedBuffer(channel: any, note: any, audioBufferId: any): Promise<any>;
203
- getFullCachedBuffer(note: any, audioBufferId: any): Promise<any>;
192
+ getFullCachedBuffer(channel: any, note: any, audioBufferId: any): Promise<any>;
204
193
  setNoteAudioNode(channel: any, note: any, realtime: any): Promise<any>;
205
194
  handleExclusiveClass(note: any, channelNumber: any, startTime: any): void;
206
195
  handleDrumExclusiveClass(note: any, channelNumber: any, startTime: any): void;
@@ -353,7 +342,8 @@ export class MidyGM2 extends EventTarget {
353
342
  scheduleTask(callback: any, scheduleTime: any): Promise<any>;
354
343
  }
355
344
  declare class Channel {
356
- constructor(audioNodes: any, settings: any);
345
+ constructor(channelNumber: any, audioNodes: any, settings: any);
346
+ channelNumber: number;
357
347
  isDrum: boolean;
358
348
  programNumber: number;
359
349
  scheduleIndex: number;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"AA4TA;IAgEE;;;;;;;;;;;;;;MAcE;IAEF,6CAuBC;IAlGD,gCAAgC;IAChC,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,qBAAqC;IACrC,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,iCAA2C;IAC3C,cAAU;IACV,cAAa;IACb,iBAAY;IACZ,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IACrC,+BAEE;IAEF,8BAA2B;IAE3B,+BAA4B;IAC5B,4BAAyB;IACzB,8BAA2B;IAE3B,0BAA2B;IAC3B,qBAAoB;IACpB,4BAA6B;IAoB3B,kBAAgC;IAChC,eAAwD;IACxD,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF,uBAAmD;IACnD;;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,kCAAyE;IACzE,sBAAiD;IACjD,oBAAqC;IACrC;;;MAAkE;IAClE;;;;;;;;MAA6C;IAQ/C,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCAYC;IAED,6BAqJC;IAED,sBAuCC;IAED,6EAiBC;IAED;;;;MAWC;IAED,4BAQC;IAED,2CAsBC;IAED,kDA6BC;IAED,mDAIC;IAED,6FAqBC;IAED,gEA2DC;IAED,mCASC;IAED,uBAWC;IAED,yDA4CC;IAED,iCA4EC;IAED,2BAuFC;IAED,uDAEC;IAED,wDAEC;IAED,qCAMC;IAED;;;MAqFC;IAED,kGAeC;IAED,mGAeC;IAED,wEAQC;IAED,oCAqMC;IAED,uBAMC;IAED,sBAIC;IAED,uBAMC;IAED,wBAIC;IAED,0BAKC;IAED,8BAoBC;IAED,wBAYC;IAED,sBAOC;IAED,kEAWC;IAED,kFAYC;IAED,sGAcC;IAED,sCAIC;IAED;;;MA4DC;IAED;;;;;;;;MA2CC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,qCAWC;IAED,2DASC;IAED,oDAEC;IAED,6CAIC;IAED,mDAIC;IAED,2CAoDC;IAED,8EASC;IAED,oEAiBC;IAED,sEASC;IAED,4DAMC;IAED,6EAOC;IAED,qDAkBC;IAED,6CAIC;IAED,8EAmBC;IAED,oEAgCC;IAED,kEAwBC;IAED,+DAgBC;IAED,gIAyEC;IAED,kIA0GC;IAED,gIA6DC;IAED,qEAwBC;IAED,6FAuCC;IAED,+EAgDC;IAED,+EA0CC;IAED,uEAqFC;IAED,0EAiBC;IAED,8EAoBC;IAED,oEAyBC;IAED,yFAQC;IAED,qFAKC;IAED,uEAiCC;IAED,gCAoBC;IAED,kCAWC;IAED,iEAkFC;IAED,4FAqBC;IAED,6CAUC;IAED,qDAUC;IAED,qFAeC;IAED,uFAkBC;IAED,+BAuBC;IAED,kDAOC;IAED,sBAEC;IAED,mFAcC;IAED,4EAYC;IAED,wFAGC;IAED,sEAWC;IAED,mEAaC;IAED,mEAYC;IAED,sEAMC;IAED,oEAQC;IAED,gEAyBC;IAED,gEAyBC;IAED,gCAKC;IAED,kDAKC;IAED,8CAOC;IAED,gEAMC;IAED;;;;;;;;;;;;MAwDC;IAED,oFAMC;IAED,6EAgCC;IAED,qCA2BC;IAED,+FAeC;IAED,+CAEC;IAED,wDAWC;IAED,4EAMC;IAED,wDAeC;IAED,2EAMC;IAED,mEAKC;IAED,mDAQC;IAED;;;MAMC;IAED,gEAWC;IAED,uEAKC;IAED,+CAEC;IAED,sEAGC;IAED,2DAWC;IAED,4EAoBC;IAED,yEAgBC;IAED,+CAEC;IAED,uEAMC;IAED,2EAkBC;IAED,oDAEC;IAED,0EAeC;IAED,sFAQC;IAED,sFAQC;IAED,kFAeC;IAED,2DAMC;IAED,uDAuBC;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,6CAsBC;IAGD,8EAoCC;IAED,gFAGC;IAED,iEAEC;IAED,gEAEC;IAED,gEAIC;IAED,gEAIC;IAED,+EAgCC;IAED,qCAaC;IAED,qCAaC;IAED,4EAwCC;IAED,4DAGC;IAED,qDAMC;IAED,gEAIC;IAED,yDAYC;IAED,kEAGC;IAED,2DAYC;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,wDAEC;IAED,+DAGC;IAED,qEASC;IAED,uEAOC;IAED,6CAEC;IAED,iDAEC;IAED,6CAEC;IAED,iDAEC;IAED,0CAEC;IAED,uCAEC;IAED,wCAEC;IAED,2CAEC;IAED,8BAyBC;IAED,0EAQC;IAED,4EAOC;IAED,qFASC;IAED,+DAEC;IAED,wEAcC;IAED,6DAiBC;IAED,yEAIC;IAED,0CAmBC;IAED,yEAcC;IAED,gDAYC;IAGD,6DAgBC;CACF;AAxhID;IA2BE,gEAKC;IA/BD,sBAAkB;IAClB,gBAAe;IACf,sBAAkB;IAClB,sBAAkB;IAClB,eAAW;IACX,gBAAc;IACd,gBAAY;IACZ,gBAAY;IACZ,gBAAY;IACZ,eAAa;IACb,eAAa;IACb,cAAa;IACb,6BAA0B;IAC1B,mBAAe;IACf,qBAAiB;IACjB,sBAAoB;IACpB,oBAAkB;IAClB,sBAAoB;IACpB,qCAAmD;IACnD,+CAA2C;IAC3C,6CAA4D;IAC5D,sCAAkD;IAClD,sBAAgC;IAChC,sBAAgC;IAChC,0BAA2B;IAMzB,uBAAkC;IAGpC,mCAEC;IAED,mBAKC;CACF;AAuID;IAUE,oCASC;IAlBD,YAAO;IACP,YAAO;IACP,YAAO;IACP,iBAAY;IACZ,eAAU;IACV,kBAAa;IACb,kBAAa;IACb,qBAAgB;CAYjB;AAvOD;IAsBE,4DAOC;IA5BD,WAAM;IACN,iBAAY;IACZ,yBAAyB;IACzB,cAAW;IACX,gBAAe;IACf,kBAAa;IACb,oBAAqB;IACrB,qBAAsB;IACtB,uBAAwB;IACxB,wBAAmB;IACnB,wBAAmB;IACnB,YAAO;IACP,mBAAc;IACd,sBAAiB;IACjB,oBAAe;IACf,YAAO;IACP,mBAAc;IACd,gBAAW;IACX,gBAAW;IACX,6BAA0B;IAGxB,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,oBAEE;IADA,mCAA2B;CAGhC;AAsHD;IACE,iCAA8B;CAa/B"}