spessasynth_lib 3.24.28 → 3.24.35

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 (74) hide show
  1. package/README.md +1 -1
  2. package/external_midi/web_midi_link.js +1 -1
  3. package/index.js +8 -52
  4. package/midi_parser/basic_midi.js +15 -30
  5. package/midi_parser/midi_builder.js +6 -6
  6. package/midi_parser/midi_data.js +2 -2
  7. package/midi_parser/midi_editor.js +15 -15
  8. package/midi_parser/midi_loader.js +3 -3
  9. package/midi_parser/midi_message.js +2 -2
  10. package/midi_parser/midi_sequence.js +32 -4
  11. package/midi_parser/midi_writer.js +8 -8
  12. package/midi_parser/rmidi_writer.js +20 -21
  13. package/midi_parser/used_keys_loaded.js +8 -6
  14. package/package.json +1 -1
  15. package/sequencer/sequencer.js +6 -6
  16. package/sequencer/worklet_sequencer/events.js +2 -1
  17. package/sequencer/worklet_sequencer/play.js +2 -3
  18. package/sequencer/worklet_sequencer/process_event.js +1 -1
  19. package/sequencer/worklet_sequencer/process_tick.js +1 -1
  20. package/sequencer/worklet_sequencer/sequencer_message.js +1 -1
  21. package/sequencer/worklet_sequencer/song_control.js +6 -7
  22. package/sequencer/worklet_sequencer/worklet_sequencer.js +2 -1
  23. package/soundfont/basic_soundfont/basic_soundfont.js +197 -13
  24. package/soundfont/basic_soundfont/generator.js +18 -16
  25. package/soundfont/basic_soundfont/modulator.js +3 -0
  26. package/soundfont/basic_soundfont/riff_chunk.js +2 -2
  27. package/soundfont/basic_soundfont/write_dls/art2.js +1 -1
  28. package/soundfont/basic_soundfont/write_dls/combine_zones.js +12 -10
  29. package/soundfont/basic_soundfont/write_dls/ins.js +2 -2
  30. package/soundfont/basic_soundfont/write_dls/lins.js +1 -1
  31. package/soundfont/basic_soundfont/write_dls/modulator_converter.js +9 -9
  32. package/soundfont/basic_soundfont/write_dls/rgn2.js +5 -5
  33. package/soundfont/basic_soundfont/write_dls/wave.js +2 -1
  34. package/soundfont/basic_soundfont/write_dls/write_dls.js +1 -1
  35. package/soundfont/basic_soundfont/write_dls/wsmp.js +2 -2
  36. package/soundfont/basic_soundfont/write_dls/wvpl.js +1 -1
  37. package/soundfont/basic_soundfont/write_sf2/ibag.js +2 -2
  38. package/soundfont/basic_soundfont/write_sf2/igen.js +20 -17
  39. package/soundfont/basic_soundfont/write_sf2/imod.js +3 -3
  40. package/soundfont/basic_soundfont/write_sf2/inst.js +2 -2
  41. package/soundfont/basic_soundfont/write_sf2/pbag.js +2 -2
  42. package/soundfont/basic_soundfont/write_sf2/pgen.js +21 -18
  43. package/soundfont/basic_soundfont/write_sf2/phdr.js +2 -2
  44. package/soundfont/basic_soundfont/write_sf2/pmod.js +2 -2
  45. package/soundfont/basic_soundfont/write_sf2/sdta.js +1 -1
  46. package/soundfont/basic_soundfont/write_sf2/shdr.js +1 -1
  47. package/soundfont/basic_soundfont/write_sf2/write.js +7 -6
  48. package/soundfont/dls/articulator_converter.js +1 -0
  49. package/soundfont/dls/dls_destinations.js +3 -3
  50. package/soundfont/dls/dls_preset.js +1 -1
  51. package/soundfont/dls/dls_soundfont.js +7 -7
  52. package/soundfont/dls/read_instrument.js +1 -1
  53. package/soundfont/dls/read_region.js +1 -0
  54. package/soundfont/dls/read_samples.js +4 -5
  55. package/soundfont/load_soundfont.js +1 -1
  56. package/soundfont/read_sf2/presets.js +1 -1
  57. package/soundfont/read_sf2/soundfont.js +5 -5
  58. package/synthetizer/audio_effects/effects_config.js +3 -3
  59. package/synthetizer/audio_effects/fancy_chorus.js +7 -7
  60. package/synthetizer/audio_effects/reverb.js +5 -5
  61. package/synthetizer/audio_effects/reverb_as_binary.js +15 -0
  62. package/synthetizer/audio_effects/reverb_buffer.min.js +1 -0
  63. package/synthetizer/synth_constants.js +14 -0
  64. package/synthetizer/synthetizer.js +1 -17
  65. package/synthetizer/worklet_processor.min.js +14 -12
  66. package/synthetizer/worklet_system/main_processor.js +2 -2
  67. package/synthetizer/worklet_system/worklet_methods/controller_control/controller_change.js +1 -1
  68. package/synthetizer/worklet_system/worklet_methods/controller_control/reset_controllers.js +1 -1
  69. package/synthetizer/worklet_system/worklet_methods/create_worklet_channel.js +2 -1
  70. package/synthetizer/worklet_system/worklet_methods/worklet_soundfont_manager/worklet_soundfont_manager.js +2 -2
  71. package/synthetizer/worklet_system/worklet_processor.js +1 -1
  72. package/soundfont/basic_soundfont/write_sf2/soundfont_trimmer.js +0 -185
  73. package/synthetizer/audio_effects/impulse_response_2.flac +0 -0
  74. package/synthetizer/worklet_system/minify_processor.sh +0 -4
