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.
Files changed (157) hide show
  1. package/README.md +188 -116
  2. package/dist/index.d.ts +4057 -0
  3. package/dist/index.js +17188 -0
  4. package/dist/index.js.map +1 -0
  5. package/package.json +23 -6
  6. package/index.js +0 -132
  7. package/src/externals/README.md +0 -6
  8. package/src/externals/fflate/LICENSE +0 -21
  9. package/src/externals/fflate/fflate.min.js +0 -1
  10. package/src/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +0 -12
  11. package/src/externals/stbvorbis_sync/LICENSE +0 -202
  12. package/src/externals/stbvorbis_sync/NOTICE +0 -6
  13. package/src/externals/stbvorbis_sync/stbvorbis_sync.min.js +0 -1
  14. package/src/midi/README.md +0 -32
  15. package/src/midi/basic_midi.js +0 -587
  16. package/src/midi/midi_builder.js +0 -203
  17. package/src/midi/midi_loader.js +0 -321
  18. package/src/midi/midi_message.js +0 -254
  19. package/src/midi/midi_sequence.js +0 -230
  20. package/src/midi/midi_tools/get_note_times.js +0 -154
  21. package/src/midi/midi_tools/midi_editor.js +0 -611
  22. package/src/midi/midi_tools/midi_writer.js +0 -105
  23. package/src/midi/midi_tools/rmidi_writer.js +0 -566
  24. package/src/midi/midi_tools/used_keys_loaded.js +0 -256
  25. package/src/midi/xmf_loader.js +0 -454
  26. package/src/sequencer/README.md +0 -9
  27. package/src/sequencer/events.js +0 -81
  28. package/src/sequencer/play.js +0 -362
  29. package/src/sequencer/process_event.js +0 -165
  30. package/src/sequencer/process_tick.js +0 -104
  31. package/src/sequencer/sequencer_engine.js +0 -372
  32. package/src/sequencer/song_control.js +0 -196
  33. package/src/soundfont/README.md +0 -11
  34. package/src/soundfont/basic_soundfont/basic_global_zone.js +0 -6
  35. package/src/soundfont/basic_soundfont/basic_instrument.js +0 -115
  36. package/src/soundfont/basic_soundfont/basic_instrument_zone.js +0 -45
  37. package/src/soundfont/basic_soundfont/basic_preset.js +0 -313
  38. package/src/soundfont/basic_soundfont/basic_preset_zone.js +0 -39
  39. package/src/soundfont/basic_soundfont/basic_sample.js +0 -477
  40. package/src/soundfont/basic_soundfont/basic_soundbank.js +0 -740
  41. package/src/soundfont/basic_soundfont/basic_zone.js +0 -145
  42. package/src/soundfont/basic_soundfont/generator.js +0 -76
  43. package/src/soundfont/basic_soundfont/generator_types.js +0 -151
  44. package/src/soundfont/basic_soundfont/modulator.js +0 -581
  45. package/src/soundfont/basic_soundfont/riff_chunk.js +0 -195
  46. package/src/soundfont/basic_soundfont/write_dls/art2.js +0 -174
  47. package/src/soundfont/basic_soundfont/write_dls/articulator.js +0 -49
  48. package/src/soundfont/basic_soundfont/write_dls/combine_zones.js +0 -374
  49. package/src/soundfont/basic_soundfont/write_dls/ins.js +0 -85
  50. package/src/soundfont/basic_soundfont/write_dls/lins.js +0 -15
  51. package/src/soundfont/basic_soundfont/write_dls/modulator_converter.js +0 -330
  52. package/src/soundfont/basic_soundfont/write_dls/rgn2.js +0 -120
  53. package/src/soundfont/basic_soundfont/write_dls/wave.js +0 -71
  54. package/src/soundfont/basic_soundfont/write_dls/write_dls.js +0 -124
  55. package/src/soundfont/basic_soundfont/write_dls/wsmp.js +0 -78
  56. package/src/soundfont/basic_soundfont/write_dls/wvpl.js +0 -35
  57. package/src/soundfont/basic_soundfont/write_sf2/ibag.js +0 -60
  58. package/src/soundfont/basic_soundfont/write_sf2/igen.js +0 -91
  59. package/src/soundfont/basic_soundfont/write_sf2/imod.js +0 -62
  60. package/src/soundfont/basic_soundfont/write_sf2/inst.js +0 -42
  61. package/src/soundfont/basic_soundfont/write_sf2/pbag.js +0 -57
  62. package/src/soundfont/basic_soundfont/write_sf2/pgen.js +0 -92
  63. package/src/soundfont/basic_soundfont/write_sf2/phdr.js +0 -61
  64. package/src/soundfont/basic_soundfont/write_sf2/pmod.js +0 -62
  65. package/src/soundfont/basic_soundfont/write_sf2/sdta.js +0 -131
  66. package/src/soundfont/basic_soundfont/write_sf2/shdr.js +0 -77
  67. package/src/soundfont/basic_soundfont/write_sf2/write.js +0 -287
  68. package/src/soundfont/dls/articulator_converter.js +0 -402
  69. package/src/soundfont/dls/dls_destinations.js +0 -38
  70. package/src/soundfont/dls/dls_instrument.js +0 -20
  71. package/src/soundfont/dls/dls_preset.js +0 -43
  72. package/src/soundfont/dls/dls_sample.js +0 -238
  73. package/src/soundfont/dls/dls_soundfont.js +0 -183
  74. package/src/soundfont/dls/dls_sources.js +0 -63
  75. package/src/soundfont/dls/dls_zone.js +0 -89
  76. package/src/soundfont/dls/read_articulation.js +0 -300
  77. package/src/soundfont/dls/read_instrument.js +0 -118
  78. package/src/soundfont/dls/read_instrument_list.js +0 -17
  79. package/src/soundfont/dls/read_lart.js +0 -35
  80. package/src/soundfont/dls/read_region.js +0 -157
  81. package/src/soundfont/dls/read_samples.js +0 -154
  82. package/src/soundfont/load_soundfont.js +0 -21
  83. package/src/soundfont/read_sf2/generators.js +0 -43
  84. package/src/soundfont/read_sf2/instrument_zones.js +0 -75
  85. package/src/soundfont/read_sf2/instruments.js +0 -71
  86. package/src/soundfont/read_sf2/modulators.js +0 -25
  87. package/src/soundfont/read_sf2/preset_zones.js +0 -79
  88. package/src/soundfont/read_sf2/presets.js +0 -80
  89. package/src/soundfont/read_sf2/samples.js +0 -317
  90. package/src/soundfont/read_sf2/soundfont.js +0 -452
  91. package/src/soundfont/read_sf2/zones.js +0 -28
  92. package/src/synthetizer/README.md +0 -7
  93. package/src/synthetizer/audio_engine/README.md +0 -9
  94. package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +0 -289
  95. package/src/synthetizer/audio_engine/engine_components/controller_tables.js +0 -90
  96. package/src/synthetizer/audio_engine/engine_components/dynamic_modulator_system.js +0 -95
  97. package/src/synthetizer/audio_engine/engine_components/enums.js +0 -18
  98. package/src/synthetizer/audio_engine/engine_components/key_modifier_manager.js +0 -151
  99. package/src/synthetizer/audio_engine/engine_components/lfo.js +0 -26
  100. package/src/synthetizer/audio_engine/engine_components/lowpass_filter.js +0 -282
  101. package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +0 -551
  102. package/src/synthetizer/audio_engine/engine_components/modulation_envelope.js +0 -181
  103. package/src/synthetizer/audio_engine/engine_components/modulator_curves.js +0 -89
  104. package/src/synthetizer/audio_engine/engine_components/soundfont_manager.js +0 -265
  105. package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +0 -124
  106. package/src/synthetizer/audio_engine/engine_components/unit_converter.js +0 -73
  107. package/src/synthetizer/audio_engine/engine_components/voice.js +0 -525
  108. package/src/synthetizer/audio_engine/engine_components/volume_envelope.js +0 -402
  109. package/src/synthetizer/audio_engine/engine_components/wavetable_oscillator.js +0 -274
  110. package/src/synthetizer/audio_engine/engine_methods/controller_control/controller_change.js +0 -159
  111. package/src/synthetizer/audio_engine/engine_methods/controller_control/master_parameters.js +0 -48
  112. package/src/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +0 -254
  113. package/src/synthetizer/audio_engine/engine_methods/create_midi_channel.js +0 -20
  114. package/src/synthetizer/audio_engine/engine_methods/data_entry/awe32.js +0 -198
  115. package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +0 -281
  116. package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_fine.js +0 -109
  117. package/src/synthetizer/audio_engine/engine_methods/mute_channel.js +0 -17
  118. package/src/synthetizer/audio_engine/engine_methods/note_on.js +0 -214
  119. package/src/synthetizer/audio_engine/engine_methods/portamento_time.js +0 -92
  120. package/src/synthetizer/audio_engine/engine_methods/program_change.js +0 -35
  121. package/src/synthetizer/audio_engine/engine_methods/render_voice.js +0 -214
  122. package/src/synthetizer/audio_engine/engine_methods/soundfont_management/embedded_sound_bank.js +0 -42
  123. package/src/synthetizer/audio_engine/engine_methods/soundfont_management/get_preset.js +0 -0
  124. package/src/synthetizer/audio_engine/engine_methods/soundfont_management/update_preset_list.js +0 -19
  125. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +0 -23
  126. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/note_off.js +0 -56
  127. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_channels.js +0 -16
  128. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_notes.js +0 -30
  129. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/voice_killing.js +0 -63
  130. package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +0 -1058
  131. package/src/synthetizer/audio_engine/engine_methods/tuning_control/channel_pressure.js +0 -23
  132. package/src/synthetizer/audio_engine/engine_methods/tuning_control/pitch_wheel.js +0 -31
  133. package/src/synthetizer/audio_engine/engine_methods/tuning_control/poly_pressure.js +0 -29
  134. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_master_tuning.js +0 -15
  135. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_modulation_depth.js +0 -27
  136. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_octave_tuning.js +0 -19
  137. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_tuning.js +0 -27
  138. package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_all_channels.js +0 -15
  139. package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_channel.js +0 -34
  140. package/src/synthetizer/audio_engine/main_processor.js +0 -813
  141. package/src/synthetizer/audio_engine/snapshot/apply_synthesizer_snapshot.js +0 -16
  142. package/src/synthetizer/audio_engine/snapshot/channel_snapshot.js +0 -175
  143. package/src/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js +0 -116
  144. package/src/synthetizer/audio_engine/synth_processor_options.js +0 -18
  145. package/src/synthetizer/synth_constants.js +0 -26
  146. package/src/utils/README.md +0 -8
  147. package/src/utils/buffer_to_wav.js +0 -197
  148. package/src/utils/byte_functions/big_endian.js +0 -32
  149. package/src/utils/byte_functions/little_endian.js +0 -77
  150. package/src/utils/byte_functions/string.js +0 -92
  151. package/src/utils/byte_functions/variable_length_quantity.js +0 -42
  152. package/src/utils/fill_with_defaults.js +0 -21
  153. package/src/utils/indexed_array.js +0 -34
  154. package/src/utils/loggin.js +0 -71
  155. package/src/utils/other.js +0 -92
  156. package/src/utils/sysex_detector.js +0 -58
  157. 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
