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.
Files changed (61) hide show
  1. package/index.js +5 -3
  2. package/package.json +1 -1
  3. package/src/externals/README.md +6 -0
  4. package/src/sequencer/README.md +5 -1
  5. package/src/soundfont/README.md +6 -8
  6. package/src/soundfont/basic_soundfont/basic_global_zone.js +16 -0
  7. package/src/soundfont/basic_soundfont/basic_instrument.js +26 -22
  8. package/src/soundfont/basic_soundfont/basic_instrument_zone.js +35 -0
  9. package/src/soundfont/basic_soundfont/basic_preset.js +45 -42
  10. package/src/soundfont/basic_soundfont/basic_preset_zone.js +30 -0
  11. package/src/soundfont/basic_soundfont/{basic_soundfont.js → basic_soundbank.js} +22 -44
  12. package/src/soundfont/basic_soundfont/basic_zone.js +1 -5
  13. package/src/soundfont/basic_soundfont/generator.js +2 -152
  14. package/src/soundfont/basic_soundfont/generator_types.js +151 -0
  15. package/src/soundfont/basic_soundfont/modulator.js +251 -79
  16. package/src/soundfont/basic_soundfont/write_dls/art2.js +3 -2
  17. package/src/soundfont/basic_soundfont/write_dls/combine_zones.js +25 -42
  18. package/src/soundfont/basic_soundfont/write_dls/ins.js +11 -27
  19. package/src/soundfont/basic_soundfont/write_dls/modulator_converter.js +2 -2
  20. package/src/soundfont/basic_soundfont/write_dls/rgn2.js +2 -2
  21. package/src/soundfont/basic_soundfont/write_sf2/ibag.js +21 -10
  22. package/src/soundfont/basic_soundfont/write_sf2/igen.js +31 -27
  23. package/src/soundfont/basic_soundfont/write_sf2/imod.js +24 -14
  24. package/src/soundfont/basic_soundfont/write_sf2/inst.js +4 -5
  25. package/src/soundfont/basic_soundfont/write_sf2/pbag.js +20 -9
  26. package/src/soundfont/basic_soundfont/write_sf2/pgen.js +32 -29
  27. package/src/soundfont/basic_soundfont/write_sf2/phdr.js +4 -2
  28. package/src/soundfont/basic_soundfont/write_sf2/pmod.js +25 -15
  29. package/src/soundfont/basic_soundfont/write_sf2/write.js +2 -2
  30. package/src/soundfont/dls/articulator_converter.js +9 -3
  31. package/src/soundfont/dls/dls_preset.js +2 -3
  32. package/src/soundfont/dls/dls_soundfont.js +1 -1
  33. package/src/soundfont/dls/dls_sources.js +7 -6
  34. package/src/soundfont/dls/dls_zone.js +4 -5
  35. package/src/soundfont/dls/read_articulation.js +2 -1
  36. package/src/soundfont/dls/read_instrument.js +3 -6
  37. package/src/soundfont/dls/read_lart.js +1 -1
  38. package/src/soundfont/dls/read_region.js +2 -1
  39. package/src/soundfont/read_sf2/instruments.js +10 -1
  40. package/src/soundfont/read_sf2/modulators.js +10 -23
  41. package/src/soundfont/read_sf2/presets.js +10 -1
  42. package/src/soundfont/read_sf2/soundfont.js +1 -2
  43. package/src/soundfont/read_sf2/zones.js +30 -14
  44. package/src/synthetizer/README.md +3 -3
  45. package/src/synthetizer/audio_engine/README.md +1 -1
  46. package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +1 -1
  47. package/src/synthetizer/audio_engine/engine_components/dynamic_modulator_system.js +11 -3
  48. package/src/synthetizer/audio_engine/engine_components/lowpass_filter.js +1 -1
  49. package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +1 -1
  50. package/src/synthetizer/audio_engine/engine_components/modulation_envelope.js +1 -1
  51. package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +1 -1
  52. package/src/synthetizer/audio_engine/engine_components/voice.js +7 -10
  53. package/src/synthetizer/audio_engine/engine_components/volume_envelope.js +2 -1
  54. package/src/synthetizer/audio_engine/engine_methods/data_entry/awe32.js +1 -1
  55. package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +7 -0
  56. package/src/synthetizer/audio_engine/engine_methods/note_on.js +1 -1
  57. package/src/synthetizer/audio_engine/engine_methods/render_voice.js +1 -1
  58. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +1 -1
  59. package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +2 -1
  60. package/src/utils/README.md +5 -2
  61. package/src/soundfont/basic_soundfont/basic_zones.js +0 -43
