spessasynth_core 3.27.8 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -51
- package/dist/index.d.ts +4057 -0
- package/dist/index.js +17178 -0
- package/dist/index.js.map +1 -0
- package/package.json +24 -6
- package/index.js +0 -132
- package/src/externals/README.md +0 -6
- package/src/externals/fflate/LICENSE +0 -21
- package/src/externals/fflate/fflate.min.js +0 -1
- package/src/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +0 -12
- package/src/externals/stbvorbis_sync/LICENSE +0 -202
- package/src/externals/stbvorbis_sync/NOTICE +0 -6
- package/src/externals/stbvorbis_sync/stbvorbis_sync.min.js +0 -1
- package/src/midi/README.md +0 -32
- package/src/midi/basic_midi.js +0 -587
- package/src/midi/midi_builder.js +0 -203
- package/src/midi/midi_loader.js +0 -321
- package/src/midi/midi_message.js +0 -254
- package/src/midi/midi_sequence.js +0 -230
- package/src/midi/midi_tools/get_note_times.js +0 -154
- package/src/midi/midi_tools/midi_editor.js +0 -611
- package/src/midi/midi_tools/midi_writer.js +0 -105
- package/src/midi/midi_tools/rmidi_writer.js +0 -566
- package/src/midi/midi_tools/used_keys_loaded.js +0 -256
- package/src/midi/xmf_loader.js +0 -454
- package/src/sequencer/README.md +0 -9
- package/src/sequencer/events.js +0 -81
- package/src/sequencer/play.js +0 -362
- package/src/sequencer/process_event.js +0 -165
- package/src/sequencer/process_tick.js +0 -104
- package/src/sequencer/sequencer_engine.js +0 -372
- package/src/sequencer/song_control.js +0 -196
- package/src/soundfont/README.md +0 -11
- package/src/soundfont/basic_soundfont/basic_global_zone.js +0 -6
- package/src/soundfont/basic_soundfont/basic_instrument.js +0 -115
- package/src/soundfont/basic_soundfont/basic_instrument_zone.js +0 -45
- package/src/soundfont/basic_soundfont/basic_preset.js +0 -313
- package/src/soundfont/basic_soundfont/basic_preset_zone.js +0 -39
- package/src/soundfont/basic_soundfont/basic_sample.js +0 -477
- package/src/soundfont/basic_soundfont/basic_soundbank.js +0 -740
- package/src/soundfont/basic_soundfont/basic_zone.js +0 -145
- package/src/soundfont/basic_soundfont/generator.js +0 -76
- package/src/soundfont/basic_soundfont/generator_types.js +0 -151
- package/src/soundfont/basic_soundfont/modulator.js +0 -581
- package/src/soundfont/basic_soundfont/riff_chunk.js +0 -195
- package/src/soundfont/basic_soundfont/write_dls/art2.js +0 -174
- package/src/soundfont/basic_soundfont/write_dls/articulator.js +0 -49
- package/src/soundfont/basic_soundfont/write_dls/combine_zones.js +0 -374
- package/src/soundfont/basic_soundfont/write_dls/ins.js +0 -85
- package/src/soundfont/basic_soundfont/write_dls/lins.js +0 -15
- package/src/soundfont/basic_soundfont/write_dls/modulator_converter.js +0 -330
- package/src/soundfont/basic_soundfont/write_dls/rgn2.js +0 -120
- package/src/soundfont/basic_soundfont/write_dls/wave.js +0 -71
- package/src/soundfont/basic_soundfont/write_dls/write_dls.js +0 -124
- package/src/soundfont/basic_soundfont/write_dls/wsmp.js +0 -78
- package/src/soundfont/basic_soundfont/write_dls/wvpl.js +0 -35
- package/src/soundfont/basic_soundfont/write_sf2/ibag.js +0 -60
- package/src/soundfont/basic_soundfont/write_sf2/igen.js +0 -91
- package/src/soundfont/basic_soundfont/write_sf2/imod.js +0 -62
- package/src/soundfont/basic_soundfont/write_sf2/inst.js +0 -42
- package/src/soundfont/basic_soundfont/write_sf2/pbag.js +0 -57
- package/src/soundfont/basic_soundfont/write_sf2/pgen.js +0 -92
- package/src/soundfont/basic_soundfont/write_sf2/phdr.js +0 -61
- package/src/soundfont/basic_soundfont/write_sf2/pmod.js +0 -62
- package/src/soundfont/basic_soundfont/write_sf2/sdta.js +0 -131
- package/src/soundfont/basic_soundfont/write_sf2/shdr.js +0 -77
- package/src/soundfont/basic_soundfont/write_sf2/write.js +0 -287
- package/src/soundfont/dls/articulator_converter.js +0 -402
- package/src/soundfont/dls/dls_destinations.js +0 -38
- package/src/soundfont/dls/dls_instrument.js +0 -20
- package/src/soundfont/dls/dls_preset.js +0 -43
- package/src/soundfont/dls/dls_sample.js +0 -238
- package/src/soundfont/dls/dls_soundfont.js +0 -183
- package/src/soundfont/dls/dls_sources.js +0 -63
- package/src/soundfont/dls/dls_zone.js +0 -89
- package/src/soundfont/dls/read_articulation.js +0 -300
- package/src/soundfont/dls/read_instrument.js +0 -118
- package/src/soundfont/dls/read_instrument_list.js +0 -17
- package/src/soundfont/dls/read_lart.js +0 -35
- package/src/soundfont/dls/read_region.js +0 -157
- package/src/soundfont/dls/read_samples.js +0 -154
- package/src/soundfont/load_soundfont.js +0 -21
- package/src/soundfont/read_sf2/generators.js +0 -43
- package/src/soundfont/read_sf2/instrument_zones.js +0 -75
- package/src/soundfont/read_sf2/instruments.js +0 -71
- package/src/soundfont/read_sf2/modulators.js +0 -25
- package/src/soundfont/read_sf2/preset_zones.js +0 -79
- package/src/soundfont/read_sf2/presets.js +0 -80
- package/src/soundfont/read_sf2/samples.js +0 -317
- package/src/soundfont/read_sf2/soundfont.js +0 -452
- package/src/soundfont/read_sf2/zones.js +0 -28
- package/src/synthetizer/README.md +0 -7
- package/src/synthetizer/audio_engine/README.md +0 -9
- package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +0 -289
- package/src/synthetizer/audio_engine/engine_components/controller_tables.js +0 -90
- package/src/synthetizer/audio_engine/engine_components/dynamic_modulator_system.js +0 -95
- package/src/synthetizer/audio_engine/engine_components/enums.js +0 -18
- package/src/synthetizer/audio_engine/engine_components/key_modifier_manager.js +0 -151
- package/src/synthetizer/audio_engine/engine_components/lfo.js +0 -26
- package/src/synthetizer/audio_engine/engine_components/lowpass_filter.js +0 -282
- package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +0 -551
- package/src/synthetizer/audio_engine/engine_components/modulation_envelope.js +0 -181
- package/src/synthetizer/audio_engine/engine_components/modulator_curves.js +0 -89
- package/src/synthetizer/audio_engine/engine_components/soundfont_manager.js +0 -265
- package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +0 -124
- package/src/synthetizer/audio_engine/engine_components/unit_converter.js +0 -73
- package/src/synthetizer/audio_engine/engine_components/voice.js +0 -525
- package/src/synthetizer/audio_engine/engine_components/volume_envelope.js +0 -402
- package/src/synthetizer/audio_engine/engine_components/wavetable_oscillator.js +0 -274
- package/src/synthetizer/audio_engine/engine_methods/controller_control/controller_change.js +0 -159
- package/src/synthetizer/audio_engine/engine_methods/controller_control/master_parameters.js +0 -53
- package/src/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +0 -254
- package/src/synthetizer/audio_engine/engine_methods/create_midi_channel.js +0 -20
- package/src/synthetizer/audio_engine/engine_methods/data_entry/awe32.js +0 -198
- package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +0 -281
- package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_fine.js +0 -109
- package/src/synthetizer/audio_engine/engine_methods/mute_channel.js +0 -17
- package/src/synthetizer/audio_engine/engine_methods/note_on.js +0 -220
- package/src/synthetizer/audio_engine/engine_methods/portamento_time.js +0 -92
- package/src/synthetizer/audio_engine/engine_methods/program_change.js +0 -35
- package/src/synthetizer/audio_engine/engine_methods/render_voice.js +0 -214
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/embedded_sound_bank.js +0 -42
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/get_preset.js +0 -0
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/update_preset_list.js +0 -19
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +0 -23
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/note_off.js +0 -56
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_channels.js +0 -16
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_notes.js +0 -30
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/voice_killing.js +0 -63
- package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +0 -1058
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/channel_pressure.js +0 -23
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/pitch_wheel.js +0 -31
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/poly_pressure.js +0 -29
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_master_tuning.js +0 -15
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_modulation_depth.js +0 -26
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_octave_tuning.js +0 -19
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_tuning.js +0 -27
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_all_channels.js +0 -15
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_channel.js +0 -34
- package/src/synthetizer/audio_engine/main_processor.js +0 -817
- package/src/synthetizer/audio_engine/snapshot/apply_synthesizer_snapshot.js +0 -16
- package/src/synthetizer/audio_engine/snapshot/channel_snapshot.js +0 -175
- package/src/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js +0 -116
- package/src/synthetizer/audio_engine/synth_processor_options.js +0 -18
- package/src/synthetizer/synth_constants.js +0 -26
- package/src/utils/README.md +0 -8
- package/src/utils/buffer_to_wav.js +0 -197
- package/src/utils/byte_functions/big_endian.js +0 -32
- package/src/utils/byte_functions/little_endian.js +0 -77
- package/src/utils/byte_functions/string.js +0 -92
- package/src/utils/byte_functions/variable_length_quantity.js +0 -42
- package/src/utils/fill_with_defaults.js +0 -21
- package/src/utils/indexed_array.js +0 -34
- package/src/utils/loggin.js +0 -71
- package/src/utils/other.js +0 -92
- package/src/utils/sysex_detector.js +0 -58
- package/src/utils/xg_hacks.js +0 -193
|
@@ -1,817 +0,0 @@
|
|
|
1
|
-
import { SpessaSynthInfo } from "../../utils/loggin.js";
|
|
2
|
-
import { consoleColors } from "../../utils/other.js";
|
|
3
|
-
import { voiceKilling } from "./engine_methods/stopping_notes/voice_killing.js";
|
|
4
|
-
import { ALL_CHANNELS_OR_DIFFERENT_ACTION, DEFAULT_SYNTH_MODE, VOICE_CAP } from "../synth_constants.js";
|
|
5
|
-
import { stbvorbis } from "../../externals/stbvorbis_sync/stbvorbis_sync.min.js";
|
|
6
|
-
import { VOLUME_ENVELOPE_SMOOTHING_FACTOR } from "./engine_components/volume_envelope.js";
|
|
7
|
-
import { systemExclusive } from "./engine_methods/system_exclusive.js";
|
|
8
|
-
import { masterParameterType, setMasterParameter } from "./engine_methods/controller_control/master_parameters.js";
|
|
9
|
-
import { resetAllControllers } from "./engine_methods/controller_control/reset_controllers.js";
|
|
10
|
-
import { SoundFontManager } from "./engine_components/soundfont_manager.js";
|
|
11
|
-
import { KeyModifierManager } from "./engine_components/key_modifier_manager.js";
|
|
12
|
-
import { getVoices, getVoicesForPreset } from "./engine_components/voice.js";
|
|
13
|
-
import { PAN_SMOOTHING_FACTOR } from "./engine_components/stereo_panner.js";
|
|
14
|
-
import { stopAllChannels } from "./engine_methods/stopping_notes/stop_all_channels.js";
|
|
15
|
-
import { clearEmbeddedBank, setEmbeddedSoundFont } from "./engine_methods/soundfont_management/embedded_sound_bank.js";
|
|
16
|
-
import { updatePresetList } from "./engine_methods/soundfont_management/update_preset_list.js";
|
|
17
|
-
import { transposeAllChannels } from "./engine_methods/tuning_control/transpose_all_channels.js";
|
|
18
|
-
import { setMasterTuning } from "./engine_methods/tuning_control/set_master_tuning.js";
|
|
19
|
-
import { applySynthesizerSnapshot } from "./snapshot/apply_synthesizer_snapshot.js";
|
|
20
|
-
import { createMidiChannel } from "./engine_methods/create_midi_channel.js";
|
|
21
|
-
import { FILTER_SMOOTHING_FACTOR } from "./engine_components/lowpass_filter.js";
|
|
22
|
-
import { getEvent, messageTypes } from "../../midi/midi_message.js";
|
|
23
|
-
import { IndexedByteArray } from "../../utils/indexed_array.js";
|
|
24
|
-
import { interpolationTypes } from "./engine_components/enums.js";
|
|
25
|
-
import { DEFAULT_SYNTH_OPTIONS } from "./synth_processor_options.js";
|
|
26
|
-
import { fillWithDefaults } from "../../utils/fill_with_defaults.js";
|
|
27
|
-
import { isSystemXG } from "../../utils/xg_hacks.js";
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @typedef {"gm"|"gm2"|"gs"|"xg"} SynthSystem
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* main_processor.js
|
|
36
|
-
* purpose: the core synthesis engine
|
|
37
|
-
*/
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* @typedef {Object} NoteOnCallback
|
|
42
|
-
* @property {number} midiNote - The MIDI note number.
|
|
43
|
-
* @property {number} channel - The MIDI channel number.
|
|
44
|
-
* @property {number} velocity - The velocity of the note.
|
|
45
|
-
*/
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* @typedef {Object} NoteOffCallback
|
|
49
|
-
* @property {number} midiNote - The MIDI note number.
|
|
50
|
-
* @property {number} channel - The MIDI channel number.
|
|
51
|
-
*/
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* @typedef {Object} DrumChangeCallback
|
|
55
|
-
* @property {number} channel - The MIDI channel number.
|
|
56
|
-
* @property {boolean} isDrumChannel - Indicates if the channel is a drum channel.
|
|
57
|
-
*/
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* @typedef {Object} ProgramChangeCallback
|
|
61
|
-
* @property {number} channel - The MIDI channel number.
|
|
62
|
-
* @property {number} program - The program number.
|
|
63
|
-
* @property {number} bank - The bank number.
|
|
64
|
-
*/
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @typedef {Object} ControllerChangeCallback
|
|
68
|
-
* @property {number} channel - The MIDI channel number.
|
|
69
|
-
* @property {number} controllerNumber - The controller number.
|
|
70
|
-
* @property {number} controllerValue - The value of the controller.
|
|
71
|
-
*/
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* @typedef {Object} MuteChannelCallback
|
|
75
|
-
* @property {number} channel - The MIDI channel number.
|
|
76
|
-
* @property {boolean} isMuted - Indicates if the channel is muted.
|
|
77
|
-
*/
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* @typedef {Object} PresetListChangeCallbackSingle
|
|
81
|
-
* @property {string} presetName - The name of the preset.
|
|
82
|
-
* @property {number} bank - The bank number.
|
|
83
|
-
* @property {number} program - The program number.
|
|
84
|
-
*/
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* @typedef {PresetListChangeCallbackSingle[]} PresetListChangeCallback - A list of preset objects.
|
|
88
|
-
*/
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* @typedef {Object} SynthDisplayCallback
|
|
92
|
-
* @property {Uint8Array} displayData - The data to display.
|
|
93
|
-
* @property {synthDisplayTypes} displayType - The type of display.
|
|
94
|
-
*/
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @typedef {Object} PitchWheelCallback
|
|
98
|
-
* @property {number} channel - The MIDI channel number.
|
|
99
|
-
* @property {number} MSB - The most significant byte of the pitch-wheel value.
|
|
100
|
-
* @property {number} LSB - The least significant byte of the pitch-wheel value.
|
|
101
|
-
*/
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* @typedef {Object} ChannelPressureCallback
|
|
105
|
-
* @property {number} channel - The MIDI channel number.
|
|
106
|
-
* @property {number} pressure - The pressure value.
|
|
107
|
-
*/
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* @typedef {Error} SoundfontErrorCallback - The error message for soundfont errors.
|
|
111
|
-
*/
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* @typedef {
|
|
115
|
-
* NoteOnCallback |
|
|
116
|
-
* NoteOffCallback |
|
|
117
|
-
* DrumChangeCallback |
|
|
118
|
-
* ProgramChangeCallback |
|
|
119
|
-
* ControllerChangeCallback |
|
|
120
|
-
* MuteChannelCallback |
|
|
121
|
-
* PresetListChangeCallback |
|
|
122
|
-
* PitchWheelCallback |
|
|
123
|
-
* SoundfontErrorCallback |
|
|
124
|
-
* ChannelPressureCallback |
|
|
125
|
-
* SynthDisplayCallback |
|
|
126
|
-
* undefined
|
|
127
|
-
* } EventCallbackData
|
|
128
|
-
*/
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* @typedef {
|
|
132
|
-
* "noteon"|
|
|
133
|
-
* "noteoff"|
|
|
134
|
-
* "pitchwheel"|
|
|
135
|
-
* "controllerchange"|
|
|
136
|
-
* "programchange"|
|
|
137
|
-
* "channelpressure"|
|
|
138
|
-
* "polypressure" |
|
|
139
|
-
* "drumchange"|
|
|
140
|
-
* "stopall"|
|
|
141
|
-
* "newchannel"|
|
|
142
|
-
* "mutechannel"|
|
|
143
|
-
* "presetlistchange"|
|
|
144
|
-
* "allcontrollerreset"|
|
|
145
|
-
* "soundfonterror"|
|
|
146
|
-
* "synthdisplay"} EventTypes
|
|
147
|
-
*/
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* @typedef {Object} SynthMethodOptions
|
|
152
|
-
* @property {number} time - the audio context time when the event should execute, in seconds.
|
|
153
|
-
*/
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* @type {SynthMethodOptions}
|
|
157
|
-
*/
|
|
158
|
-
const DEFAULT_SYNTH_METHOD_OPTIONS = {
|
|
159
|
-
time: 0
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
// if the note is released faster than that, it forced to last that long
|
|
163
|
-
// this is used mostly for drum channels, where a lot of midis like to send instant note off after a note on
|
|
164
|
-
export const MIN_NOTE_LENGTH = 0.03;
|
|
165
|
-
// this sounds way nicer for an instant hi-hat cutoff
|
|
166
|
-
export const MIN_EXCLUSIVE_LENGTH = 0.07;
|
|
167
|
-
|
|
168
|
-
export const SYNTHESIZER_GAIN = 1.0;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
// the core synthesis engine of spessasynth.
|
|
172
|
-
class SpessaSynthProcessor
|
|
173
|
-
{
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Manages sound banks.
|
|
177
|
-
* @type {SoundFontManager}
|
|
178
|
-
*/
|
|
179
|
-
soundfontManager = new SoundFontManager(this.updatePresetList.bind(this));
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Cached voices for all presets for this synthesizer.
|
|
183
|
-
* Nesting goes like this:
|
|
184
|
-
* this.cachedVoices[bankNumber][programNumber][midiNote][velocity] = a list of voices for that.
|
|
185
|
-
* @type {Voice[][][][][]}
|
|
186
|
-
*/
|
|
187
|
-
cachedVoices = [];
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Synth's device id: -1 means all
|
|
191
|
-
* @type {number}
|
|
192
|
-
*/
|
|
193
|
-
deviceID = ALL_CHANNELS_OR_DIFFERENT_ACTION;
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Synth's event queue from the main thread
|
|
197
|
-
* @type {{callback: function(), time: number}[]}
|
|
198
|
-
*/
|
|
199
|
-
eventQueue = [];
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Interpolation type used
|
|
203
|
-
* @type {interpolationTypes}
|
|
204
|
-
*/
|
|
205
|
-
interpolationType = interpolationTypes.fourthOrder;
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Global transposition in semitones
|
|
209
|
-
* @type {number}
|
|
210
|
-
*/
|
|
211
|
-
transposition = 0;
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* this.tunings[program][key] = tuning
|
|
215
|
-
* @type {MTSProgramTuning[]}
|
|
216
|
-
*/
|
|
217
|
-
tunings = [];
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* The volume gain, set by user
|
|
221
|
-
* @type {number}
|
|
222
|
-
*/
|
|
223
|
-
masterGain = SYNTHESIZER_GAIN;
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* The volume gain, set by MIDI sysEx
|
|
227
|
-
* @type {number}
|
|
228
|
-
*/
|
|
229
|
-
midiVolume = 1;
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Reverb linear gain
|
|
233
|
-
* @type {number}
|
|
234
|
-
*/
|
|
235
|
-
reverbGain = 1;
|
|
236
|
-
/**
|
|
237
|
-
* Chorus linear gain
|
|
238
|
-
* @type {number}
|
|
239
|
-
*/
|
|
240
|
-
chorusGain = 1;
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Set via system exclusive
|
|
244
|
-
* @type {number}
|
|
245
|
-
*/
|
|
246
|
-
reverbSend = 1;
|
|
247
|
-
/**
|
|
248
|
-
* Set via system exclusive
|
|
249
|
-
* @type {number}
|
|
250
|
-
*/
|
|
251
|
-
chorusSend = 1;
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Maximum number of voices allowed at once
|
|
255
|
-
* @type {number}
|
|
256
|
-
*/
|
|
257
|
-
voiceCap = VOICE_CAP;
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* (-1 to 1)
|
|
261
|
-
* @type {number}
|
|
262
|
-
*/
|
|
263
|
-
pan = 0.0;
|
|
264
|
-
/**
|
|
265
|
-
* the pan of the left channel
|
|
266
|
-
* @type {number}
|
|
267
|
-
*/
|
|
268
|
-
panLeft = 0.5;
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* the pan of the right channel
|
|
272
|
-
* @type {number}
|
|
273
|
-
*/
|
|
274
|
-
panRight = 0.5;
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* forces note killing instead of releasing
|
|
278
|
-
* @type {boolean}
|
|
279
|
-
*/
|
|
280
|
-
highPerformanceMode = false;
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Handlese custom key overrides: velocity and preset
|
|
284
|
-
* @type {KeyModifierManager}
|
|
285
|
-
*/
|
|
286
|
-
keyModifierManager = new KeyModifierManager();
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* contains all the channels with their voices on the processor size
|
|
290
|
-
* @type {MidiAudioChannel[]}
|
|
291
|
-
*/
|
|
292
|
-
midiAudioChannels = [];
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Controls the bank selection & SysEx
|
|
296
|
-
* @type {SynthSystem}
|
|
297
|
-
*/
|
|
298
|
-
system = DEFAULT_SYNTH_MODE;
|
|
299
|
-
/**
|
|
300
|
-
* Current total voices amount
|
|
301
|
-
* @type {number}
|
|
302
|
-
*/
|
|
303
|
-
totalVoicesAmount = 0;
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* Synth's default (reset) preset
|
|
307
|
-
* @type {BasicPreset}
|
|
308
|
-
*/
|
|
309
|
-
defaultPreset;
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Synth's default (reset) drum preset
|
|
313
|
-
* @type {BasicPreset}
|
|
314
|
-
*/
|
|
315
|
-
drumPreset;
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
* Controls if the processor is fully initialized
|
|
319
|
-
* @type {Promise<boolean>}
|
|
320
|
-
*/
|
|
321
|
-
processorInitialized = stbvorbis.isInitialized;
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Current audio time
|
|
325
|
-
* @type {number}
|
|
326
|
-
*/
|
|
327
|
-
currentSynthTime = 0;
|
|
328
|
-
|
|
329
|
-
/**
|
|
330
|
-
* in hertz
|
|
331
|
-
* @type {number}
|
|
332
|
-
*/
|
|
333
|
-
sampleRate;
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Sample time in seconds
|
|
337
|
-
* @type {number}
|
|
338
|
-
*/
|
|
339
|
-
sampleTime;
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* are the chorus and reverb effects enabled?
|
|
343
|
-
* @type {boolean}
|
|
344
|
-
*/
|
|
345
|
-
effectsEnabled = true;
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* one voice per note and track (issue #7)
|
|
349
|
-
*/
|
|
350
|
-
_monophonicRetriggerMode = false;
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
* for applying the snapshot after an override sound bank too
|
|
355
|
-
* @type {SynthesizerSnapshot}
|
|
356
|
-
* @private
|
|
357
|
-
*/
|
|
358
|
-
_snapshot;
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* Calls when an event occurs.
|
|
362
|
-
* @type {function}
|
|
363
|
-
* @param {EventTypes} eventType - the event type.
|
|
364
|
-
* @param {EventCallbackData} eventData - the event data.
|
|
365
|
-
*/
|
|
366
|
-
onEventCall;
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Calls when a channel property is changed.
|
|
370
|
-
* @type {function}
|
|
371
|
-
* @param {ChannelProperty} property - the updated property.
|
|
372
|
-
* @param {number} channelNumber - the channel number of the said property.
|
|
373
|
-
*/
|
|
374
|
-
onChannelPropertyChange;
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* Calls when a master parameter is changed.
|
|
378
|
-
* @type {function}
|
|
379
|
-
* @param {masterParameterType} parameter - the parameter type
|
|
380
|
-
* @param {number|string} value - the new value.
|
|
381
|
-
*/
|
|
382
|
-
onMasterParameterChange;
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Creates a new synthesizer engine.
|
|
387
|
-
* @param sampleRate {number} - sample rate, in Hertz.
|
|
388
|
-
* @param options {SynthProcessorOptions} - the processor's options.
|
|
389
|
-
*/
|
|
390
|
-
constructor(sampleRate,
|
|
391
|
-
options = DEFAULT_SYNTH_OPTIONS)
|
|
392
|
-
{
|
|
393
|
-
options = fillWithDefaults(options, DEFAULT_SYNTH_OPTIONS);
|
|
394
|
-
/**
|
|
395
|
-
* Midi output count
|
|
396
|
-
* @type {number}
|
|
397
|
-
*/
|
|
398
|
-
this.midiOutputsCount = options.midiChannels;
|
|
399
|
-
this.effectsEnabled = options.effectsEnabled;
|
|
400
|
-
this.enableEventSystem = options.enableEventSystem;
|
|
401
|
-
this.currentSynthTime = options.initialTime;
|
|
402
|
-
this.sampleTime = 1 / sampleRate;
|
|
403
|
-
this.sampleRate = sampleRate;
|
|
404
|
-
|
|
405
|
-
// these smoothing factors were tested on 44,100 Hz, adjust them to target sample rate here
|
|
406
|
-
this.volumeEnvelopeSmoothingFactor = VOLUME_ENVELOPE_SMOOTHING_FACTOR * (44100 / sampleRate);
|
|
407
|
-
this.panSmoothingFactor = PAN_SMOOTHING_FACTOR * (44100 / sampleRate);
|
|
408
|
-
this.filterSmoothingFactor = FILTER_SMOOTHING_FACTOR * (44100 / sampleRate);
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
for (let i = 0; i < 128; i++)
|
|
412
|
-
{
|
|
413
|
-
this.tunings.push([]);
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
for (let i = 0; i < this.midiOutputsCount; i++)
|
|
417
|
-
{
|
|
418
|
-
this.createMidiChannel(false);
|
|
419
|
-
}
|
|
420
|
-
this.processorInitialized.then(() =>
|
|
421
|
-
{
|
|
422
|
-
SpessaSynthInfo("%cSpessaSynth is ready!", consoleColors.recognized);
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
/**
|
|
427
|
-
* @returns {number}
|
|
428
|
-
*/
|
|
429
|
-
get currentGain()
|
|
430
|
-
{
|
|
431
|
-
return this.masterGain * this.midiVolume;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
getDefaultPresets()
|
|
435
|
-
{
|
|
436
|
-
// override this to XG, to set the default preset to NOT be XG drums!
|
|
437
|
-
const sys = this.system;
|
|
438
|
-
this.system = "xg";
|
|
439
|
-
this.defaultPreset = this.getPreset(0, 0);
|
|
440
|
-
this.system = sys;
|
|
441
|
-
this.drumPreset = this.getPreset(128, 0);
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
/**
|
|
445
|
-
* @param value {SynthSystem}
|
|
446
|
-
*/
|
|
447
|
-
setSystem(value)
|
|
448
|
-
{
|
|
449
|
-
this.system = value;
|
|
450
|
-
this?.onMasterParameterChange?.(masterParameterType.midiSystem, this.system);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
/**
|
|
454
|
-
* @param bank {number}
|
|
455
|
-
* @param program {number}
|
|
456
|
-
* @param midiNote {number}
|
|
457
|
-
* @param velocity {number}
|
|
458
|
-
* @returns {Voice[]|undefined}
|
|
459
|
-
*/
|
|
460
|
-
getCachedVoice(bank, program, midiNote, velocity)
|
|
461
|
-
{
|
|
462
|
-
return this.cachedVoices?.[bank]?.[program]?.[midiNote]?.[velocity];
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* @param bank {number}
|
|
467
|
-
* @param program {number}
|
|
468
|
-
* @param midiNote {number}
|
|
469
|
-
* @param velocity {number}
|
|
470
|
-
* @param voices {Voice[]}
|
|
471
|
-
*/
|
|
472
|
-
setCachedVoice(bank, program, midiNote, velocity, voices)
|
|
473
|
-
{
|
|
474
|
-
// make sure that it exists
|
|
475
|
-
if (!this.cachedVoices[bank])
|
|
476
|
-
{
|
|
477
|
-
this.cachedVoices[bank] = [];
|
|
478
|
-
}
|
|
479
|
-
if (!this.cachedVoices[bank][program])
|
|
480
|
-
{
|
|
481
|
-
this.cachedVoices[bank][program] = [];
|
|
482
|
-
}
|
|
483
|
-
if (!this.cachedVoices[bank][program][midiNote])
|
|
484
|
-
{
|
|
485
|
-
this.cachedVoices[bank][program][midiNote] = [];
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
// cache
|
|
489
|
-
this.cachedVoices[bank][program][midiNote][velocity] = voices;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
// noinspection JSUnusedGlobalSymbols
|
|
493
|
-
/**
|
|
494
|
-
* Renders float32 audio data to stereo outputs; buffer size of 128 is recommended
|
|
495
|
-
* All float arrays must have the same length
|
|
496
|
-
* @param outputs {Float32Array[]} output stereo channels (L, R)
|
|
497
|
-
* @param reverb {Float32Array[]} reverb stereo channels (L, R)
|
|
498
|
-
* @param chorus {Float32Array[]} chorus stereo channels (L, R)
|
|
499
|
-
* @param startIndex {number} start offset of the passed arrays, rendering starts at this index, defaults to 0
|
|
500
|
-
* @param sampleCount {number} the length of the rendered buffer, defaults to float32array length - startOffset
|
|
501
|
-
*/
|
|
502
|
-
renderAudio(outputs,
|
|
503
|
-
reverb,
|
|
504
|
-
chorus,
|
|
505
|
-
startIndex = 0,
|
|
506
|
-
sampleCount = 0
|
|
507
|
-
)
|
|
508
|
-
{
|
|
509
|
-
this.renderAudioSplit(reverb, chorus, Array(16).fill(outputs), startIndex, sampleCount);
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
/**
|
|
513
|
-
* Renders the float32 audio data of each channel; buffer size of 128 is recommended
|
|
514
|
-
* All float arrays must have the same length
|
|
515
|
-
* @param reverbChannels {Float32Array[]} reverb stereo channels (L, R)
|
|
516
|
-
* @param chorusChannels {Float32Array[]} chorus stereo channels (L, R)
|
|
517
|
-
* @param separateChannels {Float32Array[][]} a total of 16 stereo pairs (L, R) for each MIDI channel
|
|
518
|
-
* @param startIndex {number} start offset of the passed arrays, rendering starts at this index, defaults to 0
|
|
519
|
-
* @param sampleCount {number} the length of the rendered buffer, defaults to float32array length - startOffset
|
|
520
|
-
*/
|
|
521
|
-
renderAudioSplit(reverbChannels,
|
|
522
|
-
chorusChannels,
|
|
523
|
-
separateChannels,
|
|
524
|
-
startIndex = 0,
|
|
525
|
-
sampleCount = 0
|
|
526
|
-
)
|
|
527
|
-
{
|
|
528
|
-
// process event queue
|
|
529
|
-
const time = this.currentSynthTime;
|
|
530
|
-
while (this.eventQueue[0]?.time <= time)
|
|
531
|
-
{
|
|
532
|
-
this.eventQueue.shift().callback();
|
|
533
|
-
}
|
|
534
|
-
const revL = reverbChannels[0];
|
|
535
|
-
const revR = reverbChannels[1];
|
|
536
|
-
const chrL = chorusChannels[0];
|
|
537
|
-
const chrR = chorusChannels[1];
|
|
538
|
-
|
|
539
|
-
// validate
|
|
540
|
-
startIndex = Math.max(startIndex, 0);
|
|
541
|
-
const quantumSize = sampleCount || separateChannels[0][0].length - startIndex;
|
|
542
|
-
|
|
543
|
-
// for every channel
|
|
544
|
-
this.totalVoicesAmount = 0;
|
|
545
|
-
this.midiAudioChannels.forEach((channel, index) =>
|
|
546
|
-
{
|
|
547
|
-
if (channel.voices.length < 1 || channel.isMuted)
|
|
548
|
-
{
|
|
549
|
-
// there's nothing to do!
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
let voiceCount = channel.voices.length;
|
|
553
|
-
const ch = index % 16;
|
|
554
|
-
|
|
555
|
-
// render to the appropriate output
|
|
556
|
-
channel.renderAudio(
|
|
557
|
-
separateChannels[ch][0], separateChannels[ch][1],
|
|
558
|
-
revL, revR,
|
|
559
|
-
chrL, chrR,
|
|
560
|
-
startIndex, quantumSize
|
|
561
|
-
);
|
|
562
|
-
|
|
563
|
-
this.totalVoicesAmount += channel.voices.length;
|
|
564
|
-
// if voice count changed, update voice amount
|
|
565
|
-
if (channel.voices.length !== voiceCount)
|
|
566
|
-
{
|
|
567
|
-
channel.sendChannelProperty();
|
|
568
|
-
}
|
|
569
|
-
});
|
|
570
|
-
|
|
571
|
-
// advance the time appropriately
|
|
572
|
-
this.currentSynthTime += quantumSize * this.sampleTime;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
// noinspection JSUnusedGlobalSymbols
|
|
576
|
-
destroySynthProcessor()
|
|
577
|
-
{
|
|
578
|
-
this.midiAudioChannels.forEach(c =>
|
|
579
|
-
{
|
|
580
|
-
delete c.midiControllers;
|
|
581
|
-
delete c.voices;
|
|
582
|
-
delete c.sustainedVoices;
|
|
583
|
-
delete c.lockedControllers;
|
|
584
|
-
delete c.preset;
|
|
585
|
-
delete c.customControllers;
|
|
586
|
-
});
|
|
587
|
-
delete this.cachedVoices;
|
|
588
|
-
delete this.midiAudioChannels;
|
|
589
|
-
this.soundfontManager.destroyManager();
|
|
590
|
-
delete this.soundfontManager;
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
/**
|
|
594
|
-
* @param channel {number}
|
|
595
|
-
* @param controllerNumber {number}
|
|
596
|
-
* @param controllerValue {number}
|
|
597
|
-
* @param force {boolean}
|
|
598
|
-
*/
|
|
599
|
-
controllerChange(channel, controllerNumber, controllerValue, force = false)
|
|
600
|
-
{
|
|
601
|
-
this.midiAudioChannels[channel].controllerChange(controllerNumber, controllerValue, force);
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* @param channel {number}
|
|
606
|
-
* @param midiNote {number}
|
|
607
|
-
* @param velocity {number}
|
|
608
|
-
*/
|
|
609
|
-
noteOn(channel, midiNote, velocity)
|
|
610
|
-
{
|
|
611
|
-
this.midiAudioChannels[channel].noteOn(midiNote, velocity);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
/**
|
|
615
|
-
* @param channel {number}
|
|
616
|
-
* @param midiNote {number}
|
|
617
|
-
*/
|
|
618
|
-
noteOff(channel, midiNote)
|
|
619
|
-
{
|
|
620
|
-
this.midiAudioChannels[channel].noteOff(midiNote);
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
/**
|
|
624
|
-
* @param channel {number}
|
|
625
|
-
* @param midiNote {number}
|
|
626
|
-
* @param pressure {number}
|
|
627
|
-
*/
|
|
628
|
-
polyPressure(channel, midiNote, pressure)
|
|
629
|
-
{
|
|
630
|
-
this.midiAudioChannels[channel].polyPressure(midiNote, pressure);
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
/**
|
|
634
|
-
* @param channel {number}
|
|
635
|
-
* @param pressure {number}
|
|
636
|
-
*/
|
|
637
|
-
channelPressure(channel, pressure)
|
|
638
|
-
{
|
|
639
|
-
this.midiAudioChannels[channel].channelPressure(pressure);
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
/**
|
|
643
|
-
* @param channel {number}
|
|
644
|
-
* @param MSB {number}
|
|
645
|
-
* @param LSB {number}
|
|
646
|
-
*/
|
|
647
|
-
pitchWheel(channel, MSB, LSB)
|
|
648
|
-
{
|
|
649
|
-
this.midiAudioChannels[channel].pitchWheel(MSB, LSB);
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
/**
|
|
653
|
-
* @param channel {number}
|
|
654
|
-
* @param programNumber {number}
|
|
655
|
-
*/
|
|
656
|
-
programChange(channel, programNumber)
|
|
657
|
-
{
|
|
658
|
-
this.midiAudioChannels[channel].programChange(programNumber);
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
// noinspection JSUnusedGlobalSymbols
|
|
662
|
-
/**
|
|
663
|
-
* Processes a MIDI message
|
|
664
|
-
* @param message {Uint8Array} - the message to process
|
|
665
|
-
* @param channelOffset {number} - channel offset for the message
|
|
666
|
-
* @param force {boolean} cool stuff
|
|
667
|
-
* @param options {SynthMethodOptions} - additional options for scheduling the message
|
|
668
|
-
*/
|
|
669
|
-
processMessage(message, channelOffset = 0, force = false, options = DEFAULT_SYNTH_METHOD_OPTIONS)
|
|
670
|
-
{
|
|
671
|
-
const call = () =>
|
|
672
|
-
{
|
|
673
|
-
const statusByteData = getEvent(message[0]);
|
|
674
|
-
|
|
675
|
-
const channel = statusByteData.channel + channelOffset;
|
|
676
|
-
// process the event
|
|
677
|
-
switch (statusByteData.status)
|
|
678
|
-
{
|
|
679
|
-
case messageTypes.noteOn:
|
|
680
|
-
const velocity = message[2];
|
|
681
|
-
if (velocity > 0)
|
|
682
|
-
{
|
|
683
|
-
this.noteOn(channel, message[1], velocity);
|
|
684
|
-
}
|
|
685
|
-
else
|
|
686
|
-
{
|
|
687
|
-
this.noteOff(channel, message[1]);
|
|
688
|
-
}
|
|
689
|
-
break;
|
|
690
|
-
|
|
691
|
-
case messageTypes.noteOff:
|
|
692
|
-
if (force)
|
|
693
|
-
{
|
|
694
|
-
this.midiAudioChannels[channel].killNote(message[1]);
|
|
695
|
-
}
|
|
696
|
-
else
|
|
697
|
-
{
|
|
698
|
-
this.noteOff(channel, message[1]);
|
|
699
|
-
}
|
|
700
|
-
break;
|
|
701
|
-
|
|
702
|
-
case messageTypes.pitchBend:
|
|
703
|
-
this.pitchWheel(channel, message[2], message[1]);
|
|
704
|
-
break;
|
|
705
|
-
|
|
706
|
-
case messageTypes.controllerChange:
|
|
707
|
-
this.controllerChange(channel, message[1], message[2], force);
|
|
708
|
-
break;
|
|
709
|
-
|
|
710
|
-
case messageTypes.programChange:
|
|
711
|
-
this.programChange(channel, message[1]);
|
|
712
|
-
break;
|
|
713
|
-
|
|
714
|
-
case messageTypes.polyPressure:
|
|
715
|
-
this.polyPressure(channel, message[0], message[1]);
|
|
716
|
-
break;
|
|
717
|
-
|
|
718
|
-
case messageTypes.channelPressure:
|
|
719
|
-
this.channelPressure(channel, message[1]);
|
|
720
|
-
break;
|
|
721
|
-
|
|
722
|
-
case messageTypes.systemExclusive:
|
|
723
|
-
this.systemExclusive(new IndexedByteArray(message.slice(1)), channelOffset);
|
|
724
|
-
break;
|
|
725
|
-
|
|
726
|
-
case messageTypes.reset:
|
|
727
|
-
this.stopAllChannels(true);
|
|
728
|
-
this.resetAllControllers();
|
|
729
|
-
break;
|
|
730
|
-
|
|
731
|
-
default:
|
|
732
|
-
break;
|
|
733
|
-
}
|
|
734
|
-
};
|
|
735
|
-
|
|
736
|
-
const time = options.time;
|
|
737
|
-
if (time > this.currentSynthTime)
|
|
738
|
-
{
|
|
739
|
-
this.eventQueue.push({
|
|
740
|
-
callback: call.bind(this),
|
|
741
|
-
time: time
|
|
742
|
-
});
|
|
743
|
-
this.eventQueue.sort((e1, e2) => e1.time - e2.time);
|
|
744
|
-
}
|
|
745
|
-
else
|
|
746
|
-
{
|
|
747
|
-
call();
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
/**
|
|
752
|
-
* @param volume {number} 0 to 1
|
|
753
|
-
*/
|
|
754
|
-
setMIDIVolume(volume)
|
|
755
|
-
{
|
|
756
|
-
// GM2 specification, section 4.1: volume is squared.
|
|
757
|
-
// though, according to my own testing, Math.E seems like a better choice
|
|
758
|
-
this.midiVolume = Math.pow(volume, Math.E);
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
/**
|
|
762
|
-
* Calls synth event
|
|
763
|
-
* @param eventName {EventTypes} the event name
|
|
764
|
-
* @param eventData {EventCallbackData}
|
|
765
|
-
* @this {SpessaSynthProcessor}
|
|
766
|
-
*/
|
|
767
|
-
callEvent(eventName, eventData)
|
|
768
|
-
{
|
|
769
|
-
this?.onEventCall?.(eventName, eventData);
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
clearCache()
|
|
773
|
-
{
|
|
774
|
-
this.cachedVoices = [];
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
/**
|
|
778
|
-
* @param program {number}
|
|
779
|
-
* @param bank {number}
|
|
780
|
-
* @returns {BasicPreset}
|
|
781
|
-
*/
|
|
782
|
-
getPreset(bank, program)
|
|
783
|
-
{
|
|
784
|
-
return this.soundfontManager.getPreset(bank, program, isSystemXG(this.system)).preset;
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
// include other methods
|
|
789
|
-
// voice related
|
|
790
|
-
SpessaSynthProcessor.prototype.voiceKilling = voiceKilling;
|
|
791
|
-
SpessaSynthProcessor.prototype.getVoicesForPreset = getVoicesForPreset;
|
|
792
|
-
SpessaSynthProcessor.prototype.getVoices = getVoices;
|
|
793
|
-
|
|
794
|
-
// system-exclusive related
|
|
795
|
-
SpessaSynthProcessor.prototype.systemExclusive = systemExclusive;
|
|
796
|
-
|
|
797
|
-
// channel related
|
|
798
|
-
SpessaSynthProcessor.prototype.stopAllChannels = stopAllChannels;
|
|
799
|
-
SpessaSynthProcessor.prototype.createMidiChannel = createMidiChannel;
|
|
800
|
-
SpessaSynthProcessor.prototype.resetAllControllers = resetAllControllers;
|
|
801
|
-
|
|
802
|
-
// master parameter related
|
|
803
|
-
SpessaSynthProcessor.prototype.setMasterParameter = setMasterParameter;
|
|
804
|
-
|
|
805
|
-
// tuning related
|
|
806
|
-
SpessaSynthProcessor.prototype.transposeAllChannels = transposeAllChannels;
|
|
807
|
-
SpessaSynthProcessor.prototype.setMasterTuning = setMasterTuning;
|
|
808
|
-
|
|
809
|
-
// program related
|
|
810
|
-
SpessaSynthProcessor.prototype.clearEmbeddedBank = clearEmbeddedBank;
|
|
811
|
-
SpessaSynthProcessor.prototype.setEmbeddedSoundFont = setEmbeddedSoundFont;
|
|
812
|
-
SpessaSynthProcessor.prototype.updatePresetList = updatePresetList;
|
|
813
|
-
|
|
814
|
-
// snapshot related
|
|
815
|
-
SpessaSynthProcessor.prototype.applySynthesizerSnapshot = applySynthesizerSnapshot;
|
|
816
|
-
|
|
817
|
-
export { SpessaSynthProcessor };
|