소개
HTML과 자바스크립트를 이용해 아래와 같이 숫자(Transpose
)를 조절하면 서버 상에 있는 오디오 음원의 음정(pitch, 음높이)이 높아지거나 낮아지게 할 수 있습니다.
웹 페이지에서 다른 음높이의 오디오 음원을 재생하고 싶을 때 사용합니다.
장점
- 외부 라이브러리를 사용하지 않습니다.
단점
- 음정을 높이면 속도도 같이 조절됩니다. (음정과 속도가 연동됩니다.)
playbackRate
를 조절하여 속도를 낮춰보려 했으나 속도를 낮추면 음정도 같이 낮아집니다.
코드
<button id="play1">예제 1 플레이</button> Transpose: <input id="stepper1" type="number" value="0">
var context = new AudioContext(); var source = context.createBufferSource(); var buffer1 = null; var isPlaying1 = false; // mp3 파일 받아오기 var request = new XMLHttpRequest(); request.open( 'GET', 'http://somewhere.con/musicsource.mp3', true ); request.responseType = 'arraybuffer'; request.onload = function() { context.decodeAudioData(request.response, function(buffer) { console.log(buffer); buffer1 = buffer; }, function(err) { console.log(err); }); } request.send(); // 이벤트 지정 document.querySelector("#stepper1").addEventListener("change", function() { if(isPlaying1) { source.stop(); start1(); } }); document.querySelector("#play1").addEventListener("click", function() { if(isPlaying1) { source.stop(); } else { start1(); } isPlaying1 = !isPlaying1 }); // source를 리셋하고, 파일을 재생 function start1() { source = context.createBufferSource(); source.buffer = buffer1; source.connect(context.destination); var transpose = parseInt(document.querySelector("#stepper1").value); source.detune.value = transpose.value * 100; if(transpose !== 0) { console.log(source.playbackRate, Math.pow(2, transpose / 12)) } source.start(0); }
오디오, 음정 오디오 음정 음원 음높이 피치 센트 세미톤 반음 자바스크립트 자스 mp3 오디오오디오를 외동 오디오를 오디오해서 오디오 컨텍스트 키워트 최적화 오디오 거기가 오디오 자바스크립트 오디오 컨텍스트
설명
해당 소스 코드는 구형 자바스크립트(ES5 이하)로 작성되어 있으므로, 만약 최신 환경에 대한 대응이 필요하다면 인터넷 검색 등으로 ES6 이상에 대응하도록 고쳐야 합니다.
Step 1: 오디오 컨텍스트, 버퍼 소스 생성
var context = new AudioContext(); var source = context.createBufferSource();
- 버퍼 소스(
source
)를 통해 오디오 음정을 조절할 수 있습니다.
Step 2: 버퍼 저장 변수 및 재생 상태 저장 변수 추가
var buffer1 = null; var isPlaying1 = false;
- 버퍼: 서버로부터 비동기로 받아온 음원의
ArrayBuffer
를 재사용하기 위해 저장하는 곳입니다. isPlaying1
: 버퍼 소스를 한번 시작하면 재사용이 불가능하기 때문에 재사용을 위해 상태를 현재 재생 상태를 저장합니다.
Step 3: 서버로부터 mp3 파일 가져오기, 버퍼 데이터 생성
var request = new XMLHttpRequest(); request.open( 'GET', 'https://음원주소.con/source.mp3', true); request.responseType = 'arraybuffer'; request.onload = function() { context.decodeAudioData(request.response, function(buffer) { console.log(buffer); buffer1 = buffer; }, function(err) { console.log(err); }); } request.send();
- 서버의 음원 주소로 요청(request)를 보내
arraybuffer
타입으로 응답(response)을 가져온 뒤, 해당 응답을buffer1
변수에 저장합니다.
Step 4: 음정에 맞춰 transpose한 뒤 음원을 재생하는 함수 만들기
function start1() { source = context.createBufferSource(); source.buffer = buffer1; source.connect(context.destination); var transpose = parseInt(document.querySelector("#stepper1").value); source.detune.value = transpose.value * 100; source.start(0); }
BufferSource
는 재활용이 불가능하므로 재생 버튼을 누를 때마다 새로 생성해야 합니다.- BufferSource의
buffer
로 서버에서 가져온buffer1
을 사용합니다. - 소스를 오디오 컨텍스트의 도착점(
context.destination
)과 연결(connect)합니다.- 소스와 컨텍스트를 연결해야 스피커에서 소리가 나옵니다.
transpose
: HTML 코드에 있던 #stepper1 필드로부터 값을 가져옵니다.source.detune.value
: 센트(cent)단위로 튜닝을 변경합니다.- 1 반음(semitone)은 100센트입니다. transpose의 값에 100을 곱해 반음 단위로 변경합니다.
source.start(0)
: 처음 위치(0)부터 재생을 시작합니다.
센트, 반음 단위와 관련된 글은 음악 이론과 관련되어 있어 이 포스트에서 설명을 생략합니다. 아래 포스트에서 일부 내용이 설명되어 있습니다.
Step 5: HTML 요소에 이벤트 부여
document.querySelector("#stepper1").addEventListener("change", function() { if(isPlaying1) { source.stop(); start1(); } }); document.querySelector("#play1").addEventListener("click", function() { if(isPlaying1) { source.stop(); } else { start1(); } isPlaying1 = !isPlaying1 });
- 위의 이벤트 리스너는 Transpose의 필드 값(
#stepper1
)이 변경되었을 때 음원을 멈춘 다음 변경된 음정으로 다시 재생합니다. - 아래의 이벤트 리스너는 재생 버튼(
#play1
)에 할당된 이벤트로 버튼을 누르면 음원을 재생하고, 재생중인 경우 음원을 멈춥니다.
출처
- https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/detune
- https://developer.mozilla.org/ko/docs/Web/API/Web_Audio_API/Using_Web_Audio_API
- https://stackoverflow.com/questions/32172466/loading-mp3-as-arraybuffer-using-local-file-for-web-audio
- https://stackoverflow.com/questions/14908838/loading-an-audio-buffer-and-play-it-using-the-audio-tag
- https://stackoverflow.com/questions/57302931/make-audiobuffersourcenode-the-audio-source-of-an-audio-tag
- https://stackoverflow.com/questions/37206304/changing-the-pitch-of-an-audio-element-without-external-libraries
0개의 댓글