@@ -1,5 +1,6 @@
1
- import { Modulator } from "../basic_soundfont/modulator.js";
2
- import { generatorTypes } from "../basic_soundfont/generator.js";
1
+ import { DecodedModulator } from "../basic_soundfont/modulator.js";
2
+
3
+ import { generatorTypes } from "../basic_soundfont/generator_types.js";
3
4
 
4
5
  /**
5
6
  * @enum {number}
@@ -29,7 +30,7 @@ export const DLSSources = {
29
30
  coarseTune: 0x102
30
31
  };
31
32
 
32
- export const DEFAULT_DLS_REVERB = new Modulator(
33
+ export const DEFAULT_DLS_REVERB = new DecodedModulator(
33
34
  0x00DB,
34
35
  0x0,
35
36
  generatorTypes.reverbEffectsSend,
@@ -37,7 +38,7 @@ export const DEFAULT_DLS_REVERB = new Modulator(
37
38
  0
38
39
  );
39
40
 
40
- export const DEFAULT_DLS_CHORUS = new Modulator(
41
+ export const DEFAULT_DLS_CHORUS = new DecodedModulator(
41
42
  0x00DD,
42
43
  0x0,
43
44
  generatorTypes.chorusEffectsSend,
@@ -45,7 +46,7 @@ export const DEFAULT_DLS_CHORUS = new Modulator(
45
46
  0
46
47
  );
47
48
 
48
- export const DLS_1_NO_VIBRATO_MOD = new Modulator(
49
+ export const DLS_1_NO_VIBRATO_MOD = new DecodedModulator(
49
50
  0x0081,
50
51
  0x0,
51
52
  generatorTypes.vibLfoToPitch,
@@ -53,7 +54,7 @@ export const DLS_1_NO_VIBRATO_MOD = new Modulator(
53
54
  0
54
55
  );
55
56
 
56
- export const DLS_1_NO_VIBRATO_PRESSURE = new Modulator(
57
+ export const DLS_1_NO_VIBRATO_PRESSURE = new DecodedModulator(
57
58
  0x000D,
58
59
  0x0,
59
60
  generatorTypes.vibLfoToPitch,
@@ -1,5 +1,6 @@
1
- import { BasicInstrumentZone } from "../basic_soundfont/basic_zones.js";
2
- import { Generator, generatorTypes } from "../basic_soundfont/generator.js";
1
+ import { Generator } from "../basic_soundfont/generator.js";
2
+ import { generatorTypes } from "../basic_soundfont/generator_types.js";
3
+ import { BasicInstrumentZone } from "../basic_soundfont/basic_instrument_zone.js";
3
4
 
4
5
  export class DLSZone extends BasicInstrumentZone
5
6
  {
@@ -12,7 +13,6 @@ export class DLSZone extends BasicInstrumentZone
12
13
  super();
13
14
  this.keyRange = keyRange;
14
15
  this.velRange = velRange;
15
- this.isGlobal = true;
16
16
  }
17
17
 
18
18
  /**
@@ -89,7 +89,6 @@ export class DLSZone extends BasicInstrumentZone
89
89
  }
90
90
  // add sample ID
91
91
  this.generators.push(new Generator(generatorTypes.sampleID, sampleID));
92
- this.sample = sample;
93
- sample.useCount++;
92
+ this.setSample(sample);
94
93
  }
95
94
  }
@@ -4,8 +4,9 @@ import { DLS_1_NO_VIBRATO_MOD, DLS_1_NO_VIBRATO_PRESSURE, DLSSources } from "./d
4
4
  import { getSF2ModulatorFromArticulator } from "./articulator_converter.js";
5
5
  import { SpessaSynthInfo, SpessaSynthWarn } from "../../utils/loggin.js";
6
6
  import { consoleColors } from "../../utils/other.js";
7
- import { Generator, generatorTypes } from "../basic_soundfont/generator.js";
7
+ import { Generator } from "../basic_soundfont/generator.js";
8
8
  import { Modulator } from "../basic_soundfont/modulator.js";
9
+ import { generatorTypes } from "../basic_soundfont/generator_types.js";
9
10
 
10
11
 
11
12
  /**
@@ -3,11 +3,10 @@ import { readLittleEndian } from "../../utils/byte_functions/little_endian.js";
3
3
  import { DLSPreset } from "./dls_preset.js";
4
4
  import { findRIFFListType, readRIFFChunk } from "../basic_soundfont/riff_chunk.js";
5
5
  import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd } from "../../utils/loggin.js";
6
- import { BasicInstrumentZone } from "../basic_soundfont/basic_zones.js";
7
6
  import { consoleColors } from "../../utils/other.js";
8
- import { generatorLimits, generatorTypes } from "../basic_soundfont/generator.js";
9
7
  import { Modulator } from "../basic_soundfont/modulator.js";
10
8
  import { DEFAULT_DLS_CHORUS, DEFAULT_DLS_REVERB } from "./dls_sources.js";
9
+ import { generatorLimits, generatorTypes } from "../basic_soundfont/generator_types.js";
11
10
 
12
11
  /**
13
12
  * @this {DLSSoundFont}
@@ -70,8 +69,7 @@ export function readDLSInstrument(chunk)
70
69
  }
71
70
 
72
71
  // global articulation: essentially global zone
73
- const globalZone = new BasicInstrumentZone();
74
- globalZone.isGlobal = true;
72
+ const globalZone = preset.DLSInstrument.globalZone;
75
73
 
76
74
  // read articulators
77
75
  const globalLart = findRIFFListType(chunks, "lart");
@@ -93,7 +91,6 @@ export function readDLSInstrument(chunk)
93
91
  {
94
92
  globalZone.modulators.push(Modulator.copy(DEFAULT_DLS_CHORUS));
95
93
  }
96
- preset.DLSInstrument.instrumentZones.push(globalZone);
97
94
 
98
95
  // read regions
99
96
  for (let i = 0; i < regions; i++)
@@ -111,7 +108,7 @@ export function readDLSInstrument(chunk)
111
108
  const zone = this.readRegion(chunk);
112
109
  if (zone)
113
110
  {
114
- preset.DLSInstrument.instrumentZones.push(zone);
111
+ preset.DLSInstrument.addZone(zone);
115
112
  }
116
113
  }
117
114
 
@@ -4,7 +4,7 @@ import { readArticulation } from "./read_articulation.js";
4
4
  /**
5
5
  * @param lartChunk {RiffChunk|undefined}
6
6
  * @param lar2Chunk {RiffChunk|undefined}
7
- * @param zone {BasicInstrumentZone}
7
+ * @param zone {BasicZone}
8
8
  * @this {DLSSoundFont}
9
9
  */
