Chapter 12

리듬 시퀀서와 그루브

드럼 머신의 스텝 시퀀서는 음악 장비 중 가장 '공학적인' 물건입니다. 패턴은 0과 1의 행렬이고, 연주는 그 행렬을 정확한 시계로 읽는 일이며, 소리는 발진기와 잡음과 필터 몇 개로 만듭니다. 이 장에서는 브라우저 안에 실제로 쓸 수 있는 리듬 시퀀서를 놓고, 타이밍이 왜 어긋나며 어떻게 바로잡는지, 장르의 '느낌'이 어떤 데이터로 표현되는지, 그리고 기계적인 격자에서 사람다운 그루브를 되찾는 방법을 다룹니다.

스텝 시퀀서는 행렬이다

스텝 시퀀서는 한 마디를 \(S\)개의 같은 칸(스텝)으로 나누고, 악기(트랙)마다 각 칸을 켜거나 끕니다. 트랙이 \(T\)개면 패턴은 \(T\times S\) 행렬이고, 칸 값에 세기(벨로시티)를 넣으면 0/1 행렬이 작은 정수 행렬이 됩니다. 재생기는 스텝 번호 \(s\)를 시계에 맞춰 0, 1, …, \(S-1\), 0, … 으로 돌리며 열 \(s\)의 0이 아닌 칸을 연주합니다.

$$P\in\{0,1,2,3\}^{T\times S},\qquad t_s = t_0 + s\,\Delta,\qquad \Delta = \frac{60}{\text{BPM}\cdot q}$$
\(q\): 박당 스텝 수(16분 격자면 4, 32분이면 8, 8분 셋잇단이면 3). 값 0 = 쉼, 1 = 보통, 2 = 강세(accent), 3 = 고스트 노트(아주 약하게). 120 BPM 16분 격자의 \(\Delta\)는 125 ms다. 실제 온셋 시각은 여기에 스윙·휴머나이즈·트랙별 오프셋을 더한 \(t_s + \delta_{s,\text{track}}\)이다(4절).
SIMULATOR

리듬 시퀀서

