spessasynth_core 3.26.16 → 3.26.18
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/index.js +5 -3
- package/package.json +1 -1
- package/src/externals/README.md +6 -0
- package/src/sequencer/README.md +5 -1
- package/src/soundfont/README.md +6 -8
- package/src/soundfont/basic_soundfont/basic_global_zone.js +16 -0
- package/src/soundfont/basic_soundfont/basic_instrument.js +26 -22
- package/src/soundfont/basic_soundfont/basic_instrument_zone.js +35 -0
- package/src/soundfont/basic_soundfont/basic_preset.js +45 -42
- package/src/soundfont/basic_soundfont/basic_preset_zone.js +30 -0
- package/src/soundfont/basic_soundfont/{basic_soundfont.js → basic_soundbank.js} +22 -44
- package/src/soundfont/basic_soundfont/basic_zone.js +1 -5
- package/src/soundfont/basic_soundfont/generator.js +2 -152
- package/src/soundfont/basic_soundfont/generator_types.js +151 -0
- package/src/soundfont/basic_soundfont/modulator.js +251 -79
- package/src/soundfont/basic_soundfont/write_dls/art2.js +3 -2
- package/src/soundfont/basic_soundfont/write_dls/combine_zones.js +25 -42
- package/src/soundfont/basic_soundfont/write_dls/ins.js +11 -27
- package/src/soundfont/basic_soundfont/write_dls/modulator_converter.js +2 -2
- package/src/soundfont/basic_soundfont/write_dls/rgn2.js +2 -2
- package/src/soundfont/basic_soundfont/write_sf2/ibag.js +21 -10
- package/src/soundfont/basic_soundfont/write_sf2/igen.js +31 -27
- package/src/soundfont/basic_soundfont/write_sf2/imod.js +24 -14
- package/src/soundfont/basic_soundfont/write_sf2/inst.js +4 -5
- package/src/soundfont/basic_soundfont/write_sf2/pbag.js +20 -9
- package/src/soundfont/basic_soundfont/write_sf2/pgen.js +32 -29
- package/src/soundfont/basic_soundfont/write_sf2/phdr.js +4 -2
- package/src/soundfont/basic_soundfont/write_sf2/pmod.js +25 -15
- package/src/soundfont/basic_soundfont/write_sf2/write.js +2 -2
- package/src/soundfont/dls/articulator_converter.js +9 -3
- package/src/soundfont/dls/dls_preset.js +2 -3
- package/src/soundfont/dls/dls_soundfont.js +1 -1
- package/src/soundfont/dls/dls_sources.js +7 -6
- package/src/soundfont/dls/dls_zone.js +4 -5
- package/src/soundfont/dls/read_articulation.js +2 -1
- package/src/soundfont/dls/read_instrument.js +3 -6
- package/src/soundfont/dls/read_lart.js +1 -1
- package/src/soundfont/dls/read_region.js +2 -1
- package/src/soundfont/read_sf2/instruments.js +10 -1
- package/src/soundfont/read_sf2/modulators.js +10 -23
- package/src/soundfont/read_sf2/presets.js +10 -1
- package/src/soundfont/read_sf2/soundfont.js +1 -2
- package/src/soundfont/read_sf2/zones.js +30 -14
- package/src/synthetizer/README.md +3 -3
- package/src/synthetizer/audio_engine/README.md +1 -1
- package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +1 -1
- package/src/synthetizer/audio_engine/engine_components/dynamic_modulator_system.js +11 -3
- package/src/synthetizer/audio_engine/engine_components/lowpass_filter.js +1 -1
- package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +1 -1
- package/src/synthetizer/audio_engine/engine_components/modulation_envelope.js +1 -1
- package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +1 -1
- package/src/synthetizer/audio_engine/engine_components/voice.js +7 -10
- package/src/synthetizer/audio_engine/engine_components/volume_envelope.js +2 -1
- package/src/synthetizer/audio_engine/engine_methods/data_entry/awe32.js +1 -1
- package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +7 -0
- package/src/synthetizer/audio_engine/engine_methods/note_on.js +1 -1
- package/src/synthetizer/audio_engine/engine_methods/render_voice.js +1 -1
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +1 -1
- package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +2 -1
- package/src/utils/README.md +5 -2
- package/src/soundfont/basic_soundfont/basic_zones.js +0 -43
package/index.js
CHANGED
|
@@ -18,12 +18,12 @@ import {
|
|
|
18
18
|
import { SynthesizerSnapshot } from "./src/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js";
|
|
19
19
|
import { ChannelSnapshot } from "./src/synthetizer/audio_engine/snapshot/channel_snapshot.js";
|
|
20
20
|
|
|
21
|
-
import { BasicSoundBank } from "./src/soundfont/basic_soundfont/
|
|
21
|
+
import { BasicSoundBank } from "./src/soundfont/basic_soundfont/basic_soundbank.js";
|
|
22
22
|
import { BasicSample } from "./src/soundfont/basic_soundfont/basic_sample.js";
|
|
23
|
-
import {
|
|
23
|
+
import { BasicPresetZone } from "./src/soundfont/basic_soundfont/basic_preset_zone.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
|
|
26
|
+
import { Generator } from "./src/soundfont/basic_soundfont/generator.js";
|
|
27
27
|
import { Modulator, modulatorCurveTypes, modulatorSources } from "./src/soundfont/basic_soundfont/modulator.js";
|
|
28
28
|
import { loadSoundFont } from "./src/soundfont/load_soundfont.js";
|
|
29
29
|
|
|
@@ -51,6 +51,8 @@ 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
53
|
import { DLSSources } from "./src/soundfont/dls/dls_sources.js";
|
|
54
|
+
import { generatorTypes } from "./src/soundfont/basic_soundfont/generator_types.js";
|
|
55
|
+
import { BasicInstrumentZone } from "./src/soundfont/basic_soundfont/basic_instrument_zone.js";
|
|
54
56
|
// you shouldn't use these...
|
|
55
57
|
const SpessaSynthCoreUtils = {
|
|
56
58
|
consoleColors,
|
package/package.json
CHANGED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
## This is the external dependencies' folder.
|
|
2
|
+
|
|
3
|
+
The code here contains third-party libraries used by SpessaSynth.
|
|
4
|
+
|
|
5
|
+
- `stbvorbis_sync` - Vorbis audio decoder for SF3 soundfonts
|
|
6
|
+
- `fflate` - Used for decompressing XMF files. It is also used to compress the reverb buffer in spessasynth_lib
|
package/src/sequencer/README.md
CHANGED
|
@@ -2,4 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
The code here is responsible for playing back the parsed MIDI sequence with the synthesizer.
|
|
4
4
|
|
|
5
|
-
- `sequencer_engine` - the core sequencer engine
|
|
5
|
+
- `sequencer_engine.js` - the core sequencer engine
|
|
6
|
+
- `play.js` - handles playback control and timing
|
|
7
|
+
- `song_control.js` - manages song state and control
|
|
8
|
+
- `process_event.js` - processes MIDI events during playback
|
|
9
|
+
- `process_tick.js` - processes a single MIDI tick (think of it like a rendering quantum of the sequencer)
|
package/src/soundfont/README.md
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
## This is the
|
|
1
|
+
## This is the SoundFont and DLS parsing library.
|
|
2
2
|
|
|
3
|
-
The code here is responsible for parsing the SoundFont2 file and
|
|
3
|
+
The code here is responsible for parsing the SoundFont2/DLS file and
|
|
4
4
|
providing an easy way to get the data out.
|
|
5
|
-
Default modulators are also stored here (in `modulators.js`)
|
|
6
5
|
|
|
7
|
-
`basic_soundfont` folder contains the classes that represent
|
|
6
|
+
- `basic_soundfont` folder contains the classes that represent a sound bank file.
|
|
7
|
+
It also contains the code for writing the files.
|
|
8
8
|
|
|
9
|
-
`read_sf2` folder contains the code for reading
|
|
9
|
+
- `read_sf2` folder contains the code for reading a `.sf2` file.
|
|
10
10
|
|
|
11
|
-
`
|
|
12
|
-
|
|
13
|
-
`dls` folder contains the code for reading a `.dls` file (and converting in into a soundfont representation).
|
|
11
|
+
- `dls` folder contains the code for reading a `.dls` file (and converting in into a soundfont representation).
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BasicZone } from "./basic_zone.js";
|
|
2
|
+
|
|
3
|
+
export class BasicGlobalZone extends BasicZone
|
|
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
|
+
}
|
|
16
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { BasicGlobalZone } from "./basic_global_zone.js";
|
|
2
|
+
|
|
1
3
|
export class BasicInstrument
|
|
2
4
|
{
|
|
3
5
|
/**
|
|
@@ -9,9 +11,16 @@ export class BasicInstrument
|
|
|
9
11
|
/**
|
|
10
12
|
* The instrument's zones
|
|
11
13
|
* @type {BasicInstrumentZone[]}
|
|
14
|
+
* @readonly
|
|
12
15
|
*/
|
|
13
16
|
instrumentZones = [];
|
|
14
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Instrument's global zone
|
|
20
|
+
* @type {BasicGlobalZone}
|
|
21
|
+
*/
|
|
22
|
+
globalZone = new BasicGlobalZone();
|
|
23
|
+
|
|
15
24
|
/**
|
|
16
25
|
* Instrument's use count, used for trimming
|
|
17
26
|
* @type {number}
|
|
@@ -27,6 +36,15 @@ export class BasicInstrument
|
|
|
27
36
|
return this._useCount;
|
|
28
37
|
}
|
|
29
38
|
|
|
39
|
+
/**
|
|
40
|
+
* @param zone {BasicInstrumentZone}
|
|
41
|
+
*/
|
|
42
|
+
addZone(zone)
|
|
43
|
+
{
|
|
44
|
+
zone.useCount++;
|
|
45
|
+
this.instrumentZones.push(zone);
|
|
46
|
+
}
|
|
47
|
+
|
|
30
48
|
addUseCount()
|
|
31
49
|
{
|
|
32
50
|
this._useCount++;
|
|
@@ -36,16 +54,10 @@ export class BasicInstrument
|
|
|
36
54
|
removeUseCount()
|
|
37
55
|
{
|
|
38
56
|
this._useCount--;
|
|
39
|
-
|
|
40
|
-
{
|
|
41
|
-
if (this.safeDeleteZone(i))
|
|
42
|
-
{
|
|
43
|
-
i--;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
57
|
+
this.instrumentZones.forEach(z => z.useCount--);
|
|
46
58
|
}
|
|
47
59
|
|
|
48
|
-
|
|
60
|
+
deleteZones()
|
|
49
61
|
{
|
|
50
62
|
this.instrumentZones.forEach(z => z.deleteZone());
|
|
51
63
|
this.instrumentZones.length = 0;
|
|
@@ -53,25 +65,17 @@ export class BasicInstrument
|
|
|
53
65
|
|
|
54
66
|
/**
|
|
55
67
|
* @param index {number}
|
|
56
|
-
* @returns {boolean}
|
|
68
|
+
* @returns {boolean} if deleted
|
|
57
69
|
*/
|
|
58
|
-
|
|
70
|
+
deleteZone(index)
|
|
59
71
|
{
|
|
60
|
-
this.instrumentZones[index]
|
|
61
|
-
if (
|
|
72
|
+
const zone = this.instrumentZones[index];
|
|
73
|
+
if (zone.useCount < 1)
|
|
62
74
|
{
|
|
63
|
-
|
|
75
|
+
zone.deleteZone();
|
|
76
|
+
this.instrumentZones.splice(index, 1);
|
|
64
77
|
return true;
|
|
65
78
|
}
|
|
66
79
|
return false;
|
|
67
80
|
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @param index {number}
|
|
71
|
-
*/
|
|
72
|
-
deleteZone(index)
|
|
73
|
-
{
|
|
74
|
-
this.instrumentZones[index].deleteZone();
|
|
75
|
-
this.instrumentZones.splice(index, 1);
|
|
76
|
-
}
|
|
77
81
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { BasicZone } from "./basic_zone.js";
|
|
2
|
+
|
|
3
|
+
export class BasicInstrumentZone extends BasicZone
|
|
4
|
+
{
|
|
5
|
+
/**
|
|
6
|
+
* Zone's sample.
|
|
7
|
+
* @type {BasicSample}
|
|
8
|
+
*/
|
|
9
|
+
sample;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* For tracking on the individual zone level, since multiple presets can refer to the same instrument
|
|
13
|
+
* @type {number}
|
|
14
|
+
*/
|
|
15
|
+
useCount = 0;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param sample {BasicSample}
|
|
19
|
+
*/
|
|
20
|
+
setSample(sample)
|
|
21
|
+
{
|
|
22
|
+
this.sample = sample;
|
|
23
|
+
this.sample.useCount++;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
deleteZone()
|
|
27
|
+
{
|
|
28
|
+
this.sample.useCount--;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
hasSample()
|
|
32
|
+
{
|
|
33
|
+
return !!this.sample;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
* presetGenerators: Generator[],
|
|
5
5
|
* modulators: Modulator[],
|
|
6
6
|
* sample: BasicSample,
|
|
7
|
-
* sampleID: number,
|
|
8
7
|
* }} SampleAndGenerators
|
|
9
8
|
*/
|
|
10
|
-
import { generatorTypes } from "./generator.js";
|
|
11
9
|
import { Modulator } from "./modulator.js";
|
|
12
10
|
import { isXGDrums } from "../../utils/xg_hacks.js";
|
|
13
11
|
|
|
12
|
+
import { BasicGlobalZone } from "./basic_global_zone.js";
|
|
13
|
+
|
|
14
14
|
export class BasicPreset
|
|
15
15
|
{
|
|
16
16
|
/**
|
|
@@ -44,6 +44,12 @@ export class BasicPreset
|
|
|
44
44
|
*/
|
|
45
45
|
presetZones = [];
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Preset's global zone
|
|
49
|
+
* @type {BasicGlobalZone}
|
|
50
|
+
*/
|
|
51
|
+
globalZone = new BasicGlobalZone();
|
|
52
|
+
|
|
47
53
|
/**
|
|
48
54
|
* unused metadata
|
|
49
55
|
* @type {number}
|
|
@@ -171,62 +177,60 @@ export class BasicPreset
|
|
|
171
177
|
* global zone is always first, so it or nothing
|
|
172
178
|
* @type {Generator[]}
|
|
173
179
|
*/
|
|
174
|
-
let globalPresetGenerators =
|
|
180
|
+
let globalPresetGenerators = [...this.globalZone.generators];
|
|
175
181
|
|
|
176
182
|
/**
|
|
177
183
|
* @type {Modulator[]}
|
|
178
184
|
*/
|
|
179
|
-
let globalPresetModulators =
|
|
180
|
-
const globalKeyRange = this.
|
|
181
|
-
const globalVelRange = this.
|
|
185
|
+
let globalPresetModulators = [...this.globalZone.modulators];
|
|
186
|
+
const globalKeyRange = this.globalZone.keyRange;
|
|
187
|
+
const globalVelRange = this.globalZone.velRange;
|
|
182
188
|
|
|
183
189
|
// find the preset zones in range
|
|
184
190
|
let presetZonesInRange = this.presetZones.filter(currentZone =>
|
|
185
|
-
(
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
) && !currentZone.isGlobal);
|
|
191
|
+
isInRange(
|
|
192
|
+
currentZone.hasKeyRange ? currentZone.keyRange : globalKeyRange,
|
|
193
|
+
midiNote
|
|
194
|
+
)
|
|
195
|
+
&&
|
|
196
|
+
isInRange(
|
|
197
|
+
currentZone.hasVelRange ? currentZone.velRange : globalVelRange,
|
|
198
|
+
velocity
|
|
199
|
+
)
|
|
200
|
+
);
|
|
196
201
|
|
|
197
|
-
presetZonesInRange.forEach(
|
|
202
|
+
presetZonesInRange.forEach(presetZone =>
|
|
198
203
|
{
|
|
204
|
+
const instrument = presetZone.instrument;
|
|
199
205
|
// the global zone is already taken into account earlier
|
|
200
|
-
if (
|
|
206
|
+
if (instrument.instrumentZones.length < 1)
|
|
201
207
|
{
|
|
202
208
|
return;
|
|
203
209
|
}
|
|
204
|
-
let presetGenerators =
|
|
205
|
-
let presetModulators =
|
|
206
|
-
const firstZone = zone.instrument.instrumentZones[0];
|
|
210
|
+
let presetGenerators = presetZone.generators;
|
|
211
|
+
let presetModulators = presetZone.modulators;
|
|
207
212
|
/**
|
|
208
213
|
* global zone is always first, so it or nothing
|
|
209
214
|
* @type {Generator[]}
|
|
210
215
|
*/
|
|
211
|
-
let globalInstrumentGenerators =
|
|
212
|
-
let globalInstrumentModulators =
|
|
213
|
-
const globalKeyRange =
|
|
214
|
-
const globalVelRange =
|
|
216
|
+
let globalInstrumentGenerators = [...instrument.globalZone.generators];
|
|
217
|
+
let globalInstrumentModulators = [...instrument.globalZone.modulators];
|
|
218
|
+
const globalKeyRange = instrument.globalZone.keyRange;
|
|
219
|
+
const globalVelRange = instrument.globalZone.velRange;
|
|
215
220
|
|
|
216
221
|
|
|
217
|
-
let instrumentZonesInRange =
|
|
222
|
+
let instrumentZonesInRange = instrument.instrumentZones
|
|
218
223
|
.filter(currentZone =>
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
) && !currentZone.isGlobal
|
|
224
|
+
|
|
225
|
+
isInRange(
|
|
226
|
+
currentZone.hasKeyRange ? currentZone.keyRange : globalKeyRange,
|
|
227
|
+
midiNote
|
|
228
|
+
)
|
|
229
|
+
&&
|
|
230
|
+
isInRange(
|
|
231
|
+
currentZone.hasVelRange ? currentZone.velRange : globalVelRange,
|
|
232
|
+
velocity
|
|
233
|
+
)
|
|
230
234
|
);
|
|
231
235
|
|
|
232
236
|
instrumentZonesInRange.forEach(instrumentZone =>
|
|
@@ -275,7 +279,8 @@ export class BasicPreset
|
|
|
275
279
|
if (identicalInstrumentModulator !== -1)
|
|
276
280
|
{
|
|
277
281
|
// sum the amounts
|
|
278
|
-
//
|
|
282
|
+
// this makes a new modulator
|
|
283
|
+
// because otherwise it would overwrite the one in the soundfont!
|
|
279
284
|
finalModulatorList[identicalInstrumentModulator] = finalModulatorList[identicalInstrumentModulator].sumTransform(
|
|
280
285
|
mod);
|
|
281
286
|
}
|
|
@@ -291,9 +296,7 @@ export class BasicPreset
|
|
|
291
296
|
instrumentGenerators: instrumentGenerators,
|
|
292
297
|
presetGenerators: presetGenerators,
|
|
293
298
|
modulators: finalModulatorList,
|
|
294
|
-
sample: instrumentZone.sample
|
|
295
|
-
sampleID: instrumentZone.generators.find(
|
|
296
|
-
g => g.generatorType === generatorTypes.sampleID).generatorValue
|
|
299
|
+
sample: instrumentZone.sample
|
|
297
300
|
});
|
|
298
301
|
});
|
|
299
302
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { BasicZone } from "./basic_zone.js";
|
|
2
|
+
|
|
3
|
+
export class BasicPresetZone extends BasicZone
|
|
4
|
+
{
|
|
5
|
+
/**
|
|
6
|
+
* Zone's instrument
|
|
7
|
+
* @type {BasicInstrument}
|
|
8
|
+
*/
|
|
9
|
+
instrument;
|
|
10
|
+
|
|
11
|
+
deleteZone()
|
|
12
|
+
{
|
|
13
|
+
this.instrument.removeUseCount();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param instrument {BasicInstrument}
|
|
18
|
+
*/
|
|
19
|
+
setInstrument(instrument)
|
|
20
|
+
{
|
|
21
|
+
this.instrument = instrument;
|
|
22
|
+
this.instrument.addUseCount();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
hasInstrument()
|
|
27
|
+
{
|
|
28
|
+
return !!this.instrument;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -10,15 +10,20 @@ 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 {
|
|
14
|
-
import { Generator
|
|
13
|
+
import { BasicPresetZone } from "./basic_preset_zone.js";
|
|
14
|
+
import { Generator } from "./generator.js";
|
|
15
15
|
import { BasicInstrument } from "./basic_instrument.js";
|
|
16
16
|
import { BasicPreset } from "./basic_preset.js";
|
|
17
17
|
import { isXGDrums } from "../../utils/xg_hacks.js";
|
|
18
|
+
import { generatorTypes } from "./generator_types.js";
|
|
19
|
+
import { BasicInstrumentZone } from "./basic_instrument_zone.js";
|
|
20
|
+
import { BasicGlobalZone } from "./basic_global_zone.js";
|
|
18
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Represents a single sound bank, be it DLS or SF2.
|
|
24
|
+
*/
|
|
19
25
|
class BasicSoundBank
|
|
20
26
|
{
|
|
21
|
-
|
|
22
27
|
/**
|
|
23
28
|
* Soundfont's info stored as name: value. ifil and iver are stored as string representation of float (e.g., 2.1)
|
|
24
29
|
* @type {Object<string, string|IndexedByteArray>}
|
|
@@ -124,29 +129,28 @@ class BasicSoundBank
|
|
|
124
129
|
}
|
|
125
130
|
font.samples.push(sample);
|
|
126
131
|
|
|
127
|
-
const gZone = new
|
|
128
|
-
gZone.isGlobal = true;
|
|
132
|
+
const gZone = new BasicGlobalZone();
|
|
129
133
|
gZone.generators.push(new Generator(generatorTypes.initialAttenuation, 375));
|
|
130
134
|
gZone.generators.push(new Generator(generatorTypes.releaseVolEnv, -1000));
|
|
131
135
|
gZone.generators.push(new Generator(generatorTypes.sampleModes, 1));
|
|
132
136
|
|
|
133
137
|
const zone1 = new BasicInstrumentZone();
|
|
134
|
-
zone1.sample
|
|
138
|
+
zone1.setSample(sample);
|
|
135
139
|
|
|
136
140
|
const zone2 = new BasicInstrumentZone();
|
|
137
|
-
zone2.sample
|
|
141
|
+
zone2.setSample(sample);
|
|
138
142
|
zone2.generators.push(new Generator(generatorTypes.fineTune, -9));
|
|
139
143
|
|
|
140
144
|
|
|
141
145
|
const inst = new BasicInstrument();
|
|
142
146
|
inst.instrumentName = "Saw Wave";
|
|
143
|
-
inst.
|
|
144
|
-
inst.
|
|
145
|
-
inst.
|
|
147
|
+
inst.globalZone = gZone;
|
|
148
|
+
inst.addZone(zone1);
|
|
149
|
+
inst.addZone(zone2);
|
|
146
150
|
font.instruments.push(inst);
|
|
147
151
|
|
|
148
152
|
const pZone = new BasicPresetZone();
|
|
149
|
-
pZone.
|
|
153
|
+
pZone.setInstrument(inst);
|
|
150
154
|
|
|
151
155
|
const preset = new BasicPreset(font);
|
|
152
156
|
preset.presetName = "Saw Wave";
|
|
@@ -209,7 +213,7 @@ class BasicSoundBank
|
|
|
209
213
|
const soundfont = this;
|
|
210
214
|
|
|
211
215
|
/**
|
|
212
|
-
* @param instrument {
|
|
216
|
+
* @param instrument {BasicInstrument}
|
|
213
217
|
* @param combos {{key: number, velocity: number}[]}
|
|
214
218
|
* @returns {number}
|
|
215
219
|
*/
|
|
@@ -219,10 +223,6 @@ class BasicSoundBank
|
|
|
219
223
|
for (let iZoneIndex = 0; iZoneIndex < instrument.instrumentZones.length; iZoneIndex++)
|
|
220
224
|
{
|
|
221
225
|
const iZone = instrument.instrumentZones[iZoneIndex];
|
|
222
|
-
if (iZone.isGlobal)
|
|
223
|
-
{
|
|
224
|
-
continue;
|
|
225
|
-
}
|
|
226
226
|
const iKeyRange = iZone.keyRange;
|
|
227
227
|
const iVelRange = iZone.velRange;
|
|
228
228
|
let isIZoneUsed = false;
|
|
@@ -240,14 +240,13 @@ class BasicSoundBank
|
|
|
240
240
|
if (!isIZoneUsed)
|
|
241
241
|
{
|
|
242
242
|
SpessaSynthInfo(
|
|
243
|
-
`%c${iZone.sample.sampleName} %cremoved from %c${instrument.instrumentName}%c
|
|
243
|
+
`%c${iZone.sample.sampleName} %cremoved from %c${instrument.instrumentName}%c.`,
|
|
244
244
|
consoleColors.recognized,
|
|
245
245
|
consoleColors.info,
|
|
246
246
|
consoleColors.recognized,
|
|
247
|
-
consoleColors.info
|
|
248
|
-
consoleColors.recognized
|
|
247
|
+
consoleColors.info
|
|
249
248
|
);
|
|
250
|
-
if (instrument.
|
|
249
|
+
if (instrument.deleteZone(iZoneIndex))
|
|
251
250
|
{
|
|
252
251
|
trimmedIZones++;
|
|
253
252
|
iZoneIndex--;
|
|
@@ -293,6 +292,7 @@ class BasicSoundBank
|
|
|
293
292
|
consoleColors.info
|
|
294
293
|
);
|
|
295
294
|
soundfont.deletePreset(p);
|
|
295
|
+
soundfont.removeUnusedElements();
|
|
296
296
|
presetIndex--;
|
|
297
297
|
}
|
|
298
298
|
else
|
|
@@ -316,10 +316,6 @@ class BasicSoundBank
|
|
|
316
316
|
for (let zoneIndex = 0; zoneIndex < p.presetZones.length; zoneIndex++)
|
|
317
317
|
{
|
|
318
318
|
const zone = p.presetZones[zoneIndex];
|
|
319
|
-
if (zone.isGlobal)
|
|
320
|
-
{
|
|
321
|
-
continue;
|
|
322
|
-
}
|
|
323
319
|
const keyRange = zone.keyRange;
|
|
324
320
|
const velRange = zone.velRange;
|
|
325
321
|
// check if any of the combos matches the zone
|
|
@@ -384,13 +380,7 @@ class BasicSoundBank
|
|
|
384
380
|
{
|
|
385
381
|
if (i.useCount < 1)
|
|
386
382
|
{
|
|
387
|
-
i.
|
|
388
|
-
{
|
|
389
|
-
if (!z.isGlobal)
|
|
390
|
-
{
|
|
391
|
-
z.sample.useCount--;
|
|
392
|
-
}
|
|
393
|
-
});
|
|
383
|
+
i.deleteZones();
|
|
394
384
|
}
|
|
395
385
|
});
|
|
396
386
|
this.instruments = this.instruments.filter(i => i.useCount > 0);
|
|
@@ -407,8 +397,7 @@ class BasicSoundBank
|
|
|
407
397
|
throw new Error(`Cannot delete an instrument that has ${instrument.useCount} usages.`);
|
|
408
398
|
}
|
|
409
399
|
this.instruments.splice(this.instruments.indexOf(instrument), 1);
|
|
410
|
-
instrument.
|
|
411
|
-
this.removeUnusedElements();
|
|
400
|
+
instrument.deleteZones();
|
|
412
401
|
}
|
|
413
402
|
|
|
414
403
|
/**
|
|
@@ -418,7 +407,6 @@ class BasicSoundBank
|
|
|
418
407
|
{
|
|
419
408
|
preset.deletePreset();
|
|
420
409
|
this.presets.splice(this.presets.indexOf(preset), 1);
|
|
421
|
-
this.removeUnusedElements();
|
|
422
410
|
}
|
|
423
411
|
|
|
424
412
|
/**
|
|
@@ -431,7 +419,6 @@ class BasicSoundBank
|
|
|
431
419
|
throw new Error(`Cannot delete sample that has ${sample.useCount} usages.`);
|
|
432
420
|
}
|
|
433
421
|
this.samples.splice(this.samples.indexOf(sample), 1);
|
|
434
|
-
this.removeUnusedElements();
|
|
435
422
|
}
|
|
436
423
|
|
|
437
424
|
/**
|
|
@@ -563,15 +550,6 @@ class BasicSoundBank
|
|
|
563
550
|
delete this.instruments;
|
|
564
551
|
delete this.samples;
|
|
565
552
|
}
|
|
566
|
-
|
|
567
|
-
// noinspection JSUnusedGlobalSymbols
|
|
568
|
-
/**
|
|
569
|
-
* Clears the cache for all the presets
|
|
570
|
-
*/
|
|
571
|
-
clearCache()
|
|
572
|
-
{
|
|
573
|
-
this.presets.forEach(p => p.clearCache());
|
|
574
|
-
}
|
|
575
553
|
}
|
|
576
554
|
|
|
577
555
|
BasicSoundBank.prototype.write = write;
|