@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 +38 -20
- package/esm/midy-GM1.d.ts +36 -30
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +184 -142
- package/esm/midy-GM2.d.ts +43 -33
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +324 -279
- package/esm/midy-GMLite.d.ts +35 -30
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +178 -139
- package/esm/midy.d.ts +45 -34
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +414 -302
- package/package.json +2 -2
- package/script/midy-GM1.d.ts +36 -30
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +184 -142
- package/script/midy-GM2.d.ts +43 -33
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +324 -279
- package/script/midy-GMLite.d.ts +35 -30
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +178 -139
- package/script/midy.d.ts +45 -34
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +414 -302
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.
|
|
80
|
+
midy.handleMessage(data, scheduleTime);
|
|
55
81
|
midy.noteOn(channelNumber, noteNumber, velocity);
|
|
56
|
-
midy.setProgramChange(channelNumber,
|
|
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 [
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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 =
|
|
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:
|
|
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,
|
|
43
|
-
vibLfoToPitch: (_channel: any, _note: any,
|
|
44
|
-
modLfoToFilterFc: (channel: any, note: any,
|
|
45
|
-
modLfoToVolume: (channel: any, note: any,
|
|
46
|
-
chorusEffectsSend: (_channel: any, _note: any,
|
|
47
|
-
reverbEffectsSend: (_channel: any, _note: any,
|
|
48
|
-
delayModLFO: (_channel: any, note: any,
|
|
49
|
-
freqModLFO: (_channel: any, note: any,
|
|
50
|
-
delayVibLFO: (_channel: any, _note: any,
|
|
51
|
-
freqVibLFO: (_channel: any, _note: any,
|
|
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(
|
|
71
|
+
scheduleTimelineEvents(scheduleTime: any, queueIndex: any): Promise<any>;
|
|
71
72
|
getQueueIndex(second: any): number;
|
|
72
|
-
|
|
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
|
-
|
|
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,
|
|
126
|
-
vibLfoToPitch: (_channel: any, _note: any,
|
|
127
|
-
modLfoToFilterFc: (channel: any, note: any,
|
|
128
|
-
modLfoToVolume: (channel: any, note: any,
|
|
129
|
-
chorusEffectsSend: (_channel: any, _note: any,
|
|
130
|
-
reverbEffectsSend: (_channel: any, _note: any,
|
|
131
|
-
delayModLFO: (_channel: any, note: any,
|
|
132
|
-
freqModLFO: (_channel: any, note: any,
|
|
133
|
-
delayVibLFO: (_channel: any, _note: any,
|
|
134
|
-
freqVibLFO: (_channel: any, _note: any,
|
|
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
|
-
|
|
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(
|
|
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
|
}
|
package/esm/midy-GM1.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GM1.d.ts","sourceRoot":"","sources":["../src/midy-GM1.js"],"names":[],"mappings":"AA4FA;
|
|
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"}
|