spessasynth_lib 3.25.22 → 3.25.23
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/package.json +1 -1
- package/sequencer/sequencer_engine/events.js +2 -105
- package/sequencer/sequencer_engine/sequencer_engine.js +0 -2
- package/synthetizer/audio_engine/engine_components/{soundfont_manager/soundfont_manager.js → soundfont_manager.js} +3 -29
- package/synthetizer/audio_engine/engine_components/voice.js +5 -5
- package/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +1 -1
- package/synthetizer/audio_engine/engine_methods/note_on.js +3 -2
- package/synthetizer/audio_engine/engine_methods/system_exclusive.js +33 -1
- package/synthetizer/audio_engine/main_processor.js +2 -2
- package/synthetizer/worklet_processor.min.js +12 -12
- package/synthetizer/{audio_engine/engine_components/soundfont_manager → worklet_wrapper}/sfman_message.js +1 -1
- package/synthetizer/worklet_wrapper/synth_soundfont_manager.js +1 -3
- package/synthetizer/worklet_wrapper/worklet_processor.js +116 -2
package/package.json
CHANGED
|
@@ -1,112 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
returnMessageType
|
|
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";
|
|
1
|
+
import { returnMessageType } from "../../synthetizer/audio_engine/message_protocol/worklet_message.js";
|
|
2
|
+
import { SpessaSynthSequencerReturnMessageType } from "../worklet_wrapper/sequencer_message.js";
|
|
10
3
|
import { messageTypes, midiControllers } from "../../midi/midi_message.js";
|
|
11
4
|
|
|
12
5
|
import { MIDI_CHANNEL_COUNT } from "../../synthetizer/synth_constants.js";
|
|
13
6
|
|
|
14
|
-
/**
|
|
15
|
-
* @param messageType {SpessaSynthSequencerMessageType}
|
|
16
|
-
* @param messageData {any}
|
|
17
|
-
* @this {SpessaSynthSequencer}
|
|
18
|
-
*/
|
|
19
|
-
export function processMessage(messageType, messageData)
|
|
20
|
-
{
|
|
21
|
-
switch (messageType)
|
|
22
|
-
{
|
|
23
|
-
default:
|
|
24
|
-
break;
|
|
25
|
-
|
|
26
|
-
case SpessaSynthSequencerMessageType.loadNewSongList:
|
|
27
|
-
this.loadNewSongList(messageData[0], messageData[1]);
|
|
28
|
-
break;
|
|
29
|
-
|
|
30
|
-
case SpessaSynthSequencerMessageType.pause:
|
|
31
|
-
this.pause();
|
|
32
|
-
break;
|
|
33
|
-
|
|
34
|
-
case SpessaSynthSequencerMessageType.play:
|
|
35
|
-
this.play(messageData);
|
|
36
|
-
break;
|
|
37
|
-
|
|
38
|
-
case SpessaSynthSequencerMessageType.stop:
|
|
39
|
-
this.stop();
|
|
40
|
-
break;
|
|
41
|
-
|
|
42
|
-
case SpessaSynthSequencerMessageType.setTime:
|
|
43
|
-
this.currentTime = messageData;
|
|
44
|
-
break;
|
|
45
|
-
|
|
46
|
-
case SpessaSynthSequencerMessageType.changeMIDIMessageSending:
|
|
47
|
-
this.sendMIDIMessages = messageData;
|
|
48
|
-
break;
|
|
49
|
-
|
|
50
|
-
case SpessaSynthSequencerMessageType.setPlaybackRate:
|
|
51
|
-
this.playbackRate = messageData;
|
|
52
|
-
break;
|
|
53
|
-
|
|
54
|
-
case SpessaSynthSequencerMessageType.setLoop:
|
|
55
|
-
const [loop, count] = messageData;
|
|
56
|
-
this.loop = loop;
|
|
57
|
-
if (count === ALL_CHANNELS_OR_DIFFERENT_ACTION)
|
|
58
|
-
{
|
|
59
|
-
this.loopCount = Infinity;
|
|
60
|
-
}
|
|
61
|
-
else
|
|
62
|
-
{
|
|
63
|
-
this.loopCount = count;
|
|
64
|
-
}
|
|
65
|
-
break;
|
|
66
|
-
|
|
67
|
-
case SpessaSynthSequencerMessageType.changeSong:
|
|
68
|
-
switch (messageData[0])
|
|
69
|
-
{
|
|
70
|
-
case SongChangeType.forwards:
|
|
71
|
-
this.nextSong();
|
|
72
|
-
break;
|
|
73
|
-
|
|
74
|
-
case SongChangeType.backwards:
|
|
75
|
-
this.previousSong();
|
|
76
|
-
break;
|
|
77
|
-
|
|
78
|
-
case SongChangeType.shuffleOff:
|
|
79
|
-
this.shuffleMode = false;
|
|
80
|
-
this.songIndex = this.shuffledSongIndexes[this.songIndex];
|
|
81
|
-
break;
|
|
82
|
-
|
|
83
|
-
case SongChangeType.shuffleOn:
|
|
84
|
-
this.shuffleMode = true;
|
|
85
|
-
this.shuffleSongIndexes();
|
|
86
|
-
this.songIndex = 0;
|
|
87
|
-
this.loadCurrentSong();
|
|
88
|
-
break;
|
|
89
|
-
|
|
90
|
-
case SongChangeType.index:
|
|
91
|
-
this.songIndex = messageData[1];
|
|
92
|
-
this.loadCurrentSong();
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
break;
|
|
96
|
-
|
|
97
|
-
case SpessaSynthSequencerMessageType.getMIDI:
|
|
98
|
-
this.post(SpessaSynthSequencerReturnMessageType.getMIDI, this.midiData);
|
|
99
|
-
break;
|
|
100
|
-
|
|
101
|
-
case SpessaSynthSequencerMessageType.setSkipToFirstNote:
|
|
102
|
-
this.skipToFirstNoteOn = messageData;
|
|
103
|
-
break;
|
|
104
|
-
|
|
105
|
-
case SpessaSynthSequencerMessageType.setPreservePlaybackState:
|
|
106
|
-
this.preservePlaybackState = messageData;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
7
|
/**
|
|
111
8
|
*
|
|
112
9
|
* @param messageType {SpessaSynthSequencerReturnMessageType}
|
|
@@ -6,7 +6,6 @@ import { _playTo, _recalculateStartTime, play, setTimeTicks } from "./play.js";
|
|
|
6
6
|
import { messageTypes, midiControllers } from "../../midi/midi_message.js";
|
|
7
7
|
import {
|
|
8
8
|
post,
|
|
9
|
-
processMessage,
|
|
10
9
|
sendMIDICC,
|
|
11
10
|
sendMIDIMessage,
|
|
12
11
|
sendMIDIPitchWheel,
|
|
@@ -317,7 +316,6 @@ SpessaSynthSequencer.prototype.sendMIDIPitchWheel = sendMIDIPitchWheel;
|
|
|
317
316
|
SpessaSynthSequencer.prototype.assignMIDIPort = assignMIDIPort;
|
|
318
317
|
|
|
319
318
|
SpessaSynthSequencer.prototype.post = post;
|
|
320
|
-
SpessaSynthSequencer.prototype.processMessage = processMessage;
|
|
321
319
|
|
|
322
320
|
SpessaSynthSequencer.prototype._processEvent = _processEvent;
|
|
323
321
|
SpessaSynthSequencer.prototype._addNewMidiPort = _addNewMidiPort;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { SpessaSynthWarn } from "
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { isXGDrums } from "../../../../utils/xg_hacks.js";
|
|
1
|
+
import { SpessaSynthWarn } from "../../../utils/loggin.js";
|
|
2
|
+
import { loadSoundFont } from "../../../soundfont/load_soundfont.js";
|
|
3
|
+
import { isXGDrums } from "../../../utils/xg_hacks.js";
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* @typedef {Object} SoundFontType
|
|
@@ -70,31 +69,6 @@ export class WorkletSoundfontManager
|
|
|
70
69
|
}
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
/**
|
|
74
|
-
* @param type {WorkletSoundfontManagerMessageType}
|
|
75
|
-
* @param data {any}
|
|
76
|
-
*/
|
|
77
|
-
handleMessage(type, data)
|
|
78
|
-
{
|
|
79
|
-
switch (type)
|
|
80
|
-
{
|
|
81
|
-
case WorkletSoundfontManagerMessageType.addNewSoundFont:
|
|
82
|
-
this.addNewSoundFont(data[0], data[1], data[2]);
|
|
83
|
-
break;
|
|
84
|
-
|
|
85
|
-
case WorkletSoundfontManagerMessageType.reloadSoundFont:
|
|
86
|
-
this.reloadManager(data);
|
|
87
|
-
break;
|
|
88
|
-
|
|
89
|
-
case WorkletSoundfontManagerMessageType.deleteSoundFont:
|
|
90
|
-
this.deleteSoundFont(data);
|
|
91
|
-
break;
|
|
92
|
-
|
|
93
|
-
case WorkletSoundfontManagerMessageType.rearrangeSoundFonts:
|
|
94
|
-
this.rearrangeSoundFonts(data);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
72
|
/**
|
|
99
73
|
* Get the final preset list
|
|
100
74
|
* @returns {{bank: number, presetName: string, program: number}[]}
|
|
@@ -313,9 +313,10 @@ class Voice
|
|
|
313
313
|
* copies the voice
|
|
314
314
|
* @param voice {Voice}
|
|
315
315
|
* @param currentTime {number}
|
|
316
|
+
* @param realKey {number}
|
|
316
317
|
* @returns Voice
|
|
317
318
|
*/
|
|
318
|
-
static copy(voice, currentTime)
|
|
319
|
+
static copy(voice, currentTime, realKey)
|
|
319
320
|
{
|
|
320
321
|
const sampleToCopy = voice.sample;
|
|
321
322
|
const sample = new AudioSample(
|
|
@@ -336,7 +337,7 @@ class Voice
|
|
|
336
337
|
voice.channelNumber,
|
|
337
338
|
currentTime,
|
|
338
339
|
voice.targetKey,
|
|
339
|
-
|
|
340
|
+
realKey,
|
|
340
341
|
voice.generators,
|
|
341
342
|
voice.modulators.map(m => Modulator.copy(m))
|
|
342
343
|
);
|
|
@@ -403,11 +404,10 @@ export function getVoices(channel,
|
|
|
403
404
|
}
|
|
404
405
|
|
|
405
406
|
const cached = this.getCachedVoice(bank, program, midiNote, velocity);
|
|
406
|
-
|
|
407
407
|
// if cached, return it!
|
|
408
408
|
if (cached !== undefined)
|
|
409
409
|
{
|
|
410
|
-
return cached.map(v => Voice.copy(v, this.currentSynthTime));
|
|
410
|
+
return cached.map(v => Voice.copy(v, this.currentSynthTime, realKey));
|
|
411
411
|
}
|
|
412
412
|
|
|
413
413
|
// not cached...
|
|
@@ -514,6 +514,6 @@ export function getVoices(channel,
|
|
|
514
514
|
}, []);
|
|
515
515
|
// cache the voice
|
|
516
516
|
this.setCachedVoice(bank, program, midiNote, velocity, voices.map(v =>
|
|
517
|
-
Voice.copy(v, this.currentSynthTime)));
|
|
517
|
+
Voice.copy(v, this.currentSynthTime, realKey)));
|
|
518
518
|
return voices;
|
|
519
519
|
}
|
|
@@ -35,9 +35,10 @@ export function noteOn(midiNote, velocity)
|
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
const program = this.preset.program;
|
|
38
|
-
|
|
38
|
+
const tune = this.synth.tunings[program]?.[realKey]?.midiNote;
|
|
39
|
+
if (tune >= 0)
|
|
39
40
|
{
|
|
40
|
-
sentMidiNote =
|
|
41
|
+
sentMidiNote = tune;
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
// velocity override
|
|
@@ -4,6 +4,7 @@ import { midiControllers } from "../../../midi/midi_message.js";
|
|
|
4
4
|
import { ALL_CHANNELS_OR_DIFFERENT_ACTION } from "../message_protocol/worklet_message.js";
|
|
5
5
|
import { isSystemXG } from "../../../utils/xg_hacks.js";
|
|
6
6
|
import { masterParameterType } from "./controller_control/master_parameters.js";
|
|
7
|
+
import { readBytesAsString } from "../../../utils/byte_functions/string.js";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* KeyNum: tuning
|
|
@@ -167,13 +168,44 @@ export function systemExclusive(messageData, channelOffset = 0)
|
|
|
167
168
|
// MIDI Tuning standard
|
|
168
169
|
// https://midi.org/midi-tuning-updated-specification
|
|
169
170
|
case 0x08:
|
|
171
|
+
let currentMessageIndex = 4;
|
|
170
172
|
switch (messageData[3])
|
|
171
173
|
{
|
|
174
|
+
// bulk tuning dump: all 128 notes
|
|
175
|
+
case 0x01:
|
|
176
|
+
const program = messageData[currentMessageIndex++];
|
|
177
|
+
// read the name
|
|
178
|
+
messageData.currentIndex = currentMessageIndex;
|
|
179
|
+
const tuningName = readBytesAsString(messageData, 16);
|
|
180
|
+
currentMessageIndex += 16;
|
|
181
|
+
if (messageData.length < 384)
|
|
182
|
+
{
|
|
183
|
+
SpessaSynthWarn(`The Bulk Tuning Dump is too short! (${messageData.length} bytes, at least 384 are expected)`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// 128 frequencies follow
|
|
187
|
+
for (let i = 0; i < 128; i++)
|
|
188
|
+
{
|
|
189
|
+
// set the given tuning to the program
|
|
190
|
+
this.tunings[program][i] = getTuning(
|
|
191
|
+
messageData[currentMessageIndex++],
|
|
192
|
+
messageData[currentMessageIndex++],
|
|
193
|
+
messageData[currentMessageIndex++]
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
SpessaSynthInfo(
|
|
197
|
+
`%cBulk Tuning Dump %c${tuningName}%c Program: %c${program}`,
|
|
198
|
+
consoleColors.info,
|
|
199
|
+
consoleColors.value,
|
|
200
|
+
consoleColors.info,
|
|
201
|
+
consoleColors.recognized
|
|
202
|
+
);
|
|
203
|
+
break;
|
|
204
|
+
|
|
172
205
|
// single note change
|
|
173
206
|
// single note change bank
|
|
174
207
|
case 0x02:
|
|
175
208
|
case 0x07:
|
|
176
|
-
let currentMessageIndex = 4;
|
|
177
209
|
if (messageData[3] === 0x07)
|
|
178
210
|
{
|
|
179
211
|
// skip the bank
|
|
@@ -9,7 +9,7 @@ import { callEvent } from "./message_protocol/message_sending.js";
|
|
|
9
9
|
import { systemExclusive } from "./engine_methods/system_exclusive.js";
|
|
10
10
|
import { masterParameterType, setMasterParameter } from "./engine_methods/controller_control/master_parameters.js";
|
|
11
11
|
import { resetAllControllers } from "./engine_methods/controller_control/reset_controllers.js";
|
|
12
|
-
import { WorkletSoundfontManager } from "./engine_components/soundfont_manager
|
|
12
|
+
import { WorkletSoundfontManager } from "./engine_components/soundfont_manager.js";
|
|
13
13
|
import { interpolationTypes } from "./engine_components/wavetable_oscillator.js";
|
|
14
14
|
import { KeyModifierManager } from "./engine_components/key_modifier_manager.js";
|
|
15
15
|
import { getVoices } from "./engine_components/voice.js";
|
|
@@ -269,7 +269,7 @@ class SpessaSynthProcessor
|
|
|
269
269
|
this.enableEventSystem = enableEventSystem && typeof postCallback === "function";
|
|
270
270
|
|
|
271
271
|
|
|
272
|
-
for (let i = 0; i <
|
|
272
|
+
for (let i = 0; i < 128; i++)
|
|
273
273
|
{
|
|
274
274
|
this.tunings.push([]);
|
|
275
275
|
}
|