spessasynth_core 3.27.7 → 4.0.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/README.md +188 -116
- package/dist/index.d.ts +4057 -0
- package/dist/index.js +17188 -0
- package/dist/index.js.map +1 -0
- package/package.json +23 -6
- package/index.js +0 -132
- package/src/externals/README.md +0 -6
- package/src/externals/fflate/LICENSE +0 -21
- package/src/externals/fflate/fflate.min.js +0 -1
- package/src/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +0 -12
- package/src/externals/stbvorbis_sync/LICENSE +0 -202
- package/src/externals/stbvorbis_sync/NOTICE +0 -6
- package/src/externals/stbvorbis_sync/stbvorbis_sync.min.js +0 -1
- package/src/midi/README.md +0 -32
- package/src/midi/basic_midi.js +0 -587
- package/src/midi/midi_builder.js +0 -203
- package/src/midi/midi_loader.js +0 -321
- package/src/midi/midi_message.js +0 -254
- package/src/midi/midi_sequence.js +0 -230
- package/src/midi/midi_tools/get_note_times.js +0 -154
- package/src/midi/midi_tools/midi_editor.js +0 -611
- package/src/midi/midi_tools/midi_writer.js +0 -105
- package/src/midi/midi_tools/rmidi_writer.js +0 -566
- package/src/midi/midi_tools/used_keys_loaded.js +0 -256
- package/src/midi/xmf_loader.js +0 -454
- package/src/sequencer/README.md +0 -9
- package/src/sequencer/events.js +0 -81
- package/src/sequencer/play.js +0 -362
- package/src/sequencer/process_event.js +0 -165
- package/src/sequencer/process_tick.js +0 -104
- package/src/sequencer/sequencer_engine.js +0 -372
- package/src/sequencer/song_control.js +0 -196
- package/src/soundfont/README.md +0 -11
- package/src/soundfont/basic_soundfont/basic_global_zone.js +0 -6
- package/src/soundfont/basic_soundfont/basic_instrument.js +0 -115
- package/src/soundfont/basic_soundfont/basic_instrument_zone.js +0 -45
- package/src/soundfont/basic_soundfont/basic_preset.js +0 -313
- package/src/soundfont/basic_soundfont/basic_preset_zone.js +0 -39
- package/src/soundfont/basic_soundfont/basic_sample.js +0 -477
- package/src/soundfont/basic_soundfont/basic_soundbank.js +0 -740
- package/src/soundfont/basic_soundfont/basic_zone.js +0 -145
- package/src/soundfont/basic_soundfont/generator.js +0 -76
- package/src/soundfont/basic_soundfont/generator_types.js +0 -151
- package/src/soundfont/basic_soundfont/modulator.js +0 -581
- package/src/soundfont/basic_soundfont/riff_chunk.js +0 -195
- package/src/soundfont/basic_soundfont/write_dls/art2.js +0 -174
- package/src/soundfont/basic_soundfont/write_dls/articulator.js +0 -49
- package/src/soundfont/basic_soundfont/write_dls/combine_zones.js +0 -374
- package/src/soundfont/basic_soundfont/write_dls/ins.js +0 -85
- package/src/soundfont/basic_soundfont/write_dls/lins.js +0 -15
- package/src/soundfont/basic_soundfont/write_dls/modulator_converter.js +0 -330
- package/src/soundfont/basic_soundfont/write_dls/rgn2.js +0 -120
- package/src/soundfont/basic_soundfont/write_dls/wave.js +0 -71
- package/src/soundfont/basic_soundfont/write_dls/write_dls.js +0 -124
- package/src/soundfont/basic_soundfont/write_dls/wsmp.js +0 -78
- package/src/soundfont/basic_soundfont/write_dls/wvpl.js +0 -35
- package/src/soundfont/basic_soundfont/write_sf2/ibag.js +0 -60
- package/src/soundfont/basic_soundfont/write_sf2/igen.js +0 -91
- package/src/soundfont/basic_soundfont/write_sf2/imod.js +0 -62
- package/src/soundfont/basic_soundfont/write_sf2/inst.js +0 -42
- package/src/soundfont/basic_soundfont/write_sf2/pbag.js +0 -57
- package/src/soundfont/basic_soundfont/write_sf2/pgen.js +0 -92
- package/src/soundfont/basic_soundfont/write_sf2/phdr.js +0 -61
- package/src/soundfont/basic_soundfont/write_sf2/pmod.js +0 -62
- package/src/soundfont/basic_soundfont/write_sf2/sdta.js +0 -131
- package/src/soundfont/basic_soundfont/write_sf2/shdr.js +0 -77
- package/src/soundfont/basic_soundfont/write_sf2/write.js +0 -287
- package/src/soundfont/dls/articulator_converter.js +0 -402
- package/src/soundfont/dls/dls_destinations.js +0 -38
- package/src/soundfont/dls/dls_instrument.js +0 -20
- package/src/soundfont/dls/dls_preset.js +0 -43
- package/src/soundfont/dls/dls_sample.js +0 -238
- package/src/soundfont/dls/dls_soundfont.js +0 -183
- package/src/soundfont/dls/dls_sources.js +0 -63
- package/src/soundfont/dls/dls_zone.js +0 -89
- package/src/soundfont/dls/read_articulation.js +0 -300
- package/src/soundfont/dls/read_instrument.js +0 -118
- package/src/soundfont/dls/read_instrument_list.js +0 -17
- package/src/soundfont/dls/read_lart.js +0 -35
- package/src/soundfont/dls/read_region.js +0 -157
- package/src/soundfont/dls/read_samples.js +0 -154
- package/src/soundfont/load_soundfont.js +0 -21
- package/src/soundfont/read_sf2/generators.js +0 -43
- package/src/soundfont/read_sf2/instrument_zones.js +0 -75
- package/src/soundfont/read_sf2/instruments.js +0 -71
- package/src/soundfont/read_sf2/modulators.js +0 -25
- package/src/soundfont/read_sf2/preset_zones.js +0 -79
- package/src/soundfont/read_sf2/presets.js +0 -80
- package/src/soundfont/read_sf2/samples.js +0 -317
- package/src/soundfont/read_sf2/soundfont.js +0 -452
- package/src/soundfont/read_sf2/zones.js +0 -28
- package/src/synthetizer/README.md +0 -7
- package/src/synthetizer/audio_engine/README.md +0 -9
- package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +0 -289
- package/src/synthetizer/audio_engine/engine_components/controller_tables.js +0 -90
- package/src/synthetizer/audio_engine/engine_components/dynamic_modulator_system.js +0 -95
- package/src/synthetizer/audio_engine/engine_components/enums.js +0 -18
- package/src/synthetizer/audio_engine/engine_components/key_modifier_manager.js +0 -151
- package/src/synthetizer/audio_engine/engine_components/lfo.js +0 -26
- package/src/synthetizer/audio_engine/engine_components/lowpass_filter.js +0 -282
- package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +0 -551
- package/src/synthetizer/audio_engine/engine_components/modulation_envelope.js +0 -181
- package/src/synthetizer/audio_engine/engine_components/modulator_curves.js +0 -89
- package/src/synthetizer/audio_engine/engine_components/soundfont_manager.js +0 -265
- package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +0 -124
- package/src/synthetizer/audio_engine/engine_components/unit_converter.js +0 -73
- package/src/synthetizer/audio_engine/engine_components/voice.js +0 -525
- package/src/synthetizer/audio_engine/engine_components/volume_envelope.js +0 -402
- package/src/synthetizer/audio_engine/engine_components/wavetable_oscillator.js +0 -274
- package/src/synthetizer/audio_engine/engine_methods/controller_control/controller_change.js +0 -159
- package/src/synthetizer/audio_engine/engine_methods/controller_control/master_parameters.js +0 -48
- package/src/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +0 -254
- package/src/synthetizer/audio_engine/engine_methods/create_midi_channel.js +0 -20
- package/src/synthetizer/audio_engine/engine_methods/data_entry/awe32.js +0 -198
- package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +0 -281
- package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_fine.js +0 -109
- package/src/synthetizer/audio_engine/engine_methods/mute_channel.js +0 -17
- package/src/synthetizer/audio_engine/engine_methods/note_on.js +0 -214
- package/src/synthetizer/audio_engine/engine_methods/portamento_time.js +0 -92
- package/src/synthetizer/audio_engine/engine_methods/program_change.js +0 -35
- package/src/synthetizer/audio_engine/engine_methods/render_voice.js +0 -214
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/embedded_sound_bank.js +0 -42
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/get_preset.js +0 -0
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/update_preset_list.js +0 -19
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +0 -23
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/note_off.js +0 -56
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_channels.js +0 -16
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_notes.js +0 -30
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/voice_killing.js +0 -63
- package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +0 -1058
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/channel_pressure.js +0 -23
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/pitch_wheel.js +0 -31
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/poly_pressure.js +0 -29
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_master_tuning.js +0 -15
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_modulation_depth.js +0 -27
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_octave_tuning.js +0 -19
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_tuning.js +0 -27
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_all_channels.js +0 -15
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_channel.js +0 -34
- package/src/synthetizer/audio_engine/main_processor.js +0 -813
- package/src/synthetizer/audio_engine/snapshot/apply_synthesizer_snapshot.js +0 -16
- package/src/synthetizer/audio_engine/snapshot/channel_snapshot.js +0 -175
- package/src/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js +0 -116
- package/src/synthetizer/audio_engine/synth_processor_options.js +0 -18
- package/src/synthetizer/synth_constants.js +0 -26
- package/src/utils/README.md +0 -8
- package/src/utils/buffer_to_wav.js +0 -197
- package/src/utils/byte_functions/big_endian.js +0 -32
- package/src/utils/byte_functions/little_endian.js +0 -77
- package/src/utils/byte_functions/string.js +0 -92
- package/src/utils/byte_functions/variable_length_quantity.js +0 -42
- package/src/utils/fill_with_defaults.js +0 -21
- package/src/utils/indexed_array.js +0 -34
- package/src/utils/loggin.js +0 -71
- package/src/utils/other.js +0 -92
- package/src/utils/sysex_detector.js +0 -58
- package/src/utils/xg_hacks.js +0 -193
package/README.md
CHANGED
|
@@ -3,154 +3,199 @@
|
|
|
3
3
|
<img src='https://raw.githubusercontent.com/spessasus/SpessaSynth/refs/heads/master/src/website/spessasynth_logo_rounded.png' width='300' alt='SpessaSynth logo'>
|
|
4
4
|
</p>
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
*A powerful SF2/DLS/MIDI TypeScript/JavaScript library. It works with any modern JS environment that supports
|
|
7
|
+
WebAssembly.*
|
|
8
|
+
|
|
9
|
+
|
|
7
10
|
|
|
8
11
|
It allows you to:
|
|
12
|
+
|
|
9
13
|
- Play MIDI files using SF2/SF3/DLS files!
|
|
10
14
|
- Read and write MIDI files!
|
|
11
15
|
- Write SF2/SF3 files!
|
|
12
16
|
- Convert DLS to SF2! (and back!)
|
|
13
|
-
- [and more!](
|
|
14
|
-
|
|
15
|
-
> Looking for an easy-to-use WebAudioAPI browser wrapper? Try [spessasynth_lib](https://github.com/spessasus/spessasynth_lib)!
|
|
17
|
+
- [and more!](#current-features)
|
|
18
|
+
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
|
|
21
|
+
### v4.0.0 TypeScript Update is here!
|
|
22
|
+
|
|
23
|
+
[**Read about breaking changes here.**](https://spessasus.github.io/spessasynth_core/extra/3-28-migration-guide)
|
|
24
|
+
|
|
25
|
+
> **Tip:**
|
|
26
|
+
>
|
|
27
|
+
> Looking for an easy-to-use WebAudioAPI browser wrapper?
|
|
28
|
+
> Try [spessasynth_lib](https://github.com/spessasus/spessasynth_lib)!
|
|
20
29
|
|
|
21
30
|
### [Project site (consider giving it a star!)](https://github.com/spessasus/spessasynth_core)
|
|
22
31
|
|
|
23
32
|
### Made with spessasynth_core
|
|
33
|
+
|
|
24
34
|
- [SpessaSynth Online SF2/DLS MIDI Player](https://spessasus.github.io/SpessaSynth)
|
|
25
35
|
- [SpessaFont Online SoundFont/DLS Editor](https://spessasus.github.io/SpessaFont)
|
|
26
36
|
|
|
27
|
-
### [Documentation
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
> Note: This is the new heart of the SpessaSynth library, after the repository has been split.
|
|
37
|
+
### [Documentation](https://spessasus.github.io/spessasynth_core)
|
|
31
38
|
|
|
32
39
|
**SpessaSynth Project index**
|
|
33
40
|
|
|
34
41
|
- [spessasynth_core](https://github.com/spessasus/spessasynth_core) (you are here) - SF2/DLS/MIDI library
|
|
35
|
-
- [spessasynth_lib](https://github.com/spessasus/spessasynth_lib) - spessasynth_core wrapper optimized for browsers and
|
|
42
|
+
- [spessasynth_lib](https://github.com/spessasus/spessasynth_lib) - spessasynth_core wrapper optimized for browsers and
|
|
43
|
+
WebAudioAPI
|
|
36
44
|
- [SpessaSynth](https://github.com/spessasus/SpessaSynth) - online/local MIDI player/editor application
|
|
37
45
|
- [SpessaFont](https://github.com/spessasus/SpessaFont) - online SF2/DLS editor
|
|
38
46
|
|
|
39
47
|
## Current Features
|
|
40
48
|
|
|
41
49
|
### Easy Integration
|
|
50
|
+
|
|
42
51
|
- **Modular design:** *Easy integration into other projects (load what you need)*
|
|
43
52
|
- **Flexible:** *It's not just a MIDI player!*
|
|
44
|
-
- **Easy to Use:** *Basic setup is
|
|
53
|
+
- **Easy to Use:** *Basic setup is
|
|
54
|
+
just [two lines of code!](https://spessasus.github.io/spessasynth_core/getting-started#minimal-setup)*
|
|
45
55
|
- **No dependencies:** *Batteries included!*
|
|
56
|
+
- **TypeScript definitions:** *Autocompletion in IDEs!*
|
|
46
57
|
|
|
47
58
|
### Powerful MIDI Synthesizer
|
|
59
|
+
|
|
48
60
|
- Suitable for both **real-time** and **offline** synthesis
|
|
49
61
|
- **Excellent SoundFont support:**
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
- **Full Generator Support**
|
|
63
|
+
- **Full Modulator Support:** *First (to my knowledge) JavaScript SoundFont synth with that feature!*
|
|
64
|
+
- **GeneralUserGS Compatible:**
|
|
65
|
+
*[See more here!](https://github.com/mrbumpy409/GeneralUser-GS/blob/main/documentation/README.md)*
|
|
66
|
+
- **SoundFont3 Support:** Play compressed SoundFonts!
|
|
67
|
+
- **Experimental SF2Pack Support:** Play soundfonts compressed with BASSMIDI! (*Note: only works with vorbis
|
|
68
|
+
compression*)
|
|
69
|
+
- **Can load very large SoundFonts:** up to 4GB! *Note: Only Firefox handles this well; Chromium has a hard-coded
|
|
70
|
+
memory limit*
|
|
56
71
|
- **Great DLS Support:**
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
- **DLS Level 1 Support**
|
|
73
|
+
- **DLS Level 2 Support**
|
|
74
|
+
- **Mobile DLS Support**
|
|
75
|
+
- **Correct articulator support:** *Converts articulators to both modulators and generators!*
|
|
76
|
+
- **Tested and working with gm.dls!**
|
|
77
|
+
- **Correct volume:** *Properly translated to SoundFont volume!*
|
|
78
|
+
- **A-Law encoding support**
|
|
79
|
+
- **Both unsigned 8-bit and signed 16-bit sample support (24-bit theoretically supported as well!)**
|
|
80
|
+
- **Detects special articulator combinations:** *Such as vibratoLfoToPitch*
|
|
66
81
|
- **Soundfont manager:** Stack multiple soundfonts!
|
|
67
82
|
- **Unlimited channel count:** Your CPU is the limit!
|
|
68
83
|
- **Excellent MIDI Standards Support:**
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
84
|
+
- **MIDI Controller Support:** Default supported
|
|
85
|
+
controllers [here](https://spessasus.github.io/spessasynth_core/extra/midi-implementation#default-supported-controllers)
|
|
86
|
+
- **Portamento Support:** *Smooth note gliding!*
|
|
87
|
+
- **Sound Controllers:** *Real-time filter and envelope control!*
|
|
88
|
+
- **MIDI Tuning Standard Support:**
|
|
89
|
+
*[more info here](https://spessasus.github.io/spessasynth_core/extra/midi-implementation#midi-tuning-standard)*
|
|
90
|
+
- [Full **RPN** and limited **NRPN**
|
|
91
|
+
support](https://spessasus.github.io/spessasynth_core/extra/midi-implementation#supported-registered-parameters)
|
|
92
|
+
- **SoundFont2 NRPN Support**
|
|
93
|
+
- [**AWE32**
|
|
94
|
+
NRPN Compatibility Layer](https://spessasus.github.io/spessasynth_core/extra/midi-implementation#awe32-nrpn-compatibility-layer)
|
|
95
|
+
- Supports some [**Roland GS** and **Yamaha XG**
|
|
96
|
+
system exclusives](https://spessasus.github.io/spessasynth_core/extra/midi-implementation#supported-system-exclusives)
|
|
77
97
|
|
|
78
98
|
### Powerful and Fast MIDI Sequencer
|
|
99
|
+
|
|
79
100
|
- **Supports MIDI formats 0, 1, and 2:** *note: format 2 support is experimental as it's very, very rare.*
|
|
80
|
-
- **[Multi-Port MIDI](https://github.
|
|
81
|
-
|
|
82
|
-
- **
|
|
101
|
+
- **[Multi-Port MIDI](https://spessasus.github.io/spessasynth_core/extra/about-multi-port) support:** *More than 16
|
|
102
|
+
channels!*
|
|
103
|
+
- **Smart preloading:** Only preloads the samples used in the MIDI file for smooth playback *(down to key and
|
|
104
|
+
velocity!)*
|
|
105
|
+
- **Lyrics support:** *Add karaoke to your program!*
|
|
83
106
|
- **Raw lyrics available:** Decode in any encoding! *(Kanji? No problem!)*
|
|
84
|
-
- **Loop points support:** Ensures seamless loops
|
|
107
|
+
- **Loop points support:** *Ensures seamless loops!*
|
|
85
108
|
|
|
86
109
|
### Read and Write SoundFont and MIDI Files with Ease
|
|
110
|
+
|
|
87
111
|
#### Read and write MIDI files
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
112
|
+
|
|
113
|
+
- **Smart name detection:** *Handles incorrectly formatted and non-standard track names!*
|
|
114
|
+
- **Raw name available:** Decode in any encoding! *(Kanji? No problem!)*
|
|
115
|
+
- **Port detection during load time:** *Manage ports and channels easily!*
|
|
116
|
+
- **Used channels on track:** *Quickly determine which channels are used!*
|
|
117
|
+
- **Key range detection:** *Detect the key range of the MIDI!*
|
|
118
|
+
- **Easy MIDI editing:**
|
|
119
|
+
Use [helper functions](https://spessasus.github.io/spessasynth_core/writing-files/midi#modifymidi) to modify the
|
|
120
|
+
song to your needs!
|
|
121
|
+
- **Loop detection:** *Automatically detects loops in MIDIs (e.g., from **Touhou Project**)*
|
|
122
|
+
- **First note detection:** *Skip unnecessary silence at the start by jumping to the first note!*
|
|
123
|
+
- **Lyrics support:** *Both regular MIDI and .kar files!*
|
|
124
|
+
- **[Write MIDI files from scratch](https://spessasus.github.io/spessasynth_core/midi/creating-midi-files)**
|
|
125
|
+
- **Easy saving:** *Save with
|
|
126
|
+
just [one function!](https://spessasus.github.io/spessasynth_core/writing-files/midi#writemidi)*
|
|
127
|
+
|
|
128
|
+
#### Read and write [RMID files with embedded sound banks](https://github.com/spessasus/sf2-rmidi-specification#readme)
|
|
129
|
+
|
|
130
|
+
- **[Level 4](https://github.com/spessasus/sf2-rmidi-specification#level-4) compliance:** Reads and writes *everything!*
|
|
131
|
+
- **Compression and trimming support:** *Reduce a MIDI file with a 1GB sound bank to **as small as 5MB**!*
|
|
132
|
+
- **DLS Version support:** *The original legacy format with bank offset detection!*
|
|
133
|
+
- **Automatic bank shifting and validation:** Every sound bank *just works!*
|
|
134
|
+
- **Metadata support:** Add title, artist, album name and cover and more! And of course, read them too! *(In any
|
|
135
|
+
encoding!)*
|
|
136
|
+
- **Compatible with [Falcosoft Midi Player 6!](https://falcosoft.hu/softwares.html#midiplayer)**
|
|
137
|
+
- **Easy saving:**
|
|
138
|
+
*[As simple as saving a MIDI file!](https://spessasus.github.io/spessasynth_core/writing-files/midi#writermidi)*
|
|
108
139
|
|
|
109
140
|
#### Read and write SoundFont2 files
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
141
|
+
|
|
142
|
+
- **Easy info access:** *Just
|
|
143
|
+
an [object of strings!](https://spessasus.github.io/spessasynth_core/sound-bank#soundbankinfo)*
|
|
144
|
+
- **Smart trimming:** Trim the sound bank to only include samples used in the MIDI *(down to key and velocity!)*
|
|
145
|
+
- **SF3 conversion:** *Compress SoundFont2 files to SoundFont3 with variable quality!*
|
|
146
|
+
- **Easy saving:** *Also just [one function!](https://spessasus.github.io/spessasynth_core/sound-bank#write)*
|
|
114
147
|
|
|
115
148
|
#### Read and write SoundFont3 files
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
149
|
+
|
|
150
|
+
- Same features as SoundFont2 but with now with **Ogg Vorbis compression!**
|
|
151
|
+
- **Variable compression quality:** *You choose between file size and quality!*
|
|
152
|
+
- **Compression preserving:** *Avoid decompressing and recompressing uncompressed samples for minimal quality loss!*
|
|
153
|
+
- **Custom compression function:** *Want a different format than Vorbis? No problem!*
|
|
119
154
|
|
|
120
155
|
#### Read and write DLS Level One or Two files
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
156
|
+
|
|
157
|
+
- Read DLS (DownLoadable Sounds) files like SF2 files!
|
|
158
|
+
- **Native support:** *Saving it as sf2 is
|
|
159
|
+
still [just one function!](https://spessasus.github.io/spessasynth_core/sound-bank#write)*
|
|
160
|
+
- *That's right, saving as DLS is
|
|
161
|
+
also [just one function!](https://spessasus.github.io/spessasynth_core/sound-bank#writedls)*
|
|
162
|
+
- Converts articulators to both **modulators** and **generators**!
|
|
163
|
+
- Works with both unsigned 8-bit samples and signed 16-bit samples!
|
|
164
|
+
- **A-Law encoding support:** *Sure, why not?*
|
|
165
|
+
- **Covers special generator cases:** *such as modLfoToPitch*!
|
|
166
|
+
- **Correct volume:** *looking at you, Viena and gm.sf2!*
|
|
167
|
+
- Support built right into the synthesizer!
|
|
168
|
+
- **Convert SF2 to DLS:** [limited support](https://spessasus.github.io/spessasynth_core/extra/dls-conversion-problem)
|
|
131
169
|
|
|
132
170
|
### Export MIDI as WAV
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
171
|
+
|
|
172
|
+
- Save the MIDI file as WAV audio!
|
|
173
|
+
- **Metadata support:** *Embed metadata such as title, artist, album and more!*
|
|
174
|
+
- **Cue points:** *Write MIDI loop points as cue points!*
|
|
175
|
+
- **Loop multiple times:** *Render two (or more) loops into the file for seamless transitions!*
|
|
176
|
+
- *That's right, saving as WAV is
|
|
177
|
+
also [just one function!](https://spessasus.github.io/spessasynth_core/writing-files/wav#audiobuffertowav)*
|
|
138
178
|
|
|
139
179
|
### Limitations
|
|
180
|
+
|
|
140
181
|
- Synth's performance may be questionable sometimes
|
|
141
|
-
- [SF2 to DLS Conversion limits](https://github.
|
|
182
|
+
- [SF2 to DLS Conversion limits](https://spessasus.github.io/spessasynth_core/extra/dls-conversion-problem)
|
|
142
183
|
|
|
143
184
|
#### TODO
|
|
185
|
+
|
|
144
186
|
- Improve the performance of the engine
|
|
145
187
|
- Potentially port the system to Emscripten
|
|
146
188
|
|
|
147
189
|
### Special Thanks
|
|
148
|
-
|
|
190
|
+
|
|
191
|
+
- [FluidSynth](https://github.com/FluidSynth/fluidsynth) - for the source code that helped implement functionality and
|
|
192
|
+
fixes
|
|
149
193
|
- [Polyphone](https://www.polyphone-soundfonts.com/) - for the soundfont testing and editing tool
|
|
150
194
|
- [Meltysynth](https://github.com/sinshu/meltysynth) - for the initial low-pass filter implementation
|
|
151
195
|
- [RecordingBlogs](https://www.recordingblogs.com/) - for detailed explanations on MIDI messages
|
|
152
196
|
- [stbvorbis.js](https://github.com/hajimehoshi/stbvorbis.js) - for the Vorbis decoder
|
|
153
197
|
- [fflate](https://github.com/101arrowz/fflate) - for the MIT DEFLATE implementation
|
|
198
|
+
- [tsup](https://github.com/egoist/tsup) - for the TypeScript bundler
|
|
154
199
|
- [foo_midi](https://github.com/stuerp/foo_midi) - for useful resources on XMF file format
|
|
155
200
|
- [Falcosoft](https://falcosoft.hu) - for help with the RMIDI format
|
|
156
201
|
- [Christian Collins](https://schristiancollins.com) - for various bug reports regarding the synthesizer
|
|
@@ -159,73 +204,100 @@ npm install --save spessasynth_core
|
|
|
159
204
|
**If you like this project, consider giving it a star. It really helps out!**
|
|
160
205
|
|
|
161
206
|
### Short example: MIDI to wav converter
|
|
162
|
-
|
|
207
|
+
|
|
208
|
+
```ts
|
|
163
209
|
import * as fs from "node:fs";
|
|
164
|
-
import {
|
|
210
|
+
import {
|
|
211
|
+
audioToWav,
|
|
212
|
+
BasicMIDI,
|
|
213
|
+
SoundBankLoader,
|
|
214
|
+
SpessaSynthProcessor,
|
|
215
|
+
SpessaSynthSequencer
|
|
216
|
+
} from "../../src";
|
|
165
217
|
|
|
166
218
|
// process arguments
|
|
167
219
|
const args = process.argv.slice(2);
|
|
168
|
-
if (args.length !== 3)
|
|
169
|
-
|
|
170
|
-
|
|
220
|
+
if (args.length !== 3) {
|
|
221
|
+
console.info(
|
|
222
|
+
"Usage: tsx index.ts <soundbank path> <midi path> <wav output path>"
|
|
223
|
+
);
|
|
171
224
|
process.exit();
|
|
172
225
|
}
|
|
173
226
|
const sf = fs.readFileSync(args[0]);
|
|
174
227
|
const mid = fs.readFileSync(args[1]);
|
|
175
|
-
const midi =
|
|
228
|
+
const midi = BasicMIDI.fromArrayBuffer(mid.buffer);
|
|
176
229
|
const sampleRate = 44100;
|
|
177
|
-
const sampleCount = 44100 * (midi.duration + 2);
|
|
230
|
+
const sampleCount = Math.ceil(44100 * (midi.duration + 2));
|
|
178
231
|
const synth = new SpessaSynthProcessor(sampleRate, {
|
|
179
232
|
enableEventSystem: false,
|
|
180
|
-
|
|
233
|
+
enableEffects: false
|
|
181
234
|
});
|
|
182
|
-
synth.
|
|
235
|
+
synth.soundBankManager.reloadManager(
|
|
236
|
+
SoundBankLoader.fromArrayBuffer(sf.buffer)
|
|
237
|
+
);
|
|
183
238
|
await synth.processorInitialized;
|
|
184
239
|
const seq = new SpessaSynthSequencer(synth);
|
|
185
240
|
seq.loadNewSongList([midi]);
|
|
186
|
-
seq.
|
|
241
|
+
seq.play();
|
|
242
|
+
|
|
187
243
|
const outLeft = new Float32Array(sampleCount);
|
|
188
244
|
const outRight = new Float32Array(sampleCount);
|
|
189
245
|
const start = performance.now();
|
|
190
246
|
let filledSamples = 0;
|
|
191
247
|
// note: buffer size is recommended to be very small, as this is the interval between modulator updates and LFO updates
|
|
192
|
-
const
|
|
248
|
+
const BUFFER_SIZE = 128;
|
|
193
249
|
let i = 0;
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const bufRight = new Float32Array(bufSize);
|
|
250
|
+
const durationRounded = Math.floor(seq.midiData.duration * 100) / 100;
|
|
251
|
+
const outputArray = [outLeft, outRight];
|
|
252
|
+
while (filledSamples < sampleCount) {
|
|
198
253
|
// process sequencer
|
|
199
254
|
seq.processTick();
|
|
200
|
-
const arr = [bufLeft, bufRight];
|
|
201
255
|
// render
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
outRight.set(bufRight, filledSamples);
|
|
206
|
-
filledSamples += bufSize;
|
|
256
|
+
const bufferSize = Math.min(BUFFER_SIZE, sampleCount - filledSamples);
|
|
257
|
+
synth.renderAudio(outputArray, [], [], filledSamples, bufferSize);
|
|
258
|
+
filledSamples += bufferSize;
|
|
207
259
|
i++;
|
|
208
260
|
// log progress
|
|
209
|
-
if (i % 100 === 0)
|
|
210
|
-
|
|
211
|
-
|
|
261
|
+
if (i % 100 === 0) {
|
|
262
|
+
console.info(
|
|
263
|
+
"Rendered",
|
|
264
|
+
Math.floor(seq.currentTime * 100) / 100,
|
|
265
|
+
"/",
|
|
266
|
+
durationRounded
|
|
267
|
+
);
|
|
212
268
|
}
|
|
213
269
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
270
|
+
const rendered = Math.floor(performance.now() - start);
|
|
271
|
+
console.info(
|
|
272
|
+
"Rendered in",
|
|
273
|
+
rendered,
|
|
274
|
+
`ms (${Math.floor(((midi.duration * 1000) / rendered) * 100) / 100}x)`
|
|
275
|
+
);
|
|
276
|
+
const wave = audioToWav([outLeft, outRight], sampleRate);
|
|
277
|
+
fs.writeFile(args[2], new Uint8Array(wave), () => {
|
|
278
|
+
console.log(`File written to ${args[2]}`);
|
|
219
279
|
});
|
|
220
|
-
|
|
221
|
-
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Building
|
|
284
|
+
|
|
285
|
+
To build the NPM package, do:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
npm install
|
|
289
|
+
npm run build
|
|
222
290
|
```
|
|
223
291
|
|
|
224
|
-
|
|
292
|
+
The files will be placed in the `dist` folder.
|
|
293
|
+
|
|
294
|
+
## License
|
|
295
|
+
|
|
225
296
|
Copyright © 2025 Spessasus
|
|
226
297
|
Licensed under the Apache-2.0 License.
|
|
227
298
|
|
|
228
299
|
#### Legal
|
|
300
|
+
|
|
229
301
|
This project is in no way endorsed or otherwise affiliated with the MIDI Manufacturers Association,
|
|
230
302
|
Creative Technology Ltd. or E-mu Systems, Inc., or any other organization mentioned.
|
|
231
303
|
SoundFont® is a registered trademark of Creative Technology Ltd.
|