spessasynth_lib 3.25.23 → 3.26.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 (168) hide show
  1. package/README.md +29 -114
  2. package/index.js +33 -33
  3. package/package.json +16 -6
  4. package/external_midi/README.md +0 -4
  5. package/external_midi/midi_handler.js +0 -130
  6. package/external_midi/web_midi_link.js +0 -43
  7. package/externals/fflate/LICENSE +0 -21
  8. package/externals/fflate/fflate.min.js +0 -1
  9. package/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +0 -12
  10. package/externals/stbvorbis_sync/LICENSE +0 -202
  11. package/externals/stbvorbis_sync/NOTICE +0 -6
  12. package/externals/stbvorbis_sync/stbvorbis_sync.min.js +0 -1
  13. package/midi/README.md +0 -32
  14. package/midi/basic_midi.js +0 -565
  15. package/midi/midi_builder.js +0 -202
  16. package/midi/midi_data.js +0 -63
  17. package/midi/midi_loader.js +0 -324
  18. package/midi/midi_message.js +0 -254
  19. package/midi/midi_sequence.js +0 -225
  20. package/midi/midi_tools/get_note_times.js +0 -154
  21. package/midi/midi_tools/midi_editor.js +0 -611
  22. package/midi/midi_tools/midi_writer.js +0 -99
  23. package/midi/midi_tools/rmidi_writer.js +0 -567
  24. package/midi/midi_tools/used_keys_loaded.js +0 -238
  25. package/midi/xmf_loader.js +0 -454
  26. package/sequencer/README.md +0 -32
  27. package/sequencer/sequencer_engine/events.js +0 -104
  28. package/sequencer/sequencer_engine/play.js +0 -353
  29. package/sequencer/sequencer_engine/process_event.js +0 -169
  30. package/sequencer/sequencer_engine/process_tick.js +0 -106
  31. package/sequencer/sequencer_engine/sequencer_engine.js +0 -335
  32. package/sequencer/sequencer_engine/song_control.js +0 -229
  33. package/sequencer/worklet_wrapper/default_sequencer_options.js +0 -8
  34. package/sequencer/worklet_wrapper/sequencer.js +0 -807
  35. package/sequencer/worklet_wrapper/sequencer_message.js +0 -53
  36. package/soundfont/README.md +0 -13
  37. package/soundfont/basic_soundfont/basic_instrument.js +0 -77
  38. package/soundfont/basic_soundfont/basic_preset.js +0 -336
  39. package/soundfont/basic_soundfont/basic_sample.js +0 -197
  40. package/soundfont/basic_soundfont/basic_soundfont.js +0 -565
  41. package/soundfont/basic_soundfont/basic_zone.js +0 -64
  42. package/soundfont/basic_soundfont/basic_zones.js +0 -43
  43. package/soundfont/basic_soundfont/generator.js +0 -220
  44. package/soundfont/basic_soundfont/modulator.js +0 -378
  45. package/soundfont/basic_soundfont/riff_chunk.js +0 -149
  46. package/soundfont/basic_soundfont/write_dls/art2.js +0 -173
  47. package/soundfont/basic_soundfont/write_dls/articulator.js +0 -49
  48. package/soundfont/basic_soundfont/write_dls/combine_zones.js +0 -400
  49. package/soundfont/basic_soundfont/write_dls/ins.js +0 -103
  50. package/soundfont/basic_soundfont/write_dls/lins.js +0 -18
  51. package/soundfont/basic_soundfont/write_dls/modulator_converter.js +0 -330
  52. package/soundfont/basic_soundfont/write_dls/rgn2.js +0 -121
  53. package/soundfont/basic_soundfont/write_dls/wave.js +0 -94
  54. package/soundfont/basic_soundfont/write_dls/write_dls.js +0 -119
  55. package/soundfont/basic_soundfont/write_dls/wsmp.js +0 -78
  56. package/soundfont/basic_soundfont/write_dls/wvpl.js +0 -32
  57. package/soundfont/basic_soundfont/write_sf2/ibag.js +0 -39
  58. package/soundfont/basic_soundfont/write_sf2/igen.js +0 -80
  59. package/soundfont/basic_soundfont/write_sf2/imod.js +0 -46
  60. package/soundfont/basic_soundfont/write_sf2/inst.js +0 -34
  61. package/soundfont/basic_soundfont/write_sf2/pbag.js +0 -39
  62. package/soundfont/basic_soundfont/write_sf2/pgen.js +0 -82
  63. package/soundfont/basic_soundfont/write_sf2/phdr.js +0 -42
  64. package/soundfont/basic_soundfont/write_sf2/pmod.js +0 -46
  65. package/soundfont/basic_soundfont/write_sf2/sdta.js +0 -80
  66. package/soundfont/basic_soundfont/write_sf2/shdr.js +0 -55
  67. package/soundfont/basic_soundfont/write_sf2/write.js +0 -222
  68. package/soundfont/dls/articulator_converter.js +0 -396
  69. package/soundfont/dls/dls_destinations.js +0 -38
  70. package/soundfont/dls/dls_preset.js +0 -44
  71. package/soundfont/dls/dls_sample.js +0 -75
  72. package/soundfont/dls/dls_soundfont.js +0 -186
  73. package/soundfont/dls/dls_sources.js +0 -62
  74. package/soundfont/dls/dls_zone.js +0 -95
  75. package/soundfont/dls/read_articulation.js +0 -299
  76. package/soundfont/dls/read_instrument.js +0 -121
  77. package/soundfont/dls/read_instrument_list.js +0 -17
  78. package/soundfont/dls/read_lart.js +0 -35
  79. package/soundfont/dls/read_region.js +0 -152
  80. package/soundfont/dls/read_samples.js +0 -270
  81. package/soundfont/load_soundfont.js +0 -21
  82. package/soundfont/read_sf2/generators.js +0 -46
  83. package/soundfont/read_sf2/instruments.js +0 -66
  84. package/soundfont/read_sf2/modulators.js +0 -36
  85. package/soundfont/read_sf2/presets.js +0 -80
  86. package/soundfont/read_sf2/samples.js +0 -304
  87. package/soundfont/read_sf2/soundfont.js +0 -305
  88. package/soundfont/read_sf2/zones.js +0 -263
  89. package/synthetizer/README.md +0 -10
  90. package/synthetizer/audio_effects/effects_config.js +0 -25
  91. package/synthetizer/audio_effects/fancy_chorus.js +0 -162
  92. package/synthetizer/audio_effects/rb_compressed.min.js +0 -1
  93. package/synthetizer/audio_effects/reverb.js +0 -35
  94. package/synthetizer/audio_effects/reverb_as_binary.js +0 -18
  95. package/synthetizer/audio_engine/README.md +0 -25
  96. package/synthetizer/audio_engine/engine_components/compute_modulator.js +0 -266
  97. package/synthetizer/audio_engine/engine_components/controller_tables.js +0 -88
  98. package/synthetizer/audio_engine/engine_components/key_modifier_manager.js +0 -149
  99. package/synthetizer/audio_engine/engine_components/lfo.js +0 -26
  100. package/synthetizer/audio_engine/engine_components/lowpass_filter.js +0 -282
  101. package/synthetizer/audio_engine/engine_components/midi_audio_channel.js +0 -471
  102. package/synthetizer/audio_engine/engine_components/modulation_envelope.js +0 -181
  103. package/synthetizer/audio_engine/engine_components/modulator_curves.js +0 -89
  104. package/synthetizer/audio_engine/engine_components/soundfont_manager.js +0 -228
  105. package/synthetizer/audio_engine/engine_components/stereo_panner.js +0 -120
  106. package/synthetizer/audio_engine/engine_components/unit_converter.js +0 -73
  107. package/synthetizer/audio_engine/engine_components/voice.js +0 -519
  108. package/synthetizer/audio_engine/engine_components/volume_envelope.js +0 -401
  109. package/synthetizer/audio_engine/engine_components/wavetable_oscillator.js +0 -263
  110. package/synthetizer/audio_engine/engine_methods/controller_control/controller_change.js +0 -132
  111. package/synthetizer/audio_engine/engine_methods/controller_control/master_parameters.js +0 -48
  112. package/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +0 -241
  113. package/synthetizer/audio_engine/engine_methods/create_midi_channel.js +0 -27
  114. package/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +0 -253
  115. package/synthetizer/audio_engine/engine_methods/data_entry/data_entry_fine.js +0 -66
  116. package/synthetizer/audio_engine/engine_methods/mute_channel.js +0 -17
  117. package/synthetizer/audio_engine/engine_methods/note_on.js +0 -175
  118. package/synthetizer/audio_engine/engine_methods/portamento_time.js +0 -92
  119. package/synthetizer/audio_engine/engine_methods/program_change.js +0 -61
  120. package/synthetizer/audio_engine/engine_methods/render_voice.js +0 -196
  121. package/synthetizer/audio_engine/engine_methods/soundfont_management/clear_sound_font.js +0 -30
  122. package/synthetizer/audio_engine/engine_methods/soundfont_management/get_preset.js +0 -22
  123. package/synthetizer/audio_engine/engine_methods/soundfont_management/reload_sound_font.js +0 -40
  124. package/synthetizer/audio_engine/engine_methods/soundfont_management/send_preset_list.js +0 -34
  125. package/synthetizer/audio_engine/engine_methods/soundfont_management/set_embedded_sound_font.js +0 -21
  126. package/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +0 -20
  127. package/synthetizer/audio_engine/engine_methods/stopping_notes/note_off.js +0 -55
  128. package/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_channels.js +0 -16
  129. package/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_notes.js +0 -30
  130. package/synthetizer/audio_engine/engine_methods/stopping_notes/voice_killing.js +0 -63
  131. package/synthetizer/audio_engine/engine_methods/system_exclusive.js +0 -776
  132. package/synthetizer/audio_engine/engine_methods/tuning_control/channel_pressure.js +0 -24
  133. package/synthetizer/audio_engine/engine_methods/tuning_control/pitch_wheel.js +0 -33
  134. package/synthetizer/audio_engine/engine_methods/tuning_control/poly_pressure.js +0 -31
  135. package/synthetizer/audio_engine/engine_methods/tuning_control/set_master_tuning.js +0 -15
  136. package/synthetizer/audio_engine/engine_methods/tuning_control/set_modulation_depth.js +0 -27
  137. package/synthetizer/audio_engine/engine_methods/tuning_control/set_octave_tuning.js +0 -19
  138. package/synthetizer/audio_engine/engine_methods/tuning_control/set_tuning.js +0 -27
  139. package/synthetizer/audio_engine/engine_methods/tuning_control/transpose_all_channels.js +0 -15
  140. package/synthetizer/audio_engine/engine_methods/tuning_control/transpose_channel.js +0 -34
  141. package/synthetizer/audio_engine/main_processor.js +0 -765
  142. package/synthetizer/audio_engine/message_protocol/README.md +0 -13
  143. package/synthetizer/audio_engine/message_protocol/message_sending.js +0 -22
  144. package/synthetizer/audio_engine/message_protocol/worklet_message.js +0 -107
  145. package/synthetizer/audio_engine/snapshot/apply_synthesizer_snapshot.js +0 -14
  146. package/synthetizer/audio_engine/snapshot/channel_snapshot.js +0 -175
  147. package/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js +0 -122
  148. package/synthetizer/synth_constants.js +0 -20
  149. package/synthetizer/worklet_processor.min.js +0 -21
  150. package/synthetizer/worklet_wrapper/key_modifier_manager.js +0 -104
  151. package/synthetizer/worklet_wrapper/sfman_message.js +0 -9
  152. package/synthetizer/worklet_wrapper/synth_event_handler.js +0 -214
  153. package/synthetizer/worklet_wrapper/synth_soundfont_manager.js +0 -109
  154. package/synthetizer/worklet_wrapper/synthetizer.js +0 -1027
  155. package/synthetizer/worklet_wrapper/worklet_processor.js +0 -454
  156. package/synthetizer/worklet_wrapper/worklet_url.js +0 -16
  157. package/utils/README.md +0 -5
  158. package/utils/buffer_to_wav.js +0 -186
  159. package/utils/byte_functions/big_endian.js +0 -32
  160. package/utils/byte_functions/little_endian.js +0 -77
  161. package/utils/byte_functions/string.js +0 -107
  162. package/utils/byte_functions/variable_length_quantity.js +0 -42
  163. package/utils/fill_with_defaults.js +0 -21
  164. package/utils/indexed_array.js +0 -52
  165. package/utils/loggin.js +0 -79
  166. package/utils/other.js +0 -92
  167. package/utils/sysex_detector.js +0 -58
  168. package/utils/xg_hacks.js +0 -193
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/SpessaSynth)
16
+ ### [Demo](https://spessasus.github.io/spessasynth_lib)
12
17
 