10
10
  export function readLart(lartChunk, lar2Chunk, zone)
@@ -1,7 +1,8 @@
1
1
  import { readLittleEndian, signedInt16 } from "../../utils/byte_functions/little_endian.js";
2
2
  import { findRIFFListType, readRIFFChunk } from "../basic_soundfont/riff_chunk.js";
3
3
  import { DLSZone } from "./dls_zone.js";
4
- import { Generator, generatorTypes } from "../basic_soundfont/generator.js";
4
+ import { Generator } from "../basic_soundfont/generator.js";
5
+ import { generatorTypes } from "../basic_soundfont/generator_types.js";
5
6
 
6
7
  /**
7
8
  * @this {DLSSoundFont}
@@ -33,7 +33,16 @@ export class Instrument extends BasicInstrument
33
33
  this.instrumentZonesAmount = amount;
34
34
  for (let i = this.instrumentZoneIndex; i < this.instrumentZonesAmount + this.instrumentZoneIndex; i++)
35
35
  {
36
- this.instrumentZones.push(zones[i]);
36
+ const zone = zones[i];
37
+ if (zone.hasSample())
38
+ {
39
+ this.addZone(zone);
40
+ }
41
+ else
42
+ {
43
+ // global!
44
+ this.globalZone.copyFrom(zone);
45
+ }
37
46
  }
38
47
  }
39
48
  }
@@ -1,24 +1,5 @@
1
1
  import { readLittleEndian, signedInt16 } from "../../utils/byte_functions/little_endian.js";
2
- import { IndexedByteArray } from "../../utils/indexed_array.js";
3
- import { Modulator } from "../basic_soundfont/modulator.js";
4
-
5
-
6
- export class ReadModulator extends Modulator
7
- {
8
- /**
9
- * Creates a modulator
10
- * @param dataArray {IndexedByteArray}
11
- */
12
- constructor(dataArray)
13
- {
14
- const srcEnum = readLittleEndian(dataArray, 2);
15
- const destination = readLittleEndian(dataArray, 2);
16
- const amount = signedInt16(dataArray[dataArray.currentIndex++], dataArray[dataArray.currentIndex++]);
17
- const secSrcEnum = readLittleEndian(dataArray, 2);
18
- const transformType = readLittleEndian(dataArray, 2);
19
- super(srcEnum, secSrcEnum, destination, amount, transformType);
20
- }
21
- }
2
+ import { DecodedModulator, Modulator } from "../basic_soundfont/modulator.js";
22
3
 