@@ -22,7 +22,7 @@ const notGlobalizedTypes = new Set([
22
22
  generatorTypes.coarseTune, // written into wsmp, there's no global wsmp
23
23
  generatorTypes.keyNumToVolEnvHold, // KEY TO SOMETHING:
24
24
  generatorTypes.keyNumToVolEnvDecay,// cannot be globalized as they modify their respective generators
25
- generatorTypes.keyNumToModEnvHold, // (for example KNTVED modifies VolEnvDecay)
25
+ generatorTypes.keyNumToModEnvHold, // (for example, keyNumToVolEnvDecay modifies VolEnvDecay)
26
26
  generatorTypes.keyNumToModEnvDecay
27
27
  ]);
28
28
 
@@ -78,7 +78,7 @@ export function combineZones(preset, globalize = true)
78
78
  let globalPresetKeyRange = { min: 0, max: 127 };
79
79
  let globalPresetVelRange = { min: 0, max: 127 };
80
80
 
81
- // find the global zone and apply ranges, generators and modulators
81
+ // find the global zone and apply ranges, generators, and modulators
82
82
  const globalPresetZone = preset.presetZones.find(z => z.isGlobal);
83
83
  if (globalPresetZone)
84
84
  {
@@ -151,7 +151,7 @@ export function combineZones(preset, globalize = true)
151
151
  instZoneKeyRange = subtractRanges(instZoneKeyRange, presetZoneKeyRange);
152
152
  instZoneVelRange = subtractRanges(instZoneVelRange, presetZoneVelRange);
153
153
 
154
- // if either of the zones is out of range (i.e. min larger than max)
154
+ // if either of the zones is out of range (i.e.m min larger than the max),
155
155
  // then we discard that zone
156
156
  if (instZoneKeyRange.max < instZoneKeyRange.min || instZoneVelRange.max < instZoneVelRange.min)
157
157
  {
@@ -175,7 +175,9 @@ export function combineZones(preset, globalize = true)
175
175
  m => Modulator.isIdentical(mod, m));
176
176
  if (identicalInstMod !== -1)
177
177
  {
178
- // sum the amounts (this makes a new modulator because otherwise it would overwrite the one in the soundfont!!!
178
+ // sum the amounts
179
+ // (this makes a new modulator
180
+ // because otherwise it would overwrite the one in the soundfont!
179
181
  finalModList[identicalInstMod] = finalModList[identicalInstMod].sumTransform(
180
182
  mod);
181
183
  }
@@ -308,10 +310,10 @@ export function combineZones(preset, globalize = true)
308
310
  break;
309
311
  }
310
312
  }
311
- // if at least one occurence, find the most used one and add it to global
313
+ // if at least one occurrence, find the most used one and add it to global
312
314
  if (Object.keys(occurencesForValues).length > 0)
