TRENDSHIFT 딥다이브 · 2026-06-24

gary4juce 딥다이브
— AI 음악 생성기를 DAW 안으로 끌어들인 오디오 플러그인

MusicGen·Stable Audio 3 등 7개의 AI 음악 생성 모델을 하나의 VST3/AU 플러그인에 담아, Ableton·FL·Reaper 같은 음악 작업 프로그램(DAW) 세션 안에서 직접 녹음 → 생성 → 변형 → 타임라인 드래그를 반복하게 해주는 JUCE 8 기반 C++ 플러그인이다. 무거운 AI 추론은 외부 백엔드(원격 서버 또는 내 GPU)에 HTTP로 맡기고, 플러그인은 "녹음 버퍼 관리 + 통신 + 결과 재생/드래그"만 맡는 영리한 분업 구조다. 실시간 오디오 스레딩·비동기 네트워킹·AI 서빙 통합을 한꺼번에 배우기 좋은 실전 코드베이스. (저장소: betweentwomidnights/gary4juce · C++ / JUCE 8.0.8 · VST3·AU·Standalone · AGPL-3.0 · v4.0.3 · TrendShift 라이브 멘션)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

이 레포가 무엇을 하는 물건인가.

핵심 메시지

"순수 텍스트→음악이 목적이면 VST가 필요 없다.
이건 AI를 '내 작업 세션 안에' 앉히고 싶은 사람을 위한 것이다."

README 첫 문장이 정체성을 정확히 말한다. Suno 같은 웹 도구가 "텍스트로 완성곡을 뽑는" 것이라면, gary4juce는 내가 방금 친 기타 리프에 AI가 '반응'해 이어 연주하게 만든다. 작곡 도구 안에서 AI와 주고받는 게 핵심.

gary4juce는 DAW(디지털 오디오 워크스테이션) 플러그인이다. 즉 Ableton Live·FL Studio·Reaper 같은 음악 제작 프로그램에 꽂아 쓰는 부품이다. 이 플러그인 하나 안에 7개의 최신 AI 음악 모델이 탭으로 들어 있어, 사용자는 세션에서 오디오를 녹음하고 → AI에게 이어 만들기/변형을 시키고 → 결과를 타임라인에 드래그해 곡으로 엮는다.

중요한 설계 결정: 무거운 AI 계산은 플러그인이 직접 하지 않는다. 모델 추론은 외부 백엔드(개발자가 운영하는 무료 원격 서버, 또는 사용자가 자기 GPU에 띄우는 localhost 서비스)가 맡고, 플러그인은 오디오를 보내고 결과를 받아 재생·드래그하는 클라이언트 역할만 한다. 덕분에 플러그인 자체는 가볍고, GPU가 없어도 원격 백엔드로 바로 써볼 수 있다.

용어
DAW · VST3 · AU
DAW(Digital Audio Workstation)는 음악을 녹음·편집·믹싱하는 프로그램(Ableton·FL·Logic 등). VST3(스타인버그)와 AU(애플)는 그 안에 꽂는 플러그인 규격이다. 콘센트 규격처럼, 같은 플러그인을 여러 DAW에 꽂으려면 이 규격들을 맞춰야 한다. gary4juce는 둘 다(+독립 실행)로 빌드된다.
용어
JUCE
오디오 앱·플러그인을 만드는 C++ 프레임워크. 오디오 입출력, 플러그인 포맷(VST3/AU), UI 그리기, 네트워킹까지 한 묶음으로 제공한다. 전 세계 상용 플러그인 다수가 JUCE로 만들어졌다. gary4juce는 버전 8.0.8을 쓴다.

2왜 주목받는가

트렌딩 이유 · 경쟁 도구 대비 장점.

화제의 핵심은 "웹 AI 음악툴과 정반대 포지션"이다. 대부분의 AI 음악 서비스는 브라우저에서 완성곡을 뽑아주는 데 그치지만, gary4juce는 음악가가 이미 만들고 있는 작업물에 AI가 끼어들게 한다. 게다가 7개의 SOTA(최신) 모델을 한 UI에 통합한 것은 2026년 기준 사실상 최대 규모다.