23
4
  /**
24
5
  * Reads the modulator read
@@ -27,10 +8,16 @@ export class ReadModulator extends Modulator
27
8
  */
28
9
  export function readModulators(modulatorChunk)
29
10
  {
30
- let gens = [];
11
+ let mods = [];
31
12
  while (modulatorChunk.chunkData.length > modulatorChunk.chunkData.currentIndex)
32
13
  {
33
- gens.push(new ReadModulator(modulatorChunk.chunkData));
14
+ const dataArray = modulatorChunk.chunkData;
15
+ const sourceEnum = readLittleEndian(dataArray, 2);
16
+ const destination = readLittleEndian(dataArray, 2);
17
+ const amount = signedInt16(dataArray[dataArray.currentIndex++], dataArray[dataArray.currentIndex++]);
18
+ const secondarySourceEnum = readLittleEndian(dataArray, 2);
19
+ const transformType = readLittleEndian(dataArray, 2);
20
+ mods.push(new DecodedModulator(sourceEnum, secondarySourceEnum, destination, amount, transformType));
34
21
  }
35
- return gens;
22
+ return mods;
36
23
  }
@@ -43,7 +43,16 @@ export class Preset extends BasicPreset
43
43
  this.presetZonesAmount = amount;
44
44
  for (let i = this.presetZoneStartIndex; i < this.presetZonesAmount + this.presetZoneStartIndex; i++)
45
45
  {
46
- this.presetZones.push(zones[i]);
46
+ const zone = zones[i];
47
+ if (zone.hasInstrument())
48
+ {
49
+ this.presetZones.push(zone);
50
+ }
51
+ else
52
+ {
53
+ // global!
54
+ this.globalZone.copyFrom(zone);
55
+ }
47
56
  }
48
57
  }
49
58
  }
@@ -11,7 +11,7 @@ import { consoleColors } from "../../utils/other.js";
11
11
  import { SpessaSynthGroup, SpessaSynthGroupEnd, SpessaSynthInfo } from "../../utils/loggin.js";
12
12
  import { readBytesAsString } from "../../utils/byte_functions/string.js";
13
13
  import { stbvorbis } from "../../externals/stbvorbis_sync/stbvorbis_sync.min.js";
14
- import { BasicSoundBank } from "../basic_soundfont/basic_soundfont.js";
14
+ import { BasicSoundBank } from "../basic_soundfont/basic_soundbank.js";
15
15
  import { Generator } from "../basic_soundfont/generator.js";
16
16
  import { Modulator } from "../basic_soundfont/modulator.js";
17
17
 
@@ -215,7 +215,6 @@ export class SoundFont2 extends BasicSoundBank
215
215
  * @type {Modulator[]}
216
216
  */
217
217
  let instrumentModulators = readModulators(presetInstrumentModulatorsChunk);