313
315
  {
314
- // [value, occurences]
316
+ // [value, occurrences]
315
317
  const valueToGlobalize = Object.entries(occurencesForValues).reduce((max, curr) =>
316
318
  {
317
319
  if (max[1] < curr[1])
@@ -336,13 +338,13 @@ export function combineZones(preset, globalize = true)
336
338
  {
337
339
  if (z.generators[gen].generatorValue === targetValue)
338
340
  {
339
- // that exact value exists. Since it's global now, remove it
341
+ // That exact value exists. Since it's global now, remove it
340
342
  z.generators.splice(gen, 1);
341
343
  }
342
344
  }
343
345
  else
344
346
  {
345
- // that type does not exist at all here.
347
+ // That type does not exist at all here.
346
348
  // Since we're globalizing, we need to add the default here.
347
349
  if (targetValue !== defaultForChecked)
348
350
  {
@@ -378,13 +380,13 @@ export function combineZones(preset, globalize = true)
378
380
  if (existsForAllZones === true)
379
381
  {
380
382
  globalZone.modulators.push(Modulator.copy(checkedModulator));
381
- // delete from local zones.
383
+ // delete it from local zones.
382
384
  for (const zone of finalZones)
383
385
  {
384
386
  const modulator = zone.modulators.find(m => Modulator.isIdentical(m, checkedModulator));
385
387
  // Check if the amount is correct.
386
388
  // If so, delete it since it's global.
387
- // if not, then it will simply override global as it's identical.
389
+ // If not, then it will simply override global as it's identical.
388
390
  if (modulator.transformAmount === checkedModulator.transformAmount)
389
391
  {
390
392
  zone.modulators.splice(zone.modulators.indexOf(modulator), 1);
@@ -9,7 +9,7 @@ import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd } from "../../../utils/l
9
9
  import { consoleColors } from "../../../utils/other.js";
10
10
 
11
11
  /**
12
- * @this {BasicSoundFont}
12
+ * @this {BasicSoundBank}
13
13
  * @param preset {BasicPreset}
14
14
  * @returns {IndexedByteArray}
15
15
  */
@@ -65,7 +65,7 @@ export function writeIns(preset)
65
65
  );
66
66
  }
67
67
 
68
- // write region list
68
+ // write the region list
69
69
  const lrgnData = combineArrays(combined.reduce((arrs, z) =>
70
70
  {
71
71
  if (!z.isGlobal)
@@ -3,7 +3,7 @@ import { combineArrays } from "../../../utils/indexed_array.js";
3
3
  import { writeIns } from "./ins.js";
4
4
 
5
5
  /**
6
- * @this {BasicSoundFont}
6
+ * @this {BasicSoundBank}
7
7
  * @returns {IndexedByteArray}
8
8
  */
9
9
  export function writeLins()
@@ -75,7 +75,7 @@ function getDLSDestinationFromSf2(dest, amount)
75
75
  return undefined;
76
76
 
77
77
  case generatorTypes.initialAttenuation:
78
- // amount does not get EMU corrected here, as this only applies to modulator attenuation
78
+ // the amount does not get EMU corrected here, as this only applies to modulator attenuation
79
79
  // the generator (affected) attenuation is handled in wsmp.
80
80
  return { dest: DLSDestinations.gain, amount: -amount };
81
81
  case generatorTypes.fineTune:
@@ -193,10 +193,10 @@ function checkSF2SpecialCombos(dest, amt)
193
193
  isBipolar: true
194
194
  };
195
195
 
196
- // scale tuning is implemented in DLS via an articulator:
197
- // keyNum to relative pitch at 12800 cents.
196
+ // Scale tuning is implemented in DLS via an articulator:
197
+ // keyNum to relative pitch at 12,800 cents.
198
198
  // Change that to scale tuning * 128.
199
- // therefore regular scale is still 12800, half is 6400 etc.
199
+ // Therefore, a regular scale is still 12,800, half is 6400, etc.
200
200
  case generatorTypes.scaleTuning:
201
201
  return {
202
202
  source: DLSSources.keyNum,
@@ -265,7 +265,7 @@ export function getDLSArticulatorFromSf2Modulator(mod)
265
265
  SpessaSynthWarn(`Invalid source: ${mod.sourceIndex}, CC: ${mod.sourceUsesCC}`);
266
266
  return undefined;
267
267
  }
268
- // attenuation is the opposite of gain. Invert
268
+ // Attenuation is the opposite of gain. Invert.
269
269
  if (mod.modulatorDestination === generatorTypes.initialAttenuation)
270
270
  {
271
271
  sourceDirection = sourceDirection === 1 ? 0 : 1;
@@ -291,13 +291,13 @@ export function getDLSArticulatorFromSf2Modulator(mod)
291
291
  if (specialCombo !== undefined)
292
292
  {
293
293
  amt = specialCombo.amt;
294
- // move source to control
294
+ // move the source to control
295
295
  control = source;
296
296
  controlTransformType = sourceTransformType;
297
297
  controlBipolar = sourceBipolar;
298
298
  controlDirection = sourceDirection;
299
299
 
300
- // set source as static as it's either: env, lfo or keynum
300
+ // set source as static as it's either: env, lfo or key num
301
301
  sourceTransformType = modulatorCurveTypes.linear;
302
302
  sourceBipolar = specialCombo.isBipolar ? 1 : 0;
303
303
  sourceDirection = 0;
@@ -310,13 +310,13 @@ export function getDLSArticulatorFromSf2Modulator(mod)
310
310
  return undefined;
311
311
  }
312
312
 
313
- // source curve type maps to desfont curve type in section 2.10, table 9
313
+ // source curve type maps to a desfont curve type in section 2.10, table 9
314
314
  let transform = 0;
315
315
  transform |= controlTransformType << 4;
316
316
  transform |= controlBipolar << 8;
317
317
  transform |= controlDirection << 9;
318
318
 
319
- // use use the source curve in output transform
319
+ // use the source curve in output transform
320
320
  transform |= sourceTransformType;
321
321
  transform |= sourceBipolar << 14;
322
322
  transform |= sourceDirection << 15;
@@ -8,7 +8,7 @@ import { writeArticulator } from "./art2.js";
8
8
  /**
9
9
  * @param zone {BasicInstrumentZone}
10
10
  * @param globalZone {BasicInstrumentZone}
11
- * @this {BasicSoundFont}
11
+ * @this {BasicSoundBank}
12
12
  * @returns {IndexedByteArray}
13
13
  */
14
14
  export function writeDLSRegion(zone, globalZone)
@@ -35,8 +35,8 @@ export function writeDLSRegion(zone, globalZone)
35
35
 
36
36
  let rootKey = zone.getGeneratorValue(generatorTypes.overridingRootKey, zone.sample.samplePitch);
37
37
 
38
- // a lot of soundfonts like to set scaletuning to 0 in drums and keep the key at 60
39
- // since we implement scaletuning via a dls articulator and fluid doesn't support these,
38
+ // a lot of soundfonts like to set scale tuning to 0 in drums and keep the key at 60
39
+ // since we implement scale tuning via a dls articulator and fluid doesn't support these,
40
40
  // change the root key here
41
41
  const scaleTuning = zone.getGeneratorValue(
42
42
  generatorTypes.scaleTuning,
@@ -47,7 +47,7 @@ export function writeDLSRegion(zone, globalZone)
47
47
  rootKey = zone.keyRange.min;
48
48
  }
49
49
 
50
- // wavesample (Wsmp)
50
+ // wave sample (Wsmp)
51
51
  const wsmp = writeWavesample(
52
52
  zone.sample,
53
53
  rootKey,
@@ -67,7 +67,7 @@ export function writeDLSRegion(zone, globalZone)
67
67
  zone.getGeneratorValue(generatorTypes.sampleModes, 0)
68
68
  );
69
69
 
70
- // wavelink (wlnk)
70
+ // wave link (wlnk)
71
71
  const wlnkData = new IndexedByteArray(12);
72
72
  writeWord(wlnkData, 0); // fusOptions
73
73
  writeWord(wlnkData, 0); // usPhaseGroup
@@ -46,7 +46,8 @@ export function writeDLSSample(sample)
46
46
 
47
47
  for (let i = 0; i < audio.length; i++)
48
48
  {
49
- data16[i] = audio[i] * 32768;
49
+ // 32,767, as 32,768 may cause overflow (because vorbis can go above 1 sometimes)
50
+ data16[i] = audio[i] * 32767;
50
51
  }
51
52
 
52
53
 
@@ -9,7 +9,7 @@ import { consoleColors } from "../../../utils/other.js";
9
9
 
10
10
  /**
11
11
  * Write the soundfont as a .dls file. Experimental
12
- * @this {BasicSoundFont}
12
+ * @this {BasicSoundBank}
13
13
  * @returns {Uint8Array}
14
14
  */
15
15
  export function writeDLS()
@@ -34,10 +34,10 @@ export function writeWavesample(
34
34
  // gain correction, use InitialAttenuation, apply attenuation correction
35
35
  const attenuationCb = attenuationCentibels * 0.4;
36
36
 
37
- // gain correction: Each unit of gain represents 1/655360 dB
37
+ // gain correction: Each unit of gain represents 1/655360 dB
38
38
  const lGain = Math.floor(attenuationCb * -65536);
39
39
  writeDword(wsmpData, lGain);
40
- // fulOptions: has to be 2 according to all DLS files I have
40
+ // fulOptions: has to be 2, according to all DLS files I have
41
41
  writeDword(wsmpData, 2);
42
42
 
43
43
  const loopSize = loopEnd - loopStart;
@@ -3,7 +3,7 @@ import { writeRIFFOddSize } from "../riff_chunk.js";
3
3
  import { combineArrays } from "../../../utils/indexed_array.js";
4
4
 
5
5
  /**
6
- * @this {BasicSoundFont}
6
+ * @this {BasicSoundBank}
7
7
  * @returns {{data: IndexedByteArray, indexes: number[] }}
8
8
  */
9
9
  export function writeWavePool()
@@ -3,12 +3,12 @@ import { writeWord } from "../../../utils/byte_functions/little_endian.js";
3
3
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
4
 
5
5
  /**
6
- * @this {BasicSoundFont}
6
+ * @this {BasicSoundBank}
7
7
  * @returns {IndexedByteArray}
8
8
  */
9
9
  export function getIBAG()
10
10
  {
11
- // write all ibags with their start indexes as they were changed in getIGEN() and getIMOD()
11
+ // write all ibag with their start indexes as they were changed in getIGEN() and getIMOD()
12
12
  const ibagsize = this.instruments.reduce((sum, i) => i.instrumentZones.length * 4 + sum, 4);
13
13
  const ibagdata = new IndexedByteArray(ibagsize);
14
14
  let zoneID = 0;
@@ -2,10 +2,10 @@ import { writeDword, writeWord } from "../../../utils/byte_functions/little_endi
2
2
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
3
3
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
4
 
5
- import { generatorTypes } from "../generator.js";
5
+ import { Generator, generatorTypes } from "../generator.js";
6
6
 
7
7
  /**
8
- * @this {BasicSoundFont}
8
+ * @this {BasicSoundBank}
9
9
  * @returns {IndexedByteArray}
10
10
  */
11
11
  export function getIGEN()
@@ -16,35 +16,38 @@ export function getIGEN()
16
16
  {
17
17
  igensize += inst.instrumentZones.reduce((sum, z) =>
18
18
  {
19
- // clear sample and range generators before derermining the size
19
+ // clear sample and range generators before determining the size
20
20
  z.generators = z.generators.filter(g =>
21
21
  g.generatorType !== generatorTypes.sampleID &&
22
22
  g.generatorType !== generatorTypes.keyRange &&
23
23
  g.generatorType !== generatorTypes.velRange
24
24
  );
25
- // add sample and ranges if needed
26
- // unshift vel then key ( to make key first) and instrument is last
25
+ // add sample and ranges if necessary
26
+ // unshift vel then key (to make key first) and the instrument is last
27
27
  if (z.velRange.max !== 127 || z.velRange.min !== 0)
28
28
  {
29
- z.generators.unshift({
30
- generatorType: generatorTypes.velRange,
31
- generatorValue: z.velRange.max << 8 | Math.max(z.velRange.min, 0)
32
- });
29
+ z.generators.unshift(new Generator(
30
+ generatorTypes.velRange,
31
+ z.velRange.max << 8 | Math.max(z.velRange.min, 0),
32
+ false
33
+ ));
33
34
  }
34
35
  if (z.keyRange.max !== 127 || z.keyRange.min !== 0)
35
36
  {
36
- z.generators.unshift({
37
- generatorType: generatorTypes.keyRange,
38
- generatorValue: z.keyRange.max << 8 | Math.max(z.keyRange.min, 0)
39
- });
37
+ z.generators.unshift(new Generator(
38
+ generatorTypes.keyRange,
39
+ z.keyRange.max << 8 | Math.max(z.keyRange.min, 0),
40
+ false
41
+ ));
40
42
  }
41
43
  if (!z.isGlobal)
42
44
  {
43
45
  // write sample
44
- z.generators.push({
45
- generatorType: generatorTypes.sampleID,
46
- generatorValue: this.samples.indexOf(z.sample)
47
- });
46
+ z.generators.push(new Generator(
47
+ generatorTypes.sampleID,
48
+ this.samples.indexOf(z.sample),
49
+ false
50
+ ));
48
51
  }
49
52
  return z.generators.length * 4 + sum;
50
53
  }, 0);
@@ -3,13 +3,13 @@ import { writeLittleEndian, writeWord } from "../../../utils/byte_functions/litt
3
3
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
4
 
5
5
  /**
6
- * @this {BasicSoundFont}
6
+ * @this {BasicSoundBank}
7
7
  * @returns {IndexedByteArray}
8
8
  */
9
9
  export function getIMOD()
10
10
  {
11
- // very similar to igen
12
- // go through all instruments -> zones and write modulators sequentially
11
+ // very similar to igen,
12
+ // go through all instruments -> zones and write modulators sequentially
13
13
  let imodsize = 10;
14
14
  for (const inst of this.instruments)
15
15
  {
@@ -4,14 +4,14 @@ import { writeWord } from "../../../utils/byte_functions/little_endian.js";
4
4
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
5
5
 
6
6
  /**
7
- * @this {BasicSoundFont}
7
+ * @this {BasicSoundBank}
8
8
  * @returns {IndexedByteArray}
9
9
  */
10
10
  export function getINST()
11
11
  {
12
12
  const instsize = this.instruments.length * 22 + 22;
13
13
  const instdata = new IndexedByteArray(instsize);
14
- // the instrument start index is adjusted in ibag, simply write it here
14
+ // the instrument start index is adjusted in ibag, write it here
15
15
  let instrumentStart = 0;
16
16
  let instrumentID = 0;
17
17
  for (const inst of this.instruments)
@@ -3,12 +3,12 @@ import { writeWord } from "../../../utils/byte_functions/little_endian.js";
3
3
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
4
 
5
5
  /**
6
- * @this {BasicSoundFont}
6
+ * @this {BasicSoundBank}
7
7
  * @returns {IndexedByteArray}
8
8
  */
9
9
  export function getPBAG()
10
10
  {
11
- // write all pbags with their start indexes as they were changed in getPGEN() and getPMOD()
11
+ // write all pbag with their start indexes as they were changed in getPGEN() and getPMOD()
12
12
  const pbagsize = this.presets.reduce((sum, i) => i.presetZones.length * 4 + sum, 4);
13
13
  const pbagdata = new IndexedByteArray(pbagsize);
14
14
  let zoneID = 0;
@@ -2,22 +2,22 @@ import { writeWord } from "../../../utils/byte_functions/little_endian.js";
2
2
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
3
3
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
4
 
5
- import { generatorTypes } from "../generator.js";
5
+ import { Generator, generatorTypes } from "../generator.js";
6
6
 
7
7
  /**
8
- * @this {BasicSoundFont}
8
+ * @this {BasicSoundBank}
9
9
  * @returns {IndexedByteArray}
10
10
  */
11
11
  export function getPGEN()
12
12
  {
13
- // almost identical to igen, except correct instrument instead of sample gen
14
- // go through all preset zones and write generators sequentially (add 4 for terminal)
13
+ // almost identical to igen, except the correct instrument instead of sample gen
14
+ // goes through all preset zones and writes generators sequentially (add 4 for terminal)
15
15
  let pgensize = 4;
16
16
  for (const preset of this.presets)
17
17
  {
18
18
  pgensize += preset.presetZones.reduce((size, z) =>
19
19
  {
20
- // clear instrument and range generators before derermining the size
20
+ // clear instrument and range generators before determining the size
21
21
  z.generators = z.generators.filter(g =>
22
22
  g.generatorType !== generatorTypes.instrument &&
23
23
  g.generatorType !== generatorTypes.keyRange &&
@@ -26,25 +26,28 @@ export function getPGEN()
26
26
  // unshift vel then key and instrument is last
27
27
  if (z.velRange.max !== 127 || z.velRange.min !== 0)
28
28
  {
29
- z.generators.unshift({
30
- generatorType: generatorTypes.velRange,
31
- generatorValue: z.velRange.max << 8 | Math.max(z.velRange.min, 0)
32
- });
29
+ z.generators.unshift(new Generator(
30
+ generatorTypes.velRange,
31
+ z.velRange.max << 8 | Math.max(z.velRange.min, 0),
32
+ false
33
+ ));
33
34
  }
34
35
  if (z.keyRange.max !== 127 || z.keyRange.min !== 0)
35
36
  {
36
- z.generators.unshift({
37
- generatorType: generatorTypes.keyRange,
38
- generatorValue: z.keyRange.max << 8 | Math.max(z.keyRange.min, 0)
39
- });
37
+ z.generators.unshift(new Generator(
38
+ generatorTypes.keyRange,
39
+ z.keyRange.max << 8 | Math.max(z.keyRange.min, 0),
40
+ false
41
+ ));
40
42
  }
41
43
  if (!z.isGlobal)
42
44
  {
43
- // write instrument
44
- z.generators.push({
45
- generatorType: generatorTypes.instrument,
46
- generatorValue: this.instruments.indexOf(z.instrument)
47
- });
45
+ // write the instrument
46
+ z.generators.push(new Generator(
47
+ generatorTypes.instrument,
48
+ this.instruments.indexOf(z.instrument),
49
+ false
50
+ ));
48
51
  }
49
52
  return z.generators.length * 4 + size;
50
53
  }, 0);
@@ -4,7 +4,7 @@ import { writeDword, writeWord } from "../../../utils/byte_functions/little_endi
4
4
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
5
5
 
6
6
  /**
7
- * @this {BasicSoundFont}
7
+ * @this {BasicSoundBank}
8
8
  * @returns {IndexedByteArray}
9
9
  */
10
10
  export function getPHDR()
@@ -19,7 +19,7 @@ export function getPHDR()
19
19
  writeWord(phdrdata, preset.program);
20
20
  writeWord(phdrdata, preset.bank);
21
21
  writeWord(phdrdata, presetStart);
22
- // 3 unused dwords, spec says to keep em so we do
22
+ // 3 unused dword, spec says to keep em so we do
23
23
  writeDword(phdrdata, preset.library);
24
24
  writeDword(phdrdata, preset.genre);
25
25
  writeDword(phdrdata, preset.morphology);
@@ -3,12 +3,12 @@ import { writeLittleEndian, writeWord } from "../../../utils/byte_functions/litt
3
3
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
4
 
5
5
  /**
6
- * @this {BasicSoundFont}
6
+ * @this {BasicSoundBank}
7
7
  * @returns {IndexedByteArray}
8
8
  */
9
9
  export function getPMOD()
10
10
  {
11
- // very similar to imod
11
+ // very similar to imod,
12
12
  // go through all presets -> zones and write modulators sequentially
13
13
  let pmodsize = 10;
14
14
  for (const preset of this.presets)
@@ -4,7 +4,7 @@ import { SpessaSynthInfo } from "../../../utils/loggin.js";
4
4
  import { consoleColors } from "../../../utils/other.js";
5
5
 
6
6
  /**
7
- * @this {BasicSoundFont}
7
+ * @this {BasicSoundBank}
8
8
  * @param smplStartOffsets {number[]}
9
9
  * @param smplEndOffsets {number[]}
10
10
  * @param compress {boolean}
@@ -4,7 +4,7 @@ import { writeDword, writeWord } from "../../../utils/byte_functions/little_endi
4
4
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
5
5
 
6
6
  /**
7
- * @this {BasicSoundFont}
7
+ * @this {BasicSoundBank}
8
8
  * @param smplStartOffsets {number[]}
9
9
  * @param smplEndOffsets {number[]}
10
10
  * @returns {IndexedByteArray}
@@ -16,9 +16,10 @@ import { writeWord } from "../../../utils/byte_functions/little_endian.js";
16
16
  import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd, SpessaSynthInfo } from "../../../utils/loggin.js";
17
17
  /**
18
18
  * @typedef {Object} SoundFont2WriteOptions
19
- * @property {boolean} compress - if the soundfont should be compressed with the ogg vorbis codec
19
+ * @property {boolean} compress - if the soundfont should be compressed with the Ogg Vorbis codec
20
20
  * @property {number} compressionQuality - the vorbis compression quality, from -0.1 to 1
21
- * @property {EncodeVorbisFunction|undefined} compressionFunction - the encode vorbis function. Can be undefined if not compressing.
21
+ * @property {EncodeVorbisFunction|undefined} compressionFunction - the encode vorbis function.
22
+ * Can be undefined if not compressed.
22
23
  */
23
24
 
24
25
  /**
@@ -32,7 +33,7 @@ const DEFAULT_WRITE_OPTIONS = {
32
33
 
33
34
  /**
34
35
  * Write the soundfont as an .sf2 file. This method is DESTRUCTIVE
35
- * @this {BasicSoundFont}
36
+ * @this {BasicSoundBank}
36
37
  * @param {SoundFont2WriteOptions} options
37
38
  * @returns {Uint8Array}
38
39
  */
@@ -115,7 +116,7 @@ export function write(options = DEFAULT_WRITE_OPTIONS)
115
116
  "%cWriting SDTA...",
116
117
  consoleColors.info
117
118
  );
118
- // write sdata
119
+ // write sdta
119
120
  const smplStartOffsets = [];
120
121
  const smplEndOffsets = [];
121
122
  const sdtaChunk = getSDTA.call(
@@ -131,7 +132,7 @@ export function write(options = DEFAULT_WRITE_OPTIONS)
131
132
  "%cWriting PDTA...",
132
133
  consoleColors.info
133
134
  );
134
- // write pdata
135
+ // write pdta
135
136
  // go in reverse so the indexes are correct
136
137
  // instruments
137
138
  SpessaSynthInfo(
@@ -178,7 +179,7 @@ export function write(options = DEFAULT_WRITE_OPTIONS)
178
179
  const phdrChunk = getPHDR.call(this);
179
180
  // combine in the sfspec order
180
181
  const pdtadata = combineArrays([
181
- new IndexedByteArray([112, 100, 116, 97]), // "ptda"
182
+ new IndexedByteArray([112, 100, 116, 97]), // "pdta"
182
183
  phdrChunk,
183
184
  pbagChunk,
184
185
  pmodChunk,
@@ -192,6 +192,7 @@ function checkForSpecialDLSCombo(source, destination)
192
192
  }
193
193
  }
194
194
 
195
+ // noinspection JSUnusedGlobalSymbols
195
196
  /**
196
197
  * @param source {number}
197
198
  * @param control {number}
@@ -9,9 +9,9 @@ export const DLSDestinations = {
9
9
  pitch: 0x3, // pitch in cents
10
10
  pan: 0x4, // pan 10ths of a percent
11
11
  keyNum: 0x5, // MIDI key number
12
- // nuh uh, the channel controllers are not supported!!!!
13
- chorusSend: 0x80, // chorus send 10ths of a percent
14
- reverbSend: 0x81, // reverb send 10ths of a percent
12
+ // nuh uh, the channel controllers are not supported!
13
+ chorusSend: 0x80, // chorus send level 10ths of a percent
14
+ reverbSend: 0x81, // reverb send level 10ths of a percent
15
15
 
16
16
  modLfoFreq: 0x104, // modulation LFO frequency
17
17
  modLfoDelay: 0x105, // modulation LFO delay
@@ -19,7 +19,7 @@ export class DLSPreset extends BasicPreset
19
19
  const isDrums = ulBank >> 31;
20
20
  if (isDrums)
21
21
  {
22
- // soundfont bank is 128 so we change it here
22
+ // soundfont bank is 128, so we change it here
23
23
  this.bank = 128;
24
24
  }
25
25