spessasynth_core 3.26.12 → 3.26.14
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/README.md +6 -0
- package/index.js +15 -5
- package/package.json +1 -1
- package/src/soundfont/basic_soundfont/generator.js +4 -1
- package/src/soundfont/basic_soundfont/modulator.js +2 -2
- package/src/soundfont/load_soundfont.js +2 -2
- package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +6 -0
- package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +36 -15
package/README.md
CHANGED
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
**A powerful SF2/DLS/MIDI JavaScript library. It works with any modern JS environment that supports WebAssembly.**
|
|
7
7
|
|
|
8
|
+
It allows you to:
|
|
9
|
+
- Play MIDI files using SF2/SF3/DLS files
|
|
10
|
+
- Write MIDI files
|
|
11
|
+
- Write SF2/SF3 files
|
|
12
|
+
- Convert DLS to SF2 (and back!)
|
|
13
|
+
- [and more!](https://github.com/spessasus/spessasynth_core?tab=readme-ov-file#current-features)
|
|
8
14
|
> **TIP:**
|
|
9
15
|
> Looking for an easy-to-use WebAudioAPI browser wrapper? Try [spessasynth_lib](https://github.com/spessasus/spessasynth_lib)!
|
|
10
16
|
|
package/index.js
CHANGED
|
@@ -23,8 +23,8 @@ import { BasicSample } from "./src/soundfont/basic_soundfont/basic_sample.js";
|
|
|
23
23
|
import { BasicInstrumentZone, BasicPresetZone } from "./src/soundfont/basic_soundfont/basic_zones.js";
|
|
24
24
|
import { BasicInstrument } from "./src/soundfont/basic_soundfont/basic_instrument.js";
|
|
25
25
|
import { BasicPreset } from "./src/soundfont/basic_soundfont/basic_preset.js";
|
|
26
|
-
import { Generator } from "./src/soundfont/basic_soundfont/generator.js";
|
|
27
|
-
import { Modulator, modulatorSources } from "./src/soundfont/basic_soundfont/modulator.js";
|
|
26
|
+
import { Generator, generatorTypes } from "./src/soundfont/basic_soundfont/generator.js";
|
|
27
|
+
import { Modulator, modulatorCurveTypes, modulatorSources } from "./src/soundfont/basic_soundfont/modulator.js";
|
|
28
28
|
import { loadSoundFont } from "./src/soundfont/load_soundfont.js";
|
|
29
29
|
|
|
30
30
|
import { MIDI } from "./src/midi/midi_loader.js";
|
|
@@ -49,7 +49,8 @@ import { readBytesAsString } from "./src/utils/byte_functions/string.js";
|
|
|
49
49
|
import { readVariableLengthQuantity } from "./src/utils/byte_functions/variable_length_quantity.js";
|
|
50
50
|
import { consoleColors } from "./src/utils/other.js";
|
|
51
51
|
import { inflateSync } from "./src/externals/fflate/fflate.min.js";
|
|
52
|
-
|
|
52
|
+
import { DLSDestinations } from "./src/soundfont/dls/dls_destinations.js";
|
|
53
|
+
import { DLSSources } from "./src/soundfont/dls/dls_sources.js";
|
|
53
54
|
// you shouldn't use these...
|
|
54
55
|
const SpessaSynthCoreUtils = {
|
|
55
56
|
consoleColors,
|
|
@@ -64,6 +65,7 @@ const SpessaSynthCoreUtils = {
|
|
|
64
65
|
inflateSync
|
|
65
66
|
};
|
|
66
67
|
|
|
68
|
+
// see All-NPN-Exports.md in the wiki
|
|
67
69
|
export {
|
|
68
70
|
// synth and seq
|
|
69
71
|
SpessaSynthSequencer,
|
|
@@ -71,6 +73,7 @@ export {
|
|
|
71
73
|
SynthesizerSnapshot,
|
|
72
74
|
ChannelSnapshot,
|
|
73
75
|
KeyModifier,
|
|
76
|
+
|
|
74
77
|
masterParameterType,
|
|
75
78
|
channelConfiguration,
|
|
76
79
|
interpolationTypes,
|
|
@@ -92,7 +95,13 @@ export {
|
|
|
92
95
|
BasicPresetZone,
|
|
93
96
|
Generator,
|
|
94
97
|
Modulator,
|
|
98
|
+
|
|
95
99
|
modulatorSources,
|
|
100
|
+
modulatorCurveTypes,
|
|
101
|
+
generatorTypes,
|
|
102
|
+
DLSSources,
|
|
103
|
+
DLSDestinations,
|
|
104
|
+
|
|
96
105
|
|
|
97
106
|
// MIDI
|
|
98
107
|
MIDI,
|
|
@@ -100,13 +109,14 @@ export {
|
|
|
100
109
|
BasicMIDI,
|
|
101
110
|
MIDIBuilder,
|
|
102
111
|
MIDIMessage,
|
|
112
|
+
|
|
103
113
|
RMIDINFOChunks,
|
|
114
|
+
midiControllers,
|
|
115
|
+
messageTypes,
|
|
104
116
|
|
|
105
117
|
// utils
|
|
106
118
|
IndexedByteArray,
|
|
107
119
|
audioToWav,
|
|
108
120
|
SpessaSynthLogging,
|
|
109
|
-
midiControllers,
|
|
110
|
-
messageTypes,
|
|
111
121
|
SpessaSynthCoreUtils
|
|
112
122
|
};
|
package/package.json
CHANGED
|
@@ -70,11 +70,12 @@ export const generatorTypes = {
|
|
|
70
70
|
vibLfoToFilterFc: 62
|
|
71
71
|
};
|
|
72
72
|
export const GENERATORS_AMOUNT = Object.keys(generatorTypes).length;
|
|
73
|
+
export const MAX_GENERATOR = Math.max(...Object.values(generatorTypes));
|
|
73
74
|
|
|
74
75
|
/**
|
|
75
76
|
* @type {{min: number, max: number, def: number}[]}
|
|
76
77
|
*/
|
|
77
|
-
|
|
78
|
+
const generatorLimits = [];
|
|
78
79
|
// offsets
|
|
79
80
|
generatorLimits[generatorTypes.startAddrsOffset] = { min: 0, max: 32768, def: 0 };
|
|
80
81
|
generatorLimits[generatorTypes.endAddrOffset] = { min: -32768, max: 32768, def: 0 };
|
|
@@ -148,6 +149,8 @@ generatorLimits[generatorTypes.exclusiveClass] = { min: 0, max: 99999, def: 0 };
|
|
|
148
149
|
generatorLimits[generatorTypes.overridingRootKey] = { min: 0 - 1, max: 127, def: -1 };
|
|
149
150
|
generatorLimits[generatorTypes.sampleModes] = { min: 0, max: 3, def: 0 };
|
|
150
151
|
|
|
152
|
+
export { generatorLimits };
|
|
153
|
+
|
|
151
154
|
export class Generator
|
|
152
155
|
{
|
|
153
156
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { generatorTypes } from "./generator.js";
|
|
1
|
+
import { generatorTypes, MAX_GENERATOR } from "./generator.js";
|
|
2
2
|
import { midiControllers } from "../../midi/midi_message.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -79,7 +79,7 @@ export class Modulator
|
|
|
79
79
|
this.transformType = transformType;
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
if (this.modulatorDestination >
|
|
82
|
+
if (this.modulatorDestination > MAX_GENERATOR)
|
|
83
83
|
{
|
|
84
84
|
this.modulatorDestination = generatorTypes.INVALID; // flag as invalid (for linked ones)
|
|
85
85
|
}
|
|
@@ -4,8 +4,8 @@ import { DLSSoundFont } from "./dls/dls_soundfont.js";
|
|
|
4
4
|
import { SoundFont2 } from "./read_sf2/soundfont.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Loads a soundfont file
|
|
8
|
-
* @param buffer {ArrayBuffer}
|
|
7
|
+
* Loads a soundfont or dls file
|
|
8
|
+
* @param buffer {ArrayBuffer} the binary file to load
|
|
9
9
|
* @returns {BasicSoundBank}
|
|
10
10
|
*/
|
|
11
11
|
export function loadSoundFont(buffer)
|
|
@@ -4,6 +4,7 @@ import { ModulationEnvelope } from "./modulation_envelope.js";
|
|
|
4
4
|
import { generatorLimits, generatorTypes } from "../../../soundfont/basic_soundfont/generator.js";
|
|
5
5
|
import { Modulator, modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
|
|
6
6
|
import { NON_CC_INDEX_OFFSET } from "./controller_tables.js";
|
|
7
|
+
import { SpessaSynthWarn } from "../../../utils/loggin.js";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* compute_modulator.js
|
|
@@ -137,6 +138,11 @@ export function computeModulators(voice, controllerTable, sourceUsesCC = -1, sou
|
|
|
137
138
|
modulators.forEach(mod =>
|
|
138
139
|
{
|
|
139
140
|
const limits = generatorLimits[mod.modulatorDestination];
|
|
141
|
+
if (!limits)
|
|
142
|
+
{
|
|
143
|
+
SpessaSynthWarn(`Invalid modulator: ${mod.modulatorDestination}`);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
140
146
|
const newValue = modulatedGenerators[mod.modulatorDestination] + computeModulator(
|
|
141
147
|
controllerTable,
|
|
142
148
|
mod,
|
|
@@ -469,13 +469,28 @@ export function systemExclusive(syx, channelOffset = 0)
|
|
|
469
469
|
case 0x00:
|
|
470
470
|
// see https://github.com/spessasus/SpessaSynth/issues/154
|
|
471
471
|
// pitch control
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
472
|
+
// special case:
|
|
473
|
+
// if the source is a pitch wheel, it's a strange way of setting the bend range
|
|
474
|
+
// testcase: th07_03.mid
|
|
475
|
+
if (source === NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel)
|
|
476
|
+
{
|
|
477
|
+
channelObject.controllerChange(midiControllers.RPNMsb, 0x0);
|
|
478
|
+
channelObject.controllerChange(midiControllers.RPNLsb, 0x0);
|
|
479
|
+
channelObject.controllerChange(
|
|
480
|
+
midiControllers.dataEntryMsb,
|
|
481
|
+
Math.floor(centeredValue)
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
else
|
|
485
|
+
{
|
|
486
|
+
channelObject.sysExModulators.setModulator(
|
|
487
|
+
source,
|
|
488
|
+
generatorTypes.fineTune,
|
|
489
|
+
centeredValue * 100,
|
|
490
|
+
bipolar
|
|
491
|
+
);
|
|
492
|
+
niceLogging(channel, centeredValue, `${sourceName} pitch control`, "semitones");
|
|
493
|
+
}
|
|
479
494
|
break;
|
|
480
495
|
|
|
481
496
|
case 0x01:
|
|
@@ -512,7 +527,8 @@ export function systemExclusive(syx, channelOffset = 0)
|
|
|
512
527
|
channelObject.sysExModulators.setModulator(
|
|
513
528
|
source,
|
|
514
529
|
generatorTypes.vibLfoToPitch,
|
|
515
|
-
normalizedNotCentered * 600
|
|
530
|
+
normalizedNotCentered * 600,
|
|
531
|
+
bipolar
|
|
516
532
|
);
|
|
517
533
|
niceLogging(
|
|
518
534
|
channel,
|
|
@@ -527,7 +543,8 @@ export function systemExclusive(syx, channelOffset = 0)
|
|
|
527
543
|
channelObject.sysExModulators.setModulator(
|
|
528
544
|
source,
|
|
529
545
|
generatorTypes.vibLfoToFilterFc,
|
|
530
|
-
normalizedNotCentered * 2400
|
|
546
|
+
normalizedNotCentered * 2400,
|
|
547
|
+
bipolar
|
|
531
548
|
);
|
|
532
549
|
niceLogging(
|
|
533
550
|
channel,
|
|
@@ -542,11 +559,12 @@ export function systemExclusive(syx, channelOffset = 0)
|
|
|
542
559
|
channelObject.sysExModulators.setModulator(
|
|
543
560
|
source,
|
|
544
561
|
generatorTypes.vibLfoToVolume,
|
|
545
|
-
|
|
562
|
+
normalizedValue * 960,
|
|
563
|
+
bipolar
|
|
546
564
|
);
|
|
547
565
|
niceLogging(
|
|
548
566
|
channel,
|
|
549
|
-
|
|
567
|
+
normalizedValue * 960,
|
|
550
568
|
`${sourceName} LFO1 amplitude depth`,
|
|
551
569
|
"cB"
|
|
552
570
|
);
|
|
@@ -559,7 +577,8 @@ export function systemExclusive(syx, channelOffset = 0)
|
|
|
559
577
|
channelObject.sysExModulators.setModulator(
|
|
560
578
|
source,
|
|
561
579
|
generatorTypes.modLfoToPitch,
|
|
562
|
-
normalizedNotCentered * 600
|
|
580
|
+
normalizedNotCentered * 600,
|
|
581
|
+
bipolar
|
|
563
582
|
);
|
|
564
583
|
niceLogging(
|
|
565
584
|
channel,
|
|
@@ -574,7 +593,8 @@ export function systemExclusive(syx, channelOffset = 0)
|
|
|
574
593
|
channelObject.sysExModulators.setModulator(
|
|
575
594
|
source,
|
|
576
595
|
generatorTypes.modLfoToFilterFc,
|
|
577
|
-
normalizedNotCentered * 2400
|
|
596
|
+
normalizedNotCentered * 2400,
|
|
597
|
+
bipolar
|
|
578
598
|
);
|
|
579
599
|
niceLogging(
|
|
580
600
|
channel,
|
|
@@ -589,11 +609,12 @@ export function systemExclusive(syx, channelOffset = 0)
|
|
|
589
609
|
channelObject.sysExModulators.setModulator(
|
|
590
610
|
source,
|
|
591
611
|
generatorTypes.modLfoToVolume,
|
|
592
|
-
|
|
612
|
+
normalizedValue * 960,
|
|
613
|
+
bipolar
|
|
593
614
|
);
|
|
594
615
|
niceLogging(
|
|
595
616
|
channel,
|
|
596
|
-
|
|
617
|
+
normalizedValue * 960,
|
|
597
618
|
`${sourceName} LFO2 amplitude depth`,
|
|
598
619
|
"cB"
|
|
599
620
|
);
|