항목웹 AI 음악툴(예: Suno)gary4juce
작업 위치브라우저(별도 공간)DAW 세션 안(작업 흐름 유지)
입력주로 텍스트 프롬프트내 녹음 오디오 + 텍스트 + BPM/키
모델 수보통 1종(자체)7종(MusicGen·SA3·ACE-Step·Magenta…)
실행 위치제공사 서버 고정원격(무료) 또는 내 GPU(localhost) 선택
공개성비공개오픈소스(AGPL-3.0) + 소스/라이선스 투명

각 모델에는 사람 이름 코드네임이 붙어 있어 외우기 쉽다 — gary(MusicGen, 오디오 이어붙이기), jerry(stable-audio-open-small, 빠른 짧은 루프), sa3(Stable Audio 3, v4의 메인 신기능: 최대 300초 생성·변형·LoRA 블렌딩), carey(ACE-Step, 50개 언어 보컬·stem 추출), terry(MelodyFlow, 스타일 변환), darius(Magenta RT, 48kHz 고품질 이어붙이기), rc-jerry(Foundation-1, BPM·키 인식 루프). 그리고 코드 곳곳에 실전 견고함의 흔적(stall 감지, cold-start 처리, 에디터 파괴/재생성 생존)이 있어 단순 토이가 아님이 드러난다.

기존 방식의 한계
"AI 음악은 좋은데, 내 작업 흐름과 따로 논다"

웹에서 곡을 뽑으면 다시 다운로드해 DAW로 가져와야 하고, 내가 지금 만들고 있는 트랙의 BPM·키·분위기와 맞물리지 않는다. AI가 '완성품'을 던져줄 뿐, 음악가가 만드는 과정에 함께 들어오지 못한다.

이 레포의 해결
세션 안에서 '녹음→생성→드래그'를 반복

플러그인이 DAW의 재생·BPM을 읽어 내 연주를 녹음하고, 그 오디오를 조건으로 AI가 이어/변형해 만든 결과를 바로 타임라인에 드래그해 넣는다. 무거운 추론은 백엔드에 맡겨 플러그인은 가볍게 유지하면서, AI를 작곡 과정의 '연주 파트너'로 만든다.

3기술 스택 전체 지도

플러그인(클라이언트) · 네트워킹 · AI 백엔드.

구조는 명확히 둘로 갈린다 — 이 저장소에 담긴 C++ 플러그인(클라이언트)과, 별도 저장소에 있는 Python AI 백엔드(서버). 플러그인은 별도 네트워킹 라이브러리 없이 순수 JUCE만으로 HTTP 통신을 한다.

레이어기술 / 버전역할
언어C++ (모던 — std::atomic·shared_ptr·람다)플러그인 전체 로직(~3.3만 줄).
프레임워크JUCE 8.0.8 (모듈 12종, DSP 모듈 없음)오디오·플러그인 포맷·UI·네트워킹.
플러그인 포맷VST3 / AU / StandaloneAbleton·FL·Reaper·Logic 등에서 동작.
프로젝트 정의Projucer .jucer (XML)모듈·포맷·빌드 설정의 단일 진실원.
빌드Windows VS2022 / macOS XcodeProjucer가 프로젝트 파일 생성.
네트워킹juce::URL + InputStream (별도 lib 없음)HTTP POST/GET. 오디오는 base64로 JSON에 실음.
JSON / 인코딩juce::JSON · DynamicObject · Base64요청 직렬화 · 오디오 base64 변환.
비동기juce::Thread::launchMessageManager::callAsync네트워크 I/O를 워커 스레드로, UI 복귀는 메시지 스레드.
AI 백엔드(별도 레포)Python + PyTorch (Audiocraft·stable-audio-tools·ACE-Step…)HTTP API로 모델 추론 서빙.
모델MusicGen·Stable Audio 3/Open·ACE-Step·MelodyFlow·Magenta RT7종. 각기 다른 라이선스(MIT·CC-BY-NC·Stability Community…).
용어
Projucer / .jucer
JUCE의 프로젝트 생성기와 그 설정 파일. 어떤 JUCE 모듈을 쓰고, 어떤 플러그인 포맷(VST3/AU)으로, 어떤 빌드 도구(VS/Xcode)로 내보낼지를 .jucer XML에 적어두면 Projucer가 실제 프로젝트 파일을 만들어 준다. "설계도 → 공장 세팅"의 설계도에 해당.
용어
base64로 오디오 보내기
오디오는 바이너리(0·1 덩어리)라 JSON 같은 텍스트에 바로 못 담는다. base64는 바이너리를 안전한 글자들로 바꿔 텍스트에 실을 수 있게 하는 인코딩이다. gary4juce는 녹음 WAV를 base64 문자열로 바꿔 HTTP 요청 본문에 넣어 백엔드로 보낸다(돌아올 때도 base64).
용어
LoRA (저랭크 어댑터)
큰 모델 전체를 다시 학습하지 않고, 작은 보조 가중치만 얹어 특정 스타일·음색을 주입하는 기법. SA3 탭에서는 LoRA 여러 개를 강도(0~2) 슬라이더로 동시에 섞어 "이 분위기 + 저 음색"을 블렌딩한다.

