Reddit

A-ha, Take On Me - recreated in javascript

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

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

AI 요약

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

악보 데이터와 재생

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

악기 합성과 믹싱

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

보컬 재현

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

코드 상단은 악기와 곡 데이터를 자유롭게 사용할 수 있지만 제작자 표기와 링크를 남겨 달라고 요청합니다.

Reddit 반응

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

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