본문 바로가기
웹 오디오 프로그래밍

[Web Audio API #2] 오디오 재생

by 영바이트 2021. 6. 18.

 

서버에 보관되어 있는 음원 파일을 재생하는 간단한 예제를 일단 만들어보자. 웹 오디오 API와 관련된 내용은 이 예제 내용을 통해 살펴보는게 이야기를 풀어가기 수월할 것 같다.

 

웹 오디오 API는 어디까지나 '웹web' 환경을 전제로 한 것이기 때문에 기본적으로 웹 프로그래밍, 즉 서버와 클라이언트가 요청과 응답을 주고 받는 방식으로 프로그래밍해야한다. 웹 오디오 API의 내부는 C언어로 구현되어 있지만 API는 JavaScript로 되어있다.

 

서버로부터 음원 데이터를 받으면 가장 먼저 이를 해석(decoding)해야 한다. 해석된 오디오 데이터는 오디오 버퍼 소스(bufferSource) 객체에 전달된다.

const audioContext = new(window.AudioContext || window.webkitAudioContext)();

var source = audioContext.createBufferSource();

audioContext.decodeAudioData(buffer, (buffer) => {
	source.buffer = buffer;
	source.connect(audioContext.destination);
});

 

오디오 버퍼 소스 객체의 buffer 속성으로 넘겨받은 음원 데이터를 아래와 같이 오디오 버퍼 소스 객체의 start, stop 메서드를 호출하여 재생하고 멈출 수 있다.

// 재생
source.start(0);

// 멈춤
source.stop(0);

 

음원은 아래와 같은 흐름으로 재생되어 스피커나 헤드폰을 통해 들리게된다. 여기서 destination은 오디오 데이터를 물리적인 파형으로 바꿀 수 있는 스피커와 헤드폰 등의 장치가 자동으로 설정된다.

 

buffer → decoding → bufferSource → audioContext.destination

 

위와 같은 데이터 처리를 위한 구조를 오디오 그래프audio graph라고 한다. 이 오디오 그래프를 그림으로 나타내면 아래와 같다.

 

 

오디오는 이 오디오 그래프의 각 노드node들을 거쳐가며 최종적으로 스피커나 헤드폰에 도착한다. 위 오디오 그래프의 예에서 보면 AudioDestinationNode가 스피커나 헤드폰과 같은 재생 장치에 해당한다. 소스 코드에서 오디오 그래프를 어떻게 생성했는지 살펴보자.

const audioContext = new(window.AudioContext || window.webkitAudioContext)();

//	AudioBufferSourceNode 생성
var source = audioContext.createBufferSource();

audioContext.decodeAudioData(buffer, (buffer) => {
	//	buffer → AudioBufferSourceNode.buffer
	source.buffer = buffer;
    
    //	AudioBufferSourceNode - AudioDestinationNode 연결
	source.connect(audioContext.destination);
});

 

가장 먼저 오디오를 다루기 위한 최상위 객체인 Audio Context를 생성하고,

const audioContext = new(window.AudioContext || window.webkitAudioContext)();

 

이 Audio Context 객체의 create 메서드를 이용해서 필요한 오디오 노드들을 생성한다.

var source = audioContext.createBufferSource();

 

생성한 오디오 노드들은 각 노드 객체의 connect 메서드를 호출해서 다음에 연결될 오디오 노드와 연결해줄 수 있다.

source.connect(audioContext.destination);

 

 

오디오 그래프가 완성되면 오디오 버퍼 소스 노드의 start, stop 메서드를 호출해서 buffer에 들어있는 데이터를 재생하고 멈출 수 있다.

// 재생
source.start(0);

// 멈춤
source.stop(0);

 

댓글