TECH 으로 돌아가기
TECH HACKER NEWS 오늘 8분 읽기 27 READS

키보드로 기타를 친다고? 'Guitoro'로 알아보는 웹 오디오 악기 만드는 법

키보드가 기타 줄이 되는 웹앱

Guitoro는 브라우저에서 돌아가는 가상 기타예요. 이름 그대로 컴퓨터 키보드를 눌러서 기타를 스트럼하듯 연주할 수 있게 만든 게 특징이에요. 스트럼(strum)이 뭐냐면, 기타 줄 여러 개를 피크로 위에서 아래로(또는 아래에서 위로) 쓸어내리듯 한 번에 치는 주법이에요. 통기타 반주 하면 떠오르는 '징~ 징징' 하는 그 소리요.

그냥 장난감처럼 보일 수도 있어요. 그런데 이런 웹 악기는 브라우저가 실시간 오디오를 얼마나 잘 다룰 수 있는지 보여주는 좋은 사례예요. 설치 없이 링크 하나로 악기를 연주한다는 건 10년 전만 해도 쉽지 않았거든요. 사이드 프로젝트 아이디어를 찾고 있다면 '나라면 이걸 어떻게 만들까?' 하는 관점으로 보면 배울 게 꽤 많아요.

웹에서 기타 소리를 만드는 두 가지 방법

Guitoro가 내부적으로 정확히 어떤 방식을 쓰는지는 공개된 정보만으로 단정하기 어려워요. 다만 이런 앱을 만드는 길은 보통 두 가지예요.

첫째는 샘플 방식이에요. 실제 기타 줄을 녹음한 오디오 파일을 음 높이별로 준비해두고, 키를 누르면 해당 파일을 재생하는 거죠. 소리는 가장 사실적이지만 파일 용량이 커지고, 모든 음과 주법을 녹음하려면 손이 많이 가요.

둘째는 물리 모델링 합성이에요. 대표적인 게 1983년에 발표된 Karplus-Strong 알고리즘인데, 원리가 놀랄 만큼 단순해요. 짧은 잡음(랜덤한 소리)을 일정 길이의 버퍼에 넣고, 이걸 계속 되풀이하면서 이웃한 값들의 평균을 내요. 평균을 낼수록 날카로운 고음 성분이 깎여 나가면서 소리가 점점 부드럽게 사그라드는데, 이게 실제로 줄을 튕긴 뒤 소리가 잦아드는 모습과 꽤 비슷하거든요. 그리고 버퍼 길이가 음 높이를 정해요.

function pluck(ctx, freq, when) {
const sr = ctx.sampleRate;
const N = Math.round(sr / freq); // 버퍼 길이 = 음 높이
const buf = ctx.createBuffer(1, sr * 2, sr);
const out = buf.getChannelData(0);
for (let i = 0; i < N; i++) out[i] = Math.random() * 2 - 1; // 잡음으로 시작
for (let i = N; i < out.length; i++) {
out[i] = 0.996 0.5 (out[i - N] + out[i - N + 1]); // 평균 + 감쇠
}
const src = ctx.createBufferSource();
src.buffer = buf;
src.connect(ctx.destination);
src.start(when);
}

const STRINGS = [82.41, 110.0, 146.83, 196.0, 246.94, 329.63]; // 표준 튜닝 E A D G B E
function strum(ctx, down = true) {
const order = down ? STRINGS : [...STRINGS].reverse();
const t0 = ctx.currentTime;
order.forEach((f, i) => pluck(ctx, f, t0 + i * 0.015)); // 줄마다 15ms씩 어긋나게
}

스트럼의 비밀은 마지막 줄에 있어요. 여섯 줄을 완전히 동시에 울리면 오히려 전자음처럼 딱딱하게 들려요. 줄마다 10~20ms 정도 시간차를 줘야 진짜 쓸어내리는 느낌이 나요. 코드(chord)를 잡을 때는 각 줄 주파수에 2^(프렛/12)를 곱하면 되고요. 그리고 setTimeout 대신 ctx.currentTime 기준으로 재생을 예약하는 게 중요해요. 자바스크립트 타이머는 메인 스레드 상황에 따라 밀릴 수 있지만, 오디오 클럭은 정확하거든요.

키보드 악기가 부딪히는 현실적인 벽

이런 앱에는 생각보다 까다로운 문제들이 있어요. 먼저 지연 시간(latency)이에요. 키를 누르고 소리가 나기까지 수십 ms만 늦어져도 연주하는 사람은 굼뜨다고 느껴요. 둘째는 키보드 고스팅이에요. 저렴한 멤브레인 키보드는 여러 키를 동시에 누르면 일부 입력을 놓치기도 해서, 코드를 누른 채 스트럼하는 키 조합을 잘 설계해야 해요. 셋째, 브라우저는 사용자 동작 없이 소리를 내지 못하게 막아두기 때문에 첫 클릭이나 키 입력 때 AudioContext를 resume() 해줘야 해요.

한국 개발자를 위한 팁

한국 개발자가 특히 조심할 함정이 하나 있어요. 한글 입력 상태에서는 event.key에 기대한 값이 안 들어올 수 있다는 거예요. IME(한글 입력기)가 글자를 조합하는 중이면 브라우저에 따라 'Process' 같은 값이 넘어오거든요. 이럴 땐 자판 배열과 상관없이 물리적인 키 위치를 알려주는 event.code('KeyA', 'KeyS' 등)를 쓰면 한/영 상태와 관계없이 안정적으로 동작해요. 게임, 단축키, 악기 앱 어디에나 통하는 팁이에요.

Web Audio API는 음악 앱 말고도 알림음, 음성 시각화, 간단한 게임 효과음처럼 쓸 데가 많아요. 주말 프로젝트로 나만의 악기를 만들어보면 브라우저 이벤트, 타이밍, 신호 처리를 한 번에 연습할 수 있어요.

마무리

한줄 정리: 잡음 한 줌과 평균 계산만으로 기타 소리가 나요. 웹 오디오는 생각보다 훨씬 강력해요.

키보드로 연주하는 웹 악기를 만든다면 어떤 악기를 고르시겠어요? 키 배치는 어떻게 설계하실 건가요?


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://guitoro.com/
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기 →
처리 중...