spessasynth_core 3.27.7 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/README.md +188 -116
  2. package/dist/index.d.ts +4057 -0
  3. package/dist/index.js +17188 -0
  4. package/dist/index.js.map +1 -0
  5. package/package.json +23 -6
  6. package/index.js +0 -132
  7. package/src/externals/README.md +0 -6
  8. package/src/externals/fflate/LICENSE +0 -21
  9. package/src/externals/fflate/fflate.min.js +0 -1
  10. package/src/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +0 -12
  11. package/src/externals/stbvorbis_sync/LICENSE +0 -202
  12. package/src/externals/stbvorbis_sync/NOTICE +0 -6
  13. package/src/externals/stbvorbis_sync/stbvorbis_sync.min.js +0 -1
  14. package/src/midi/README.md +0 -32
  15. package/src/midi/basic_midi.js +0 -587
  16. package/src/midi/midi_builder.js +0 -203
  17. package/src/midi/midi_loader.js +0 -321
  18. package/src/midi/midi_message.js +0 -254
  19. package/src/midi/midi_sequence.js +0 -230
  20. package/src/midi/midi_tools/get_note_times.js +0 -154
  21. package/src/midi/midi_tools/midi_editor.js +0 -611
  22. package/src/midi/midi_tools/midi_writer.js +0 -105
  23. package/src/midi/midi_tools/rmidi_writer.js +0 -566
  24. package/src/midi/midi_tools/used_keys_loaded.js +0 -256
  25. package/src/midi/xmf_loader.js +0 -454
  26. package/src/sequencer/README.md +0 -9
  27. package/src/sequencer/events.js +0 -81
  28. package/src/sequencer/play.js +0 -362
  29. package/src/sequencer/process_event.js +0 -165
  30. package/src/sequencer/process_tick.js +0 -104
  31. package/src/sequencer/sequencer_engine.js +0 -372
  32. package/src/sequencer/song_control.js +0 -196
  33. package/src/soundfont/README.md +0 -11
  34. package/src/soundfont/basic_soundfont/basic_global_zone.js +0 -6
  35. package/src/soundfont/basic_soundfont/basic_instrument.js +0 -115
  36. package/src/soundfont/basic_soundfont/basic_instrument_zone.js +0 -45
  37. package/src/soundfont/basic_soundfont/basic_preset.js +0 -313
  38. package/src/soundfont/basic_soundfont/basic_preset_zone.js +0 -39
  39. package/src/soundfont/basic_soundfont/basic_sample.js +0 -477
  40. package/src/soundfont/basic_soundfont/basic_soundbank.js +0 -740
  41. package/src/soundfont/basic_soundfont/basic_zone.js +0 -145
  42. package/src/soundfont/basic_soundfont/generator.js +0 -76
  43. package/src/soundfont/basic_soundfont/generator_types.js +0 -151
  44. package/src/soundfont/basic_soundfont/modulator.js +0 -581
  45. package/src/soundfont/basic_soundfont/riff_chunk.js +0 -195
  46. package/src/soundfont/basic_soundfont/write_dls/art2.js +0 -174
  47. package/src/soundfont/basic_soundfont/write_dls/articulator.js +0 -49
  48. package/src/soundfont/basic_soundfont/write_dls/combine_zones.js +0 -374
  49. package/src/soundfont/basic_soundfont/write_dls/ins.js +0 -85
  50. package/src/soundfont/basic_soundfont/write_dls/lins.js +0 -15
  51. package/src/soundfont/basic_soundfont/write_dls/modulator_converter.js +0 -330
  52. package/src/soundfont/basic_soundfont/write_dls/rgn2.js +0 -120
  53. package/src/soundfont/basic_soundfont/write_dls/wave.js +0 -71
  54. package/src/soundfont/basic_soundfont/write_dls/write_dls.js +0 -124
  55. package/src/soundfont/basic_soundfont/write_dls/wsmp.js +0 -78
  56. package/src/soundfont/basic_soundfont/write_dls/wvpl.js +0 -35
  57. package/src/soundfont/basic_soundfont/write_sf2/ibag.js +0 -60
  58. package/src/soundfont/basic_soundfont/write_sf2/igen.js +0 -91
  59. package/src/soundfont/basic_soundfont/write_sf2/imod.js +0 -62
  60. package/src/soundfont/basic_soundfont/write_sf2/inst.js +0 -42
  61. package/src/soundfont/basic_soundfont/write_sf2/pbag.js +0 -57
  62. package/src/soundfont/basic_soundfont/write_sf2/pgen.js +0 -92
  63. package/src/soundfont/basic_soundfont/write_sf2/phdr.js +0 -61
  64. package/src/soundfont/basic_soundfont/write_sf2/pmod.js +0 -62
  65. package/src/soundfont/basic_soundfont/write_sf2/sdta.js +0 -131
  66. package/src/soundfont/basic_soundfont/write_sf2/shdr.js +0 -77
  67. package/src/soundfont/basic_soundfont/write_sf2/write.js +0 -287
  68. package/src/soundfont/dls/articulator_converter.js +0 -402
  69. package/src/soundfont/dls/dls_destinations.js +0 -38
  70. package/src/soundfont/dls/dls_instrument.js +0 -20
  71. package/src/soundfont/dls/dls_preset.js +0 -43
  72. package/src/soundfont/dls/dls_sample.js +0 -238
  73. package/src/soundfont/dls/dls_soundfont.js +0 -183
  74. package/src/soundfont/dls/dls_sources.js +0 -63
  75. package/src/soundfont/dls/dls_zone.js +0 -89
  76. package/src/soundfont/dls/read_articulation.js +0 -300
  77. package/src/soundfont/dls/read_instrument.js +0 -118
  78. package/src/soundfont/dls/read_instrument_list.js +0 -17
  79. package/src/soundfont/dls/read_lart.js +0 -35
  80. package/src/soundfont/dls/read_region.js +0 -157
  81. package/src/soundfont/dls/read_samples.js +0 -154
  82. package/src/soundfont/load_soundfont.js +0 -21
  83. package/src/soundfont/read_sf2/generators.js +0 -43
  84. package/src/soundfont/read_sf2/instrument_zones.js +0 -75
  85. package/src/soundfont/read_sf2/instruments.js +0 -71
  86. package/src/soundfont/read_sf2/modulators.js +0 -25
  87. package/src/soundfont/read_sf2/preset_zones.js +0 -79
  88. package/src/soundfont/read_sf2/presets.js +0 -80
  89. package/src/soundfont/read_sf2/samples.js +0 -317
  90. package/src/soundfont/read_sf2/soundfont.js +0 -452
  91. package/src/soundfont/read_sf2/zones.js +0 -28
  92. package/src/synthetizer/README.md +0 -7
  93. package/src/synthetizer/audio_engine/README.md +0 -9
  94. package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +0 -289
  95. package/src/synthetizer/audio_engine/engine_components/controller_tables.js +0 -90
  96. package/src/synthetizer/audio_engine/engine_components/dynamic_modulator_system.js +0 -95
  97. package/src/synthetizer/audio_engine/engine_components/enums.js +0 -18
  98. package/src/synthetizer/audio_engine/engine_components/key_modifier_manager.js +0 -151
  99. package/src/synthetizer/audio_engine/engine_components/lfo.js +0 -26
  100. package/src/synthetizer/audio_engine/engine_components/lowpass_filter.js +0 -282
  101. package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +0 -551
  102. package/src/synthetizer/audio_engine/engine_components/modulation_envelope.js +0 -181
  103. package/src/synthetizer/audio_engine/engine_components/modulator_curves.js +0 -89
  104. package/src/synthetizer/audio_engine/engine_components/soundfont_manager.js +0 -265
  105. package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +0 -124
  106. package/src/synthetizer/audio_engine/engine_components/unit_converter.js +0 -73
  107. package/src/synthetizer/audio_engine/engine_components/voice.js +0 -525
  108. package/src/synthetizer/audio_engine/engine_components/volume_envelope.js +0 -402
  109. package/src/synthetizer/audio_engine/engine_components/wavetable_oscillator.js +0 -274
  110. package/src/synthetizer/audio_engine/engine_methods/controller_control/controller_change.js +0 -159
  111. package/src/synthetizer/audio_engine/engine_methods/controller_control/master_parameters.js +0 -48
  112. package/src/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +0 -254
  113. package/src/synthetizer/audio_engine/engine_methods/create_midi_channel.js +0 -20
  114. package/src/synthetizer/audio_engine/engine_methods/data_entry/awe32.js +0 -198
  115. package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +0 -281
  116. package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_fine.js +0 -109
  117. package/src/synthetizer/audio_engine/engine_methods/mute_channel.js +0 -17
  118. package/src/synthetizer/audio_engine/engine_methods/note_on.js +0 -214
  119. package/src/synthetizer/audio_engine/engine_methods/portamento_time.js +0 -92
  120. package/src/synthetizer/audio_engine/engine_methods/program_change.js +0 -35
  121. package/src/synthetizer/audio_engine/engine_methods/render_voice.js +0 -214
  122. package/src/synthetizer/audio_engine/engine_methods/soundfont_management/embedded_sound_bank.js +0 -42
  123. package/src/synthetizer/audio_engine/engine_methods/soundfont_management/get_preset.js +0 -0
  124. package/src/synthetizer/audio_engine/engine_methods/soundfont_management/update_preset_list.js +0 -19
  125. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +0 -23
  126. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/note_off.js +0 -56
  127. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_channels.js +0 -16
  128. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_notes.js +0 -30
  129. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/voice_killing.js +0 -63
  130. package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +0 -1058
  131. package/src/synthetizer/audio_engine/engine_methods/tuning_control/channel_pressure.js +0 -23
  132. package/src/synthetizer/audio_engine/engine_methods/tuning_control/pitch_wheel.js +0 -31
  133. package/src/synthetizer/audio_engine/engine_methods/tuning_control/poly_pressure.js +0 -29
  134. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_master_tuning.js +0 -15
  135. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_modulation_depth.js +0 -27
  136. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_octave_tuning.js +0 -19
  137. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_tuning.js +0 -27
  138. package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_all_channels.js +0 -15
  139. package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_channel.js +0 -34
  140. package/src/synthetizer/audio_engine/main_processor.js +0 -813
  141. package/src/synthetizer/audio_engine/snapshot/apply_synthesizer_snapshot.js +0 -16
  142. package/src/synthetizer/audio_engine/snapshot/channel_snapshot.js +0 -175
  143. package/src/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js +0 -116
  144. package/src/synthetizer/audio_engine/synth_processor_options.js +0 -18
  145. package/src/synthetizer/synth_constants.js +0 -26
  146. package/src/utils/README.md +0 -8
  147. package/src/utils/buffer_to_wav.js +0 -197
  148. package/src/utils/byte_functions/big_endian.js +0 -32
  149. package/src/utils/byte_functions/little_endian.js +0 -77
  150. package/src/utils/byte_functions/string.js +0 -92
  151. package/src/utils/byte_functions/variable_length_quantity.js +0 -42
  152. package/src/utils/fill_with_defaults.js +0 -21
  153. package/src/utils/indexed_array.js +0 -34
  154. package/src/utils/loggin.js +0 -71
  155. package/src/utils/other.js +0 -92
  156. package/src/utils/sysex_detector.js +0 -58
  157. package/src/utils/xg_hacks.js +0 -193
