PageSourceSearch

https://asenno.com/_app/immutable/chunks/BbgUzL3S.js

js asenno.com collected 2026-10-08 13:53:48 UTC 5,560 bytes, 37 lines download raw bytes

1const e={id:"level-cal",title:"Level Calibration",description:"Calibrate audio levels with reference tones.",category:"Calibration",defaultSettings:{referenceLevel:-30,signalType:"sine",frequency:1e3,playing:!1,channelMode:"both"},referenceLevels:[{value:-30,label:"-30 dBFS",desc:"Safe starting level"},{value:-23,label:"-23 dBFS",desc:"EBU R128 (old)"},{value:-20,label:"-20 dBFS",desc:"SMPTE reference"},{value:-18,label:"-18 dBFS",desc:"EBU R128"},{value:-14,label:"-14 dBFS",desc:"Netflix spec"},{value:-12,label:"-12 dBFS",desc:"Broadcast reference"},{value:-6,label:"-6 dBFS",desc:"Half scale"},{value:0,label:"0 dBFS",desc:"Digital maximum"}],signalTypes:{sine:"1 kHz Sine",pink:"Pink Noise","band-limited":"Band-Limited Pink"},channelModes:{both:"Both Channels",left:"Left Only",right:"Right Only",alternating:"Alternating"},dbfsToGain:e=>Math.pow(10,e/20),createBandLimitedPinkNoise(e){const n=2*e.sampleRate,a=e.createBuffer(2,n,e.sampleRate)
2for(let e=0;e<2;e++){const t=a.getChannelData(e)
3let r=0,l=0,i=0,c=0,o=0,s=0,u=0
4for(let e=0;e<n;e++){const n=2*Math.random()-1
5r=.99886*r+.0555179*n,l=.99332*l+.0750759*n,i=.969*i+.153852*n,c=.8665*c+.3104856*n,o=.55*o+.5329522*n,s=-.7616*s-.016898*n,t[e]=r+l+i+c+o+s+u+.5362*n,t[e]*=.11,u=.115926*n}}return a},createNodes(e,n){const a=e.createGain(),t=e.createGain(),r=e.createGain(),l=e.createChannelSplitter(2),i=e.createChannelMerger(2),c=e.createBiquadFilter()
6c.type="highpass",c.frequency.value=500,c.Q.value=.7
7const o=e.createBiquadFilter()
8o.type="lowpass",o.frequency.value=2e3,o.Q.value=.7
9const s=e.createAnalyser()
10return s.fftSize=4096,a.connect(c),c.connect(o),o.connect(l),l.connect(t,0),l.connect(r,1),t.connect(i,0,0),r.connect(i,0,1),i.connect(s),s.connect(n),{calibrationGain:a,leftGain:t,rightGain:r,highpass:c,lowpass:o,splitter:l,merger:i,analyser:s}},updateChannelMode(e,n,a){const{leftGain:t,rightGain:r}=e
11switch(e.alternatingInterval&&(clearInterval(e.alternatingInterval),e.alternatingInterval=null),n){case"both":t.gain.setValueAtTime(1,a.currentTime),r.gain.setValueAtTime(1,a.currentTime)
12break
13case"left":t.gain.setValueAtTime(1,a.currentTime),r.gain.setValueAtTime(0,a.currentTime)
14break
15case"right":t.gain.setValueAtTime(0,a.currentTime),r.gain.setValueAtTime(1,a.currentTime)
16break
17case"alternating":t.gain.setValueAtTime(1,a.currentTime),r.gain.setValueAtTime(0,a.currentTime),e.alternatingInterval=setInterval(()=>{const e=t.gain.value
18t.gain.setValueAtTime(1===e?0:1,a.currentTime),r.gain.setValueAtTime(1===e?1:0,a.currentTime)},1e3)}},start(e,n,a){const t=this.dbfsToGain(n.referenceLevel)
19let r
20e.calibrationGain.gain.setValueAtTime(t,a.currentTime),this.updateChannelMode(e,n.channelMode,a),"band-limited"===n.signalType?(e.highpass.frequency.value=500,e.lowpass.frequency.value=2e3):(e.highpass.frequency.value=20,e.lowpass.frequency.value=2e4)
21let l=null
22switch(n.signalType){case"sine":r=a.createOscillator(),r.type="sine",r.frequency.setValueAtTime(n.frequency,a.currentTime),l=a.createChannelMerger(2),r.connect(l,0,0),r.connect(l,0,1),l.connect(e.calibrationGain)
23break
24case"pink":case"band-limited":r=a.createBufferSource(),r.buffer=this.createBandLimitedPinkNoise(a),r.loop=!0,r.connect(e.calibrationGain)}r.start(),e.source=r,l&&(e.monoToStereo=l),e.currentSignalType=n.signalType},stop(e){e.source&&(e.source.stop(),e.source.disconnect(),e.source=null),e.monoToStereo&&(e.monoToStereo.disconnect(),e.monoToStereo=null),e.alternatingInterval&&(clearInterval(e.alternatingInterval),e.alternatingInterval=null)},updateSettings(e,n,a){const t=this.dbfsToGain(n.referenceLevel)
25if(e.calibrationGain.gain.exponentialRampToValueAtTime(t,a.currentTime+.01),this.updateChannelMode(e,n.channelMode,a),e.currentSignalType!==n.signalType){let t
26e.source&&(e.source.stop(),e.source.disconnect(),e.source=null),e.monoToStereo&&(e.monoToStereo.disconnect(),e.monoToStereo=null)
27let r=null
28switch(n.signalType){case"sine":t=a.createOscillator(),t.type="sine",t.frequency.setValueAtTime(n.frequency,a.currentTime),r=a.createChannelMerger(2),t.connect(r,0,0),t.connect(r,0,1),r.connect(e.calibrationGain)
29break
30case"pink":case"band-limited":t=a.createBufferSource(),t.buffer=this.createBandLimitedPinkNoise(a),t.loop=!0,t.connect(e.calibrationGain)}
30t.start(),e.source=t,r&&(e.monoToStereo=r),e.currentSignalType=n.signalType}"band-limited"===n.signalType?(e.highpass.frequency.exponentialRampToValueAtTime(500,a.currentTime+.01),e.lowpass.frequency.exponentialRampToValueAtTime(2e3,a.currentTime+.01)):(e.highpass.frequency.exponentialRampToValueAtTime(20,a.currentTime+.01),e.lowpass.frequency.exponentialRampToValueAtTime(2e4,a.currentTime+.01)),"sine"===n.signalType&&e.source&&e.source.frequency&&e.source.frequency.exponentialRampToValueAtTime(n.frequency,a.currentTime+.01)},getRMSLevel(e){if(!e.analyser)return-1/0
31const n=e.analyser.fftSize,a=new Float32Array(n)
32e.analyser.getFloatTimeDomainData(a)
33let t=0
34for(let e=0;e<n;e++)t+=a[e]*a[e]
35const r=Math.sqrt(t/n)
36return 20*Math.log10(r)},keyboard:{handlers:{" ":e=>({playing:!e.playing}),ArrowUp:e=>({referenceLevel:Math.min(0,e.referenceLevel+1)}),ArrowDown:e=>({referenceLevel:Math.max(-60,e.referenceLevel-1)})}},visualization:{type:"level-meter",fftSize:4096,showRMS:!0,showPeak:!0,showTarget:!0},controls:{showReferenceLevelSelector:!0,showSignalTypeSelector:!0,showChannelModeSelector:!0,showPlayButton:!0,showLevelMeter:!0,showFrequencySlider:!0,infoText:"Generate calibrated reference signals for setting up audio systems. Match levels across equipment for optimal gain staging."}}
37export{e as default}

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.