웹 오디오 FAQ

지난 몇 개월 동안 WebKit Web Audio API가 웹에서 게임과 오디오 애플리케이션을 위한 매력적인 플랫폼으로 떠올랐습니다. 개발자가 익숙해짐에 따라 비슷한 질문이 반복적으로 제기됩니다. 이 빠른 업데이트는 Web Audio API 사용 환경을 개선하기 위해 자주 묻는 질문을 해결하기 위한 것입니다.

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의 일부로 구현되며 Web Audio 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 속성)를 사용하여 특정 시점에 콜백할 수 있습니다. 자세한 내용은 이 기능 요청을 참고하세요.

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

Q: Web Audio API를 사용하여 소리의 피치를 변경하려면 어떻게 해야 하나요?

A: 소스 노드에서 playbackRate를 변경합니다.

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

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

  • 시간 영역 알고리즘: 반복된 세그먼트 에코 아티팩트를 유발합니다.
  • 잔향이 있는 음향 아티팩트를 유발하는 주파수 영역 기법

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

Q: 원하는 샘플링 비율로 AudioContext를 만들려면 어떻게 해야 하나요?

A: 현재는 지원되지 않지만 YouTube에서 살펴보고 있습니다. 이 기능 요청을 참고하세요.

추가 질문이 있는 경우 언제든지 StackOverflow에서 web-audio 태그를 사용하여 문의해 주세요.