- **A powerful SF2/DLS/MIDI JavaScript library. It works with any modern JS environment that supports WebAssembly.**
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!](https://github.com/spessasus/spessasynth_core?tab=readme-ov-file#current-features)
14
- > **TIP:**
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
- ```shell
18
- npm install --save spessasynth_core
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 (in progress!)](https://github.com/spessasus/spessasynth_core/wiki/Home)
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 WebAudioAPI
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 just [two lines of code!](https://github.com/spessasus/spessasynth_core/wiki/Getting-Started#minimal-setup)*
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
- - **Full Generator Support**
51
- - **Full Modulator Support:** *First (to my knowledge) JavaScript SoundFont synth with that feature!*
52
- - **GeneralUserGS Compatible:** *[See more here!](https://github.com/mrbumpy409/GeneralUser-GS/blob/main/documentation/README.md)*
53
- - **SoundFont3 Support:** Play compressed SoundFonts!
54
- - **Experimental SF2Pack Support:** Play soundfonts compressed with BASSMIDI! (*Note: only works with vorbis compression*)
55
- - **Can load very large SoundFonts:** up to 4GB! *Note: Only Firefox handles this well; Chromium has a hard-coded memory limit*
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
- - **DLS Level 1 Support**
58
- - **DLS Level 2 Support**
59
- - **Mobile DLS Support**
60
- - **Correct articulator support:** *Converts articulators to both modulators and generators!*
61
- - **Tested and working with gm.dls!**
62
- - **Correct volume:** *Properly translated to SoundFont volume!*
63
- - **A-Law encoding support**
64
- - **Both unsigned 8-bit and signed 16-bit sample support (24-bit theoretically supported as well!)**
65
- - **Detects special articulator combinations:** *Such as vibratoLfoToPitch*
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
- - **MIDI Controller Support:** Default supported controllers [here](https://github.com/spessasus/spessasynth_core/wiki/MIDI-Implementation#default-supported-controllers)
70
- - **Portamento Support:** Glide the notes!
71
- - **Sound Controllers:** Real-time filter and envelope control!
72
- - **MIDI Tuning Standard Support:** [more info here](https://github.com/spessasus/spessasynth_core/wiki/MIDI-Implementation#midi-tuning-standard)
73
- - [Full **RPN** and limited **NRPN** support](https://github.com/spessasus/spessasynth_core/wiki/MIDI-Implementation#supported-registered-parameters)
74
- - **SoundFont2 NRPN Support**
75
- - [**AWE32** NRPN Compatibility Layer](https://github.com/spessasus/spessasynth_core/wiki/MIDI-Implementation#awe32-nrpn-compatibility-layer)
76
- - Supports some [**Roland GS** and **Yamaha XG** system exclusives](https://github.com/spessasus/spessasynth_core/wiki/MIDI-Implementation#supported-system-exclusives)
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.com/spessasus/spessasynth_core/wiki/About-Multi-Port) support:** More than 16 channels!
81
- - **Smart preloading:** Only preloads the samples used in the MIDI file for smooth playback *(down to key and velocity!)*
82
- - **Lyrics support:** Add karaoke to your program!
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
- - **Smart name detection:** Handles incorrectly formatted and non-standard track names
89
- - **Raw name available:** Decode in any encoding! *(Kanji? No problem!)*
90
- - **Port detection during load time:** Manage ports and channels easily!
91
- - **Used channels on track:** Quickly determine which channels are used
92
- - **Key range detection:** Detect the key range of the MIDI
93
- - **Easy MIDI editing:** Use [helper functions](https://github.com/spessasus/spessasynth_core/wiki/Writing-MIDI-Files#modifymidi) to modify the song to your needs!
94
- - **Loop detection:** Automatically detects loops in MIDIs (e.g., from *Touhou Project*)
95
- - **First note detection:** Skip unnecessary silence at the start by jumping to the first note!
96
- - **Lyrics support:** Both regular MIDI and .kar files!
97
- - **[Write MIDI files from scratch](https://github.com/spessasus/spessasynth_core/wiki/Creating-MIDI-Files)**
98
- - **Easy saving:** Save with just [one function!](https://github.com/spessasus/spessasynth_core/wiki/Writing-MIDI-Files#writemidi)
99
-
100
- #### Read and write [RMID files with embedded SF2 soundfonts](https://github.com/spessasus/sf2-rmidi-specification#readme)
101
- - **[Level 4](https://github.com/spessasus/sf2-rmidi-specification#level-4) compliance:** Reads and writes *everything!*
102
- - **Compression and trimming support:** Reduce a MIDI file with a 1GB soundfont to **as small as 5MB**!
103
- - **DLS Version support:** The original legacy format with bank offset detection!
104
- - **Automatic bank shifting and validation:** Every soundfont *just works!*
105
- - **Metadata support:** Add title, artist, album name and cover and more! And of course, read them too! *(In any encoding!)*
106
- - **Compatible with [Falcosoft Midi Player 6!](https://falcosoft.hu/softwares.html#midiplayer)**
107
- - **Easy saving:** [As simple as saving a MIDI file!](https://github.com/spessasus/spessasynth_core/wiki/Writing-MIDI-Files#writermidi)
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
- - **Easy info access:** Just an [object of strings!](https://github.com/spessasus/spessasynth_core/wiki/SoundFont2-Class#soundfontinfo)
111
- - **Smart trimming:** Trim the SoundFont to only include samples used in the MIDI *(down to key and velocity!)*
112
- - **sf3 conversion:** Compress SoundFont2 files to SoundFont3 with variable quality!
113
- - **Easy saving:** Also just [one function!](https://github.com/spessasus/spessasynth_core/wiki/Sound-Bank-Parser#write)
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
- - Same features as SoundFont2 but with now with **Ogg Vorbis compression!**
117
- - **Variable compression quality:** You choose between file size and quality!
118
- - **Compression preserving:** Avoid decompressing and recompressing uncompressed samples for minimal quality loss!
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
- - Read DLS (DownLoadable Sounds) files as SF2 files!
122
- - **Works like a normal soundfont:** *Saving it as sf2 is still [just one function!](https://github.com/spessasus/spessasynth_core/wiki/Sound-Bank-Parser#write)*
123
- - *That's right, saving as DLS is also [just one function!](https://github.com/spessasus/spessasynth_core/wiki/Sound-Bank-Parser#writedls)*
124
- - Converts articulators to both **modulators** and **generators**!
125
- - Works with both unsigned 8-bit samples and signed 16-bit samples!
126
- - A-Law encoding support
127
- - **Covers special generator cases:** *such as modLfoToPitch*!
128
- - **Correct volume:** *looking at you, Viena and gm.sf2!*
129
- - Support built right into the synthesizer!
130
- - **Convert SF2 to DLS:** [with limitations](https://github.com/spessasus/spessasynth_core/wiki/DLS-Conversion-Problem)
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
- - Save the MIDI file as WAV audio!
134
- - **Metadata support:** *Embed metadata such as title, artist, album and more!*
135
- - **Cue points:** *Write MIDI loop points as cue points!*
136
- - **Loop multiple times:** *Render two (or more) loops into the file for seamless transitions!*
137
- - *That's right, saving as WAV is also [just one function!](https://github.com/spessasus/spessasynth_core/wiki/Writing-Wave-Files#audiobuffertowav)*
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.com/spessasus/SpessaSynth/wiki/DLS-Conversion-Problem)
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
- - [FluidSynth](https://github.com/FluidSynth/fluidsynth) - for the source code that helped implement functionality and fixes
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
- ```js
207
+
208
+ ```ts
163
209
  import * as fs from "node:fs";
164
- import { MIDI, SpessaSynthProcessor, SpessaSynthSequencer, audioToWav, loadSoundFont } from "spessasynth_core";
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
- console.log("Usage: node index.js <soundfont path> <midi path> <wav output path>");
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 = new MIDI(mid);
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
- effectsEnabled: false
233
+ enableEffects: false
181
234
  });
182
- synth.soundfontManager.reloadManager(loadSoundFont(sf));
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.loop = false;
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 bufSize = 128;
248
+ const BUFFER_SIZE = 128;
193
249
  let i = 0;
194
- while (filledSamples + bufSize < sampleCount)
195
- {
196
- const bufLeft = new Float32Array(bufSize);
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
- synth.renderAudio(arr, arr, arr);
203
- // write out
204
- outLeft.set(bufLeft, filledSamples);
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
- console.log("Rendered", seq.currentTime, "/", midi.duration);
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
- console.log("Rendered in", Math.floor(performance.now() - start), "ms");
215
- const wave = audioToWav({
216
- leftChannel: outLeft,
217
- rightChannel: outRight,
218
- sampleRate: sampleRate
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
- fs.writeFileSync(args[2], new Buffer(wave));
221
- process.exit();
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
- # License
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.