13
- ### [Complete documentation](https://github.com/spessasus/SpessaSynth/wiki/Usage-As-Library)
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
- ### Numerous Format Support
36
- Supported formats list:
37
- - `.mid` - Standard MIDI File
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/SpessaSynth/wiki/Home)** *With [examples!](https://github.com/spessasus/SpessaSynth/wiki/Usage-As-Library#examples)*
54
- - **Flexible:** *It's not just a MIDI player!*
55
- - **Easy to Use:** *Basic setup is just [two lines of code!](https://github.com/spessasus/SpessaSynth/wiki/Usage-As-Library#minimal-setup)*
56
- - **No dependencies:** *Batteries included!*
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
- ### Powerful and Fast MIDI Sequencer
96
- - **Supports MIDI formats 0, 1, and 2:** *note: format 2 support is experimental as it's very, very rare.*
97
- - **[Multi-Port MIDI](https://github.com/spessasus/SpessaSynth/wiki/About-Multi-Port) support:** More than 16 channels!
98
- - **Smart preloading:** Only preloads the samples used in the MIDI file for smooth playback *(down to key and velocity!)*
99
- - **Lyrics support:** Add karaoke to your program!
100
- - **Raw lyrics available:** Decode in any encoding! *(Kanji? No problem!)*
101
- - **Runs in Audio Thread as well:** Never blocks the main thread
102
- - **Loop points support:** Ensures seamless loops
103
-
104
- ### Read and Write SoundFont and MIDI Files with Ease
105
- #### Read and write MIDI files
106
- - **Smart name detection:** Handles incorrectly formatted and non-standard track names
107
- - **Raw name available:** Decode in any encoding! *(Kanji? No problem!)*
108
- - **Port detection during load time:** Manage ports and channels easily!
109
- - **Used channels on track:** Quickly determine which channels are used
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
package/index.js CHANGED
@@ -1,35 +1,38 @@
1
1
  // Import modules
2
- import { loadSoundFont } from "./soundfont/load_soundfont.js";
3
- import { BasicSoundBank } from "./soundfont/basic_soundfont/basic_soundfont.js";
4
- import { BasicSample } from "./soundfont/basic_soundfont/basic_sample.js";
5
- import { BasicInstrumentZone } from "./soundfont/basic_soundfont/basic_zones.js";
6
- import { BasicInstrument } from "./soundfont/basic_soundfont/basic_instrument.js";
7
- import { Generator } from "./soundfont/basic_soundfont/generator.js";
8
- import { Modulator } from "./soundfont/basic_soundfont/modulator.js";
9
- import { BasicPresetZone } from "./soundfont/basic_soundfont/basic_zones.js";
10
- import { BasicPreset } from "./soundfont/basic_soundfont/basic_preset.js";
11
- import { BasicMIDI } from "./midi/basic_midi.js";
12
- import { MIDIMessage } from "./midi/midi_message.js";
13
- import { MIDI } from "./midi/midi_loader.js";
14
- import { RMIDINFOChunks } from "./midi/midi_tools/rmidi_writer.js";
15
- import { MIDIBuilder } from "./midi/midi_builder.js";
16
- import { Synthetizer } from "./synthetizer/worklet_wrapper/synthetizer.js";
17
- import { VOICE_CAP, DEFAULT_PERCUSSION } from "./synthetizer/synth_constants.js";
18
- import { Sequencer } from "./sequencer/worklet_wrapper/sequencer.js";
19
- import { IndexedByteArray } from './utils/indexed_array.js';
20
- import { audioBufferToWav } from './utils/buffer_to_wav.js';
21
- import { SpessaSynthLogging } from './utils/loggin.js';
22
- import { midiControllers, messageTypes } from "./midi/midi_message.js";
23
- import { MIDIDeviceHandler} from "./external_midi/midi_handler.js";
24
- import { WebMIDILinkHandler} from "./external_midi/web_midi_link.js";
25
- import { modulatorSources } from "./soundfont/basic_soundfont/modulator.js";
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/worklet_wrapper/worklet_url.js";
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.25.23",
4
- "description": "MIDI and SoundFont2/DLS library with no compromises",
3
+ "version": "3.26.0",
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/SpessaSynth.git"
13
+ "url": "git+https://github.com/spessasus/spessasynth_lib.git"
13
14
  },
14
15
  "main": "index.js",
15
16
  "keywords": [
@@ -36,8 +37,17 @@
36
37
  },
37
38
  "license": "Apache-2.0",
38
39
  "bugs": {
39
- "url": "https://github.com/spessasus/SpessaSynth/issues",
40
+ "url": "https://github.com/spessasus/spessasynth_lib/issues",
40
41
  "email": "spesekspesek@gmail.com"
41
42
  },
42
- "homepage": "https://github.com/spessasus/SpessaSynth#readme"
43
+ "homepage": "https://github.com/spessasus/spessasynth_lib#readme",
44
+ "files": [
45
+ "index.js",
46
+ "LICENSE",
47
+ "README.md",
48
+ "src"
49
+ ],
50
+ "dependencies": {
51
+ "spessasynth_core": "latest"
52
+ }
43
53
  }
@@ -1,4 +0,0 @@
1
- ## This is the MIDI handling folder.
2
-
3
- The code here is respnsible for dealing with MIDI Inputs and outputs
4
- and also for the WebMidiLink functionality.
@@ -1,130 +0,0 @@
1
- import { Synthetizer } from "../synthetizer/worklet_wrapper/synthetizer.js";
2
- import { consoleColors } from "../utils/other.js";
3
- import { SpessaSynthInfo, SpessaSynthWarn } from "../utils/loggin.js";
4
-
5
- /**
6
- * midi_handler.js
7
- * purpose: handles the connection between MIDI devices and synthesizer/sequencer via Web MIDI API
8
- */
9
-
10
- const NO_INPUT = null;
11
-
12
- export class MIDIDeviceHandler
13
- {
14
- constructor()
15
- {
16
- }
17
-
18
- /**
19
- * @returns {Promise<boolean>} if succeded
20
- */
21
- async createMIDIDeviceHandler()
22
- {
23
- /**
24
- * @type {MIDIInput}
25
- */
26
- this.selectedInput = NO_INPUT;
27
- /**
28
- * @type {MIDIOutput}
29
- */
30
- this.selectedOutput = NO_INPUT;
31
- if (navigator.requestMIDIAccess)
32
- {
33
- // prepare the midi access
34
- try
35
- {
36
- const response = await navigator.requestMIDIAccess({ sysex: true, software: true });
37
- this.inputs = response.inputs;
38
- this.outputs = response.outputs;
39
- SpessaSynthInfo("%cMIDI handler created!", consoleColors.recognized);
40
- return true;
41
- }
42
- catch (e)
43
- {
44
- SpessaSynthWarn(`Could not get MIDI Devices:`, e);
45
- this.inputs = [];
46
- this.outputs = [];
47
- return false;
48
- }
49
- }
50
- else
51
- {
52
- SpessaSynthWarn("Web MIDI Api not supported!", consoleColors.unrecognized);
53
- this.inputs = [];
54
- this.outputs = [];
55
- return false;
56
- }
57
- }
58
-
59
- /**
60
- * Connects the sequencer to a given MIDI output port
61
- * @param output {MIDIOutput}
62
- * @param seq {Sequencer}
63
- */
64
- connectMIDIOutputToSeq(output, seq)
65
- {
66
- this.selectedOutput = output;
67
- seq.connectMidiOutput(output);
68
- SpessaSynthInfo(
69
- `%cPlaying MIDI to %c${output.name}`,
70
- consoleColors.info,
71
- consoleColors.recognized
72
- );
73
- }
74
-
75
- /**
76
- * Disconnects a midi output port from the sequencer
77
- * @param seq {Sequencer}
78
- */
79
- disconnectSeqFromMIDI(seq)
80
- {
81
- this.selectedOutput = NO_INPUT;
82
- seq.connectMidiOutput(undefined);
83
- SpessaSynthInfo(
84
- "%cDisconnected from MIDI out.",
85
- consoleColors.info
86
- );
87
- }
88
-
89
- /**
90
- * Connects a MIDI input to the synthesizer
91
- * @param input {MIDIInput}
92
- * @param synth {Synthetizer}
93
- */
94
- connectDeviceToSynth(input, synth)
95
- {
96
- this.selectedInput = input;
97
- input.onmidimessage = event =>
98
- {
99
- synth.sendMessage(event.data);
100
- };
101
- SpessaSynthInfo(
102
- `%cListening for messages on %c${input.name}`,
103
- consoleColors.info,
104
- consoleColors.recognized
105
- );
106
- }
107
-
108
- /**
109
- * @param input {MIDIInput}
110
- */
111
- disconnectDeviceFromSynth(input)
112
- {
113
- this.selectedInput = NO_INPUT;
114
- input.onmidimessage = undefined;
115
- SpessaSynthInfo(
116
- `%cDisconnected from %c${input.name}`,
117
- consoleColors.info,
118
- consoleColors.recognized
119
- );
120
- }
121
-
122
- disconnectAllDevicesFromSynth()
123
- {
124
- this.selectedInput = NO_INPUT;
125
- for (const i of this.inputs)
126
- {
127
- i[1].onmidimessage = undefined;
128
- }
129
- }
130
- }
@@ -1,43 +0,0 @@
1
- import { Synthetizer } from "../synthetizer/worklet_wrapper/synthetizer.js";
2
- import { consoleColors } from "../utils/other.js";
3
- import { SpessaSynthInfo } from "../utils/loggin.js";
4
-
5
- /**
6
- * web_midi_link.js
7
- * purpose: handles the web midi link connection to the synthesizer
8
- * https://www.g200kg.com/en/docs/webmidilink/
9
- */
10
-
11
- export class WebMIDILinkHandler
12
- {
13
- /**
14
- * @param synth {Synthetizer} the synth to play to
15
- */
16
- constructor(synth)
17
- {
18
-
19
- window.addEventListener("message", msg =>
20
- {
21
- if (typeof msg.data !== "string")
22
- {
23
- return;
24
- }
25
- /**
26
- * @type {string[]}
27
- */
28
- const data = msg.data.split(",");
29
- if (data[0] !== "midi")
30
- {
31
- return;
32
- }
33
-
34
- data.shift(); // remove MIDI
35
-
36
- const midiData = data.map(byte => parseInt(byte, 16));
37
-
38
- synth.sendMessage(midiData);
39
- });
40
-
41
- SpessaSynthInfo("%cWeb MIDI Link handler created!", consoleColors.recognized);
42
- }
43
- }
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2023 Arjun Barrett
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
@@ -1 +0,0 @@
1
- let tr;(()=>{var l=Uint8Array,T=Uint16Array,ur=Int32Array,W=new l([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),X=new l([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),wr=new l([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Y=function(r,a){for(var e=new T(31),f=0;f<31;++f)e[f]=a+=1<<r[f-1];for(var v=new ur(e[30]),f=1;f<30;++f)for(var g=e[f];g<e[f+1];++g)v[g]=g-e[f]<<5|f;return{b:e,r:v}},Z=Y(W,2),$=Z.b,cr=Z.r;$[28]=258,cr[258]=28;var j=Y(X,0),hr=j.b,Fr=j.r,_=new T(32768);for(i=0;i<32768;++i)c=(i&43690)>>1|(i&21845)<<1,c=(c&52428)>>2|(c&13107)<<2,c=(c&61680)>>4|(c&3855)<<4,_[i]=((c&65280)>>8|(c&255)<<8)>>1;var c,i,A=function(r,a,e){for(var f=r.length,v=0,g=new T(a);v<f;++v)r[v]&&++g[r[v]-1];var k=new T(a);for(v=1;v<a;++v)k[v]=k[v-1]+g[v-1]<<1;var b;if(e){b=new T(1<<a);var m=15-a;for(v=0;v<f;++v)if(r[v])for(var U=v<<4|r[v],x=a-r[v],n=k[r[v]-1]++<<x,o=n|(1<<x)-1;n<=o;++n)b[_[n]>>m]=U}else for(b=new T(f),v=0;v<f;++v)r[v]&&(b[v]=_[k[r[v]-1]++]>>15-r[v]);return b},M=new l(288);for(i=0;i<144;++i)M[i]=8;var i;for(i=144;i<256;++i)M[i]=9;var i;for(i=256;i<280;++i)M[i]=7;var i;for(i=280;i<288;++i)M[i]=8;var i,L=new l(32);for(i=0;i<32;++i)L[i]=5;var i,gr=A(M,9,1),br=A(L,5,1),q=function(r){for(var a=r[0],e=1;e<r.length;++e)r[e]>a&&(a=r[e]);return a},u=function(r,a,e){var f=a/8|0;return(r[f]|r[f+1]<<8)>>(a&7)&e},C=function(r,a){var e=a/8|0;return(r[e]|r[e+1]<<8|r[e+2]<<16)>>(a&7)},kr=function(r){return(r+7)/8|0},xr=function(r,a,e){return(a==null||a<0)&&(a=0),(e==null||e>r.length)&&(e=r.length),new l(r.subarray(a,e))},yr=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],h=function(r,a,e){var f=new Error(a||yr[r]);if(f.code=r,Error.captureStackTrace&&Error.captureStackTrace(f,h),!e)throw f;return f},Sr=function(r,a,e,f){var v=r.length,g=f?f.length:0;if(!v||a.f&&!a.l)return e||new l(0);var k=!e,b=k||a.i!=2,m=a.i;k&&(e=new l(v*3));var U=function(fr){var or=e.length;if(fr>or){var lr=new l(Math.max(or*2,fr));lr.set(e),e=lr}},x=a.f||0,n=a.p||0,o=a.b||0,S=a.l,I=a.d,z=a.m,D=a.n,G=v*8;do{if(!S){x=u(r,n,1);var H=u(r,n+1,3);if(n+=3,H)if(H==1)S=gr,I=br,z=9,D=5;else if(H==2){var N=u(r,n,31)+257,s=u(r,n+10,15)+4,d=N+u(r,n+5,31)+1;n+=14;for(var F=new l(d),P=new l(19),t=0;t<s;++t)P[wr[t]]=u(r,n+t*3,7);n+=s*3;for(var rr=q(P),Ar=(1<<rr)-1,Mr=A(P,rr,1),t=0;t<d;){var ar=Mr[u(r,n,Ar)];n+=ar&15;var w=ar>>4;if(w<16)F[t++]=w;else{var E=0,O=0;for(w==16?(O=3+u(r,n,3),n+=2,E=F[t-1]):w==17?(O=3+u(r,n,7),n+=3):w==18&&(O=11+u(r,n,127),n+=7);O--;)F[t++]=E}}var er=F.subarray(0,N),y=F.subarray(N);z=q(er),D=q(y),S=A(er,z,1),I=A(y,D,1)}else h(1);else{var w=kr(n)+4,J=r[w-4]|r[w-3]<<8,K=w+J;if(K>v){m&&h(0);break}b&&U(o+J),e.set(r.subarray(w,K),o),a.b=o+=J,a.p=n=K*8,a.f=x;continue}if(n>G){m&&h(0);break}}b&&U(o+131072);for(var Ur=(1<<z)-1,zr=(1<<D)-1,Q=n;;Q=n){var E=S[C(r,n)&Ur],p=E>>4;if(n+=E&15,n>G){m&&h(0);break}if(E||h(2),p<256)e[o++]=p;else if(p==256){Q=n,S=null;break}else{var nr=p-254;if(p>264){var t=p-257,B=W[t];nr=u(r,n,(1<<B)-1)+$[t],n+=B}var R=I[C(r,n)&zr],V=R>>4;R||h(3),n+=R&15;var y=hr[V];if(V>3){var B=X[V];y+=C(r,n)&(1<<B)-1,n+=B}if(n>G){m&&h(0);break}b&&U(o+131072);var vr=o+nr;if(o<y){var ir=g-y,Dr=Math.min(y,vr);for(ir+o<0&&h(3);o<Dr;++o)e[o]=f[ir+o]}for(;o<vr;++o)e[o]=e[o-y]}}a.l=S,a.p=Q,a.b=o,a.f=x,S&&(x=1,a.m=z,a.d=I,a.n=D)}while(!x);return o!=e.length&&k?xr(e,0,o):e.subarray(0,o)},Tr=new l(0);function mr(r,a){return Sr(r,{i:2},a&&a.out,a&&a.dictionary)}var Er=typeof TextDecoder<"u"&&new TextDecoder,pr=0;try{Er.decode(Tr,{stream:!0}),pr=1}catch{}tr=mr})();export{tr as inflateSync};
@@ -1,12 +0,0 @@
1
- declare type DecodedData =
2
- {
3
- data: Float32Array[],
4
- error: string | null,
5
- sampleRate: number,
6
- eof: boolean
7
- }
8
-
9
- declare const stbvorbis: {
10
- decode(buffer: ArrayBuffer): DecodedData
11
- isInitialized: Promise<boolean>
12
- }