Web Audio API 알아보기

HBBB·2025년 4월 19일

Speechfy

목록 보기
1/2

Speechfy를 만들면서

이번에 프로젝트를 진행하면서 Web Audio API를 활용할 일이 생겼습니다.

진행했던 프로젝트는 음성을 기반으로 음악을 만들 수 있는 프로젝트 "Speechfy"입니다.

해당 서비스는 사용자의 음성을 입력받아서, 목소리를 악기소리로 변환해주고, 이를 병합해서 MusicGen 모델을 활용해서 완성된 곡으로 만들어주는 기능을 가졌습니다.

제가 구현해야 했던 기능은
1. 사용자 목소리 녹음
2. 사용자 목소리 변환
3. 음원 병합 처리

입니다.

이 과정에서 단순히 audio태그만으로는 해결 할 수 없는 기능들이 많아서 추가적으로 Web Audio API를 활용하기로 했습니다.

여담으로 프로젝트를 진행하는 도중에 gpt 4o의 그림 생성 서비스를 활용해보았는데, 상당히 잘 만들어 줘서 만족스럽게 사용했습니다.

Web Audio API란?

단순히 음원을 재생하는 것만이라면 audio태그를 사용하면 되지만, 음원 데이터를 활용해야 한다면 WebAudio API를 사용해야 합니다.

개념과 사용법

Web Audio API는 웹에서 오디오를 제어하기 위한 강력하고 다양한 기능을 제공합니다. Web Audio API를 이용하면 오디오 소스를 선택할 수 있도록 하거나, 오디오에 이펙트를 추가하거나, 오디오를 시각화하거나, 패닝과 같은 공간 이펙트를 적용시키는 등의 작업이 가능합니다.
출처: https://developer.mozilla.org/ko/docs/Web/API/Web_Audio_API

위에서 읽었듯이 Web Audio API는 웹에서 오디어의 이펙트 추가, 시각화 등 데이터를 활용해야 할 때 사용합니다.

흐름은 다음과 같습니다.
1. AudioContext 생성
2. Context내에 소스를 생성
3. 이펙트 노드를 생성
4. 최종 목적지 선택
5. 사운드를 이펙트에 연결하고, 이펙트를 목적지에 연결

그럼 이제 이 흐름을 따라가면서 더 자세히 알아보겠습니다.

1. AudioContext 생성

Web Audio API의 작업은 AudioContext 내에서 처리하는데, AudioContext란 Web Audio API에서 오디오 처리를 관리하는 최상위 객체입니다. AudioContext는 모든 오디오 노드를 관리하며 오디오 작업의 시작점이라고 볼 수 있습니다.

// AudioContext 생성하기
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();

이렇게 생성된 AudioContext는 사운드의 시간 관리와 샘플레이트를 처리하며, 브라우저에서 지원하는 오디오 출력을 위해 반드시 생성되어야 합니다.

2. 소스 노드(SourceNode) 생성

소스 노드는 음원의 원본을 의미하며, 여러 가지 형태가 있습니다. 제 프로젝트에서는 사용자의 목소리를 녹음해야 했기 때문에 MediaStreamAudioSourceNode를 사용하여 마이크 입력을 받아들였습니다.

// 사용자 마이크 입력을 소스로 설정하기
navigator.mediaDevices.getUserMedia({ audio: true })
  .then(stream => {
    const micSource = audioCtx.createMediaStreamSource(stream);
  });

이 외에도 다양한 소스 노드가 있는데, 예를 들어 미리 녹음된 파일을 재생하려면 AudioBufferSourceNode를 사용할 수 있습니다.

3. 이펙트 노드(EffectNode) 생성

음성을 악기 소리로 변환하거나 음원의 볼륨을 조절하는 등 다양한 효과를 위해 이펙트 노드를 생성할 수 있습니다. 예를 들어, 볼륨 조절을 위해서는 GainNode를 활용할 수 있습니다.

// 볼륨 조절을 위한 GainNode 생성
const gainNode = audioCtx.createGain();
gainNode.gain.value = 0.5; // 볼륨 50% 설정

다양한 주파수 필터를 적용하고 싶다면 BiquadFilterNode를 활용합니다.

// 저역 필터 적용 예시
const filterNode = audioCtx.createBiquadFilter();
filterNode.type = 'lowpass';
filterNode.frequency.value = 1000; // 1000Hz 이하 주파수만 통과

4. 최종 목적지(DestinationNode) 선택

최종 목적지는 처리된 오디오 신호가 출력되는 곳입니다. 대부분은 사용자의 스피커를 목적지로 설정합니다.

// 스피커를 최종 목적지로 설정
const destination = audioCtx.destination;

만약 오디오 데이터를 스트림 형태로 다시 사용하거나 녹음하는 용도로 활용하고 싶다면 MediaStreamDestinationNode를 사용합니다.

// 스트림 목적지 설정
const mediaDest = audioCtx.createMediaStreamDestination();

5. 오디오 노드 연결 및 재생

마지막으로 소스 노드와 이펙트 노드, 그리고 목적지 노드를 서로 연결하여 오디오 데이터를 출력합니다.

// 소스 → 이펙트 → 목적지 연결
micSource.connect(gainNode).connect(filterNode).connect(audioCtx.destination);

이렇게 구성하면 마이크 입력이 GainNode를 통해 볼륨이 조정되고, 필터링을 거쳐 사용자의 스피커로 출력됩니다.


이렇게 Web Audio API의 간단한 사용법을 알아보았습니다. 다음 글에서는 이를 구체적으로 어떻게 활용했는지 다루어 보겠습니다.

profile
안녕하세요. 음악을 좋아하는 프론트엔드 개발자입니다

0개의 댓글