1import { getAudioContext } from './audioContext.mjs';
https://github.com/KilledByAPixel/ZzFX/blob/master/ZzFX.js#L85C5-L180C6 changes: replaced this.volume with 1 + using sampleRate from getAudioContext()
5export function buildSamples( 6 volume = 1, 7 randomness = 0.05, 8 frequency = 220, 9 attack = 0, 10 sustain = 0, 11 release = 0.1, 12 shape = 0, 13 shapeCurve = 1, 14 slide = 0, 15 deltaSlide = 0, 16 pitchJump = 0, 17 pitchJumpTime = 0, 18 repeatTime = 0, 19 noise = 0, 20 modulation = 0, 21 bitCrush = 0, 22 delay = 0, 23 sustainVolume = 1, 24 decay = 0, 25 tremolo = 0, 26) { 27 // init parameters 28 let PI2 = Math.PI * 2, 29 sampleRate = getAudioContext().sampleRate, 30 sign = (v) => (v > 0 ? 1 : -1), 31 startSlide = (slide *= (500 * PI2) / sampleRate / sampleRate), 32 startFrequency = (frequency *= ((1 + randomness * 2 * Math.random() - randomness) * PI2) / sampleRate), 33 b = [], 34 t = 0, 35 tm = 0, 36 i = 0, 37 j = 1, 38 r = 0, 39 c = 0, 40 s = 0, 41 f, 42 length;
scale by sample rate
45 attack = attack * sampleRate + 9; // minimum attack to prevent pop 46 decay *= sampleRate; 47 sustain *= sampleRate; 48 release *= sampleRate; 49 delay *= sampleRate; 50 deltaSlide *= (500 * PI2) / sampleRate ** 3; 51 modulation *= PI2 / sampleRate; 52 pitchJump *= PI2 / sampleRate; 53 pitchJumpTime *= sampleRate; 54 repeatTime = (repeatTime * sampleRate) | 0;
generate waveform
57 for (length = (attack + decay + sustain + release + delay) | 0; i < length; b[i++] = s) { 58 if (!(++c % ((bitCrush * 100) | 0))) { 59 // bit crush 60 s = shape 61 ? shape > 1 62 ? shape > 2 63 ? shape > 3 // wave shape 64 ? Math.sin((t % PI2) ** 3) // 4 noise 65 : Math.max(Math.min(Math.tan(t), 1), -1) // 3 tan 66 : 1 - (((((2 * t) / PI2) % 2) + 2) % 2) // 2 saw 67 : 1 - 4 * Math.abs(Math.round(t / PI2) - t / PI2) // 1 triangle 68 : Math.sin(t); // 0 sin 69 70 s = 71 (repeatTime 72 ? 1 - tremolo + tremolo * Math.sin((PI2 * i) / repeatTime) // tremolo 73 : 1) * 74 sign(s) * 75 Math.abs(s) ** shapeCurve * // curve 0=square, 2=pointy 76 volume * 77 1 * // envelope 78 (i < attack 79 ? i / attack // attack 80 : i < attack + decay // decay 81 ? 1 - ((i - attack) / decay) * (1 - sustainVolume) // decay falloff 82 : i < attack + decay + sustain // sustain 83 ? sustainVolume // sustain volume 84 : i < length - delay // release 85 ? ((length - i - delay) / release) * // release falloff 86 sustainVolume // release volume 87 : 0); // post release 88 89 s = delay 90 ? s / 2 + 91 (delay > i 92 ? 0 // delay 93 : ((i < length - delay ? 1 : (length - i) / delay) * // release delay 94 b[(i - delay) | 0]) / 95 2) 96 : s; // sample delay 97 } 98 99 f = 100 (frequency += slide += deltaSlide) * // frequency 101 Math.cos(modulation * tm++); // modulation 102 t += f - f * noise * (1 - (((Math.sin(i) + 1) * 1e9) % 2)); // noise 103 104 if (j && ++j > pitchJumpTime) { 105 // pitch jump 106 frequency += pitchJump; // apply pitch jump 107 startFrequency += pitchJump; // also apply to start 108 j = 0; // stop pitch jump time 109 } 110 111 if (repeatTime && !(++r % repeatTime)) { 112 // repeat 113 frequency = startFrequency; // reset frequency 114 slide = startSlide; // reset slide 115 j ||= 1; // reset pitch jump time 116 } 117 }