builder / lib /utils /task-complete-sound.ts
Leon4gr45's picture
Upload folder using huggingface_hub (part 3)
94193b5 verified
Raw
History Blame Contribute Delete
3.1 kB
const VOLUME = 0.176; // base peak gain (80% of 0.22)
let sharedContext: AudioContext | null = null;
function getContext(): AudioContext | null {
if (typeof window === 'undefined') return null;
if (sharedContext && sharedContext.state !== 'closed') return sharedContext;
const AC = window.AudioContext || (window as any).webkitAudioContext;
sharedContext = AC ? new AC() : null;
return sharedContext;
}
export function playTaskCompleteSound() {
const ac = getContext();
if (!ac) return;
const t0 = ac.currentTime;
const freqs = [523.3, 784];
const spd = 0.11;
const sw = 0.080;
const dly = ac.createDelay(1.0);
dly.delayTime.value = spd * 1.5;
const dlyG = ac.createGain();
dlyG.gain.value = 0.12;
const fb = ac.createGain();
fb.gain.value = 0.3;
dly.connect(dlyG).connect(ac.destination);
dly.connect(fb).connect(dly);
freqs.forEach((freq, i) => {
const t = t0 + i * spd + (i % 2 === 1 ? spd * sw : 0);
const prev = i > 0 ? freqs[i - 1] : freq;
const o1 = ac.createOscillator();
const o2 = ac.createOscillator();
o1.type = o2.type = 'sine';
o1.frequency.setValueAtTime(prev, t);
o1.frequency.exponentialRampToValueAtTime(freq, t + 0.02);
o2.frequency.setValueAtTime(prev * 1.004, t);
o2.frequency.exponentialRampToValueAtTime(freq * 1.004, t + 0.02);
const flt = ac.createBiquadFilter();
flt.type = 'lowpass';
flt.Q.value = 1;
flt.frequency.setValueAtTime(3500, t);
flt.frequency.exponentialRampToValueAtTime(3000, t + spd + 0.2);
const g = ac.createGain();
g.gain.setValueAtTime(0, t);
g.gain.linearRampToValueAtTime(VOLUME, t + 0.015);
g.gain.setValueAtTime(VOLUME, t + spd * 0.4);
g.gain.exponentialRampToValueAtTime(0.001, t + spd + 0.2);
const mx = ac.createGain();
mx.gain.value = 0.5;
o1.connect(mx);
o2.connect(mx);
mx.connect(flt);
flt.connect(g).connect(ac.destination);
g.connect(dly);
o1.start(t);
o1.stop(t + spd + 0.2 + 0.1);
o2.start(t);
o2.stop(t + spd + 0.2 + 0.1);
});
}
export function playTaskCompleteSoundSubtle() {
const ac = getContext();
if (!ac) return;
const t0 = ac.currentTime;
const freq = 784; // G5
const spd = 0.11;
const o1 = ac.createOscillator();
const o2 = ac.createOscillator();
o1.type = o2.type = 'sine';
o1.frequency.setValueAtTime(freq, t0);
o2.frequency.setValueAtTime(freq * 1.004, t0);
const flt = ac.createBiquadFilter();
flt.type = 'lowpass';
flt.Q.value = 1;
flt.frequency.setValueAtTime(3500, t0);
flt.frequency.exponentialRampToValueAtTime(3000, t0 + spd + 0.2);
const g = ac.createGain();
g.gain.setValueAtTime(0, t0);
g.gain.linearRampToValueAtTime(VOLUME, t0 + 0.015);
g.gain.setValueAtTime(VOLUME, t0 + spd * 0.4);
g.gain.exponentialRampToValueAtTime(0.001, t0 + spd + 0.2);
const mx = ac.createGain();
mx.gain.value = 0.5;
o1.connect(mx);
o2.connect(mx);
mx.connect(flt);
flt.connect(g).connect(ac.destination);
o1.start(t0);
o1.stop(t0 + spd + 0.2 + 0.1);
o2.start(t0);
o2.stop(t0 + spd + 0.2 + 0.1);
}