레슨 5 / 8·20분
시퀀싱과 패턴
고급 시퀀싱 기법
Tone.js의 시퀀싱 기능을 활용하면 복잡한 리듬 패턴과 멜로디를 프로그래밍할 수 있습니다. Part를 사용하면 각 음에 개별 시간과 길이를 지정할 수 있고, 여러 Part를 조합하여 완전한 악곡 구성이 가능합니다.
javascript
import * as Tone from 'tone';
// Part — 각 음에 개별 시간/길이/속도 지정
const synth = new Tone.Synth().toDestination();
const melody = new Tone.Part(
(time, event) => {
synth.triggerAttackRelease(
event.note,
event.duration,
time,
event.velocity
);
},
[
{ time: '0:0:0', note: 'C4', duration: '8n', velocity: 0.9 },
{ time: '0:0:2', note: 'E4', duration: '8n', velocity: 0.7 },
{ time: '0:1:0', note: 'G4', duration: '4n', velocity: 0.8 },
{ time: '0:2:0', note: 'B4', duration: '8n', velocity: 0.6 },
{ time: '0:2:2', note: 'C5', duration: '2n', velocity: 1.0 },
]
);
melody.loop = true;
melody.loopEnd = '1m'; // 1마디마다 반복
melody.start(0);
Tone.Transport.bpm.value = 120;
Tone.Transport.start();다중 트랙 구성
javascript
// 멜로디 트랙
const melodySynth = new Tone.Synth({
oscillator: { type: 'triangle' },
}).toDestination();
const melodyPart = new Tone.Sequence(
(time, note) => {
if (note !== null) {
melodySynth.triggerAttackRelease(note, '8n', time);
}
},
['C4', 'E4', 'G4', null, 'E4', 'C4', null, 'G3'],
'8n'
);
// 베이스 트랙
const bassSynth = new Tone.MonoSynth({
oscillator: { type: 'sawtooth' },
filter: { Q: 2, frequency: 800, type: 'lowpass' },
envelope: { attack: 0.01, decay: 0.3, sustain: 0.4, release: 0.8 },
}).toDestination();
const bassPart = new Tone.Sequence(
(time, note) => {
bassSynth.triggerAttackRelease(note, '4n', time);
},
['C2', 'C2', 'G2', 'E2'],
'4n'
);
// 드럼 트랙
const kick = new Tone.MembraneSynth().toDestination();
const snare = new Tone.NoiseSynth({
noise: { type: 'white' },
envelope: { attack: 0.005, decay: 0.15, sustain: 0 },
}).toDestination();
const drumPart = new Tone.Loop((time) => {
kick.triggerAttackRelease('C1', '8n', time);
snare.triggerAttackRelease('16n', time + Tone.Time('8n').toSeconds());
}, '4n');javascript
// 모든 트랙 동시 시작/정지
function startAll() {
melodyPart.start(0);
bassPart.start(0);
drumPart.start(0);
Tone.Transport.start();
}
function stopAll() {
melodyPart.stop();
bassPart.stop();
drumPart.stop();
Tone.Transport.stop();
}
// BPM 변경
function setBPM(bpm) {
Tone.Transport.bpm.rampTo(bpm, 1); // 1초에 걸쳐 변경
}
// 스윙 추가 (셔플 느낌)
Tone.Transport.swing = 0.3; // 0~1, 스윙 정도
Tone.Transport.swingSubdivision = '8n'; // 스윙 적용 단위
// 시간 표기법
// '0:0:0' = 마디:박:16분음표
// '4n' = 4분음표, '8n' = 8분음표
// '1m' = 1마디, '2t' = 2분음표 셋잇단- •Part — 각 이벤트에 개별 시간/값을 지정하는 유연한 시퀀서
- •Sequence — 배열을 균등 간격으로 순차 재생
- •Loop — 일정 간격마다 콜백 반복
- •null — Sequence에서 해당 타이밍을 쉼표(rest)로 처리
- •swing — 셔플/스윙 느낌 추가 (재즈, 펑크 등)
- •시간 표기: "마디:박:16분음표" 또는 "4n"(음표 단위)
💡
Part에서 time은 "마디:박:16분음표" 형식입니다. "0:0:0"은 시작점, "0:1:0"은 두 번째 박, "1:0:0"은 두 번째 마디입니다. 4/4 박자에서 한 마디는 4박입니다.