4아키텍처 심화 분석

내 연주가 AI를 거쳐 타임라인으로 돌아오기까지.

먼저 독수리 시점. 플러그인 내부는 크게 둘로 나뉜다 — 오디오를 실시간으로 다루는 Gary4juceAudioProcessor(프로세서)와, UI + 모든 네트워킹을 맡는 Gary4juceAudioProcessorEditor(에디터). 그 바깥에 HTTP로 연결된 AI 백엔드가 있다.

DAW (Ableton/FL/Reaper) ── 오디오 입력 · 재생/BPM ──┐ ▼ ┌──────────────────────────────────────────────────────────┐ │ gary4juce 플러그인 (VST3/AU/Standalone) │ │ ┌────────────────────┐ ┌────────────────────────┐ │ │ │ AudioProcessor │ ───▶ │ Editor (UI + 네트워킹) │ │ │ │ processBlock(실시간)│ │ 녹음 저장→base64→POST │ │ │ │ 녹음버퍼·재생·BPM │ │ 3초마다 폴링→결과 수신 │ │ │ └────────────────────┘ └───────────┬────────────┘ │ └───────────────────────────────────────────┼──────────────┘ myBuffer.wav / myOutput.wav │ HTTP/JSON(base64 audio) ▼ ┌────────────────────────────────────────────┐ │ AI 백엔드 (원격 g4l.thecollabagepatch.com │ │ 또는 localhost GPU 서비스들) │ │ gary:8000 terry:8002 carey:8003 │ │ jerry:8005 sa3:8006 foundation:8015 │ │ (Python + PyTorch, 작업 큐잉) │ └────────────────────────────────────────────┘ 생성 오디오 → myOutput.wav → 사용자가 DAW 타임라인에 드래그

이제 대표 흐름 한 줄기를 따라가자 — "녹음한 오디오로 AI에게 이어 만들기를 시킨다". 폴링(주기적으로 물어보기) 기반의 긴 작업 패턴이 핵심이다.

① 녹음 processBlock이 재생 중 입력을 recordingBuffer에 모음 → myBuffer.wav 저장 ② 인코딩 myBuffer.wav → MemoryBlock → Base64 문자열 ③ 제출 POST /api/juce/process_audio (model_name·audio_data·옵션을 JSON으로) ④ 접수 백엔드가 { success, session_id } 반환 (작업을 큐에 등록) ⑤ 폴링 50ms 타이머가 3초마다 GET /poll_status/{session_id} ★ ⑥ 진행 { progress, queue_status, audio_data(base64) } 수신 ⑦ 완료 base64 → myOutput.wav 저장 → 파형 표시 → 재생/드래그 준비

여기서 가장 배울 점은 오디오 스레드를 절대 멈추지 않는 설계다. 실시간 오디오 콜백(processBlock)에서 락(잠금)을 걸고 기다리면 소리가 끊긴다(글리치). 그래서 이 코드는 "논블로킹 시도 + 폴백 버퍼" 패턴을 쓴다 — 락을 시도만 하고, 못 잡으면 입력을 짧은 임시 버퍼에 잠깐 담아뒀다 다음 블록에서 합류시킨다.

