@marmooo/midy 0.3.6 → 0.3.8

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
@@ -18,6 +18,31 @@ This library provides several files depending on the implementation level.
18
18
  [ja v1.0](https://amei.or.jp/midistandardcommittee/Recommended_Practice/GM2_japanese.pdf))
19
19
  - midy.js: full implementation (in progress)
20
20
 
21
+ ## Demo
22
+
23
+ - [@marmooo/midi-player](https://marmooo.github.io/midi-player/) - GUI library
24
+ - [Humidy](https://marmooo.github.io/humidy/) - GM2 MIDI mixer app
25
+
26
+ ## Support Status
27
+
28
+ All implementations follow the specification.
29
+
30
+ | Message | Support | Notes |
31
+ | :----------------------- | :-----: | :------- |
32
+ | Note Off | ✔️ | |
33
+ | Note On | ✔️ | |
34
+ | Polyphonic Key Pressure | ✔️ | full GM2 |
35
+ | Controller Change | ✔️ | full GM2 |
36
+ | Program Change | ✔️ | full GM2 |
37
+ | Channel Pressure | ✔️ | full GM2 |
38
+ | Pitch Bend | ✔️ | |
39
+ | System Exclusive Message | ✔️ | full GM2 |
40
+ | System Common Message | ❌ | |
41
+ | System Real Time Message | ✔️ | full GM2 |
42
+ | MIDI Time Code | ❌ | |
43
+ | MIDI Show Control | ❌ | |
44
+ | MIDI Machine Control | ❌ | |
45
+
21
46
  ## Usage
22
47
 
23
48
  ### Initialization
@@ -29,6 +54,7 @@ This library provides several files depending on the implementation level.
29
54
  import { Midy } from "midy.js";
30
55
 
31
56
  const audioContext = new AudioContext();
57
+ await audioContext.suspend();
32
58
  const midy = new Midy(audioContext);
33
59
  await midy.loadMIDI("test.mid");
34
60
  await midy.loadSoundFont("test.sf3");
@@ -39,8 +65,8 @@ await midy.start();
39
65
 
40
66
  ```js
41
67
  await midy.start();
42
- midy.stop();
43
- midy.pause();
68
+ await midy.stop();
69
+ await midy.pause();
44
70
  await midy.resume();
45
71
  midy.seekTo(second);
46
72
  ```
@@ -51,9 +77,9 @@ There are functions that handle MIDI messages as they are, as well as simplified
51
77
  functions.
52
78
 
53
79
  ```js
54
- midy.handleMIDIMessage(statusByte, data1, data2, scheduleTime);
80
+ midy.handleMessage(data, scheduleTime);
55
81
  midy.noteOn(channelNumber, noteNumber, velocity);
56
- midy.setProgramChange(channelNumber, program);
82
+ midy.setProgramChange(channelNumber, programNumber);
57
83
  ```
58
84
 
59
85
  ### Control Change
@@ -96,19 +122,18 @@ const soundFontURL = "https://soundfonts.pages.dev/GeneralUser_GS_v1.471";
96
122
  function getSoundFontPaths() {
97
123
  const paths = [];
98
124
  for (const instrument of midy.instruments) {
99
- const [bankNumber, programNumber] = instrument.split(":").map(Number);
100
- const table = midy.soundFontTable[programNumber];
101
- if (table.has(bankNumber)) continue;
102
- const program = programNumber.toString().padStart(3, "0");
103
- const path = bankNumber === 128
104
- ? `${soundFontURL}/128.sf3`
105
- : `${soundFontURL}/${program}.sf3`;
106
- paths.push(path);
125
+ const [bank, program] = instrument.split(":");
126
+ const bankNumber = Number(bank);
127
+ const programNumber = Number(program);
128
+ const index = midy.soundFontTable[programNumber][bankNumber];
129
+ if (index !== undefined) continue;
130
+ const baseName = bankNumber === 128 ? "128" : program;
131
+ paths.push(`${soundFontURL}/${baseName}.sf3`);
107
132
  }
108
133
  return paths;
109
134
  }
110
135
 
111
- const paths = this.getSoundFontPaths();
136
+ const paths = getSoundFontPaths();
112
137
  await midy.loadSoundFont(paths);
113
138
  ```
114
139
 
@@ -118,13 +143,6 @@ await midy.loadSoundFont(paths);
118
143
  deno task build
119
144
  ```
120
145
 
121
- ## Test
122
-
123
- WebAudio only works on web browsers currently, so we are testing this library
124
- using the following GUI libraries.
125
-
126
- - [@marmooo/midi-player](https://github.com/marmooo/midi-player)
127
-
128
146
  ## License
129
147
 
130
148
  Apache-2.0
package/esm/midy-GM1.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export class MidyGM1 {
2
2
  static channelSettings: {
3
+ scheduleIndex: number;
3
4
  detune: number;
4
5
  programNumber: number;
5
- bank: number;
6
6
  dataMSB: number;
7
7
  dataLSB: number;
8
8
  rpnMSB: number;
@@ -22,7 +22,7 @@ export class MidyGM1 {
22
22
  startTime: number;
23
23
  resumeTime: number;
24
24
  soundFonts: any[];
25
- soundFontTable: any[];
25
+ soundFontTable: never[][];
26
26
  voiceCounter: Map<any, any>;
27
27
  voiceCache: Map<any, any>;
28
28
  isPlaying: boolean;
@@ -30,6 +30,7 @@ export class MidyGM1 {
30
30
  isPaused: boolean;
31
31
  isStopping: boolean;
32
32
  isSeeking: boolean;
33
+ playPromise: any;
33
34
  timeline: any[];
34
35
  notePromises: any[];
35
36
  instruments: Set<any>;
@@ -38,21 +39,21 @@ export class MidyGM1 {
38
39
  masterVolume: any;
39
40
  scheduler: any;
40
41
  schedulerBuffer: any;
42
+ messageHandlers: any[];
41
43
  voiceParamsHandlers: {
42
- modLfoToPitch: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
43
- vibLfoToPitch: (_channel: any, _note: any, _prevValue: any, _scheduleTime: any) => void;
44
- modLfoToFilterFc: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
45
- modLfoToVolume: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
46
- chorusEffectsSend: (_channel: any, _note: any, _prevValue: any, _scheduleTime: any) => void;
47
- reverbEffectsSend: (_channel: any, _note: any, _prevValue: any, _scheduleTime: any) => void;
48
- delayModLFO: (_channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
49
- freqModLFO: (_channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
50
- delayVibLFO: (_channel: any, _note: any, _prevValue: any, _scheduleTime: any) => void;
51
- freqVibLFO: (_channel: any, _note: any, _prevValue: any, _scheduleTime: any) => void;
44
+ modLfoToPitch: (channel: any, note: any, scheduleTime: any) => void;
45
+ vibLfoToPitch: (_channel: any, _note: any, _scheduleTime: any) => void;
46
+ modLfoToFilterFc: (channel: any, note: any, scheduleTime: any) => void;
47
+ modLfoToVolume: (channel: any, note: any, scheduleTime: any) => void;
48
+ chorusEffectsSend: (_channel: any, _note: any, _scheduleTime: any) => void;
49
+ reverbEffectsSend: (_channel: any, _note: any, _scheduleTime: any) => void;
50
+ delayModLFO: (_channel: any, note: any, scheduleTime: any) => void;
51
+ freqModLFO: (_channel: any, note: any, scheduleTime: any) => void;
52
+ delayVibLFO: (_channel: any, _note: any, _scheduleTime: any) => void;
53
+ freqVibLFO: (_channel: any, _note: any, _scheduleTime: any) => void;
52
54
  };
53
55
  controlChangeHandlers: any[];
54
56
  channels: any[];
55
- initSoundFontTable(): any[];
56
57
  addSoundFont(soundFont: any): void;
57
58
  toUint8Array(input: any): Promise<Uint8Array<ArrayBuffer>>;
58
59
  loadSoundFont(input: any): Promise<void>;
@@ -67,11 +68,14 @@ export class MidyGM1 {
67
68
  createChannels(audioContext: any): any[];
68
69
  createAudioBuffer(voiceParams: any): Promise<any>;
69
70
  createBufferSource(voiceParams: any, audioBuffer: any): any;
70
- scheduleTimelineEvents(t: any, resumeTime: any, queueIndex: any): Promise<any>;
71
+ scheduleTimelineEvents(scheduleTime: any, queueIndex: any): Promise<any>;
71
72
  getQueueIndex(second: any): number;
72
- playNotes(): Promise<any>;
73
+ resetAllStates(): void;
74
+ updateStates(queueIndex: any, nextQueueIndex: any): void;
75
+ playNotes(): Promise<void>;
73
76
  ticksToSecond(ticks: any, secondsPerBeat: any): number;
74
77
  secondToTicks(second: any, secondsPerBeat: any): number;
78
+ getSoundFontId(channel: any): string;
75
79
  extractMidiData(midi: any): {
76
80
  instruments: Set<any>;
77
81
  timeline: any[];
@@ -80,8 +84,8 @@ export class MidyGM1 {
80
84
  stopChannelNotes(channelNumber: any, velocity: any, force: any, scheduleTime: any): Promise<any[]>;
81
85
  stopNotes(velocity: any, force: any, scheduleTime: any): Promise<any[]>;
82
86
  start(): Promise<void>;
83
- stop(): void;
84
- pause(): void;
87
+ stop(): Promise<void>;
88
+ pause(): Promise<void>;
85
89
  resume(): Promise<void>;
86
90
  seekTo(second: any): void;
87
91
  calcTotalTime(): number;
@@ -112,7 +116,9 @@ export class MidyGM1 {
112
116
  findNoteOffIndex(channel: any, noteNumber: any): any;
113
117
  noteOff(channelNumber: any, noteNumber: any, velocity: any, scheduleTime: any): void;
114
118
  releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): void[];
115
- handleMIDIMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): void | Promise<void>;
119
+ createMessageHandlers(): any[];
120
+ handleMessage(data: any, scheduleTime: any): void;
121
+ handleChannelMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): void | Promise<void>;
116
122
  setProgramChange(channelNumber: any, programNumber: any, _scheduleTime: any): void;
117
123
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any, scheduleTime: any): void;
118
124
  setPitchBend(channelNumber: any, value: any, scheduleTime: any): void;
@@ -122,16 +128,16 @@ export class MidyGM1 {
122
128
  setDelayModLFO(note: any, scheduleTime: any): void;
123
129
  setFreqModLFO(note: any, scheduleTime: any): void;
124
130
  createVoiceParamsHandlers(): {
125
- modLfoToPitch: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
126
- vibLfoToPitch: (_channel: any, _note: any, _prevValue: any, _scheduleTime: any) => void;
127
- modLfoToFilterFc: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
128
- modLfoToVolume: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
129
- chorusEffectsSend: (_channel: any, _note: any, _prevValue: any, _scheduleTime: any) => void;
130
- reverbEffectsSend: (_channel: any, _note: any, _prevValue: any, _scheduleTime: any) => void;
131
- delayModLFO: (_channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
132
- freqModLFO: (_channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
133
- delayVibLFO: (_channel: any, _note: any, _prevValue: any, _scheduleTime: any) => void;
134
- freqVibLFO: (_channel: any, _note: any, _prevValue: any, _scheduleTime: any) => void;
131
+ modLfoToPitch: (channel: any, note: any, scheduleTime: any) => void;
132
+ vibLfoToPitch: (_channel: any, _note: any, _scheduleTime: any) => void;
133
+ modLfoToFilterFc: (channel: any, note: any, scheduleTime: any) => void;
134
+ modLfoToVolume: (channel: any, note: any, scheduleTime: any) => void;
135
+ chorusEffectsSend: (_channel: any, _note: any, _scheduleTime: any) => void;
136
+ reverbEffectsSend: (_channel: any, _note: any, _scheduleTime: any) => void;
137
+ delayModLFO: (_channel: any, note: any, scheduleTime: any) => void;
138
+ freqModLFO: (_channel: any, note: any, scheduleTime: any) => void;
139
+ delayVibLFO: (_channel: any, _note: any, _scheduleTime: any) => void;
140
+ freqVibLFO: (_channel: any, _note: any, _scheduleTime: any) => void;
135
141
  };
136
142
  getControllerState(channel: any, noteNumber: any, velocity: any): Float32Array<any>;
137
143
  applyVoiceParams(channel: any, controllerType: any, scheduleTime: any): void;
@@ -162,14 +168,14 @@ export class MidyGM1 {
162
168
  handleCoarseTuningRPN(channelNumber: any, scheduleTime: any): void;
163
169
  setCoarseTuning(channelNumber: any, value: any, scheduleTime: any): void;
164
170
  allSoundOff(channelNumber: any, _value: any, scheduleTime: any): Promise<any[]>;
165
- resetAllStates(channelNumber: any): void;
171
+ resetChannelStates(channelNumber: any): void;
166
172
  resetAllControllers(channelNumber: any, _value: any, scheduleTime: any): void;
167
173
  allNotesOff(channelNumber: any, _value: any, scheduleTime: any): Promise<any[]>;
168
174
  handleUniversalNonRealTimeExclusiveMessage(data: any, scheduleTime: any): void;
169
175
  GM1SystemOn(scheduleTime: any): void;
170
176
  handleUniversalRealTimeExclusiveMessage(data: any, scheduleTime: any): void;
171
177
  handleMasterVolumeSysEx(data: any, scheduleTime: any): void;
172
- setMasterVolume(volume: any, scheduleTime: any): void;
178
+ setMasterVolume(value: any, scheduleTime: any): void;
173
179
  handleSysEx(data: any, scheduleTime: any): void;
174
180
  scheduleTask(callback: any, scheduleTime: any): Promise<any>;
175
181
  }
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AA4FA;IAwBE;;;;;;;;;;;MAWE;IAEF,+BAcC;IAlDD,aAAa;IACb,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,4BAAyB;IACzB,0BAAuB;IACvB,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,oBAAkB;IAClB,sBAAwB;IACxB,2BAAqC;IAgBnC,kBAAgC;IAChC,kBAA8C;IAC9C,eAAwD;IACxD,qBAGE;IACF;;;;;;;;;;;MAA2D;IAC3D,6BAA+D;IAC/D,gBAAiD;IAMnD,4BAMC;IAED,mCASC;IAED,2DAYC;IAED,yCAmBC;IAED,oCASC;IAED,sBAoCC;IAED,8DAcC;IAED;;;;MAeC;IAED,yCAaC;IAED,kDAUC;IAED,4DASC;IAED,+EAkDC;IAED,mCAOC;IAED,0BAgEC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgEC;IAED,kGAeC;IAED,mGAeC;IAED,wEAMC;IAED,uBAMC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;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,6FAyBC;IAED,oGAuCC;IAED,0EAiBC;IAED,kGAmCC;IAED,6FASC;IAED,gCASC;IAED,iEAoBC;IAED,qGAeC;IAED,6CAUC;IAED,qDAUC;IAED,qFASC;IAED,sFAeC;IAED,oGA2BC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAWC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;MA2BC;IAED,oFAMC;IAED,6EAgCC;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,2DAMC;IAED,uDAkBC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,iEAKC;IAED,uEAQC;IAED,mEAKC;IAED,yEAQC;IAED,gFAGC;IAED,yCAqBC;IAGD,8EAgCC;IAED,gFAGC;IAED,+EAgBC;IAED,qCAWC;IAED,4EAaC;IAED,4DAGC;IAED,sDASC;IAED,gDAYC;IAGD,6DAgBC;CACF;AAjgDD;IAWE,0FAMC;IAhBD,cAAW;IACX,gBAAe;IACf,kBAAa;IACb,gBAAW;IACX,iBAAY;IACZ,wBAAmB;IACnB,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,WAAkB;IAClB,iBAA8B;CAEjC"}
1
+ {"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AA4FA;IAyBE;;;;;;;;;;;MAWE;IAEF,+BAeC;IApDD,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,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,kDAUC;IAED,4DASC;IAED,yEAqDC;IAED,mCAOC;IAED,uBAQC;IAED,yDA2BC;IAED,2BAwCC;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,sBAGC;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,6FAyBC;IAED,oGAuCC;IAED,0EAiBC;IAED,kGAgCC;IAED,6FASC;IAED,gCASC;IAED,iEAoBC;IAED,qGAeC;IAED,6CAUC;IAED,qDAUC;IAED,qFASC;IAED,sFAeC;IAED,+BAmBC;IAED,kDAOC;IAED,uGA2BC;IAED,mFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAWC;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,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;AAtiDD;IAWE,0FAMC;IAhBD,cAAW;IACX,gBAAe;IACf,kBAAa;IACb,gBAAW;IACX,iBAAY;IACZ,wBAAmB;IACnB,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,WAAkB;IAClB,iBAA8B;CAEjC"}