spessasynth_lib 3.14.2 → 3.15.0
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/@types/midi_parser/rmidi_writer.d.ts +6 -0
- package/@types/soundfont/read/presets.d.ts +4 -4
- package/@types/soundfont/read/samples.d.ts +12 -8
- package/@types/soundfont/read/zones.d.ts +6 -6
- package/@types/soundfont/soundfont.d.ts +3 -3
- package/README.md +7 -2
- package/midi_parser/midi_loader.js +1 -1
- package/midi_parser/rmidi_writer.js +13 -2
- package/package.json +1 -1
- package/soundfont/read/presets.js +2 -2
- package/soundfont/read/samples.js +53 -30
- package/soundfont/read/zones.js +3 -3
- package/soundfont/soundfont.js +49 -5
- package/synthetizer/worklet_processor.min.js +6 -6
- package/synthetizer/worklet_system/worklet_methods/note_on.js +2 -2
- package/synthetizer/worklet_system/worklet_methods/program_control.js +14 -0
- package/synthetizer/worklet_system/worklet_methods/voice_control.js +1 -1
- package/synthetizer/worklet_system/worklet_utilities/worklet_voice.js +10 -4
- package/utils/byte_functions/string.js +1 -1
|
@@ -38,9 +38,9 @@ export function noteOn(channel, midiNote, velocity, enableDebugging = false, sen
|
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
40
40
|
const program = channelObject.preset.program;
|
|
41
|
-
if(this.tunings[program][midiNote]?.midiNote >= 0)
|
|
41
|
+
if(this.tunings[program]?.[midiNote]?.midiNote >= 0)
|
|
42
42
|
{
|
|
43
|
-
sentMidiNote = this.tunings[program][midiNote].midiNote;
|
|
43
|
+
sentMidiNote = this.tunings[program]?.[midiNote].midiNote;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
// get voices
|
|
@@ -40,6 +40,11 @@ export function programChange(channel, programNumber, userChange=false)
|
|
|
40
40
|
channelObject.presetUsesOverride = true;
|
|
41
41
|
}
|
|
42
42
|
else
|
|
43
|
+
if(this.soundfontBankOffset === 0)
|
|
44
|
+
{
|
|
45
|
+
preset = this.overrideSoundfont.getPreset(0, programNumber);
|
|
46
|
+
}
|
|
47
|
+
else
|
|
43
48
|
{
|
|
44
49
|
preset = this.soundfont.getPreset(bank, programNumber);
|
|
45
50
|
sentBank = preset.bank;
|
|
@@ -79,6 +84,11 @@ export function getPreset(bank, program)
|
|
|
79
84
|
{
|
|
80
85
|
return preset;
|
|
81
86
|
}
|
|
87
|
+
else
|
|
88
|
+
if(this.soundfontBankOffset === 0)
|
|
89
|
+
{
|
|
90
|
+
return this.overrideSoundfont.getPreset(0, program);
|
|
91
|
+
}
|
|
82
92
|
}
|
|
83
93
|
return this.soundfont.getPreset(bank, program);
|
|
84
94
|
}
|
|
@@ -215,6 +225,10 @@ export function reloadSoundFont(buffer, isOverride = false)
|
|
|
215
225
|
this.clearSoundFont(false, isOverride);
|
|
216
226
|
if(!isOverride)
|
|
217
227
|
{
|
|
228
|
+
delete this.soundfont.dataArray;
|
|
229
|
+
this.soundfont.samples.length = 0;
|
|
230
|
+
this.soundfont.instruments.length = 0;
|
|
231
|
+
this.soundfont.presets.length = 0;
|
|
218
232
|
delete this.soundfont;
|
|
219
233
|
}
|
|
220
234
|
try
|
|
@@ -67,7 +67,7 @@ export function renderVoice(
|
|
|
67
67
|
+ channel.customControllers[customControllers.channelTuningSemitones];
|
|
68
68
|
|
|
69
69
|
// midi tuning standard
|
|
70
|
-
const tuning = this.tunings[channel.preset.program][targetKey];
|
|
70
|
+
const tuning = this.tunings[channel.preset.program]?.[targetKey];
|
|
71
71
|
if(tuning?.midiNote >= 0)
|
|
72
72
|
{
|
|
73
73
|
targetKey = tuning.midiNote;
|
|
@@ -65,7 +65,7 @@ export function clearSamplesList()
|
|
|
65
65
|
|
|
66
66
|
function /**
|
|
67
67
|
* @param channel {number} channel hint for the processor to recalculate cursor positions
|
|
68
|
-
* @param sample {
|
|
68
|
+
* @param sample {LoadedSample}
|
|
69
69
|
* @param id {number}
|
|
70
70
|
* @param sampleDumpCallback {function({channel: number, sampleID: number, sampleData: Float32Array})}
|
|
71
71
|
*/
|
|
@@ -195,10 +195,16 @@ export function getWorkletVoices(channel,
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
// determine looping mode now. if the loop is too small, disable
|
|
198
|
-
|
|
199
|
-
|
|
198
|
+
let loopStart = (sampleAndGenerators.sample.sampleLoopStartIndex / 2) + (generators[generatorTypes.startloopAddrsOffset] + (generators[generatorTypes.startloopAddrsCoarseOffset] * 32768));
|
|
199
|
+
let loopEnd = (sampleAndGenerators.sample.sampleLoopEndIndex / 2) + (generators[generatorTypes.endloopAddrsOffset] + (generators[generatorTypes.endloopAddrsCoarseOffset] * 32768));
|
|
200
200
|
let loopingMode = generators[generatorTypes.sampleModes];
|
|
201
|
-
|
|
201
|
+
const sampleLength = sampleAndGenerators.sample.getAudioData().length;
|
|
202
|
+
// clamp loop
|
|
203
|
+
loopStart = Math.min(Math.max(0, loopStart), sampleLength);
|
|
204
|
+
// clamp loop
|
|
205
|
+
loopEnd = Math.min(Math.max(0, loopEnd), sampleLength);
|
|
206
|
+
if (loopEnd - loopStart < 1)
|
|
207
|
+
{
|
|
202
208
|
loopingMode = 0;
|
|
203
209
|
}
|
|
204
210
|
|
|
@@ -43,7 +43,7 @@ export function readBytesAsString(dataArray, bytes, encoding = undefined, trimEn
|
|
|
43
43
|
{
|
|
44
44
|
let byteBuffer = dataArray.slice(dataArray.currentIndex, dataArray.currentIndex + bytes)
|
|
45
45
|
dataArray.currentIndex += bytes
|
|
46
|
-
let decoder = new TextDecoder(encoding)
|
|
46
|
+
let decoder = new TextDecoder(encoding.replace(/[^\x20-\x7E]/g, ''))
|
|
47
47
|
return decoder.decode(byteBuffer.buffer)
|
|
48
48
|
}
|
|
49
49
|
}
|