# PluginProcessor.cpp — 오디오 스레드는 절대 블로킹하지 않는다
if (bufferLock.tryEnter()) {              // 잠금을 '시도만'
    flushDeferredRecordingBlocks(...);    // 임시버퍼에 쌓인 것 합류
    copyInputBlockToRecordingBuffer(...); // 정상 녹음
    bufferLock.exit();
} else {
    appendDeferredRecordingBlock(...);    // 락 실패 → 임시버퍼로 (안 멈춤)
}

또 하나의 백미는 비동기 콜백 안전장치 3종 세트다. 네트워크 응답이 늦게 도착했을 때 UI가 이미 닫혔거나 사용자가 탭을 바꿨을 수 있다. 이를 위해 ① SafePointer(에디터가 파괴됐는지 검사), ② weak_ptr<atomic<bool>>(살아있는지 플래그), ③ 단조 증가 토큰(GenerationAsyncToken — 옛 작업의 늦은 응답을 무시)을 함께 쓴다. "늦게 온 답이 엉뚱한 곳에 꽂히는" use-after-free·stale response 사고를 막는 정석이다.

이 프로젝트 특유의 관례: 모든 오디오 교환을 파일로 한다(~/Documents/gary4juce/). 녹음은 myBuffer.wav, 결과는 myOutput.wav로 저장하고, 백엔드 출력 샘플레이트가 호스트와 다르면 LagrangeInterpolator로 리샘플해 맞춘다. 타임라인 드래그도 임시 파일을 만들어 OS 네이티브 드래그로 DAW에 넘긴다.

설계 패턴
논블로킹 + 폴백 버퍼 (lock-free 우선)
실시간 오디오 콜백에서는 절대 멈추면 안 된다. 그래서 잠금을 "시도(tryEnter)"만 하고, 실패하면 데이터를 짧은 임시 버퍼에 담아뒀다 나중에 합류시킨다. "지금 못 받으면 잠깐 메모지에 적어뒀다 이따 옮기는" 방식. 오디오 글리치를 막는 핵심 기교.
설계 패턴
폴링 기반 장기 작업 (submit → session_id → poll)
AI 생성은 수 초~수십 초 걸린다. 그래서 한 번에 답을 기다리지 않고, ① 작업을 제출해 접수증(session_id)을 받고 ② 주기적으로 "다 됐어?"라고 물어(poll) 진행률·결과를 받는다. 음식점 진동벨처럼, 맡겨두고 상태만 확인하는 구조.

5디렉토리 구조 해부

어디부터 열어봐야 하나.

핵심은 Source/ 안에 있다. 거대한 에디터 클래스를 기능별 .cpp로 쪼개 두었고(같은 클래스, 여러 파일), 모델별 UI는 별도 컴포넌트로 떼어냈다. 처음엔 PluginProcessor(오디오)와 PluginEditor(UI·네트워킹) 두 축만 잡으면 된다.

