spessasynth_lib 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/modules.xml +8 -0
- package/.idea/spessasynth_lib.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/copy_version.sh +38 -0
- package/index.js +73 -0
- package/package/@types/externals/stbvorbis_sync/stbvorbis_sync.min.d.ts +1 -0
- package/package/@types/index.d.ts +34 -0
- package/package/@types/midi_handler/midi_handler.d.ts +39 -0
- package/package/@types/midi_handler/web_midi_link.d.ts +12 -0
- package/package/@types/midi_parser/midi_data.d.ts +95 -0
- package/package/@types/midi_parser/midi_editor.d.ts +45 -0
- package/package/@types/midi_parser/midi_loader.d.ts +100 -0
- package/package/@types/midi_parser/midi_message.d.ts +154 -0
- package/package/@types/midi_parser/midi_writer.d.ts +6 -0
- package/package/@types/midi_parser/rmidi_writer.d.ts +9 -0
- package/package/@types/midi_parser/used_keys_loaded.d.ts +7 -0
- package/package/@types/sequencer/sequencer.d.ts +180 -0
- package/package/@types/sequencer/worklet_sequencer/sequencer_message.d.ts +28 -0
- package/package/@types/soundfont/read/generators.d.ts +98 -0
- package/package/@types/soundfont/read/instruments.d.ts +50 -0
- package/package/@types/soundfont/read/modulators.d.ts +73 -0
- package/package/@types/soundfont/read/presets.d.ts +87 -0
- package/package/@types/soundfont/read/riff_chunk.d.ts +31 -0
- package/package/@types/soundfont/read/samples.d.ts +134 -0
- package/package/@types/soundfont/read/zones.d.ts +141 -0
- package/package/@types/soundfont/soundfont.d.ts +76 -0
- package/package/@types/soundfont/write/ibag.d.ts +6 -0
- package/package/@types/soundfont/write/igen.d.ts +6 -0
- package/package/@types/soundfont/write/imod.d.ts +6 -0
- package/package/@types/soundfont/write/inst.d.ts +6 -0
- package/package/@types/soundfont/write/pbag.d.ts +6 -0
- package/package/@types/soundfont/write/pgen.d.ts +6 -0
- package/package/@types/soundfont/write/phdr.d.ts +6 -0
- package/package/@types/soundfont/write/pmod.d.ts +6 -0
- package/package/@types/soundfont/write/sdta.d.ts +11 -0
- package/package/@types/soundfont/write/shdr.d.ts +8 -0
- package/package/@types/soundfont/write/soundfont_trimmer.d.ts +6 -0
- package/package/@types/soundfont/write/write.d.ts +21 -0
- package/package/@types/synthetizer/audio_effects/effects_config.d.ts +29 -0
- package/package/@types/synthetizer/audio_effects/fancy_chorus.d.ts +93 -0
- package/package/@types/synthetizer/audio_effects/reverb.d.ts +7 -0
- package/package/@types/synthetizer/synth_event_handler.d.ts +161 -0
- package/package/@types/synthetizer/synthetizer.d.ts +294 -0
- package/package/@types/synthetizer/worklet_system/message_protocol/worklet_message.d.ts +89 -0
- package/package/@types/synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.d.ts +134 -0
- package/package/@types/synthetizer/worklet_url.d.ts +5 -0
- package/package/@types/utils/buffer_to_wav.d.ts +8 -0
- package/package/@types/utils/byte_functions/big_endian.d.ts +13 -0
- package/package/@types/utils/byte_functions/little_endian.d.ts +35 -0
- package/package/@types/utils/byte_functions/string.d.ts +22 -0
- package/package/@types/utils/byte_functions/variable_length_quantity.d.ts +12 -0
- package/package/@types/utils/indexed_array.d.ts +21 -0
- package/package/@types/utils/loggin.d.ts +26 -0
- package/package/@types/utils/other.d.ts +32 -0
- package/package/LICENSE +26 -0
- package/package/README.md +84 -0
- package/package/externals/NOTICE +9 -0
- package/package/externals/libvorbis/@types/OggVorbisEncoder.d.ts +34 -0
- package/package/externals/libvorbis/OggVorbisEncoder.min.js +1 -0
- package/package/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +12 -0
- package/package/externals/stbvorbis_sync/LICENSE +202 -0
- package/package/externals/stbvorbis_sync/stbvorbis_sync.min.js +1 -0
- package/package/index.js +73 -0
- package/package/midi_handler/README.md +3 -0
- package/package/midi_handler/midi_handler.js +118 -0
- package/package/midi_handler/web_midi_link.js +41 -0
- package/package/midi_parser/README.md +3 -0
- package/package/midi_parser/midi_data.js +121 -0
- package/package/midi_parser/midi_editor.js +557 -0
- package/package/midi_parser/midi_loader.js +502 -0
- package/package/midi_parser/midi_message.js +234 -0
- package/package/midi_parser/midi_writer.js +95 -0
- package/package/midi_parser/rmidi_writer.js +271 -0
- package/package/midi_parser/used_keys_loaded.js +172 -0
- package/package/package.json +43 -0
- package/package/sequencer/README.md +23 -0
- package/package/sequencer/sequencer.js +439 -0
- package/package/sequencer/worklet_sequencer/events.js +92 -0
- package/package/sequencer/worklet_sequencer/play.js +309 -0
- package/package/sequencer/worklet_sequencer/process_event.js +167 -0
- package/package/sequencer/worklet_sequencer/process_tick.js +85 -0
- package/package/sequencer/worklet_sequencer/sequencer_message.js +39 -0
- package/package/sequencer/worklet_sequencer/song_control.js +193 -0
- package/package/sequencer/worklet_sequencer/worklet_sequencer.js +218 -0
- package/package/soundfont/README.md +8 -0
- package/package/soundfont/read/generators.js +212 -0
- package/package/soundfont/read/instruments.js +125 -0
- package/package/soundfont/read/modulators.js +249 -0
- package/package/soundfont/read/presets.js +300 -0
- package/package/soundfont/read/riff_chunk.js +81 -0
- package/package/soundfont/read/samples.js +398 -0
- package/package/soundfont/read/zones.js +310 -0
- package/package/soundfont/soundfont.js +357 -0
- package/package/soundfont/write/ibag.js +39 -0
- package/package/soundfont/write/igen.js +75 -0
- package/package/soundfont/write/imod.js +46 -0
- package/package/soundfont/write/inst.js +34 -0
- package/package/soundfont/write/pbag.js +39 -0
- package/package/soundfont/write/pgen.js +77 -0
- package/package/soundfont/write/phdr.js +42 -0
- package/package/soundfont/write/pmod.js +46 -0
- package/package/soundfont/write/sdta.js +72 -0
- package/package/soundfont/write/shdr.js +54 -0
- package/package/soundfont/write/soundfont_trimmer.js +169 -0
- package/package/soundfont/write/write.js +180 -0
- package/package/synthetizer/README.md +6 -0
- package/package/synthetizer/audio_effects/effects_config.js +21 -0
- package/package/synthetizer/audio_effects/fancy_chorus.js +120 -0
- package/package/synthetizer/audio_effects/impulse_response_2.flac +0 -0
- package/package/synthetizer/audio_effects/reverb.js +24 -0
- package/package/synthetizer/synth_event_handler.js +156 -0
- package/package/synthetizer/synthetizer.js +766 -0
- package/package/synthetizer/worklet_processor.min.js +13 -0
- package/package/synthetizer/worklet_system/README.md +6 -0
- package/package/synthetizer/worklet_system/main_processor.js +363 -0
- package/package/synthetizer/worklet_system/message_protocol/handle_message.js +197 -0
- package/package/synthetizer/worklet_system/message_protocol/message_sending.js +74 -0
- package/package/synthetizer/worklet_system/message_protocol/worklet_message.js +121 -0
- package/package/synthetizer/worklet_system/minify_processor.sh +4 -0
- package/package/synthetizer/worklet_system/worklet_methods/controller_control.js +230 -0
- package/package/synthetizer/worklet_system/worklet_methods/data_entry.js +277 -0
- package/package/synthetizer/worklet_system/worklet_methods/note_off.js +109 -0
- package/package/synthetizer/worklet_system/worklet_methods/note_on.js +91 -0
- package/package/synthetizer/worklet_system/worklet_methods/program_control.js +183 -0
- package/package/synthetizer/worklet_system/worklet_methods/reset_controllers.js +177 -0
- package/package/synthetizer/worklet_system/worklet_methods/snapshot.js +129 -0
- package/package/synthetizer/worklet_system/worklet_methods/system_exclusive.js +272 -0
- package/package/synthetizer/worklet_system/worklet_methods/tuning_control.js +195 -0
- package/package/synthetizer/worklet_system/worklet_methods/vibrato_control.js +29 -0
- package/package/synthetizer/worklet_system/worklet_methods/voice_control.js +233 -0
- package/package/synthetizer/worklet_system/worklet_processor.js +9 -0
- package/package/synthetizer/worklet_system/worklet_utilities/lfo.js +23 -0
- package/package/synthetizer/worklet_system/worklet_utilities/lowpass_filter.js +130 -0
- package/package/synthetizer/worklet_system/worklet_utilities/modulation_envelope.js +73 -0
- package/package/synthetizer/worklet_system/worklet_utilities/modulator_curves.js +86 -0
- package/package/synthetizer/worklet_system/worklet_utilities/stereo_panner.js +81 -0
- package/package/synthetizer/worklet_system/worklet_utilities/unit_converter.js +66 -0
- package/package/synthetizer/worklet_system/worklet_utilities/volume_envelope.js +265 -0
- package/package/synthetizer/worklet_system/worklet_utilities/wavetable_oscillator.js +83 -0
- package/package/synthetizer/worklet_system/worklet_utilities/worklet_modulator.js +234 -0
- package/package/synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.js +116 -0
- package/package/synthetizer/worklet_system/worklet_utilities/worklet_voice.js +272 -0
- package/package/synthetizer/worklet_url.js +5 -0
- package/package/utils/README.md +4 -0
- package/package/utils/buffer_to_wav.js +101 -0
- package/package/utils/byte_functions/big_endian.js +28 -0
- package/package/utils/byte_functions/little_endian.js +74 -0
- package/package/utils/byte_functions/string.js +97 -0
- package/package/utils/byte_functions/variable_length_quantity.js +37 -0
- package/package/utils/encode_vorbis.js +30 -0
- package/package/utils/indexed_array.js +41 -0
- package/package/utils/loggin.js +79 -0
- package/package/utils/other.js +54 -0
- package/package.json +43 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Synthetizer } from '../synthetizer/synthetizer.js'
|
|
2
|
+
import { consoleColors } from '../utils/other.js';
|
|
3
|
+
import { SpessaSynthInfo, SpessaSynthWarn } from '../utils/loggin.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* midi_handler.js
|
|
7
|
+
* purpose: handles the connection between MIDI devices and synthesizer/sequencer via Web MIDI API
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const NO_INPUT = null;
|
|
11
|
+
|
|
12
|
+
export class MIDIDeviceHandler
|
|
13
|
+
{
|
|
14
|
+
constructor()
|
|
15
|
+
{}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @returns {Promise<boolean>} if succeded
|
|
19
|
+
*/
|
|
20
|
+
async createMIDIDeviceHandler()
|
|
21
|
+
{
|
|
22
|
+
/**
|
|
23
|
+
* @type {MIDIInput}
|
|
24
|
+
*/
|
|
25
|
+
this.selectedInput = NO_INPUT;
|
|
26
|
+
/**
|
|
27
|
+
* @type {MIDIOutput}
|
|
28
|
+
*/
|
|
29
|
+
this.selectedOutput = NO_INPUT;
|
|
30
|
+
if(navigator.requestMIDIAccess) {
|
|
31
|
+
// prepare the midi access
|
|
32
|
+
try
|
|
33
|
+
{
|
|
34
|
+
const response = await navigator.requestMIDIAccess({ sysex: true, software: true });
|
|
35
|
+
this.inputs = response.inputs;
|
|
36
|
+
this.outputs = response.outputs;
|
|
37
|
+
SpessaSynthInfo("%cMIDI handler created!", consoleColors.recognized);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
SpessaSynthWarn(`Could not get MIDI Devices:`, e);
|
|
42
|
+
this.inputs = [];
|
|
43
|
+
this.outputs = [];
|
|
44
|
+
return false
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else
|
|
48
|
+
{
|
|
49
|
+
SpessaSynthWarn("Web MIDI Api not supported!", consoleColors.unrecognized);
|
|
50
|
+
this.inputs = [];
|
|
51
|
+
this.outputs = [];
|
|
52
|
+
return false
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Connects the sequencer to a given MIDI output port
|
|
58
|
+
* @param output {MIDIOutput}
|
|
59
|
+
* @param seq {Sequencer}
|
|
60
|
+
*/
|
|
61
|
+
connectMIDIOutputToSeq(output, seq)
|
|
62
|
+
{
|
|
63
|
+
this.selectedOutput = output;
|
|
64
|
+
seq.connectMidiOutput(output);
|
|
65
|
+
SpessaSynthInfo(`%cPlaying MIDI to %c${output.name}`,
|
|
66
|
+
consoleColors.info,
|
|
67
|
+
consoleColors.recognized);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Disconnects a midi output port from the sequencer
|
|
72
|
+
* @param seq {Sequencer}
|
|
73
|
+
*/
|
|
74
|
+
disconnectSeqFromMIDI(seq)
|
|
75
|
+
{
|
|
76
|
+
this.selectedOutput = NO_INPUT;
|
|
77
|
+
seq.connectMidiOutput(undefined);
|
|
78
|
+
SpessaSynthInfo("%cDisconnected from MIDI out.",
|
|
79
|
+
consoleColors.info);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Connects a MIDI input to the synthesizer
|
|
84
|
+
* @param input {MIDIInput}
|
|
85
|
+
* @param synth {Synthetizer}
|
|
86
|
+
*/
|
|
87
|
+
connectDeviceToSynth(input, synth)
|
|
88
|
+
{
|
|
89
|
+
this.selectedInput = input;
|
|
90
|
+
input.onmidimessage = event => {
|
|
91
|
+
synth.sendMessage(event.data);
|
|
92
|
+
}
|
|
93
|
+
SpessaSynthInfo(`%cListening for messages on %c${input.name}`,
|
|
94
|
+
consoleColors.info,
|
|
95
|
+
consoleColors.recognized);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @param input {MIDIInput}
|
|
100
|
+
*/
|
|
101
|
+
disconnectDeviceFromSynth(input)
|
|
102
|
+
{
|
|
103
|
+
this.selectedInput = NO_INPUT;
|
|
104
|
+
input.onmidimessage = undefined;
|
|
105
|
+
SpessaSynthInfo(`%cDisconnected from %c${input.name}`,
|
|
106
|
+
consoleColors.info,
|
|
107
|
+
consoleColors.recognized);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
disconnectAllDevicesFromSynth()
|
|
111
|
+
{
|
|
112
|
+
this.selectedInput = NO_INPUT;
|
|
113
|
+
for(const i of this.inputs)
|
|
114
|
+
{
|
|
115
|
+
i[1].onmidimessage = undefined;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Synthetizer } from '../synthetizer/synthetizer.js'
|
|
2
|
+
import { consoleColors } from '../utils/other.js'
|
|
3
|
+
import { SpessaSynthInfo } from '../utils/loggin.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* web_midi_link.js
|
|
7
|
+
* purpose: handles the web midi link connection to the synthesizer
|
|
8
|
+
* https://www.g200kg.com/en/docs/webmidilink/
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export class WebMidiLinkHandler
|
|
12
|
+
{
|
|
13
|
+
/**
|
|
14
|
+
* @param synth {Synthetizer} the synth to play to
|
|
15
|
+
*/
|
|
16
|
+
constructor(synth) {
|
|
17
|
+
|
|
18
|
+
window.addEventListener("message", msg => {
|
|
19
|
+
if(typeof msg.data !== "string")
|
|
20
|
+
{
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @type {string[]}
|
|
25
|
+
*/
|
|
26
|
+
const data = msg.data.split(",");
|
|
27
|
+
if(data[0] !== "midi")
|
|
28
|
+
{
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
data.shift(); // remove MIDI
|
|
33
|
+
|
|
34
|
+
const midiData = data.map(byte => parseInt(byte, 16));
|
|
35
|
+
|
|
36
|
+
synth.sendMessage(midiData);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
SpessaSynthInfo("%cWeb MIDI Link handler created!", consoleColors.recognized);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A simplified version of the MIDI, accessible at all times from the Sequencer. use getMIDI() to get the actual sequence
|
|
3
|
+
* This class contains all properties that MIDI does, except for tracks, which is the track data.
|
|
4
|
+
*/
|
|
5
|
+
export class MidiData
|
|
6
|
+
{
|
|
7
|
+
/**
|
|
8
|
+
* @param midi {MIDI}
|
|
9
|
+
*/
|
|
10
|
+
constructor(midi)
|
|
11
|
+
{
|
|
12
|
+
/**
|
|
13
|
+
* The time division of the sequence
|
|
14
|
+
* @type {number}
|
|
15
|
+
*/
|
|
16
|
+
this.timeDivision = midi.timeDivision;
|
|
17
|
+
/**
|
|
18
|
+
* The duration of the sequence, in seconds
|
|
19
|
+
* @type {number}
|
|
20
|
+
*/
|
|
21
|
+
this.duration = midi.duration;
|
|
22
|
+
/**
|
|
23
|
+
* The tempo changes in the sequence, ordered from last to first
|
|
24
|
+
* @type {{ticks: number, tempo: number}[]}
|
|
25
|
+
*/
|
|
26
|
+
this.tempoChanges = midi.tempoChanges;
|
|
27
|
+
/**
|
|
28
|
+
* Contains the copyright strings
|
|
29
|
+
* @type {string}
|
|
30
|
+
*/
|
|
31
|
+
this.copyright = midi.copyright;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The amount of tracks in the sequence
|
|
35
|
+
* @type {number}
|
|
36
|
+
*/
|
|
37
|
+
this.tracksAmount = midi.tracksAmount;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The lyrics of the sequence as binary chunks
|
|
41
|
+
* @type {Uint8Array[]}
|
|
42
|
+
*/
|
|
43
|
+
this.lyrics = midi.lyrics;
|
|
44
|
+
|
|
45
|
+
this.firstNoteOn = midi.firstNoteOn;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The MIDI's key range
|
|
49
|
+
* @type {{min: number, max: number}}
|
|
50
|
+
*/
|
|
51
|
+
this.keyRange = midi.keyRange;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The last voice (note on, off, cc change etc.) event tick
|
|
55
|
+
* @type {number}
|
|
56
|
+
*/
|
|
57
|
+
this.lastVoiceEventTick = midi.lastVoiceEventTick;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Midi port numbers for each track
|
|
61
|
+
* @type {number[]}
|
|
62
|
+
*/
|
|
63
|
+
this.midiPorts = midi.midiPorts;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* All channels that each track uses
|
|
67
|
+
* @type {Set<number>[]}
|
|
68
|
+
*/
|
|
69
|
+
this.usedChannelsOnTrack = midi.usedChannelsOnTrack;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The loop points (in ticks) of the sequence
|
|
73
|
+
* @type {{start: number, end: number}}
|
|
74
|
+
*/
|
|
75
|
+
this.loop = midi.loop;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The sequence's name
|
|
79
|
+
* @type {string}
|
|
80
|
+
*/
|
|
81
|
+
this.midiName = midi.midiName;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The file name of the sequence, if provided in the MIDI class
|
|
85
|
+
* @type {string}
|
|
86
|
+
*/
|
|
87
|
+
this.fileName = midi.fileName;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The raw, encoded MIDI name.
|
|
91
|
+
* @type {Uint8Array}
|
|
92
|
+
*/
|
|
93
|
+
this.rawMidiName = midi.rawMidiName;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
*
|
|
99
|
+
* @type {MidiData}
|
|
100
|
+
*/
|
|
101
|
+
export const DUMMY_MIDI_DATA = {
|
|
102
|
+
duration: 99999,
|
|
103
|
+
firstNoteOn: 0,
|
|
104
|
+
loop: {
|
|
105
|
+
start: 0,
|
|
106
|
+
end: 123456
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
lastVoiceEventTick: 123456,
|
|
110
|
+
lyrics: [],
|
|
111
|
+
copyright: "",
|
|
112
|
+
midiPorts: [],
|
|
113
|
+
tracksAmount: 0,
|
|
114
|
+
tempoChanges: [{ticks: 0, tempo: 120}],
|
|
115
|
+
fileName: "NOT_LOADED.mid",
|
|
116
|
+
midiName: "Loading...",
|
|
117
|
+
rawMidiName: new Uint8Array([76, 111, 97, 100, 105, 110, 103, 46, 46, 46]), // "Loading..."
|
|
118
|
+
usedChannelsOnTrack: [],
|
|
119
|
+
timeDivision: 0,
|
|
120
|
+
keyRange: {min: 0, max: 127}
|
|
121
|
+
};
|