From 1069cc8a3fd2dc2b3779a66a36979d1dad355256 Mon Sep 17 00:00:00 2001 From: SAKryukov Date: Sun, 20 Aug 2017 19:47:44 -0400 Subject: [PATCH] Fixed adjustPreset in player, to work around two pathological cases in instrument .js files (presets): 1) some files have zones with zone.keyRangeLow > zone.keyRangeHigh; they are not used anyway and can be removed; this is a big performance improved, as, in some files, they reduce number of zones by order of magnitude 2) ALL files have zones with 1-semiton gaps, such as 0..29, 29..36, and so on. This is methodically totally wrong, but works with integer number of semitones. Microtones can be fractional; if, for example, the pitch values is 29.1, the zone will never be found, and its fallback is a zone at index 0. It produces intolerably bad quality of sound. The fix is in just one function, just few line; it does not change sounds with integer number of semitones: this.adjustPreset = function (audioContext, preset) { const fixedZones = []; for (let zone of preset.zones) { if (zone.keyRangeLow > zone.keyRangeHigh) continue; // pathological case, not used anyway fixedZones.push(zone); this.adjustZone(audioContext, zone); } //loop preset.zones preset.zones = fixedZones; // removing 1-semitone gaps between zones; important for microtones: for (let index = 1; index < preset.zones.length; ++index) preset.zones[index].keyRangeLow = preset.zones[index - 1].keyRangeHigh; }; --- npm/dist/WebAudioFontPlayer.js | 15 +++++++++++---- npm/src/player.js | 13 ++++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/npm/dist/WebAudioFontPlayer.js b/npm/dist/WebAudioFontPlayer.js index 5e71ffc..4bfac97 100644 --- a/npm/dist/WebAudioFontPlayer.js +++ b/npm/dist/WebAudioFontPlayer.js @@ -296,10 +296,17 @@ function WebAudioFontPlayer() { return envelope; }; this.adjustPreset = function (audioContext, preset) { - for (var i = 0; i < preset.zones.length; i++) { - this.adjustZone(audioContext, preset.zones[i]); - } - }; + const fixedZones = []; + for (let zone of preset.zones) { + if (zone.keyRangeLow > zone.keyRangeHigh) continue; // pathological case, not used anyway + fixedZones.push(zone); + this.adjustZone(audioContext, zone); + } //loop preset.zones + preset.zones = fixedZones; + // removing 1-semitone gaps between zones; important for microtones: + for (let index = 1; index < preset.zones.length; ++index) + preset.zones[index].keyRangeLow = preset.zones[index - 1].keyRangeHigh; + }; this.adjustZone = function (audioContext, zone) { if (zone.buffer) { // diff --git a/npm/src/player.js b/npm/src/player.js index 77fdc70..5e3e368 100644 --- a/npm/src/player.js +++ b/npm/src/player.js @@ -169,9 +169,16 @@ function WebAudioFontPlayer() { return envelope; }; this.adjustPreset = function (audioContext, preset) { - for (var i = 0; i < preset.zones.length; i++) { - this.adjustZone(audioContext, preset.zones[i]); - } + const fixedZones = []; + for (let zone of preset.zones) { + if (zone.keyRangeLow > zone.keyRangeHigh) continue; // pathological case, not used anyway + fixedZones.push(zone); + this.adjustZone(audioContext, zone); + } //loop preset.zones + preset.zones = fixedZones; + // removing 1-semitone gaps between zones; important for microtones: + for (let index = 1; index < preset.zones.length; ++index) + preset.zones[index].keyRangeLow = preset.zones[index - 1].keyRangeHigh; }; this.adjustZone = function (audioContext, zone) { if (zone.buffer) {