218
-
219
218
  /**
220
219
  * read all the instrument zones
221
220
  * @type {InstrumentZone[]}
@@ -1,9 +1,11 @@
1
1
  import { readLittleEndian } from "../../utils/byte_functions/little_endian.js";
2
2
  import { IndexedByteArray } from "../../utils/indexed_array.js";
3
3
  import { RiffChunk } from "../basic_soundfont/riff_chunk.js";
4
- import { BasicInstrumentZone, BasicPresetZone } from "../basic_soundfont/basic_zones.js";
5
- import { Generator, generatorTypes } from "../basic_soundfont/generator.js";
4
+ import { BasicPresetZone } from "../basic_soundfont/basic_preset_zone.js";
5
+ import { Generator } from "../basic_soundfont/generator.js";
6
6
  import { Modulator } from "../basic_soundfont/modulator.js";
7
+ import { generatorTypes } from "../basic_soundfont/generator_types.js";
8
+ import { BasicInstrumentZone } from "../basic_soundfont/basic_instrument_zone.js";
7
9
 
8
10
  /**
9
11
  * zones.js
@@ -23,7 +25,6 @@ export class InstrumentZone extends BasicInstrumentZone
23
25
  this.modulatorZoneStartIndex = readLittleEndian(dataArray, 2);
24
26
  this.modulatorZoneSize = 0;
25
27
  this.generatorZoneSize = 0;
26
- this.isGlobal = true;
27
28
  }
28
29
 
29
30
  setZoneSize(modulatorZoneSize, generatorZoneSize)
@@ -40,7 +41,12 @@ export class InstrumentZone extends BasicInstrumentZone
40
41
  {
41
42
  for (let i = this.generatorZoneStartIndex; i < this.generatorZoneStartIndex + this.generatorZoneSize; i++)
42
43
  {
43
- this.generators.push(generators[i]);
44
+ const g = generators[i];
45
+ if (!g)
46
+ {
47
+ throw new Error("Missing generator in instrument zone! The file may corrupted.");
48
+ }
49
+ this.generators.push(g);
44
50
  }
45
51
  }
46
52
 
@@ -52,7 +58,12 @@ export class InstrumentZone extends BasicInstrumentZone
52
58
  {
53
59
  for (let i = this.modulatorZoneStartIndex; i < this.modulatorZoneStartIndex + this.modulatorZoneSize; i++)
54
60
  {
55
- this.modulators.push(modulators[i]);
61
+ const m = modulators[i];
62
+ if (!m)
63
+ {
64
+ throw new Error("Missing modulator in instrument zone! The file may corrupted.");
65
+ }
66
+ this.modulators.push(m);
56
67
  }
57
68
  }
58
69
 
@@ -65,9 +76,7 @@ export class InstrumentZone extends BasicInstrumentZone
65
76
  let sampleID = this.generators.find(g => g.generatorType === generatorTypes.sampleID);
66
77
  if (sampleID)
67
78
  {
68
- this.sample = samples[sampleID.generatorValue];
69
- this.isGlobal = false;
70
- this.sample.useCount++;
79
+ this.setSample(samples[sampleID.generatorValue]);
71
80
  }
72
81
  }
73
82
 
@@ -149,7 +158,6 @@ export class PresetZone extends BasicPresetZone
149
158
  this.modulatorZoneStartIndex = readLittleEndian(dataArray, 2);
150
159
  this.modulatorZoneSize = 0;
151
160
  this.generatorZoneSize = 0;
152
- this.isGlobal = true;
153
161
  }
154
162
 
155
163
  setZoneSize(modulatorZoneSize, generatorZoneSize)
@@ -166,7 +174,12 @@ export class PresetZone extends BasicPresetZone
166
174
  {
167
175
  for (let i = this.generatorZoneStartIndex; i < this.generatorZoneStartIndex + this.generatorZoneSize; i++)
168
176
  {
169
- this.generators.push(generators[i]);
177
+ const g = generators[i];
178
+ if (!g)
179
+ {
180
+ throw new Error("Missing generator in preset zone! The file may corrupted.");
181
+ }
182
+ this.generators.push(g);
170
183
  }
171
184
  }
172
185
 
@@ -178,7 +191,12 @@ export class PresetZone extends BasicPresetZone
178
191
  {
179
192
  for (let i = this.modulatorZoneStartIndex; i < this.modulatorZoneStartIndex + this.modulatorZoneSize; i++)
180
193
  {
181
- this.modulators.push(modulators[i]);
194
+ const m = modulators[i];
195
+ if (!m)
196
+ {
197
+ throw new Error("Missing modulator in preset zone! The file may corrupted.");
198
+ }
199
+ this.modulators.push(m);
182
200
  }
183
201
  }
184
202
 
@@ -191,9 +209,7 @@ export class PresetZone extends BasicPresetZone
191
209
  let instrumentID = this.generators.find(g => g.generatorType === generatorTypes.instrument);
192
210
  if (instrumentID)
193
211
  {
194
- this.instrument = instruments[instrumentID.generatorValue];
195
- this.instrument.addUseCount();
196
- this.isGlobal = false;
212
+ this.setInstrument(instruments[instrumentID.generatorValue]);
197
213
  }
198
214
  }
199
215
 
@@ -1,7 +1,7 @@
1
- ## This is the main synthesizer folder.
1
+ ## This is the synthesizer folder.
2
2
 
3
3
  The code here is responsible for making the actual sound.
4
4
  This is the heart of the SpessaSynth library.
5
5
 
6
- - `audio_engine` - the core synthesis engine, it theoretically can run on non-browser environments.
7
- - `audio_effects` - the WebAudioAPI audio effects.
6
+ - `audio_engine` - the core synthesis engine, it theoretically can run on non-browser environments
7
+ - `synth_constants.js` - contains the synthesizer's configuration constants
@@ -6,4 +6,4 @@ The code here is responsible for a single midi channel, synthesizing the sound t
6
6
  - `engine_components` contains the various digital signal processing functions such as the wavetable oscillator, low
7
7
  pass filter, etc.
8
8
 
9
- For those interested, `render_voice.js` file contains the actual DSP synthesis code.
9
+ For those interested, `engine_methods/render_voice.js` file contains the actual DSP synthesis code.
@@ -1,10 +1,10 @@
1
1
  import { getModulatorCurveValue, MOD_PRECOMPUTED_LENGTH } from "./modulator_curves.js";
2
2
  import { VolumeEnvelope } from "./volume_envelope.js";
3
3
  import { ModulationEnvelope } from "./modulation_envelope.js";
4
- import { generatorLimits, generatorTypes } from "../../../soundfont/basic_soundfont/generator.js";
5
4
  import { Modulator, modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
6
5
  import { NON_CC_INDEX_OFFSET } from "./controller_tables.js";
7
6
  import { SpessaSynthWarn } from "../../../utils/loggin.js";
7
+ import { generatorLimits, generatorTypes } from "../../../soundfont/basic_soundfont/generator_types.js";
8
8
 
9
9
  /**
10
10
  * compute_modulator.js
@@ -1,4 +1,4 @@
1
- import { getModSourceEnum, Modulator, modulatorCurveTypes } from "../../../soundfont/basic_soundfont/modulator.js";
1
+ import { Modulator, modulatorCurveTypes, modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
2
2
  import { NON_CC_INDEX_OFFSET } from "./controller_tables.js";
3
3
 
4
4
  /**
@@ -72,8 +72,16 @@ export class DynamicModulatorSystem
72
72
  isCC = true;
73
73
  }
74
74
  const modulator = new Modulator(
75
- getModSourceEnum(modulatorCurveTypes.linear, isBipolar, 0, isCC, srcNum),
76
- 0x0, // linear no controller
75
+ srcNum,
76
+ modulatorCurveTypes.linear,
77
+ isCC ? 1 : 0,
78
+ isBipolar ? 1 : 0,
79
+ 0,
80
+ modulatorSources.noController,
81
+ modulatorCurveTypes.linear,
82
+ 0,
83
+ 0,
84
+ 0,
77
85
  destination,
78
86
  amount,
79
87
  0
@@ -1,5 +1,5 @@
1
1
  import { absCentsToHz, decibelAttenuationToGain } from "./unit_converter.js";
2
- import { generatorTypes } from "../../../soundfont/basic_soundfont/generator.js";
2
+ import { generatorTypes } from "../../../soundfont/basic_soundfont/generator_types.js";
3
3
 
4
4
  /**
5
5
  * lowpass_filter.js
@@ -32,8 +32,8 @@ import { chooseBank, isSystemXG, parseBankSelect } from "../../../utils/xg_hacks
32
32
  import { DEFAULT_PERCUSSION, GENERATOR_OVERRIDE_NO_CHANGE_VALUE } from "../../synth_constants.js";
33
33
  import { modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
34
34
  import { DynamicModulatorSystem } from "./dynamic_modulator_system.js";
35
- import { generatorLimits, GENERATORS_AMOUNT } from "../../../soundfont/basic_soundfont/generator.js";
36
35
  import { computeModulators } from "./compute_modulator.js";
36
+ import { generatorLimits, GENERATORS_AMOUNT } from "../../../soundfont/basic_soundfont/generator_types.js";
37
37
 
38
38
  /**
39
39
  * This class represents a single MIDI Channel within the synthesizer.
@@ -1,7 +1,7 @@
1
1
  import { timecentsToSeconds } from "./unit_converter.js";
2
2
  import { getModulatorCurveValue } from "./modulator_curves.js";
3
- import { generatorTypes } from "../../../soundfont/basic_soundfont/generator.js";
4
3
  import { modulatorCurveTypes } from "../../../soundfont/basic_soundfont/modulator.js";
4
+ import { generatorTypes } from "../../../soundfont/basic_soundfont/generator_types.js";
5
5
 
6
6
  /**
7
7
  * modulation_envelope.js
@@ -1,4 +1,4 @@
1
- import { generatorTypes } from "../../../soundfont/basic_soundfont/generator.js";
1
+ import { generatorTypes } from "../../../soundfont/basic_soundfont/generator_types.js";
2
2
 
3
3
  /**
4
4
  * stereo_panner.js
@@ -7,12 +7,9 @@ import { SpessaSynthWarn } from "../../../utils/loggin.js";
7
7
  import { LowpassFilter } from "./lowpass_filter.js";
8
8
  import { VolumeEnvelope } from "./volume_envelope.js";
9
9
  import { ModulationEnvelope } from "./modulation_envelope.js";
10
- import {
11
- addAndClampGenerator,
12
- GENERATORS_AMOUNT,
13
- generatorTypes
14
- } from "../../../soundfont/basic_soundfont/generator.js";
10
+ import { addAndClampGenerator } from "../../../soundfont/basic_soundfont/generator.js";
15
11
  import { Modulator } from "../../../soundfont/basic_soundfont/modulator.js";
12
+ import { GENERATORS_AMOUNT, generatorTypes } from "../../../soundfont/basic_soundfont/generator_types.js";
16
13
 
17
14
  const EXCLUSIVE_CUTOFF_TIME = -2320;
18
15
  const EXCLUSIVE_MOD_CUTOFF_TIME = -1130; // less because filter shenanigans
@@ -330,7 +327,7 @@ class Voice
330
327
  currentTime,
331
328
  voice.targetKey,
332
329
  realKey,
333
- voice.generators,
330
+ new Int16Array(voice.generators),
334
331
  voice.modulators.map(m => Modulator.copy(m))
335
332
  );
336
333
  }
@@ -401,7 +398,7 @@ export function getVoicesForPreset(preset, bank, program, midiNote, velocity, re
401
398
  }
402
399
 
403
400
  // EMU initial attenuation correction, multiply initial attenuation by 0.4!
404
- // all EMU sound cards have this quirk and all sf2 editors and players emulate it too
401
+ // all EMU sound cards have this quirk, and all sf2 editors and players emulate it too
405
402
  generators[generatorTypes.initialAttenuation] = Math.floor(generators[generatorTypes.initialAttenuation] * 0.4);
406
403
 
407
404
  // key override
@@ -473,9 +470,9 @@ export function getVoicesForPreset(preset, bank, program, midiNote, velocity, re
473
470
  return voices;
474
471
  }, []);
475
472
  // cache the voice
476
- this.setCachedVoice(bank, program, midiNote, velocity, voices.map(v =>
477
- Voice.copy(v, this.currentSynthTime, realKey)));
478
- return voices;
473
+ this.setCachedVoice(bank, program, midiNote, velocity, voices);
474
+ return voices.map(v =>
475
+ Voice.copy(v, this.currentSynthTime, realKey));
479
476
  }
480
477
 
481
478
  /**
@@ -1,6 +1,7 @@
1
1
  import { decibelAttenuationToGain, timecentsToSeconds } from "./unit_converter.js";
2
2
 
3
- import { generatorTypes } from "../../../soundfont/basic_soundfont/generator.js";
3
+
4
+ import { generatorTypes } from "../../../soundfont/basic_soundfont/generator_types.js";
4
5
 
5
6
  /**
6
7
  * volume_envelope.js
@@ -1,6 +1,6 @@
1
- import { generatorTypes } from "../../../../soundfont/basic_soundfont/generator.js";
2
1
  import { SpessaSynthWarn } from "../../../../utils/loggin.js";
3
2
  import { consoleColors } from "../../../../utils/other.js";
3
+ import { generatorTypes } from "../../../../soundfont/basic_soundfont/generator_types.js";
4
4
 
5
5
  /**
6
6
  * http://archive.gamedev.net/archive/reference/articles/article445.html
@@ -54,6 +54,13 @@ export function dataEntryCoarse(dataValue)
54
54
  {
55
55
  // store in cc table
56
56
  this.midiControllers[midiControllers.dataEntryMsb] = dataValue << 7;
57
+ /*
58
+ A note on this vibrato.
59
+ This is a completely custom vibrato, with its own oscillator and parameters.
60
+ It is disabled by default,
61
+ only being enabled when one of the NPRN messages changing it is received
62
+ and stays on until the next system-reset.
63
+ */
57
64
  const addDefaultVibrato = () =>
