spessasynth_lib 3.25.23 → 3.26.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.
Files changed (162) hide show
  1. package/README.md +29 -114
  2. package/external_midi/midi_handler.js +14 -14
  3. package/external_midi/web_midi_link.js +3 -3
  4. package/index.js +33 -33
  5. package/package.json +19 -6
  6. package/{midi → sequencer}/midi_data.js +1 -1
  7. package/sequencer/{worklet_wrapper/sequencer.js → sequencer.js} +13 -12
  8. package/sequencer/{worklet_wrapper/sequencer_message.js → sequencer_message.js} +1 -1
  9. package/synthetizer/README.md +29 -1
  10. package/synthetizer/audio_effects/reverb_as_binary.js +2 -2
  11. package/synthetizer/{worklet_wrapper/key_modifier_manager.js → key_modifier_manager.js} +11 -2
  12. package/synthetizer/{worklet_wrapper/synth_event_handler.js → synth_event_handler.js} +16 -13
  13. package/synthetizer/{worklet_wrapper/synth_soundfont_manager.js → synth_soundfont_manager.js} +8 -5
  14. package/synthetizer/{worklet_wrapper/synthetizer.js → synthetizer.js} +29 -23
  15. package/synthetizer/{audio_engine/message_protocol/worklet_message.js → worklet_message.js} +15 -2
  16. package/synthetizer/{worklet_wrapper/worklet_processor.js → worklet_processor.js} +214 -31
  17. package/synthetizer/worklet_processor.min.js +13 -12
  18. package/synthetizer/worklet_processor.min.js.map +7 -0
  19. package/synthetizer/{worklet_wrapper/worklet_url.js → worklet_url.js} +2 -0
  20. package/utils/buffer_to_wav.js +7 -165
  21. package/utils/other.js +3 -84
  22. package/externals/fflate/LICENSE +0 -21
  23. package/externals/fflate/fflate.min.js +0 -1
  24. package/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +0 -12
  25. package/externals/stbvorbis_sync/LICENSE +0 -202
  26. package/externals/stbvorbis_sync/NOTICE +0 -6
  27. package/externals/stbvorbis_sync/stbvorbis_sync.min.js +0 -1
  28. package/midi/README.md +0 -32
  29. package/midi/basic_midi.js +0 -565
  30. package/midi/midi_builder.js +0 -202
  31. package/midi/midi_loader.js +0 -324
  32. package/midi/midi_message.js +0 -254
  33. package/midi/midi_sequence.js +0 -225
  34. package/midi/midi_tools/get_note_times.js +0 -154
  35. package/midi/midi_tools/midi_editor.js +0 -611
  36. package/midi/midi_tools/midi_writer.js +0 -99
  37. package/midi/midi_tools/rmidi_writer.js +0 -567
  38. package/midi/midi_tools/used_keys_loaded.js +0 -238
  39. package/midi/xmf_loader.js +0 -454
  40. package/sequencer/sequencer_engine/events.js +0 -104
  41. package/sequencer/sequencer_engine/play.js +0 -353
  42. package/sequencer/sequencer_engine/process_event.js +0 -169
  43. package/sequencer/sequencer_engine/process_tick.js +0 -106
  44. package/sequencer/sequencer_engine/sequencer_engine.js +0 -335
  45. package/sequencer/sequencer_engine/song_control.js +0 -229
  46. package/soundfont/README.md +0 -13
  47. package/soundfont/basic_soundfont/basic_instrument.js +0 -77
  48. package/soundfont/basic_soundfont/basic_preset.js +0 -336
  49. package/soundfont/basic_soundfont/basic_sample.js +0 -197
  50. package/soundfont/basic_soundfont/basic_soundfont.js +0 -565
  51. package/soundfont/basic_soundfont/basic_zone.js +0 -64
  52. package/soundfont/basic_soundfont/basic_zones.js +0 -43
  53. package/soundfont/basic_soundfont/generator.js +0 -220
  54. package/soundfont/basic_soundfont/modulator.js +0 -378
  55. package/soundfont/basic_soundfont/riff_chunk.js +0 -149
  56. package/soundfont/basic_soundfont/write_dls/art2.js +0 -173
  57. package/soundfont/basic_soundfont/write_dls/articulator.js +0 -49
  58. package/soundfont/basic_soundfont/write_dls/combine_zones.js +0 -400
  59. package/soundfont/basic_soundfont/write_dls/ins.js +0 -103
  60. package/soundfont/basic_soundfont/write_dls/lins.js +0 -18
  61. package/soundfont/basic_soundfont/write_dls/modulator_converter.js +0 -330
  62. package/soundfont/basic_soundfont/write_dls/rgn2.js +0 -121
  63. package/soundfont/basic_soundfont/write_dls/wave.js +0 -94
  64. package/soundfont/basic_soundfont/write_dls/write_dls.js +0 -119
  65. package/soundfont/basic_soundfont/write_dls/wsmp.js +0 -78
  66. package/soundfont/basic_soundfont/write_dls/wvpl.js +0 -32
  67. package/soundfont/basic_soundfont/write_sf2/ibag.js +0 -39
  68. package/soundfont/basic_soundfont/write_sf2/igen.js +0 -80
  69. package/soundfont/basic_soundfont/write_sf2/imod.js +0 -46
  70. package/soundfont/basic_soundfont/write_sf2/inst.js +0 -34
  71. package/soundfont/basic_soundfont/write_sf2/pbag.js +0 -39
  72. package/soundfont/basic_soundfont/write_sf2/pgen.js +0 -82
  73. package/soundfont/basic_soundfont/write_sf2/phdr.js +0 -42
  74. package/soundfont/basic_soundfont/write_sf2/pmod.js +0 -46
  75. package/soundfont/basic_soundfont/write_sf2/sdta.js +0 -80
  76. package/soundfont/basic_soundfont/write_sf2/shdr.js +0 -55
  77. package/soundfont/basic_soundfont/write_sf2/write.js +0 -222
  78. package/soundfont/dls/articulator_converter.js +0 -396
  79. package/soundfont/dls/dls_destinations.js +0 -38
  80. package/soundfont/dls/dls_preset.js +0 -44
  81. package/soundfont/dls/dls_sample.js +0 -75
  82. package/soundfont/dls/dls_soundfont.js +0 -186
  83. package/soundfont/dls/dls_sources.js +0 -62
  84. package/soundfont/dls/dls_zone.js +0 -95
  85. package/soundfont/dls/read_articulation.js +0 -299
  86. package/soundfont/dls/read_instrument.js +0 -121
  87. package/soundfont/dls/read_instrument_list.js +0 -17
  88. package/soundfont/dls/read_lart.js +0 -35
  89. package/soundfont/dls/read_region.js +0 -152
  90. package/soundfont/dls/read_samples.js +0 -270
  91. package/soundfont/load_soundfont.js +0 -21
  92. package/soundfont/read_sf2/generators.js +0 -46
  93. package/soundfont/read_sf2/instruments.js +0 -66
  94. package/soundfont/read_sf2/modulators.js +0 -36
  95. package/soundfont/read_sf2/presets.js +0 -80
  96. package/soundfont/read_sf2/samples.js +0 -304
  97. package/soundfont/read_sf2/soundfont.js +0 -305
  98. package/soundfont/read_sf2/zones.js +0 -263
  99. package/synthetizer/audio_engine/README.md +0 -25
  100. package/synthetizer/audio_engine/engine_components/compute_modulator.js +0 -266
  101. package/synthetizer/audio_engine/engine_components/controller_tables.js +0 -88
  102. package/synthetizer/audio_engine/engine_components/key_modifier_manager.js +0 -149
  103. package/synthetizer/audio_engine/engine_components/lfo.js +0 -26
  104. package/synthetizer/audio_engine/engine_components/lowpass_filter.js +0 -282
  105. package/synthetizer/audio_engine/engine_components/midi_audio_channel.js +0 -471
  106. package/synthetizer/audio_engine/engine_components/modulation_envelope.js +0 -181
  107. package/synthetizer/audio_engine/engine_components/modulator_curves.js +0 -89
  108. package/synthetizer/audio_engine/engine_components/soundfont_manager.js +0 -228
  109. package/synthetizer/audio_engine/engine_components/stereo_panner.js +0 -120
  110. package/synthetizer/audio_engine/engine_components/unit_converter.js +0 -73
  111. package/synthetizer/audio_engine/engine_components/voice.js +0 -519
  112. package/synthetizer/audio_engine/engine_components/volume_envelope.js +0 -401
  113. package/synthetizer/audio_engine/engine_components/wavetable_oscillator.js +0 -263
  114. package/synthetizer/audio_engine/engine_methods/controller_control/controller_change.js +0 -132
  115. package/synthetizer/audio_engine/engine_methods/controller_control/master_parameters.js +0 -48
  116. package/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +0 -241
  117. package/synthetizer/audio_engine/engine_methods/create_midi_channel.js +0 -27
  118. package/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +0 -253
  119. package/synthetizer/audio_engine/engine_methods/data_entry/data_entry_fine.js +0 -66
  120. package/synthetizer/audio_engine/engine_methods/mute_channel.js +0 -17
  121. package/synthetizer/audio_engine/engine_methods/note_on.js +0 -175
  122. package/synthetizer/audio_engine/engine_methods/portamento_time.js +0 -92
  123. package/synthetizer/audio_engine/engine_methods/program_change.js +0 -61
  124. package/synthetizer/audio_engine/engine_methods/render_voice.js +0 -196
  125. package/synthetizer/audio_engine/engine_methods/soundfont_management/clear_sound_font.js +0 -30
  126. package/synthetizer/audio_engine/engine_methods/soundfont_management/get_preset.js +0 -22
  127. package/synthetizer/audio_engine/engine_methods/soundfont_management/reload_sound_font.js +0 -40
  128. package/synthetizer/audio_engine/engine_methods/soundfont_management/send_preset_list.js +0 -34
  129. package/synthetizer/audio_engine/engine_methods/soundfont_management/set_embedded_sound_font.js +0 -21
  130. package/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +0 -20
  131. package/synthetizer/audio_engine/engine_methods/stopping_notes/note_off.js +0 -55
  132. package/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_channels.js +0 -16
  133. package/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_notes.js +0 -30
  134. package/synthetizer/audio_engine/engine_methods/stopping_notes/voice_killing.js +0 -63
  135. package/synthetizer/audio_engine/engine_methods/system_exclusive.js +0 -776
  136. package/synthetizer/audio_engine/engine_methods/tuning_control/channel_pressure.js +0 -24
  137. package/synthetizer/audio_engine/engine_methods/tuning_control/pitch_wheel.js +0 -33
  138. package/synthetizer/audio_engine/engine_methods/tuning_control/poly_pressure.js +0 -31
  139. package/synthetizer/audio_engine/engine_methods/tuning_control/set_master_tuning.js +0 -15
  140. package/synthetizer/audio_engine/engine_methods/tuning_control/set_modulation_depth.js +0 -27
  141. package/synthetizer/audio_engine/engine_methods/tuning_control/set_octave_tuning.js +0 -19
  142. package/synthetizer/audio_engine/engine_methods/tuning_control/set_tuning.js +0 -27
  143. package/synthetizer/audio_engine/engine_methods/tuning_control/transpose_all_channels.js +0 -15
  144. package/synthetizer/audio_engine/engine_methods/tuning_control/transpose_channel.js +0 -34
  145. package/synthetizer/audio_engine/main_processor.js +0 -765
  146. package/synthetizer/audio_engine/message_protocol/README.md +0 -13
  147. package/synthetizer/audio_engine/message_protocol/message_sending.js +0 -22
  148. package/synthetizer/audio_engine/snapshot/apply_synthesizer_snapshot.js +0 -14
  149. package/synthetizer/audio_engine/snapshot/channel_snapshot.js +0 -175
  150. package/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js +0 -122
  151. package/synthetizer/synth_constants.js +0 -20
  152. package/utils/README.md +0 -5
  153. package/utils/byte_functions/big_endian.js +0 -32
  154. package/utils/byte_functions/little_endian.js +0 -77
  155. package/utils/byte_functions/string.js +0 -107
  156. package/utils/byte_functions/variable_length_quantity.js +0 -42
  157. package/utils/indexed_array.js +0 -52
  158. package/utils/loggin.js +0 -79
  159. package/utils/sysex_detector.js +0 -58
  160. package/utils/xg_hacks.js +0 -193
  161. /package/sequencer/{worklet_wrapper/default_sequencer_options.js → default_sequencer_options.js} +0 -0
  162. /package/synthetizer/{worklet_wrapper/sfman_message.js → sfman_message.js} +0 -0
