WebAudioAPI 사용
40508 단어 JavaScriptWebAudioAPItech
이 글의 내용
다음은 간단한 모바일 해설을 통해 브라우저에서 사운드를 사용하는 API 웹오디오 API에 대한 해설입니다.
우선 분위기와 흐름을 파악하도록 이 글을 썼습니다.
글에는 MDN을 추가한 몇 가지 더 자세한 보도 링크가 있으니 음성 처리에 관심이 있기를 바랍니다.
이른바 웹오디오 API
브라우저를 사용하여 낮은 수준의 사운드 머시닝을 제공하는 API입니다.
API는
AudioContext
또는 웹 키트 접두어를 사용하여 제공됩니다.따라서 초기화
const audioCtx= new (window.AudioContext || window.webkitAudioContext)();
와 같은 초기화MDN에서 추천.AudioContext
에서 baseLatency
,outputLatency
등 지연 시간을 얻거나currentTime
에서 현재 시간state
을 얻거나AudioContext.resume()
에서 상태를 얻는다.사용자 동작에 불이 났습니다. AudioContext.resume()
2010/12/17
웹 오디오 API의 어둠 에서 보듯이 Google Chrome에서는 사용자 동작, 예를 들어 버튼 클릭 등 (Confirm은 사용자 동작으로 간주되지 않는 모양) 으로 부르지 않으면
Promise<>
정상적으로 작동할 수 없습니다.이 반환값은AudioContext.destination
이기 때문에 프로그램의 구조 자체를 고칠 필요가 있으니 주의해야 한다.AudioNode
WebAudioAPI에서는 연결을 통해 AudioNode의 (출력 목적지) 를 계승하여 소리를 생성합니다.
이 연결은
input.connect(output)
처럼 연결되지만 이 방법은 연결 목적지 자체로 되돌아오기 때문에 input.connect(output).connect(next)
처럼 쓸 수 있다.기본적으로
AudioContext
의createXXX
공장 방법으로 생성된다.AudioParam
AudioParam의 인터페이스에서 음성을 제어하는 매개 변수를 제공합니다.이들 가운데
defaultValue
, minValue
, maxValue
등의 설정값(읽기만 가능)과 값 자체value
가 설정됐다.value 변경을 통해 다양한 효과를 낼 수 있습니다.파라미터 이름 자체의 값을 설정에 대입할 수 있으면 오류가 발생할 수 있으니 주의하십시오!
방법을 통해 스케줄링을 할 수도 있다.
샘플링 확률
a-rate
을 완전히 따르는 매개 변수와 그보다 더 따르지 않는 매개 변수(128개의 샘플마다)k-rate
가 있다.(자세한 설정은 문서 등을 확인하십시오.)구체적인 음원들.
발진기 OscillatorNode
특정 주파수의 파형의 음원
type
속성에 따라 파형을 설정할 수 있다.setPeriodicWave(wave)
설정을 통해frequency
와detune
(AudioParam)를 통해 설정할 수 있다.AudioBufferSourceNode
파형 자체 사용AudioBuffer.
playbackRate
또는 detune
를 통해 음정을 바꿀 수 있다.또한,
loop
(bool 값)에서 순환 설정loopStart
(초 단위)시 순환으로 돌아가는 지점, loopEnd
(초 단위)로 순환에 들어가는 지점을 설정할 수 있다.이번에는 흰색 소음에 사용되는 다음과 같은 느낌의 코드를 사용했다.
whiteNoise.js
function makeWhiteNoise(){
const buffer=audioCtx.createBuffer(2, 5*audioCtx.sampleRate, audioCtx.sampleRate);
for( let channel=0; channel<buffer.numberOfChannels; channel++ ){
const data=buffer.getChannelData(channel);
for( let i=0; i<buffer.length; i++ ){
data[i]=Math.random()*2.0-1.0; // [ 0: 1.0 ]-> [ -1.0 : 1.0 ]の乱数へ
}
}
const bufferSrc=audioCtx.createBufferSource();
bufferSrc.buffer=buffer;
bufferSrc.loop=true;
return bufferSrc;
}
디코딩 소스 파일
음원 파일을 사용하고 싶을 때AudicoContext.decodeAudioData(arrayBuffer).
이것도 예전의 호출 형식과 Promise 형식이 있었지만 지금은 기본적으로 Promise 형식을 지원한다.(Promise를 사용할 수 없는 브라우저는 WebAudioAPI 자체를 지원하지 않음)
arrayBuffer
XML HTTPRequest 또는 FileReader로 직접 찾기(MDN에 적혀 있음).물론 FetchAPI도 이렇게 할 수 있어요.
decodeAudioData.js
function decodeAudioData(url){
fetch(url).then(res=>res.arrayBuffer()).then(arrayBuffer=>{
return audioCtx.decodeAudioData(arrayBuffer)
});
}
Media Stream Audio SourceNode를 위한 마이크 오디오
getMediaDevices.js
async function(){
const stream = await navigator.mediaDevices.getUserMedia({ video: false, audio: true });
const audioStream=audioCtx.createMediaStreamSource(stream);
return audioStream;
}
이런 코드로navigator에서 마이크 흐름을 추출하고 웹오디오 API로 처리할 수 있습니다.효과계 노드 소개
GainNode
AudioParam
gain
이 있는 간단한 노드의 음량에 주로 사용됩니다.이 밖에도 몇 개의 채널을 통합하는 데 쓰인다.
DelayNode
AudioParam
delayTime
이 있는 노드에서 신호를 지연합니다.주의점은 완전한 지연이기 때문에 단독으로 사용할 수 없습니다. 반드시 무엇으로 순환해야만 사용할 수 있습니까? 여기 참고g200kg의 웹 오디오 API 해설 >13.지연 사용 방법는 다음과 같은 두 가지 예를 들었습니다.
Delay 모듈
이른바 효과기인 딜레이 모듈이 지연 신호를 혼합해 출력하기 때문에 이런 구조가 만들어졌다.
SimpleDelay.js
class SimpleDelay{
constructor(audioCtx){
this.inputNode=audioCtx.createGain();
this.delayNode=audioCtx.createDelay();
this.feedbackNode=audioCtx.createGain();
this.dryNode=audioCtx.createGain();
this.wetNode=audioCtx.createGain();
this.delayNode.delayTime.value=1.0;
this.feedbackNode.gain.value=0.5;
this.dryNode.gain.value=0.8;
this.wetNode.gain.value=0.2;
this.inputNode.connect(this.delayNode).connect(this.feedbackNode).connect(this.delayNode);
this.delayNode.connect(this.wetNode);
this.inputNode.connect(this.dryNode);
}
connect(next){
this.dryNode.connect(next);
this.wetNode.connect(next);
return next;
}
get input(){ return this.inputNode; }
get delayTime(){ return this.delayNode.delayTime; }
get feedback(){ return this.feedbackNode.gain; }
get mix(){ return this.wetNode.gain.value; }
set mix(value){
if( value<0 && 1<value ) new Error(`Invalid mix value ${val}`);
this.wetNode.gain.value=value;
this.dryNode.gain.value=1.0-value;
}
}
있긴 하지만g200kg님도 맞춤형 노드 만드는 방법기존오디오노드를혼자상속받고new를두드릴 필요가있어특별하므로각노드를상속받지 않고반원으로하는 방법을취했다.결과적으로 입력단이 체인을 사용하는connect는 사용할 수 없습니다.각 오디오노드의 속성인 오디오노드를
get xxx()
형식으로 자신의 것으로 위장했다.또한 출력 측
connect
은 안에 두 개의 출구 연결 노드를 연결하기 때문에 여기서 체인을 사용할 수 있다.AudioParam에 연결, 로터리 효과기 Chorus
오디오노드는 오디오팔람에 연결될 수 있으며, 이를 통해 델리타임 같은 것을 흔들어 이른바 합창을 실현할 수 있다.
Chorus.js
class Chorus{
constructor(audioCtx){
this.inputNode=audioCtx.createGain();
this.delayNode=audioCtx.createDelay();
this.mixNode=audioCtx.createGain();
this.lfo=audioCtx.createOscillator();
this.depthNode=audioCtx.createGain();
this.lfo.frequency.value=5;
this.depthNode.gain.value=0.005;
this.mixNode.gain.value=0.2;
this.lfo.connect(this.depthNode).connect(this.delayNode.delayTime); // この部分
this.inputNode.connect(this.delayNode).connect(this.mixNode);
}
connect(next){
this.mixNode.connect(next);
this.input.connect(next);
return next;
}
get input(){ return this.inputNode; }
get speed(){ return this.lfo.frequency; }
get depth(){ return this.depthNode.gain; }
get mix(){ return this.mixNode.gain; }
}
lfo
는 Low Frequency Oscillator라는 뜻으로 현실의 효과기 등에 자주 등장한다.BiquadFilterNode(이중 필터)
일반 필터
주파수 설정 (frequency 및 detune), Q 값,gain을 나타내는 오디오 Param, 종류 type (속성 값) 이 있습니다.
BiquadFilterNode의 종류
전체 사용 방법
index.js
onst audioCtx = new (window.AudioContext || window.webkitAudioContext)();
window.addEventListener('DOMContentLoaded', async ()=>{
const masterGain=audioCtx.createGain();
bindValue(document.getElementById('master-vol'), masterGain.gain);
const sourceInput=audioCtx.createGain();
const simpleDelay=new SimpleDelay(audioCtx);
bindValue(document.getElementById("delay-time"), simpleDelay.delayTime);
bindValue(document.getElementById("feedback-gain"), simpleDelay.feedback);
bindProp(document.getElementById('delay-mix'), simpleDelay, 'mix');
const oscillator=audioCtx.createOscillator();
oscillator.start();
bindValue(document.getElementById('oscillator-freq'), oscillator.frequency);
bindSelect(document.getElementById('oscillator-type'), oscillator, 'type');
oscillator.connect(sourceInput).connect(simpleDelay.input); // can not connect as chain
simpleDelay.connect(masterGain).connect(audioCtx.destination);
document.getElementById('start-btn', ()=>{ oscillator.start() });
});
function bindValue(element, param){ element.addEventListener('change', ()=>{ param.value=element.value; }); }
function bindProp(element, param, prop){ element.addEventListener('change', ()=>{ param[prop]=element.value; }); }
function bindSelect(select, node, prop){ select.addEventListener('change', ()=>{ node[prop]=[ ...select.children ].find(a=> a.selected).value; }); }
이렇게 사용하세요.bindValue
AudioParam의 값value
과 HTML Elementinput[type="range"]
을 직접 제한bindSelect
는 발진기 유형을 HTML Element의 select 라벨과 유사하게 결합시킨다.Delay 모듈의
mix
는 value
속성이 아니기 때문에 다른 함수를 준비했습니다.(이것들은 모두 일부라서 복제만 하면 움직이지 않을 것 같다.)
후기
먼저 기초 개념을 겸비한 해설을 겸비한 간단한 것들의 제작 방법을 설명한다.
더 자세한 노드와 다른 해설은 이 글에서도 자주 언급된g200kg 홈페이지을 참조하십시오.
또 Web Sounder간단한 샘플을 첨부하여 해설을 진행한다.
더 자세한 설명은 W3C 기사(일본어) 더 정확한 정보W3C를 참조하십시오.
다른 노드 해설 등 추가 예정
Reference
이 문제에 관하여(WebAudioAPI 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/takeyasu/articles/c8688b559a4cc4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)