spessasynth_core 3.26.19 → 3.26.21
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 +0 -1
- package/package.json +1 -1
- package/src/soundfont/basic_soundfont/basic_global_zone.js +1 -11
- package/src/soundfont/basic_soundfont/basic_instrument.js +28 -16
- package/src/soundfont/basic_soundfont/basic_instrument_zone.js +29 -7
- package/src/soundfont/basic_soundfont/basic_preset.js +11 -8
- package/src/soundfont/basic_soundfont/basic_preset_zone.js +27 -6
- package/src/soundfont/basic_soundfont/basic_sample.js +33 -5
- package/src/soundfont/basic_soundfont/basic_soundbank.js +19 -15
- package/src/soundfont/basic_soundfont/basic_zone.js +11 -0
- package/src/soundfont/basic_soundfont/modulator.js +8 -3
- package/src/soundfont/basic_soundfont/write_dls/combine_zones.js +13 -22
- package/src/soundfont/basic_soundfont/write_dls/ins.js +3 -1
- package/src/soundfont/dls/dls_instrument.js +20 -0
- package/src/soundfont/dls/dls_preset.js +8 -8
- package/src/soundfont/dls/dls_zone.js +4 -7
- package/src/soundfont/dls/read_instrument.js +5 -9
- package/src/soundfont/dls/read_region.js +5 -8
- package/src/soundfont/read_sf2/generators.js +2 -5
- package/src/soundfont/read_sf2/instrument_zones.js +88 -0
- package/src/soundfont/read_sf2/instruments.js +26 -30
- package/src/soundfont/read_sf2/modulators.js +2 -0
- package/src/soundfont/read_sf2/preset_zones.js +92 -0
- package/src/soundfont/read_sf2/presets.js +23 -31
- package/src/soundfont/read_sf2/samples.js +5 -5
- package/src/soundfont/read_sf2/soundfont.js +44 -32
- package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +2 -1
- package/src/soundfont/read_sf2/zones.js +0 -223
package/README.md
CHANGED
|
@@ -79,7 +79,6 @@ npm install --save spessasynth_core
|
|
|
79
79
|
- **Smart preloading:** Only preloads the samples used in the MIDI file for smooth playback *(down to key and velocity!)*
|
|
80
80
|
- **Lyrics support:** Add karaoke to your program!
|
|
81
81
|
- **Raw lyrics available:** Decode in any encoding! *(Kanji? No problem!)*
|
|
82
|
-
- **Runs in Audio Thread as well:** Never blocks the main thread
|
|
83
82
|
- **Loop points support:** Ensures seamless loops
|
|
84
83
|
|
|
85
84
|
### Read and Write SoundFont and MIDI Files with Ease
|
package/package.json
CHANGED
|
@@ -2,15 +2,5 @@ import { BasicZone } from "./basic_zone.js";
|
|
|
2
2
|
|
|
3
3
|
export class BasicGlobalZone extends BasicZone
|
|
4
4
|
{
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @param zone {BasicZone}
|
|
8
|
-
*/
|
|
9
|
-
copyFrom(zone)
|
|
10
|
-
{
|
|
11
|
-
this.keyRange = { ...zone.keyRange };
|
|
12
|
-
this.velRange = { ...zone.velRange };
|
|
13
|
-
this.generators = [...zone.generators];
|
|
14
|
-
this.modulators = [...zone.modulators];
|
|
15
|
-
}
|
|
5
|
+
// nothing here, just a different instance...
|
|
16
6
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BasicGlobalZone } from "./basic_global_zone.js";
|
|
2
|
+
import { BasicInstrumentZone } from "./basic_instrument_zone.js";
|
|
2
3
|
|
|
3
4
|
export class BasicInstrument
|
|
4
5
|
{
|
|
@@ -22,42 +23,53 @@ export class BasicInstrument
|
|
|
22
23
|
globalZone = new BasicGlobalZone();
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
|
-
* Instrument's
|
|
26
|
-
*
|
|
27
|
-
* @
|
|
26
|
+
* Instrument's linked presets (the presets that use it)
|
|
27
|
+
* note that duplicates are allowed since one preset can use the same instrument multople times
|
|
28
|
+
* @type {BasicPreset[]}
|
|
28
29
|
*/
|
|
29
|
-
|
|
30
|
+
linkedPresets = [];
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* @returns {number}
|
|
33
34
|
*/
|
|
34
35
|
get useCount()
|
|
35
36
|
{
|
|
36
|
-
return this.
|
|
37
|
+
return this.linkedPresets.length;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
|
-
* @
|
|
41
|
+
* @returns {BasicInstrumentZone}
|
|
41
42
|
*/
|
|
42
|
-
|
|
43
|
+
createZone()
|
|
43
44
|
{
|
|
44
|
-
|
|
45
|
-
this.instrumentZones.push(
|
|
45
|
+
const zone = new BasicInstrumentZone(this);
|
|
46
|
+
this.instrumentZones.push(zone);
|
|
47
|
+
return zone;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
/**
|
|
51
|
+
* @param preset {BasicPreset}
|
|
52
|
+
*/
|
|
53
|
+
linkTo(preset)
|
|
49
54
|
{
|
|
50
|
-
this.
|
|
51
|
-
this.instrumentZones.forEach(z => z.useCount
|
|
55
|
+
this.linkedPresets.push(preset);
|
|
56
|
+
this.instrumentZones.forEach(z => z.useCount = this.linkedPresets.length);
|
|
52
57
|
}
|
|
53
58
|
|
|
54
|
-
|
|
59
|
+
/**
|
|
60
|
+
* @param preset {BasicPreset}
|
|
61
|
+
*/
|
|
62
|
+
unlinkFrom(preset)
|
|
55
63
|
{
|
|
56
|
-
this.
|
|
57
|
-
|
|
64
|
+
const index = this.linkedPresets.indexOf(preset);
|
|
65
|
+
if (index < 0)
|
|
66
|
+
{
|
|
67
|
+
throw new Error(`Cannot unlink ${preset.presetName} from ${this.instrumentName}: not linked.`);
|
|
68
|
+
}
|
|
69
|
+
this.linkedPresets.splice(index, 1);
|
|
58
70
|
}
|
|
59
71
|
|
|
60
|
-
|
|
72
|
+
deleteAllZones()
|
|
61
73
|
{
|
|
62
74
|
this.instrumentZones.forEach(z => z.deleteZone());
|
|
63
75
|
this.instrumentZones.length = 0;
|
|
@@ -2,17 +2,32 @@ import { BasicZone } from "./basic_zone.js";
|
|
|
2
2
|
|
|
3
3
|
export class BasicInstrumentZone extends BasicZone
|
|
4
4
|
{
|
|
5
|
+
/**
|
|
6
|
+
* The parent instrument.
|
|
7
|
+
* @type {BasicInstrument}
|
|
8
|
+
*/
|
|
9
|
+
parentInstrument;
|
|
10
|
+
|
|
5
11
|
/**
|
|
6
12
|
* Zone's sample.
|
|
7
13
|
* @type {BasicSample}
|
|
8
14
|
*/
|
|
9
15
|
sample;
|
|
10
|
-
|
|
11
16
|
/**
|
|
12
|
-
* For tracking on the individual zone level, since multiple presets can refer to the same instrument
|
|
17
|
+
* For tracking on the individual zone level, since multiple presets can refer to the same instrument.
|
|
13
18
|
* @type {number}
|
|
14
19
|
*/
|
|
15
|
-
useCount
|
|
20
|
+
useCount;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param instrument {BasicInstrument}
|
|
24
|
+
*/
|
|
25
|
+
constructor(instrument)
|
|
26
|
+
{
|
|
27
|
+
super();
|
|
28
|
+
this.parentInstrument = instrument;
|
|
29
|
+
this.useCount = instrument.linkedPresets.length;
|
|
30
|
+
}
|
|
16
31
|
|
|
17
32
|
/**
|
|
18
33
|
* @param sample {BasicSample}
|
|
@@ -20,16 +35,23 @@ export class BasicInstrumentZone extends BasicZone
|
|
|
20
35
|
setSample(sample)
|
|
21
36
|
{
|
|
22
37
|
this.sample = sample;
|
|
23
|
-
this.
|
|
38
|
+
sample.linkTo(this.parentInstrument);
|
|
24
39
|
}
|
|
25
40
|
|
|
26
41
|
deleteZone()
|
|
27
42
|
{
|
|
28
|
-
this.sample.
|
|
43
|
+
this.sample.unlinkFrom(this.parentInstrument);
|
|
29
44
|
}
|
|
30
45
|
|
|
31
|
-
|
|
46
|
+
/**
|
|
47
|
+
* @param zone {BasicZone}
|
|
48
|
+
*/
|
|
49
|
+
copyFrom(zone)
|
|
32
50
|
{
|
|
33
|
-
|
|
51
|
+
super.copyFrom(zone);
|
|
52
|
+
if (zone instanceof BasicInstrumentZone)
|
|
53
|
+
{
|
|
54
|
+
this.sample = zone.sample;
|
|
55
|
+
}
|
|
34
56
|
}
|
|
35
57
|
}
|
|
@@ -10,6 +10,7 @@ import { Modulator } from "./modulator.js";
|
|
|
10
10
|
import { isXGDrums } from "../../utils/xg_hacks.js";
|
|
11
11
|
|
|
12
12
|
import { BasicGlobalZone } from "./basic_global_zone.js";
|
|
13
|
+
import { BasicPresetZone } from "./basic_preset_zone.js";
|
|
13
14
|
|
|
14
15
|
export class BasicPreset
|
|
15
16
|
{
|
|
@@ -75,14 +76,6 @@ export class BasicPreset
|
|
|
75
76
|
this.parentSoundBank = parentSoundBank;
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
/**
|
|
79
|
-
* @param zones {BasicPresetZone}
|
|
80
|
-
*/
|
|
81
|
-
addZones(...zones)
|
|
82
|
-
{
|
|
83
|
-
this.presetZones.push(...zones);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
79
|
/**
|
|
87
80
|
* @param allowXG {boolean}
|
|
88
81
|
* @param allowSFX {boolean}
|
|
@@ -113,6 +106,16 @@ export class BasicPreset
|
|
|
113
106
|
this.presetZones.splice(index, 1);
|
|
114
107
|
}
|
|
115
108
|
|
|
109
|
+
/**
|
|
110
|
+
* @returns {BasicPresetZone}
|
|
111
|
+
*/
|
|
112
|
+
createZone()
|
|
113
|
+
{
|
|
114
|
+
const z = new BasicPresetZone(this);
|
|
115
|
+
this.presetZones.push(z);
|
|
116
|
+
return z;
|
|
117
|
+
}
|
|
118
|
+
|
|
116
119
|
// noinspection JSUnusedGlobalSymbols
|
|
117
120
|
/**
|
|
118
121
|
* Preloads all samples (async)
|
|
@@ -3,14 +3,29 @@ import { BasicZone } from "./basic_zone.js";
|
|
|
3
3
|
export class BasicPresetZone extends BasicZone
|
|
4
4
|
{
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* The parent preset.
|
|
7
|
+
* @type {BasicPreset}
|
|
8
|
+
*/
|
|
9
|
+
parentPreset;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Zone's instrument.
|
|
7
13
|
* @type {BasicInstrument}
|
|
8
14
|
*/
|
|
9
15
|
instrument;
|
|
10
16
|
|
|
17
|
+
/**
|
|
18
|
+
* @param preset {BasicPreset}
|
|
19
|
+
*/
|
|
20
|
+
constructor(preset)
|
|
21
|
+
{
|
|
22
|
+
super();
|
|
23
|
+
this.parentPreset = preset;
|
|
24
|
+
}
|
|
25
|
+
|
|
11
26
|
deleteZone()
|
|
12
27
|
{
|
|
13
|
-
this.instrument.
|
|
28
|
+
this.instrument.unlinkFrom(this.parentPreset);
|
|
14
29
|
}
|
|
15
30
|
|
|
16
31
|
/**
|
|
@@ -19,12 +34,18 @@ export class BasicPresetZone extends BasicZone
|
|
|
19
34
|
setInstrument(instrument)
|
|
20
35
|
{
|
|
21
36
|
this.instrument = instrument;
|
|
22
|
-
this.instrument.
|
|
37
|
+
this.instrument.linkTo(this.parentPreset);
|
|
23
38
|
}
|
|
24
39
|
|
|
25
|
-
|
|
26
|
-
|
|
40
|
+
/**
|
|
41
|
+
* @param zone {BasicZone}
|
|
42
|
+
*/
|
|
43
|
+
copyFrom(zone)
|
|
27
44
|
{
|
|
28
|
-
|
|
45
|
+
super.copyFrom(zone);
|
|
46
|
+
if (zone instanceof BasicPresetZone)
|
|
47
|
+
{
|
|
48
|
+
this.instrument = zone.instrument;
|
|
49
|
+
}
|
|
29
50
|
}
|
|
30
51
|
}
|
|
@@ -79,13 +79,12 @@ export class BasicSample
|
|
|
79
79
|
* @type {Uint8Array}
|
|
80
80
|
*/
|
|
81
81
|
compressedData = undefined;
|
|
82
|
-
|
|
83
82
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
83
|
+
* Sample's linked instruments (the instruments that use it)
|
|
84
|
+
* note that duplicates are allowed since one instrument can use the same sample multople times
|
|
85
|
+
* @type {BasicInstrument[]}
|
|
86
86
|
*/
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
linkedInstruments = [];
|
|
89
88
|
/**
|
|
90
89
|
* The sample's audio data
|
|
91
90
|
* @type {Float32Array}
|
|
@@ -126,6 +125,14 @@ export class BasicSample
|
|
|
126
125
|
this.isCompressed = (sampleType & 0x10) > 0;
|
|
127
126
|
}
|
|
128
127
|
|
|
128
|
+
/**
|
|
129
|
+
* The sample's use count
|
|
130
|
+
* @type {number}
|
|
131
|
+
*/
|
|
132
|
+
get useCount()
|
|
133
|
+
{
|
|
134
|
+
return this.linkedInstruments.length;
|
|
135
|
+
}
|
|
129
136
|
|
|
130
137
|
/**
|
|
131
138
|
* @returns {Uint8Array|IndexedByteArray}
|
|
@@ -196,6 +203,27 @@ export class BasicSample
|
|
|
196
203
|
|
|
197
204
|
}
|
|
198
205
|
|
|
206
|
+
/**
|
|
207
|
+
* @param instrument {BasicInstrument}
|
|
208
|
+
*/
|
|
209
|
+
linkTo(instrument)
|
|
210
|
+
{
|
|
211
|
+
this.linkedInstruments.push(instrument);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @param instrument {BasicInstrument}
|
|
216
|
+
*/
|
|
217
|
+
unlinkFrom(instrument)
|
|
218
|
+
{
|
|
219
|
+
const index = this.linkedInstruments.indexOf(instrument);
|
|
220
|
+
if (index < 0)
|
|
221
|
+
{
|
|
222
|
+
throw new Error(`Cannot unlink ${instrument.instrumentName} from ${this.sampleName}: not linked.`);
|
|
223
|
+
}
|
|
224
|
+
this.linkedInstruments.splice(index, 1);
|
|
225
|
+
}
|
|
226
|
+
|
|
199
227
|
/**
|
|
200
228
|
* @returns {Float32Array}
|
|
201
229
|
*/
|
|
@@ -10,13 +10,11 @@ import { write } from "./write_sf2/write.js";
|
|
|
10
10
|
import { defaultModulators, Modulator } from "./modulator.js";
|
|
11
11
|
import { writeDLS } from "./write_dls/write_dls.js";
|
|
12
12
|
import { BasicSample } from "./basic_sample.js";
|
|
13
|
-
import { BasicPresetZone } from "./basic_preset_zone.js";
|
|
14
13
|
import { Generator } from "./generator.js";
|
|
15
14
|
import { BasicInstrument } from "./basic_instrument.js";
|
|
16
15
|
import { BasicPreset } from "./basic_preset.js";
|
|
17
16
|
import { isXGDrums } from "../../utils/xg_hacks.js";
|
|
18
17
|
import { generatorTypes } from "./generator_types.js";
|
|
19
|
-
import { BasicInstrumentZone } from "./basic_instrument_zone.js";
|
|
20
18
|
import { BasicGlobalZone } from "./basic_global_zone.js";
|
|
21
19
|
|
|
22
20
|
/**
|
|
@@ -168,26 +166,25 @@ class BasicSoundBank
|
|
|
168
166
|
new Generator(generatorTypes.sampleModes, 1)
|
|
169
167
|
);
|
|
170
168
|
|
|
171
|
-
const
|
|
169
|
+
const inst = new BasicInstrument();
|
|
170
|
+
inst.instrumentName = "Saw Wave";
|
|
171
|
+
inst.globalZone = gZone;
|
|
172
|
+
|
|
173
|
+
const zone1 = inst.createZone();
|
|
172
174
|
zone1.setSample(sample);
|
|
173
175
|
|
|
174
|
-
const zone2 =
|
|
176
|
+
const zone2 = inst.createZone();
|
|
175
177
|
zone2.setSample(sample);
|
|
176
178
|
zone2.addGenerators(new Generator(generatorTypes.fineTune, -9));
|
|
177
179
|
|
|
178
|
-
|
|
179
|
-
const inst = new BasicInstrument();
|
|
180
|
-
inst.instrumentName = "Saw Wave";
|
|
181
|
-
inst.globalZone = gZone;
|
|
182
|
-
inst.addZones(zone1, zone2);
|
|
183
180
|
font.addInstruments(inst);
|
|
184
181
|
|
|
185
|
-
const pZone = new BasicPresetZone();
|
|
186
|
-
pZone.setInstrument(inst);
|
|
187
182
|
|
|
188
183
|
const preset = new BasicPreset(font);
|
|
189
184
|
preset.presetName = "Saw Wave";
|
|
190
|
-
preset.
|
|
185
|
+
const pZone = preset.createZone();
|
|
186
|
+
pZone.setInstrument(inst);
|
|
187
|
+
|
|
191
188
|
font.addPresets(preset);
|
|
192
189
|
|
|
193
190
|
font.soundFontInfo["ifil"] = "2.1";
|
|
@@ -207,7 +204,14 @@ class BasicSoundBank
|
|
|
207
204
|
|
|
208
205
|
flush()
|
|
209
206
|
{
|
|
210
|
-
this.presets.sort((a, b) =>
|
|
207
|
+
this.presets.sort((a, b) =>
|
|
208
|
+
{
|
|
209
|
+
if (a.bank !== b.bank)
|
|
210
|
+
{
|
|
211
|
+
return a.bank - b.bank;
|
|
212
|
+
}
|
|
213
|
+
return a.program - b.program;
|
|
214
|
+
});
|
|
211
215
|
this._parseInternal();
|
|
212
216
|
}
|
|
213
217
|
|
|
@@ -443,7 +447,7 @@ class BasicSoundBank
|
|
|
443
447
|
{
|
|
444
448
|
if (i.useCount < 1)
|
|
445
449
|
{
|
|
446
|
-
i.
|
|
450
|
+
i.deleteAllZones();
|
|
447
451
|
}
|
|
448
452
|
});
|
|
449
453
|
this.instruments = this.instruments.filter(i => i.useCount > 0);
|
|
@@ -460,7 +464,7 @@ class BasicSoundBank
|
|
|
460
464
|
throw new Error(`Cannot delete an instrument that has ${instrument.useCount} usages.`);
|
|
461
465
|
}
|
|
462
466
|
this.instruments.splice(this.instruments.indexOf(instrument), 1);
|
|
463
|
-
instrument.
|
|
467
|
+
instrument.deleteAllZones();
|
|
464
468
|
}
|
|
465
469
|
|
|
466
470
|
/**
|
|
@@ -128,5 +128,16 @@ export class BasicZone
|
|
|
128
128
|
{
|
|
129
129
|
return this.generators.find(g => g.generatorType === generatorType)?.generatorValue ?? notFoundValue;
|
|
130
130
|
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @param zone {BasicZone}
|
|
134
|
+
*/
|
|
135
|
+
copyFrom(zone)
|
|
136
|
+
{
|
|
137
|
+
this.generators = [...zone.generators];
|
|
138
|
+
this.modulators = [...zone.modulators];
|
|
139
|
+
this.velRange = { ...zone.velRange };
|
|
140
|
+
this.keyRange = { ...zone.keyRange };
|
|
141
|
+
}
|
|
131
142
|
}
|
|
132
143
|
|
|
@@ -150,6 +150,7 @@ export class Modulator
|
|
|
150
150
|
* @param destination {generatorTypes}
|
|
151
151
|
* @param amount {number}
|
|
152
152
|
* @param transformType {0|2}
|
|
153
|
+
* @param isEffectModulator {boolean}
|
|
153
154
|
*/
|
|
154
155
|
constructor(sourceIndex,
|
|
155
156
|
sourceCurveType,
|
|
@@ -163,7 +164,8 @@ export class Modulator
|
|
|
163
164
|
secSrcDirection,
|
|
164
165
|
destination,
|
|
165
166
|
amount,
|
|
166
|
-
transformType
|
|
167
|
+
transformType,
|
|
168
|
+
isEffectModulator = false)
|
|
167
169
|
{
|
|
168
170
|
this.sourcePolarity = sourcePolarity;
|
|
169
171
|
this.sourceDirection = sourceDirection;
|
|
@@ -180,6 +182,7 @@ export class Modulator
|
|
|
180
182
|
this.modulatorDestination = destination;
|
|
181
183
|
this.transformAmount = amount;
|
|
182
184
|
this.transformType = transformType;
|
|
185
|
+
this.isEffectModulator = isEffectModulator;
|
|
183
186
|
|
|
184
187
|
|
|
185
188
|
if (this.modulatorDestination > MAX_GENERATOR)
|
|
@@ -208,7 +211,8 @@ export class Modulator
|
|
|
208
211
|
modulator.secSrcDirection,
|
|
209
212
|
modulator.modulatorDestination,
|
|
210
213
|
modulator.transformAmount,
|
|
211
|
-
modulator.transformType
|
|
214
|
+
modulator.transformType,
|
|
215
|
+
modulator.isEffectModulator
|
|
212
216
|
);
|
|
213
217
|
}
|
|
214
218
|
|
|
@@ -322,7 +326,8 @@ export class Modulator
|
|
|
322
326
|
this.secSrcDirection,
|
|
323
327
|
this.modulatorDestination,
|
|
324
328
|
this.transformAmount + modulator.transformAmount,
|
|
325
|
-
this.transformType
|
|
329
|
+
this.transformType,
|
|
330
|
+
this.isEffectModulator
|
|
326
331
|
);
|
|
327
332
|
}
|
|
328
333
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Modulator } from "../modulator.js";
|
|
2
2
|
import { Generator } from "../generator.js";
|
|
3
3
|
import { generatorLimits, generatorTypes } from "../generator_types.js";
|
|
4
|
-
import {
|
|
5
|
-
import { BasicGlobalZone } from "../basic_global_zone.js";
|
|
4
|
+
import { BasicInstrument } from "../basic_instrument.js";
|
|
6
5
|
|
|
7
6
|
const notGlobalizedTypes = new Set([
|
|
8
7
|
generatorTypes.velRange,
|
|
@@ -32,7 +31,7 @@ const notGlobalizedTypes = new Set([
|
|
|
32
31
|
* Combines preset zones
|
|
33
32
|
* @param preset {BasicPreset}
|
|
34
33
|
* @param globalize {boolean}
|
|
35
|
-
* @returns {
|
|
34
|
+
* @returns {BasicInstrument}
|
|
36
35
|
*/
|
|
37
36
|
export function combineZones(preset, globalize = true)
|
|
38
37
|
{
|
|
@@ -64,10 +63,7 @@ export function combineZones(preset, globalize = true)
|
|
|
64
63
|
main.push(...adder.filter(m => !main.find(mm => Modulator.isIdentical(m, mm))));
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
|
|
68
|
-
* @type {BasicInstrumentZone[]}
|
|
69
|
-
*/
|
|
70
|
-
const finalZones = [];
|
|
66
|
+
const outputInstrument = new BasicInstrument();
|
|
71
67
|
|
|
72
68
|
/**
|
|
73
69
|
* @type {Generator[]}
|
|
@@ -77,7 +73,6 @@ export function combineZones(preset, globalize = true)
|
|
|
77
73
|
* @type {Modulator[]}
|
|
78
74
|
*/
|
|
79
75
|
const globalPresetModulators = [];
|
|
80
|
-
|
|
81
76
|
// find the global zone and apply ranges, generators, and modulators
|
|
82
77
|
const globalPresetZone = preset.globalZone;
|
|
83
78
|
globalPresetGenerators.push(...globalPresetZone.generators);
|
|
@@ -209,7 +204,7 @@ export function combineZones(preset, globalize = true)
|
|
|
209
204
|
);
|
|
210
205
|
|
|
211
206
|
// create the zone and copy over values
|
|
212
|
-
const zone =
|
|
207
|
+
const zone = outputInstrument.createZone();
|
|
213
208
|
zone.keyRange = instZoneKeyRange;
|
|
214
209
|
zone.velRange = instZoneVelRange;
|
|
215
210
|
if (zone.keyRange.min === 0 && zone.keyRange.max === 127)
|
|
@@ -221,12 +216,11 @@ export function combineZones(preset, globalize = true)
|
|
|
221
216
|
zone.velRange.min = -1;
|
|
222
217
|
}
|
|
223
218
|
zone.setSample(instZone.sample);
|
|
224
|
-
zone.
|
|
225
|
-
zone.
|
|
226
|
-
finalZones.push(zone);
|
|
219
|
+
zone.addGenerators(...finalGenList);
|
|
220
|
+
zone.addModulators(...finalModList);
|
|
227
221
|
}
|
|
228
222
|
}
|
|
229
|
-
const globalZone =
|
|
223
|
+
const globalZone = outputInstrument.globalZone;
|
|
230
224
|
if (globalize)
|
|
231
225
|
{
|
|
232
226
|
// create a global zone and add repeating generators to it
|
|
@@ -245,7 +239,7 @@ export function combineZones(preset, globalize = true)
|
|
|
245
239
|
let occurencesForValues = {};
|
|
246
240
|
const defaultForChecked = generatorLimits[checkedType]?.def || 0;
|
|
247
241
|
occurencesForValues[defaultForChecked] = 0;
|
|
248
|
-
for (const z of
|
|
242
|
+
for (const z of outputInstrument.instrumentZones)
|
|
249
243
|
{
|
|
250
244
|
const gen = z.generators.find(g => g.generatorType === checkedType);
|
|
251
245
|
if (gen)
|
|
@@ -311,7 +305,7 @@ export function combineZones(preset, globalize = true)
|
|
|
311
305
|
globalZone.addGenerators(new Generator(checkedType, targetValue));
|
|
312
306
|
}
|
|
313
307
|
// remove from the zones
|
|
314
|
-
|
|
308
|
+
outputInstrument.instrumentZones.forEach(z =>
|
|
315
309
|
{
|
|
316
310
|
const gen = z.generators.findIndex(g =>
|
|
317
311
|
g.generatorType === checkedType);
|
|
@@ -337,12 +331,12 @@ export function combineZones(preset, globalize = true)
|
|
|
337
331
|
}
|
|
338
332
|
|
|
339
333
|
// globalize only modulators that exist in all zones
|
|
340
|
-
const firstZone =
|
|
334
|
+
const firstZone = outputInstrument.instrumentZones[0];
|
|
341
335
|
const modulators = firstZone.modulators.map(m => Modulator.copy(m));
|
|
342
336
|
for (const checkedModulator of modulators)
|
|
343
337
|
{
|
|
344
338
|
let existsForAllZones = true;
|
|
345
|
-
for (const zone of
|
|
339
|
+
for (const zone of outputInstrument.instrumentZones)
|
|
346
340
|
{
|
|
347
341
|
if (!existsForAllZones)
|
|
348
342
|
{
|
|
@@ -362,7 +356,7 @@ export function combineZones(preset, globalize = true)
|
|
|
362
356
|
{
|
|
363
357
|
globalZone.addModulators(Modulator.copy(checkedModulator));
|
|
364
358
|
// delete it from local zones.
|
|
365
|
-
for (const zone of
|
|
359
|
+
for (const zone of outputInstrument.instrumentZones)
|
|
366
360
|
{
|
|
367
361
|
const modulator = zone.modulators.find(m => Modulator.isIdentical(m, checkedModulator));
|
|
368
362
|
// Check if the amount is correct.
|
|
@@ -376,8 +370,5 @@ export function combineZones(preset, globalize = true)
|
|
|
376
370
|
}
|
|
377
371
|
}
|
|
378
372
|
}
|
|
379
|
-
return
|
|
380
|
-
zones: finalZones,
|
|
381
|
-
global: globalZone
|
|
382
|
-
};
|
|
373
|
+
return outputInstrument;
|
|
383
374
|
}
|
|
@@ -22,7 +22,9 @@ export function writeIns(preset)
|
|
|
22
22
|
consoleColors.info
|
|
23
23
|
);
|
|
24
24
|
// combine preset and instrument zones into a single instrument zone (region) list
|
|
25
|
-
const
|
|
25
|
+
const inst = combineZones(preset);
|
|
26
|
+
const global = inst.globalZone;
|
|
27
|
+
const zones = inst.instrumentZones;
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
// insh: instrument header
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BasicInstrument } from "../basic_soundfont/basic_instrument.js";
|
|
2
|
+
import { DLSZone } from "./dls_zone.js";
|
|
3
|
+
|
|
4
|
+
export class DLSInstrument extends BasicInstrument
|
|
5
|
+
{
|
|
6
|
+
constructor()
|
|
7
|
+
{
|
|
8
|
+
super();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @returns {DLSZone}
|
|
13
|
+
*/
|
|
14
|
+
createZone()
|
|
15
|
+
{
|
|
16
|
+
const z = new DLSZone(this);
|
|
17
|
+
this.instrumentZones.push(z);
|
|
18
|
+
return z;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { BasicPreset } from "../basic_soundfont/basic_preset.js";
|
|
2
|
-
import {
|
|
3
|
-
import { BasicInstrument } from "../basic_soundfont/basic_instrument.js";
|
|
2
|
+
import { DLSInstrument } from "./dls_instrument.js";
|
|
4
3
|
|
|
5
4
|
export class DLSPreset extends BasicPreset
|
|
6
5
|
{
|
|
6
|
+
/**
|
|
7
|
+
* @type {DLSInstrument}
|
|
8
|
+
*/
|
|
9
|
+
dlsInstrument = new DLSInstrument();
|
|
10
|
+
|
|
7
11
|
/**
|
|
8
12
|
* Creates a new DLS preset
|
|
9
13
|
* @param dls {BasicSoundBank}
|
|
@@ -33,11 +37,7 @@ export class DLSPreset extends BasicPreset
|
|
|
33
37
|
this.bank = 128;
|
|
34
38
|
}
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const zone = new BasicPresetZone();
|
|
39
|
-
zone.setInstrument(this.DLSInstrument);
|
|
40
|
-
|
|
41
|
-
this.presetZones = [zone];
|
|
40
|
+
const zone = this.createZone();
|
|
41
|
+
zone.setInstrument(this.dlsInstrument);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -5,14 +5,11 @@ import { BasicInstrumentZone } from "../basic_soundfont/basic_instrument_zone.js
|
|
|
5
5
|
export class DLSZone extends BasicInstrumentZone
|
|
6
6
|
{
|
|
7
7
|
/**
|
|
8
|
-
* @param
|
|
9
|
-
* @param velRange {SoundFontRange}
|
|
8
|
+
* @param inst {BasicInstrument}
|
|
10
9
|
*/
|
|
11
|
-
constructor(
|
|
10
|
+
constructor(inst)
|
|
12
11
|
{
|
|
13
|
-
super();
|
|
14
|
-
this.keyRange = keyRange;
|
|
15
|
-
this.velRange = velRange;
|
|
12
|
+
super(inst);
|
|
16
13
|
}
|
|
17
14
|
|
|
18
15
|
/**
|
|
@@ -86,7 +83,7 @@ export class DLSZone extends BasicInstrumentZone
|
|
|
86
83
|
{
|
|
87
84
|
this.addGenerators(new Generator(generatorTypes.overridingRootKey, sampleKey));
|
|
88
85
|
}
|
|
89
|
-
// add sample
|
|
86
|
+
// add sample
|
|
90
87
|
this.setSample(sample);
|
|
91
88
|
}
|
|
92
89
|
}
|