
캐릭터에 맞춰 효과음을 양산하기 - 음성 파일 생성은 필요 없었다
요약
Tone.js를 활용하여 코드로 효과음을 설계하고 양산하는 방법을 소개합니다. 파형 선택, 음정의 높낮이, 엔벨로프(Envelope) 설정을 통해 캐릭터의 성격과 UI의 피드백을 효과적으로 구현하는 원칙을 다룹니다.
핵심 포인트
- 신시사이저 파형(Waveform) 선택이 음색의 핵심
- 캐릭터 크기에 비례하여 음정을 낮게 설정
- 상승/장조는 보상, 하강/단조는 실패의 문법 활용
- UI 효과음은 sustain을 0으로 설정하는 것이 효율적
- 지연 초기화(Lazy Initialization) 패턴으로 오디오 재생 제한 대응
효과음을 「찾기·사기·내보내기」 하는 것이 아니라 코드로 설계하면, 음정(Pitch)도 길이도 한 줄로 조정할 수 있으며 다양한 효과음을 양산할 수 있습니다.
await Tone.start(); // ← 반드시 사용자 조작 내에서 (브라우저의 자동 재생 제한)
const vol = new Tone.Volume(-14).toDestination(); // 마스터는 절제되게
const blip = new Tone.Synth({
...
신시사이저(Synth)는 클릭할 때마다 new 하지 않고, 초기화 시에 한 세트를 만들어 재사용합니다. Tone.start()를 첫 사용자 조작 내에서 호출하는 「지연 초기화 (Lazy Initialization)」 패턴으로 설정해 두면 안전합니다.
let audioReady = false;
async function ensureAudio() {
if (audioReady) return true;
...
준비가 되었다면 아래의 4원칙을 규칙으로 삼으면 캐릭터에 따라 효과음을 양산하는 것이 가능합니다.
신시사이저의 음색은 oscillator의 파형(Waveform)에 의해 거의 결정됩니다.
| 파형 | 성격 | 데모에서의 용도 |
|---|---|---|
sine (정현파) | 둥글고·부드러움 | 작은 캐릭터의 「피요(ピヨッ)」 |
triangle (삼각파) | 가볍고·팝(Pop)함 | 호버(Hover) 시의 blip |
square (사각파) | 8bit 게임·활기참 | 카트 추가 징글(Jingle) |
sawtooth (톱니파) | 거칠고 존재감 있음 | 납작한 캐릭터의 「페앗(ぺあっ)」 |
MembraneSynth (막) | 드럼·통통 튐 | 큰 캐릭터의 「보무...(ボム…)」 |
캐릭터나 조작의 성격을 정했다면, 그에 맞는 파형을 선택합니다. 이것만으로 음색의 8할이 결정됩니다.
// 큰 캐릭터: 낮은 막 소리 한 번
new Tone.MembraneSynth({ octaves: 4, pitchDecay: 0.12 })
.triggerAttackRelease('C2', 0.4);
...
몸집에 비례하여 음을 낮게 만듭니다. 현실의 동물과 같은 법칙이므로, 듣는 순간 「저 큰 녀석이 울었다」라고 전달됩니다. 캐릭터는 외형보다 소리로 성격이 부여된다는 것이 만들어보며 얻은 발견이었습니다.
참고로 MembraneSynth의 pitchDecay는 음정의 급강하량 = 「통통(ボヨン)」 하는 느낌의 정체입니다.
// 카트 추가: C-E-G-C 상승 메이저 아르페지오
const n = Tone.now();
['C5','E5','G5','C6'].forEach((p, i) =>
...
「상승 + 장조(Major)」 = 달성·보상의 문법입니다 (마리오의 코인 소리와 같은 이치). 반대로 실패음은 **하강 + 단조(Minor)**로 만듭니다.
// 실패음 예시: 하강
synth.triggerAttackRelease('E5', 0.15, n);
synth.triggerAttackRelease('C5', 0.3, n + 0.15);
소리의 방향만으로 감정이 반전되므로, 성공/실패/주의 3종류 정도는 같은 신시사이저의 음정 차이로 해결할 수 있습니다.
envelope: { attack: 0.005, decay: 0.08, sustain: 0, release: 0.05 }
envelope는 소리의 형태(Attack → Decay → Sustain → Release)입니다. UI 효과음 설계는 거의 이것으로 고정할 수 있습니다:
attack: 0.005〜0.02
→ 누르는 순간 울림
sustain: 0
→ 계속 누르고 있어도 길어지지 않음
전체 길이를 0.05〜0.4초 내로 맞춤
「UI 효과음은 sustain 0」이라고 기억해 두면, envelope 설정으로 고민할 일은 없어집니다.
원칙이라기보다 매너에 가깝지만, 아래 사항을 어기면 민폐 사이트가 됩니다.
멋대로 울리지 않기 — Tone.start()는 사용자 조작 내에서 (앞서 언급한 지연 초기화)
언제든 끌 수 있기 — 화면의 눈에 띄는 곳에 ON/OFF 토글을 상시 배치. 꺼도 모든 기능을 사용할 수 있을 것
짧고·작게 — 마스터 볼륨은 절제되게 (데모는 -14dB)
데모 페이지를 열어 DevTools를 통해 바로 테스트할 수 있습니다 (어딘가를 한 번 클릭하여 소리를 활성화한 후):
synths.blip.triggerAttackRelease('A3', 0.3); // 음정(Pitch)을 바꾼다
synths.boing.triggerAttackRelease('C4', 0.4); // 큰 녀석의 목소리를 높게 → 작은 녀석이 된다
음정 하나로 체격이 바뀌고, 방향 하나로 감정이 반전되는 것을 체감할 수 있을 것입니다.
파형 (Waveform) = 성격— sine/triangle/square/sawtooth/膜(Membrane) 중에서 선택 -
음정 (Pitch) = 체격— 큰 것은 낮게, 작은 것은 높게 -
상승 = 긍정적— 보상은 상승 메이저 (Major), 실패는 하강 마이너 (Minor) -
sustain 0— UI 효과음은 짧게 울리고 사라짐
이 데모의 몬스터 3마리는 이미지 제로의 전량 CSS 렌더링 (CSS drawing) 입니다 (별도 기사: 「이미지 제로로 마스코트 캐릭터를 그리기 — CSS 몬스터의 4원칙」).
👉 작동 데모: MONSTER DENIM
제작: 주식회사 Landland — 「쇼핑이 즐거운」을 만드는 Web 제작·앱 개발을 하고 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기