spessasynth_lib 3.25.23 → 3.26.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 +29 -114
- package/external_midi/midi_handler.js +14 -14
- package/external_midi/web_midi_link.js +3 -3
- package/index.js +33 -33
- package/package.json +19 -6
- package/{midi → sequencer}/midi_data.js +1 -1
- package/sequencer/{worklet_wrapper/sequencer.js → sequencer.js} +13 -12
- package/sequencer/{worklet_wrapper/sequencer_message.js → sequencer_message.js} +1 -1
- package/synthetizer/README.md +29 -1
- package/synthetizer/audio_effects/reverb_as_binary.js +2 -2
- package/synthetizer/{worklet_wrapper/key_modifier_manager.js → key_modifier_manager.js} +11 -2
- package/synthetizer/{worklet_wrapper/synth_event_handler.js → synth_event_handler.js} +16 -13
- package/synthetizer/{worklet_wrapper/synth_soundfont_manager.js → synth_soundfont_manager.js} +8 -5
- package/synthetizer/{worklet_wrapper/synthetizer.js → synthetizer.js} +29 -23
- package/synthetizer/{audio_engine/message_protocol/worklet_message.js → worklet_message.js} +15 -2
- package/synthetizer/{worklet_wrapper/worklet_processor.js → worklet_processor.js} +214 -31
- package/synthetizer/worklet_processor.min.js +13 -12
- package/synthetizer/worklet_processor.min.js.map +7 -0
- package/synthetizer/{worklet_wrapper/worklet_url.js → worklet_url.js} +2 -0
- package/utils/buffer_to_wav.js +7 -165
- package/utils/other.js +3 -84
- package/externals/fflate/LICENSE +0 -21
- package/externals/fflate/fflate.min.js +0 -1
- package/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +0 -12
- package/externals/stbvorbis_sync/LICENSE +0 -202
- package/externals/stbvorbis_sync/NOTICE +0 -6
- package/externals/stbvorbis_sync/stbvorbis_sync.min.js +0 -1
- package/midi/README.md +0 -32
- package/midi/basic_midi.js +0 -565
- package/midi/midi_builder.js +0 -202
- package/midi/midi_loader.js +0 -324
- package/midi/midi_message.js +0 -254
- package/midi/midi_sequence.js +0 -225
- package/midi/midi_tools/get_note_times.js +0 -154
- package/midi/midi_tools/midi_editor.js +0 -611
- package/midi/midi_tools/midi_writer.js +0 -99
- package/midi/midi_tools/rmidi_writer.js +0 -567
- package/midi/midi_tools/used_keys_loaded.js +0 -238
- package/midi/xmf_loader.js +0 -454
- package/sequencer/sequencer_engine/events.js +0 -104
- package/sequencer/sequencer_engine/play.js +0 -353
- package/sequencer/sequencer_engine/process_event.js +0 -169
- package/sequencer/sequencer_engine/process_tick.js +0 -106
- package/sequencer/sequencer_engine/sequencer_engine.js +0 -335
- package/sequencer/sequencer_engine/song_control.js +0 -229
- package/soundfont/README.md +0 -13
- package/soundfont/basic_soundfont/basic_instrument.js +0 -77
- package/soundfont/basic_soundfont/basic_preset.js +0 -336
- package/soundfont/basic_soundfont/basic_sample.js +0 -197
- package/soundfont/basic_soundfont/basic_soundfont.js +0 -565
- package/soundfont/basic_soundfont/basic_zone.js +0 -64
- package/soundfont/basic_soundfont/basic_zones.js +0 -43
- package/soundfont/basic_soundfont/generator.js +0 -220
- package/soundfont/basic_soundfont/modulator.js +0 -378
- package/soundfont/basic_soundfont/riff_chunk.js +0 -149
- package/soundfont/basic_soundfont/write_dls/art2.js +0 -173
- package/soundfont/basic_soundfont/write_dls/articulator.js +0 -49
- package/soundfont/basic_soundfont/write_dls/combine_zones.js +0 -400
- package/soundfont/basic_soundfont/write_dls/ins.js +0 -103
- package/soundfont/basic_soundfont/write_dls/lins.js +0 -18
- package/soundfont/basic_soundfont/write_dls/modulator_converter.js +0 -330
- package/soundfont/basic_soundfont/write_dls/rgn2.js +0 -121
- package/soundfont/basic_soundfont/write_dls/wave.js +0 -94
- package/soundfont/basic_soundfont/write_dls/write_dls.js +0 -119
- package/soundfont/basic_soundfont/write_dls/wsmp.js +0 -78
- package/soundfont/basic_soundfont/write_dls/wvpl.js +0 -32
- package/soundfont/basic_soundfont/write_sf2/ibag.js +0 -39
- package/soundfont/basic_soundfont/write_sf2/igen.js +0 -80
- package/soundfont/basic_soundfont/write_sf2/imod.js +0 -46
- package/soundfont/basic_soundfont/write_sf2/inst.js +0 -34
- package/soundfont/basic_soundfont/write_sf2/pbag.js +0 -39
- package/soundfont/basic_soundfont/write_sf2/pgen.js +0 -82
- package/soundfont/basic_soundfont/write_sf2/phdr.js +0 -42
- package/soundfont/basic_soundfont/write_sf2/pmod.js +0 -46
- package/soundfont/basic_soundfont/write_sf2/sdta.js +0 -80
- package/soundfont/basic_soundfont/write_sf2/shdr.js +0 -55
- package/soundfont/basic_soundfont/write_sf2/write.js +0 -222
- package/soundfont/dls/articulator_converter.js +0 -396
- package/soundfont/dls/dls_destinations.js +0 -38
- package/soundfont/dls/dls_preset.js +0 -44
- package/soundfont/dls/dls_sample.js +0 -75
- package/soundfont/dls/dls_soundfont.js +0 -186
- package/soundfont/dls/dls_sources.js +0 -62
- package/soundfont/dls/dls_zone.js +0 -95
- package/soundfont/dls/read_articulation.js +0 -299
- package/soundfont/dls/read_instrument.js +0 -121
- package/soundfont/dls/read_instrument_list.js +0 -17
- package/soundfont/dls/read_lart.js +0 -35
- package/soundfont/dls/read_region.js +0 -152
- package/soundfont/dls/read_samples.js +0 -270
- package/soundfont/load_soundfont.js +0 -21
- package/soundfont/read_sf2/generators.js +0 -46
- package/soundfont/read_sf2/instruments.js +0 -66
- package/soundfont/read_sf2/modulators.js +0 -36
- package/soundfont/read_sf2/presets.js +0 -80
- package/soundfont/read_sf2/samples.js +0 -304
- package/soundfont/read_sf2/soundfont.js +0 -305
- package/soundfont/read_sf2/zones.js +0 -263
- package/synthetizer/audio_engine/README.md +0 -25
- package/synthetizer/audio_engine/engine_components/compute_modulator.js +0 -266
- package/synthetizer/audio_engine/engine_components/controller_tables.js +0 -88
- package/synthetizer/audio_engine/engine_components/key_modifier_manager.js +0 -149
- package/synthetizer/audio_engine/engine_components/lfo.js +0 -26
- package/synthetizer/audio_engine/engine_components/lowpass_filter.js +0 -282
- package/synthetizer/audio_engine/engine_components/midi_audio_channel.js +0 -471
- package/synthetizer/audio_engine/engine_components/modulation_envelope.js +0 -181
- package/synthetizer/audio_engine/engine_components/modulator_curves.js +0 -89
- package/synthetizer/audio_engine/engine_components/soundfont_manager.js +0 -228
- package/synthetizer/audio_engine/engine_components/stereo_panner.js +0 -120
- package/synthetizer/audio_engine/engine_components/unit_converter.js +0 -73
- package/synthetizer/audio_engine/engine_components/voice.js +0 -519
- package/synthetizer/audio_engine/engine_components/volume_envelope.js +0 -401
- package/synthetizer/audio_engine/engine_components/wavetable_oscillator.js +0 -263
- package/synthetizer/audio_engine/engine_methods/controller_control/controller_change.js +0 -132
- package/synthetizer/audio_engine/engine_methods/controller_control/master_parameters.js +0 -48
- package/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +0 -241
- package/synthetizer/audio_engine/engine_methods/create_midi_channel.js +0 -27
- package/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +0 -253
- package/synthetizer/audio_engine/engine_methods/data_entry/data_entry_fine.js +0 -66
- package/synthetizer/audio_engine/engine_methods/mute_channel.js +0 -17
- package/synthetizer/audio_engine/engine_methods/note_on.js +0 -175
- package/synthetizer/audio_engine/engine_methods/portamento_time.js +0 -92
- package/synthetizer/audio_engine/engine_methods/program_change.js +0 -61
- package/synthetizer/audio_engine/engine_methods/render_voice.js +0 -196
- package/synthetizer/audio_engine/engine_methods/soundfont_management/clear_sound_font.js +0 -30
- package/synthetizer/audio_engine/engine_methods/soundfont_management/get_preset.js +0 -22
- package/synthetizer/audio_engine/engine_methods/soundfont_management/reload_sound_font.js +0 -40
- package/synthetizer/audio_engine/engine_methods/soundfont_management/send_preset_list.js +0 -34
- package/synthetizer/audio_engine/engine_methods/soundfont_management/set_embedded_sound_font.js +0 -21
- package/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +0 -20
- package/synthetizer/audio_engine/engine_methods/stopping_notes/note_off.js +0 -55
- package/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_channels.js +0 -16
- package/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_notes.js +0 -30
- package/synthetizer/audio_engine/engine_methods/stopping_notes/voice_killing.js +0 -63
- package/synthetizer/audio_engine/engine_methods/system_exclusive.js +0 -776
- package/synthetizer/audio_engine/engine_methods/tuning_control/channel_pressure.js +0 -24
- package/synthetizer/audio_engine/engine_methods/tuning_control/pitch_wheel.js +0 -33
- package/synthetizer/audio_engine/engine_methods/tuning_control/poly_pressure.js +0 -31
- package/synthetizer/audio_engine/engine_methods/tuning_control/set_master_tuning.js +0 -15
- package/synthetizer/audio_engine/engine_methods/tuning_control/set_modulation_depth.js +0 -27
- package/synthetizer/audio_engine/engine_methods/tuning_control/set_octave_tuning.js +0 -19
- package/synthetizer/audio_engine/engine_methods/tuning_control/set_tuning.js +0 -27
- package/synthetizer/audio_engine/engine_methods/tuning_control/transpose_all_channels.js +0 -15
- package/synthetizer/audio_engine/engine_methods/tuning_control/transpose_channel.js +0 -34
- package/synthetizer/audio_engine/main_processor.js +0 -765
- package/synthetizer/audio_engine/message_protocol/README.md +0 -13
- package/synthetizer/audio_engine/message_protocol/message_sending.js +0 -22
- package/synthetizer/audio_engine/snapshot/apply_synthesizer_snapshot.js +0 -14
- package/synthetizer/audio_engine/snapshot/channel_snapshot.js +0 -175
- package/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js +0 -122
- package/synthetizer/synth_constants.js +0 -20
- package/utils/README.md +0 -5
- package/utils/byte_functions/big_endian.js +0 -32
- package/utils/byte_functions/little_endian.js +0 -77
- package/utils/byte_functions/string.js +0 -107
- package/utils/byte_functions/variable_length_quantity.js +0 -42
- package/utils/indexed_array.js +0 -52
- package/utils/loggin.js +0 -79
- package/utils/sysex_detector.js +0 -58
- package/utils/xg_hacks.js +0 -193
- /package/sequencer/{worklet_wrapper/default_sequencer_options.js → default_sequencer_options.js} +0 -0
- /package/synthetizer/{worklet_wrapper/sfman_message.js → sfman_message.js} +0 -0
package/README.md
CHANGED
|
@@ -2,15 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
**A powerful SF2/DLS/MIDI JavaScript library for the browsers.**
|
|
4
4
|
|
|
5
|
+
*This is a WebAudioAPI wrapper for the [spessasynth_core](https://github.com/spessasus/spessasynth_core) library.*
|
|
6
|
+
|
|
7
|
+
> **TIP:**
|
|
8
|
+
> Looking for a bare JS version that works without WebAudioAPI? Try [spessasynth_core](https://github.com/spessasus/spessasynth_core)!
|
|
9
|
+
|
|
5
10
|
```shell
|
|
6
11
|
npm install --save spessasynth_lib
|
|
7
12
|
```
|
|
8
13
|
|
|
9
14
|
### [Project site (consider giving it a star!)](https://github.com/spessasus/SpessaSynth)
|
|
10
15
|
|
|
11
|
-
### [Demo](https://spessasus.github.io/
|
|
16
|
+
### [Demo](https://spessasus.github.io/spessasynth_lib)
|
|
12
17
|
|
|
13
|
-
### [Complete documentation](https://github.com/spessasus/
|
|
18
|
+
### [Complete documentation](https://github.com/spessasus/spessasynth_lib/wiki/)
|
|
14
19
|
|
|
15
20
|
#### Basic example: play a single note
|
|
16
21
|
|
|
@@ -32,126 +37,36 @@ document.getElementById("button").onclick = async () =>
|
|
|
32
37
|
|
|
33
38
|
## Current Features
|
|
34
39
|
|
|
35
|
-
###
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- `.kar` - Soft Karaoke MIDI File
|
|
39
|
-
- `.sf2` - SoundFont2 File
|
|
40
|
-
- `.sf3` - SoundFont2 Compressed File
|
|
41
|
-
- `.sfogg` - SF2Pack With Vorbis Compression
|
|
42
|
-
- `.dls` - Downloadable Sounds Levels 1 & 2 (as well as Mobile DLS)
|
|
43
|
-
- `.rmi` - RIFF MIDI File
|
|
44
|
-
- `.rmi` - RIFF MIDI File With Embedded DLS
|
|
45
|
-
- `.rmi` - [RIFF MIDI File With Embedded SF2](https://github.com/spessasus/sf2-rmidi-specification)
|
|
46
|
-
- `.xmf` - eXtensible Music Format
|
|
47
|
-
- `.mxmf` - Mobile eXtensible Music format
|
|
48
|
-
|
|
49
|
-
*With [an easy way of converting between them!](https://github.com/spessasus/SpessaSynth/wiki/Converting-Between-Formats)*
|
|
50
|
-
|
|
51
|
-
### Easy Integration
|
|
40
|
+
### [All the features of spessasynth_core!](https://github.com/spessasus/spessasynth_core?#current-features)
|
|
41
|
+
|
|
42
|
+
### On top of that...
|
|
52
43
|
- **Modular design:** *Easy integration into other projects (load what you need)*
|
|
53
|
-
- **[Detailed documentation:](https://github.com/spessasus/
|
|
54
|
-
- **
|
|
55
|
-
- **
|
|
56
|
-
- **
|
|
57
|
-
|
|
58
|
-
### Powerful MIDI Synthesizer
|
|
59
|
-
- Suitable for both **real-time** and **offline** synthesis
|
|
60
|
-
- **Excellent SoundFont support:**
|
|
61
|
-
- **Full Generator Support**
|
|
62
|
-
- **Full Modulator Support:** *First (to my knowledge) JavaScript SoundFont synth with that feature!*
|
|
63
|
-
- **GeneralUserGS Compatible:** *[See more here!](https://github.com/mrbumpy409/GeneralUser-GS/blob/main/documentation/README.md)*
|
|
64
|
-
- **SoundFont3 Support:** Play compressed SoundFonts!
|
|
65
|
-
- **Experimental SF2Pack Support:** Play soundfonts compressed with BASSMIDI! (*Note: only works with vorbis compression*)
|
|
66
|
-
- **Can load very large SoundFonts:** up to 4GB! *Note: Only Firefox handles this well; Chromium has a hard-coded memory limit*
|
|
67
|
-
- **Great DLS Support:**
|
|
68
|
-
- **DLS Level 1 Support**
|
|
69
|
-
- **DLS Level 2 Support**
|
|
70
|
-
- **Mobile DLS Support**
|
|
71
|
-
- **Correct articulator support:** *Converts articulators to both modulators and generators!*
|
|
72
|
-
- **Tested and working with gm.dls!**
|
|
73
|
-
- **Correct volume:** *Properly translated to SoundFont volume!*
|
|
74
|
-
- **A-Law encoding support**
|
|
75
|
-
- **Both unsigned 8-bit and signed 16-bit sample support (24-bit theoretically supported as well!)**
|
|
76
|
-
- **Detects special articulator combinations:** *Such as vibratoLfoToPitch*
|
|
77
|
-
- **Soundfont manager:** Stack multiple soundfonts!
|
|
78
|
-
- **Reverb and chorus support:** [customizable!](https://github.com/spessasus/SpessaSynth/wiki/Synthetizer-Class#effects-configuration-object)
|
|
44
|
+
- **[Detailed documentation:](https://github.com/spessasus/spessasynth_lib/wiki/Home)** *With [examples!](https://github.com/spessasus/spessasynth_lib/wiki/Usage-As-Library#examples)*
|
|
45
|
+
- **Easy to Use:** *Basic setup is just [two lines of code!](https://github.com/spessasus/spessasynth_lib/wiki/Usage-As-Library#minimal-setup)*
|
|
46
|
+
- **No external dependencies:** *Just spessasynth_core!*
|
|
47
|
+
- **Reverb and chorus support:** [customizable!](https://github.com/spessasus/spessasynth_lib/wiki/Synthetizer-Class#effects-configuration-object)
|
|
79
48
|
- **Export audio files** using [OfflineAudioContext](https://developer.mozilla.org/en-US/docs/Web/API/OfflineAudioContext)
|
|
80
|
-
- **[Custom modulators for additional controllers](https://github.com/spessasus/SpessaSynth/wiki/Modulator-Class#default-modulators):** *Why not?*
|
|
81
49
|
- **Written using AudioWorklets:**
|
|
82
50
|
- Runs in a **separate thread** for maximum performance
|
|
83
51
|
- Doesn't stop playing even when the main thread is frozen
|
|
84
52
|
- Supported by all modern browsers
|
|
85
|
-
- **Unlimited channel count:** Your CPU is the limit!
|
|
86
|
-
- **Excellent MIDI Standards Support:**
|
|
87
|
-
- **MIDI Controller Support:** Default supported controllers [here](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-controllers)
|
|
88
|
-
- **Portamento Support:** Glide the notes!
|
|
89
|
-
- **Sound Controllers:** Real-time filter and envelope control!
|
|
90
|
-
- **MIDI Tuning Standard Support:** [more info here](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#midi-tuning-standard)
|
|
91
|
-
- [Full **RPN** and limited **NRPN** support](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-registered-parameters)
|
|
92
|
-
- Supports some [**Roland GS** and **Yamaha XG** system exclusives](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-system-exclusives)
|
|
93
53
|
- **High-performance mode:** Play Rush E! *note: may kill your browser ;)*
|
|
94
54
|
|
|
95
|
-
|
|
96
|
-
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
- **Key range detection:** Detect the key range of the MIDI
|
|
111
|
-
- **Easy MIDI editing:** Use [helper functions](https://github.com/spessasus/SpessaSynth/wiki/Writing-MIDI-Files#modifymidi) to modify the song to your needs!
|
|
112
|
-
- **Loop detection:** Automatically detects loops in MIDIs (e.g., from *Touhou Project*)
|
|
113
|
-
- **First note detection:** Skip unnecessary silence at the start by jumping to the first note!
|
|
114
|
-
- **Lyrics support:** Both regular MIDI and .kar files!
|
|
115
|
-
- **[Write MIDI files from scratch](https://github.com/spessasus/SpessaSynth/wiki/Creating-MIDI-Files)**
|
|
116
|
-
- **Easy saving:** Save with just [one function!](https://github.com/spessasus/SpessaSynth/wiki/Writing-MIDI-Files#writemidi)
|
|
117
|
-
|
|
118
|
-
#### Read and write [RMID files with embedded SF2 soundfonts](https://github.com/spessasus/sf2-rmidi-specification#readme)
|
|
119
|
-
- **[Level 4](https://github.com/spessasus/sf2-rmidi-specification#level-4) compliance:** Reads and writes *everything!*
|
|
120
|
-
- **Compression and trimming support:** Reduce a MIDI file with a 1GB soundfont to **as small as 5MB**!
|
|
121
|
-
- **DLS Version support:** The original legacy format with bank offset detection!
|
|
122
|
-
- **Automatic bank shifting and validation:** Every soundfont *just works!*
|
|
123
|
-
- **Metadata support:** Add title, artist, album name and cover and more! And of course read them too! *(In any encoding!)*
|
|
124
|
-
- **Compatible with [Falcosoft Midi Player 6!](https://falcosoft.hu/softwares.html#midiplayer)**
|
|
125
|
-
- **Easy saving:** [As simple as saving a MIDI file!](https://github.com/spessasus/SpessaSynth/wiki/Writing-MIDI-Files#writermidi)
|
|
126
|
-
|
|
127
|
-
#### Read and write SoundFont2 files
|
|
128
|
-
- **Easy info access:** Just an [object of strings!](https://github.com/spessasus/SpessaSynth/wiki/SoundFont2-Class#soundfontinfo)
|
|
129
|
-
- **Smart trimming:** Trim the SoundFont to only include samples used in the MIDI *(down to key and velocity!)*
|
|
130
|
-
- **sf3 conversion:** Compress SoundFont2 files to SoundFont3 with variable quality!
|
|
131
|
-
- **Easy saving:** Also just [one function!](https://github.com/spessasus/SpessaSynth/wiki/SoundFont2-Class#write)
|
|
132
|
-
|
|
133
|
-
#### Read and write SoundFont3 files
|
|
134
|
-
- Same features as SoundFont2 but with now with **Ogg Vorbis compression!**
|
|
135
|
-
- **Variable compression quality:** You choose between file size and quality!
|
|
136
|
-
- **Compression preserving:** Avoid decompressing and recompressing uncompressed samples for minimal quality loss!
|
|
137
|
-
|
|
138
|
-
#### Read and write DLS Level One or Two files
|
|
139
|
-
- Read DLS (DownLoadable Sounds) files as SF2 files!
|
|
140
|
-
- **Works like a normal soundfont:** *Saving it as sf2 is still [just one function!](https://github.com/spessasus/SpessaSynth/wiki/SoundFont2-Class#write)*
|
|
141
|
-
- Converts articulators to both **modulators** and **generators**!
|
|
142
|
-
- Works with both unsigned 8-bit samples and signed 16-bit samples!
|
|
143
|
-
- A-Law encoding support
|
|
144
|
-
- **Covers special generator cases:** *such as modLfoToPitch*!
|
|
145
|
-
- **Correct volume:** *looking at you, Viena and gm.sf2!*
|
|
146
|
-
- Support built right into the synthesizer!
|
|
147
|
-
- **Convert SF2 to DLS:** [with limitations](https://github.com/spessasus/SpessaSynth/wiki/DLS-Conversion-Problem)
|
|
148
|
-
|
|
149
|
-
### Export MIDI as WAV
|
|
150
|
-
- Save the MIDI file as WAV audio!
|
|
151
|
-
- **Metadata support:** *Embed metadata such as title, artist, album and more!*
|
|
152
|
-
- **Cue points:** *Write MIDI loop points as cue points!*
|
|
153
|
-
- **Loop multiple times:** *Render two (or more) loops into the file for seamless transitions!*
|
|
154
|
-
- *That's right, saving as WAV is also [just one function!](https://github.com/spessasus/SpessaSynth/wiki/Writing-Wave-Files#audiobuffertowav)*
|
|
55
|
+
#### TODO
|
|
56
|
+
- Enhance the built-in chorus and reverb effects (suggestions welcome!)
|
|
57
|
+
|
|
58
|
+
### Special Thanks
|
|
59
|
+
- [FluidSynth](https://github.com/FluidSynth/fluidsynth) - for the source code that helped implement functionality and fixes
|
|
60
|
+
- [Polyphone](https://www.polyphone-soundfonts.com/) - for the soundfont testing and editing tool
|
|
61
|
+
- [Meltysynth](https://github.com/sinshu/meltysynth) - for the initial low-pass filter implementation
|
|
62
|
+
- [RecordingBlogs](https://www.recordingblogs.com/) - for detailed explanations on MIDI messages
|
|
63
|
+
- [stbvorbis.js](https://github.com/hajimehoshi/stbvorbis.js) - for the Vorbis decoder
|
|
64
|
+
- [fflate](https://github.com/101arrowz/fflate) - for the MIT DEFLATE implementation
|
|
65
|
+
- [foo_midi](https://github.com/stuerp/foo_midi) - for useful resources on XMF file format
|
|
66
|
+
- [Falcosoft](https://falcosoft.hu) - for help with the RMIDI format
|
|
67
|
+
- [Christian Collins](https://schristiancollins.com) - for various bug reports regarding the synthesizer
|
|
68
|
+
- **And You!** - for checking out this project. I hope you like it :)
|
|
69
|
+
|
|
155
70
|
|
|
156
71
|
# License
|
|
157
72
|
Copyright © 2025 Spessasus
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Synthetizer } from "../synthetizer/
|
|
1
|
+
import { Synthetizer } from "../synthetizer/synthetizer.js";
|
|
2
|
+
import { SpessaSynthCoreUtils as util } from "spessasynth_core";
|
|
2
3
|
import { consoleColors } from "../utils/other.js";
|
|
3
|
-
import { SpessaSynthInfo, SpessaSynthWarn } from "../utils/loggin.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* midi_handler.js
|
|
@@ -9,14 +9,14 @@ import { SpessaSynthInfo, SpessaSynthWarn } from "../utils/loggin.js";
|
|
|
9
9
|
|
|
10
10
|
const NO_INPUT = null;
|
|
11
11
|
|
|
12
|
+
// noinspection JSUnusedGlobalSymbols
|
|
13
|
+
/**
|
|
14
|
+
* A class for handling MIDI devices
|
|
15
|
+
*/
|
|
12
16
|
export class MIDIDeviceHandler
|
|
13
17
|
{
|
|
14
|
-
constructor()
|
|
15
|
-
{
|
|
16
|
-
}
|
|
17
|
-
|
|
18
18
|
/**
|
|
19
|
-
* @returns {Promise<boolean>} if
|
|
19
|
+
* @returns {Promise<boolean>} if succeeded
|
|
20
20
|
*/
|
|
21
21
|
async createMIDIDeviceHandler()
|
|
22
22
|
{
|
|
@@ -36,12 +36,12 @@ export class MIDIDeviceHandler
|
|
|
36
36
|
const response = await navigator.requestMIDIAccess({ sysex: true, software: true });
|
|
37
37
|
this.inputs = response.inputs;
|
|
38
38
|
this.outputs = response.outputs;
|
|
39
|
-
SpessaSynthInfo("%cMIDI handler created!", consoleColors.recognized);
|
|
39
|
+
util.SpessaSynthInfo("%cMIDI handler created!", consoleColors.recognized);
|
|
40
40
|
return true;
|
|
41
41
|
}
|
|
42
42
|
catch (e)
|
|
43
43
|
{
|
|
44
|
-
SpessaSynthWarn(`Could not get MIDI Devices:`, e);
|
|
44
|
+
util.SpessaSynthWarn(`Could not get MIDI Devices:`, e);
|
|
45
45
|
this.inputs = [];
|
|
46
46
|
this.outputs = [];
|
|
47
47
|
return false;
|
|
@@ -49,7 +49,7 @@ export class MIDIDeviceHandler
|
|
|
49
49
|
}
|
|
50
50
|
else
|
|
51
51
|
{
|
|
52
|
-
SpessaSynthWarn("Web MIDI Api not supported!", consoleColors.unrecognized);
|
|
52
|
+
util.SpessaSynthWarn("Web MIDI Api not supported!", consoleColors.unrecognized);
|
|
53
53
|
this.inputs = [];
|
|
54
54
|
this.outputs = [];
|
|
55
55
|
return false;
|
|
@@ -65,7 +65,7 @@ export class MIDIDeviceHandler
|
|
|
65
65
|
{
|
|
66
66
|
this.selectedOutput = output;
|
|
67
67
|
seq.connectMidiOutput(output);
|
|
68
|
-
SpessaSynthInfo(
|
|
68
|
+
util.SpessaSynthInfo(
|
|
69
69
|
`%cPlaying MIDI to %c${output.name}`,
|
|
70
70
|
consoleColors.info,
|
|
71
71
|
consoleColors.recognized
|
|
@@ -80,7 +80,7 @@ export class MIDIDeviceHandler
|
|
|
80
80
|
{
|
|
81
81
|
this.selectedOutput = NO_INPUT;
|
|
82
82
|
seq.connectMidiOutput(undefined);
|
|
83
|
-
SpessaSynthInfo(
|
|
83
|
+
util.SpessaSynthInfo(
|
|
84
84
|
"%cDisconnected from MIDI out.",
|
|
85
85
|
consoleColors.info
|
|
86
86
|
);
|
|
@@ -98,7 +98,7 @@ export class MIDIDeviceHandler
|
|
|
98
98
|
{
|
|
99
99
|
synth.sendMessage(event.data);
|
|
100
100
|
};
|
|
101
|
-
SpessaSynthInfo(
|
|
101
|
+
util.SpessaSynthInfo(
|
|
102
102
|
`%cListening for messages on %c${input.name}`,
|
|
103
103
|
consoleColors.info,
|
|
104
104
|
consoleColors.recognized
|
|
@@ -112,7 +112,7 @@ export class MIDIDeviceHandler
|
|
|
112
112
|
{
|
|
113
113
|
this.selectedInput = NO_INPUT;
|
|
114
114
|
input.onmidimessage = undefined;
|
|
115
|
-
SpessaSynthInfo(
|
|
115
|
+
util.SpessaSynthInfo(
|
|
116
116
|
`%cDisconnected from %c${input.name}`,
|
|
117
117
|
consoleColors.info,
|
|
118
118
|
consoleColors.recognized
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Synthetizer } from "../synthetizer/
|
|
1
|
+
import { Synthetizer } from "../synthetizer/synthetizer.js";
|
|
2
2
|
import { consoleColors } from "../utils/other.js";
|
|
3
|
-
import {
|
|
3
|
+
import { SpessaSynthCoreUtils } from "spessasynth_core";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* web_midi_link.js
|
|
@@ -38,6 +38,6 @@ export class WebMIDILinkHandler
|
|
|
38
38
|
synth.sendMessage(midiData);
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
SpessaSynthInfo("%cWeb MIDI Link handler created!", consoleColors.recognized);
|
|
41
|
+
SpessaSynthCoreUtils.SpessaSynthInfo("%cWeb MIDI Link handler created!", consoleColors.recognized);
|
|
42
42
|
}
|
|
43
43
|
}
|
package/index.js
CHANGED
|
@@ -1,35 +1,38 @@
|
|
|
1
1
|
// Import modules
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
2
|
+
import {
|
|
3
|
+
ALL_CHANNELS_OR_DIFFERENT_ACTION,
|
|
4
|
+
BasicInstrument,
|
|
5
|
+
BasicInstrumentZone,
|
|
6
|
+
BasicMIDI,
|
|
7
|
+
BasicPreset,
|
|
8
|
+
BasicPresetZone,
|
|
9
|
+
BasicSample,
|
|
10
|
+
BasicSoundBank,
|
|
11
|
+
ChannelSnapshot,
|
|
12
|
+
DEFAULT_PERCUSSION,
|
|
13
|
+
Generator,
|
|
14
|
+
IndexedByteArray,
|
|
15
|
+
loadSoundFont,
|
|
16
|
+
messageTypes,
|
|
17
|
+
MIDI,
|
|
18
|
+
MIDIBuilder,
|
|
19
|
+
midiControllers,
|
|
20
|
+
MIDIMessage,
|
|
21
|
+
Modulator,
|
|
22
|
+
modulatorSources,
|
|
23
|
+
NON_CC_INDEX_OFFSET,
|
|
24
|
+
RMIDINFOChunks,
|
|
25
|
+
SpessaSynthLogging,
|
|
26
|
+
SynthesizerSnapshot,
|
|
27
|
+
VOICE_CAP
|
|
28
|
+
} from "spessasynth_core";
|
|
29
|
+
import { Synthetizer } from "./synthetizer/synthetizer.js";
|
|
30
|
+
import { Sequencer } from "./sequencer/sequencer.js";
|
|
31
|
+
import { audioBufferToWav } from "./utils/buffer_to_wav.js";
|
|
32
|
+
import { MIDIDeviceHandler } from "./external_midi/midi_handler.js";
|
|
33
|
+
import { WebMIDILinkHandler } from "./external_midi/web_midi_link.js";
|
|
26
34
|
import { DEFAULT_SYNTH_CONFIG } from "./synthetizer/audio_effects/effects_config.js";
|
|
27
|
-
import { WORKLET_URL_ABSOLUTE } from "./synthetizer/
|
|
28
|
-
import { SynthesizerSnapshot } from "./synthetizer/audio_engine/snapshot/synthesizer_snapshot.js";
|
|
29
|
-
import { ChannelSnapshot } from "./synthetizer/audio_engine/snapshot/channel_snapshot.js";
|
|
30
|
-
import { SpessaSynthProcessor } from "./synthetizer/audio_engine/main_processor.js";
|
|
31
|
-
import { NON_CC_INDEX_OFFSET } from "./synthetizer/audio_engine/engine_components/controller_tables.js";
|
|
32
|
-
import { ALL_CHANNELS_OR_DIFFERENT_ACTION } from "./synthetizer/audio_engine/message_protocol/worklet_message.js";
|
|
35
|
+
import { WORKLET_URL_ABSOLUTE } from "./synthetizer/worklet_url.js";
|
|
33
36
|
|
|
34
37
|
// Export modules
|
|
35
38
|
export {
|
|
@@ -44,9 +47,6 @@ export {
|
|
|
44
47
|
ALL_CHANNELS_OR_DIFFERENT_ACTION,
|
|
45
48
|
NON_CC_INDEX_OFFSET,
|
|
46
49
|
|
|
47
|
-
// Audio Engine
|
|
48
|
-
SpessaSynthProcessor,
|
|
49
|
-
|
|
50
50
|
// SoundFont
|
|
51
51
|
BasicSoundBank,
|
|
52
52
|
BasicSample,
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spessasynth_lib",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "MIDI and SoundFont2/DLS library with no compromises",
|
|
3
|
+
"version": "3.26.1",
|
|
4
|
+
"description": "MIDI and SoundFont2/DLS library for the browsers with no compromises",
|
|
5
5
|
"browser": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
9
|
+
"build": "./minify_processor.sh"
|
|
9
10
|
},
|
|
10
11
|
"repository": {
|
|
11
12
|
"type": "git",
|
|
12
|
-
"url": "git+https://github.com/spessasus/
|
|
13
|
+
"url": "git+https://github.com/spessasus/spessasynth_lib.git"
|
|
13
14
|
},
|
|
14
15
|
"main": "index.js",
|
|
15
16
|
"keywords": [
|
|
@@ -36,8 +37,20 @@
|
|
|
36
37
|
},
|
|
37
38
|
"license": "Apache-2.0",
|
|
38
39
|
"bugs": {
|
|
39
|
-
"url": "https://github.com/spessasus/
|
|
40
|
+
"url": "https://github.com/spessasus/spessasynth_lib/issues",
|
|
40
41
|
"email": "spesekspesek@gmail.com"
|
|
41
42
|
},
|
|
42
|
-
"homepage": "https://github.com/spessasus/
|
|
43
|
+
"homepage": "https://github.com/spessasus/spessasynth_lib#readme",
|
|
44
|
+
"files": [
|
|
45
|
+
"index.js",
|
|
46
|
+
"LICENSE",
|
|
47
|
+
"README.md",
|
|
48
|
+
"sequencer",
|
|
49
|
+
"synthetizer",
|
|
50
|
+
"utils",
|
|
51
|
+
"external_midi"
|
|
52
|
+
],
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"spessasynth_core": "latest"
|
|
55
|
+
}
|
|
43
56
|
}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { Synthetizer } from "
|
|
2
|
-
import { messageTypes } from "../../midi/midi_message.js";
|
|
1
|
+
import { Synthetizer } from "../synthetizer/synthetizer.js";
|
|
3
2
|
import {
|
|
4
3
|
ALL_CHANNELS_OR_DIFFERENT_ACTION,
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
BasicMIDI,
|
|
5
|
+
messageTypes,
|
|
6
|
+
MIDI,
|
|
7
|
+
MIDIMessage,
|
|
8
|
+
SpessaSynthCoreUtils as util
|
|
9
|
+
} from "spessasynth_core";
|
|
10
|
+
import { workletMessageType } from "../synthetizer/worklet_message.js";
|
|
7
11
|
import {
|
|
8
12
|
SongChangeType,
|
|
9
13
|
SpessaSynthSequencerMessageType,
|
|
10
14
|
SpessaSynthSequencerReturnMessageType
|
|
11
15
|
} from "./sequencer_message.js";
|
|
12
|
-
import {
|
|
13
|
-
import { DUMMY_MIDI_DATA, MIDIData } from "../../midi/midi_data.js";
|
|
14
|
-
import { BasicMIDI } from "../../midi/basic_midi.js";
|
|
15
|
-
import { readBytesAsUintBigEndian } from "../../utils/byte_functions/big_endian.js";
|
|
16
|
+
import { DUMMY_MIDI_DATA, MIDIData } from "./midi_data.js";
|
|
16
17
|
import { DEFAULT_SEQUENCER_OPTIONS } from "./default_sequencer_options.js";
|
|
17
18
|
|
|
18
19
|
/**
|
|
@@ -520,7 +521,7 @@ export class Sequencer
|
|
|
520
521
|
}
|
|
521
522
|
catch (e)
|
|
522
523
|
{
|
|
523
|
-
SpessaSynthWarn(`Failed to execute callback for ${callback[0]}:`, e);
|
|
524
|
+
util.SpessaSynthWarn(`Failed to execute callback for ${callback[0]}:`, e);
|
|
524
525
|
}
|
|
525
526
|
}
|
|
526
527
|
}
|
|
@@ -570,7 +571,7 @@ export class Sequencer
|
|
|
570
571
|
|
|
571
572
|
case SpessaSynthSequencerReturnMessageType.timeChange:
|
|
572
573
|
// message data is absolute time
|
|
573
|
-
const time =
|
|
574
|
+
const time = messageData;
|
|
574
575
|
this._callEvents(this.onTimeChange, time);
|
|
575
576
|
this._recalculateStartTime(time);
|
|
576
577
|
if (this.paused && this._preservePlaybackState)
|
|
@@ -619,7 +620,7 @@ export class Sequencer
|
|
|
619
620
|
{
|
|
620
621
|
case messageTypes.setTempo:
|
|
621
622
|
event.messageData.currentIndex = 0;
|
|
622
|
-
const bpm = 60000000 / readBytesAsUintBigEndian(event.messageData, 3);
|
|
623
|
+
const bpm = 60000000 / util.readBytesAsUintBigEndian(event.messageData, 3);
|
|
623
624
|
event.messageData.currentIndex = 0;
|
|
624
625
|
this.currentTempo = Math.round(bpm * 100) / 100;
|
|
625
626
|
if (this.onTempoChange)
|
|
@@ -769,7 +770,7 @@ export class Sequencer
|
|
|
769
770
|
{
|
|
770
771
|
if (this.paused)
|
|
771
772
|
{
|
|
772
|
-
SpessaSynthWarn("Already paused");
|
|
773
|
+
util.SpessaSynthWarn("Already paused");
|
|
773
774
|
return;
|
|
774
775
|
}
|
|
775
776
|
this.pausedTime = this.currentTime;
|
|
@@ -43,7 +43,7 @@ export const SpessaSynthSequencerMessageType = {
|
|
|
43
43
|
export const SpessaSynthSequencerReturnMessageType = {
|
|
44
44
|
midiEvent: 0, // [...midiEventBytes<number>]
|
|
45
45
|
songChange: 1, // [songIndex<number>, isAutoPlayed<boolean>]
|
|
46
|
-
timeChange: 2, //
|
|
46
|
+
timeChange: 2, // newTime<number>
|
|
47
47
|
pause: 3, // no data
|
|
48
48
|
getMIDI: 4, // midiData<MIDI>
|
|
49
49
|
midiError: 5, // errorMSG<string>
|
package/synthetizer/README.md
CHANGED
|
@@ -7,4 +7,32 @@ This is the heart of the SpessaSynth library.
|
|
|
7
7
|
- `audio_effects` - the WebAudioAPI audio effects.
|
|
8
8
|
- `worklet_wrapper` - the wrapper for the core synthesis engine using audio worklets.
|
|
9
9
|
|
|
10
|
-
`worklet_processor.min.js` - the minified worklet processor code to import.
|
|
10
|
+
`worklet_processor.min.js` - the minified worklet processor code to import.
|
|
11
|
+
|
|
12
|
+
# About the message protocol
|
|
13
|
+
Since spessasynth_lib runs in the audioWorklet thread, here is an explanation of how it works:
|
|
14
|
+
|
|
15
|
+
There's one processor per synthesizer, with a `MessagePort` for communication.
|
|
16
|
+
Each processor has a single `SpessaSynthequencer` instance that is idle by default.
|
|
17
|
+
|
|
18
|
+
The `Synthetizer`,
|
|
19
|
+
`Sequencer` and `SoundFontManager` classes are all interfaces
|
|
20
|
+
that do not do anything except sending the commands to te processor.
|
|
21
|
+
|
|
22
|
+
The synthesizer sends the commands (note on, off, etc.) directly to the processor where they are processed and executed.
|
|
23
|
+
|
|
24
|
+
The sequencer sends the commands through the connected synthesizer's messagePort, which then get processed as sequencer messages and routed properly.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## How it works in spessasynth_lib
|
|
28
|
+
Both `Synthetizer` and `Sequencer` are essentially "remote control"
|
|
29
|
+
for the actual sequencer and synthesizer in the audio worklet thread (here)
|
|
30
|
+
These core components are wrapped in the AudioWorkletProcessor, which is receiving both commands and data (MIDIs, sound banks)
|
|
31
|
+
through the message port, and sends data back (events, time changes, status changes, etc.).
|
|
32
|
+
|
|
33
|
+
For example,
|
|
34
|
+
the playback to WebMIDIAPI is actually the sequencer in the worklet thread
|
|
35
|
+
playing back the sequence and then postMessaging the commands through the synthesizer to the sequencer
|
|
36
|
+
which actually sends them to the specified output.
|
|
37
|
+
|
|
38
|
+
The wonders of separate audio thread...
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { rbCompressed } from "./rb_compressed.min.js";
|
|
2
|
-
import {
|
|
2
|
+
import { SpessaSynthCoreUtils } from "spessasynth_core";
|
|
3
3
|
|
|
4
4
|
// convert the base64 string to array buffer
|
|
5
5
|
const binaryString = atob(rbCompressed);
|
|
@@ -14,5 +14,5 @@ for (let i = 0; i < binaryString.length; i++)
|
|
|
14
14
|
* the reverb is zlib compressed, decompress here
|
|
15
15
|
* @type {ArrayBuffer}
|
|
16
16
|
*/
|
|
17
|
-
const reverbBufferBinary = inflateSync(binary).buffer;
|
|
17
|
+
const reverbBufferBinary = SpessaSynthCoreUtils.inflateSync(binary).buffer;
|
|
18
18
|
export { reverbBufferBinary };
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
import { workletMessageType } from "
|
|
2
|
-
import { KeyModifier
|
|
1
|
+
import { workletMessageType } from "./worklet_message.js";
|
|
2
|
+
import { KeyModifier } from "spessasynth_core";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @enum {number}
|
|
6
|
+
*/
|
|
7
|
+
export const workletKeyModifierMessageType = {
|
|
8
|
+
addMapping: 0, // [channel<number>, midiNote<number>, mapping<KeyModifier>]
|
|
9
|
+
deleteMapping: 1, // [channel<number>, midiNote<number>]
|
|
10
|
+
clearMappings: 2 // <no data>
|
|
11
|
+
};
|
|
3
12
|
|
|
4
13
|
export class WorkletKeyModifierManagerWrapper
|
|
5
14
|
{
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { synthDisplayTypes } from "spessasynth_core";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* synth_event_handler.js
|
|
3
|
-
* purpose: manages the synthesizer's event system, calling
|
|
5
|
+
* purpose: manages the synthesizer's event system, calling assigned functions when synthesizer requests dispatching the event
|
|
4
6
|
*/
|
|
5
7
|
|
|
6
8
|
/**
|
|
@@ -56,14 +58,14 @@
|
|
|
56
58
|
/**
|
|
57
59
|
* @typedef {Object} SynthDisplayCallback
|
|
58
60
|
* @property {Uint8Array} displayData - The data to display.
|
|
59
|
-
* @property {
|
|
61
|
+
* @property {synthDisplayTypes} displayType - The type of display.
|
|
60
62
|
*/
|
|
61
63
|
|
|
62
64
|
/**
|
|
63
65
|
* @typedef {Object} PitchWheelCallback
|
|
64
66
|
* @property {number} channel - The MIDI channel number.
|
|
65
|
-
* @property {number} MSB - The most significant byte of the pitch
|
|
66
|
-
* @property {number} LSB - The least significant byte of the pitch
|
|
67
|
+
* @property {number} MSB - The most significant byte of the pitch-wheel value.
|
|
68
|
+
* @property {number} LSB - The least significant byte of the pitch-wheel value.
|
|
67
69
|
*/
|
|
68
70
|
|
|
69
71
|
/**
|
|
@@ -123,15 +125,15 @@ export class EventHandler
|
|
|
123
125
|
* @type {Object<EventTypes, Object<string, function(EventCallbackData)>>}
|
|
124
126
|
*/
|
|
125
127
|
this.events = {
|
|
126
|
-
"noteoff": {}, // called on note off message
|
|
127
|
-
"noteon": {}, // called on note on message
|
|
128
|
-
"pitchwheel": {}, // called on pitch
|
|
129
|
-
"controllerchange": {}, // called on controller change
|
|
130
|
-
"programchange": {}, // called on program change
|
|
131
|
-
"channelpressure": {}, // called on channel pressure message
|
|
132
|
-
"polypressure": {}, // called on poly pressure message
|
|
133
|
-
"drumchange": {}, // called when channel type changes
|
|
134
|
-
"stopall": {}, // called when synth receives stop all command
|
|
128
|
+
"noteoff": {}, // called on a note off message
|
|
129
|
+
"noteon": {}, // called on a note on message
|
|
130
|
+
"pitchwheel": {}, // called on a pitch-wheel change
|
|
131
|
+
"controllerchange": {}, // called on a controller change
|
|
132
|
+
"programchange": {}, // called on a program change
|
|
133
|
+
"channelpressure": {}, // called on a channel pressure message
|
|
134
|
+
"polypressure": {}, // called on a poly pressure message
|
|
135
|
+
"drumchange": {}, // called when a channel type changes
|
|
136
|
+
"stopall": {}, // called when the synth receives stop all command
|
|
135
137
|
"newchannel": {}, // called when a new channel is created
|
|
136
138
|
"mutechannel": {}, // called when a channel is muted/unmuted
|
|
137
139
|
"presetlistchange": {}, // called when the preset list changes (soundfont gets reloaded)
|
|
@@ -158,6 +160,7 @@ export class EventHandler
|
|
|
158
160
|
this.events[name][id] = callback;
|
|
159
161
|
}
|
|
160
162
|
|
|
163
|
+
// noinspection JSUnusedGlobalSymbols
|
|
161
164
|
/**
|
|
162
165
|
* Removes an event listener
|
|
163
166
|
* @param name {EventTypes}
|