58
65
  {
59
66
  if (this.channelVibrato.delay === 0 && this.channelVibrato.rate === 0 && this.channelVibrato.depth === 0)
@@ -1,9 +1,9 @@
1
- import { generatorTypes } from "../../../soundfont/basic_soundfont/generator.js";
2
1
  import { midiControllers } from "../../../midi/midi_message.js";
3
2
  import { portamentoTimeToSeconds } from "./portamento_time.js";
4
3
  import { customControllers } from "../engine_components/controller_tables.js";
5
4
  import { Modulator } from "../../../soundfont/basic_soundfont/modulator.js";
6
5
  import { GENERATOR_OVERRIDE_NO_CHANGE_VALUE } from "../../synth_constants.js";
6
+ import { generatorTypes } from "../../../soundfont/basic_soundfont/generator_types.js";
7
7
 
8
8
  /**
9
9
  * sends a "MIDI Note on message"
@@ -1,12 +1,12 @@
1
1
  import { VolumeEnvelope } from "../engine_components/volume_envelope.js";
2
2
  import { ModulationEnvelope } from "../engine_components/modulation_envelope.js";
3
- import { generatorTypes } from "../../../soundfont/basic_soundfont/generator.js";
4
3
  import { customControllers } from "../engine_components/controller_tables.js";
5
4
  import { absCentsToHz, timecentsToSeconds } from "../engine_components/unit_converter.js";
6
5
  import { getLFOValue } from "../engine_components/lfo.js";
7
6
  import { WavetableOscillator } from "../engine_components/wavetable_oscillator.js";
8
7
  import { LowpassFilter } from "../engine_components/lowpass_filter.js";
9
8
  import { interpolationTypes } from "../engine_components/enums.js";
9
+ import { generatorTypes } from "../../../soundfont/basic_soundfont/generator_types.js";
10
10
 
11
11
  /**
12
12
  * Renders a voice to the stereo output buffer
@@ -1,5 +1,5 @@
1
- import { generatorTypes } from "../../../../soundfont/basic_soundfont/generator.js";
2
1
  import { customControllers } from "../../engine_components/controller_tables.js";
2
+ import { generatorTypes } from "../../../../soundfont/basic_soundfont/generator_types.js";
3
3
 
4
4
  /**
5
5
  * Stops a note nearly instantly
@@ -8,7 +8,8 @@ import { readBytesAsString } from "../../../utils/byte_functions/string.js";
8
8
  import { synthDisplayTypes } from "../engine_components/enums.js";
9
9
  import { customControllers, NON_CC_INDEX_OFFSET } from "../engine_components/controller_tables.js";
10
10
  import { modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
11
- import { generatorTypes } from "../../../soundfont/basic_soundfont/generator.js";
11
+
12
+ import { generatorTypes } from "../../../soundfont/basic_soundfont/generator_types.js";
12
13
 
13
14
  /**
14
15
  * KeyNum: tuning
@@ -1,5 +1,8 @@
1
1
  ## This is the utility folder.
2
2
 
3
- There are various utilites here used by the SpessaSynth library.
3
+ There are various utilities here used by the SpessaSynth library.
4
4
 
5
- ### Note that the stbvorbis_sync.js is licensed under Apache-2.0.
5
+ - `byte_functions` - low-level byte manipulation utilities
6
+ - `buffer_to_wav.js` - converts audio buffer to WAV format
7
+ - `sysex_detector.js` - detects various System Exclusive messages
8
+ - `xg_hacks.js` - XG-specific MIDI handling utilities
@@ -1,43 +0,0 @@
1
- import { BasicZone } from "./basic_zone.js";
2
-
3
- export class BasicInstrumentZone extends BasicZone
4
- {
5
- /**
6
- * Zone's sample. Undefined if global
7
- * @type {BasicSample|undefined}
8
- */
9
- sample = undefined;
10
- /**
11
- * The zone's use count
12
- * @type {number}
13
- */
14
- useCount = 0;
15
-
16
- deleteZone()
17
- {
18
- this.useCount--;
19
- if (this.isGlobal)
20
- {
21
- return;
22
- }
23
- this.sample.useCount--;
24
- }
25
- }
26
-
27
- export class BasicPresetZone extends BasicZone
28
- {
29
- /**
30
- * Zone's instrument. Undefined if global
31
- * @type {BasicInstrument|undefined}
32
- */
33
- instrument = undefined;
34
-
35
- deleteZone()
36
- {
37
- if (this.isGlobal)
38
- {
39
- return;
40
- }
41
- this.instrument.removeUseCount();
42
- }
43
- }