칸 클릭: 켜기/끄기 · Shift(또는 Alt)+클릭: 보통 → 강세 → 고스트
장르 프리셋
격자
칸 클릭 동작
믹서: 트랙별 볼륨 · 음높이 · 감쇠 · 스윙 적용 · 음색
위치 (마디.박.스텝)—
스텝 길이—
예약 여유(최소)—
휴머나이즈 실측 RMS—
칸을 클릭해 찍고, 트랙 이름을 누르면 그 소리를 미리 듣습니다. M은 음소거, S는 솔로입니다. 색: 보라 = 보통, 청록 = 강세, 흐린 칸 = 고스트. 세로로 진한 칸이 박입니다. 스윙은 16분음표 쌍의 뒷칸을 늦추며(50% = 스트레이트, 66.7% = 셋잇단), 믹서에서 트랙별로 끌 수 있고 셋잇단 격자에서는 적용되지 않습니다. 휴머나이즈는 온셋마다 평균 0, 표준편차 σ인 가우스 시간 오차(±2.5σ로 제한)와 비례하는 세기 오차를 더합니다. '변주'는 현재 패턴을 바탕으로 같은 트랙에만 박절 가중치를 따라 음을 더하거나 뺍니다. '링크 복사'는 패턴을 URL(#)에 담습니다. 예약 여유는 소리가 나기 몇 ms 전에 예약되었는지(작을수록 위험)를 보여 줍니다. 드럼은 모두 실시간 합성입니다.

드럼 머신 약사와 장르 패턴

프로그래밍 가능한 드럼 머신은 1980년 전후에 대중화되었습니다. Roland TR-808(1980)은 아날로그 회로로 북소리를 '흉내 낸' 소리가 오히려 개성이 되어 힙합·일렉트로·트랩의 기본 음색이 되었고, 같은 해 나온 Linn LM-1과 이어진 LinnDrum(1982)은 실제 드럼을 녹음한 샘플을 써서 팝 음반의 드럼을 대신했습니다. TR-909(1983)는 아날로그 북과 샘플 심벌을 섞은 하이브리드로 하우스와 테크노의 소리가 되었습니다. 스텝을 칸으로 보여 주고 칸을 눌러 찍는 TR 계열의 '16개 버튼' 인터페이스가 오늘날 스텝 시퀀서 UI의 원형입니다. 또 로저 린의 설계를 이은 Akai MPC 계열은 스윙 비율(50–75%)을 숫자로 조절하는 기능을 널리 퍼뜨렸습니다.

장르의 정체성 상당 부분은 템포 대역과 이 행렬의 몇몇 칸으로 요약됩니다.

장르BPM킥스네어/클랩하이햇·기타
록 8비트90–1401, 3(+3의 &)2, 4 (백비트)8분 닫힌 햇
디스코·하우스115–130매 박(포 온 더 플로어)2, 4 클랩뒷박 열린 햇
힙합 붐뱁80–95엇박이 섞인 1–2개2, 4 강한 스네어스윙된 8·16분
트랩130–170 (하프타임)길게 울리는 8083박에만(하프타임)16·32분 롤, 셋잇단
펑크90–11516분 엇박 킥2, 4 + 고스트 노트16분 햇, 강세 패턴
보사노바120–140 (2박 느낌)점4분+8분 반복림 클라베8분 셰이커·햇
레게 원 드롭60–803박에만3박 림(킥과 함께)스윙된 햇
드럼앤베이스 2-step160–1801, 3의 &2, 48분 햇, 고스트
레게톤(뎀보우)88–100매 박3+3+2 계열8분 햇

정확한 타이밍: 두 시계 이야기

브라우저에서 박자를 맞추는 가장 쉬운 방법은 setInterval(playStep, 125)입니다. 그런데 이렇게 만든 시퀀서는 들어 보면 미세하게 절뚝입니다. 자바스크립트 타이머 콜백은 메인 스레드에서 실행되므로 레이아웃·그리기·가비지 컬렉션·다른 스크립트가 끝나기를 기다려야 하고, 백그라운드 탭에서는 1초 단위로 묶이기까지 합니다. 콜백이 몇 ms 늦으면 소리도 그만큼 늦습니다. 사람은 등간격 클릭열의 한 음이 수 ms(템포의 몇 %)만 밀려도 알아차릴 수 있으므로 이 흔들림은 충분히 들립니다.

해결책은 Chris Wilson의 글 "A Tale of Two Clocks"(2013)로 널리 알려진 룩어헤드 스케줄링입니다. 시계를 두 개 씁니다. 부정확하지만 자주 깨어나는 자바스크립트 타이머(예: 25 ms마다)는 '앞으로 100 ms 안에 울릴 음이 있는가?'만 확인하고, 있으면 그 음을 오디오 시계(AudioContext.currentTime, 오디오 스레드의 샘플 카운터)의 정확한 시각에 예약합니다. 실제 발음은 오디오 렌더링 스레드가 샘플 단위로 처리하므로, 타이머가 늦게 깨어나도 룩어헤드 창 안에서만 늦으면 소리는 정확합니다. 이 책의 MB.Clock이 이 방식이며 타이머 25 ms, 룩어헤드 120 ms를 씁니다.

그림 12-1. 두 시계. 위: 25 ms마다 깨어나는(실제로는 들쭉날쭉한) 타이머 콜백과 각 콜백이 살펴보는 룩어헤드 창(색 띠). 아래: 오디오 시계 위에 예약된 음(▲)은 정확히 등간격이다. 한 음은 여러 창에 걸칠 수 있지만 처음 발견된 창에서 한 번만 예약된다. 조건은 '타이머의 최대 지연 < 룩어헤드 − 타이머 주기'다.
$$\underbrace{\tau_{\text{timer}}}_{25\,\text{ms}} + \underbrace{\max(\text{메인 스레드 블로킹})}_{?} \;<\; \underbrace{L}_{\text{룩어헤드}}\qquad\text{그리고}\qquad \text{반응 지연} \approx L$$
룩어헤드 \(L\)을 늘리면 블로킹에 강해지지만, 템포 변경·음소거 같은 조작이 \(L\)만큼 늦게 반영된다(이미 예약된 음은 되돌리기 어렵다). 그래서 100 ms 안팎이 절충점이다.

지연 예산도 함께 봅시다. 오디오 그래프는 128샘플 단위(렌더 퀀텀, 48 kHz에서 2.67 ms)로 처리되고, 블록 길이 자체는 전체 처리 지연이 아닙니다. baseLatency는 AudioDestinationNode에서 오디오 서브시스템으로 넘기는 처리 지연이고, outputLatency는 호스트의 버퍼 재생 요청부터 장치 출력까지의 추정 지연입니다. 장치의 출력 지연은 보통 10–40 ms, 블루투스 이어폰은 150–250 ms에 이릅니다. 예약된 음끼리의 상대 간격은 정확하므로 리듬은 흔들리지 않지만, 패드를 누른 순간부터 소리가 날 때까지의 절대 지연에는 입력 이벤트 처리, 그래프·버퍼 처리, baseLatency·outputLatency와 예약 여유가 영향을 줍니다. 렌더 퀀텀 하나와 outputLatency만 더해 모든 환경을 설명할 수는 없습니다. 실시간 연주(손가락 → 소리)는 대략 10 ms 이하가 바람직합니다.

SIMULATOR

스케줄러 지터 측정: setTimeout vs 룩어헤드

스케줄러
setTimeout 오차 평균 · SD—
setTimeout 최대—
MB.Clock 늦은 예약—
왼쪽 귀(낮은 클릭)는 setTimeout으로 매 16분음표마다 '지금' 소리를 내고(드리프트는 매번 보정), 오른쪽 귀(높은 클릭)는 MB.Clock이 오디오 시계에 예약합니다. 위 그래프: 의도한 시각 대비 실제 콜백 시각의 오차 히스토그램(ms). 아래: 시간에 따른 오차. setTimeout 쪽은 performance.now()로 잰 콜백 지연이고, MB.Clock 쪽은 예약 시점에 이미 지나 버린 시간(늦은 예약)입니다. 부하를 50 ms쯤 주면 setTimeout 클릭이 눈에 띄게 절뚝이지만 Clock 쪽은 그대로입니다. 부하가 룩어헤드(120 ms)를 넘으면 Clock도 무너지는 것을 확인하세요. 부하 슬라이더는 실제로 메인 스레드를 바쁘게 만들므로 페이지가 버벅입니다.

벨로시티, 스윙, 휴머나이즈, 미세 타이밍

행렬을 정확히 연주하기만 하면 '기계 같다'는 말을 듣습니다. 그루브는 행렬 바깥의 세 가지 정보에서 나옵니다. 첫째, 세기: 강세와 고스트 노트의 대비(펑크 스네어의 고스트는 보통 음보다 20–30 dB 작습니다). 둘째, 체계적 시간 이동: 스윙과 트랙별 오프셋. 셋째, 무작위 변동: 휴머나이즈. 셋을 한 식으로 쓰면 다음과 같습니다.

$$t'_{s,k} = t_0 + \Delta\,\sigma_{sw}\!\left(s\right) + o_k + \varepsilon_{s,k},\qquad \varepsilon\sim\mathcal N(0,\sigma_t^2),\qquad v' = v\,(1+\eta),\;\eta\sim\mathcal N(0,\sigma_v^2)$$
\(\sigma_{sw}\): 스윙 시간 변환(16분 쌍 안의 위치 \(u\in[0,1)\)을 \(u<\tfrac12\)이면 \(u\cdot 2p\), 아니면 \(p+(u-\tfrac12)\cdot 2(1-p)\)로 보낸다. \(p\)가 스윙 %). \(o_k\): 트랙 \(k\)의 고정 오프셋(스네어 +20 ms면 '레이드백'). \(\varepsilon\): 독립 가우스 지터. 실제 연주자의 오차는 독립이 아니라 이웃끼리 상관되고(1/f 잡음에 가깝다는 연구가 있다), 독립 지터는 크게 하면 그냥 '서툴게' 들린다.

프로듀서들이 말하는 '레이드백 스네어'나 'J Dilla 풍의 느슨한 필'은 대개 트랙별 \(o_k\)를 일관되게 주는 기법입니다. 킥을 조금 이르게, 스네어를 늦게, 하이햇을 16분 격자와 셋잇단 격자 사이에 두면 격자 하나로는 설명되지 않는 출렁임이 생깁니다. 반대로 같은 크기의 무작위 지터는 대체로 그루브를 해칩니다. 아래 시뮬레이터에서 둘을 직접 비교해 보세요.

SIMULATOR

휴머나이즈와 미세 타이밍

A/B
온셋 편차 RMS—
스네어 − 킥 평균—
16분 대비 오프셋—
그래프: 가로는 마디 안 위치(16분 칸), 세로는 격자 대비 실제 온셋의 편차(ms, 위가 늦음). 점은 최근 두 마디의 실제 온셋(보라 = 킥, 청록 = 스네어, 주황 = 하이햇), 점선은 트랙별 오프셋입니다. A/B를 재생 중에 전환하면 같은 패턴의 양자화 버전과 비교할 수 있습니다. 해볼 것: ① 스네어 +20 ms만 주고 A/B 비교 → 느긋하고 무거운 느낌. ② 같은 RMS가 되도록 '무작위만 20 ms'와 비교 → 대부분 더 서툴게 들립니다. ③ 하이햇을 −10 ms로 당기면 곡이 앞으로 쏠리는 '푸시'.

유클리드 리듬: 가장 고르게 흩어 놓기

\(n\)칸에 \(k\)개의 온셋을 가능한 한 고르게 배치하면 어떤 리듬이 나올까요? \(k\)가 \(n\)의 약수면 답은 등간격이지만, 8칸에 3개처럼 나누어떨어지지 않으면 간격이 3과 2로 섞입니다. Toussaint(2005, "The Euclidean Algorithm Generates Traditional Musical Rhythms")는 이 '최대한 고른' 배치가 유클리드 호제법과 같은 구조의 재귀로 만들어지며, 그 결과가 세계 여러 전통 음악의 리듬과 놀랍도록 일치한다는 것을 보였습니다. 이 알고리즘은 원래 Bjorklund(2003)가 핵파쇄 중성자원(SNS) 가속기의 타이밍 펄스를 고르게 배치하려고 쓴 것입니다.

$$E(k,n):\quad \text{온셋 위치 } p_i = \left\lfloor \frac{i\,n}{k} \right\rfloor,\; i = 0,\dots,k-1 \quad(\text{회전 동치까지 같은 결과})$$
비요르클룬드 알고리즘은 [1]을 \(k\)개, [0]을 \(n-k\)개 두고, 남은 쪽 묶음을 앞 묶음 뒤에 하나씩 붙이는 과정을 나머지가 1개 이하가 될 때까지 반복한다. 이는 \(\gcd(n,k)\)를 구하는 유클리드 호제법의 나눗셈 단계와 대응한다. E(3,8): [1][1][1][0][0][0][0][0] → [10][10][10][0][0] → [100][100][10] → 10010010.
E(k, n)패턴간격대표 예
E(2, 5)x.x..2-3페르시아 리듬(khafif-e-ramal)
E(3, 8)x..x..x.3-3-2쿠바 트레실로, 록·팝의 '3-3-2'
E(5, 8)x.xx.xx.2-1-2-1-2쿠바 신킬로(cinquillo)
E(3, 7)x.x.x..2-2-3불가리아 루체니차(7/8)
E(4, 9)x.x.x.x..2-2-2-3튀르키예 아크사크(9/8)
E(7, 12)x.xx.x.xx.x.2-1-2-2-1-2-2서아프리카 표준 종 패턴(회전형)
E(5, 16)x..x..x..x..x...3-3-3-3-4보사노바 리듬의 회전 동치
SIMULATOR

유클리드 리듬 생성기 (3고리)

편집할 고리
A—
B—
C—
전체 주기—
세 고리(바깥 A = 킥, 가운데 B = 림, 안쪽 C = 하이햇)마다 E(k, n)을 비요르클룬드 알고리즘으로 만들고 r칸 회전합니다. 모든 고리는 같은 16분음표 펄스로 돌기 때문에 n이 다르면 폴리미터가 되고, 전체 주기는 n들의 최소공배수입니다. 이름 붙은 패턴 버튼은 '편집할 고리'에 적용됩니다. 해볼 것: A = E(4,16) 포 온 더 플로어, B = E(3,8), C = E(7,12)… 아니면 C를 E(5,16)으로. 수 세 개로 만든 리듬이 꽤 음악적이라는 것이 유클리드 리듬이 라이브 코딩과 모듈러 신스에서 인기 있는 이유입니다.

드럼 합성의 물리

TR-808 이후의 전자 드럼은 실제 북의 물리를 몇 가지 핵심 특징으로 줄여 흉내 냅니다. 막을 세게 치면 장력이 순간적으로 커져 음높이가 높게 시작했다가 빠르게 내려오고(피치 스윕), 스네어는 아래 막에 닿는 쇠줄(스내어)이 넓은 대역의 잡음을 더하며, 심벌은 비조화 모드가 촘촘히 겹쳐 잡음에 가까운 금속성 스펙트럼을 냅니다.

그림 12-2. 세 가지 드럼 합성 회로. 킥: 주파수 엔벨로프가 걸린 사인 발진기 + 진폭 엔벨로프(+ 짧은 클릭). 스네어: 톤(삼각파)과 고역 통과 잡음의 혼합. 하이햇: 비조화 주파수의 사각파 6개 → 대역 통과 → 고역 통과 → 아주 짧은 엔벨로프(TR-808 방식).
$$f(t) = f_1 + (f_0 - f_1)\,e^{-t/\tau_f},\qquad x(t) = e^{-t/\tau_a}\sin\!\Big(2\pi\!\int_0^t f(u)\,du\Big)$$
킥 모델. \(f_0\): 시작 주파수(100–300 Hz, 어택의 '퍽'), \(f_1\): 최종 주파수(40–60 Hz, 몸통), \(\tau_f\): 스윕 시상수(수 ms ~ 수십 ms), \(\tau_a\): 진폭 감쇠. 위상은 주파수의 적분이라는 점에 주의(주파수를 바꿔도 파형이 끊기지 않는다). 트랩의 '808 베이스'는 \(\tau_a\)를 1초 이상으로 늘려 음높이 있는 베이스로 쓰는 것이다. TR-808 하이햇의 여섯 발진기는 약 205, 304, 370, 523, 540, 800 Hz로 서로 정수비가 아니며, 그 사각파들의 고차 배음이 6–12 kHz 대역을 촘촘히 채운다.
SIMULATOR

드럼 합성 실험실

악기
피크 · −40 dB 시간—
스펙트럼 무게중심—
모델—
파라미터를 바꿀 때마다 OfflineAudioContext로 같은 회로를 렌더링해 위에는 파형, 아래에는 스펙트로그램(로그 주파수, 2048점 STFT, 최대값 기준 60 dB 범위)을 그립니다. 킥은 이론 피치 곡선 \(f(t)\)를 점선으로 겹칩니다. '비트로 듣기'는 지금 설정한 세 악기로 간단한 비트를 돌립니다(악기별 설정은 따로 기억됨). 해볼 것: ① 킥의 τa를 1000 ms 이상, f₁을 50 Hz 근처로 → 808 베이스. ② f₀를 낮추고 클릭을 0으로 → 어택이 사라져 작은 스피커에서 킥이 안 들림(배음이 없어서). ③ 하이햇 감쇠를 400 ms 이상 → 열린 햇. 회로는 이 페이지에서 직접 만든 근사 모델이며 MB.drum과 별개입니다.

길이가 다른 트랙: 폴리미터 시퀀싱

모든 트랙이 16스텝일 필요는 없습니다. 트랙마다 길이를 다르게 하면 같은 펄스 위에서 패턴들이 서로 미끄러지며 매 마디 조금씩 다른 조합이 나옵니다(11장의 폴리미터). Elektron 계열 시퀀서나 모듈러 신스 시퀀서가 '트랙별 길이'를 기본으로 제공하는 이유입니다. 짧은 데이터로 긴 변화를 얻는 압축 기법이기도 합니다. 16, 12, 10스텝 트랙은 lcm(16, 12, 10) = 240스텝, 즉 15마디 뒤에야 처음 상태로 돌아옵니다.

$$P_{\text{전체}} = \operatorname{lcm}(L_1, L_2, \dots, L_T)\ \text{스텝},\qquad \text{트랙 } k\text{의 현재 칸} = s \bmod L_k$$
서로소인 길이(예: 16, 15, 7)를 고르면 주기가 곱(1680스텝 = 105마디)이 되어 반복을 거의 느끼지 못한다. 반대로 약수 관계(16, 8, 4)면 주기는 가장 긴 트랙과 같다.
SIMULATOR

폴리미터 시퀀서

전체 주기—
마디 · 시간—
현재 진행—
각 줄의 칸 수가 트랙 길이입니다(칸을 클릭해 편집). 모든 트랙이 같은 16분음표 펄스로 진행하고, 줄마다 자기 길이에서 처음으로 돌아갑니다. 아래 그래프는 트랙별 주기의 시작점(세로 막대)을 시간축에 늘어놓은 것으로, 모든 막대가 한 세로선에 모이는 곳이 전체 재정렬 지점입니다(길면 앞부분만 표시). 흰 선이 현재 위치입니다. 해볼 것: 킥은 16 그대로 두고 카우벨만 7로 → 매 마디 카우벨의 자리가 바뀌는 '기계적인 변주'.

핵심 정리

  1. 스텝 시퀀서 패턴은 트랙 × 스텝 행렬이다. 칸 값에 세기(보통·강세·고스트)를 담고, 스텝 간격은 \(60/(\text{BPM}\cdot q)\)다.
  2. 메인 스레드 타이머는 수 ms에서 수십 ms까지 흔들린다. 타이머는 앞을 내다보기만 하고 오디오 시계에 예약하는 룩어헤드 방식(25 ms 타이머, 약 100 ms 창)이 표준 해법이다.
  3. 상대 타이밍은 샘플 정확도로 맞출 수 있지만 절대 지연(입력 이벤트·그래프/버퍼 처리·baseLatency·outputLatency·예약 여유)은 남는다. 실시간 연주는 약 10 ms 이하가 바람직하다.
  4. 장르의 느낌은 템포 대역, 행렬의 핵심 칸(백비트, 포 온 더 플로어, 하프타임), 세기 패턴, 스윙 값으로 상당 부분 요약된다.
  5. 그루브는 체계적 시간 이동(스윙, 트랙별 오프셋)에서 주로 나오고, 독립 가우스 지터는 크게 하면 대개 '서툰' 느낌을 준다.
  6. 유클리드 리듬 E(k, n)은 k개의 온셋을 n칸에 최대한 고르게 둔 것으로, 비요르클룬드(유클리드 호제법) 알고리즘이 만든다. E(3,8) 트레실로, E(5,8) 신킬로 등이 대표적이다.
  7. 킥 = 지수 피치 스윕 사인 + 감쇠, 스네어 = 톤 + 고역 잡음, 하이햇 = 비조화 사각파 묶음 + 대역·고역 필터 + 짧은 감쇠.
  8. 트랙 길이가 다르면 전체 주기는 길이들의 최소공배수다. 짧은 데이터로 긴 변화를 얻는다.

확인 퀴즈

140 BPM, 32분음표 격자에서 한 스텝의 길이는?

박 = 60000/140 ≈ 428.6 ms이고 32분음표는 박의 1/8이므로 약 53.6 ms다.

룩어헤드 스케줄러에서 타이머 주기 25 ms, 룩어헤드 100 ms일 때 소리가 늦지 않으려면 메인 스레드가 한 번에 막혀 있는 시간은 대략 얼마 이하여야 하는가?

콜백은 최악의 경우 주기 25 ms에 블로킹 시간만큼 더 늦게 깨어난다. 그 사이에 울릴 음이 이미 예약되어 있으려면 25 + 블로킹 < 100, 즉 블로킹 < 약 75 ms여야 한다.

비요르클룬드 알고리즘으로 만든 E(5, 8)과 같은 리듬(회전 포함)은?

5개를 8칸에 고르게 두면 간격이 2-1-2-1-2가 된다. 쿠바의 신킬로다. x..x..x.는 E(3,8)(트레실로), xxxxx...는 가장 고르지 않은 배치다.

16분 격자에서 스윙을 66.7%로 하면 120 BPM에서 둘째 16분음표(뒷칸)는 스트레이트보다 얼마나 늦는가?

16분 쌍(8분음표) 길이 = 250 ms. 뒷칸은 50%(125 ms) 대신 66.7%(166.7 ms) 위치에 오므로 약 41.7 ms 늦다.

킥 합성에서 시작 주파수를 높게(예: 250 Hz) 하고 빠르게 떨어지게 하는 주된 효과는?

짧은 시간 높은 주파수에서 시작하는 스윕은 어택 부분의 스펙트럼을 위로 넓힌다. 몸통의 음높이는 최종 주파수가 정하고, 울림 길이는 진폭 감쇠가 정한다.

길이 16, 12, 10인 세 트랙이 같은 펄스로 돌 때 전체 패턴이 처음 상태로 돌아오는 주기는?

lcm(16, 12, 10) = 240 스텝 = 16분 격자로 15마디. 곱 1920이 아니라 최소공배수다.