gmuwe 0.0.0-stage → 0.1.0
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/CHANGELOG.md +10 -0
- package/LICENSE +21 -0
- package/README.md +59 -2
- package/dist/gmuwe.js +3560 -0
- package/dist/gmuwe.umd.js +1 -0
- package/dist/types/errors.d.ts +16 -0
- package/dist/types/fm.d.ts +2330 -0
- package/dist/types/index.d.ts +300 -0
- package/dist/types/live.d.ts +189 -0
- package/dist/types/midi.d.ts +150 -0
- package/dist/types/musicalTime.d.ts +120 -0
- package/dist/types/sequencer.d.ts +414 -0
- package/package.json +47 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# What changes, version by version
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
The first release on its own. Until now the engine was a part of `groggo`, the library for point-and-click adventures, where it was built against five scores and a battery of listening probes; `groggo/gmuwe` keeps re-exporting it.
|
|
6
|
+
|
|
7
|
+
- **`MusicEngine`**: plays a `.mid` file through the synthesizer, changes piece on the bar, the beat or a marker the composer wrote, resumes a piece where it left off, fades, renders a score offline into an `AudioBuffer`, and tells where it is: `position()` and `onBeat()` with the audio-clock instant each beat falls on.
|
|
8
|
+
- **`FmSynth`**: a two-operator FM synthesizer with a bank covering the 128 General MIDI programs, the GM2/GS drum kits, per-channel reverb, chorus, pan, rotary and drive, a tempo-locked delay, a limiter on the output and a polyphony reserve that keeps a full chord from clipping. Any instrument can be replaced by a sampled one.
|
|
9
|
+
- **`MidiInput`**: the General MIDI message set played live, from a keyboard or your own code, with the same laws as a score.
|
|
10
|
+
- **`parseMidi`** and the musical-time helpers: ticks, seconds, bars and beats, the next boundary of a grid.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Communication Box
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,60 @@
|
|
|
1
|
-
#
|
|
1
|
+
# gMUWE
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
*A music engine for the browser: an FM synthesizer with a General MIDI bank, a sequencer that plays `.mid` files and knows where the bar is, and a live MIDI input. No dependencies, about 40 KB gzipped.*
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm install gmuwe
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## A note in three lines
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import { MidiInput } from 'gmuwe';
|
|
13
|
+
|
|
14
|
+
const input = new MidiInput({ context: new AudioContext() });
|
|
15
|
+
input.programChange(0, 73); // a flute on channel 1
|
|
16
|
+
input.noteOn(0, 60, 100); // middle C, now
|
|
17
|
+
input.noteOff(0, 60, input.ctx.currentTime + 0.5); // released half a second later
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
A MIDI keyboard takes two more:
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
const midi = await navigator.requestMIDIAccess();
|
|
24
|
+
for (const port of midi.inputs.values()) port.onmidimessage = (e) => input.message(e.data);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## A score in two
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
import { MusicEngine } from 'gmuwe';
|
|
31
|
+
|
|
32
|
+
const music = new MusicEngine({ context: new AudioContext(), fetchFile: (file) => fetch(file).then((r) => r.arrayBuffer()) });
|
|
33
|
+
await music.play('theme.mid');
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The score is a standard MIDI file, written with any notation program. The engine reads its programs, its controllers, its tempo map, its time signatures and its markers, and from then on the music is something a program can talk to:
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
await music.play('battle.mid', { quantize: 'bar' }); // the change falls on the next bar line
|
|
40
|
+
await music.play('ending.mid', { quantize: 'marker', marker: 'coda' }); // or where the composer put a mark
|
|
41
|
+
music.onMarker((name, when) => { /* the scene waits for the music */ });
|
|
42
|
+
music.onBeat((beat, when) => { /* a light pulses on the beat, at `when` on the audio clock */ });
|
|
43
|
+
music.position(); // { bar, beat, tick, seconds, bpm }
|
|
44
|
+
const buffer = await music.render('theme.mid'); // the score played once, offline, as an AudioBuffer
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
A piece resumed is resumed where it was left; a piece stopped on a marker stops on the marker; the loop returns to the tick you say. The browser starts no sound without a gesture of the user: create the `AudioContext` inside a click.
|
|
48
|
+
|
|
49
|
+
## What is inside
|
|
50
|
+
|
|
51
|
+
- **A two-operator FM synthesizer**, in the style of the sound cards of the Nineties, with a bank that covers the 128 General MIDI programs and the GM2/GS drum kits. Reverb, chorus, pan, a rotary speaker and a drive per channel, a delay locked to the tempo, a limiter on the output, and a polyphony reserve that keeps a full chord from clipping instead of letting it.
|
|
52
|
+
- **Sampled instruments in place of synthesized ones**, declared per program, with zones, loops and envelopes, played by the same sequencer under the same laws.
|
|
53
|
+
- **A sequencer** that schedules on the audio clock with a lookahead, follows the tempo map and the time signatures, applies the sustain pedal, the pitch wheel and the volume and expression curves inside a held note, and reports beats and markers with the instant they fall on.
|
|
54
|
+
- **A live input** that plays a note exactly as the same note in a score: the pedal holds it, the wheel bends it, the controllers shape it.
|
|
55
|
+
|
|
56
|
+
## Where to read more
|
|
57
|
+
|
|
58
|
+
The engine was born inside [Groggo](https://groggo.dev-box.it), a library for point-and-click adventures, and the chapter [Sound and music](https://groggo.dev-box.it/en/14-sound-and-music.html) of its guide is the engine's manual: the General MIDI table, the effects, the drum kits, the sample bank, the markers and the live input. Whoever installs Groggo reaches the engine as `groggo/gmuwe`.
|
|
59
|
+
|
|
60
|
+
MIT. gMUWE is a project of [Communication Box](https://communicationbox.it).
|