repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
stars
latest
clone command
git clone gitlawb://did:key:z6MkvfHn...poLu/gitcatgit clone gitlawb://did:key:z6MkvfHn.../gitcata815108csync from playground1d ago| #1 | import { useCallback, useRef } from 'react'; |
| #2 | |
| #3 | export function usePopSound() { |
| #4 | const ctxRef = useRef<AudioContext | null>(null); |
| #5 | |
| #6 | const play = useCallback(() => { |
| #7 | if (!ctxRef.current) { |
| #8 | ctxRef.current = new AudioContext(); |
| #9 | } |
| #10 | const ctx = ctxRef.current; |
| #11 | if (ctx.state === 'suspended') ctx.resume(); |
| #12 | const now = ctx.currentTime; |
| #13 | |
| #14 | // Noise burst for "p" attack |
| #15 | const noiseLen = 0.035; |
| #16 | const noiseBuf = ctx.createBuffer(1, ctx.sampleRate * noiseLen, ctx.sampleRate); |
| #17 | const noiseData = noiseBuf.getChannelData(0); |
| #18 | for (let i = 0; i < noiseData.length; i++) { |
| #19 | noiseData[i] = (Math.random() * 2 - 1) * 0.4; |
| #20 | } |
| #21 | const noiseSrc = ctx.createBufferSource(); |
| #22 | noiseSrc.buffer = noiseBuf; |
| #23 | const noiseGain = ctx.createGain(); |
| #24 | noiseGain.gain.setValueAtTime(0.18, now); |
| #25 | noiseGain.gain.exponentialRampToValueAtTime(0.001, now + noiseLen); |
| #26 | const noiseFilt = ctx.createBiquadFilter(); |
| #27 | noiseFilt.type = 'highpass'; |
| #28 | noiseFilt.frequency.value = 2000; |
| #29 | noiseSrc.connect(noiseFilt).connect(noiseGain).connect(ctx.destination); |
| #30 | noiseSrc.start(now); |
| #31 | noiseSrc.stop(now + noiseLen); |
| #32 | |
| #33 | // Main "git" sine sweep — sharper attack, higher start for "g" consonant |
| #34 | const osc = ctx.createOscillator(); |
| #35 | osc.type = 'sine'; |
| #36 | osc.frequency.setValueAtTime(1100, now); |
| #37 | osc.frequency.exponentialRampToValueAtTime(140, now + 0.13); |
| #38 | const oscGain = ctx.createGain(); |
| #39 | oscGain.gain.setValueAtTime(0.32, now); |
| #40 | oscGain.gain.exponentialRampToValueAtTime(0.001, now + 0.15); |
| #41 | osc.connect(oscGain).connect(ctx.destination); |
| #42 | osc.start(now); |
| #43 | osc.stop(now + 0.17); |
| #44 | |
| #45 | // Sub tone for weight |
| #46 | const sub = ctx.createOscillator(); |
| #47 | sub.type = 'sine'; |
| #48 | sub.frequency.setValueAtTime(220, now); |
| #49 | sub.frequency.exponentialRampToValueAtTime(55, now + 0.09); |
| #50 | const subGain = ctx.createGain(); |
| #51 | subGain.gain.setValueAtTime(0.2, now); |
| #52 | subGain.gain.exponentialRampToValueAtTime(0.001, now + 0.11); |
| #53 | sub.connect(subGain).connect(ctx.destination); |
| #54 | sub.start(now); |
| #55 | sub.stop(now + 0.13); |
| #56 | }, []); |
| #57 | |
| #58 | return play; |
| #59 | } |
| #60 |