spessasynth_core 3.27.8 → 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 +85 -51
  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 -53
  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 -220
  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 -26
  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 -817
  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,7 +3,10 @@
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:
9
12
 
@@ -13,13 +16,14 @@ It allows you to:
13
16
  - Convert DLS to SF2! (and back!)
14
17
  - [and more!](#current-features)
15
18
 
16
- ### Install
17
19
 
18
- ```shell
19
- npm install --save spessasynth_core
20
- ```
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)
21
24
 
22
25
  > **Tip:**
26
+ >
23
27
  > Looking for an easy-to-use WebAudioAPI browser wrapper?
24
28
  > Try [spessasynth_lib](https://github.com/spessasus/spessasynth_lib)!
25
29
 
@@ -47,8 +51,9 @@ npm install --save spessasynth_core
47
51
  - **Modular design:** *Easy integration into other projects (load what you need)*
48
52
  - **Flexible:** *It's not just a MIDI player!*
49
53
  - **Easy to Use:** *Basic setup is
50
- just [two lines of code!](https://spessasus.github.io/spessasynth_core/Getting-Started#minimal-setup)*
54
+ just [two lines of code!](https://spessasus.github.io/spessasynth_core/getting-started#minimal-setup)*
51
55
  - **No dependencies:** *Batteries included!*
56
+ - **TypeScript definitions:** *Autocompletion in IDEs!*
52
57
 
53
58
  ### Powerful MIDI Synthesizer
54
59
 
@@ -77,23 +82,24 @@ npm install --save spessasynth_core
77
82
  - **Unlimited channel count:** Your CPU is the limit!
78
83
  - **Excellent MIDI Standards Support:**
79
84
  - **MIDI Controller Support:** Default supported
80
- controllers [here](https://spessasus.github.io/spessasynth_core/MIDI-Implementation#default-supported-controllers)
85
+ controllers [here](https://spessasus.github.io/spessasynth_core/extra/midi-implementation#default-supported-controllers)
81
86
  - **Portamento Support:** *Smooth note gliding!*
82
87
  - **Sound Controllers:** *Real-time filter and envelope control!*
83
88
  - **MIDI Tuning Standard Support:**
84
- *[more info here](https://spessasus.github.io/spessasynth_core/MIDI-Implementation#midi-tuning-standard)*
89
+ *[more info here](https://spessasus.github.io/spessasynth_core/extra/midi-implementation#midi-tuning-standard)*
85
90
  - [Full **RPN** and limited **NRPN**
86
- support](https://spessasus.github.io/spessasynth_core/MIDI-Implementation#supported-registered-parameters)
91
+ support](https://spessasus.github.io/spessasynth_core/extra/midi-implementation#supported-registered-parameters)
87
92
  - **SoundFont2 NRPN Support**
88
93
  - [**AWE32**
89
- NRPN Compatibility Layer](https://spessasus.github.io/spessasynth_core/MIDI-Implementation#awe32-nrpn-compatibility-layer)
94
+ NRPN Compatibility Layer](https://spessasus.github.io/spessasynth_core/extra/midi-implementation#awe32-nrpn-compatibility-layer)
90
95
  - Supports some [**Roland GS** and **Yamaha XG**
91
- system exclusives](https://spessasus.github.io/spessasynth_core/MIDI-Implementation#supported-system-exclusives)
96
+ system exclusives](https://spessasus.github.io/spessasynth_core/extra/midi-implementation#supported-system-exclusives)
92
97
 
93
98
  ### Powerful and Fast MIDI Sequencer
94
99
 
95
100
  - **Supports MIDI formats 0, 1, and 2:** *note: format 2 support is experimental as it's very, very rare.*
96
- - **[Multi-Port MIDI](https://spessasus.github.io/spessasynth_core/About-Multi-Port) support:** *More than 16 channels!*
101
+ - **[Multi-Port MIDI](https://spessasus.github.io/spessasynth_core/extra/about-multi-port) support:** *More than 16
102
+ channels!*
97
103
  - **Smart preloading:** Only preloads the samples used in the MIDI file for smooth playback *(down to key and
98
104
  velocity!)*
99
105
  - **Lyrics support:** *Add karaoke to your program!*
@@ -110,16 +116,16 @@ npm install --save spessasynth_core
110
116
  - **Used channels on track:** *Quickly determine which channels are used!*
111
117
  - **Key range detection:** *Detect the key range of the MIDI!*
112
118
  - **Easy MIDI editing:**
113
- Use [helper functions](https://spessasus.github.io/spessasynth_core/Writing-MIDI-Files#modifymidi) to modify the
119
+ Use [helper functions](https://spessasus.github.io/spessasynth_core/writing-files/midi#modifymidi) to modify the
114
120
  song to your needs!
115
121
  - **Loop detection:** *Automatically detects loops in MIDIs (e.g., from **Touhou Project**)*
116
122
  - **First note detection:** *Skip unnecessary silence at the start by jumping to the first note!*
117
123
  - **Lyrics support:** *Both regular MIDI and .kar files!*
118
- - **[Write MIDI files from scratch](https://spessasus.github.io/spessasynth_core/Creating-MIDI-Files)**
124
+ - **[Write MIDI files from scratch](https://spessasus.github.io/spessasynth_core/midi/creating-midi-files)**
119
125
  - **Easy saving:** *Save with
120
- just [one function!](https://spessasus.github.io/spessasynth_core/Writing-MIDI-Files#writemidi)*
126
+ just [one function!](https://spessasus.github.io/spessasynth_core/writing-files/midi#writemidi)*
121
127
 
122
- #### Read and write [RMID files with embedded SF2 soundfonts](https://github.com/spessasus/sf2-rmidi-specification#readme)*
128
+ #### Read and write [RMID files with embedded sound banks](https://github.com/spessasus/sf2-rmidi-specification#readme)
123
129
 
124
130
  - **[Level 4](https://github.com/spessasus/sf2-rmidi-specification#level-4) compliance:** Reads and writes *everything!*
125
131
  - **Compression and trimming support:** *Reduce a MIDI file with a 1GB sound bank to **as small as 5MB**!*
@@ -129,15 +135,15 @@ npm install --save spessasynth_core
129
135
  encoding!)*
130
136
  - **Compatible with [Falcosoft Midi Player 6!](https://falcosoft.hu/softwares.html#midiplayer)**
131
137
  - **Easy saving:**
132
- *[As simple as saving a MIDI file!](https://spessasus.github.io/spessasynth_core/Writing-MIDI-Files#writermidi)*
138
+ *[As simple as saving a MIDI file!](https://spessasus.github.io/spessasynth_core/writing-files/midi#writermidi)*
133
139
 
134
140
  #### Read and write SoundFont2 files
135
141
 
136
142
  - **Easy info access:** *Just
137
- an [object of strings!](https://spessasus.github.io/spessasynth_core/Sound-Bank#soundfontinfo)*
143
+ an [object of strings!](https://spessasus.github.io/spessasynth_core/sound-bank#soundbankinfo)*
138
144
  - **Smart trimming:** Trim the sound bank to only include samples used in the MIDI *(down to key and velocity!)*
139
145
  - **SF3 conversion:** *Compress SoundFont2 files to SoundFont3 with variable quality!*
140
- - **Easy saving:** *Also just [one function!](https://spessasus.github.io/spessasynth_core/Sound-Bank#write)*
146
+ - **Easy saving:** *Also just [one function!](https://spessasus.github.io/spessasynth_core/sound-bank#write)*
141
147
 
142
148
  #### Read and write SoundFont3 files
143
149
 
@@ -150,16 +156,16 @@ npm install --save spessasynth_core
150
156
 
151
157
  - Read DLS (DownLoadable Sounds) files like SF2 files!
152
158
  - **Native support:** *Saving it as sf2 is
153
- still [just one function!](https://spessasus.github.io/spessasynth_core/Sound-Bank#write)*
159
+ still [just one function!](https://spessasus.github.io/spessasynth_core/sound-bank#write)*
154
160
  - *That's right, saving as DLS is
155
- also [just one function!](https://spessasus.github.io/spessasynth_core/Sound-Bank#writedls)*
161
+ also [just one function!](https://spessasus.github.io/spessasynth_core/sound-bank#writedls)*
156
162
  - Converts articulators to both **modulators** and **generators**!
157
163
  - Works with both unsigned 8-bit samples and signed 16-bit samples!
158
164
  - **A-Law encoding support:** *Sure, why not?*
159
165
  - **Covers special generator cases:** *such as modLfoToPitch*!
160
166
  - **Correct volume:** *looking at you, Viena and gm.sf2!*
161
167
  - Support built right into the synthesizer!
162
- - **Convert SF2 to DLS:** [limited support](https://spessasus.github.io/spessasynth_core/DLS-Conversion-Problem)
168
+ - **Convert SF2 to DLS:** [limited support](https://spessasus.github.io/spessasynth_core/extra/dls-conversion-problem)
163
169
 
164
170
  ### Export MIDI as WAV
165
171
 
@@ -168,12 +174,12 @@ npm install --save spessasynth_core
168
174
  - **Cue points:** *Write MIDI loop points as cue points!*
169
175
  - **Loop multiple times:** *Render two (or more) loops into the file for seamless transitions!*
170
176
  - *That's right, saving as WAV is
171
- also [just one function!](https://spessasus.github.io/spessasynth_core/Writing-Wave-Files#audiobuffertowav)*
177
+ also [just one function!](https://spessasus.github.io/spessasynth_core/writing-files/wav#audiobuffertowav)*
172
178
 
173
179
  ### Limitations
174
180
 
175
181
  - Synth's performance may be questionable sometimes
176
- - [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)
177
183
 
178
184
  #### TODO
179
185
 
@@ -189,6 +195,7 @@ npm install --save spessasynth_core
189
195
  - [RecordingBlogs](https://www.recordingblogs.com/) - for detailed explanations on MIDI messages
190
196
  - [stbvorbis.js](https://github.com/hajimehoshi/stbvorbis.js) - for the Vorbis decoder
191
197
  - [fflate](https://github.com/101arrowz/fflate) - for the MIT DEFLATE implementation
198
+ - [tsup](https://github.com/egoist/tsup) - for the TypeScript bundler
192
199
  - [foo_midi](https://github.com/stuerp/foo_midi) - for useful resources on XMF file format
193
200
  - [Falcosoft](https://falcosoft.hu) - for help with the RMIDI format
194
201
  - [Christian Collins](https://schristiancollins.com) - for various bug reports regarding the synthesizer
@@ -198,66 +205,93 @@ npm install --save spessasynth_core
198
205
 
199
206
  ### Short example: MIDI to wav converter
200
207
 
201
- ```js
208
+ ```ts
202
209
  import * as fs from "node:fs";
203
- import {MIDI, SpessaSynthProcessor, SpessaSynthSequencer, audioToWav, loadSoundFont} from "spessasynth_core";
210
+ import {
211
+ audioToWav,
212
+ BasicMIDI,
213
+ SoundBankLoader,
214
+ SpessaSynthProcessor,
215
+ SpessaSynthSequencer
216
+ } from "../../src";
204
217
 
205
218
  // process arguments
206
219
  const args = process.argv.slice(2);
207
220
  if (args.length !== 3) {
208
- console.log("Usage: node index.js <soundfont path> <midi path> <wav output path>");
221
+ console.info(
222
+ "Usage: tsx index.ts <soundbank path> <midi path> <wav output path>"
223
+ );
209
224
  process.exit();
210
225
  }
211
226
  const sf = fs.readFileSync(args[0]);
212
227
  const mid = fs.readFileSync(args[1]);
213
- const midi = new MIDI(mid);
228
+ const midi = BasicMIDI.fromArrayBuffer(mid.buffer);
214
229
  const sampleRate = 44100;
215
- const sampleCount = 44100 * (midi.duration + 2);
230
+ const sampleCount = Math.ceil(44100 * (midi.duration + 2));
216
231
  const synth = new SpessaSynthProcessor(sampleRate, {
217
232
  enableEventSystem: false,
218
- effectsEnabled: false
233
+ enableEffects: false
219
234
  });
220
- synth.soundfontManager.reloadManager(loadSoundFont(sf));
235
+ synth.soundBankManager.reloadManager(
236
+ SoundBankLoader.fromArrayBuffer(sf.buffer)
237
+ );
221
238
  await synth.processorInitialized;
222
239
  const seq = new SpessaSynthSequencer(synth);
223
240
  seq.loadNewSongList([midi]);
224
- seq.loop = false;
241
+ seq.play();
242
+
225
243
  const outLeft = new Float32Array(sampleCount);
226
244
  const outRight = new Float32Array(sampleCount);
227
245
  const start = performance.now();
228
246
  let filledSamples = 0;
229
247
  // note: buffer size is recommended to be very small, as this is the interval between modulator updates and LFO updates
230
- const bufSize = 128;
248
+ const BUFFER_SIZE = 128;
231
249
  let i = 0;
232
- while (filledSamples + bufSize < sampleCount) {
233
- const bufLeft = new Float32Array(bufSize);
234
- const bufRight = new Float32Array(bufSize);
250
+ const durationRounded = Math.floor(seq.midiData.duration * 100) / 100;
251
+ const outputArray = [outLeft, outRight];
252
+ while (filledSamples < sampleCount) {
235
253
  // process sequencer
236
254
  seq.processTick();
237
- const arr = [bufLeft, bufRight];
238
255
  // render
239
- synth.renderAudio(arr, arr, arr);
240
- // write out
241
- outLeft.set(bufLeft, filledSamples);
242
- outRight.set(bufRight, filledSamples);
243
- filledSamples += bufSize;
256
+ const bufferSize = Math.min(BUFFER_SIZE, sampleCount - filledSamples);
257
+ synth.renderAudio(outputArray, [], [], filledSamples, bufferSize);
258
+ filledSamples += bufferSize;
244
259
  i++;
245
260
  // log progress
246
261
  if (i % 100 === 0) {
247
- console.log("Rendered", seq.currentTime, "/", midi.duration);
262
+ console.info(
263
+ "Rendered",
264
+ Math.floor(seq.currentTime * 100) / 100,
265
+ "/",
266
+ durationRounded
267
+ );
248
268
  }
249
269
  }
250
- console.log("Rendered in", Math.floor(performance.now() - start), "ms");
251
- const wave = audioToWav({
252
- leftChannel: outLeft,
253
- rightChannel: outRight,
254
- 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]}`);
255
279
  });
256
- fs.writeFileSync(args[2], new Buffer(wave));
257
- 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
258
290
  ```
259
291
 
260
- # License
292
+ The files will be placed in the `dist` folder.
293
+
294
+ ## License
261
295
 
262
296
  Copyright © 2025 Spessasus
263
297
  Licensed under the Apache-2.0 License.