Trawling

JavaScript로 재현한 A-ha의 〈Take On Me〉

Shadertoy 사운드 셰이더를 Dittytoy용 JavaScript 코드로 옮겨 A-ha의 〈Take On Me〉를 재현합니다. 압축된 악보 데이터와 직접 구현한 신스·보컬 처리 코드로 여러 악기 트랙을 재생합니다.

Tonny Espeset이 Shadertoy에 올린 사운드 셰이더를 Dittytoy 포맷으로 옮겼습니다. 곡을 60 BPM으로 설정하고, 악기별 루프를 229초 단위로 재생합니다. 코드에는 압축 악보를 풀어 트랙별 음표를 재생하는 로직과 악기·보컬 사운드를 합성하는 DSP가 들어 있습니다.

악보 데이터와 재생

악보는 트랙별 열 데이터를 LZ 방식으로 압축한 뒤 문자열에 저장합니다. bytes가 문자열에서 13비트 단위 데이터를 복원하고 unlz가 반복 구간을 풀어 악보 배열을 만듭니다. 음표 타이밍은 24틱을 1박으로 계산해 초 단위로 바꾸며, 재생이 끝난 음표 주변의 공백도 다시 구성해 원래 셰이더의 음표 스캔 동작을 재현합니다.

악기 합성과 믹싱

킥, 백비트, 톰, 브러시를 각각 별도 트랙으로 구성하고, 드럼 소리는 모드 공명과 대역 제한 노이즈를 합성해 만듭니다. DX7 베이스는 6개 오퍼레이터의 엔벌로프와 주파수 변조를 구현합니다. 벨, Juno 계열 신스, 패드, FM 건반, 브리지 스트링과 플럭도 각각 다른 합성 경로를 사용합니다. 트랙마다 믹스 레벨을 지정하고, 마스터 게인과 곡 끝부분의 페이드도 적용합니다.

보컬 재현

리드 보컬은 압축된 음색·피치·게인 데이터를 읽어 합성합니다. 음색 데이터는 최대 72개 고조파와 12개 노이즈 대역의 레벨로 풀어내며, 피치와 음량은 5밀리초 단위 기록 사이를 보간합니다. 백킹 보컬과 코러스는 별도 음성 데이터와 트랙으로 처리합니다.

코드 상단에서는 악기와 곡을 재사용할 때 제작자 표기와 원문 링크를 남겨 달라고 요청합니다. 작품 페이지의 라이선스 표시는 CC BY-NC-SA 4.0입니다. 이 라이선스는 출처 표시와 비상업적 이용을 조건으로 하며, 수정한 작품을 공유할 때에는 같은 라이선스를 적용해야 합니다.

Reddit 반응

  • @u/Elkemper — 이게 대체 어떻게 된 건가요… 0_∆. 코드가 있는 건 봤지만 그래도요…
    • @u/eindbaas — 뒤쪽에 효율적으로 인코딩한 데이터가 많이 들어 있습니다.
  • @u/okcookie7 — 각 트랙을 오디오 필터로 하나씩 만들었나요?

원문: Dittytoy / 번역·요약: Trawling

참고 자료

오류 제보