@@ -1,776 +0,0 @@
1
- import { arrayToHexString, consoleColors } from "../../../utils/other.js";
2
- import { SpessaSynthInfo, SpessaSynthWarn } from "../../../utils/loggin.js";
3
- import { midiControllers } from "../../../midi/midi_message.js";
4
- import { ALL_CHANNELS_OR_DIFFERENT_ACTION } from "../message_protocol/worklet_message.js";
5
- import { isSystemXG } from "../../../utils/xg_hacks.js";
6
- import { masterParameterType } from "./controller_control/master_parameters.js";
7
- import { readBytesAsString } from "../../../utils/byte_functions/string.js";
8
-
9
- /**
10
- * KeyNum: tuning
11
- * @typedef {MTSNoteTuning[]} MTSProgramTuning
12
- */
13
-
14
- /**
15
- * @typedef {Object} MTSNoteTuning
16
- * @property {number} midiNote - the base midi note to use, -1 means no change
17
- * @property {number} centTuning - additional tuning
18
- */
19
-
20
- /**
21
- * Calculates freqency for MIDI Tuning Standard
22
- * @param byte1 {number}
23
- * @param byte2 {number}
24
- * @param byte3 {number}
25
- * @return {{midiNote: number, centTuning: number|null}}
26
- */
27
- function getTuning(byte1, byte2, byte3)
28
- {
29
- const midiNote = byte1;
30
- const fraction = (byte2 << 7) | byte3; // Combine byte2 and byte3 into a 14-bit number
31
-
32
- // no change
33
- if (byte1 === 0x7F && byte2 === 0x7F && byte3 === 0x7F)
34
- {
35
- return { midiNote: -1, centTuning: null };
36
- }
37
-
38
- // calculate cent tuning
39
- return { midiNote: midiNote, centTuning: fraction * 0.0061 };
40
- }
41
-
42
- /**
43
- * The text types for the synth display
44
- * @enum {number}
45
- */
46
- export const SynthDisplayType = {
47
- SoundCanvasText: 0,
48
- XGText: 1,
49
- SoundCanvasDotDisplay: 2
50
- };
51
-
52
-
53
- /**
54
- * Executes a system exclusive
55
- * @param messageData {number[]|IndexedByteArray} - the message data without f0
56
- * @param channelOffset {number}
57
- * @this {SpessaSynthProcessor}
58
- */
59
- export function systemExclusive(messageData, channelOffset = 0)
60
- {
61
- const type = messageData[0];
62
- if (this.deviceID !== ALL_CHANNELS_OR_DIFFERENT_ACTION && messageData[1] !== 0x7F)
63
- {
64
- if (this.deviceID !== messageData[1])
65
- {
66
- // not our device ID
67
- return;
68
- }
69
- }
70
- switch (type)
71
- {
72
- default:
73
- SpessaSynthWarn(
74
- `%cUnrecognized SysEx: %c${arrayToHexString(messageData)}`,
75
- consoleColors.warn,
76
- consoleColors.unrecognized
77
- );
78
- break;
79
-
80
- // non realtime
81
- case 0x7E:
82
- case 0x7F:
83
- switch (messageData[2])
84
- {
85
- case 0x04:
86
- let cents;
87
- // device control
88
- switch (messageData[3])
89
- {
90
- case 0x01:
91
- // main volume
92
- const vol = messageData[5] << 7 | messageData[4];
93
- this.setMIDIVolume(vol / 16384);
94
- SpessaSynthInfo(
95
- `%cMaster Volume. Volume: %c${vol}`,
96
- consoleColors.info,
97
- consoleColors.value
98
- );
99
- break;
100
-
101
- case 0x02:
102
- // main balance
103
- // midi spec page 62
104
- const balance = messageData[5] << 7 | messageData[4];
105
- const pan = (balance - 8192) / 8192;
106
- this.setMasterParameter(masterParameterType.masterPan, pan);
107
- SpessaSynthInfo(
108
- `%cMaster Pan. Pan: %c${pan}`,
109
- consoleColors.info,
110
- consoleColors.value
111
- );
112
- break;
113
-
114
-
115
- case 0x03:
116
- // fine-tuning
117
- const tuningValue = ((messageData[5] << 7) | messageData[6]) - 8192;
118
- cents = Math.floor(tuningValue / 81.92); // [-100;+99] cents range
119
- this.setMasterTuning(cents);
120
- SpessaSynthInfo(
121
- `%cMaster Fine Tuning. Cents: %c${cents}`,
122
- consoleColors.info,
123
- consoleColors.value
124
- );
125
- break;
126
-
127
- case 0x04:
128
- // coarse tuning
129
- // lsb is ignored
130
- const semitones = messageData[5] - 64;
131
- cents = semitones * 100;
132
- this.setMasterTuning(cents);
133
- SpessaSynthInfo(
134
- `%cMaster Coarse Tuning. Cents: %c${cents}`,
135
- consoleColors.info,
136
- consoleColors.value
137
- );
138
- break;
139
-
140
- default:
141
- SpessaSynthWarn(
142
- `%cUnrecognized MIDI Device Control Real-time message: %c${arrayToHexString(messageData)}`,
143
- consoleColors.warn,
144
- consoleColors.unrecognized
145
- );
146
- }
147
- break;
148
-
149
- case 0x09:
150
- // gm system related
151
- if (messageData[3] === 0x01)
152
- {
153
- SpessaSynthInfo("%cGM1 system on", consoleColors.info);
154
- this.setSystem("gm");
155
- }
156
- else if (messageData[3] === 0x03)
157
- {
158
- SpessaSynthInfo("%cGM2 system on", consoleColors.info);
159
- this.setSystem("gm2");
160
- }
161
- else
162
- {
163
- SpessaSynthInfo("%cGM system off, defaulting to GS", consoleColors.info);
164
- this.setSystem("gs");
165
- }
166
- break;
167
-
168
- // MIDI Tuning standard
169
- // https://midi.org/midi-tuning-updated-specification
170
- case 0x08:
171
- let currentMessageIndex = 4;
172
- switch (messageData[3])
173
- {
174
- // bulk tuning dump: all 128 notes
175
- case 0x01:
176
- const program = messageData[currentMessageIndex++];
177
- // read the name
178
- messageData.currentIndex = currentMessageIndex;
179
- const tuningName = readBytesAsString(messageData, 16);
180
- currentMessageIndex += 16;
181
- if (messageData.length < 384)
182
- {
183
- SpessaSynthWarn(`The Bulk Tuning Dump is too short! (${messageData.length} bytes, at least 384 are expected)`);
184
- return;
185
- }
186
- // 128 frequencies follow
187
- for (let i = 0; i < 128; i++)
188
- {
189
- // set the given tuning to the program
190
- this.tunings[program][i] = getTuning(
191
- messageData[currentMessageIndex++],
192
- messageData[currentMessageIndex++],
193
- messageData[currentMessageIndex++]
194
- );
195
- }
196
- SpessaSynthInfo(
197
- `%cBulk Tuning Dump %c${tuningName}%c Program: %c${program}`,
198
- consoleColors.info,
199
- consoleColors.value,
200
- consoleColors.info,
201
- consoleColors.recognized
202
- );
203
- break;
204
-
205
- // single note change
206
- // single note change bank
207
- case 0x02:
208
- case 0x07:
209
- if (messageData[3] === 0x07)
210
- {
211
- // skip the bank
212
- currentMessageIndex++;
213
- }
214
- // get program and number of changes
215
- const tuningProgram = messageData[currentMessageIndex++];
216
- const numberOfChanges = messageData[currentMessageIndex++];
217
- for (let i = 0; i < numberOfChanges; i++)
218
- {
219
- // set the given tuning to the program
220
- this.tunings[tuningProgram][messageData[currentMessageIndex++]] = getTuning(
221
- messageData[currentMessageIndex++],
222
- messageData[currentMessageIndex++],
223
- messageData[currentMessageIndex++]
224
- );
225
- }
226
- SpessaSynthInfo(
227
- `%cSingle Note Tuning. Program: %c${tuningProgram}%c Keys affected: %c${numberOfChanges}`,
228
- consoleColors.info,
229
- consoleColors.recognized,
230
- consoleColors.info,
231
- consoleColors.recognized
232
- );
233
- break;
234
-
235
- // octave tuning (1 byte)
236
- // and octave tuning (2 bytes)
237
- case 0x09:
238
- case 0x08:
239
- // get tuning:
240
- const newOctaveTuning = new Int8Array(12);
241
- // start from bit 7
242
- if (messageData[3] === 0x08)
243
- {
244
- // 1 byte tuning: 0 is -64 cents, 64 is 0, 127 is +63
245
- for (let i = 0; i < 12; i++)
246
- {
247
- newOctaveTuning[i] = messageData[7 + i] - 64;
248
- }
249
- }
250
- else
251
- {
252
- // 2 byte tuning. Like fine tune: 0 is -100 cents, 8192 is 0 cents, 16,383 is +100 cents
253
- for (let i = 0; i < 24; i += 2)
254
- {
255
- const tuning = ((messageData[7 + i] << 7) | messageData[8 + i]) - 8192;
256
- newOctaveTuning[i / 2] = Math.floor(tuning / 81.92); // map to [-100;+99] cents
257
- }
258
- }
259
- // apply to channels (ordered from 0)
260
- // bit 1: 14 and 15
261
- if ((messageData[4] & 1) === 1)
262
- {
263
- this.midiAudioChannels[14 + channelOffset].setOctaveTuning(newOctaveTuning);
264
- }
265
- if (((messageData[4] >> 1) & 1) === 1)
266
- {
267
- this.midiAudioChannels[15 + channelOffset].setOctaveTuning(newOctaveTuning);
268
- }
269
-
270
- // bit 2: channels 7 to 13
271
- for (let i = 0; i < 7; i++)
272
- {
273
- const bit = (messageData[5] >> i) & 1;
274
- if (bit === 1)
275
- {
276
- this.midiAudioChannels[7 + i + channelOffset].setOctaveTuning(newOctaveTuning);
277
- }
278
- }
279
-
280
- // bit 3: channels 0 to 16
281
- for (let i = 0; i < 7; i++)
282
- {
283
- const bit = (messageData[6] >> i) & 1;
284
- if (bit === 1)
285
- {
286
- this.midiAudioChannels[i + channelOffset].setOctaveTuning(newOctaveTuning);
287
- }
288
- }
289
-
290
- SpessaSynthInfo(
291
- `%cMIDI Octave Scale ${
292
- messageData[3] === 0x08 ? "(1 byte)" : "(2 bytes)"
293
- } tuning via Tuning: %c${newOctaveTuning.join(" ")}`,
294
- consoleColors.info,
295
- consoleColors.value
296
- );
297
- break;
298
-
299
- default:
300
- SpessaSynthWarn(
301
- `%cUnrecognized MIDI Tuning standard message: %c${arrayToHexString(messageData)}`,
302
- consoleColors.warn,
303
- consoleColors.unrecognized
304
- );
305
- break;
306
- }
307
- break;
308
-
309
- default:
310
- SpessaSynthWarn(
311
- `%cUnrecognized MIDI Realtime/non realtime message: %c${arrayToHexString(messageData)}`,
312
- consoleColors.warn,
313
- consoleColors.unrecognized
314
- );
315
-
316
- }
317
- break;
318
-
319
- // this is a roland sysex
320
- // http://www.bandtrax.com.au/sysex.htm
321
- // https://cdn.roland.com/assets/media/pdf/AT-20R_30R_MI.pdf
322
- case 0x41:
323
-
324
- function notRecognized()
325
- {
326
- // this is some other GS sysex...
327
- SpessaSynthWarn(
328
- `%cUnrecognized Roland %cGS %cSysEx: %c${arrayToHexString(messageData)}`,
329
- consoleColors.warn,
330
- consoleColors.recognized,
331
- consoleColors.warn,
332
- consoleColors.unrecognized
333
- );
334
- }
335
-
336
- if (messageData[2] === 0x42 && messageData[3] === 0x12)
337
- {
338
- // this is a GS sysex
339
- // messageData[5] and [6] is the system parameter, messageData[7] is the value
340
- const messageValue = messageData[7];
341
- if (messageData[6] === 0x7F)
342
- {
343
- // GS mode set
344
- if (messageValue === 0x00)
345
- {
346
- // this is a GS reset
347
- SpessaSynthInfo("%cGS Reset received!", consoleColors.info);
348
- this.resetAllControllers(false);
349
- this.setSystem("gs");
350
- }
351
- else if (messageValue === 0x7F)
352
- {
353
- // GS mode off
354
- SpessaSynthInfo("%cGS system off, switching to GM2", consoleColors.info);
355
- this.resetAllControllers(false);
356
- this.setSystem("gm2");
357
- }
358
- return;
359
- }
360
- else if (messageData[4] === 0x40)
361
- {
362
- // this is a system parameter
363
- if ((messageData[5] & 0x10) > 0)
364
- {
365
- // this is an individual part (channel) parameter
366
- // determine the channel 0 means channel 10 (default), 1 means 1 etc.
367
- const channel = [9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15][messageData[5] & 0x0F] + channelOffset;
368
- // for example, 0x1A means A = 11, which corresponds to channel 12 (counting from 1)
369
- const channelObject = this.midiAudioChannels[channel];
370
- switch (messageData[6])
371
- {
372
- default:
373
- // this is some other GS sysex...
374
- notRecognized();
375
- break;
376
-
377
- case 0x15:
378
- // this is the Use for Drum Part sysex (multiple drums)
379
- const isDrums = messageValue > 0 && messageData[5] >> 4; // if set to other than 0, is a drum channel
380
- channelObject.setDrums(isDrums);
381
- SpessaSynthInfo(
382
- `%cChannel %c${channel}%c ${isDrums ?
383
- "is now a drum channel"
384
- :
385
- "now isn't a drum channel"
386
- }%c via: %c${arrayToHexString(messageData)}`,
387
- consoleColors.info,
388
- consoleColors.value,
389
- consoleColors.recognized,
390
- consoleColors.info,
391
- consoleColors.value
392
- );
393
- return;
394
-
395
- case 0x16:
396
- // this is the pitch key shift sysex
397
- const keyShift = messageValue - 64;
398
- channelObject.transposeChannel(keyShift);
399
- SpessaSynthInfo(
400
- `%cChannel %c${channel}%c pitch shift. Semitones %c${keyShift}%c, with %c${arrayToHexString(
401
- messageData)}`,
402
- consoleColors.info,
403
- consoleColors.recognized,
404
- consoleColors.info,
405
- consoleColors.value,
406
- consoleColors.info,
407
- consoleColors.value
408
- );
409
- return;
410
-
411
- // pan position
412
- case 0x1C:
413
- // 0 is random
414
- let panpot = messageValue;
415
- if (panpot === 0)
416
- {
417
- channelObject.randomPan = true;
418
- SpessaSynthInfo(
419
- `%cRandom pan is set to %cON%c for %c${channel}`,
420
- consoleColors.info,
421
- consoleColors.recognized,
422
- consoleColors.info,
423
- consoleColors.value
424
- );
425
- }
426
- else
427
- {
428
- channelObject.randomPan = false;
429
- channelObject.controllerChange(midiControllers.pan, panpot);
430
- }
431
- break;
432
-
433
- // chorus send
434
- case 0x21:
435
- channelObject.controllerChange(midiControllers.chorusDepth, messageValue);
436
- break;
437
-
438
- // reverb send
439
- case 0x22:
440
- channelObject.controllerChange(midiControllers.reverbDepth, messageValue);
441
- break;
442
-
443
- case 0x40:
444
- case 0x41:
445
- case 0x42:
446
- case 0x43:
447
- case 0x44:
448
- case 0x45:
449
- case 0x46:
450
- case 0x47:
451
- case 0x48:
452
- case 0x49:
453
- case 0x4A:
454
- case 0x4B:
455
- // scale tuning: up to 12 bytes
456
- const tuningBytes = messageData.length - 9; // data starts at 7, minus checksum and f7
457
- // read em bytes
458
- const newTuning = new Int8Array(12);
459
- for (let i = 0; i < tuningBytes; i++)
460
- {
461
- newTuning[i] = messageData[i + 7] - 64;
462
- }
463
- channelObject.setOctaveTuning(newTuning);
464
- const cents = messageValue - 64;
465
- SpessaSynthInfo(
466
- `%cChannel %c${channel}%c octave scale tuning. Cents %c${newTuning.join(
467
- " ")}%c, with %c${arrayToHexString(messageData)}`,
468
- consoleColors.info,
469
- consoleColors.recognized,
470
- consoleColors.info,
471
- consoleColors.value,
472
- consoleColors.info,
473
- consoleColors.value
474
- );
475
- channelObject.setTuning(cents);
476
- break;
477
- }
478
- return;
479
- }
480
- else
481
- // this is a global system parameter
482
- if (messageData[5] === 0x00 && messageData[6] === 0x06)
483
- {
484
- // roland master pan
485
- SpessaSynthInfo(
486
- `%cRoland GS Master Pan set to: %c${messageValue}%c with: %c${arrayToHexString(
487
- messageData)}`,
488
- consoleColors.info,
489
- consoleColors.value,
490
- consoleColors.info,
491
- consoleColors.value
492
- );
493
- this.setMasterParameter(masterParameterType.masterPan, (messageValue - 64) / 64);
494
- return;
495
- }
496
- else if (messageData[5] === 0x00 && messageData[6] === 0x05)
497
- {
498
- // roland master key shift (transpose)
499
- const transpose = messageValue - 64;
500
- SpessaSynthInfo(
501
- `%cRoland GS Master Key-Shift set to: %c${transpose}%c with: %c${arrayToHexString(
502
- messageData)}`,
503
- consoleColors.info,
504
- consoleColors.value,
505
- consoleColors.info,
506
- consoleColors.value
507
- );
508
- this.setMasterTuning(transpose * 100);
509
- return;
510
- }
511
- else if (messageData[5] === 0x00 && messageData[6] === 0x04)
512
- {
513
- // roland GS master volume
514
- SpessaSynthInfo(
515
- `%cRoland GS Master Volume set to: %c${messageValue}%c with: %c${arrayToHexString(
516
- messageData)}`,
517
- consoleColors.info,
518
- consoleColors.value,
519
- consoleColors.info,
520
- consoleColors.value
521
- );
522
- this.setMIDIVolume(messageValue / 127);
523
- return;
524
- }
525
- }
526
- // this is some other GS sysex...
527
- notRecognized();
528
- return;
529
- }
530
- else if (messageData[2] === 0x45 && messageData[3] === 0x12)
531
- {
532
- // 0x45: GS Display Data, 0x12: DT1 (Device Transmit)
533
- // check for embedded copyright
534
- // (roland SC display sysex) http://www.bandtrax.com.au/sysex.htm
535
-
536
- if (
537
- messageData[4] === 0x10 && // Sound Canvas Display
538
- messageData[6] === 0x00 // Data follows
539
- )
540
- {
541
- if (messageData[5] === 0x00) // Display letters
542
- {
543
- // get the text
544
- // and header ends with (checksum) F7
545
- const text = new Uint8Array(messageData.slice(7, messageData.length - 2));
546
- this.callEvent(
547
- "synthdisplay",
548
- {
549
- displayData: text,
550
- displayType: SynthDisplayType.SoundCanvasText
551
- }
552
- );
553
- }
554
- else if (messageData[5] === 0x01) // Matrix display
555
- {
556
- // get the data
557
- // and header ends with (checksum) F7
558
- const dotMatrixData = new Uint8Array(messageData.slice(7, messageData.length - 3));
559
- this.callEvent(
560
- "synthdisplay",
561
- {
562
- displayData: dotMatrixData,
563
- displayType: SynthDisplayType.SoundCanvasDotDisplay
564
- }
565
- );
566
- SpessaSynthInfo(
567
- `%cRoland SC Display Dot Matrix via: %c${arrayToHexString(
568
- messageData)}`,
569
- consoleColors.info,
570
- consoleColors.value
571
- );
572
- }
573
- else
574
- {
575
- // this is some other GS sysex...
576
- notRecognized();
577
- }
578
- }
579
- }
580
- else if (messageData[2] === 0x16 && messageData[3] === 0x12 && messageData[4] === 0x10)
581
- {
582
- // this is a roland master volume message
583
- this.setMIDIVolume(messageData[7] / 100);
584
- SpessaSynthInfo(
585
- `%cRoland Master Volume control set to: %c${messageData[7]}%c via: %c${arrayToHexString(
586
- messageData)}`,
587
- consoleColors.info,
588
- consoleColors.value,
589
- consoleColors.info,
590
- consoleColors.value
591
- );
592
- return;
593
- }
594
- else
595
- {
596
- // this is something else...
597
- SpessaSynthWarn(
598
- `%cUnrecognized Roland SysEx: %c${arrayToHexString(messageData)}`,
599
- consoleColors.warn,
600
- consoleColors.unrecognized
601
- );
602
- return;
603
- }
604
- break;
605
-
606
- // yamaha
607
- // http://www.studio4all.de/htmle/main91.html
608
- case 0x43:
609
- // XG sysex
610
- if (messageData[2] === 0x4C)
611
- {
612
- // XG system parameter
613
- if (messageData[3] === 0x00 && messageData[4] === 0x00)
614
- {
615
- switch (messageData[5])
616
- {
617
- // master volume
618
- case 0x04:
619
- const vol = messageData[6];
620
- this.setMIDIVolume(vol / 127);
621
- SpessaSynthInfo(
622
- `%cXG master volume. Volume: %c${vol}`,
623
- consoleColors.info,
624
- consoleColors.recognized
625
- );
626
- break;
627
-
628
- // master transpose
629
- case 0x06:
630
- const transpose = messageData[6] - 64;
631
- this.transposeAllChannels(transpose);
632
- SpessaSynthInfo(
633
- `%cXG master transpose. Volume: %c${transpose}`,
634
- consoleColors.info,
635
- consoleColors.recognized
636
- );
637
- break;
638
-
639
- // XG on
640
- case 0x7E:
641
- SpessaSynthInfo("%cXG system on", consoleColors.info);
642
- this.resetAllControllers(false);
643
- this.setSystem("xg");
644
- break;
645
- }
646
- }
647
- else
648
- // XG part parameter
649
- if (messageData[3] === 0x08)
650
- {
651
- if (!isSystemXG(this.system))
652
- {
653
- return;
654
- }
655
- const channel = messageData[4] + channelOffset;
656
- if (channel >= this.midiAudioChannels.length)
657
- {
658
- // invalid channel
659
- return;
660
- }
661
- const channelObject = this.midiAudioChannels[channel];
662
- const value = messageData[6];
663
- switch (messageData[5])
664
- {
665
- // bank-select MSB
666
- case 0x01:
667
- channelObject.controllerChange(midiControllers.bankSelect, value);
668
- break;
669
-
670
- // bank-select LSB
671
- case 0x02:
672
- channelObject.controllerChange(midiControllers.lsbForControl0BankSelect, value);
673
- break;
674
-
675
- // program change
676
- case 0x03:
677
- channelObject.programChange(value);
678
- break;
679
-
680
- // note shift
681
- case 0x08:
682
- if (channelObject.drumChannel)
683
- {
684
- return;
685
- }
686
- const semitones = value - 64;
687
- channelObject.channelTransposeKeyShift = semitones;
688
- break;
689
-
690
- // volume
691
- case 0x0B:
692
- channelObject.controllerChange(midiControllers.mainVolume, value);
693
- break;
694
-
695
- // pan position
696
- case 0x0E:
697
- let pan = value;
698
- if (pan === 0)
699
- {
700
- // 0 means random
701
- channelObject.randomPan = true;
702
- SpessaSynthInfo(
703
- `%cRandom pan is set to %cON%c for %c${channel}`,
704
- consoleColors.info,
705
- consoleColors.recognized,
706
- consoleColors.info,
707
- consoleColors.value
708
- );
709
- }
710
- else
711
- {
712
- channelObject.controllerChange(midiControllers.pan, pan);
713
- }
714
- break;
715
-
716
- // reverb
717
- case 0x13:
718
- channelObject.controllerChange(midiControllers.reverbDepth, value);
719
- break;
720
-
721
- // chorus
722
- case 0x12:
723
- channelObject.controllerChange(midiControllers.chorusDepth, value);
724
- break;
725
-
726
- default:
727
- SpessaSynthWarn(
728
- `%cUnrecognized Yamaha XG Part Setup: %c${messageData[5].toString(16)
729
- .toUpperCase()}`,
730
- consoleColors.warn,
731
- consoleColors.unrecognized
732
- );
733
- }
734
- }
735
- else if (
736
- messageData[3] === 0x06 && // XG System parameter
737
- messageData[4] === 0x00 // System Byte
738
- )
739
- {
740
- // displayed letters (remove F7 at the end)
741
- // include byte 5 as it seems to be line information (useful)
742
- const textData = new Uint8Array(messageData.slice(5, messageData.length - 1));
743
- this.callEvent(
744
- "synthdisplay",
745
- {
746
- displayData: textData,
747
- displayType: SynthDisplayType.XGText
748
- }
749
- );
750
- }
751
- else if (isSystemXG(this.system))
752
- {
753
- SpessaSynthWarn(
754
- `%cUnrecognized Yamaha XG SysEx: %c${arrayToHexString(messageData)}`,
755
- consoleColors.warn,
756
- consoleColors.unrecognized
757
- );
758
- }
759
-
760
- }
761
- else
762
- {
763
- if (isSystemXG(this.system))
764
- {
765
- SpessaSynthWarn(
766
- `%cUnrecognized Yamaha SysEx: %c${arrayToHexString(messageData)}`,
767
- consoleColors.warn,
768
- consoleColors.unrecognized
769
- );
770
- }
771
- }
772
- break;
773
-
774
-
775
- }
776
- }