spessasynth_core 1.1.3 → 1.1.5
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/LICENSE +3 -26
- package/README.md +156 -474
- package/index.js +74 -8
- package/package.json +21 -8
- package/src/externals/fflate/LICENSE +21 -0
- package/src/externals/fflate/fflate.min.js +1 -0
- package/src/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +12 -0
- package/src/externals/stbvorbis_sync/LICENSE +202 -0
- package/src/externals/stbvorbis_sync/NOTICE +6 -0
- package/src/externals/stbvorbis_sync/stbvorbis_sync.min.js +1 -0
- package/src/midi/README.md +32 -0
- package/src/midi/basic_midi.js +567 -0
- package/src/midi/midi_builder.js +202 -0
- package/src/midi/midi_loader.js +324 -0
- package/{spessasynth_core/midi_parser → src/midi}/midi_message.js +58 -35
- package/src/midi/midi_sequence.js +224 -0
- package/src/midi/midi_tools/get_note_times.js +154 -0
- package/src/midi/midi_tools/midi_editor.js +611 -0
- package/src/midi/midi_tools/midi_writer.js +99 -0
- package/src/midi/midi_tools/rmidi_writer.js +567 -0
- package/src/midi/midi_tools/used_keys_loaded.js +238 -0
- package/src/midi/xmf_loader.js +454 -0
- package/src/sequencer/README.md +5 -0
- package/src/sequencer/events.js +81 -0
- package/src/sequencer/play.js +349 -0
- package/src/sequencer/process_event.js +165 -0
- package/{spessasynth_core/sequencer/worklet_sequencer → src/sequencer}/process_tick.js +103 -84
- package/src/sequencer/sequencer_engine.js +367 -0
- package/src/sequencer/song_control.js +201 -0
- package/src/soundfont/README.md +13 -0
- package/src/soundfont/basic_soundfont/basic_instrument.js +77 -0
- package/src/soundfont/basic_soundfont/basic_preset.js +336 -0
- package/src/soundfont/basic_soundfont/basic_sample.js +206 -0
- package/src/soundfont/basic_soundfont/basic_soundfont.js +565 -0
- package/src/soundfont/basic_soundfont/basic_zone.js +64 -0
- package/src/soundfont/basic_soundfont/basic_zones.js +43 -0
- package/src/soundfont/basic_soundfont/generator.js +220 -0
- package/src/soundfont/basic_soundfont/modulator.js +378 -0
- package/src/soundfont/basic_soundfont/riff_chunk.js +149 -0
- package/src/soundfont/basic_soundfont/write_dls/art2.js +173 -0
- package/src/soundfont/basic_soundfont/write_dls/articulator.js +49 -0
- package/src/soundfont/basic_soundfont/write_dls/combine_zones.js +400 -0
- package/src/soundfont/basic_soundfont/write_dls/ins.js +103 -0
- package/src/soundfont/basic_soundfont/write_dls/lins.js +18 -0
- package/src/soundfont/basic_soundfont/write_dls/modulator_converter.js +330 -0
- package/src/soundfont/basic_soundfont/write_dls/rgn2.js +121 -0
- package/src/soundfont/basic_soundfont/write_dls/wave.js +94 -0
- package/src/soundfont/basic_soundfont/write_dls/write_dls.js +119 -0
- package/src/soundfont/basic_soundfont/write_dls/wsmp.js +78 -0
- package/src/soundfont/basic_soundfont/write_dls/wvpl.js +32 -0
- package/src/soundfont/basic_soundfont/write_sf2/ibag.js +39 -0
- package/src/soundfont/basic_soundfont/write_sf2/igen.js +80 -0
- package/src/soundfont/basic_soundfont/write_sf2/imod.js +46 -0
- package/src/soundfont/basic_soundfont/write_sf2/inst.js +34 -0
- package/src/soundfont/basic_soundfont/write_sf2/pbag.js +39 -0
- package/src/soundfont/basic_soundfont/write_sf2/pgen.js +82 -0
- package/src/soundfont/basic_soundfont/write_sf2/phdr.js +42 -0
- package/src/soundfont/basic_soundfont/write_sf2/pmod.js +46 -0
- package/src/soundfont/basic_soundfont/write_sf2/sdta.js +80 -0
- package/src/soundfont/basic_soundfont/write_sf2/shdr.js +55 -0
- package/src/soundfont/basic_soundfont/write_sf2/write.js +222 -0
- package/src/soundfont/dls/articulator_converter.js +396 -0
- package/src/soundfont/dls/dls_destinations.js +38 -0
- package/src/soundfont/dls/dls_preset.js +44 -0
- package/src/soundfont/dls/dls_sample.js +75 -0
- package/src/soundfont/dls/dls_soundfont.js +186 -0
- package/src/soundfont/dls/dls_sources.js +62 -0
- package/src/soundfont/dls/dls_zone.js +95 -0
- package/src/soundfont/dls/read_articulation.js +299 -0
- package/src/soundfont/dls/read_instrument.js +121 -0
- package/src/soundfont/dls/read_instrument_list.js +17 -0
- package/src/soundfont/dls/read_lart.js +35 -0
- package/src/soundfont/dls/read_region.js +152 -0
- package/src/soundfont/dls/read_samples.js +270 -0
- package/src/soundfont/load_soundfont.js +21 -0
- package/src/soundfont/read_sf2/generators.js +46 -0
- package/{spessasynth_core/soundfont/chunk → src/soundfont/read_sf2}/instruments.js +20 -14
- package/src/soundfont/read_sf2/modulators.js +36 -0
- package/src/soundfont/read_sf2/presets.js +80 -0
- package/src/soundfont/read_sf2/samples.js +304 -0
- package/src/soundfont/read_sf2/soundfont.js +305 -0
- package/{spessasynth_core/soundfont/chunk → src/soundfont/read_sf2}/zones.js +68 -69
- package/src/synthetizer/README.md +7 -0
- package/src/synthetizer/audio_engine/README.md +9 -0
- package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +266 -0
- package/src/synthetizer/audio_engine/engine_components/controller_tables.js +88 -0
- package/src/synthetizer/audio_engine/engine_components/key_modifier_manager.js +150 -0
- package/{spessasynth_core/synthetizer/worklet_system/worklet_utilities → src/synthetizer/audio_engine/engine_components}/lfo.js +9 -6
- package/src/synthetizer/audio_engine/engine_components/lowpass_filter.js +282 -0
- package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +467 -0
- package/src/synthetizer/audio_engine/engine_components/modulation_envelope.js +181 -0
- package/{spessasynth_core/synthetizer/worklet_system/worklet_utilities → src/synthetizer/audio_engine/engine_components}/modulator_curves.js +33 -30
- package/src/synthetizer/audio_engine/engine_components/soundfont_manager.js +221 -0
- package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +120 -0
- package/{spessasynth_core/synthetizer/worklet_system/worklet_utilities → src/synthetizer/audio_engine/engine_components}/unit_converter.js +11 -4
- package/src/synthetizer/audio_engine/engine_components/voice.js +519 -0
- package/src/synthetizer/audio_engine/engine_components/volume_envelope.js +401 -0
- package/src/synthetizer/audio_engine/engine_components/wavetable_oscillator.js +263 -0
- package/src/synthetizer/audio_engine/engine_methods/controller_control/controller_change.js +132 -0
- package/src/synthetizer/audio_engine/engine_methods/controller_control/master_parameters.js +48 -0
- package/src/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +241 -0
- package/src/synthetizer/audio_engine/engine_methods/create_midi_channel.js +27 -0
- package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +253 -0
- package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_fine.js +66 -0
- package/src/synthetizer/audio_engine/engine_methods/mute_channel.js +17 -0
- package/src/synthetizer/audio_engine/engine_methods/note_on.js +175 -0
- package/src/synthetizer/audio_engine/engine_methods/portamento_time.js +92 -0
- package/src/synthetizer/audio_engine/engine_methods/program_change.js +61 -0
- package/src/synthetizer/audio_engine/engine_methods/render_voice.js +196 -0
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/clear_sound_font.js +30 -0
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/get_preset.js +22 -0
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/reload_sound_font.js +28 -0
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/send_preset_list.js +31 -0
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/set_embedded_sound_font.js +21 -0
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +20 -0
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/note_off.js +55 -0
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_channels.js +16 -0
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_notes.js +30 -0
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/voice_killing.js +63 -0
- package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +776 -0
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/channel_pressure.js +24 -0
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/pitch_wheel.js +33 -0
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/poly_pressure.js +31 -0
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_master_tuning.js +15 -0
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_modulation_depth.js +27 -0
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_octave_tuning.js +19 -0
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_tuning.js +27 -0
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_all_channels.js +15 -0
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_channel.js +34 -0
- package/src/synthetizer/audio_engine/main_processor.js +804 -0
- package/src/synthetizer/audio_engine/snapshot/apply_synthesizer_snapshot.js +15 -0
- package/src/synthetizer/audio_engine/snapshot/channel_snapshot.js +175 -0
- package/src/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js +116 -0
- package/src/synthetizer/synth_constants.js +22 -0
- package/{spessasynth_core → src}/utils/README.md +1 -0
- package/src/utils/buffer_to_wav.js +185 -0
- package/src/utils/byte_functions/big_endian.js +32 -0
- package/src/utils/byte_functions/little_endian.js +77 -0
- package/src/utils/byte_functions/string.js +107 -0
- package/src/utils/byte_functions/variable_length_quantity.js +42 -0
- package/src/utils/fill_with_defaults.js +21 -0
- package/src/utils/indexed_array.js +52 -0
- package/{spessasynth_core → src}/utils/loggin.js +70 -78
- package/src/utils/other.js +92 -0
- package/src/utils/sysex_detector.js +58 -0
- package/src/utils/xg_hacks.js +193 -0
- package/.idea/inspectionProfiles/Project_Default.xml +0 -10
- package/.idea/jsLibraryMappings.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/spessasynth_core.iml +0 -12
- package/.idea/vcs.xml +0 -6
- package/spessasynth_core/midi_parser/README.md +0 -3
- package/spessasynth_core/midi_parser/midi_loader.js +0 -386
- package/spessasynth_core/sequencer/sequencer.js +0 -202
- package/spessasynth_core/sequencer/worklet_sequencer/play.js +0 -209
- package/spessasynth_core/sequencer/worklet_sequencer/process_event.js +0 -120
- package/spessasynth_core/sequencer/worklet_sequencer/song_control.js +0 -112
- package/spessasynth_core/soundfont/README.md +0 -4
- package/spessasynth_core/soundfont/chunk/generators.js +0 -205
- package/spessasynth_core/soundfont/chunk/modulators.js +0 -232
- package/spessasynth_core/soundfont/chunk/presets.js +0 -264
- package/spessasynth_core/soundfont/chunk/riff_chunk.js +0 -46
- package/spessasynth_core/soundfont/chunk/samples.js +0 -250
- package/spessasynth_core/soundfont/soundfont_parser.js +0 -301
- package/spessasynth_core/synthetizer/README.md +0 -6
- package/spessasynth_core/synthetizer/synthesizer.js +0 -313
- package/spessasynth_core/synthetizer/worklet_system/README.md +0 -3
- package/spessasynth_core/synthetizer/worklet_system/worklet_methods/controller_control.js +0 -290
- package/spessasynth_core/synthetizer/worklet_system/worklet_methods/data_entry.js +0 -280
- package/spessasynth_core/synthetizer/worklet_system/worklet_methods/note_off.js +0 -102
- package/spessasynth_core/synthetizer/worklet_system/worklet_methods/note_on.js +0 -77
- package/spessasynth_core/synthetizer/worklet_system/worklet_methods/program_control.js +0 -140
- package/spessasynth_core/synthetizer/worklet_system/worklet_methods/system_exclusive.js +0 -266
- package/spessasynth_core/synthetizer/worklet_system/worklet_methods/tuning_control.js +0 -104
- package/spessasynth_core/synthetizer/worklet_system/worklet_methods/vibrato_control.js +0 -29
- package/spessasynth_core/synthetizer/worklet_system/worklet_methods/voice_control.js +0 -223
- package/spessasynth_core/synthetizer/worklet_system/worklet_utilities/lowpass_filter.js +0 -133
- package/spessasynth_core/synthetizer/worklet_system/worklet_utilities/modulation_envelope.js +0 -73
- package/spessasynth_core/synthetizer/worklet_system/worklet_utilities/stereo_panner.js +0 -76
- package/spessasynth_core/synthetizer/worklet_system/worklet_utilities/volume_envelope.js +0 -272
- package/spessasynth_core/synthetizer/worklet_system/worklet_utilities/wavetable_oscillator.js +0 -83
- package/spessasynth_core/synthetizer/worklet_system/worklet_utilities/worklet_modulator.js +0 -175
- package/spessasynth_core/synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.js +0 -106
- package/spessasynth_core/synthetizer/worklet_system/worklet_utilities/worklet_voice.js +0 -285
- package/spessasynth_core/utils/buffer_to_wav.js +0 -70
- package/spessasynth_core/utils/byte_functions.js +0 -141
- package/spessasynth_core/utils/other.js +0 -49
- package/spessasynth_core/utils/shiftable_array.js +0 -26
- package/spessasynth_core/utils/stbvorbis_sync.js +0 -1877
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { IndexedByteArray } from "../indexed_array.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param dataArray {IndexedByteArray}
|
|
5
|
+
* @param bytes {number}
|
|
6
|
+
* @param encoding {string} the textElement encoding
|
|
7
|
+
* @param trimEnd {boolean} if we should trim once we reach an invalid byte
|
|
8
|
+
* @returns {string}
|
|
9
|
+
*/
|
|
10
|
+
export function readBytesAsString(dataArray, bytes, encoding = undefined, trimEnd = true)
|
|
11
|
+
{
|
|
12
|
+
if (!encoding)
|
|
13
|
+
{
|
|
14
|
+
let finished = false;
|
|
15
|
+
let string = "";
|
|
16
|
+
for (let i = 0; i < bytes; i++)
|
|
17
|
+
{
|
|
18
|
+
let byte = dataArray[dataArray.currentIndex++];
|
|
19
|
+
if (finished)
|
|
20
|
+
{
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if ((byte < 32 || byte > 127) && byte !== 10) // 10 is "\n"
|
|
24
|
+
{
|
|
25
|
+
if (trimEnd)
|
|
26
|
+
{
|
|
27
|
+
finished = true;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
else
|
|
31
|
+
{
|
|
32
|
+
if (byte === 0)
|
|
33
|
+
{
|
|
34
|
+
finished = true;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
string += String.fromCharCode(byte);
|
|
40
|
+
}
|
|
41
|
+
return string;
|
|
42
|
+
}
|
|
43
|
+
else
|
|
44
|
+
{
|
|
45
|
+
let byteBuffer = dataArray.slice(dataArray.currentIndex, dataArray.currentIndex + bytes);
|
|
46
|
+
dataArray.currentIndex += bytes;
|
|
47
|
+
let decoder = new TextDecoder(encoding.replace(/[^\x20-\x7E]/g, ""));
|
|
48
|
+
return decoder.decode(byteBuffer.buffer);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param string {string}
|
|
54
|
+
* @param padLength {number}
|
|
55
|
+
* @returns {IndexedByteArray}
|
|
56
|
+
*/
|
|
57
|
+
export function getStringBytes(string, padLength = 0)
|
|
58
|
+
{
|
|
59
|
+
let len = string.length;
|
|
60
|
+
if (padLength > 0)
|
|
61
|
+
{
|
|
62
|
+
len = padLength;
|
|
63
|
+
}
|
|
64
|
+
const arr = new IndexedByteArray(len);
|
|
65
|
+
writeStringAsBytes(arr, string, padLength);
|
|
66
|
+
return arr;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @param string {string}
|
|
71
|
+
* @returns {IndexedByteArray}
|
|
72
|
+
*/
|
|
73
|
+
export function getStringBytesZero(string)
|
|
74
|
+
{
|
|
75
|
+
return getStringBytes(string, string.length + 1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @param string {string}
|
|
80
|
+
* @param outArray {IndexedByteArray}
|
|
81
|
+
* @param padLength {number}
|
|
82
|
+
* @returns {IndexedByteArray} modified IN PLACE
|
|
83
|
+
*/
|
|
84
|
+
export function writeStringAsBytes(outArray, string, padLength = 0)
|
|
85
|
+
{
|
|
86
|
+
if (padLength > 0)
|
|
87
|
+
{
|
|
88
|
+
if (string.length > padLength)
|
|
89
|
+
{
|
|
90
|
+
string = string.slice(0, padLength);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
for (let i = 0; i < string.length; i++)
|
|
94
|
+
{
|
|
95
|
+
outArray[outArray.currentIndex++] = string.charCodeAt(i);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// pad with zeros if needed
|
|
99
|
+
if (padLength > string.length)
|
|
100
|
+
{
|
|
101
|
+
for (let i = 0; i < padLength - string.length; i++)
|
|
102
|
+
{
|
|
103
|
+
outArray[outArray.currentIndex++] = 0;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return outArray;
|
|
107
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads VLQ From a MIDI byte array
|
|
3
|
+
* @param MIDIbyteArray {IndexedByteArray}
|
|
4
|
+
* @returns {number}
|
|
5
|
+
*/
|
|
6
|
+
export function readVariableLengthQuantity(MIDIbyteArray)
|
|
7
|
+
{
|
|
8
|
+
let out = 0;
|
|
9
|
+
while (MIDIbyteArray)
|
|
10
|
+
{
|
|
11
|
+
const byte = MIDIbyteArray[MIDIbyteArray.currentIndex++];
|
|
12
|
+
// extract the first 7 bytes
|
|
13
|
+
out = (out << 7) | (byte & 127);
|
|
14
|
+
|
|
15
|
+
// if the last byte isn't 1, stop reading
|
|
16
|
+
if ((byte >> 7) !== 1)
|
|
17
|
+
{
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Write a VLQ from a number to a byte array
|
|
26
|
+
* @param number {number}
|
|
27
|
+
* @returns {number[]}
|
|
28
|
+
*/
|
|
29
|
+
export function writeVariableLengthQuantity(number)
|
|
30
|
+
{
|
|
31
|
+
// Add the first byte
|
|
32
|
+
let bytes = [number & 127];
|
|
33
|
+
number >>= 7;
|
|
34
|
+
|
|
35
|
+
// Continue processing the remaining bytes
|
|
36
|
+
while (number > 0)
|
|
37
|
+
{
|
|
38
|
+
bytes.unshift((number & 127) | 128);
|
|
39
|
+
number >>= 7;
|
|
40
|
+
}
|
|
41
|
+
return bytes;
|
|
42
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fills the object with default values
|
|
3
|
+
* @param obj {Object}
|
|
4
|
+
* @param defObj {Object}
|
|
5
|
+
* @returns {Object}
|
|
6
|
+
*/
|
|
7
|
+
export function fillWithDefaults(obj, defObj)
|
|
8
|
+
{
|
|
9
|
+
if (obj === undefined)
|
|
10
|
+
{
|
|
11
|
+
obj = {};
|
|
12
|
+
}
|
|
13
|
+
for (const key in defObj)
|
|
14
|
+
{
|
|
15
|
+
if (defObj.hasOwnProperty(key) && !(key in obj))
|
|
16
|
+
{
|
|
17
|
+
obj[key] = defObj[key];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return obj;
|
|
21
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* indexed_array.js
|
|
3
|
+
* purpose: exteds Uint8Array with a currentIndex property
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export class IndexedByteArray extends Uint8Array
|
|
7
|
+
{
|
|
8
|
+
/**
|
|
9
|
+
* The current index of the array
|
|
10
|
+
* @type {number}
|
|
11
|
+
*/
|
|
12
|
+
currentIndex = 0;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new instance of an Uint8Array with a currentIndex property
|
|
16
|
+
* @param args {any} same as for Uint8Array
|
|
17
|
+
*/
|
|
18
|
+
constructor(args)
|
|
19
|
+
{
|
|
20
|
+
super(args);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param start {number?}
|
|
25
|
+
* @param end {number?}
|
|
26
|
+
* @returns {IndexedByteArray}
|
|
27
|
+
*/
|
|
28
|
+
slice(start, end)
|
|
29
|
+
{
|
|
30
|
+
const a = super.slice(start, end);
|
|
31
|
+
a.currentIndex = 0;
|
|
32
|
+
return a;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param arrs {(IndexedByteArray|Uint8Array)[]}
|
|
39
|
+
* @returns {IndexedByteArray|Uint8Array}
|
|
40
|
+
*/
|
|
41
|
+
export function combineArrays(arrs)
|
|
42
|
+
{
|
|
43
|
+
const length = arrs.reduce((sum, current) => sum + current.length, 0);
|
|
44
|
+
const newArr = new IndexedByteArray(length);
|
|
45
|
+
let offset = 0;
|
|
46
|
+
for (const arr of arrs)
|
|
47
|
+
{
|
|
48
|
+
newArr.set(arr, offset);
|
|
49
|
+
offset += arr.length;
|
|
50
|
+
}
|
|
51
|
+
return newArr;
|
|
52
|
+
}
|
|
@@ -1,79 +1,71 @@
|
|
|
1
|
-
let ENABLE_INFO =
|
|
2
|
-
let ENABLE_WARN = true;
|
|
3
|
-
let ENABLE_GROUP =
|
|
4
|
-
let ENABLE_TABLE = true;
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Enables or disables looging
|
|
8
|
-
* @param enableInfo {boolean} - enables info
|
|
9
|
-
* @param enableWarn {boolean} - enables warning
|
|
10
|
-
* @param enableGroup {boolean} - enables groups
|
|
11
|
-
* @param enableTable {boolean} - enables tables
|
|
12
|
-
*/
|
|
13
|
-
export function SpessaSynthLogging(enableInfo, enableWarn, enableGroup, enableTable)
|
|
14
|
-
{
|
|
15
|
-
ENABLE_INFO = enableInfo;
|
|
16
|
-
ENABLE_WARN = enableWarn;
|
|
17
|
-
ENABLE_GROUP = enableGroup;
|
|
18
|
-
ENABLE_TABLE = enableTable;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @param message {...any}
|
|
23
|
-
*/
|
|
24
|
-
export function SpessaSynthInfo(...message)
|
|
25
|
-
{
|
|
26
|
-
if(ENABLE_INFO)
|
|
27
|
-
{
|
|
28
|
-
console.info(...message);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @param message {...any}
|
|
34
|
-
*/
|
|
35
|
-
export function SpessaSynthWarn(...message)
|
|
36
|
-
{
|
|
37
|
-
if(ENABLE_WARN)
|
|
38
|
-
{
|
|
39
|
-
console.warn(...message);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
export function
|
|
66
|
-
{
|
|
67
|
-
if(ENABLE_GROUP)
|
|
68
|
-
{
|
|
69
|
-
console.
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function SpessaSynthGroupEnd()
|
|
74
|
-
{
|
|
75
|
-
if(ENABLE_GROUP)
|
|
76
|
-
{
|
|
77
|
-
console.groupEnd();
|
|
78
|
-
}
|
|
1
|
+
let ENABLE_INFO = false;
|
|
2
|
+
let ENABLE_WARN = true;
|
|
3
|
+
let ENABLE_GROUP = false;
|
|
4
|
+
let ENABLE_TABLE = true;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Enables or disables looging
|
|
8
|
+
* @param enableInfo {boolean} - enables info
|
|
9
|
+
* @param enableWarn {boolean} - enables warning
|
|
10
|
+
* @param enableGroup {boolean} - enables groups
|
|
11
|
+
* @param enableTable {boolean} - enables tables
|
|
12
|
+
*/
|
|
13
|
+
export function SpessaSynthLogging(enableInfo, enableWarn, enableGroup, enableTable)
|
|
14
|
+
{
|
|
15
|
+
ENABLE_INFO = enableInfo;
|
|
16
|
+
ENABLE_WARN = enableWarn;
|
|
17
|
+
ENABLE_GROUP = enableGroup;
|
|
18
|
+
ENABLE_TABLE = enableTable;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param message {...any}
|
|
23
|
+
*/
|
|
24
|
+
export function SpessaSynthInfo(...message)
|
|
25
|
+
{
|
|
26
|
+
if (ENABLE_INFO)
|
|
27
|
+
{
|
|
28
|
+
console.info(...message);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param message {...any}
|
|
34
|
+
*/
|
|
35
|
+
export function SpessaSynthWarn(...message)
|
|
36
|
+
{
|
|
37
|
+
if (ENABLE_WARN)
|
|
38
|
+
{
|
|
39
|
+
console.warn(...message);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param message {...any} the message
|
|
45
|
+
*/
|
|
46
|
+
export function SpessaSynthGroup(...message)
|
|
47
|
+
{
|
|
48
|
+
if (ENABLE_GROUP)
|
|
49
|
+
{
|
|
50
|
+
console.group(...message);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @param message {...any} the message
|
|
56
|
+
*/
|
|
57
|
+
export function SpessaSynthGroupCollapsed(...message)
|
|
58
|
+
{
|
|
59
|
+
if (ENABLE_GROUP)
|
|
60
|
+
{
|
|
61
|
+
console.groupCollapsed(...message);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function SpessaSynthGroupEnd()
|
|
66
|
+
{
|
|
67
|
+
if (ENABLE_GROUP)
|
|
68
|
+
{
|
|
69
|
+
console.groupEnd();
|
|
70
|
+
}
|
|
79
71
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* other.js
|
|
3
|
+
* purpose: contains some useful functions that don't belong in any specific category
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Formats the given seconds to nice readable time
|
|
8
|
+
* @param totalSeconds {number} time in seconds
|
|
9
|
+
* @return {{seconds: number, minutes: number, time: string}}
|
|
10
|
+
*/
|
|
11
|
+
export function formatTime(totalSeconds)
|
|
12
|
+
{
|
|
13
|
+
totalSeconds = Math.floor(totalSeconds);
|
|
14
|
+
let minutes = Math.floor(totalSeconds / 60);
|
|
15
|
+
let seconds = Math.round(totalSeconds - (minutes * 60));
|
|
16
|
+
return {
|
|
17
|
+
"minutes": minutes,
|
|
18
|
+
"seconds": seconds,
|
|
19
|
+
"time": `${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param fileName {string}
|
|
25
|
+
* @returns {string}
|
|
26
|
+
*/
|
|
27
|
+
export function formatTitle(fileName)
|
|
28
|
+
{
|
|
29
|
+
return fileName
|
|
30
|
+
.trim()
|
|
31
|
+
.replaceAll(".mid", "")
|
|
32
|
+
.replaceAll(".kar", "")
|
|
33
|
+
.replaceAll(".rmi", "")
|
|
34
|
+
.replaceAll(".xmf", "")
|
|
35
|
+
.replaceAll(".mxmf", "")
|
|
36
|
+
.replaceAll("_", " ")
|
|
37
|
+
.trim();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Does what it says
|
|
42
|
+
* @param arr {number[]|Uint8Array}
|
|
43
|
+
* @returns {string}
|
|
44
|
+
*/
|
|
45
|
+
export function arrayToHexString(arr)
|
|
46
|
+
{
|
|
47
|
+
let hexString = "";
|
|
48
|
+
|
|
49
|
+
for (let i = 0; i < arr.length; i++)
|
|
50
|
+
{
|
|
51
|
+
const hex = arr[i].toString(16).padStart(2, "0").toUpperCase();
|
|
52
|
+
hexString += hex;
|
|
53
|
+
hexString += " ";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return hexString;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @param eventData {Uint8Array}
|
|
61
|
+
* @returns {Uint8Array}
|
|
62
|
+
*/
|
|
63
|
+
export function sanitizeKarLyrics(eventData)
|
|
64
|
+
{
|
|
65
|
+
// for KAR files:
|
|
66
|
+
// https://www.mixagesoftware.com/en/midikit/help/HTML/karaoke_formats.html
|
|
67
|
+
// "/" is the newline character
|
|
68
|
+
// "\" is also the newline character
|
|
69
|
+
// "\" ASCII code is 92
|
|
70
|
+
// "/" ASCII code is 47
|
|
71
|
+
// newline ASCII code is 10
|
|
72
|
+
const sanitized = [];
|
|
73
|
+
for (let byte of eventData)
|
|
74
|
+
{
|
|
75
|
+
if (byte === 47 || byte === 92)
|
|
76
|
+
{
|
|
77
|
+
byte = 10;
|
|
78
|
+
}
|
|
79
|
+
sanitized.push(byte);
|
|
80
|
+
}
|
|
81
|
+
return new Uint8Array(sanitized);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const consoleColors = {
|
|
85
|
+
warn: "color: orange;",
|
|
86
|
+
unrecognized: "color: red;",
|
|
87
|
+
info: "color: aqua;",
|
|
88
|
+
recognized: "color: lime",
|
|
89
|
+
value: "color: yellow; background-color: black;"
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param e {MIDIMessage}
|
|
3
|
+
* @returns boolean
|
|
4
|
+
*/
|
|
5
|
+
export function isXGOn(e)
|
|
6
|
+
{
|
|
7
|
+
return e.messageData[0] === 0x43 && // Yamaha
|
|
8
|
+
e.messageData[2] === 0x4C && // XG ON
|
|
9
|
+
e.messageData[5] === 0x7E &&
|
|
10
|
+
e.messageData[6] === 0x00;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param e {MIDIMessage}
|
|
15
|
+
* @returns boolean
|
|
16
|
+
*/
|
|
17
|
+
export function isGSDrumsOn(e)
|
|
18
|
+
{
|
|
19
|
+
return e.messageData[0] === 0x41 && // roland
|
|
20
|
+
e.messageData[2] === 0x42 && // GS
|
|
21
|
+
e.messageData[3] === 0x12 && // GS
|
|
22
|
+
e.messageData[4] === 0x40 && // system parameter
|
|
23
|
+
(e.messageData[5] & 0x10) !== 0 && // part parameter
|
|
24
|
+
e.messageData[6] === 0x15; // drum pars
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param e {MIDIMessage}
|
|
29
|
+
* @returns boolean
|
|
30
|
+
*/
|
|
31
|
+
export function isGSOn(e)
|
|
32
|
+
{
|
|
33
|
+
return e.messageData[0] === 0x41 // roland
|
|
34
|
+
&& e.messageData[2] === 0x42 // GS
|
|
35
|
+
&& e.messageData[6] === 0x7F; // Mode set
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param e {MIDIMessage}
|
|
40
|
+
* @returns boolean
|
|
41
|
+
*/
|
|
42
|
+
export function isGMOn(e)
|
|
43
|
+
{
|
|
44
|
+
return e.messageData[0] === 0x7E // non realtime
|
|
45
|
+
&& e.messageData[2] === 0x09 // gm system
|
|
46
|
+
&& e.messageData[3] === 0x01; // gm1
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @param e {MIDIMessage}
|
|
51
|
+
* @returns boolean
|
|
52
|
+
*/
|
|
53
|
+
export function isGM2On(e)
|
|
54
|
+
{
|
|
55
|
+
return e.messageData[0] === 0x7E // non realtime
|
|
56
|
+
&& e.messageData[2] === 0x09 // gm system
|
|
57
|
+
&& e.messageData[3] === 0x03; // gm2
|
|
58
|
+
}
|