SOUND / 247
Low-pass filter
高い成分を削る
低い周波数を通すフィルターで、同じ音の明るさを変えます。
見本の中を操作して変化を試してください。
ひとつ試すなら
カットオフを下げると、角のある音が丸くなるか聴く。
こんなときに
効果音の設計、音色と空間の比較。
仕組みと使い方
カットオフを下げると、角のある音が丸くなるか聴く。
対応状況は使用する機能と端末により異なります。公式資料も参照してください。
表現名には通称や説明のための名称を含みます。デモと掲載コードはこの図鑑のオリジナルです。作者について
実装コードを見る
<!doctype html><html lang="ja"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><style>body{margin:0;min-height:330px}.sample{width:100%;height:100%;min-height:330px;padding:12px!important;display:flex!important;flex-direction:column;justify-content:center;align-items:center;gap:8px!important;background:#f0efeb;color:#232323;font-family:Arial,Meiryo,sans-serif;overflow:hidden;box-sizing:border-box}.sample *{box-sizing:border-box}.lab-scene{width:100%;max-width:430px;height:140px;position:relative;overflow:hidden;border-bottom:1px solid #ccc}.lab-scene:has(canvas){max-width:320px;height:auto;aspect-ratio:16/9;flex-shrink:0}.lab-canvas{display:block;width:100%;height:100%!important;outline-offset:-3px}.lab-canvas:focus-visible{outline:2px solid #222}.lab-controls{width:100%;max-width:390px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 14px}.lab-controls label{display:grid;grid-template-columns:1fr auto;gap:2px;font-size:11px;min-width:0}.lab-controls input{grid-column:1/-1;width:100%;min-width:0;margin:0;accent-color:#333;height:30px}.lab-controls output{font-variant-numeric:tabular-nums}.lab-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap;justify-content:center}.sample .lab-actions button{color:inherit;font:11px Arial,Meiryo,sans-serif;border:1px solid #aaa;border-radius:99px;background:transparent;min-height:44px;padding:8px 12px;cursor:pointer}.lab-status{font-size:10px;line-height:1.4;min-height:14px;margin:0;text-align:center}.lab-note{font-size:9px;line-height:1.3;color:#666;margin:0;text-align:center}.lab-actions button:focus-visible{outline:2px solid #222;outline-offset:2px}@media(prefers-reduced-motion:reduce){.sample *{animation-play-state:paused!important;transition:none!important}}</style><div class="sample"><div class="lab-scene"><canvas class="lab-canvas" role="img" aria-label="高い成分を削るの可視化"></canvas></div><div class="lab-controls"><label>カットオフ Hz<output>1800</output><input type="range" aria-label="カットオフ Hz" min="150" max="5000" step="50" value="1800" data-key="cutoff"></label><label>共鳴<output>1</output><input type="range" aria-label="共鳴" min="0.1" max="8" step="0.1" value="1" data-key="resonance"></label></div><div class="lab-actions"><button data-audio aria-pressed="false">音を再生</button></div><p class="lab-status" role="status">停止中 · 音は自動では鳴りません</p></div><script>const lab=(function runAudioLab(root,cfg){
const canvas=root.querySelector('canvas'),ctx=canvas.getContext('2d'),button=root.querySelector('[data-audio]'),status=root.querySelector('.lab-status'),abort=new AbortController();let ac=null,osc=null,amp=null,filter=null,analyser=null,panner=null,delay=null,feedback=null,reverb=null,frame=0,timer=0,nodes=[],starting=false,dead=false,playing=false;
const values=Object.fromEntries(cfg.controls.map(c=>[c.key,c.value]));canvas.width=640;canvas.height=360;
function paint(data=null){ctx.setTransform(2,0,0,2,0,0);ctx.clearRect(0,0,320,180);ctx.translate(0,15);ctx.strokeStyle='#333';ctx.fillStyle='#333';ctx.lineWidth=1.5;const kind=cfg.kind;
if(data&&kind==='av-spectrum'){const a=new Uint8Array(analyser.frequencyBinCount);analyser.getByteFrequencyData(a);for(let i=0;i<32;i++){const h=a[i*3]/255*120;ctx.fillStyle=`rgb(${40+i*4},${40+i*4},${40+i*4})`;ctx.fillRect(5+i*9.8,135-h,6,h)}}
else if(data&&(kind==='av-amplitude'||kind==='av-particles')){const rms=Math.sqrt(data.reduce((sum,x)=>sum+((x-128)/128)**2,0)/data.length);const r=15+rms*180;for(let i=0;i<(kind==='av-particles'?48:1);i++){const a=i*2.399,t=kind==='av-particles'?r+Math.sqrt(i)*5:0;ctx.beginPath();ctx.arc(160+Math.cos(a+ac.currentTime*.2)*t,75+Math.sin(a+ac.currentTime*.2)*t*.65,kind==='av-particles'?2+rms*8:r,0,Math.PI*2);ctx.fill()}}
else if(kind==='sound-spatial'){ctx.fillStyle='#bbb';ctx.beginPath();ctx.arc(160,100,16,0,Math.PI*2);ctx.fill();ctx.fillStyle='#333';ctx.beginPath();ctx.arc(160+(values.pan||0)*32,95-(values.distance||1)*15,9,0,Math.PI*2);ctx.fill();ctx.font='11px Arial';ctx.textAlign='center';ctx.fillText('listener',160,135);}
else if(data){ctx.beginPath();for(let i=0;i<data.length;i++){const x=i/data.length*320,y=75+(data[i]-128)*.8;i?ctx.lineTo(x,y):ctx.moveTo(x,y)}ctx.stroke();}
else {ctx.beginPath();ctx.moveTo(15,75);ctx.lineTo(305,75);ctx.stroke();ctx.font='16px Arial';ctx.textAlign='center';ctx.fillText('press to listen.',160,55);}
}
function stop(){playing=false;cancelAnimationFrame(frame);clearTimeout(timer);if(ac){const old=ac;ac=null;old.close().catch(()=>{});}nodes=[];button.textContent='音を再生';button.setAttribute('aria-pressed','false');status.textContent='停止中 · 音は自動では鳴りません';paint()}
function update(){if(!ac)return;const now=ac.currentTime;osc.frequency.setTargetAtTime(values.pitch||220,now,.025);filter.frequency.setTargetAtTime(values.cutoff||2400,now,.025);filter.Q.setTargetAtTime(values.resonance||1,now,.025);if(panner){panner.positionX.setTargetAtTime(values.pan||0,now,.025);panner.positionZ.setTargetAtTime(-(values.distance||1),now,.025);}if(delay)delay.delayTime.setTargetAtTime(values.delay||.25,now,.025);if(feedback)feedback.gain.setTargetAtTime(values.feedback??.35,now,.025);if(cfg.kind==='sound-timbre')osc.type=['sine','triangle','square','sawtooth'][values.wave];}
async function start(){if(starting||dead)return;if(playing){stop();return}starting=true;try{const Audio=globalThis.AudioContext||globalThis.webkitAudioContext;if(!Audio)throw Error('unavailable');ac=new Audio();await ac.resume();if(dead){ac.close();ac=null;return}osc=ac.createOscillator();osc.type=['sound-filter','av-spectrum'].includes(cfg.kind)?'sawtooth':'sine';amp=ac.createGain();amp.gain.value=.06;filter=ac.createBiquadFilter();filter.type='lowpass';analyser=ac.createAnalyser();analyser.fftSize=512;const master=ac.createGain();master.gain.value=.45;osc.connect(amp);amp.connect(filter);filter.connect(analyser);analyser.connect(master);master.connect(ac.destination);nodes=[osc,amp,filter,analyser,master];
if(cfg.kind==='sound-delay'){delay=ac.createDelay(1);feedback=ac.createGain();feedback.gain.value=.3;filter.connect(delay);delay.connect(feedback);feedback.connect(delay);delay.connect(analyser);}
if(cfg.kind==='sound-reverb'){reverb=ac.createConvolver();const length=Math.floor(ac.sampleRate*values.tail),impulse=ac.createBuffer(2,length,ac.sampleRate);let seed=42;for(let ch=0;ch<2;ch++){const a=impulse.getChannelData(ch);for(let i=0;i<length;i++){seed=(seed*1664525+1013904223)>>>0;a[i]=(seed/4294967296*2-1)*Math.pow(1-i/length,3);}}reverb.buffer=impulse;const wet=ac.createGain();wet.gain.value=.65;filter.connect(reverb);reverb.connect(wet);wet.connect(analyser);}
if(cfg.kind==='sound-spatial'){panner=ac.createPanner();panner.panningModel='HRTF';panner.distanceModel='inverse';filter.disconnect();filter.connect(panner);panner.connect(analyser);}
const now=ac.currentTime;update();osc.start(now);playing=true;button.textContent='音を停止';button.setAttribute('aria-pressed','true');status.textContent=cfg.kind==='sound-reverb'?'残響の長さは次回再生に反映 · 最大8秒':'再生中 · 最大8秒で自動停止';
if(['sound-envelope','sound-reverb','sound-delay'].includes(cfg.kind)){amp.gain.cancelScheduledValues(now);amp.gain.setValueAtTime(0,now);amp.gain.linearRampToValueAtTime(.18,now+(values.attack||.02));amp.gain.exponentialRampToValueAtTime(.0001,now+(values.attack||.02)+(values.release||.18));}
const data=new Uint8Array(analyser.fftSize);function tick(){if(!playing||!ac||dead)return;if(cfg.kind==='av-amplitude'||cfg.kind==='av-particles')amp.gain.setTargetAtTime(.02+.12*Math.max(0,Math.sin(ac.currentTime*(values.tempo||90)/60*Math.PI*2)),ac.currentTime,.015);analyser.getByteTimeDomainData(data);paint(data);frame=requestAnimationFrame(tick)}tick();timer=setTimeout(stop,8000);
}catch{stop();status.textContent='音を再生できませんでした。端末の音声設定を確認してください。'}finally{starting=false}}
button.addEventListener('click',start,{signal:abort.signal});for(const input of root.querySelectorAll('[data-key]'))input.addEventListener('input',()=>{values[input.dataset.key]=Number(input.value);input.closest('label').querySelector('output').textContent=input.value;update();if(!playing)paint()},{signal:abort.signal});document.addEventListener('visibilitychange',()=>{if(document.hidden)stop()},{signal:abort.signal});paint();
return {setAuto(on){if(!on&&playing)stop()},destroy(){dead=true;stop();abort.abort()}};
})(document,{"kind":"sound-filter","controls":[{"key":"cutoff","label":"カットオフ Hz","min":150,"max":5000,"value":1800,"step":50},{"key":"resonance","label":"共鳴","min":0.1,"max":8,"value":1,"step":0.1}]});addEventListener('pagehide',()=>lab.destroy(),{once:true});</script></html>