웹 오디오 FAQ

보리스 스머스

지난 몇 달 동안 WebKit Web Audio API는 웹에서 게임 및 오디오 애플리케이션을 위한 매력적인 플랫폼으로 부상했습니다. 개발자들이 이에 익숙해지면 비슷한 질문이 반복적으로 쏟아집니다. 이 빠른 업데이트는 Web Audio API를 더 즐겁게 사용할 수 있도록 자주 묻는 질문(FAQ)을 해결하기 위한 노력의 일환입니다.

Q: 소리를 낼 수 없습니다.

A: Web Audio API를 처음 사용한다면 시작하기 튜토리얼 또는 에릭이 사용자 상호작용에 기반한 오디오 재생 레시피를 참고하세요.

Q. 오디오 컨텍스트는 몇 개가 있어야 하나요?

A: 일반적으로 페이지당 하나의 AudioContext를 포함해야 하며 단일 오디오 컨텍스트로도 연결된 여러 노드를 지원할 수 있습니다. 한 페이지에 여러 AudioContext를 포함할 수도 있지만 이로 인해 실적 저하가 발생할 수 있습니다.

Q: 방금 noteOn()로 재생한 AudioBufferSourceNode가 있는데 다시 재생하고 싶지만 noteOn()에서 아무것도 하지 않습니다. 도와 주세요!

A: 소스 노드가 재생을 완료하면 더 이상 재생할 수 없습니다. 기본 버퍼를 다시 재생하려면 새 AudioBufferSourceNode를 만들고 noteOn()를 호출해야 합니다.

소스 노드를 다시 만드는 것은 비효율적으로 느껴질 수 있지만, 소스 노드는 이 패턴에 크게 최적화되어 있습니다. 또한 AudioBuffer에 대한 핸들을 유지하면 동일한 사운드를 다시 재생하기 위해 저작물에 다시 요청할 필요가 없습니다. 이 패턴을 반복해야 하는 경우 playSound(buffer)와 같은 간단한 도우미 함수를 사용하여 재생을 캡슐화합니다.

Q: 사운드를 재생할 때 매번 새로운 소스 노드를 만들어야 하는 이유는 무엇인가요?

A: 이 아키텍처의 개념은 오디오 애셋을 재생 상태에서 분리하는 것입니다. 레코드 플레이어에 빗대어 보면, 버퍼는 레코드와 플레이헤드, 소스는 플레이헤드와 유사합니다. 많은 애플리케이션에서는 동일한 버퍼의 여러 버전을 동시에 재생하므로 이 패턴이 필수적입니다.

Q: audiovideo 태그의 소리를 처리하려면 어떻게 해야 하나요?

A: MediaElementAudioSourceNode을(를) 준비 중입니다. 가능한 경우 대략 다음과 같이 작동합니다 (오디오 태그를 통해 재생되는 샘플에 필터 효과 추가).

<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);

이 기능은 이 crbug에서 추적됩니다. 이 설정에서는 mediaSourceNode.noteOn()를 호출하지 않아도 됩니다. 오디오 태그가 재생을 제어합니다.

Q: 마이크는 언제 울릴 수 있나요?

A: 오디오 입력 부분은 getUserMedia를 사용하여 WebRTC의 일부로 구현되며 웹 오디오 API의 특수 소스 노드로 사용할 수 있습니다. createMediaElementSource와 함께 작동합니다.

Q: AudioSourceNode의 재생이 완료된 시점을 확인하려면 어떻게 해야 하나요?

A: Web Audio API가 이 기능을 지원하지 않으므로 JavaScript 타이머를 사용해야 합니다. Web Audio API 시작하기 가이드의 다음 스니펫은 이를 실제 사용하는 예입니다.

// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
    console.log('playback finished');
}, buffer.duration * 1000);

Web Audio API가 더 정확한 콜백을 구현하도록 미해결 버그가 있습니다.

Q: 로드 알림음으로 인해 전체 UI 스레드가 잠기고 UI가 응답하지 않습니다. 도와주세요!**

A: 비동기 로드에 decodeAudioData API를 사용하여 기본 스레드가 차단되지 않도록 합니다. 예시를 참고하세요.

Q: Web Audio API를 사용하여 실시간보다 빠르게 사운드를 처리할 수 있나요?

A: 예, 현재 해결 방법을 찾기 위해 노력하고 있습니다. 계속해서 많은 관심 바랍니다.

Q: 멋진 Web Audio API 애플리케이션을 만들었는데 실행되는 탭이 백그라운드로 이동할 때마다 소리가 이상하게 들립니다.

A: 페이지가 백그라운드에 있으면 다르게 작동하는 setTimeouts를 사용하기 때문일 수 있습니다. 앞으로 Web Audio API에서 웹 오디오의 내부 타이머 (context.currentTime 속성)를 사용하여 특정 시간에 콜백할 수 있게 됩니다. 자세한 내용은 이 기능 요청을 참고하세요.

일반적으로 앱이 백그라운드로 전환될 때 재생을 중지하는 것이 좋습니다. Page Visibility API를 사용하여 페이지가 백그라운드로 이동하는 시점을 감지할 수 있습니다.

Q: Web Audio API를 사용하여 사운드의 높낮이를 변경하려면 어떻게 해야 하나요?

A: 소스 노드의 playbackRate을 변경합니다.

Q: 속도를 변경하지 않고 피치를 변경할 수 있나요?

A: Web Audio API는 오디오 컨텍스트에 PitchNode를 포함할 수 있지만 구현이 어렵습니다. 오디오 커뮤니티에는 간단한 피치 시프팅 알고리즘이 없기 때문입니다. 특히 피치 변경이 큰 경우 알려진 기법으로 아티팩트가 발생합니다. 이 문제를 해결하는 방법에는 두 가지가 있습니다.

  • 반복되는 세그먼트를 유발하는 시간 도메인 알고리즘은 아티팩트를 에코합니다.
  • 잔향 사운드 아티팩트를 발생시키는 주파수 도메인 기법입니다.

이러한 기법을 실행하는 네이티브 노드는 없지만 JavaScriptAudioNode를 사용하면 됩니다. 이 코드 스니펫을 시작점으로 사용할 수 있습니다.

Q: 내가 선택한 샘플링 레이트로 AudioContext를 생성하려면 어떻게 해야 하나요?

A: 현재 이와 관련된 지원은 제공되지 않지만 검토 중입니다. 이 기능 요청을 참고하세요.

더 궁금한 점이 있으면 언제든지 StackOverflow에서 web-audio 태그를 사용하여 문의하세요.