spessasynth_lib 3.23.8 → 3.23.12

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.
@@ -17,13 +17,13 @@ export const generatorTypes = {
17
17
  modEnvToFilterFc: 11, // filter modulation - modulation envelope lowpass filter cutoff in cents
18
18
  endAddrsCoarseOffset: 12, // ample control - moves sample end point in 32768 increments
19
19
  modLfoToVolume: 13, // modulation lfo - volume (tremolo), where 100 = 10dB
20
- unused1: 14,
20
+ unused1: 14, // unused
21
21
  chorusEffectsSend: 15, // effect send - how much is sent to chorus 0 - 1000
22
22
  reverbEffectsSend: 16, // effect send - how much is sent to reverb 0 - 1000
23
23
  pan: 17, // panning - where -500 = left, 0 = center, 500 = right
24
- unused2: 18,
25
- unused3: 19,
26
- unused4: 20,
24
+ unused2: 18, // unused
25
+ unused3: 19, // unused
26
+ unused4: 20, // unused
27
27
  delayModLFO: 21, // mod lfo - delay for mod lfo to start from zero (weird scale)
28
28
  freqModLFO: 22, // mod lfo - frequency of mod lfo, 0 = 8.176Hz, unit: f => 1200log2(f/8.176)
29
29
  delayVibLFO: 23, // vib lfo - delay for vibrato lfo to start from zero (weird scale)
@@ -45,24 +45,24 @@ export const generatorTypes = {
45
45
  keyNumToVolEnvHold: 39, // vol env - key number to volume envelope hold
46
46
  keyNumToVolEnvDecay: 40, // vol env - key number to volume envelope decay
47
47
  instrument: 41, // zone - instrument index to use for preset zone
48
- reserved1: 42,
48
+ reserved1: 42, // reserved
49
49
  keyRange: 43, // zone - key range for which preset / instrument zone is active
50
50
  velRange: 44, // zone - velocity range for which preset / instrument zone is active
51
51
  startloopAddrsCoarseOffset: 45, // sample control - moves sample loop start point in 32768 increments
52
52
  keyNum: 46, // zone - instrument only: always use this midi number (ignore what's pressed)
53
53
  velocity: 47, // zone - instrument only: always use this velocity (ignore what's pressed)
54
54
  initialAttenuation: 48, // zone - allows turning down the volume, 10 = -1dB
55
- reserved2: 49,
55
+ reserved2: 49, // reserved
56
56
  endloopAddrsCoarseOffset: 50, // sample control - moves sample loop end point in 32768 increments
57
57
  coarseTune: 51, // tune - pitch offset in semitones
58
58
  fineTune: 52, // tune - pitch offset in cents
59
59
  sampleID: 53, // sample - instrument zone only: which sample to use
60
60
  sampleModes: 54, // sample - 0 = no loop, 1 = loop, 2 = reserved, 3 = loop and play till end in release phase
61
- reserved3: 55,
61
+ reserved3: 55, // reserved
62
62
  scaleTuning: 56, // sample - the degree to which MIDI key number influences pitch, 100 = default
63
63
  exclusiveClass: 57, // sample - = cut = choke group
64
64
  overridingRootKey: 58, // sample - can override the sample's original pitch
65
- unused5: 59,
65
+ unused5: 59, // unused
66
66
  endOper: 60 // end marker
67
67
  };
68
68
  /**
@@ -187,7 +187,7 @@ export function getModSourceEnum(curveType, polarity, direction, isCC, index)
187
187
  return (curveType << 10) | (polarity << 9) | (direction << 8) | (isCC << 7) | index;
188
188
  }
189
189
 
190
- export const defaultModulators = [
190
+ const soundFontModulators = [
191
191
  // vel to attenuation
192
192
  new Modulator({
193
193
  srcEnum: getModSourceEnum(
@@ -250,8 +250,10 @@ export const defaultModulators = [
250
250
  new Modulator({ srcEnum: 0x00DB, dest: generatorTypes.reverbEffectsSend, amt: 200, secSrcEnum: 0x0, transform: 0 }),
251
251
 
252
252
  // chorus effects to send
253
- new Modulator({ srcEnum: 0x00DD, dest: generatorTypes.chorusEffectsSend, amt: 200, secSrcEnum: 0x0, transform: 0 }),
254
-
253
+ new Modulator({ srcEnum: 0x00DD, dest: generatorTypes.chorusEffectsSend, amt: 200, secSrcEnum: 0x0, transform: 0 })
254
+ ];
255
+
256
+ const customModulators = [
255
257
  // custom modulators heck yeah
256
258
  // poly pressure to vibrato
257
259
  new Modulator({
@@ -321,4 +323,6 @@ export const defaultModulators = [
321
323
  secSrcEnum: 0x0, // no controller
322
324
  transform: 0
323
325
  })
324
- ];
326
+ ];
327
+
328
+ export const defaultModulators = soundFontModulators.concat(customModulators);
@@ -39,16 +39,36 @@ const invalidGeneratorTypes = new Set([
39
39
  */
40
40
  export function writeArticulator(zone)
41
41
  {
42
- /**
43
- * @returns {number}
44
- */
42
+
43
+
44
+ // envelope generators are limited to 40 seconds
45
+ // in timecents, this is 1200 * log2(10) = 6386
46
+
47
+ for (let i = 0; i < zone.generators.length; i++)
48
+ {
49
+ const g = zone.generators[i];
50
+ if (
51
+ g.generatorType === generatorTypes.delayVolEnv ||
52
+ g.generatorType === generatorTypes.attackVolEnv ||
53
+ g.generatorType === generatorTypes.holdVolEnv ||
54
+ g.generatorType === generatorTypes.decayVolEnv ||
55
+ g.generatorType === generatorTypes.releaseVolEnv ||
56
+ g.generatorType === generatorTypes.delayModEnv ||
57
+ g.generatorType === generatorTypes.attackModEnv ||
58
+ g.generatorType === generatorTypes.holdModEnv ||
59
+ g.generatorType === generatorTypes.decayModEnv
60
+ )
61
+ {
62
+ zone.generators[i] = new Generator(g.generatorType, Math.min(g.generatorValue, 6386), false);
63
+ }
64
+ }
65
+
45
66
 
46
67
  // read_articulation.js:
47
68
  // according to viena and another strange (with modulators) rendition of gm.dls in sf2,
48
69
  // it shall be divided by -128
49
70
  // and a strange correction needs to be applied to the real value:
50
71
  // real + (60 / 128) * scale
51
-
52
72
  // we invert this here
53
73
  for (let i = 0; i < zone.generators.length; i++)
54
74
  {
@@ -24,11 +24,14 @@ export function getSDTA(smplStartOffsets, smplEndOffsets, compress, quality, vor
24
24
  }
25
25
  const r = s.getRawData();
26
26
  SpessaSynthInfo(
27
- `%cEncoded sample %c${i}. ${s.sampleName}%c of %c${this.samples.length}`,
27
+ `%cEncoded sample %c${i}. ${s.sampleName}%c of %c${this.samples.length}%c. Compressed: %c${s.isCompressed}%c.`,
28
28
  consoleColors.info,
29
29
  consoleColors.recognized,
30
30
  consoleColors.info,
31
- consoleColors.recognized
31
+ consoleColors.recognized,
32
+ consoleColors.info,
33
+ s.isCompressed ? consoleColors.recognized : consoleColors.unrecognized,
34
+ consoleColors.info
32
35
  );
33
36
  return r;
34
37
  });
@@ -135,6 +135,16 @@ function getSF2GeneratorFromDLS(destination, amount)
135
135
  return generatorTypes.chorusEffectsSend;
136
136
  case DLSDestinations.reverbSend:
137
137
  return generatorTypes.reverbEffectsSend;
138
+
139
+ // lfos
140
+ case DLSDestinations.modLfoFreq:
141
+ return generatorTypes.freqModLFO;
142
+ case DLSDestinations.modLfoDelay:
143
+ return generatorTypes.delayModLFO;
144
+ case DLSDestinations.vibLfoFreq:
145
+ return generatorTypes.freqVibLFO;
146
+ case DLSDestinations.vibLfoDelay:
147
+ return generatorTypes.delayVibLFO;
138
148
  }
