spessasynth_core 3.26.35 → 3.26.36
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/src/soundfont/basic_soundfont/basic_instrument.js +4 -2
- package/src/soundfont/basic_soundfont/basic_sample.js +3 -2
- package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +2 -3
- package/src/synthetizer/audio_engine/engine_components/voice.js +8 -2
- package/src/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +8 -4
- package/src/synthetizer/audio_engine/engine_methods/note_on.js +8 -1
- package/src/synthetizer/audio_engine/engine_methods/program_change.js +10 -1
- package/src/synthetizer/audio_engine/engine_methods/render_voice.js +1 -1
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BasicGlobalZone } from "./basic_global_zone.js";
|
|
2
2
|
import { BasicInstrumentZone } from "./basic_instrument_zone.js";
|
|
3
|
+
import { SpessaSynthWarn } from "../../utils/loggin.js";
|
|
3
4
|
|
|
4
5
|
export class BasicInstrument
|
|
5
6
|
{
|
|
@@ -64,7 +65,8 @@ export class BasicInstrument
|
|
|
64
65
|
const index = this.linkedPresets.indexOf(preset);
|
|
65
66
|
if (index < 0)
|
|
66
67
|
{
|
|
67
|
-
|
|
68
|
+
SpessaSynthWarn(`Cannot unlink ${preset.presetName} from ${this.instrumentName}: not linked.`);
|
|
69
|
+
return;
|
|
68
70
|
}
|
|
69
71
|
this.linkedPresets.splice(index, 1);
|
|
70
72
|
this.instrumentZones.forEach(z => z.useCount--);
|
|
@@ -87,7 +89,7 @@ export class BasicInstrument
|
|
|
87
89
|
{
|
|
88
90
|
if (this.useCount > 0)
|
|
89
91
|
{
|
|
90
|
-
throw new Error(`Cannot delete an instrument that
|
|
92
|
+
throw new Error(`Cannot delete an instrument that is used by: ${this.linkedPresets.map(p => p.presetName)}.`);
|
|
91
93
|
}
|
|
92
94
|
this.instrumentZones.forEach(z => z.deleteZone());
|
|
93
95
|
this.instrumentZones.length = 0;
|
|
@@ -249,7 +249,7 @@ export class BasicSample
|
|
|
249
249
|
{
|
|
250
250
|
if (this.useCount > 0)
|
|
251
251
|
{
|
|
252
|
-
throw new Error(`Cannot delete sample
|
|
252
|
+
throw new Error(`Cannot delete sample used by: ${this.linkedInstruments.map(i => i.instrumentName)}.`);
|
|
253
253
|
}
|
|
254
254
|
this.unlinkSample();
|
|
255
255
|
}
|
|
@@ -310,7 +310,8 @@ export class BasicSample
|
|
|
310
310
|
const index = this.linkedInstruments.indexOf(instrument);
|
|
311
311
|
if (index < 0)
|
|
312
312
|
{
|
|
313
|
-
|
|
313
|
+
SpessaSynthWarn(`Cannot unlink ${instrument.instrumentName} from ${this.sampleName}: not linked.`);
|
|
314
|
+
return;
|
|
314
315
|
}
|
|
315
316
|
this.linkedInstruments.splice(index, 1);
|
|
316
317
|
}
|
|
@@ -166,7 +166,7 @@ class MidiAudioChannel
|
|
|
166
166
|
|
|
167
167
|
/**
|
|
168
168
|
* The preset currently assigned to the channel.
|
|
169
|
-
* @type {BasicPreset}
|
|
169
|
+
* @type {?BasicPreset}
|
|
170
170
|
*/
|
|
171
171
|
preset = undefined;
|
|
172
172
|
|
|
@@ -364,7 +364,6 @@ class MidiAudioChannel
|
|
|
364
364
|
{
|
|
365
365
|
return;
|
|
366
366
|
}
|
|
367
|
-
delete this.preset;
|
|
368
367
|
this.preset = preset;
|
|
369
368
|
}
|
|
370
369
|
|
|
@@ -464,7 +463,7 @@ class MidiAudioChannel
|
|
|
464
463
|
isDrum: this.drumChannel,
|
|
465
464
|
transposition: this.channelTransposeKeyShift + this.customControllers[customControllers.channelTransposeFine] / 100,
|
|
466
465
|
bank: this.sentBank,
|
|
467
|
-
program: this.preset
|
|
466
|
+
program: this.preset?.program
|
|
468
467
|
};
|
|
469
468
|
this.synth?.onChannelPropertyChange?.(data, this.channelNumber);
|
|
470
469
|
}
|
|
@@ -491,7 +491,14 @@ export function getVoices(channel, midiNote, velocity, realKey)
|
|
|
491
491
|
const overridePatch = this.keyModifierManager.hasOverridePatch(channel, midiNote);
|
|
492
492
|
|
|
493
493
|
let bank = channelObject.getBankSelect();
|
|
494
|
-
|
|
494
|
+
|
|
495
|
+
let preset = channelObject.preset;
|
|
496
|
+
if (!preset)
|
|
497
|
+
{
|
|
498
|
+
SpessaSynthWarn(`No preset for channel ${channel}!`);
|
|
499
|
+
return [];
|
|
500
|
+
}
|
|
501
|
+
let program = preset.program;
|
|
495
502
|
if (overridePatch)
|
|
496
503
|
{
|
|
497
504
|
const override = this.keyModifierManager.getPatch(channel, midiNote);
|
|
@@ -507,7 +514,6 @@ export function getVoices(channel, midiNote, velocity, realKey)
|
|
|
507
514
|
}
|
|
508
515
|
|
|
509
516
|
// not cached...
|
|
510
|
-
let preset = channelObject.preset;
|
|
511
517
|
if (overridePatch)
|
|
512
518
|
{
|
|
513
519
|
preset = this.getPreset(bank, program);
|
|
@@ -29,13 +29,17 @@ export function resetAllControllers(log = true)
|
|
|
29
29
|
this.setSystem(DEFAULT_SYNTH_MODE);
|
|
30
30
|
for (let channelNumber = 0; channelNumber < this.midiAudioChannels.length; channelNumber++)
|
|
31
31
|
{
|
|
32
|
-
this.midiAudioChannels[channelNumber].resetControllers();
|
|
33
|
-
|
|
34
32
|
/**
|
|
35
33
|
* @type {MidiAudioChannel}
|
|
36
34
|
**/
|
|
37
35
|
const ch = this.midiAudioChannels[channelNumber];
|
|
38
36
|
|
|
37
|
+
ch.resetControllers();
|
|
38
|
+
// safety net
|
|
39
|
+
if (!ch.preset)
|
|
40
|
+
{
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
39
43
|
// if preset is unlocked, switch to non-drums and call event
|
|
40
44
|
if (!ch.lockPreset)
|
|
41
45
|
{
|
|
@@ -67,11 +71,11 @@ export function resetAllControllers(log = true)
|
|
|
67
71
|
});
|
|
68
72
|
}
|
|
69
73
|
|
|
70
|
-
const presetBank = ch.preset
|
|
74
|
+
const presetBank = ch.preset?.bank;
|
|
71
75
|
// call program change
|
|
72
76
|
this.callEvent("programchange", {
|
|
73
77
|
channel: channelNumber,
|
|
74
|
-
program: ch.preset
|
|
78
|
+
program: ch.preset?.program,
|
|
75
79
|
bank: presetBank
|
|
76
80
|
});
|
|
77
81
|
|
|
@@ -4,6 +4,7 @@ import { customControllers } from "../engine_components/controller_tables.js";
|
|
|
4
4
|
import { Modulator } from "../../../soundfont/basic_soundfont/modulator.js";
|
|
5
5
|
import { GENERATOR_OVERRIDE_NO_CHANGE_VALUE } from "../../synth_constants.js";
|
|
6
6
|
import { generatorTypes } from "../../../soundfont/basic_soundfont/generator_types.js";
|
|
7
|
+
import { SpessaSynthWarn } from "../../../utils/loggin.js";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* sends a "MIDI Note on message"
|
|
@@ -29,6 +30,12 @@ export function noteOn(midiNote, velocity)
|
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
if (!this.preset)
|
|
34
|
+
{
|
|
35
|
+
SpessaSynthWarn(`No preset for channel ${this.channelNumber}!`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
const realKey = midiNote + this.channelTransposeKeyShift + this.customControllers[customControllers.channelKeyShift];
|
|
33
40
|
let internalMidiNote = realKey;
|
|
34
41
|
|
|
@@ -36,7 +43,7 @@ export function noteOn(midiNote, velocity)
|
|
|
36
43
|
{
|
|
37
44
|
return;
|
|
38
45
|
}
|
|
39
|
-
const program = this.preset
|
|
46
|
+
const program = this.preset?.program;
|
|
40
47
|
const tune = this.synth.tunings[program]?.[realKey]?.midiNote;
|
|
41
48
|
if (tune >= 0)
|
|
42
49
|
{
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { SpessaSynthWarn } from "../../../utils/loggin.js";
|
|
2
|
+
import { BasicPreset } from "../../../soundfont/basic_soundfont/basic_preset.js";
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* executes a program change
|
|
3
6
|
* @param programNumber {number}
|
|
@@ -14,7 +17,13 @@ export function programChange(programNumber)
|
|
|
14
17
|
|
|
15
18
|
const isXG = this.isXGChannel;
|
|
16
19
|
const p = this.synth.soundfontManager.getPreset(bank, programNumber, isXG);
|
|
17
|
-
|
|
20
|
+
let preset = p.preset;
|
|
21
|
+
if (!preset)
|
|
22
|
+
{
|
|
23
|
+
SpessaSynthWarn("No presets! Using empty fallback.");
|
|
24
|
+
preset = new BasicPreset(this.synth.soundfontManager.soundfontList[0].soundfont);
|
|
25
|
+
preset.presetName = "SPESSA EMPTY FALLBACK PRESET";
|
|
26
|
+
}
|
|
18
27
|
this.setPreset(preset);
|
|
19
28
|
this.sentBank = Math.min(128, preset.bank + p.bankOffset);
|
|
20
29
|
this.synth.callEvent("programchange", {
|
|
@@ -66,7 +66,7 @@ export function renderVoice(
|
|
|
66
66
|
let semitones = voice.modulatedGenerators[generatorTypes.coarseTune]; // soundfont coarse tuning
|
|
67
67
|
|
|
68
68
|
// midi tuning standard
|
|
69
|
-
const tuning = this.synth.tunings[this.preset
|
|
69
|
+
const tuning = this.synth.tunings[this.preset?.program]?.[voice.realKey];
|
|
70
70
|
if (tuning !== undefined && tuning?.midiNote >= 0)
|
|
71
71
|
{
|
|
72
72
|
// override key
|