spessasynth_lib 3.25.18 → 3.25.20
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/external_midi/midi_handler.js +1 -1
- package/external_midi/web_midi_link.js +1 -1
- package/index.js +4 -0
- package/midi_parser/midi_editor.js +1 -1
- package/package.json +1 -1
- package/sequencer/README.md +2 -0
- package/sequencer/{worklet_sequencer → sequencer_engine}/events.js +33 -25
- package/sequencer/{worklet_sequencer → sequencer_engine}/play.js +11 -11
- package/sequencer/{worklet_sequencer → sequencer_engine}/process_event.js +4 -4
- package/sequencer/{worklet_sequencer → sequencer_engine}/process_tick.js +5 -5
- package/sequencer/{worklet_sequencer/worklet_sequencer.js → sequencer_engine/sequencer_engine.js} +29 -28
- package/sequencer/{worklet_sequencer → sequencer_engine}/song_control.js +10 -10
- package/sequencer/{sequencer.js → worklet_wrapper/sequencer.js} +44 -41
- package/sequencer/{worklet_sequencer → worklet_wrapper}/sequencer_message.js +2 -2
- package/soundfont/basic_soundfont/generator.js +1 -1
- package/soundfont/dls/read_region.js +1 -5
- package/synthetizer/README.md +3 -1
- package/synthetizer/audio_engine/README.md +25 -0
- package/synthetizer/{worklet_system → audio_engine}/main_processor.js +128 -116
- package/synthetizer/{worklet_system → audio_engine}/message_protocol/worklet_message.js +4 -4
- package/synthetizer/{worklet_system → audio_engine}/snapshot/channel_snapshot.js +2 -2
- package/synthetizer/{worklet_system → audio_engine}/snapshot/synthesizer_snapshot.js +2 -2
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/controller_control/controller_change.js +1 -1
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/controller_control/reset_controllers.js +7 -7
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/create_worklet_channel.js +3 -3
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/note_on.js +1 -2
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/render_voice.js +2 -3
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/soundfont_management/clear_sound_font.js +2 -2
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/soundfont_management/reload_sound_font.js +1 -1
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/stopping_notes/kill_note.js +1 -1
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/stopping_notes/note_off.js +1 -1
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/stopping_notes/stop_all_channels.js +2 -2
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/stopping_notes/stop_all_notes.js +2 -2
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/stopping_notes/voice_killing.js +1 -1
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/system_exclusive.js +7 -7
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/tuning_control/set_master_tuning.js +2 -2
- package/synthetizer/{worklet_system → audio_engine}/worklet_methods/tuning_control/transpose_all_channels.js +2 -2
- package/synthetizer/{worklet_system → audio_engine}/worklet_utilities/lowpass_filter.js +20 -3
- package/synthetizer/{worklet_system → audio_engine}/worklet_utilities/stereo_panner.js +2 -2
- package/synthetizer/{worklet_system → audio_engine}/worklet_utilities/worklet_processor_channel.js +1 -1
- package/synthetizer/{worklet_system → audio_engine}/worklet_utilities/worklet_voice.js +13 -12
- package/synthetizer/synth_constants.js +15 -10
- package/synthetizer/worklet_processor.min.js +11 -11
- package/synthetizer/{key_modifier_manager.js → worklet_wrapper/key_modifier_manager.js} +2 -2
- package/synthetizer/{synth_soundfont_manager.js → worklet_wrapper/synth_soundfont_manager.js} +3 -3
- package/synthetizer/{synthetizer.js → worklet_wrapper/synthetizer.js} +14 -18
- package/synthetizer/worklet_wrapper/worklet_processor.js +338 -0
- package/synthetizer/worklet_wrapper/worklet_url.js +16 -0
- package/synthetizer/worklet_system/README.md +0 -12
- package/synthetizer/worklet_system/message_protocol/handle_message.js +0 -210
- package/synthetizer/worklet_system/snapshot/send_synthesizer_snapshot.js +0 -14
- package/synthetizer/worklet_system/worklet_processor.js +0 -9
- package/synthetizer/worklet_url.js +0 -5
- /package/sequencer/{default_sequencer_options.js → worklet_wrapper/default_sequencer_options.js} +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/message_protocol/README.md +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/message_protocol/message_sending.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/snapshot/apply_synthesizer_snapshot.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/controller_control/master_parameters.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/data_entry/data_entry_coarse.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/data_entry/data_entry_fine.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/mute_channel.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/portamento_time.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/program_change.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/soundfont_management/get_preset.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/soundfont_management/send_preset_list.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/soundfont_management/set_embedded_sound_font.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/tuning_control/channel_pressure.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/tuning_control/pitch_wheel.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/tuning_control/poly_pressure.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/tuning_control/set_modulation_depth.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/tuning_control/set_octave_tuning.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/tuning_control/set_tuning.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/tuning_control/transpose_channel.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/worklet_key_modifier.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/worklet_soundfont_manager/sfman_message.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_methods/worklet_soundfont_manager/worklet_soundfont_manager.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_utilities/controller_tables.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_utilities/lfo.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_utilities/modulation_envelope.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_utilities/modulator_curves.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_utilities/unit_converter.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_utilities/volume_envelope.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_utilities/wavetable_oscillator.js +0 -0
- /package/synthetizer/{worklet_system → audio_engine}/worklet_utilities/worklet_modulator.js +0 -0
- /package/synthetizer/{synth_event_handler.js → worklet_wrapper/synth_event_handler.js} +0 -0
package/index.js
CHANGED
|
@@ -27,6 +27,8 @@ import { DEFAULT_SYNTH_CONFIG } from "./synthetizer/audio_effects/effects_config
|
|
|
27
27
|
import { WORKLET_URL_ABSOLUTE } from './synthetizer/worklet_url.js';
|
|
28
28
|
import { SynthesizerSnapshot} from "./synthetizer/worklet_system/snapshot/synthesizer_snapshot.js";
|
|
29
29
|
import { ChannelSnapshot } from "./synthetizer/worklet_system/snapshot/channel_snapshot.js";
|
|
30
|
+
import { NON_CC_INDEX_OFFSET } from "./synthetizer/worklet_system/worklet_utilities/controller_tables.js";
|
|
31
|
+
import { ALL_CHANNELS_OR_DIFFERENT_ACTION } from "./synthetizer/worklet_system/message_protocol/worklet_message.js";
|
|
30
32
|
|
|
31
33
|
// Export modules
|
|
32
34
|
export {
|
|
@@ -38,6 +40,8 @@ export {
|
|
|
38
40
|
DEFAULT_PERCUSSION,
|
|
39
41
|
VOICE_CAP,
|
|
40
42
|
DEFAULT_SYNTH_CONFIG,
|
|
43
|
+
ALL_CHANNELS_OR_DIFFERENT_ACTION,
|
|
44
|
+
NON_CC_INDEX_OFFSET,
|
|
41
45
|
|
|
42
46
|
// SoundFont
|
|
43
47
|
BasicSoundBank,
|
|
@@ -3,7 +3,7 @@ import { IndexedByteArray } from "../utils/indexed_array.js";
|
|
|
3
3
|
import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd, SpessaSynthInfo } from "../utils/loggin.js";
|
|
4
4
|
import { consoleColors } from "../utils/other.js";
|
|
5
5
|
|
|
6
|
-
import { customControllers } from "../synthetizer/
|
|
6
|
+
import { customControllers } from "../synthetizer/audio_engine/worklet_utilities/controller_tables.js";
|
|
7
7
|
import { DEFAULT_PERCUSSION } from "../synthetizer/synth_constants.js";
|
|
8
8
|
import { isGM2On, isGMOn, isGSOn, isXGOn } from "../utils/sysex_detector.js";
|
|
9
9
|
import { isSystemXG, isXGDrums, XG_SFX_VOICE } from "../utils/xg_hacks.js";
|
package/package.json
CHANGED
package/sequencer/README.md
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ALL_CHANNELS_OR_DIFFERENT_ACTION,
|
|
3
3
|
returnMessageType
|
|
4
|
-
} from "../../synthetizer/
|
|
5
|
-
import {
|
|
4
|
+
} from "../../synthetizer/audio_engine/message_protocol/worklet_message.js";
|
|
5
|
+
import {
|
|
6
|
+
SongChangeType,
|
|
7
|
+
SpessaSynthSequencerMessageType,
|
|
8
|
+
SpessaSynthSequencerReturnMessageType
|
|
9
|
+
} from "../worklet_wrapper/sequencer_message.js";
|
|
6
10
|
import { messageTypes, midiControllers } from "../../midi_parser/midi_message.js";
|
|
7
11
|
|
|
8
12
|
import { MIDI_CHANNEL_COUNT } from "../../synthetizer/synth_constants.js";
|
|
9
13
|
|
|
10
14
|
/**
|
|
11
|
-
* @param messageType {
|
|
15
|
+
* @param messageType {SpessaSynthSequencerMessageType}
|
|
12
16
|
* @param messageData {any}
|
|
13
|
-
* @this {
|
|
17
|
+
* @this {SpessaSynthSequencer}
|
|
14
18
|
*/
|
|
15
19
|
export function processMessage(messageType, messageData)
|
|
16
20
|
{
|
|
@@ -19,35 +23,35 @@ export function processMessage(messageType, messageData)
|
|
|
19
23
|
default:
|
|
20
24
|
break;
|
|
21
25
|
|
|
22
|
-
case
|
|
26
|
+
case SpessaSynthSequencerMessageType.loadNewSongList:
|
|
23
27
|
this.loadNewSongList(messageData[0], messageData[1]);
|
|
24
28
|
break;
|
|
25
29
|
|
|
26
|
-
case
|
|
30
|
+
case SpessaSynthSequencerMessageType.pause:
|
|
27
31
|
this.pause();
|
|
28
32
|
break;
|
|
29
33
|
|
|
30
|
-
case
|
|
34
|
+
case SpessaSynthSequencerMessageType.play:
|
|
31
35
|
this.play(messageData);
|
|
32
36
|
break;
|
|
33
37
|
|
|
34
|
-
case
|
|
38
|
+
case SpessaSynthSequencerMessageType.stop:
|
|
35
39
|
this.stop();
|
|
36
40
|
break;
|
|
37
41
|
|
|
38
|
-
case
|
|
42
|
+
case SpessaSynthSequencerMessageType.setTime:
|
|
39
43
|
this.currentTime = messageData;
|
|
40
44
|
break;
|
|
41
45
|
|
|
42
|
-
case
|
|
46
|
+
case SpessaSynthSequencerMessageType.changeMIDIMessageSending:
|
|
43
47
|
this.sendMIDIMessages = messageData;
|
|
44
48
|
break;
|
|
45
49
|
|
|
46
|
-
case
|
|
50
|
+
case SpessaSynthSequencerMessageType.setPlaybackRate:
|
|
47
51
|
this.playbackRate = messageData;
|
|
48
52
|
break;
|
|
49
53
|
|
|
50
|
-
case
|
|
54
|
+
case SpessaSynthSequencerMessageType.setLoop:
|
|
51
55
|
const [loop, count] = messageData;
|
|
52
56
|
this.loop = loop;
|
|
53
57
|
if (count === ALL_CHANNELS_OR_DIFFERENT_ACTION)
|
|
@@ -60,7 +64,7 @@ export function processMessage(messageType, messageData)
|
|
|
60
64
|
}
|
|
61
65
|
break;
|
|
62
66
|
|
|
63
|
-
case
|
|
67
|
+
case SpessaSynthSequencerMessageType.changeSong:
|
|
64
68
|
switch (messageData[0])
|
|
65
69
|
{
|
|
66
70
|
case SongChangeType.forwards:
|
|
@@ -90,24 +94,24 @@ export function processMessage(messageType, messageData)
|
|
|
90
94
|
}
|
|
91
95
|
break;
|
|
92
96
|
|
|
93
|
-
case
|
|
94
|
-
this.post(
|
|
97
|
+
case SpessaSynthSequencerMessageType.getMIDI:
|
|
98
|
+
this.post(SpessaSynthSequencerReturnMessageType.getMIDI, this.midiData);
|
|
95
99
|
break;
|
|
96
100
|
|
|
97
|
-
case
|
|
101
|
+
case SpessaSynthSequencerMessageType.setSkipToFirstNote:
|
|
98
102
|
this.skipToFirstNoteOn = messageData;
|
|
99
103
|
break;
|
|
100
104
|
|
|
101
|
-
case
|
|
105
|
+
case SpessaSynthSequencerMessageType.setPreservePlaybackState:
|
|
102
106
|
this.preservePlaybackState = messageData;
|
|
103
107
|
}
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
/**
|
|
107
111
|
*
|
|
108
|
-
* @param messageType {
|
|
112
|
+
* @param messageType {SpessaSynthSequencerReturnMessageType}
|
|
109
113
|
* @param messageData {any}
|
|
110
|
-
* @this {
|
|
114
|
+
* @this {SpessaSynthSequencer}
|
|
111
115
|
*/
|
|
112
116
|
export function post(messageType, messageData = undefined)
|
|
113
117
|
{
|
|
@@ -126,15 +130,19 @@ export function post(messageType, messageData = undefined)
|
|
|
126
130
|
|
|
127
131
|
/**
|
|
128
132
|
* @param message {number[]}
|
|
129
|
-
* @this {
|
|
133
|
+
* @this {SpessaSynthSequencer}
|
|
130
134
|
*/
|
|
131
135
|
export function sendMIDIMessage(message)
|
|
132
136
|
{
|
|
133
|
-
this.
|
|
137
|
+
if (!this.sendMIDIMessages)
|
|
138
|
+
{
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
this.post(SpessaSynthSequencerReturnMessageType.midiEvent, message);
|
|
134
142
|
}
|
|
135
143
|
|
|
136
144
|
/**
|
|
137
|
-
* @this {
|
|
145
|
+
* @this {SpessaSynthSequencer}
|
|
138
146
|
* @param channel {number}
|
|
139
147
|
* @param type {number}
|
|
140
148
|
* @param value {number}
|
|
@@ -150,7 +158,7 @@ export function sendMIDICC(channel, type, value)
|
|
|
150
158
|
}
|
|
151
159
|
|
|
152
160
|
/**
|
|
153
|
-
* @this {
|
|
161
|
+
* @this {SpessaSynthSequencer}
|
|
154
162
|
* @param channel {number}
|
|
155
163
|
* @param program {number}
|
|
156
164
|
*/
|
|
@@ -166,7 +174,7 @@ export function sendMIDIProgramChange(channel, program)
|
|
|
166
174
|
|
|
167
175
|
/**
|
|
168
176
|
* Sets the pitch of the given channel
|
|
169
|
-
* @this {
|
|
177
|
+
* @this {SpessaSynthSequencer}
|
|
170
178
|
* @param channel {number} usually 0-15: the channel to change pitch
|
|
171
179
|
* @param MSB {number} SECOND byte of the MIDI pitchWheel message
|
|
172
180
|
* @param LSB {number} FIRST byte of the MIDI pitchWheel message
|
|
@@ -182,7 +190,7 @@ export function sendMIDIPitchWheel(channel, MSB, LSB)
|
|
|
182
190
|
}
|
|
183
191
|
|
|
184
192
|
/**
|
|
185
|
-
* @this {
|
|
193
|
+
* @this {SpessaSynthSequencer}
|
|
186
194
|
*/
|
|
187
195
|
export function sendMIDIReset()
|
|
188
196
|
{
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { getEvent, messageTypes, midiControllers } from "../../midi_parser/midi_message.js";
|
|
2
|
-
import {
|
|
3
|
-
import { resetArray } from "../../synthetizer/
|
|
2
|
+
import { SpessaSynthSequencerReturnMessageType } from "../worklet_wrapper/sequencer_message.js";
|
|
3
|
+
import { resetArray } from "../../synthetizer/audio_engine/worklet_utilities/controller_tables.js";
|
|
4
4
|
import {
|
|
5
5
|
nonResetableCCs
|
|
6
|
-
} from "../../synthetizer/
|
|
6
|
+
} from "../../synthetizer/audio_engine/worklet_methods/controller_control/reset_controllers.js";
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
// an array with preset default values
|
|
@@ -15,7 +15,7 @@ const defaultControllerArray = resetArray.slice(0, 128);
|
|
|
15
15
|
* @param time {number} in seconds
|
|
16
16
|
* @param ticks {number} optional MIDI ticks, when given is used instead of time
|
|
17
17
|
* @returns {boolean} true if the midi file is not finished
|
|
18
|
-
* @this {
|
|
18
|
+
* @this {SpessaSynthSequencer}
|
|
19
19
|
*/
|
|
20
20
|
export function _playTo(time, ticks = undefined)
|
|
21
21
|
{
|
|
@@ -25,7 +25,7 @@ export function _playTo(time, ticks = undefined)
|
|
|
25
25
|
this.sendMIDIReset();
|
|
26
26
|
this._resetTimers();
|
|
27
27
|
|
|
28
|
-
const channelsToSave = this.synth.
|
|
28
|
+
const channelsToSave = this.synth.midiAudioChannels.length;
|
|
29
29
|
/**
|
|
30
30
|
* save pitch bends here and send them only after
|
|
31
31
|
* @type {number[]}
|
|
@@ -281,7 +281,7 @@ export function _playTo(time, ticks = undefined)
|
|
|
281
281
|
/**
|
|
282
282
|
* Starts the playback
|
|
283
283
|
* @param resetTime {boolean} If true, time is set to 0 s
|
|
284
|
-
* @this {
|
|
284
|
+
* @this {SpessaSynthSequencer}
|
|
285
285
|
*/
|
|
286
286
|
export function play(resetTime = false)
|
|
287
287
|
{
|
|
@@ -323,7 +323,7 @@ export function play(resetTime = false)
|
|
|
323
323
|
}
|
|
324
324
|
|
|
325
325
|
/**
|
|
326
|
-
* @this {
|
|
326
|
+
* @this {SpessaSynthSequencer}
|
|
327
327
|
* @param ticks {number}
|
|
328
328
|
*/
|
|
329
329
|
export function setTimeTicks(ticks)
|
|
@@ -332,8 +332,8 @@ export function setTimeTicks(ticks)
|
|
|
332
332
|
this.playingNotes = [];
|
|
333
333
|
this.pausedTime = undefined;
|
|
334
334
|
this.post(
|
|
335
|
-
|
|
336
|
-
|
|
335
|
+
SpessaSynthSequencerReturnMessageType.timeChange,
|
|
336
|
+
this.synth.currentSynthTime - this.midiData.MIDIticksToSeconds(ticks)
|
|
337
337
|
);
|
|
338
338
|
const isNotFinished = this._playTo(0, ticks);
|
|
339
339
|
this._recalculateStartTime(this.playedTime);
|
|
@@ -347,9 +347,9 @@ export function setTimeTicks(ticks)
|
|
|
347
347
|
/**
|
|
348
348
|
* @param time
|
|
349
349
|
* @private
|
|
350
|
-
* @this {
|
|
350
|
+
* @this {SpessaSynthSequencer}
|
|
351
351
|
*/
|
|
352
352
|
export function _recalculateStartTime(time)
|
|
353
353
|
{
|
|
354
|
-
this.absoluteStartTime =
|
|
354
|
+
this.absoluteStartTime = this.synth.currentSynthTime - time / this._playbackRate;
|
|
355
355
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getEvent, messageTypes } from "../../midi_parser/midi_message.js";
|
|
2
|
-
import {
|
|
2
|
+
import { SpessaSynthSequencerReturnMessageType } from "../worklet_wrapper/sequencer_message.js";
|
|
3
3
|
import { consoleColors } from "../../utils/other.js";
|
|
4
4
|
import { SpessaSynthWarn } from "../../utils/loggin.js";
|
|
5
5
|
import { readBytesAsUintBigEndian } from "../../utils/byte_functions/big_endian.js";
|
|
@@ -8,7 +8,7 @@ import { readBytesAsUintBigEndian } from "../../utils/byte_functions/big_endian.
|
|
|
8
8
|
* Processes a single event
|
|
9
9
|
* @param event {MIDIMessage}
|
|
10
10
|
* @param trackIndex {number}
|
|
11
|
-
* @this {
|
|
11
|
+
* @this {SpessaSynthSequencer}
|
|
12
12
|
* @private
|
|
13
13
|
*/
|
|
14
14
|
export function _processEvent(event, trackIndex)
|
|
@@ -149,7 +149,7 @@ export function _processEvent(event, trackIndex)
|
|
|
149
149
|
if (statusByteData.status >= 0 && statusByteData.status < 0x80)
|
|
150
150
|
{
|
|
151
151
|
this.post(
|
|
152
|
-
|
|
152
|
+
SpessaSynthSequencerReturnMessageType.metaEvent,
|
|
153
153
|
[event, trackIndex]
|
|
154
154
|
);
|
|
155
155
|
}
|
|
@@ -157,7 +157,7 @@ export function _processEvent(event, trackIndex)
|
|
|
157
157
|
|
|
158
158
|
/**
|
|
159
159
|
* Adds 16 channels to the synth
|
|
160
|
-
* @this {
|
|
160
|
+
* @this {SpessaSynthSequencer}
|
|
161
161
|
* @private
|
|
162
162
|
*/
|
|
163
163
|
export function _addNewMidiPort()
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SpessaSynthSequencerReturnMessageType } from "../worklet_wrapper/sequencer_message.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Processes a single tick
|
|
5
|
-
* @this {
|
|
5
|
+
* @this {SpessaSynthSequencer}
|
|
6
6
|
*/
|
|
7
7
|
export function processTick()
|
|
8
8
|
{
|
|
@@ -50,7 +50,7 @@ export function processTick()
|
|
|
50
50
|
if (this.loopCount !== Infinity)
|
|
51
51
|
{
|
|
52
52
|
this.loopCount--;
|
|
53
|
-
this.post(
|
|
53
|
+
this.post(SpessaSynthSequencerReturnMessageType.loopCountChange, this.loopCount);
|
|
54
54
|
}
|
|
55
55
|
this.setTimeTicks(this.midiData.loop.start);
|
|
56
56
|
return;
|
|
@@ -64,7 +64,7 @@ export function processTick()
|
|
|
64
64
|
if (this.loopCount !== Infinity)
|
|
65
65
|
{
|
|
66
66
|
this.loopCount--;
|
|
67
|
-
this.post(
|
|
67
|
+
this.post(SpessaSynthSequencerReturnMessageType.loopCountChange, this.loopCount);
|
|
68
68
|
}
|
|
69
69
|
this.setTimeTicks(this.midiData.loop.start);
|
|
70
70
|
return;
|
|
@@ -84,7 +84,7 @@ export function processTick()
|
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
86
|
* @returns {number} the index of the first to the current played time
|
|
87
|
-
* @this {
|
|
87
|
+
* @this {SpessaSynthSequencer}
|
|
88
88
|
*/
|
|
89
89
|
export function _findFirstEventIndex()
|
|
90
90
|
{
|
package/sequencer/{worklet_sequencer/worklet_sequencer.js → sequencer_engine/sequencer_engine.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SpessaSynthSequencerReturnMessageType } from "../worklet_wrapper/sequencer_message.js";
|
|
2
2
|
import { _addNewMidiPort, _processEvent } from "./process_event.js";
|
|
3
3
|
import { _findFirstEventIndex, processTick } from "./process_tick.js";
|
|
4
4
|
import { assignMIDIPort, loadNewSequence, loadNewSongList, nextSong, previousSong } from "./song_control.js";
|
|
@@ -17,7 +17,7 @@ import { SpessaSynthWarn } from "../../utils/loggin.js";
|
|
|
17
17
|
|
|
18
18
|
import { MIDI_CHANNEL_COUNT } from "../../synthetizer/synth_constants.js";
|
|
19
19
|
|
|
20
|
-
class
|
|
20
|
+
class SpessaSynthSequencer
|
|
21
21
|
{
|
|
22
22
|
/**
|
|
23
23
|
* All the sequencer's songs
|
|
@@ -83,7 +83,7 @@ class WorkletSequencer
|
|
|
83
83
|
* Absolute playback startTime, bases on the synth's time
|
|
84
84
|
* @type {number}
|
|
85
85
|
*/
|
|
86
|
-
absoluteStartTime =
|
|
86
|
+
absoluteStartTime = 0;
|
|
87
87
|
/**
|
|
88
88
|
* Currently playing notes (for pausing and resuming)
|
|
89
89
|
* @type {{
|
|
@@ -142,6 +142,7 @@ class WorkletSequencer
|
|
|
142
142
|
constructor(spessasynthProcessor)
|
|
143
143
|
{
|
|
144
144
|
this.synth = spessasynthProcessor;
|
|
145
|
+
this.absoluteStartTime = this.synth.currentSynthTime;
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
/**
|
|
@@ -169,7 +170,7 @@ class WorkletSequencer
|
|
|
169
170
|
return this.pausedTime;
|
|
170
171
|
}
|
|
171
172
|
|
|
172
|
-
return (
|
|
173
|
+
return (this.synth.currentSynthTime - this.absoluteStartTime) * this._playbackRate;
|
|
173
174
|
}
|
|
174
175
|
|
|
175
176
|
set currentTime(time)
|
|
@@ -199,11 +200,11 @@ class WorkletSequencer
|
|
|
199
200
|
this.playingNotes = [];
|
|
200
201
|
const wasPaused = this.paused && this.preservePlaybackState;
|
|
201
202
|
this.pausedTime = undefined;
|
|
202
|
-
this.post(
|
|
203
|
+
this.post(SpessaSynthSequencerReturnMessageType.timeChange, this.synth.currentSynthTime - time);
|
|
203
204
|
if (this.midiData.duration === 0)
|
|
204
205
|
{
|
|
205
206
|
SpessaSynthWarn("No duration!");
|
|
206
|
-
this.post(
|
|
207
|
+
this.post(SpessaSynthSequencerReturnMessageType.pause, true);
|
|
207
208
|
return;
|
|
208
209
|
}
|
|
209
210
|
this._playTo(time);
|
|
@@ -240,7 +241,7 @@ class WorkletSequencer
|
|
|
240
241
|
}
|
|
241
242
|
this.pausedTime = this.currentTime;
|
|
242
243
|
this.stop();
|
|
243
|
-
this.post(
|
|
244
|
+
this.post(SpessaSynthSequencerReturnMessageType.pause, isFinished);
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
/**
|
|
@@ -308,29 +309,29 @@ class WorkletSequencer
|
|
|
308
309
|
}
|
|
309
310
|
|
|
310
311
|
// Web MIDI sending
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
312
|
+
SpessaSynthSequencer.prototype.sendMIDIMessage = sendMIDIMessage;
|
|
313
|
+
SpessaSynthSequencer.prototype.sendMIDIReset = sendMIDIReset;
|
|
314
|
+
SpessaSynthSequencer.prototype.sendMIDICC = sendMIDICC;
|
|
315
|
+
SpessaSynthSequencer.prototype.sendMIDIProgramChange = sendMIDIProgramChange;
|
|
316
|
+
SpessaSynthSequencer.prototype.sendMIDIPitchWheel = sendMIDIPitchWheel;
|
|
317
|
+
SpessaSynthSequencer.prototype.assignMIDIPort = assignMIDIPort;
|
|
317
318
|
|
|
318
|
-
|
|
319
|
-
|
|
319
|
+
SpessaSynthSequencer.prototype.post = post;
|
|
320
|
+
SpessaSynthSequencer.prototype.processMessage = processMessage;
|
|
320
321
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
322
|
+
SpessaSynthSequencer.prototype._processEvent = _processEvent;
|
|
323
|
+
SpessaSynthSequencer.prototype._addNewMidiPort = _addNewMidiPort;
|
|
324
|
+
SpessaSynthSequencer.prototype.processTick = processTick;
|
|
325
|
+
SpessaSynthSequencer.prototype._findFirstEventIndex = _findFirstEventIndex;
|
|
325
326
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
327
|
+
SpessaSynthSequencer.prototype.loadNewSequence = loadNewSequence;
|
|
328
|
+
SpessaSynthSequencer.prototype.loadNewSongList = loadNewSongList;
|
|
329
|
+
SpessaSynthSequencer.prototype.nextSong = nextSong;
|
|
330
|
+
SpessaSynthSequencer.prototype.previousSong = previousSong;
|
|
330
331
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
332
|
+
SpessaSynthSequencer.prototype.play = play;
|
|
333
|
+
SpessaSynthSequencer.prototype._playTo = _playTo;
|
|
334
|
+
SpessaSynthSequencer.prototype.setTimeTicks = setTimeTicks;
|
|
335
|
+
SpessaSynthSequencer.prototype._recalculateStartTime = _recalculateStartTime;
|
|
335
336
|
|
|
336
|
-
export {
|
|
337
|
+
export { SpessaSynthSequencer };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SpessaSynthSequencerReturnMessageType } from "../worklet_wrapper/sequencer_message.js";
|
|
2
2
|
import { consoleColors, formatTime } from "../../utils/other.js";
|
|
3
3
|
import {
|
|
4
4
|
SpessaSynthGroupCollapsed,
|
|
@@ -14,7 +14,7 @@ import { BasicMIDI } from "../../midi_parser/basic_midi.js";
|
|
|
14
14
|
/**
|
|
15
15
|
* @param trackNum {number}
|
|
16
16
|
* @param port {number}
|
|
17
|
-
* @this {
|
|
17
|
+
* @this {SpessaSynthSequencer}
|
|
18
18
|
*/
|
|
19
19
|
export function assignMIDIPort(trackNum, port)
|
|
20
20
|
{
|
|
@@ -33,7 +33,7 @@ export function assignMIDIPort(trackNum, port)
|
|
|
33
33
|
|
|
34
34
|
if (this.midiPortChannelOffsets[port] === undefined)
|
|
35
35
|
{
|
|
36
|
-
if (this.synth.
|
|
36
|
+
if (this.synth.midiAudioChannels.length < this.midiPortChannelOffset + 15)
|
|
37
37
|
{
|
|
38
38
|
this._addNewMidiPort();
|
|
39
39
|
}
|
|
@@ -48,7 +48,7 @@ export function assignMIDIPort(trackNum, port)
|
|
|
48
48
|
* Loads a new sequence
|
|
49
49
|
* @param parsedMidi {BasicMIDI}
|
|
50
50
|
* @param autoPlay {boolean}
|
|
51
|
-
* @this {
|
|
51
|
+
* @this {SpessaSynthSequencer}
|
|
52
52
|
*/
|
|
53
53
|
export function loadNewSequence(parsedMidi, autoPlay = true)
|
|
54
54
|
{
|
|
@@ -127,7 +127,7 @@ export function loadNewSequence(parsedMidi, autoPlay = true)
|
|
|
127
127
|
this.firstNoteTime = this.midiData.MIDIticksToSeconds(this.midiData.firstNoteOn);
|
|
128
128
|
SpessaSynthInfo(`%cTotal song time: ${formatTime(Math.ceil(this.duration)).time}`, consoleColors.recognized);
|
|
129
129
|
|
|
130
|
-
this.post(
|
|
130
|
+
this.post(SpessaSynthSequencerReturnMessageType.songChange, [this.songIndex, autoPlay]);
|
|
131
131
|
|
|
132
132
|
if (this.duration <= 1)
|
|
133
133
|
{
|
|
@@ -153,7 +153,7 @@ export function loadNewSequence(parsedMidi, autoPlay = true)
|
|
|
153
153
|
/**
|
|
154
154
|
* @param midiBuffers {MIDIFile[]}
|
|
155
155
|
* @param autoPlay {boolean}
|
|
156
|
-
* @this {
|
|
156
|
+
* @this {SpessaSynthSequencer}
|
|
157
157
|
*/
|
|
158
158
|
export function loadNewSongList(midiBuffers, autoPlay = true)
|
|
159
159
|
{
|
|
@@ -175,7 +175,7 @@ export function loadNewSongList(midiBuffers, autoPlay = true)
|
|
|
175
175
|
catch (e)
|
|
176
176
|
{
|
|
177
177
|
console.error(e);
|
|
178
|
-
this.post(
|
|
178
|
+
this.post(SpessaSynthSequencerReturnMessageType.midiError, e);
|
|
179
179
|
return mids;
|
|
180
180
|
}
|
|
181
181
|
return mids;
|
|
@@ -191,12 +191,12 @@ export function loadNewSongList(midiBuffers, autoPlay = true)
|
|
|
191
191
|
}
|
|
192
192
|
this.shuffleSongIndexes();
|
|
193
193
|
const midiDatas = this.songs.map(s => new MIDIData(s));
|
|
194
|
-
this.post(
|
|
194
|
+
this.post(SpessaSynthSequencerReturnMessageType.songListChange, midiDatas);
|
|
195
195
|
this.loadCurrentSong(autoPlay);
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
/**
|
|
199
|
-
* @this {
|
|
199
|
+
* @this {SpessaSynthSequencer}
|
|
200
200
|
*/
|
|
201
201
|
export function nextSong()
|
|
202
202
|
{
|
|
@@ -211,7 +211,7 @@ export function nextSong()
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
/**
|
|
214
|
-
* @this {
|
|
214
|
+
* @this {SpessaSynthSequencer}
|
|
215
215
|
*/
|
|
216
216
|
export function previousSong()
|
|
217
217
|
{
|