TF 팀 프로젝트로 “작곡” 도메인의 클라이언트를 대상으로 하는 플랫폼을 만들어야 할 일이 생겼다. 필요한 요구사항 중 필수적인 Music Player, Midi Player (.mp3, .midi multi-format) 기능을 만들었던 기록이다.
제작하는 기능의 모든 라이브러리는 Tone.js 를 의존하고 있다. 구현에 필요한 기능을 가장 많이 갖추고 있으면서 테스트 코드가 작성되어 있고 자주 유지보수 되고 있는 점을 고려했을 때 프로덕션 환경에서 가장 적합한 라이브러리라고 생각되었다.
midi 관련 기능 요구사항 때문에 선택에 있어 까다로웠는데, midi 파일을 간편하게 연주해주는 기능이 추상화 되어있는 라이브러리가 거의 없었고, 또한 Midi 의 Volume 조절 기능을 지원하는 라이브러리가 거의 존재하지 않았기에, 직접 구현하기에 가장 세부적인 지원 기능의 폭이 넓은 Tone.js 를 의존성으로 가지면서 midi 파일을 기반으로 mp3 파일로 변환해주는 @magenta/music 라이브러리를 선택했다.
Player - [email protected]
Midi Loader - @tonejs/[email protected] (midi-file 라이브러리의 wrapper)
Midi Player - @magenta/[email protected]
.mp3 형식과 .mid, .midi 파일 포맷 형식을 모두 지원하는 플레이어를 개발해야 하고, 동일한 동작이 구현되어야 한다.
Tone.js 의 Player Class 의 내부 동작을 설계한 클래스의 인터페이스로 필요한 추가 기능을 붙여서 패키징하였다. 볼륨 조절, 뮤트, 재생/일시중지 등 웬만한 플레이어의 일반적인 기능을 제공해 주기 때문에 구현에 큰 어려움은 없었다.
@magenta/music 라이브러리의 SoundFontPlayer Class 를 사용해서 플레이어를 구현했다.
Midi 는 기본적으로 개별 노트를 실제 건반 두들기듯이 직접 하나하나 출력시키는 방식이다. 따라서 mp3 같은 source 를 틀기만 하는 방식과 완전히 달라서 자연스러운 연주의 구현 복잡도가 높은데, @magenta/music 라이브러리는 자동적으로 플레이가 가능하게 변환시켜준다. (내부적으로 tensorflow 를 사용함. 학습된 model 을 사용하는 듯) 그리고 별도 지정이 없으면 Master Destination(output) 을 사용하는데, 여기에 플레이어 별로 output 을 따로 출력 채널로 관리해야 볼륨의 조절값을 격리해서 관리할 수 있다.
그럼에도, Music Player 와 인터페이스가 모두 동일해야 사용에 지장이 없었다.