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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spessasynth_lib",
3
- "version": "3.25.22",
3
+ "version": "3.25.23",
4
4
  "description": "MIDI and SoundFont2/DLS library with no compromises",
5
5
  "browser": "index.js",
6
6
  "type": "module",
@@ -1,112 +1,9 @@
1
- import {
2
- ALL_CHANNELS_OR_DIFFERENT_ACTION,
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 "../../../../utils/loggin.js";
2
- import { WorkletSoundfontManagerMessageType } from "./sfman_message.js";
3
- import { loadSoundFont } from "../../../../soundfont/load_soundfont.js";
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
- voice.realKey,
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
  }
@@ -109,7 +109,7 @@ export function resetAllControllers(log = true)
109
109
  }
110
110
  this.tunings = [];
111
111
  this.tunings = [];
112
- for (let i = 0; 127 > i; i++)
112
+ for (let i = 0; i < 128; i++)
113
113
  {
114
114
  this.tunings.push([]);
115
115
  }
@@ -35,9 +35,10 @@ export function noteOn(midiNote, velocity)
35
35
  return;
36
36
  }
37
37
  const program = this.preset.program;
38
- if (this.synth.tunings[program]?.[realKey]?.midiNote >= 0)
38
+ const tune = this.synth.tunings[program]?.[realKey]?.midiNote;
39
+ if (tune >= 0)
39
40
  {
40
- sentMidiNote = this.synth.tunings[program]?.[realKey].midiNote;
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/soundfont_manager.js";
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 < 127; i++)
272
+ for (let i = 0; i < 128; i++)
273
273
  {
274
274
  this.tunings.push([]);
275
275
  }