@@ -1,1058 +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 "../../synth_constants.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
- import { synthDisplayTypes } from "../engine_components/enums.js";
9
- import { customControllers, NON_CC_INDEX_OFFSET } from "../engine_components/controller_tables.js";
10
- import { modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
11
-
12
- import { generatorTypes } from "../../../soundfont/basic_soundfont/generator_types.js";
13
-
14
- /**
15
- * KeyNum: tuning
16
- * @typedef {MTSNoteTuning[]} MTSProgramTuning
17
- */
18
-
19
- /**
20
- * @typedef {Object} MTSNoteTuning
21
- * @property {number} midiNote - the base midi note to use, -1 means no change
22
- * @property {number} centTuning - additional tuning
23
- */
24
-
25
- /**
26
- * Calculates freqency for MIDI Tuning Standard
27
- * @param byte1 {number}
28
- * @param byte2 {number}
29
- * @param byte3 {number}
30
- * @return {{midiNote: number, centTuning: number|null}}
31
- */
32
- function getTuning(byte1, byte2, byte3)
33
- {
34
- const midiNote = byte1;
35
- const fraction = (byte2 << 7) | byte3; // Combine byte2 and byte3 into a 14-bit number
36
-
37
- // no change
38
- if (byte1 === 0x7F && byte2 === 0x7F && byte3 === 0x7F)
39
- {
40
- return { midiNote: -1, centTuning: null };
41
- }
42
-
43
- // calculate cent tuning
44
- return { midiNote: midiNote, centTuning: fraction * 0.0061 };
45
- }
46
-
47
- /**
48
- * Executes a system exclusive
49
- * @param syx {number[]|IndexedByteArray} - the message data without f0
50
- * @param channelOffset {number}
51
- * @this {SpessaSynthProcessor}
52
- */
53
- export function systemExclusive(syx, channelOffset = 0)
54
- {
55
- const type = syx[0];
56
- if (this.deviceID !== ALL_CHANNELS_OR_DIFFERENT_ACTION && syx[1] !== 0x7F)
57
- {
58
- if (this.deviceID !== syx[1])
59
- {
60
- // not our device ID
61
- return;
62
- }
63
- }
64
-
65
- function niceLogging(channel, value, what, units)
66
- {
67
- SpessaSynthInfo(
68
- `%cChannel %c${channel}%c ${what}. %c${value} ${units}%c, with %c${arrayToHexString(syx)}`,
69
- consoleColors.info,
70
- consoleColors.recognized,
71
- consoleColors.info,
72
- consoleColors.value,
73
- consoleColors.info,
74
- consoleColors.value
75
- );
76
- }
77
-
78
- function notRecognized()
79
- {
80
- // this is some other GS sysex...
81
- SpessaSynthWarn(
82
- `%cUnrecognized Roland %cGS %cSysEx: %c${arrayToHexString(syx)}`,
83
- consoleColors.warn,
84
- consoleColors.recognized,
85
- consoleColors.warn,
86
- consoleColors.unrecognized
87
- );
88
- }
89
-
90
- switch (type)
91
- {
92
- default:
93
- SpessaSynthWarn(
94
- `%cUnrecognized SysEx: %c${arrayToHexString(syx)}`,
95
- consoleColors.warn,
96
- consoleColors.unrecognized
97
- );
98
- break;
99
-
100
- // non realtime
101
- case 0x7E:
102
- case 0x7F:
103
- switch (syx[2])
104
- {
105
- case 0x04:
106
- let cents;
107
- // device control
108
- switch (syx[3])
109
- {
110
- case 0x01:
111
- // main volume
112
- const vol = syx[5] << 7 | syx[4];
113
- this.setMIDIVolume(vol / 16384);
114
- SpessaSynthInfo(
115
- `%cMaster Volume. Volume: %c${vol}`,
116
- consoleColors.info,
117
- consoleColors.value
118
- );
119
- break;
120
-
121
- case 0x02:
122
- // main balance
123
- // midi spec page 62
124
- const balance = syx[5] << 7 | syx[4];
125
- const pan = (balance - 8192) / 8192;
126
- this.setMasterParameter(masterParameterType.masterPan, pan);
127
- SpessaSynthInfo(
128
- `%cMaster Pan. Pan: %c${pan}`,
129
- consoleColors.info,
130
- consoleColors.value
131
- );
132
- break;
133
-
134
-
135
- case 0x03:
136
- // fine-tuning
137
- const tuningValue = ((syx[5] << 7) | syx[6]) - 8192;
138
- cents = Math.floor(tuningValue / 81.92); // [-100;+99] cents range
139
- this.setMasterTuning(cents);
140
- SpessaSynthInfo(
141
- `%cMaster Fine Tuning. Cents: %c${cents}`,
142
- consoleColors.info,
143
- consoleColors.value
144
- );
145
- break;
146
-
147
- case 0x04:
148
- // coarse tuning
149
- // lsb is ignored
150
- const semitones = syx[5] - 64;
151
- cents = semitones * 100;
152
- this.setMasterTuning(cents);
153
- SpessaSynthInfo(
154
- `%cMaster Coarse Tuning. Cents: %c${cents}`,
155
- consoleColors.info,
156
- consoleColors.value
157
- );
158
- break;
159
-
160
- default:
161
- SpessaSynthWarn(
162
- `%cUnrecognized MIDI Device Control Real-time message: %c${arrayToHexString(syx)}`,
163
- consoleColors.warn,
164
- consoleColors.unrecognized
165
- );
166
- }
167
- break;
168
-
169
- case 0x09:
170
- // gm system related
171
- if (syx[3] === 0x01)
172
- {
173
- SpessaSynthInfo("%cGM1 system on", consoleColors.info);
174
- this.setSystem("gm");
175
- }
176
- else if (syx[3] === 0x03)
177
- {
178
- SpessaSynthInfo("%cGM2 system on", consoleColors.info);
179
- this.setSystem("gm2");
180
- }
181
- else
182
- {
183
- SpessaSynthInfo("%cGM system off, defaulting to GS", consoleColors.info);
184
- this.setSystem("gs");
185
- }
186
- break;
187
-
188
- // MIDI Tuning standard
189
- // https://midi.org/midi-tuning-updated-specification
190
- case 0x08:
191
- let currentMessageIndex = 4;
192
- switch (syx[3])
193
- {
194
- // bulk tuning dump: all 128 notes
195
- case 0x01:
196
- const program = syx[currentMessageIndex++];
197
- // read the name
198
- syx.currentIndex = currentMessageIndex;
199
- const tuningName = readBytesAsString(syx, 16);
200
- currentMessageIndex += 16;
201
- if (syx.length < 384)
202
- {
203
- SpessaSynthWarn(`The Bulk Tuning Dump is too short! (${syx.length} bytes, at least 384 are expected)`);
204
- return;
205
- }
206
- // 128 frequencies follow
207
- for (let i = 0; i < 128; i++)
208
- {
209
- // set the given tuning to the program
210
- this.tunings[program][i] = getTuning(
211
- syx[currentMessageIndex++],
212
- syx[currentMessageIndex++],
213
- syx[currentMessageIndex++]
214
- );
215
- }
216
- SpessaSynthInfo(
217
- `%cBulk Tuning Dump %c${tuningName}%c Program: %c${program}`,
218
- consoleColors.info,
219
- consoleColors.value,
220
- consoleColors.info,
221
- consoleColors.recognized
222
- );
223
- break;
224
-
225
- // single note change
226
- // single note change bank
227
- case 0x02:
228
- case 0x07:
229
- if (syx[3] === 0x07)
230
- {
231
- // skip the bank
232
- currentMessageIndex++;
233
- }
234
- // get program and number of changes
235
- const tuningProgram = syx[currentMessageIndex++];
236
- const numberOfChanges = syx[currentMessageIndex++];
237
- for (let i = 0; i < numberOfChanges; i++)
238
- {
239
- // set the given tuning to the program
240
- this.tunings[tuningProgram][syx[currentMessageIndex++]] = getTuning(
241
- syx[currentMessageIndex++],
242
- syx[currentMessageIndex++],
243
- syx[currentMessageIndex++]
244
- );
245
- }
246
- SpessaSynthInfo(
247
- `%cSingle Note Tuning. Program: %c${tuningProgram}%c Keys affected: %c${numberOfChanges}`,
248
- consoleColors.info,
249
- consoleColors.recognized,
250
- consoleColors.info,
251
- consoleColors.recognized
252
- );
253
- break;
254
-
255
- // octave tuning (1 byte)
256
- // and octave tuning (2 bytes)
257
- case 0x09:
258
- case 0x08:
259
- // get tuning:
260
- const newOctaveTuning = new Int8Array(12);
261
- // start from bit 7
262
- if (syx[3] === 0x08)
263
- {
264
- // 1 byte tuning: 0 is -64 cents, 64 is 0, 127 is +63
265
- for (let i = 0; i < 12; i++)
266
- {
267
- newOctaveTuning[i] = syx[7 + i] - 64;
268
- }
269
- }
270
- else
271
- {
272
- // 2 byte tuning. Like fine tune: 0 is -100 cents, 8192 is 0 cents, 16,383 is +100 cents
273
- for (let i = 0; i < 24; i += 2)
274
- {
275
- const tuning = ((syx[7 + i] << 7) | syx[8 + i]) - 8192;
276
- newOctaveTuning[i / 2] = Math.floor(tuning / 81.92); // map to [-100;+99] cents
277
- }
278
- }
279
- // apply to channels (ordered from 0)
280
- // bit 1: 14 and 15
281
- if ((syx[4] & 1) === 1)
282
- {
283
- this.midiAudioChannels[14 + channelOffset].setOctaveTuning(newOctaveTuning);
284
- }
285
- if (((syx[4] >> 1) & 1) === 1)
286
- {
287
- this.midiAudioChannels[15 + channelOffset].setOctaveTuning(newOctaveTuning);
288
- }
289
-
290
- // bit 2: channels 7 to 13
291
- for (let i = 0; i < 7; i++)
292
- {
293
- const bit = (syx[5] >> i) & 1;
294
- if (bit === 1)
295
- {
296
- this.midiAudioChannels[7 + i + channelOffset].setOctaveTuning(newOctaveTuning);
297
- }
298
- }
299
-
300
- // bit 3: channels 0 to 16
301
- for (let i = 0; i < 7; i++)
302
- {
303
- const bit = (syx[6] >> i) & 1;
304
- if (bit === 1)
305
- {
306
- this.midiAudioChannels[i + channelOffset].setOctaveTuning(newOctaveTuning);
307
- }
308
- }
309
-
310
- SpessaSynthInfo(
311
- `%cMIDI Octave Scale ${
312
- syx[3] === 0x08 ? "(1 byte)" : "(2 bytes)"
313
- } tuning via Tuning: %c${newOctaveTuning.join(" ")}`,
314
- consoleColors.info,
315
- consoleColors.value
316
- );
317
- break;
318
-
319
- default:
320
- SpessaSynthWarn(
321
- `%cUnrecognized MIDI Tuning standard message: %c${arrayToHexString(syx)}`,
322
- consoleColors.warn,
323
- consoleColors.unrecognized
324
- );
325
- break;
326
- }
327
- break;
328
-
329
- default:
330
- SpessaSynthWarn(
331
- `%cUnrecognized MIDI Realtime/non realtime message: %c${arrayToHexString(syx)}`,
332
- consoleColors.warn,
333
- consoleColors.unrecognized
334
- );
335
-
336
- }
337
- break;
338
-
339
- // this is a roland sysex
340
- // http://www.bandtrax.com.au/sysex.htm
341
- // https://cdn.roland.com/assets/media/pdf/AT-20R_30R_MI.pdf
342
- case 0x41:
343
- if (syx[2] === 0x42 && syx[3] === 0x12)
344
- {
345
- // this is a GS sysex
346
- const messageValue = syx[7];
347
- // syx[5] and [6] is the system parameter, syx[7] is the value
348
- // either patch common or SC-88 mode set
349
- if (syx[4] === 0x40 || (syx[4] === 0x00 && syx[6] === 0x7F))
350
- {
351
- // this is a channel parameter
352
- if ((syx[5] & 0x10) > 0)
353
- {
354
- // this is an individual part (channel) parameter
355
- // determine the channel 0 means channel 10 (default), 1 means 1 etc.
356
- // SC88 manual page 196
357
- const channel = [9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15][syx[5] & 0x0F] + channelOffset;
358
- // for example, 0x1A means A = 11, which corresponds to channel 12 (counting from 1)
359
- const channelObject = this.midiAudioChannels[channel];
360
- switch (syx[6])
361
- {
362
- default:
363
- // this is some other GS sysex...
364
- notRecognized();
365
- break;
366
-
367
- case 0x15:
368
- // this is the Use for Drum Part sysex (multiple drums)
369
- const isDrums = messageValue > 0 && syx[5] >> 4; // if set to other than 0, is a drum channel
370
- channelObject.setDrums(isDrums);
371
- SpessaSynthInfo(
372
- `%cChannel %c${channel}%c ${isDrums ?
373
- "is now a drum channel"
374
- :
375
- "now isn't a drum channel"
376
- }%c via: %c${arrayToHexString(syx)}`,
377
- consoleColors.info,
378
- consoleColors.value,
379
- consoleColors.recognized,
380
- consoleColors.info,
381
- consoleColors.value
382
- );
383
- return;
384
-
385
- case 0x16:
386
- // this is the pitch key shift sysex
387
- const keyShift = messageValue - 64;
388
- channelObject.setCustomController(customControllers.channelKeyShift, keyShift);
389
- niceLogging(channel, keyShift, "key shift", "keys");
390
- return;
391
-
392
- // pan position
393
- case 0x1C:
394
- // 0 is random
395
- let panpot = messageValue;
396
- if (panpot === 0)
397
- {
398
- channelObject.randomPan = true;
399
- SpessaSynthInfo(
400
- `%cRandom pan is set to %cON%c for %c${channel}`,
401
- consoleColors.info,
402
- consoleColors.recognized,
403
- consoleColors.info,
404
- consoleColors.value
405
- );
406
- }
407
- else
408
- {
409
- channelObject.randomPan = false;
410
- channelObject.controllerChange(midiControllers.pan, panpot);
411
- }
412
- break;
413
-
414
- // chorus send
415
- case 0x21:
416
- channelObject.controllerChange(midiControllers.chorusDepth, messageValue);
417
- break;
418
-
419
- // reverb send
420
- case 0x22:
421
- channelObject.controllerChange(midiControllers.reverbDepth, messageValue);
422
- break;
423
-
424
- case 0x40:
425
- case 0x41:
426
- case 0x42:
427
- case 0x43:
428
- case 0x44:
429
- case 0x45:
430
- case 0x46:
431
- case 0x47:
432
- case 0x48:
433
- case 0x49:
434
- case 0x4A:
435
- case 0x4B:
436
- // scale tuning: up to 12 bytes
437
- const tuningBytes = syx.length - 9; // data starts at 7, minus checksum and f7
438
- // read em bytes
439
- const newTuning = new Int8Array(12);
440
- for (let i = 0; i < tuningBytes; i++)
441
- {
442
- newTuning[i] = syx[i + 7] - 64;
443
- }
444
- channelObject.setOctaveTuning(newTuning);
445
- const cents = messageValue - 64;
446
- niceLogging(channel, newTuning.join(" "), "octave scale tuning", "cents");
447
- channelObject.setTuning(cents);
448
- break;
449
- }
450
- return;
451
- }
452
- else
453
- // this is a channel parameter also
454
- if ((syx[5] & 0x20) > 0)
455
- {
456
- // this is an individual part (channel) parameter
457
- // determine the channel 0 means channel 10 (default), 1 means 1 etc.
458
- const channel = [9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15][syx[5] & 0x0F] + channelOffset;
459
- // for example, 0x1A means A = 11, which corresponds to channel 12 (counting from 1)
460
- const channelObject = this.midiAudioChannels[channel];
461
- const centeredValue = (messageValue - 64);
462
- const normalizedValue = centeredValue / 64;
463
- const normalizedNotCentered = messageValue / 128;
464
-
465
- // setup receivers for cc to parameter (sc-88 manual page 198)
466
- const setupReceivers = (source, sourceName, bipolar = false) =>
467
- {
468
- switch (syx[6] & 0x0F)
469
- {
470
- case 0x00:
471
- // see https://github.com/spessasus/SpessaSynth/issues/154
472
- // pitch control
473
- // special case:
474
- // if the source is a pitch wheel, it's a strange way of setting the bend range
475
- // testcase: th07_03.mid
476
- if (source === NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel)
477
- {
478
- channelObject.controllerChange(midiControllers.RPNMsb, 0x0);
479
- channelObject.controllerChange(midiControllers.RPNLsb, 0x0);
480
- channelObject.controllerChange(
481
- midiControllers.dataEntryMsb,
482
- Math.floor(centeredValue)
483
- );
484
- }
485
- else
486
- {
487
- channelObject.sysExModulators.setModulator(
488
- source,
489
- generatorTypes.fineTune,
490
- centeredValue * 100,
491
- bipolar
492
- );
493
- niceLogging(channel, centeredValue, `${sourceName} pitch control`, "semitones");
494
- }
495
- break;
496
-
497
- case 0x01:
498
- // cutoff
499
- channelObject.sysExModulators.setModulator(
500
- source,
501
- generatorTypes.initialFilterFc,
502
- normalizedValue * 9600,
503
- bipolar
504
- );
505
- niceLogging(
506
- channel,
507
- normalizedValue * 9600,
508
- `${sourceName} pitch control`,
509
- "cents"
510
- );
511
- break;
512
-
513
- case 0x02:
514
- // amplitude
515
- channelObject.sysExModulators.setModulator(
516
- source,
517
- generatorTypes.initialAttenuation,
518
- normalizedValue * 960, // spec says "100%" so 960cB in sf2
519
- bipolar
520
- );
521
- niceLogging(channel, normalizedValue * 960, `${sourceName} amplitude`, "cB");
522
- break;
523
-
524
- // rate control is ignored as it is in hertz
525
-
526
- case 0x04:
527
- // LFO1 pitch depth
528
- channelObject.sysExModulators.setModulator(
529
- source,
530
- generatorTypes.vibLfoToPitch,
531
- normalizedNotCentered * 600,
532
- bipolar
533
- );
534
- niceLogging(
535
- channel,
536
- normalizedNotCentered * 600,
537
- `${sourceName} LFO1 pitch depth`,
538
- "cents"
539
- );
540
- break;
541
-
542
- case 0x05:
543
- // LFO1 filter depth
544
- channelObject.sysExModulators.setModulator(
545
- source,
546
- generatorTypes.vibLfoToFilterFc,
547
- normalizedNotCentered * 2400,
548
- bipolar
549
- );
550
- niceLogging(
551
- channel,
552
- normalizedNotCentered * 2400,
553
- `${sourceName} LFO1 filter depth`,
554
- "cents"
555
- );
556
- break;
557
-
558
- case 0x06:
559
- // LFO1 amplitude depth
560
- channelObject.sysExModulators.setModulator(
561
- source,
562
- generatorTypes.vibLfoToVolume,
563
- normalizedValue * 960,
564
- bipolar
565
- );
566
- niceLogging(
567
- channel,
568
- normalizedValue * 960,
569
- `${sourceName} LFO1 amplitude depth`,
570
- "cB"
571
- );
572
- break;
573
-
574
- // rate control is ignored as it is in hertz
575
-
576
- case 0x08:
577
- // LFO2 pitch depth
578
- channelObject.sysExModulators.setModulator(
579
- source,
580
- generatorTypes.modLfoToPitch,
581
- normalizedNotCentered * 600,
582
- bipolar
583
- );
584
- niceLogging(
585
- channel,
586
- normalizedNotCentered * 600,
587
- `${sourceName} LFO2 pitch depth`,
588
- "cents"
589
- );
590
- break;
591
-
592
- case 0x09:
593
- // LFO2 filter depth
594
- channelObject.sysExModulators.setModulator(
595
- source,
596
- generatorTypes.modLfoToFilterFc,
597
- normalizedNotCentered * 2400,
598
- bipolar
599
- );
600
- niceLogging(
601
- channel,
602
- normalizedNotCentered * 2400,
603
- `${sourceName} LFO2 filter depth`,
604
- "cents"
605
- );
606
- break;
607
-
608
- case 0x0A:
609
- // LFO2 amplitude depth
610
- channelObject.sysExModulators.setModulator(
611
- source,
612
- generatorTypes.modLfoToVolume,
613
- normalizedValue * 960,
614
- bipolar
615
- );
616
- niceLogging(
617
- channel,
618
- normalizedValue * 960,
619
- `${sourceName} LFO2 amplitude depth`,
620
- "cB"
621
- );
622
- break;
623
- }
624
- };
625
-
626
- // SC88 manual page 198
627
- switch (syx[6] & 0xF0)
628
- {
629
- default:
630
- // this is some other GS sysex...
631
- notRecognized();
632
- break;
633
-
634
- case 0x00:
635
- // modulation wheel
636
- setupReceivers(midiControllers.modulationWheel, "mod wheel");
637
- break;
638
-
639
- case 0x10:
640
- // pitch bend
641
- setupReceivers(NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel, "pitch bend", true);
642
- break;
643
-
644
- case 0x20:
645
- // channel pressure
646
- setupReceivers(
647
- NON_CC_INDEX_OFFSET + modulatorSources.channelPressure,
648
- "channel pressure"
649
- );
650
- break;
651
-
652
- case 0x30:
653
- // poly pressure
654
- setupReceivers(
655
- NON_CC_INDEX_OFFSET + modulatorSources.polyPressure,
656
- "poly pressure"
657
- );
658
- break;
659
- }
660
- return;
661
- }
662
- else
663
- // this is a global system parameter
664
- if (syx[5] === 0x00)
665
- {
666
- switch (syx[6])
667
- {
668
- default:
669
- notRecognized();
670
- break;
671
-
672
- case 0x7F:
673
- // roland mode set
674
- // GS mode set
675
- if (messageValue === 0x00)
676
- {
677
- // this is a GS reset
678
- SpessaSynthInfo("%cGS Reset received!", consoleColors.info);
679
- this.resetAllControllers(false);
680
- this.setSystem("gs");
681
- }
682
- else if (messageValue === 0x7F)
683
- {
684
- // GS mode off
685
- SpessaSynthInfo("%cGS system off, switching to GM2", consoleColors.info);
686
- this.resetAllControllers(false);
687
- this.setSystem("gm2");
688
- }
689
- break;
690
-
691
- case 0x06:
692
- // roland master pan
693
- SpessaSynthInfo(
694
- `%cRoland GS Master Pan set to: %c${messageValue}%c with: %c${arrayToHexString(
695
- syx)}`,
696
- consoleColors.info,
697
- consoleColors.value,
698
- consoleColors.info,
699
- consoleColors.value
700
- );
701
- this.setMasterParameter(masterParameterType.masterPan, (messageValue - 64) / 64);
702
- break;
703
-
704
-
705
- case 0x04:
706
- // roland GS master volume
707
- SpessaSynthInfo(
708
- `%cRoland GS Master Volume set to: %c${messageValue}%c with: %c${arrayToHexString(
709
- syx)}`,
710
- consoleColors.info,
711
- consoleColors.value,
712
- consoleColors.info,
713
- consoleColors.value
714
- );
715
- this.setMIDIVolume(messageValue / 127);
716
- break;
717
-
718
- case 0x05:
719
- // roland master key shift (transpose)
720
- const transpose = messageValue - 64;
721
- SpessaSynthInfo(
722
- `%cRoland GS Master Key-Shift set to: %c${transpose}%c with: %c${arrayToHexString(
723
- syx)}`,
724
- consoleColors.info,
725
- consoleColors.value,
726
- consoleColors.info,
727
- consoleColors.value
728
- );
729
- this.setMasterTuning(transpose * 100);
730
- break;
731
- }
732
- return;
733
- }
734
- else
735
- // this is a global system parameter also
736
- if (syx[5] === 0x01)
737
- {
738
- switch (syx[6])
739
- {
740
- default:
741
- notRecognized();
742
- break;
743
-
744
- case 0x00:
745
- // patch name. cool!
746
- syx.currentIndex = 7;
747
- const patchName = readBytesAsString(syx, 16);
748
- SpessaSynthInfo(
749
- `%cGS Patch name: %c${patchName}`,
750
- consoleColors.info,
751
- consoleColors.value
752
- );
753
- break;
754
-
755
- case 0x33:
756
- // reverb level
757
- SpessaSynthInfo(
758
- `%cGS Reverb level: %c${messageValue}`,
759
- consoleColors.info, consoleColors.value
760
- );
761
- // 64 is the default
762
- this.reverbSend = messageValue / 64;
763
- break;
764
-
765
- // unsupported reverb params
766
- case 0x30:
767
- case 0x31:
768
- case 0x32:
769
- case 0x34:
770
- case 0x35:
771
- case 0x37:
772
- SpessaSynthInfo(
773
- `%cUnsupported GS Reverb Parameter: %c${syx[6].toString(16)}`,
774
- consoleColors.warn, consoleColors.unrecognized
775
- );
776
- break;
777
-
778
- case 0x3A:
779
- // chorus level
780
- SpessaSynthInfo(
781
- `%cGS Chorus level: %c${messageValue}`,
782
- consoleColors.info, consoleColors.value
783
- );
784
- // 64 is the default
785
- this.chorusSend = messageValue / 64;
786
- break;
787
-
788
- // unsupported chorus params
789
- case 0x38:
790
- case 0x39:
791
- case 0x3B:
792
- case 0x3C:
793
- case 0x3D:
794
- case 0x3E:
795
- case 0x3F:
796
- case 0x40:
797
- SpessaSynthInfo(
798
- `%cUnsupported GS Chorus Parameter: %c${syx[6].toString(16)}`,
799
- consoleColors.warn, consoleColors.unrecognized
800
- );
801
- break;
802
- }
803
- }
804
- }
805
- else
806
- {
807
- // this is some other GS sysex...
808
- notRecognized();
809
- }
810
- return;
811
- }
812
- else if (syx[2] === 0x45 && syx[3] === 0x12)
813
- {
814
- // 0x45: GS Display Data, 0x12: DT1 (Device Transmit)
815
- // check for embedded copyright
816
- // (roland SC display sysex) http://www.bandtrax.com.au/sysex.htm
817
-
818
- if (
819
- syx[4] === 0x10 && // Sound Canvas Display
820
- syx[6] === 0x00 // Data follows
821
- )
822
- {
823
- if (syx[5] === 0x00) // Display letters
824
- {
825
- // get the text
826
- // and header ends with (checksum) F7
827
- const text = new Uint8Array(syx.slice(7, syx.length - 2));
828
- this.callEvent(
829
- "synthdisplay",
830
- {
831
- displayData: text,
832
- displayType: synthDisplayTypes.SoundCanvasText
833
- }
834
- );
835
- }
836
- else if (syx[5] === 0x01) // Matrix display
837
- {
838
- // get the data
839
- // and header ends with (checksum) F7
840
- const dotMatrixData = new Uint8Array(syx.slice(7, syx.length - 3));
841
- this.callEvent(
842
- "synthdisplay",
843
- {
844
- displayData: dotMatrixData,
845
- displayType: synthDisplayTypes.SoundCanvasDotDisplay
846
- }
847
- );
848
- SpessaSynthInfo(
849
- `%cRoland SC Display Dot Matrix via: %c${arrayToHexString(
850
- syx)}`,
851
- consoleColors.info,
852
- consoleColors.value
853
- );
854
- }
855
- else
856
- {
857
- // this is some other GS sysex...
858
- notRecognized();
859
- }
860
- }
861
- }
862
- else if (syx[2] === 0x16 && syx[3] === 0x12 && syx[4] === 0x10)
863
- {
864
- // this is a roland master volume message
865
- this.setMIDIVolume(syx[7] / 100);
866
- SpessaSynthInfo(
867
- `%cRoland Master Volume control set to: %c${syx[7]}%c via: %c${arrayToHexString(
868
- syx)}`,
869
- consoleColors.info,
870
- consoleColors.value,
871
- consoleColors.info,
872
- consoleColors.value
873
- );
874
- return;
875
- }
876
- else
877
- {
878
- // this is something else...
879
- SpessaSynthWarn(
880
- `%cUnrecognized Roland SysEx: %c${arrayToHexString(syx)}`,
881
- consoleColors.warn,
882
- consoleColors.unrecognized
883
- );
884
- return;
885
- }
886
- break;
887
-
888
- // yamaha
889
- // http://www.studio4all.de/htmle/main91.html
890
- case 0x43:
891
- // XG sysex
892
- if (syx[2] === 0x4C)
893
- {
894
- // XG system parameter
895
- if (syx[3] === 0x00 && syx[4] === 0x00)
896
- {
897
- switch (syx[5])
898
- {
899
- // master volume
900
- case 0x04:
901
- const vol = syx[6];
902
- this.setMIDIVolume(vol / 127);
903
- SpessaSynthInfo(
904
- `%cXG master volume. Volume: %c${vol}`,
905
- consoleColors.info,
906
- consoleColors.recognized
907
- );
908
- break;
909
-
910
- // master transpose
911
- case 0x06:
912
- const transpose = syx[6] - 64;
913
- this.transposeAllChannels(transpose);
914
- SpessaSynthInfo(
915
- `%cXG master transpose. Volume: %c${transpose}`,
916
- consoleColors.info,
917
- consoleColors.recognized
918
- );
919
- break;
920
-
921
- // XG on
922
- case 0x7E:
923
- SpessaSynthInfo("%cXG system on", consoleColors.info);
924
- this.resetAllControllers(false);
925
- this.setSystem("xg");
926
- break;
927
- }
928
- }
929
- else
930
- // XG part parameter
931
- if (syx[3] === 0x08)
932
- {
933
- if (!isSystemXG(this.system))
934
- {
935
- return;
936
- }
937
- const channel = syx[4] + channelOffset;
938
- if (channel >= this.midiAudioChannels.length)
939
- {
940
- // invalid channel
941
- return;
942
- }
943
- const channelObject = this.midiAudioChannels[channel];
944
- const value = syx[6];
945
- switch (syx[5])
946
- {
947
- // bank-select MSB
948
- case 0x01:
949
- channelObject.controllerChange(midiControllers.bankSelect, value);
950
- break;
951
-
952
- // bank-select LSB
953
- case 0x02:
954
- channelObject.controllerChange(midiControllers.lsbForControl0BankSelect, value);
955
- break;
956
-
957
- // program change
958
- case 0x03:
959
- channelObject.programChange(value);
960
- break;
961
-
962
- // note shift
963
- case 0x08:
964
- if (channelObject.drumChannel)
965
- {
966
- return;
967
- }
968
- const semitones = value - 64;
969
- channelObject.channelTransposeKeyShift = semitones;
970
- break;
971
-
972
- // volume
973
- case 0x0B:
974
- channelObject.controllerChange(midiControllers.mainVolume, value);
975
- break;
976
-
977
- // pan position
978
- case 0x0E:
979
- let pan = value;
980
- if (pan === 0)
981
- {
982
- // 0 means random
983
- channelObject.randomPan = true;
984
- SpessaSynthInfo(
985
- `%cRandom pan is set to %cON%c for %c${channel}`,
986
- consoleColors.info,
987
- consoleColors.recognized,
988
- consoleColors.info,
989
- consoleColors.value
990
- );
991
- }
992
- else
993
- {
994
- channelObject.controllerChange(midiControllers.pan, pan);
995
- }
996
- break;
997
-
998
- // reverb
999
- case 0x13:
1000
- channelObject.controllerChange(midiControllers.reverbDepth, value);
1001
- break;
1002
-
1003
- // chorus
1004
- case 0x12:
1005
- channelObject.controllerChange(midiControllers.chorusDepth, value);
1006
- break;
1007
-
1008
- default:
1009
- SpessaSynthWarn(
1010
- `%cUnrecognized Yamaha XG Part Setup: %c${syx[5].toString(16)
1011
- .toUpperCase()}`,
1012
- consoleColors.warn,
1013
- consoleColors.unrecognized
1014
- );
1015
- }
1016
- }
1017
- else if (
1018
- syx[3] === 0x06 && // XG System parameter
1019
- syx[4] === 0x00 // System Byte
1020
- )
1021
- {
1022
- // displayed letters (remove F7 at the end)
1023
- // include byte 5 as it seems to be line information (useful)
1024
- const textData = new Uint8Array(syx.slice(5, syx.length - 1));
1025
- this.callEvent(
1026
- "synthdisplay",
1027
- {
1028
- displayData: textData,
1029
- displayType: synthDisplayTypes.XGText
1030
- }
1031
- );
1032
- }
1033
- else if (isSystemXG(this.system))
1034
- {
1035
- SpessaSynthWarn(
1036
- `%cUnrecognized Yamaha XG SysEx: %c${arrayToHexString(syx)}`,
1037
- consoleColors.warn,
1038
- consoleColors.unrecognized
1039
- );
1040
- }
1041
-
1042
- }
1043
- else
1044
- {
1045
- if (isSystemXG(this.system))
1046
- {
1047
- SpessaSynthWarn(
1048
- `%cUnrecognized Yamaha SysEx: %c${arrayToHexString(syx)}`,
1049
- consoleColors.warn,
1050
- consoleColors.unrecognized
1051
- );
1052
- }
1053
- }
1054
- break;
1055
-
1056
-
1057
- }
1058
- }