웹 환경에서 음악적 요소를 구현하려는 개발자들에게 MIDI 데이터의 처리와 재생은 매우 중요한 과제입니다. MIDI.js는 브라우저상에서 별도의 플러그인 없이 MIDI 데이터를 파싱하고 사운드폰트를 활용해 고품질의 소리를 출력할 수 있도록 돕는 오픈소스 자바스크립트 라이브러리입니다.
MIDI 기술의 이해
MIDI(Musical Instrument Digital Interface)는 디지털 악기 간의 통신을 위한 표준 프로토콜입니다. 실제 오디오 파형을 저장하는 대신 음의 높낮이, 길이, 강도(Velocity), 악기 정보 등의 수치 데이터를 전달하므로 파일 크기가 매우 작고 유연한 편집이 가능하다는 장점이 있습니다.
MIDI.js의 핵심 기능
- MIDI 파일 렌더링: 표준 MIDI 파일을 로드하여 브라우저에서 직접 재생할 수 있습니다.
- 가상 악기 제어: 사운드폰트(Soundfont)를 활용하여 피아노, 기타, 드럼 등 다양한 악기 소리를 코드로 생성합니다.
- 실시간 이벤트 처리: 사용자의 키보드 입력이나 마우스 클릭에 반응하여 실시간으로 음표를 연주하는 인터랙티브 앱 제작이 가능합니다.
- 정밀한 타이밍 제어: 여러 악기를 동시에 연주할 때 발생하는 레이턴시를 최소화하여 정확한 박자를 유지합니다.
라이브러리 주요 특징
MIDI.js는 가볍고 효율적인 구조로 설계되어 모바일과 데스크톱 환경을 모두 지원합니다. 복잡한 합성 엔진을 직접 구축할 필요 없이 추상화된 API를 통해 사운드폰트를 로드하고 바로 연주를 시작할 수 있습니다. 또한 플러그인 시스템을 통해 기능을 확장하거나 특정 환경에 최적화된 설정을 적용하기 용이합니다.
MIDI.js 시작하기
먼저 라이브러리를 프로젝트에 포함해야 합니다. CDN을 통해 최신 버전을 불러올 수 있습니다.
<script src="https://cdn.jsdelivr.net/npm/@mudcube/midijs@latest/dist/midi.min.js"></script>
초기화 및 사운드폰트 로드
라이브러리를 사용하기 전, 출력하려는 악기의 사운드폰트 리소스를 먼저 로드해야 합니다. 다음은 피아노 악기를 설정하는 기본적인 초기화 코드입니다.
const midiConfig = {
soundfontUrl: "./sounds/font/",
instrument: "acoustic_grand_piano",
onReady: function() {
console.log("MIDI 시스템 준비 완료");
// 이후 연주 로직 실행
}
};
MIDI.loadPlugin({
soundfontUrl: midiConfig.soundfontUrl,
targetFormat: "mp3",
instrument: midiConfig.instrument,
onprogress: (state, progress) => {
console.log(`로딩 상태: ${state}, 진행률: ${progress}`);
},
callback: midiConfig.onReady
});
음표 연주 및 파일 재생
초기화가 완료되면 특정 음표를 연주하거나 준비된 MIDI 파일을 재생할 수 있습니다. noteOn 함수는 음을 발생시키고, noteOff 함수는 음을 중지시킵니다.
// 특정 음표 연주 (채널, 노트번호, 벨로시티, 지연시간)
function playSingleNote(noteNumber) {
const channel = 0;
const velocity = 127; // 최대 강도
const delay = 0;
MIDI.setVolume(channel, 127);
MIDI.noteOn(channel, noteNumber, velocity, delay);
MIDI.noteOff(channel, noteNumber, delay + 0.8);
}
// MIDI 파일 전체 재생
function startMidiPlayback(fileUrl) {
MIDI.Player.loadFile(fileUrl, function() {
MIDI.Player.start();
});
}
위 예시에서 노트 번호 60은 가온 도(C4)에 해당합니다. MIDI.Player 객체를 사용하면 파일 단위의 제어가 가능하며, MIDI.noteOn과 같은 로우 레벨 API를 사용하면 시퀀서나 가상 키보드와 같은 정밀한 음악 도구를 개발할 수 있습니다.