import { ZZFX } from 'zzfx';
8export const getZZFX = (value, t) => { 9 let { 10 s, 11 note = 36, 12 freq, 13 // 14 zrand = 0, 15 attack = 0, 16 decay = 0, 17 sustain = 0.8, 18 release = 0.1, 19 curve = 1, 20 slide = 0, 21 deltaSlide = 0, 22 pitchJump = 0, 23 pitchJumpTime = 0, 24 lfo = 0, 25 znoise = 0, 26 zmod = 0, 27 zcrush = 0, 28 zdelay = 0, 29 tremolo = 0, 30 duration = 0.2, 31 zzfx, 32 } = value; 33 const sustainTime = Math.max(duration - attack - decay, 0); 34 if (typeof note === 'string') { 35 note = noteToMidi(note); // e.g. c3 => 48 36 } 37 // get frequency 38 if (!freq && typeof note === 'number') { 39 freq = midiToFreq(note); 40 } 41 s = s.replace('z_', ''); 42 const shape = ['sine', 'triangle', 'sawtooth', 'tan', 'noise'].indexOf(s) || 0; 43 curve = s === 'square' ? 0 : curve; 44 45 const params = zzfx || [ 46 0.25, // volume 47 zrand, 48 freq, 49 attack, 50 sustainTime, 51 release, 52 shape, 53 curve, 54 slide, 55 deltaSlide, 56 pitchJump, 57 pitchJumpTime, 58 lfo, 59 znoise, 60 zmod, 61 zcrush, 62 zdelay, 63 sustain, // sustain volume! 64 decay, 65 tremolo, 66 ]; 67 // console.log(redableZZFX(params)); 68 69 const samples = /* ZZFX. */ buildSamples(...params); 70 const context = getAudioContext(); 71 const buffer = context.createBuffer(1, samples.length, context.sampleRate); 72 buffer.getChannelData(0).set(samples); 73 const source = getAudioContext().createBufferSource(); 74 source.buffer = buffer; 75 source.start(t); 76 return { 77 node: source, 78 }; 79}; 80 81export function registerZZFXSounds() { 82 ['zzfx', 'z_sine', 'z_sawtooth', 'z_triangle', 'z_square', 'z_tan', 'z_noise'].forEach((wave) => { 83 registerSound( 84 wave, 85 (t, value, onended) => { 86 const { node: o } = getZZFX({ s: wave, ...value }, t); 87 onceEnded(o, () => { 88 releaseAudioNode(o); 89 onended(); 90 }); 91 return { 92 node: o, 93 nodes: { source: [o] }, 94 stop: () => {}, 95 }; 96 }, 97 { type: 'synth', prebake: true }, 98 ); 99 }); 100}
just for debugging
103function redableZZFX(params) { 104 const paramOrder = [ 105 'volume', 106 'zrand', 107 'frequency', 108 'attack', 109 'sustain', 110 'release', 111 'shape', 112 'curve', 113 'slide', 114 'deltaSlide', 115 'pitchJump', 116 'pitchJumpTime', 117 'lfo', 118 'noise', 119 'zmod', 120 'zcrush', 121 'zdelay', 122 'sustainVolume', 123 'decay', 124 'tremolo', 125 ]; 126 return Object.fromEntries(paramOrder.map((param, i) => [param, params[i]])); 127}