1/** 2 * Shared bubble-wrap style pop sound (Web Audio API). 3 */ 4(function (global) { 5 'use strict'; 6 7 var audioContext = null; 8 9 function initAudioContext() { 10 if (audioContext) return audioContext; 11 try { 12 audioContext = new (global.AudioContext || global.webkitAudioContext)(); 13 } catch (e) { 14 audioContext = null; 15 } 16 return audioContext; 17 } 18 19 function playPopSound(volume) { 20 var vol = typeof volume === 'number' ? volume : 0.7; 21 var ctx = initAudioContext(); 22 if (!ctx) return; 23 24 try { 25 if (ctx.state === 'suspended') { 26 ctx.resume(); 27 } 28 29 var duration = 0.08; 30 var sampleRate = ctx.sampleRate; 31 var frameCount = Math.floor(sampleRate * duration); 32 var buffer = ctx.createBuffer(1, frameCount, sampleRate); 33 var data = buffer.getChannelData(0); 34 35 for (var i = 0; i < frameCount; i++) { 36 var t = i / sampleRate; 37 var progress = t / duration; 38 var freq1 = 200 + Math.random() * 100; 39 var freq2 = 800 + Math.random() * 400; 40 var freq3 = 2000 + Math.random() * 1000; 41 var envelope = Math.exp(-t * 50) * (1 - progress); 42 var wave1 = Math.sin(2 * Math.PI * freq1 * t) * 0.4; 43 var wave2 = Math.sin(2 * Math.PI * freq2 * t) * 0.3; 44 var wave3 = Math.sin(2 * Math.PI * freq3 * t) * 0.2; 45 var noise = (Math.random() * 2 - 1) * 0.1; 46 data[i] = (wave1 + wave2 + wave3 + noise) * envelope * vol; 47 } 48 49 var source = ctx.createBufferSource(); 50 source.buffer = buffer; 51 source.connect(ctx.destination); 52 source.start(0); 53 } catch (e) { 54 /* ignore */ 55 } 56 } 57 58 global.PopSound = { 59 init: initAudioContext, 60 play: playPopSound, 61 playSoft: function () { 62 playPopSound(0.49); 63 } 64 }; 65})(typeof window !== 'undefined' ? window : this);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.