gary4juce/ ├── gary4juce.jucer ★ Projucer 프로젝트 정의 (모듈·포맷·빌드 단일 진실원) ├── README.md (517줄) 모델 7종·백엔드·설치·빌드·라이선스 총정리 ├── CAREY.md / SA3.md ACE-Step / Stable Audio 3 실사용 가이드 ├── LICENSE AGPL-3.0-only ├── docs/ │ ├── lmms-compatibility.md LMMS 호환 실패 기록 │ └── updates/gary4juce/ 인앱 업데이트 체크용 JSON └── Source/ ├── PluginProcessor.{h,cpp} ★ AudioProcessor: 녹음·재생·상태·BPM ├── PluginEditor.{h,cpp} ★ 메인 에디터(7,465줄) — UI + 네트워킹 허브 ├── PluginEditor.Backend.cpp 백엔드 토글·로컬 health 폴링·stall 처리 ├── PluginEditor.Jerry.cpp Jerry/SA3/Foundation 요청 (2,084줄) ├── PluginEditor.Carey.cpp Carey 4모드 요청 (2,594줄) ├── PluginEditor.Terry.cpp / .Foundation.cpp / .Updates.cpp ├── Components/ │ ├── Base/ 공통 룩앤필 버튼·콤보·슬라이더 │ ├── Gary/ Jerry/ Carey/ Terry/ Darius/ Foundation/ 모델별 UI 패널 │ └── AudioSelectionDialog.{h,cpp} 긴 오디오 구간 선택 모달 └── Utils/ ├── Theme.h 색·폰트·레이아웃 상수 (블랙+레드 브랜드) ├── CustomLookAndFeel.{h,cpp} · IconFactory.{h,cpp} └── BarTrim.h 마디 경계 크롭 유틸
위치역할
gary4juce.jucer빌드의 출발점. 어떤 JUCE 모듈·플러그인 포맷·빌드 도구를 쓰는지 다 여기. Projucer로 열어 프로젝트를 생성.
PluginProcessor.cpp오디오의 심장. processBlock(실시간 콜백), 녹음/재생 버퍼, 호스트 BPM 읽기, 상태 영속화. 스레딩 학습의 핵심 파일.
PluginEditor.cppUI 골격 + 모든 네트워킹의 허브(7,465줄). 제출·폴링·콜백 안전장치가 여기. 가장 큰 파일.
PluginEditor.<모델>.cpp같은 에디터 클래스를 모델별 .cpp로 분할. 각 모델의 요청 본문(JSON) 작성 로직.
Components/<모델>/모델별 UI 패널을 별도 컴포넌트로 분리. unique_ptr로 보유, 탭 enum으로 전환.
Utils/BarTrim.h생성 오디오를 마디 경계로 자르는 유틸. 파일 쓰기 완료 대기·무음 감지 같은 실전 디테일.

6학습 포인트 (기술별)

이 레포에서 배울 만한 것 + 어느 파일을 펴면 되는지.

포인트 1 · JUCE 플러그인 기초

Processor와 Editor를 나누는 철학

AudioProcessor(오디오·상태)와 AudioProcessorEditor(UI)를 분리하고, 오래 유지할 상태는 Processor에 두는 설계를 본다. getStateInformation으로 XML 상태를 DAW 프로젝트에 영속화하고 버전 마이그레이션까지 처리. 빈 JUCE 플러그인에 "녹음→WAV 저장"만 붙여보는 게 좋은 첫 실습.

포인트 2 · 실시간 오디오 스레딩

오디오 콜백에서 절대 멈추지 않는 법 (이 레포 최고 교보재)

processBlock에서 mutex를 쓰지 않고 atomic + tryEnter() + 폴백 버퍼로 글리치를 막는다. std::memory_order_acquire/release의 실제 용례, shared_ptr의 원자적 교체로 새 데이터를 오디오 스레드에 안전히 넘기는 패턴을 코드로 익힌다.

포인트 3 · 비동기 네트워킹 + UI 생명주기

늦게 온 응답이 사고를 일으키지 않게

Thread::launch 워커 → MessageManager::callAsync 복귀의 정석과, SafePointer+weak_ptr+증가 토큰의 안전장치 3종을 본다. "생성 중 탭을 바꾸면 결과가 엉뚱한 탭에 꽂히는" 문제를 토큰 검사로 막는 방식이 백미. 일부러 토큰 검사를 빼고 버그를 재현해보면 이해가 빠르다.

포인트 4 · AI 모델 서빙 통합(클라이언트 관점)

무거운 추론을 HTTP로 분리하는 아키텍처

모델 추론을 플러그인에서 떼어내 별도 프로세스(HTTP)로 두는 설계의 장단점, 오디오를 base64 JSON으로 실어 보내는 방식의 한계, 다중 모델을 포트로 구분해 운영하는 법을 본다. warmup(cold-start)·stall·queue 같은 실제 서빙의 너저분한 현실을 코드가 어떻게 받아내는지가 압권.

포인트 5 · 거대 클래스 다루기 + 샘플레이트

모놀리식을 기능별 파일로 쪼개고, SR 불일치를 메우기

7,465줄짜리 에디터를 같은 클래스의 여러 .cpp로 분할하고 모델별 UI를 컴포넌트로 떼는 구조를 본다. 또 백엔드 출력(예 48kHz)과 호스트(예 44.1kHz)의 샘플레이트가 다를 때 LagrangeInterpolator로 리샘플하는 실전 처리를 익힌다.