139
149
  }
140
150
 
@@ -3,36 +3,36 @@
3
3
  * @enum {number}
4
4
  */
5
5
  export const DLSDestinations = {
6
- none: 0x0,
7
- gain: 0x1,
8
- reserved: 0x2,
9
- pitch: 0x3,
10
- pan: 0x4,
11
- keyNum: 0x5,
6
+ none: 0x0, // no destination
7
+ gain: 0x1, // linear gain
8
+ reserved: 0x2, // reserved
9
+ pitch: 0x3, // pitch in cents
10
+ pan: 0x4, // pan 10ths of a percent
11
+ keyNum: 0x5, // MIDI key number
12
12
  // nuh uh, the channel controllers are not supported!!!!
13
- chorusSend: 0x80,
14
- reverbSend: 0x81,
13
+ chorusSend: 0x80, // chorus send 10ths of a percent
14
+ reverbSend: 0x81, // reverb send 10ths of a percent
15
15
 
16
- modLfoFreq: 0x104,
17
- modLfoDelay: 0x105,
16
+ modLfoFreq: 0x104, // modulation LFO frequency
17
+ modLfoDelay: 0x105, // modulation LFO delay
18
18
 
19
- vibLfoFreq: 0x114,
20
- vibLfoDelay: 0x115,
19
+ vibLfoFreq: 0x114, // vibrato LFO frequency
20
+ vibLfoDelay: 0x115, // vibrato LFO delay
21
21
 
22
- volEnvAttack: 0x206,
23
- volEnvDecay: 0x207,
24
- volEnvRelease: 0x209,
25
- volEnvSustain: 0x20a,
26
- volEnvDelay: 0x20b,
27
- volEnvHold: 0x20c,
22
+ volEnvAttack: 0x206, // volume envelope attack
23
+ volEnvDecay: 0x207, // volume envelope decay
24
+ volEnvRelease: 0x209, // volume envelope release
25
+ volEnvSustain: 0x20a, // volume envelope sustain
26
+ volEnvDelay: 0x20b, // volume envelope delay
27
+ volEnvHold: 0x20c, // volume envelope hold
28
28
 
29
- modEnvAttack: 0x30a,
30
- modEnvDecay: 0x30b,
31
- modEnvRelease: 0x30d,
32
- modEnvSustain: 0x30e,
33
- modEnvDelay: 0x30f,
34
- modEnvHold: 0x310,
29
+ modEnvAttack: 0x30a, // modulation envelope attack
30
+ modEnvDecay: 0x30b, // modulation envelope decay
31
+ modEnvRelease: 0x30d, // modulation envelope release
32
+ modEnvSustain: 0x30e, // modulation envelope sustain
33
+ modEnvDelay: 0x30f, // modulation envelope delay
34
+ modEnvHold: 0x310, // modulation envelope hold
35
35
 
36
- filterCutoff: 0x500,
37
- filterQ: 0x501
36
+ filterCutoff: 0x500, // low pass filter cutoff frequency
37
+ filterQ: 0x501 // low pass filter resonance
38
38
  };
