그렇다면 컴퓨터는 어떻게 소리를 들을까??
0과 1밖에 모르는 컴퓨터는 연속성을 가진 아날로그
신호를 이해할수 없기 때문에 디지털
로 바꿔줘야 한다.
그리고 이를 변경하기 위해서는 몇 가지 순서를 거쳐야 한다. 이 순서에서 어떤 값을 사용하느냐에 따라 소리의 해상도, 즉 음질이 결정된다.
샘플링
은 아날로그 신호를 디지털 신호로 바꾸는 첫번째 단계이다. 예를들면, 마이크를 사용하여 소리를 녹음할 때, 이 아날로그 신호가 결국 전기 신호로 변환되어 컴퓨터에게 주어진다. 이러한 연속적인 전기 신호를 컴퓨터는 특정 타이밍을 정해서 그 값을 저장한다.
이때, 이 신호를 측정하는 간격을 샘플 레이트(Sample Rate)
라고 하고, 이 샘플 레이트가 높을수록 소리의 해상도가 좋아진다.(음질 up👍)
위의 그림에서 신호 내부의 사각형이 컴퓨터가 이해한 신호의 모양이다.
조금 더 샘플레이트에 대해 궁금하다면 다음 사이트를 참조하면 된다.
웹에서 구현하고자 하는 오디오 기능이 재생, 일시정지 등과 같은 단순한 기능이라면 <audio>
태그를 이용하면 된다. 하지만 웹에서 좀 더 복잡하고 고차원적인 음원 처리를 필요로 한다면 Web Audio API를 사용하면 된다.
AudioContext
객체를 생성하면서 시작된다.Inputs
에서 이 객체 내부에 오디오 소스를 생성한다.Effects
내부에 여러 개의 AudioNode(각각 하나의 역할을 수행하는 모듈들)를 가질 수 있다. AudioContext
객체 안에 있는 노드들은 서로 연결되어 하나의 연결된 그래프(Audio routing graph)를 형성하게 된다.methods: {
async getAudio() {
// AudioContext 객체인데 음원과 관련된 모든 처리가 일어난다.
const audioContext = await new (window.AudioContext || window.webkitAudioContext)();
console.log('audioContext', audioContext);
const res = await fetch('http://localhost:8080/1to20.wav');
// arrayBuffer()를 이용해 오디오 파일 데이터를 고정 길이의 원시 이진 데이터 버퍼 객체로 나타낸다.
const bufferData = await res.arrayBuffer();
// 버퍼 객체를 비동기적으로 디코딩한다(raw한 오디오 데이터일뿐 아직 하나의 노드가 아니여서 사용할 수 없는 상태이다)
const audioBuffer = await audioContext.decodeAudioData(bufferData);
// sound source 생성
const source = audioContext.createBufferSource(); // 생성했던 데이터는 한번 재생이 끝나고 재접근 불가
// 생성된 source에 어떤 사운드(audioBuffer)를 플레이할지 알려준다.
source.buffer = audioBuffer;
// 스피커에 source를 연결한다...!
source.connect(audioContext.destination);
source.start();
},
},
AudioBuffer는 이진법으로 이루어진 오디오 파일을 AudioContext.decodeAudioData()
나 AudioContext.createBuffer()
를 사용해 생성된 가장 기본적인 오디오 데이터이다. 주로 short-to medium-length 사운드를 위해 사용한다.
Props
- sampleRate: 위에서 설명한 샘플 레이트를 의미
- numberOfChannels: 이 오디오가 몇 개의 채널을 가지고 있는지 나타낸다.
- length: 피크(Peak: 컴퓨터가 샘플링할 때 전압을 측정한 값을 의미)들의 개수를 의미한다.
- duration: 오디오 파일의 재생 길이를 초 단위로 표시한다.
여기서 하다보면 궁금한게 생기는데 buffer란 무엇일까??
Buffer: 데이터를 한 곳에서 다른 한 곳으로 전송하는 동안 속도차이를 극복하기 위해 사용하는 Queue 형태(FIFO)의 임시 저장 공간(메모리 영역)이다. 아래 그림에서 회색 부분이 버퍼이다..!!
맞아서 아파요?