Learning
레슨 3 / 8·20분

시퀀스와 패턴

Transport와 시퀀싱

Tone.Transport는 음악의 "지휘자" 역할로 BPM(템포), 재생/정지, 타임라인을 관리합니다. Sequence는 배열의 음을 순서대로 반복 재생하고, Pattern은 다양한 순서 패턴(위/아래/랜덤 등)으로 재생하며, Loop는 지정 간격마다 콜백을 실행합니다.

javascript
import * as Tone from 'tone';

// ── Transport 설정 ──
Tone.Transport.bpm.value = 120; // 분당 박자 수

// ── Sequence — 순서대로 반복 재생 ──
const synth = new Tone.Synth().toDestination();

const melody = new Tone.Sequence(
  (time, note) => {
    synth.triggerAttackRelease(note, '8n', time);
  },
  ['C4', 'E4', 'G4', 'B4', 'C5', 'B4', 'G4', 'E4'], // 음 배열
  '8n'  // 각 음의 간격 (8분음표)
);

melody.start(0);           // Transport 시작 시점부터
Tone.Transport.start();    // 재생 시작
javascript
// ── Pattern — 다양한 패턴으로 재생 ──
const bellSynth = new Tone.FMSynth({
  modulationIndex: 4,
}).toDestination();

const pattern = new Tone.Pattern(
  (time, note) => {
    bellSynth.triggerAttackRelease(note, '4n', time);
  },
  ['C4', 'D4', 'E4', 'F4', 'G4'],
  'upDown'  // 패턴: up, down, upDown, downUp, random, randomOnce
);

pattern.interval = '4n';
pattern.start(0);

// ── Loop — 일정 간격 반복 실행 ──
const kick = new Tone.MembraneSynth().toDestination();

const drumLoop = new Tone.Loop((time) => {
  kick.triggerAttackRelease('C1', '8n', time);
}, '4n'); // 4분음표마다 반복

drumLoop.start(0);
javascript
// ── Transport 제어 ──
// 재생 / 정지 / 일시정지
Tone.Transport.start();
Tone.Transport.stop();
Tone.Transport.pause();

// BPM 변경 (부드러운 전환)
Tone.Transport.bpm.rampTo(140, 2); // 2초에 걸쳐 140 BPM으로

// 시간 표현 (Tone.Time)
console.log(Tone.Time('4n').toSeconds());   // 4분음표 → 초
console.log(Tone.Time('1m').toSeconds());   // 1마디 → 초
console.log(Tone.Time('2n + 8n').toSeconds()); // 2분음표 + 8분음표

// 멜로디 정지
melody.stop();
drumLoop.stop();
Tone.Transport.stop();
  • Tone.Transport — 전역 타임라인 관리자 (start/stop/pause/bpm)
  • Tone.Sequence — 배열의 음을 순서대로 반복 재생
  • Tone.Pattern — up/down/upDown/random 등 다양한 순서로 재생
  • Tone.Loop — 지정 간격마다 콜백 함수 반복 실행
  • Tone.Time — "4n"(4분음표), "1m"(1마디), "2s"(2초) 등 시간 표기
  • BPM 120 기준: 4n=0.5초, 8n=0.25초, 1m=2초
💡

Sequence와 Pattern의 콜백에서 받는 time 매개변수를 triggerAttackRelease의 세 번째 인자로 전달하면 정확한 타이밍에 소리가 납니다. time 대신 현재 시간을 사용하면 약간의 지연이 발생할 수 있습니다.