예컨대 SA3 생성 요청은 이런 JSON으로 나간다 — 프롬프트에 BPM·키를 자동으로 붙이고, 켜진 LoRA만 배열로 싣는다:

// PluginEditor.Jerry.cpp — SA3 /generate 요청 본문(요약)
prompt   = userPrompt + ", 120 bpm"   // BPM/키 자동 첨부
steps    = 8                          // 추론 스텝(품질↔속도)
cfg_scale= 1.0                        // 프롬프트 충실도
seed     = -1                         // -1=랜덤, 응답에 쓰인 seed 반환(재현용)
loras    = [{ name, strength(0~2) }]  // 강도 0 초과만 실음

7하드웨어 / 시스템 요구사항

플러그인은 가볍고, 백엔드(GPU)는 무겁다.

플러그인 자체는 매우 가볍다 — VST3/AU를 지원하는 DAW와 인터넷(원격 백엔드 사용 시)이면 충분하다. 무게는 전부 AI 백엔드 쪽에 있고, 그건 원격(무료)으로 우회할 수 있다.

항목요구사항
플러그인VST3/AU 지원 DAW. 가벼움. 코드사이닝 없음 → Windows Defender 경고 가능.
OS / 빌드Windows(VST3·VS2022) / macOS(AU+VST3·Xcode). LMMS 미지원.
호스트 DAWAU: GarageBand·Logic / VST3: Ableton·FL·Reaper·Cubase·Bitwig.
백엔드(원격)g4l.thecollabagepatch.com 사용 시 내 GPU 불필요(단, spot VM이라 가끔 죽음).
백엔드(localhost)최소 10GB+ VRAM, 권장 16GB+. Darius(Magenta RT)는 24GB+ 권장.
JUCE 소스레포에 미포함. JUCE 8.0.8을 별도로 받아 Projucer로 프로젝트 재생성 필요.
비유

gary4juce는 '요리를 외주 주는 주방장'이다. 플러그인(주방장)은 재료를 다듬고(녹음) 주문서를 쓰고(요청) 완성된 요리를 차린다(재생)만 한다. 실제 조리(AI 추론)는 멀리 있는 거대한 주방(GPU 백엔드)이 맡는다. 그래서 내 컴퓨터(주방장)는 가벼워도 되지만, 주방(GPU)은 따로 있어야 — 또는 남의 공용 주방(원격)을 빌려야 — 한다.

8직접 해볼 수 있는 실습 과제

읽기만 하지 말고 손에 익히는 단계.

실습 1

빌드해서 원격 백엔드로 첫 생성 난이도 ★☆☆ 입문

레포를 받아 Projucer로 .jucer를 열고 VS2022/Xcode로 Release 빌드 → DAW에 올린 뒤, 원격 백엔드로 Jerry 루프를 하나 만들어 타임라인에 드래그한다. JUCE 빌드 파이프라인을 끝까지 한 번 통과하는 게 목표.

실습 2

녹음 버퍼 길이 바꿔 동작 관찰 난이도 ★☆☆ 입문

processBlock의 녹음 길이(180초)와 폴백 버퍼(2초) 상수를 바꿔보고, 작은 호스트 버퍼에서 "deferred 버퍼 오버플로" 로그가 뜨는 조건을 만들어 관찰한다. 실시간 오디오의 제약을 몸으로 느끼는 단계.

실습 3

가짜 백엔드로 전체 round-trip 재현 난이도 ★★☆ 중급

Python(FastAPI)으로 /health, /api/juce/process_audio(즉시 session_id 반환), /poll_status/{id}(진행률 올리다 테스트 WAV를 base64로 반환) 세 개만 만들어 localhost(8000)에 띄운다. 플러그인을 붙여 제출→폴링→재생 전 과정을 GPU 없이 재현.

실습 4

요청 파라미터 UI로 노출하기 난이도 ★★☆ 중급

SA3 요청 본문에 있지만 UI엔 없는 값(예: per-LoRA interval)을 슬라이더로 추가하고, JSON에 실어 보내도록 PluginEditor.Jerry.cpp를 확장한다. "UI 컨트롤 → 요청 본문 필드"의 배선을 직접 깔아보는 연습.

