Add CLAUDE.md context file for Claude Code
Browse files
CLAUDE.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# PluginBridge β Claude Code Context
|
| 2 |
+
|
| 3 |
+
## What This Is
|
| 4 |
+
A JUCE-based VST3/AU plugin that:
|
| 5 |
+
1. Hosts any third-party VST3/AU plugin inside itself (audio passes through)
|
| 6 |
+
2. Exposes ALL hosted plugin parameters via a local MCP server (port 16620)
|
| 7 |
+
3. Provides real-time audio analysis (LUFS, FFT bands, stereo width)
|
| 8 |
+
4. Any AI that speaks MCP (Claude Code, Codex CLI, Gemini CLI) can control any plugin
|
| 9 |
+
|
| 10 |
+
## Architecture (Single Plugin Host, Not a Graph)
|
| 11 |
+
```
|
| 12 |
+
PluginBridgeProcessor (AudioProcessor β the outer VST3/AU shell)
|
| 13 |
+
βββ HostedPluginManager β loads ONE inner VST3/AU, enumerates params
|
| 14 |
+
βββ McpServer (httplib) β JSON-RPC 2.0 on http://127.0.0.1:16620/mcp
|
| 15 |
+
βββ AudioAnalyser β LUFS + 7-band FFT + stereo width in processBlock
|
| 16 |
+
βββ processBlock():
|
| 17 |
+
buffer β analyser.process(buffer)
|
| 18 |
+
β hostedPlugin->processBlock(buffer, midi)
|
| 19 |
+
β output
|
| 20 |
+
```
|
| 21 |
+
|
| 22 |
+
## Build System
|
| 23 |
+
- **JUCE 8** via CMake (git submodule at `/JUCE`)
|
| 24 |
+
- **cpp-httplib** β single header `libs/httplib.h` (MIT)
|
| 25 |
+
- **nlohmann/json** β single header `libs/json.hpp` (MIT)
|
| 26 |
+
- **LUFSMeter** β 4 files in `Source/LufsMeter/` (MIT, from klangfreund/LUFSMeter)
|
| 27 |
+
- Targets: VST3 + AU, macOS (Xcode) + Windows (MSVC)
|
| 28 |
+
|
| 29 |
+
## MCP Protocol
|
| 30 |
+
- Transport: Streamable HTTP (NOT stdio β we're inside a DAW process)
|
| 31 |
+
- Endpoint: `POST http://127.0.0.1:16620/mcp`
|
| 32 |
+
- Wire format: JSON-RPC 2.0
|
| 33 |
+
- Handshake: `initialize` β `notifications/initialized` β then tools/list, tools/call
|
| 34 |
+
- 5 tools only: `list_plugins`, `search_param`, `get_params`, `set_params`, `get_analysis`
|
| 35 |
+
|
| 36 |
+
## Key JUCE APIs (Correct, Verified)
|
| 37 |
+
- `addDefaultFormatsToManager(formatManager)` β NOT deprecated `addDefaultFormats()`
|
| 38 |
+
- `formatManager.createPluginInstanceAsync(desc, sr, bs, callback)` β ALWAYS async
|
| 39 |
+
- `instance->enableAllBuses()` β MUST call before using
|
| 40 |
+
- `plugin->getParameters()` β `Array<AudioProcessorParameter*>`
|
| 41 |
+
- Cast to `AudioPluginInstance::HostedParameter*` for `getParameterID()` (stable ID)
|
| 42 |
+
- `param->beginChangeGesture()` / `setValueNotifyingHost(val)` / `endChangeGesture()`
|
| 43 |
+
- `juce::dsp::FFT` for spectral analysis (NOT KissFFT, NOT Gist β those are GPL)
|
| 44 |
+
|
| 45 |
+
## Design Laws
|
| 46 |
+
- Never return all parameters β search first, fetch by ID
|
| 47 |
+
- Delta only after param changes
|
| 48 |
+
- Single-line compact responses (numbers only)
|
| 49 |
+
- Batch operations (set 10 params in one call)
|
| 50 |
+
- Silence detection (no analysis if RMS < -60dB)
|
| 51 |
+
- Target: <2,000 tokens per full mixing session
|
| 52 |
+
|
| 53 |
+
## Thread Safety Rules
|
| 54 |
+
- HTTP handlers run on httplib's thread pool β NOT audio thread
|
| 55 |
+
- Use `std::atomic<float>` for analysis values queried by HTTP
|
| 56 |
+
- Use `CriticalSection` / `ScopedLock` for plugin hot-swap
|
| 57 |
+
- Never call `getValue()` directly from HTTP thread β read from atomic cache
|
| 58 |
+
- `httplib::Server` lifecycle: constructor starts thread, destructor calls stop()+join()
|
| 59 |
+
|
| 60 |
+
## Sprint Order
|
| 61 |
+
1. **Sprint 1**: Empty plugin shell + httplib server responding to curl
|
| 62 |
+
2. **Sprint 2**: Host Pro-Q 4, route audio, enumerate params
|
| 63 |
+
3. **Sprint 3**: MCP JSON-RPC dispatch, all 5 tools working from Claude Code
|
| 64 |
+
4. **Sprint 4**: Audio analysis (LUFS, FFT bands, stereo, True Peak)
|
| 65 |
+
|
| 66 |
+
## What NOT To Do
|
| 67 |
+
- Don't use `AudioProcessorGraph` β we host ONE plugin, not a graph
|
| 68 |
+
- Don't use `AudioPluginHost`'s settings file β use runtime file picker
|
| 69 |
+
- Don't fork `getdunne/juce-plugin-wrapper` β dead, GPL, JUCE 6
|
| 70 |
+
- Don't use Gist or Sound-Analyser code β GPL license
|
| 71 |
+
- Don't use stdio MCP transport β plugin is inside DAW, not a subprocess
|
| 72 |
+
- Don't use `getParameter(int)` / `setParameter(int, float)` β deprecated, asserts
|
| 73 |
+
|
| 74 |
+
## Questions Before Building (Ask Adi)
|
| 75 |
+
1. macOS only for now, or Windows too? (affects CMake targets + code signing)
|
| 76 |
+
2. Do you have a JUCE license, or are we building under GPL for now?
|
| 77 |
+
3. Where on your Mac should the built .vst3 be installed? (default: ~/Library/Audio/Plug-Ins/VST3/)
|
| 78 |
+
4. Which plugin should we test with first? (Pro-Q 4 assumed β confirm)
|
| 79 |
+
5. Your Xcode version? (need 14+ for JUCE 8)
|
| 80 |
+
|
| 81 |
+
## Repo Structure
|
| 82 |
+
```
|
| 83 |
+
pluginbridge/
|
| 84 |
+
βββ CLAUDE.md β this file (Claude Code reads automatically)
|
| 85 |
+
βββ ROADMAP.md β full technical roadmap with code samples
|
| 86 |
+
βββ CMakeLists.txt β (to be created)
|
| 87 |
+
βββ JUCE/ β git submodule (to be added locally)
|
| 88 |
+
βββ libs/
|
| 89 |
+
β βββ httplib.h
|
| 90 |
+
β βββ json.hpp
|
| 91 |
+
βββ Source/
|
| 92 |
+
βββ PluginBridgeProcessor.h/.cpp
|
| 93 |
+
βββ PluginBridgeEditor.h/.cpp
|
| 94 |
+
βββ HostedPluginManager.h/.cpp
|
| 95 |
+
βββ McpServer.h/.cpp
|
| 96 |
+
βββ AudioAnalyser.h/.cpp
|
| 97 |
+
βββ LufsMeter/
|
| 98 |
+
βββ Ebu128LoudnessMeter.h/.cpp
|
| 99 |
+
βββ SecondOrderIIRFilter.h/.cpp
|
| 100 |
+
```
|