C.W.K.
Stream
Lesson 04 of 05 · published

Web MIDI: 또 다른 sink, 또 다른 scheduler 가 아냐

~12 min · web-midi, one-scheduler, sinks

Level 0식은 재
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"출력을 더할 땐 leaf 에서 갈라 — 절대 scheduler 를 fork 하지 마."

기능: 진짜 신스를, 라이브로

v1 엔진은 solo 와 코드를 Web MIDI 로 내보낼 수 있어 — 진짜 소프트/하드웨어 악기(macOS IAC 버스로 먹인 신스)를 구동해서 인앱 오디오와 나란히 박자 맞게 울려. 그 자체로 만족스러운 기능이야. 근데 흥미로운 건 어떻게 더했나 야, 틀린 방식이 너무 유혹적이거든.

유혹적인 실수: scheduler 를 fork

MIDI 출력을 더하는 순진한 방식은 MIDI 한테 자기 scheduler 를 주는 거야 — 자기 루프, 자기 타이밍 — 오디오 것 옆에서 돌게. 이제 scheduler 가 둘이고, 두 출력은 지난 레슨의 독립 voice 들처럼 정확히 갈라져. jitter 문제를 한 층 위에서 다시 만든 거야. 방금 배운 수정(클럭 하나)이 결정자를 fork 하면서 조용히 풀려.

맞는 방식: scheduler 하나, sink 여럿

대신, 단일 scheduler 가 여전히 언제 를 정해. 출력은 어떻게 내보내느냐만 달라: Web Audio sink 는 샘플을 재생하고, Web MIDI sink 는 note-on 바이트를 보내. MIDI 추가는 scheduler 가 아니라 sink 를 더한 거야. Track 4 의 API-first / 단일 진실원 아이디어가 이제 playback 레이어에 있어: 결정자 하나, 컨슈머 여럿, 실제 방출이 다른 leaf 에서만 갈라져. 작동 증명: 인앱 오디오를 구동하는 같은 scheduler 가 하드웨어 신스도 박자 맞게 구동해, 두 번째 타이밍 엔진 없이.

Code

scheduler 가 아니라 sink 에서 갈라·javascript
// ONE scheduler 가 WHEN 을 정해 (지난 레슨의 anchored 클럭에서).
// 출력은 HOW 만 달라 -- scheduler 가 아니라 sink 야.
function emit(note, audioTime) {
  if (audioOut.enabled) {
    playSample(note, audioTime);                  // Web Audio sink
  }
  if (midiOut.enabled) {
    midiOut.send(noteOnBytes(note), toMidiTime(audioTime));  // Web MIDI sink
  }
}

// MIDI 추가는 scheduler 를 fork 안 했어 -- sink 를 더했어.
// scheduler 하나, sink 여럿: playback 레이어의 API-first 규칙.

External links

Exercise

출력을 만드는 시스템(렌더러, 알림기, exporter)을 가져와 두 번째 출력 채널을 더한다고 상상해. 무엇/언제를 정하는 로직을 복제할래, 아니면 마지막 방출에서만 갈래? 새 출력을 위해 파이프라인 전체를 복사하려는 본능이면 scheduler 를 fork 하는 거야 — 출력이 실제로 다른 단일 leaf 를 찾아 거기서만 갈라.
Hint
결정 로직(뭘, 언제, 어느 음)은 한 번 살아야 해. 방출(스피커로, MIDI 로, 파일로, webhook 으로)만 출력별이야. 방출만 복사하고, 그 위 전부는 공유해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 피파warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.