@@ -72,7 +72,7 @@ export class LoadedSample extends BasicSample
72
72
 
73
73
  /**
74
74
  * Get raw data, whether it's compressed or not as we simply write it to the file
75
- * @return {Uint8Array}
75
+ * @return {Uint8Array} either s16 or vorbis data
76
76
  */
77
77
  getRawData()
78
78
  {
@@ -90,7 +90,8 @@ export class LoadedSample extends BasicSample
90
90
  {
91
91
  if (!this.isDataRaw)
92
92
  {
93
- throw new Error("Writing SF2Pack samples is not supported.");
93
+ // encode the f32 into s16 manually
94
+ super.getRawData();
94
95
  }
95
96
  const dataStartIndex = smplArr.currentIndex;
96
97
  return smplArr.slice(dataStartIndex + this.sampleStartIndex, dataStartIndex + this.sampleEndIndex);
@@ -123,7 +124,9 @@ export class LoadedSample extends BasicSample
123
124
  }
124
125
  catch (e)
125
126
  {
126
- throw new Error(`Ogg Vorbis decode error: ${e}`);
127
+ // do not error out, fill with silence
128
+ SpessaSynthWarn(`Error decoding sample ${this.sampleName}: ${e}`);
129
+ this.sampleData = new Float32Array(this.sampleLoopEndIndex + 1);
127
130
  }
128
131
  }
129
132