실습 5

새 '모델 탭'을 처음부터 배선 난이도 ★★★ 고급

탭 enum 추가 → 새 XxxUI 컴포넌트 → ActiveOp 항목 → getServiceUrl 라우팅 → 제출/폴링 함수 → 상태 영속화(getStateInformation)까지, 한 모델을 끝에서 끝까지 연결한다. 이 플러그인의 전체 구조를 손으로 꿰는 종합 실습.

실습 6

콜백 안전장치 제거 후 버그 재현 난이도 ★★★ 고급

GenerationAsyncToken 검사를 일부러 빼고, 생성 도중 탭을 빠르게 전환해 "늦게 온 응답이 엉뚱한 탭에 꽂히는" stale response 버그를 재현한 뒤 다시 복구한다. 비동기 안전장치가 왜 필요한지 가장 확실히 배우는 방법.

9관련 기술 심화 학습 로드맵

한 주씩 따라가는 6주 계획.

주차주제학습 자료
1주차JUCE 기초 + 빈 플러그인 빌드JUCE 튜토리얼 · Projucer · gary4juce.jucer + 실습 1
2주차AudioProcessor·processBlock·상태 영속화PluginProcessor.cpp + 실습 2
3주차실시간 오디오 스레딩 — atomic·lock-free·메모리 순서PluginProcessor.cpp 녹음 로직 · C++ 동시성 자료
4주차비동기 네트워킹 + 콜백 안전장치PluginEditor.cpp 제출/폴링 · 실습 3
5주차AI 음악 모델 이해(MusicGen·Stable Audio)Audiocraft · stable-audio-tools 문서 + 실습 4
6주차구조 확장 — 새 모델 탭·요청/응답 스키마 설계PluginEditor.<모델>.cpp · Components/ + 실습 5·6

10핵심 키워드 사전

본문에 나온 용어 빠른 참조.

용어의미
DAW디지털 오디오 워크스테이션. 음악을 녹음·편집·믹싱하는 프로그램(Ableton·FL·Logic).
VST3 / AU / Standalone플러그인 규격(스타인버그/애플)과 독립 실행 형태. 하나의 JUCE 프로젝트가 여러 형태로 빌드.
JUCE오디오 앱·플러그인용 C++ 프레임워크. 오디오·포맷·UI·네트워킹 제공(여기 8.0.8).
Projucer / .jucerJUCE 프로젝트 생성기와 그 설정 파일(모듈·포맷·빌드 익스포트).
processBlock플러그인의 실시간 오디오 콜백. 멈춤·메모리 할당 금지 구역.
recording / deferred buffer입력을 모으는 메인 버퍼(180초)와, 락 경합 시 임시로 받는 폴백 버퍼(2초).
샘플레이트 / 리샘플초당 샘플 수. 백엔드 출력과 호스트 SR이 다르면 LagrangeInterpolator로 변환.
base64 audio바이너리 WAV를 텍스트로 인코딩해 JSON에 실어 HTTP 전송.
session_id / polling비동기 추론 작업 식별자. 제출 후 /poll_status/{id}를 3초마다 GET해 결과 수신.
warmup / cold start모델·서버가 처음 깨어나며 가중치를 로딩하는 구간(최대 8분 유예).
MusicGen (gary)Meta Audiocraft의 음악 생성/이어붙이기 모델.
Stable Audio 3 / Open (sa3 / jerry)Stability AI의 text-to-audio 모델. SA3는 변형·이어붙이기·LoRA·seed recall 지원.
LoRA작은 보조 가중치로 특정 스타일/음색을 주입(강도 0~2, 여러 개 동시).
seed recall랜덤 생성 후 사용된 seed를 응답으로 돌려줘 같은 결과를 재현.
cfg_scale / steps프롬프트 충실도 / 추론 스텝 수. 생성 품질·성격을 조절.
ACE-Step (carey)가사·다국어 보컬 생성 + stem 추출/cover 모델.
SafePointer / weak_ptr / 토큰늦게 온 비동기 응답이 파괴된 UI·옛 작업에 꽂히는 사고를 막는 안전장치 3종.

11참고 링크