spessasynth_lib 3.25.4 → 3.25.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/midi_parser/basic_midi.js +0 -28
- package/package.json +1 -1
- package/soundfont/basic_soundfont/basic_instrument.js +18 -14
- package/soundfont/basic_soundfont/basic_preset.js +64 -59
- package/soundfont/basic_soundfont/basic_sample.js +75 -55
- package/soundfont/basic_soundfont/basic_soundfont.js +121 -68
- package/soundfont/dls/dls_preset.js +3 -3
- package/soundfont/dls/dls_soundfont.js +1 -1
- package/soundfont/dls/dls_sources.js +3 -2
- package/soundfont/dls/read_instrument.js +1 -1
- package/soundfont/read_sf2/presets.js +6 -6
- package/soundfont/read_sf2/samples.js +19 -18
- package/soundfont/read_sf2/soundfont.js +2 -2
- package/soundfont/read_sf2/zones.js +2 -3
- package/synthetizer/synthetizer.js +21 -0
- package/synthetizer/worklet_processor.min.js +11 -11
- package/synthetizer/worklet_system/worklet_methods/controller_control/master_parameters.js +3 -1
- package/synthetizer/worklet_system/worklet_methods/program_change.js +1 -0
- package/synthetizer/worklet_system/worklet_methods/soundfont_management/reload_sound_font.js +0 -2
- package/synthetizer/worklet_system/worklet_methods/worklet_soundfont_manager/worklet_soundfont_manager.js +0 -13
- package/synthetizer/worklet_system/worklet_utilities/lowpass_filter.js +16 -10
|
@@ -6,7 +6,9 @@ import { SYNTHESIZER_GAIN } from "../../main_processor.js";
|
|
|
6
6
|
*/
|
|
7
7
|
export function setMIDIVolume(volume)
|
|
8
8
|
{
|
|
9
|
-
|
|
9
|
+
// GM2 specification, section 4.1: master-volume is squared though,
|
|
10
|
+
// according to my own testing, e seems like a better choice
|
|
11
|
+
this.midiVolume = Math.pow(volume, Math.E);
|
|
10
12
|
this.setMasterPan(this.pan);
|
|
11
13
|
}
|
|
12
14
|
|
|
@@ -45,6 +45,7 @@ export function programChange(programNumber, userChange = false)
|
|
|
45
45
|
this.presetUsesOverride = false;
|
|
46
46
|
}
|
|
47
47
|
this.setPreset(preset);
|
|
48
|
+
console.log(preset.presetName, this.isXGChannel, this.drumChannel, bank);
|
|
48
49
|
this.synth.callEvent("programchange", {
|
|
49
50
|
channel: this.channelNumber,
|
|
50
51
|
program: preset.program,
|
package/synthetizer/worklet_system/worklet_methods/soundfont_management/reload_sound_font.js
CHANGED
|
@@ -16,8 +16,6 @@ export function reloadSoundFont(buffer, isOverride = false)
|
|
|
16
16
|
if (isOverride)
|
|
17
17
|
{
|
|
18
18
|
this.overrideSoundfont = loadSoundFont(buffer);
|
|
19
|
-
// assign sample offset
|
|
20
|
-
this.overrideSoundfont.setSampleIDOffset(this.soundfontManager.totalSoundfontOffset);
|
|
21
19
|
}
|
|
22
20
|
else
|
|
23
21
|
{
|
|
@@ -23,24 +23,11 @@ export class WorkletSoundfontManager
|
|
|
23
23
|
* @type {Function}
|
|
24
24
|
*/
|
|
25
25
|
this.ready = readyCallback;
|
|
26
|
-
this.totalSoundfontOffset = 0;
|
|
27
26
|
this.reloadManager(initialSoundFontBuffer);
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
_assingSampleOffsets()
|
|
31
|
-
{
|
|
32
|
-
let offset = 0;
|
|
33
|
-
this.soundfontList.forEach(s =>
|
|
34
|
-
{
|
|
35
|
-
s.soundfont.setSampleIDOffset(offset);
|
|
36
|
-
offset += s.soundfont.samples.length;
|
|
37
|
-
});
|
|
38
|
-
this.totalSoundfontOffset = offset;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
29
|
generatePresetList()
|
|
42
30
|
{
|
|
43
|
-
this._assingSampleOffsets();
|
|
44
31
|
/**
|
|
45
32
|
* <"bank-program", "presetName">
|
|
46
33
|
* @type {Object<string, string>}
|
|
@@ -4,9 +4,11 @@ import { generatorTypes } from "../../../soundfont/basic_soundfont/generator.js"
|
|
|
4
4
|
/**
|
|
5
5
|
* lowpass_filter.js
|
|
6
6
|
* purpose: applies a low pass filter to a voice
|
|
7
|
-
* note to self: a lot of tricks and
|
|
7
|
+
* note to self: a lot of tricks and come from fluidsynth.
|
|
8
8
|
* They are the real smart guys.
|
|
9
9
|
* Shoutout to them!
|
|
10
|
+
* Give their repo a star over at:
|
|
11
|
+
* https://github.com/FluidSynth/fluidsynth
|
|
10
12
|
*/
|
|
11
13
|
|
|
12
14
|
export const FILTER_SMOOTHING_FACTOR = 0.1;
|
|
@@ -123,9 +125,8 @@ export class WorkletLowpassFilter
|
|
|
123
125
|
|
|
124
126
|
if (!filter.initialized)
|
|
125
127
|
{
|
|
126
|
-
// filter initialization
|
|
128
|
+
// filter initialization, set the current fc to target
|
|
127
129
|
filter.initialized = true;
|
|
128
|
-
// don't smooth, override
|
|
129
130
|
filter.currentInitialFc = initialFc;
|
|
130
131
|
}
|
|
131
132
|
else
|
|
@@ -161,6 +162,7 @@ export class WorkletLowpassFilter
|
|
|
161
162
|
}
|
|
162
163
|
|
|
163
164
|
// filter the input
|
|
165
|
+
// initial filtering code was ported from meltysynth created by sinshu.
|
|
164
166
|
for (let i = 0; i < outputBuffer.length; i++)
|
|
165
167
|
{
|
|
166
168
|
let input = outputBuffer[i];
|
|
@@ -201,19 +203,23 @@ export class WorkletLowpassFilter
|
|
|
201
203
|
}
|
|
202
204
|
let cutoffHz = absCentsToHz(cutoffCents);
|
|
203
205
|
|
|
204
|
-
// fix cutoff on low
|
|
206
|
+
// fix cutoff on low sample rates
|
|
205
207
|
cutoffHz = Math.min(cutoffHz, 0.45 * sampleRate);
|
|
206
208
|
|
|
209
|
+
// the coefficient calculation code was originally ported from meltysynth by sinshu.
|
|
210
|
+
// turn resonance to gain, -3.01 so it gives a non-resonant peak
|
|
207
211
|
const qDb = qCb / 10;
|
|
208
|
-
//
|
|
209
|
-
const resonanceGain = decibelAttenuationToGain(-
|
|
212
|
+
// -1 because it's attenuation, and we don't want attenuation
|
|
213
|
+
const resonanceGain = decibelAttenuationToGain(-(qDb - 3.01));
|
|
210
214
|
|
|
211
|
-
//
|
|
215
|
+
// the sfspec asks for a reduction in gain based on the Q value.
|
|
216
|
+
// note that we calculate it again,
|
|
217
|
+
// without the 3.01-peak offset as it only applies to the coefficients, not the gain.
|
|
212
218
|
const qGain = 1 / Math.sqrt(decibelAttenuationToGain(-qDb));
|
|
213
219
|
|
|
214
220
|
|
|
215
|
-
//
|
|
216
|
-
let w = 2 * Math.PI * cutoffHz / sampleRate;
|
|
221
|
+
// note: no sin or cos tables here as the coefficients are cached
|
|
222
|
+
let w = 2 * Math.PI * cutoffHz / sampleRate;
|
|
217
223
|
let cosw = Math.cos(w);
|
|
218
224
|
let alpha = Math.sin(w) / (2 * resonanceGain);
|
|
219
225
|
|
|
@@ -248,7 +254,7 @@ export class WorkletLowpassFilter
|
|
|
248
254
|
}
|
|
249
255
|
}
|
|
250
256
|
|
|
251
|
-
// precompute all the cutoffs for 0q
|
|
257
|
+
// precompute all the cutoffs for 0q (most common)
|
|
252
258
|
const dummy = new WorkletLowpassFilter();
|
|
253
259
|
dummy.resonanceCb = 0;
|
|
254
260
|
// sfspec section 8.1.3: initialFilterFc ranges from 1500 to 13,500 cents
|