Initial commit
This commit is contained in:
886
commands/analyze-performance.md
Normal file
886
commands/analyze-performance.md
Normal file
@@ -0,0 +1,886 @@
|
||||
---
|
||||
argument-hint: "[target] [--profiler=<tool>] [--benchmark] [--report]"
|
||||
description: "Profile plugin performance with Instruments, perf, VTune, Tracy to identify bottlenecks and optimize DSP algorithms"
|
||||
allowed-tools: Bash, Read, Write, AskUserQuestion
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
# /analyze-performance - Performance Profiling and Optimization
|
||||
|
||||
Profile your JUCE plugin's performance to identify bottlenecks, optimize DSP algorithms, and ensure efficient CPU usage across different scenarios.
|
||||
|
||||
## Overview
|
||||
|
||||
This command guides you through comprehensive performance analysis using profiling tools, benchmarking, and optimization strategies. It helps identify hot paths in DSP code, memory bottlenecks, and inefficient algorithms.
|
||||
|
||||
## Syntax
|
||||
|
||||
```bash
|
||||
/analyze-performance [target] [--profiler=<tool>] [--benchmark] [--report]
|
||||
```
|
||||
|
||||
### Arguments
|
||||
|
||||
- `target` (optional): What to profile - `dsp`, `ui`, `full`, or `specific` (default: `dsp`)
|
||||
- `--profiler=<tool>`: Profiler to use - `instruments`, `perf`, `vtune`, `tracy`, or `auto` (default: `auto`)
|
||||
- `--benchmark`: Run performance benchmarks and compare against baseline
|
||||
- `--report`: Generate detailed performance report with recommendations
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Profile DSP code with platform default profiler
|
||||
/analyze-performance dsp
|
||||
|
||||
# Profile entire plugin with Instruments (macOS)
|
||||
/analyze-performance full --profiler=instruments
|
||||
|
||||
# Run benchmarks and generate report
|
||||
/analyze-performance dsp --benchmark --report
|
||||
|
||||
# Profile UI rendering performance
|
||||
/analyze-performance ui --profiler=instruments
|
||||
```
|
||||
|
||||
## Instructions
|
||||
|
||||
### Step 1: Pre-Profiling Setup
|
||||
|
||||
**@build-engineer** - Prepare optimized build with profiling symbols.
|
||||
|
||||
1. **Build with Release optimization + debug symbols:**
|
||||
|
||||
macOS (Xcode):
|
||||
```cmake
|
||||
# CMakeLists.txt
|
||||
if(APPLE)
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo)
|
||||
# Disable stripping for profiling
|
||||
set(CMAKE_XCODE_ATTRIBUTE_STRIP_INSTALLED_PRODUCT NO)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DEPLOYMENT_POSTPROCESSING NO)
|
||||
endif()
|
||||
```
|
||||
|
||||
Build:
|
||||
```bash
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
cmake --build build --config RelWithDebInfo
|
||||
```
|
||||
|
||||
Windows (Visual Studio):
|
||||
```bash
|
||||
cmake -B build
|
||||
cmake --build build --config RelWithDebInfo
|
||||
```
|
||||
|
||||
Linux:
|
||||
```bash
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_CXX_FLAGS="-g -O2"
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
2. **Verify optimizations are enabled:**
|
||||
```bash
|
||||
# macOS: Check optimization flags
|
||||
xcrun otool -v -s __TEXT __text build/MyPlugin.vst3/Contents/MacOS/MyPlugin | grep -A 5 "optimization"
|
||||
|
||||
# Linux: Check binary for debug symbols and optimization
|
||||
objdump -d build/MyPlugin.vst3 | head -50
|
||||
```
|
||||
|
||||
3. **Install profiling tools:**
|
||||
|
||||
**macOS:**
|
||||
```bash
|
||||
# Instruments comes with Xcode
|
||||
xcode-select --install
|
||||
|
||||
# Optional: Tracy profiler
|
||||
brew install tracy
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
```powershell
|
||||
# Intel VTune (recommended)
|
||||
# Download from: https://www.intel.com/content/www/us/en/developer/tools/oneapi/vtune-profiler.html
|
||||
|
||||
# Or Visual Studio Profiler (included with VS)
|
||||
```
|
||||
|
||||
**Linux:**
|
||||
```bash
|
||||
# perf (Linux perf tool)
|
||||
sudo apt install linux-tools-common linux-tools-generic
|
||||
|
||||
# Tracy profiler
|
||||
sudo apt install tracy-profiler
|
||||
|
||||
# OR build from source
|
||||
git clone https://github.com/wolfpld/tracy
|
||||
cd tracy/profiler
|
||||
make
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2: DSP Performance Profiling
|
||||
|
||||
**@dsp-engineer** + **@test-automation-engineer** - Identify DSP bottlenecks.
|
||||
|
||||
### Profile Audio Processing
|
||||
|
||||
#### macOS - Using Instruments
|
||||
|
||||
1. **Launch Instruments with plugin:**
|
||||
```bash
|
||||
# Open standalone plugin in Instruments
|
||||
open -a Instruments
|
||||
|
||||
# Or profile in DAW:
|
||||
# 1. Launch Instruments
|
||||
# 2. Choose "Time Profiler" template
|
||||
# 3. Click Record
|
||||
# 4. In dropdown, select DAW process (e.g., "Logic Pro")
|
||||
# 5. Load plugin in DAW and play audio
|
||||
```
|
||||
|
||||
2. **Time Profiler Configuration:**
|
||||
- Template: Time Profiler
|
||||
- Sample Frequency: 1ms (high resolution)
|
||||
- Record Waiting Threads: OFF (focus on CPU time)
|
||||
- High Frequency: ON
|
||||
|
||||
3. **Record profiling session:**
|
||||
- Click Record in Instruments
|
||||
- Load plugin in standalone app or DAW
|
||||
- Play test audio for 30-60 seconds
|
||||
- Include various parameter automations
|
||||
- Stop recording
|
||||
|
||||
4. **Analyze results:**
|
||||
- Switch to "Call Tree" view
|
||||
- Enable filters:
|
||||
- ✅ Separate by Thread
|
||||
- ✅ Invert Call Tree
|
||||
- ✅ Hide System Libraries
|
||||
- Look for hot functions in your code
|
||||
- **Focus on:** `processBlock()`, DSP algorithm functions
|
||||
|
||||
5. **Identify bottlenecks:**
|
||||
- Functions taking > 5% of CPU time are candidates for optimization
|
||||
- Look for:
|
||||
- Unexpected memory allocations (`malloc`, `new`)
|
||||
- Expensive math operations (use vectorization)
|
||||
- Inefficient loops
|
||||
- Cache misses (scattered memory access)
|
||||
|
||||
**Example Instruments Output:**
|
||||
```
|
||||
Symbol Name % Time
|
||||
MyPlugin::processBlock() 45.2%
|
||||
MyFilter::processSample() 28.3%
|
||||
std::pow() 15.1% ⚠️ Expensive!
|
||||
MyFilter::updateCoefficients() 13.2%
|
||||
MyDistortion::process() 16.9%
|
||||
```
|
||||
|
||||
**Red Flags:**
|
||||
- `std::pow()`, `std::sin()`, `std::cos()` in inner loops → Use lookup tables or approximations
|
||||
- Memory allocations → Pre-allocate in `prepareToPlay()`
|
||||
- Virtual function calls in hot path → Consider static polymorphism
|
||||
|
||||
---
|
||||
|
||||
#### Windows - Using Visual Studio Profiler
|
||||
|
||||
1. **Start profiling:**
|
||||
- Open Visual Studio
|
||||
- Debug → Performance Profiler
|
||||
- Select: CPU Usage
|
||||
- Start profiling
|
||||
- Launch DAW and load plugin
|
||||
- Play audio for 60 seconds
|
||||
- Stop profiling
|
||||
|
||||
2. **Analyze:**
|
||||
- View "Hot Path"
|
||||
- Check "Functions" view sorted by "Total CPU %"
|
||||
- Drill into `processBlock()`
|
||||
|
||||
3. **Generate report:**
|
||||
- File → Export Report
|
||||
- Save as `performance-analysis-[date].diagsession`
|
||||
|
||||
---
|
||||
|
||||
#### Linux - Using perf
|
||||
|
||||
1. **Record performance data:**
|
||||
```bash
|
||||
# Profile specific process (find PID of DAW or standalone)
|
||||
perf record -F 999 -g -p <PID>
|
||||
|
||||
# Or profile command:
|
||||
perf record -F 999 -g ./build/MyPlugin_Standalone
|
||||
|
||||
# Play audio for 60 seconds, then Ctrl+C to stop
|
||||
```
|
||||
|
||||
2. **View results:**
|
||||
```bash
|
||||
# Interactive TUI
|
||||
perf report
|
||||
|
||||
# Generate flame graph (requires flamegraph tools)
|
||||
git clone https://github.com/brendangregg/FlameGraph
|
||||
perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > flamegraph.svg
|
||||
open flamegraph.svg # or xdg-open on Linux
|
||||
```
|
||||
|
||||
3. **Interpret flame graph:**
|
||||
- Width = CPU time
|
||||
- Look for wide sections in your code
|
||||
- Drill down into `processBlock()` stack frames
|
||||
|
||||
---
|
||||
|
||||
### Common Performance Issues and Fixes
|
||||
|
||||
#### Issue 1: Expensive Transcendental Functions
|
||||
|
||||
**Symptom:** `std::sin()`, `std::cos()`, `std::pow()` show up in profiler.
|
||||
|
||||
**Solution:** Use lookup tables or polynomial approximations.
|
||||
|
||||
**Example:**
|
||||
```cpp
|
||||
// ❌ Slow: Direct call in processBlock
|
||||
float sine = std::sin(phase);
|
||||
|
||||
// ✅ Fast: Lookup table
|
||||
class SineLUT {
|
||||
static constexpr int tableSize = 2048;
|
||||
std::array<float, tableSize> table;
|
||||
|
||||
public:
|
||||
SineLUT() {
|
||||
for (int i = 0; i < tableSize; ++i)
|
||||
table[i] = std::sin(2.0 * M_PI * i / tableSize);
|
||||
}
|
||||
|
||||
float lookup(float phase) const {
|
||||
float index = phase * tableSize;
|
||||
int i0 = static_cast<int>(index) % tableSize;
|
||||
int i1 = (i0 + 1) % tableSize;
|
||||
float frac = index - std::floor(index);
|
||||
return table[i0] + frac * (table[i1] - table[i0]);
|
||||
}
|
||||
};
|
||||
|
||||
// Use in processBlock:
|
||||
float sine = sineLUT.lookup(phase);
|
||||
```
|
||||
|
||||
**Speedup:** 5-10x faster
|
||||
|
||||
---
|
||||
|
||||
#### Issue 2: Inefficient Memory Access Patterns
|
||||
|
||||
**Symptom:** High cache miss rate, poor vectorization.
|
||||
|
||||
**Solution:** Structure-of-arrays instead of array-of-structures.
|
||||
|
||||
**Example:**
|
||||
```cpp
|
||||
// ❌ Poor cache locality (AoS)
|
||||
struct Voice {
|
||||
float frequency, amplitude, phase;
|
||||
};
|
||||
std::vector<Voice> voices;
|
||||
|
||||
for (auto& voice : voices) {
|
||||
voice.phase += voice.frequency;
|
||||
output += voice.amplitude * std::sin(voice.phase);
|
||||
}
|
||||
|
||||
// ✅ Better cache locality (SoA)
|
||||
struct VoiceBank {
|
||||
std::vector<float> frequencies;
|
||||
std::vector<float> amplitudes;
|
||||
std::vector<float> phases;
|
||||
};
|
||||
|
||||
for (int i = 0; i < voices.phases.size(); ++i) {
|
||||
voices.phases[i] += voices.frequencies[i];
|
||||
output += voices.amplitudes[i] * std::sin(voices.phases[i]);
|
||||
}
|
||||
```
|
||||
|
||||
**Benefit:** Better SIMD vectorization, fewer cache misses.
|
||||
|
||||
---
|
||||
|
||||
#### Issue 3: Unnecessary Branching
|
||||
|
||||
**Symptom:** Unpredictable branches in inner loops.
|
||||
|
||||
**Solution:** Branchless code or precompute decisions.
|
||||
|
||||
**Example:**
|
||||
```cpp
|
||||
// ❌ Branch in inner loop
|
||||
for (int i = 0; i < numSamples; ++i) {
|
||||
if (bypassEnabled)
|
||||
output[i] = input[i];
|
||||
else
|
||||
output[i] = process(input[i]);
|
||||
}
|
||||
|
||||
// ✅ Branchless or separate loops
|
||||
if (bypassEnabled) {
|
||||
std::copy(input, input + numSamples, output);
|
||||
} else {
|
||||
for (int i = 0; i < numSamples; ++i)
|
||||
output[i] = process(input[i]);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Issue 4: Virtual Function Calls
|
||||
|
||||
**Symptom:** Virtual dispatch overhead in hot path.
|
||||
|
||||
**Solution:** Static polymorphism (templates) or function pointers.
|
||||
|
||||
**Example:**
|
||||
```cpp
|
||||
// ❌ Virtual function call per sample
|
||||
class Filter {
|
||||
public:
|
||||
virtual float process(float input) = 0;
|
||||
};
|
||||
|
||||
// ✅ Template-based static polymorphism
|
||||
template<typename FilterType>
|
||||
class Processor {
|
||||
FilterType filter;
|
||||
public:
|
||||
void processBlock(float* buffer, int numSamples) {
|
||||
for (int i = 0; i < numSamples; ++i)
|
||||
buffer[i] = filter.process(buffer[i]); // Inlined!
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3: SIMD Optimization
|
||||
|
||||
**@dsp-engineer** - Leverage SIMD instructions for maximum performance.
|
||||
|
||||
### Identify Vectorization Opportunities
|
||||
|
||||
1. **Check if compiler vectorized loops:**
|
||||
|
||||
**macOS/Linux:**
|
||||
```bash
|
||||
# GCC/Clang vectorization report
|
||||
cmake -B build -DCMAKE_CXX_FLAGS="-O3 -fopt-info-vec"
|
||||
cmake --build build 2>&1 | grep vectorized
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
```powershell
|
||||
# MSVC vectorization report
|
||||
cmake -B build
|
||||
cmake --build build -- /p:CL="/Qvec-report:2"
|
||||
```
|
||||
|
||||
2. **Manual SIMD with JUCE:**
|
||||
|
||||
JUCE provides cross-platform SIMD abstractions:
|
||||
|
||||
```cpp
|
||||
#include <juce_dsp/juce_dsp.h>
|
||||
|
||||
// Example: Process 4 samples at once with SIMD
|
||||
void processBlock(juce::AudioBuffer<float>& buffer) {
|
||||
auto* channelData = buffer.getWritePointer(0);
|
||||
int numSamples = buffer.getNumSamples();
|
||||
|
||||
// Process in chunks of 4 (SSE/NEON)
|
||||
using SIMDFloat = juce::dsp::SIMDRegister<float>;
|
||||
constexpr int simdSize = SIMDFloat::size();
|
||||
|
||||
int i = 0;
|
||||
for (; i < numSamples - simdSize; i += simdSize) {
|
||||
auto simdInput = SIMDFloat::fromRawArray(channelData + i);
|
||||
auto simdOutput = simdInput * SIMDFloat(gain); // SIMD multiply
|
||||
simdOutput.copyToRawArray(channelData + i);
|
||||
}
|
||||
|
||||
// Handle remaining samples
|
||||
for (; i < numSamples; ++i) {
|
||||
channelData[i] *= gain;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. **Benchmark SIMD vs scalar:**
|
||||
```bash
|
||||
# Build with SIMD enabled
|
||||
cmake -B build-simd -DCMAKE_CXX_FLAGS="-O3 -march=native"
|
||||
cmake --build build-simd
|
||||
|
||||
# Compare performance (see Step 4 below)
|
||||
```
|
||||
|
||||
**Expected Speedup:** 2-4x for SIMD-friendly code.
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Performance Benchmarking
|
||||
|
||||
**@test-automation-engineer** - Quantify performance improvements.
|
||||
|
||||
### Create Benchmark Tests
|
||||
|
||||
```cpp
|
||||
// Tests/PerformanceBenchmark.cpp
|
||||
#include <benchmark/benchmark.h> // Google Benchmark
|
||||
#include "../Source/PluginProcessor.h"
|
||||
|
||||
static void BM_ProcessBlock(benchmark::State& state) {
|
||||
MyPluginProcessor processor;
|
||||
processor.setPlayConfigDetails(2, 2, 44100.0, 512);
|
||||
processor.prepareToPlay(44100.0, 512);
|
||||
|
||||
juce::AudioBuffer<float> buffer(2, 512);
|
||||
juce::MidiBuffer midi;
|
||||
|
||||
// Fill with test signal
|
||||
for (int ch = 0; ch < 2; ++ch)
|
||||
for (int i = 0; i < 512; ++i)
|
||||
buffer.setSample(ch, i, std::sin(2 * M_PI * 440 * i / 44100.0));
|
||||
|
||||
for (auto _ : state) {
|
||||
processor.processBlock(buffer, midi);
|
||||
benchmark::DoNotOptimize(buffer.getReadPointer(0));
|
||||
}
|
||||
|
||||
// Report CPU usage metric
|
||||
state.SetItemsProcessed(state.iterations() * 512);
|
||||
}
|
||||
|
||||
BENCHMARK(BM_ProcessBlock)->Iterations(10000);
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
```
|
||||
|
||||
### Run Benchmarks
|
||||
|
||||
```bash
|
||||
# Install Google Benchmark
|
||||
git clone https://github.com/google/benchmark.git
|
||||
cd benchmark
|
||||
cmake -E make_directory "build"
|
||||
cmake -E chdir "build" cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake --build "build" --config Release
|
||||
sudo cmake --build "build" --config Release --target install
|
||||
|
||||
# Build and run your benchmarks
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build --target PerformanceBenchmark
|
||||
./build/Tests/PerformanceBenchmark --benchmark_out=results.json --benchmark_out_format=json
|
||||
```
|
||||
|
||||
**Example Output:**
|
||||
```
|
||||
-----------------------------------------------------------------
|
||||
Benchmark Time CPU Iterations
|
||||
-----------------------------------------------------------------
|
||||
BM_ProcessBlock 1.23 ms 1.22 ms 571
|
||||
```
|
||||
|
||||
**Interpretation:**
|
||||
- 1.22 ms per block @ 512 samples = ~24% CPU at 44.1kHz (1.22ms / (512/44100 * 1000))
|
||||
- Goal: < 5% CPU (< 0.29 ms/block)
|
||||
|
||||
### Compare Before/After Optimization
|
||||
|
||||
```bash
|
||||
# Save baseline
|
||||
./build/Tests/PerformanceBenchmark > baseline.txt
|
||||
|
||||
# Make optimizations
|
||||
# ...
|
||||
|
||||
# Compare
|
||||
./build/Tests/PerformanceBenchmark > optimized.txt
|
||||
diff baseline.txt optimized.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 5: UI Performance Profiling
|
||||
|
||||
**@ui-engineer** - Ensure UI doesn't impact audio performance.
|
||||
|
||||
### Profile UI Rendering
|
||||
|
||||
1. **Check UI frame rate:**
|
||||
```cpp
|
||||
// Add to Editor
|
||||
class MyEditor : public juce::AudioProcessorEditor, private juce::Timer {
|
||||
void timerCallback() override {
|
||||
auto now = juce::Time::getMillisecondCounterHiRes();
|
||||
double fps = 1000.0 / (now - lastFrameTime);
|
||||
DBG("FPS: " << fps); // Should be 60fps
|
||||
lastFrameTime = now;
|
||||
repaint();
|
||||
}
|
||||
|
||||
double lastFrameTime = 0;
|
||||
};
|
||||
```
|
||||
|
||||
2. **Profile with Instruments (macOS):**
|
||||
- Use "Core Animation" template
|
||||
- Check for:
|
||||
- Dropped frames (should be 0)
|
||||
- Expensive drawing operations
|
||||
- Off-screen rendering
|
||||
|
||||
3. **Optimize UI:**
|
||||
- **Use `repaint()` only when needed** (not on every audio callback!)
|
||||
- **Coalesce repaints:**
|
||||
```cpp
|
||||
// ❌ Repaint on every parameter change (60 times/sec from audio thread!)
|
||||
parameterChanged(parameter, newValue) {
|
||||
repaint(); // BAD
|
||||
}
|
||||
|
||||
// ✅ Rate-limit repaints
|
||||
parameterChanged(parameter, newValue) {
|
||||
startTimer(16); // 60fps max
|
||||
}
|
||||
|
||||
timerCallback() {
|
||||
stopTimer();
|
||||
repaint();
|
||||
}
|
||||
```
|
||||
- **Cache rendered graphics:**
|
||||
```cpp
|
||||
juce::Image cachedBackground;
|
||||
|
||||
void paint(Graphics& g) {
|
||||
if (cachedBackground.isNull()) {
|
||||
cachedBackground = juce::Image(juce::Image::ARGB, getWidth(), getHeight(), true);
|
||||
Graphics cg(cachedBackground);
|
||||
drawComplexBackground(cg);
|
||||
}
|
||||
g.drawImageAt(cachedBackground, 0, 0);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Memory Profiling
|
||||
|
||||
**@test-automation-engineer** - Detect memory leaks and excessive allocations.
|
||||
|
||||
### macOS - Instruments Leaks
|
||||
|
||||
1. **Launch Instruments → Leaks template**
|
||||
2. **Record session** (load/unload plugin multiple times)
|
||||
3. **Check for leaks:**
|
||||
- Red flags = memory leaks
|
||||
- Click to see stack trace of allocation
|
||||
|
||||
### Linux - Valgrind
|
||||
|
||||
```bash
|
||||
# Profile standalone plugin
|
||||
valgrind --leak-check=full --track-origins=yes ./build/MyPlugin_Standalone
|
||||
|
||||
# Play audio, then quit
|
||||
# Check report for leaks
|
||||
```
|
||||
|
||||
### Windows - Visual Studio Memory Profiler
|
||||
|
||||
1. Debug → Performance Profiler → Memory Usage
|
||||
2. Take snapshots before and after loading plugin
|
||||
3. Compare snapshots for memory growth
|
||||
|
||||
### Check for Allocations in Audio Thread
|
||||
|
||||
Use `-fsanitize=address` (Clang/GCC):
|
||||
```bash
|
||||
cmake -B build -DCMAKE_CXX_FLAGS="-fsanitize=address -g"
|
||||
cmake --build build
|
||||
./build/Tests/MyPluginTests
|
||||
```
|
||||
|
||||
**Look for:** Allocations called from `processBlock()` - these are FORBIDDEN.
|
||||
|
||||
---
|
||||
|
||||
## Step 7: Advanced Profiling - Tracy
|
||||
|
||||
**@test-automation-engineer** - Use Tracy for frame-perfect profiling.
|
||||
|
||||
Tracy is a real-time profiler with nanosecond precision.
|
||||
|
||||
### Integrate Tracy
|
||||
|
||||
```cpp
|
||||
// CMakeLists.txt
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
tracy
|
||||
GIT_REPOSITORY https://github.com/wolfpld/tracy.git
|
||||
GIT_TAG v0.10
|
||||
)
|
||||
FetchContent_MakeAvailable(tracy)
|
||||
|
||||
target_link_libraries(MyPlugin PRIVATE TracyClient)
|
||||
target_compile_definitions(MyPlugin PRIVATE TRACY_ENABLE)
|
||||
```
|
||||
|
||||
### Add Tracy Zones
|
||||
|
||||
```cpp
|
||||
#include <tracy/Tracy.hpp>
|
||||
|
||||
void processBlock(AudioBuffer<float>& buffer, MidiBuffer& midi) {
|
||||
ZoneScoped; // Automatic profiling for this function
|
||||
|
||||
{
|
||||
ZoneScopedN("Filter Processing");
|
||||
filter.process(buffer);
|
||||
}
|
||||
|
||||
{
|
||||
ZoneScopedN("Distortion Processing");
|
||||
distortion.process(buffer);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Run Tracy
|
||||
|
||||
```bash
|
||||
# Launch Tracy profiler GUI
|
||||
tracy
|
||||
|
||||
# Run plugin in DAW
|
||||
# Tracy will automatically connect and show real-time profiling
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- Real-time visualization
|
||||
- Frame-by-frame analysis
|
||||
- Memory allocation tracking
|
||||
- Lock contention detection
|
||||
|
||||
---
|
||||
|
||||
## Step 8: Generate Performance Report
|
||||
|
||||
**@support-engineer** - Document findings and recommendations.
|
||||
|
||||
### Report Template
|
||||
|
||||
```markdown
|
||||
# Performance Analysis Report - MyPlugin v1.2.0
|
||||
|
||||
**Date:** 2024-05-15
|
||||
**Analyst:** @dsp-engineer
|
||||
**Platform:** macOS 14.5, Apple M1 Max
|
||||
|
||||
## Summary
|
||||
|
||||
CPU usage has been reduced from **8.2%** to **2.1%** (74% improvement) through targeted optimizations.
|
||||
|
||||
## Profiling Results
|
||||
|
||||
### Baseline (v1.1.0)
|
||||
- Single instance CPU: 8.2% @ 44.1kHz, 512 samples
|
||||
- 10 instances: 82% CPU (not sustainable)
|
||||
- Hot path: `std::pow()` in saturation curve (45% of CPU time)
|
||||
|
||||
### Optimized (v1.2.0)
|
||||
- Single instance CPU: 2.1%
|
||||
- 10 instances: 21% CPU
|
||||
- Hot path: Vectorized filter processing (18% of CPU time)
|
||||
|
||||
## Optimizations Applied
|
||||
|
||||
### 1. Replaced `std::pow()` with Lookup Table
|
||||
**Impact:** 45% CPU reduction
|
||||
**Location:** `Source/DSP/Saturation.cpp:42`
|
||||
|
||||
### 2. SIMD Vectorization of Filter
|
||||
**Impact:** 15% CPU reduction
|
||||
**Location:** `Source/DSP/SVFilter.cpp:87`
|
||||
|
||||
### 3. Removed Allocation in processBlock
|
||||
**Impact:** Eliminated RT violations
|
||||
**Location:** `Source/PluginProcessor.cpp:156`
|
||||
|
||||
## Benchmark Results
|
||||
|
||||
| Test | Baseline | Optimized | Improvement |
|
||||
|------|----------|-----------|-------------|
|
||||
| ProcessBlock (512 samples) | 1.85 ms | 0.48 ms | 74% faster |
|
||||
| Single instance CPU | 8.2% | 2.1% | 74% reduction |
|
||||
| 50 instances CPU | 410% | 105% | 74% reduction |
|
||||
|
||||
## Remaining Bottlenecks
|
||||
|
||||
1. **Reverb Algorithm** - Still using naive implementation (12% CPU)
|
||||
- Recommendation: Switch to FDN reverb or partitioned convolution
|
||||
2. **UI Repaints** - Currently 120fps (unnecessary)
|
||||
- Recommendation: Rate-limit to 60fps
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [ ] Optimize reverb algorithm (target: 5% CPU)
|
||||
- [ ] Rate-limit UI repaints (target: 60fps)
|
||||
- [ ] Profile on Windows (Intel CPU) to verify SIMD portability
|
||||
- [ ] Run stress test with 100+ instances
|
||||
|
||||
## Flame Graphs
|
||||
|
||||

|
||||

|
||||
|
||||
## Conclusion
|
||||
|
||||
Plugin now meets performance targets for release:
|
||||
- ✅ Single instance < 5% CPU
|
||||
- ✅ 20 instances < 50% CPU
|
||||
- ✅ No RT violations detected
|
||||
- ⚠️ Further optimization possible in reverb module
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
Performance analysis is complete when:
|
||||
|
||||
- ✅ Profiling data collected on target platforms
|
||||
- ✅ Hot paths identified and documented
|
||||
- ✅ Optimization opportunities prioritized
|
||||
- ✅ Key optimizations implemented and benchmarked
|
||||
- ✅ Performance regression tests added
|
||||
- ✅ Report generated with flame graphs and recommendations
|
||||
- ✅ CPU usage meets targets (< 5% single instance)
|
||||
- ✅ No allocations or locks in audio thread
|
||||
|
||||
---
|
||||
|
||||
## Performance Targets
|
||||
|
||||
### CPU Usage Goals
|
||||
|
||||
| Scenario | Target | Acceptable | Poor |
|
||||
|----------|--------|------------|------|
|
||||
| Single instance @ 44.1kHz, 512 samples | < 2% | < 5% | > 10% |
|
||||
| 10 instances | < 20% | < 40% | > 60% |
|
||||
| 50 instances | < 50% | < 80% | > 100% |
|
||||
|
||||
### Latency Goals
|
||||
|
||||
| Plugin Type | Target Latency |
|
||||
|-------------|----------------|
|
||||
| Dynamics (compressor, gate) | 0 samples |
|
||||
| EQ, filter | 0-64 samples |
|
||||
| Modulation effects | 0-128 samples |
|
||||
| Reverb, delay | 0-512 samples |
|
||||
|
||||
### Memory Usage
|
||||
|
||||
- **RAM:** < 50 MB per instance
|
||||
- **Allocations:** 0 in `processBlock()`
|
||||
|
||||
---
|
||||
|
||||
## Quick Profiling Checklist
|
||||
|
||||
For rapid performance validation:
|
||||
|
||||
```bash
|
||||
# 1. Build optimized
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
cmake --build build
|
||||
|
||||
# 2. Profile (macOS)
|
||||
instruments -t "Time Profiler" ./build/MyPlugin_Standalone
|
||||
|
||||
# 3. Check for RT violations
|
||||
# (Look for malloc/new in processBlock stack traces)
|
||||
|
||||
# 4. Benchmark
|
||||
./build/Tests/PerformanceBenchmark
|
||||
|
||||
# 5. Verify targets
|
||||
# Single instance should be < 5% CPU
|
||||
```
|
||||
|
||||
**Time Required:** 30 minutes
|
||||
|
||||
---
|
||||
|
||||
## Expert Help
|
||||
|
||||
Delegate performance tasks:
|
||||
|
||||
- **@dsp-engineer** - Optimize DSP algorithms, implement SIMD
|
||||
- **@test-automation-engineer** - Set up benchmarks, run profilers
|
||||
- **@ui-engineer** - Optimize UI rendering, fix repainting issues
|
||||
- **@technical-lead** - Review architectural performance issues
|
||||
- **@plugin-engineer** - Integrate optimizations into build system
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- **TESTING_STRATEGY.md** - Performance testing in CI/CD
|
||||
- **juce-best-practices** skill - Realtime safety guidelines
|
||||
- **dsp-cookbook** skill - Optimized DSP algorithms
|
||||
- `/run-pluginval` command - Validation includes performance tests
|
||||
|
||||
---
|
||||
|
||||
## Tools Reference
|
||||
|
||||
### macOS
|
||||
- **Instruments** (Xcode) - Time Profiler, Allocations, Leaks
|
||||
- **Activity Monitor** - Real-time CPU monitoring
|
||||
- **sample** - Command-line profiler: `sample <PID> 10 -f output.txt`
|
||||
|
||||
### Windows
|
||||
- **Visual Studio Profiler** - CPU Usage, Memory Usage
|
||||
- **Intel VTune** - Advanced profiling, hardware counters
|
||||
- **Windows Performance Analyzer (WPA)** - System-wide profiling
|
||||
|
||||
### Linux
|
||||
- **perf** - Linux performance profiler
|
||||
- **Valgrind** - Memory profiling, cache profiling
|
||||
- **gprof** - GNU profiler
|
||||
- **Tracy** - Real-time frame profiler
|
||||
|
||||
### Cross-Platform
|
||||
- **Tracy Profiler** - Real-time, frame-perfect profiling
|
||||
- **Google Benchmark** - Microbenchmarking library
|
||||
- **Superluminal** - Commercial profiler (excellent for audio plugins)
|
||||
|
||||
---
|
||||
|
||||
**Remember:** "Premature optimization is the root of all evil" - but audio plugins are performance-critical. Profile first, optimize hot paths, and always measure the impact!
|
||||
437
commands/build-all-formats.md
Normal file
437
commands/build-all-formats.md
Normal file
@@ -0,0 +1,437 @@
|
||||
---
|
||||
argument-hint: "[build-type: debug|release|relwithdebinfo]"
|
||||
description: "Build JUCE plugin for all configured formats (VST3, AU, AAX, Standalone) with CMake, tests, and build report"
|
||||
allowed-tools: Bash, Read, AskUserQuestion
|
||||
---
|
||||
|
||||
# Build All Plugin Formats
|
||||
|
||||
This command builds your JUCE plugin for all configured formats (VST3, AU, AAX, Standalone) in one operation. It configures CMake, compiles the code, runs tests, and generates a comprehensive build report.
|
||||
|
||||
## Instructions
|
||||
|
||||
You are tasked with building a JUCE plugin project for all target formats. Execute the following steps systematically:
|
||||
|
||||
### 1. Verify Project Structure
|
||||
|
||||
Check that we're in a JUCE plugin project:
|
||||
|
||||
```bash
|
||||
# Look for key files
|
||||
if [ ! -f "CMakeLists.txt" ]; then
|
||||
echo "❌ No CMakeLists.txt found. Are you in a JUCE plugin project?"
|
||||
echo "Run /new-juce-plugin to create a new project first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Confirm JUCE is available
|
||||
if [ ! -d "JUCE" ] && [ ! -d "submodules/JUCE" ]; then
|
||||
echo "⚠️ JUCE framework not found"
|
||||
echo "Options:"
|
||||
echo " 1. Add as submodule: git submodule add https://github.com/juce-framework/JUCE.git"
|
||||
echo " 2. Install system-wide: brew install juce (macOS)"
|
||||
echo " 3. Specify JUCE path in CMake: cmake -DJUCE_PATH=/path/to/JUCE"
|
||||
# Don't exit - let CMake fail with helpful error
|
||||
fi
|
||||
```
|
||||
|
||||
### 2. Determine Build Type
|
||||
|
||||
Use the argument provided, or ask the user:
|
||||
|
||||
**Build Types:**
|
||||
- `Debug` - Development build with symbols, no optimization
|
||||
- `Release` - Optimized build for distribution
|
||||
- `RelWithDebInfo` - Optimized with debug symbols (recommended for profiling)
|
||||
|
||||
If no argument provided:
|
||||
```
|
||||
Which build type? (Default: Release)
|
||||
1. Debug - Development with symbols
|
||||
2. Release - Optimized for distribution ⭐
|
||||
3. RelWithDebInfo - Optimized + symbols for profiling
|
||||
```
|
||||
|
||||
Default to `Release` if no response.
|
||||
|
||||
### 3. Clean Previous Build (Optional)
|
||||
|
||||
Ask if user wants to clean previous build:
|
||||
|
||||
```bash
|
||||
echo "Clean previous build? (y/N)"
|
||||
read -r response
|
||||
if [[ "$response" =~ ^[Yy]$ ]]; then
|
||||
rm -rf build
|
||||
echo "✓ Cleaned build directory"
|
||||
fi
|
||||
```
|
||||
|
||||
### 4. Configure CMake
|
||||
|
||||
Run CMake configuration:
|
||||
|
||||
```bash
|
||||
echo "🔧 Configuring CMake..."
|
||||
|
||||
cmake -B build \
|
||||
-DCMAKE_BUILD_TYPE=[BuildType] \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ CMake configuration failed"
|
||||
echo ""
|
||||
echo "Common issues:"
|
||||
echo " - JUCE not found: Set JUCE_PATH or add as submodule"
|
||||
echo " - Missing dependencies: Check CMakeLists.txt requirements"
|
||||
echo " - CMake version: Requires CMake 3.22+"
|
||||
echo ""
|
||||
echo "Run cmake -B build for detailed error messages"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ CMake configuration successful"
|
||||
```
|
||||
|
||||
### 5. Detect Available Formats
|
||||
|
||||
Determine which formats were configured:
|
||||
|
||||
```bash
|
||||
echo ""
|
||||
echo "📦 Detecting configured plugin formats..."
|
||||
|
||||
formats=()
|
||||
if grep -q "VST3" build/CMakeCache.txt 2>/dev/null; then
|
||||
formats+=("VST3")
|
||||
fi
|
||||
if grep -q "AU" build/CMakeCache.txt 2>/dev/null; then
|
||||
formats+=("AU")
|
||||
fi
|
||||
if grep -q "AAX" build/CMakeCache.txt 2>/dev/null; then
|
||||
formats+=("AAX")
|
||||
fi
|
||||
if grep -q "Standalone" build/CMakeCache.txt 2>/dev/null; then
|
||||
formats+=("Standalone")
|
||||
fi
|
||||
|
||||
if [ ${#formats[@]} -eq 0 ]; then
|
||||
echo "⚠️ No plugin formats detected - building all targets"
|
||||
else
|
||||
echo "Configured formats: ${formats[*]}"
|
||||
fi
|
||||
```
|
||||
|
||||
### 6. Build All Targets
|
||||
|
||||
Execute the build with progress indication:
|
||||
|
||||
```bash
|
||||
echo ""
|
||||
echo "🏗️ Building all targets..."
|
||||
echo "Build type: [BuildType]"
|
||||
echo "This may take several minutes..."
|
||||
echo ""
|
||||
|
||||
# Use parallel builds for speed
|
||||
num_cores=$(sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || echo 4)
|
||||
|
||||
cmake --build build \
|
||||
--config [BuildType] \
|
||||
--parallel $num_cores
|
||||
|
||||
build_exit_code=$?
|
||||
|
||||
if [ $build_exit_code -ne 0 ]; then
|
||||
echo ""
|
||||
echo "❌ Build failed with exit code $build_exit_code"
|
||||
echo ""
|
||||
echo "Troubleshooting:"
|
||||
echo " - Check compiler errors above"
|
||||
echo " - Ensure all JUCE modules are available"
|
||||
echo " - Verify C++17 or C++20 compiler support"
|
||||
echo " - Try: cmake --build build --verbose for details"
|
||||
echo ""
|
||||
echo "Need help? Invoke @build-engineer to debug build issues"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✓ Build completed successfully"
|
||||
```
|
||||
|
||||
### 7. Run Tests (if available)
|
||||
|
||||
If tests are configured, run them:
|
||||
|
||||
```bash
|
||||
echo ""
|
||||
echo "🧪 Running tests..."
|
||||
|
||||
if [ -f "build/Tests/RunUnitTests" ] || [ -d "build/Tests" ]; then
|
||||
ctest --test-dir build -C [BuildType] --output-on-failure
|
||||
test_exit_code=$?
|
||||
|
||||
if [ $test_exit_code -eq 0 ]; then
|
||||
echo "✓ All tests passed"
|
||||
else
|
||||
echo "⚠️ Some tests failed - review output above"
|
||||
echo "Continue anyway? (Y/n)"
|
||||
read -r response
|
||||
if [[ "$response" =~ ^[Nn]$ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "ℹ️ No tests configured - skipping test phase"
|
||||
echo "Tip: Run @test-automation-engineer to add tests"
|
||||
fi
|
||||
```
|
||||
|
||||
### 8. Locate Built Plugins
|
||||
|
||||
Find and report built plugin binaries:
|
||||
|
||||
```bash
|
||||
echo ""
|
||||
echo "📍 Locating built plugins..."
|
||||
echo ""
|
||||
|
||||
plugin_name=$(grep "project(" CMakeLists.txt | head -1 | sed 's/.*(\(.*\)).*/\1/' | tr -d ' ')
|
||||
|
||||
# VST3
|
||||
vst3_path=$(find build -name "*.vst3" -type d | head -1)
|
||||
if [ -n "$vst3_path" ]; then
|
||||
vst3_size=$(du -sh "$vst3_path" | cut -f1)
|
||||
echo "✓ VST3: $vst3_path ($vst3_size)"
|
||||
fi
|
||||
|
||||
# AU (macOS only)
|
||||
au_path=$(find build -name "*.component" -type d | head -1)
|
||||
if [ -n "$au_path" ]; then
|
||||
au_size=$(du -sh "$au_path" | cut -f1)
|
||||
echo "✓ AU: $au_path ($au_size)"
|
||||
fi
|
||||
|
||||
# AAX
|
||||
aax_path=$(find build -name "*.aaxplugin" -type d | head -1)
|
||||
if [ -n "$aax_path" ]; then
|
||||
aax_size=$(du -sh "$aax_path" | cut -f1)
|
||||
echo "✓ AAX: $aax_path ($aax_size)"
|
||||
fi
|
||||
|
||||
# Standalone
|
||||
standalone_path=$(find build -name "${plugin_name}" -type f -o -name "${plugin_name}.app" -type d | head -1)
|
||||
if [ -n "$standalone_path" ]; then
|
||||
standalone_size=$(du -sh "$standalone_path" | cut -f1)
|
||||
echo "✓ Standalone: $standalone_path ($standalone_size)"
|
||||
fi
|
||||
```
|
||||
|
||||
### 9. Generate Build Report
|
||||
|
||||
Create a comprehensive build report:
|
||||
|
||||
```bash
|
||||
cat > build/BUILD_REPORT.md << EOF
|
||||
# Build Report
|
||||
|
||||
**Date**: $(date '+%Y-%m-%d %H:%M:%S')
|
||||
**Build Type**: [BuildType]
|
||||
**Platform**: $(uname -s) $(uname -m)
|
||||
**CMake Version**: $(cmake --version | head -1)
|
||||
**Compiler**: $(cmake -LA -N build | grep CMAKE_CXX_COMPILER: | cut -d= -f2)
|
||||
|
||||
## Build Summary
|
||||
|
||||
- ✓ Configuration successful
|
||||
- ✓ Compilation successful
|
||||
- $([ -f build/Tests/RunUnitTests ] && echo "✓ Tests passed" || echo "ℹ️ Tests not configured")
|
||||
|
||||
## Built Artifacts
|
||||
|
||||
$(find build -name "*.vst3" -o -name "*.component" -o -name "*.aaxplugin" | while read file; do
|
||||
echo "- $file ($(du -sh "$file" | cut -f1))"
|
||||
done)
|
||||
|
||||
## Plugin Formats
|
||||
|
||||
$([ -n "$vst3_path" ] && echo "- [x] VST3" || echo "- [ ] VST3")
|
||||
$([ -n "$au_path" ] && echo "- [x] AU" || echo "- [ ] AU")
|
||||
$([ -n "$aax_path" ] && echo "- [x] AAX" || echo "- [ ] AAX")
|
||||
$([ -n "$standalone_path" ] && echo "- [x] Standalone" || echo "- [ ] Standalone")
|
||||
|
||||
## Build Configuration
|
||||
|
||||
\`\`\`
|
||||
$(cmake -LA -N build | grep -E "CMAKE_BUILD_TYPE|CMAKE_CXX_STANDARD|JUCE_VERSION")
|
||||
\`\`\`
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Test plugins in DAW
|
||||
2. Run pluginval: \`/run-pluginval\`
|
||||
3. Profile performance: \`/analyze-performance\`
|
||||
4. Prepare for release: \`/release-build\`
|
||||
|
||||
---
|
||||
Generated by JUCE Dev Team - Build All Formats
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "✓ Build report saved to build/BUILD_REPORT.md"
|
||||
```
|
||||
|
||||
### 10. Display Summary
|
||||
|
||||
Present final build summary:
|
||||
|
||||
```
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✅ BUILD COMPLETE - All Formats"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "📦 Plugin Name: $plugin_name"
|
||||
echo "🏗️ Build Type: [BuildType]"
|
||||
echo "⏱️ Build Time: $(cat build/.build_time 2>/dev/null || echo "N/A")"
|
||||
echo ""
|
||||
echo "Built Formats:"
|
||||
$([ -n "$vst3_path" ] && echo " ✓ VST3")
|
||||
$([ -n "$au_path" ] && echo " ✓ AU")
|
||||
$([ -n "$aax_path" ] && echo " ✓ AAX")
|
||||
$([ -n "$standalone_path" ] && echo " ✓ Standalone")
|
||||
echo ""
|
||||
echo "📂 Build Output: build/"
|
||||
echo "📄 Build Report: build/BUILD_REPORT.md"
|
||||
echo ""
|
||||
echo "🚀 Next Steps:"
|
||||
echo " 1. Test in DAW: Load built plugins in your DAW"
|
||||
echo " 2. Validate: /run-pluginval"
|
||||
echo " 3. Debug issues: @build-engineer or @daw-compatibility-engineer"
|
||||
echo " 4. Package for release: /release-build"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
```
|
||||
|
||||
## Platform-Specific Notes
|
||||
|
||||
### macOS
|
||||
|
||||
- Builds universal binaries (arm64 + x86_64) by default
|
||||
- AU format requires macOS
|
||||
- Code signing not performed (use `/release-build` for signed builds)
|
||||
|
||||
### Windows
|
||||
|
||||
- Builds for x64 architecture
|
||||
- AAX requires AAX SDK from Avid
|
||||
- Use Visual Studio 2019+ or Ninja generator
|
||||
|
||||
### Linux
|
||||
|
||||
- VST3 only (AU and AAX not available)
|
||||
- Ensure required libraries installed (ALSA, X11, etc.)
|
||||
|
||||
## Error Handling
|
||||
|
||||
### CMake Configuration Fails
|
||||
|
||||
```
|
||||
@build-engineer CMake configuration failed with the following error:
|
||||
[paste error output]
|
||||
|
||||
Please help diagnose and fix this issue.
|
||||
```
|
||||
|
||||
### Compilation Errors
|
||||
|
||||
```
|
||||
@technical-lead The build failed with compilation errors:
|
||||
[paste error output]
|
||||
|
||||
Please review and suggest fixes.
|
||||
```
|
||||
|
||||
### Linker Errors
|
||||
|
||||
```
|
||||
@build-engineer Linking failed with the following errors:
|
||||
[paste error output]
|
||||
|
||||
Please help resolve these linker issues.
|
||||
```
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Project structure verified
|
||||
- [ ] CMake configured successfully
|
||||
- [ ] All targets built without errors
|
||||
- [ ] Tests run (if configured)
|
||||
- [ ] Built plugins located and verified
|
||||
- [ ] Build report generated
|
||||
- [ ] User provided with plugin locations and next steps
|
||||
|
||||
## Optimization Tips
|
||||
|
||||
### Speed Up Builds
|
||||
|
||||
```bash
|
||||
# Use Ninja generator (faster than Make)
|
||||
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
# Use ccache to cache compilation
|
||||
cmake -B build -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
|
||||
# Build specific target only
|
||||
cmake --build build --target MyPlugin_VST3
|
||||
```
|
||||
|
||||
### Clean Rebuilds
|
||||
|
||||
```bash
|
||||
# Clean and rebuild
|
||||
rm -rf build && /build-all-formats release
|
||||
|
||||
# Or just clean build artifacts (keeps CMake cache)
|
||||
cmake --build build --target clean
|
||||
```
|
||||
|
||||
## Integration with Other Commands
|
||||
|
||||
This command works well with:
|
||||
|
||||
- `/new-juce-plugin` - Create project first
|
||||
- `/run-pluginval` - Validate after building
|
||||
- `/analyze-performance` - Profile the build
|
||||
- `/release-build` - Create signed release builds
|
||||
- `@build-engineer` - Debug build issues
|
||||
- `@test-automation-engineer` - Add/fix tests
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Build Specific Format Only
|
||||
|
||||
```bash
|
||||
cmake --build build --target MyPlugin_VST3 --config Release
|
||||
```
|
||||
|
||||
### Build with Warnings as Errors
|
||||
|
||||
```bash
|
||||
cmake -B build -DCMAKE_CXX_FLAGS="-Werror"
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
### Generate Xcode/Visual Studio Project
|
||||
|
||||
```bash
|
||||
# Xcode (macOS)
|
||||
cmake -B build -G Xcode
|
||||
open build/MyPlugin.xcodeproj
|
||||
|
||||
# Visual Studio (Windows)
|
||||
cmake -B build -G "Visual Studio 17 2022"
|
||||
start build/MyPlugin.sln
|
||||
```
|
||||
484
commands/new-juce-plugin.md
Normal file
484
commands/new-juce-plugin.md
Normal file
@@ -0,0 +1,484 @@
|
||||
---
|
||||
argument-hint: "[plugin-name] [type: effect|synth|midi]"
|
||||
description: "Scaffold complete JUCE plugin project with architecture, build config, and CI/CD using expert agents"
|
||||
allowed-tools: Read, Write, Bash, AskUserQuestion, Task
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
# Create New JUCE Plugin Project
|
||||
|
||||
This command scaffolds a complete JUCE plugin project with proper structure, build configuration, and best practices. It orchestrates multiple expert agents to set up a production-ready plugin foundation.
|
||||
|
||||
## Instructions
|
||||
|
||||
You are tasked with creating a new JUCE audio plugin project from scratch. Follow these steps to build a complete, professional plugin foundation:
|
||||
|
||||
### 1. Gather Project Requirements
|
||||
|
||||
Ask the user for essential project details (if not provided as arguments):
|
||||
|
||||
**Required Information:**
|
||||
- **Plugin Name**: What should the plugin be called? (e.g., "MyCompressor", "SuperSynth")
|
||||
- **Plugin Type**: What type of plugin?
|
||||
- `effect` - Audio effect processor (compressor, EQ, reverb, etc.)
|
||||
- `synth` - Software synthesizer or instrument
|
||||
- `midi` - MIDI effect or processor
|
||||
- **Plugin Formats**: Which formats to support?
|
||||
- VST3 (recommended, cross-platform)
|
||||
- AU (Audio Unit, macOS only)
|
||||
- AAX (Pro Tools, requires Avid SDK)
|
||||
- Standalone (optional desktop application)
|
||||
- **Build System**: CMake (recommended) or Projucer?
|
||||
- **Company/Manufacturer Name**: For plugin metadata
|
||||
- **Description**: Brief description of what the plugin does
|
||||
|
||||
### 2. Delegate to Technical Lead
|
||||
|
||||
Invoke `@technical-lead` to define the architecture:
|
||||
|
||||
```
|
||||
@technical-lead Define the architecture for a new [plugin-type] plugin called "[plugin-name]".
|
||||
|
||||
Requirements:
|
||||
- Plugin type: [effect/synth/midi]
|
||||
- Target formats: [VST3/AU/AAX/Standalone]
|
||||
- Build system: [CMake/Projucer]
|
||||
|
||||
Please provide:
|
||||
1. Recommended folder structure
|
||||
2. Parameter framework approach
|
||||
3. DSP organization strategy
|
||||
4. State management approach
|
||||
5. Thread safety guidelines
|
||||
```
|
||||
|
||||
Wait for technical-lead's architectural recommendations before proceeding.
|
||||
|
||||
### 3. Create Project Directory Structure
|
||||
|
||||
Based on the architecture recommendations, create the folder structure:
|
||||
|
||||
```bash
|
||||
mkdir -p [PluginName]
|
||||
cd [PluginName]
|
||||
|
||||
# Standard JUCE plugin structure
|
||||
mkdir -p Source/DSP
|
||||
mkdir -p Source/UI
|
||||
mkdir -p Source/Parameters
|
||||
mkdir -p Tests/DSP
|
||||
mkdir -p Tests/Integration
|
||||
mkdir -p Resources
|
||||
mkdir -p Scripts
|
||||
mkdir -p .github/workflows
|
||||
|
||||
echo "# [PluginName]" > README.md
|
||||
```
|
||||
|
||||
### 4. Initialize Git Repository
|
||||
|
||||
```bash
|
||||
git init
|
||||
git add .
|
||||
git commit -m "chore: initial project structure for [PluginName]"
|
||||
```
|
||||
|
||||
Create a comprehensive `.gitignore`:
|
||||
|
||||
```bash
|
||||
cat > .gitignore << 'EOF'
|
||||
# Builds
|
||||
Builds/
|
||||
build/
|
||||
cmake-build-*/
|
||||
*.xcodeproj
|
||||
*.vcxproj
|
||||
*.sln
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
*.dSYM
|
||||
|
||||
# Windows
|
||||
*.exe
|
||||
*.dll
|
||||
*.pdb
|
||||
|
||||
# Plugin binaries
|
||||
*.vst3
|
||||
*.component
|
||||
*.aaxplugin
|
||||
|
||||
# JUCE
|
||||
JuceLibraryCode/
|
||||
|
||||
# Dependencies
|
||||
JUCE/
|
||||
submodules/
|
||||
|
||||
# Testing
|
||||
*.log
|
||||
test_output/
|
||||
EOF
|
||||
```
|
||||
|
||||
### 5. Delegate to Build Engineer - CMake Setup
|
||||
|
||||
Invoke `@build-engineer` to create the build configuration:
|
||||
|
||||
```
|
||||
@build-engineer Set up CMake configuration for [PluginName] plugin.
|
||||
|
||||
Requirements:
|
||||
- Plugin type: [effect/synth/midi]
|
||||
- Formats: [VST3, AU, AAX, Standalone]
|
||||
- JUCE version: latest stable
|
||||
- C++ standard: C++17 or C++20
|
||||
- Enable testing support
|
||||
|
||||
Create:
|
||||
1. CMakeLists.txt with JUCE integration
|
||||
2. GitHub Actions CI/CD workflow
|
||||
3. Build scripts for macOS and Windows
|
||||
```
|
||||
|
||||
The build engineer will create:
|
||||
- `CMakeLists.txt`
|
||||
- `.github/workflows/build.yml`
|
||||
- Build documentation
|
||||
|
||||
### 6. Delegate to Plugin Engineer - Core Plugin Files
|
||||
|
||||
Invoke `@plugin-engineer` to create the plugin boilerplate:
|
||||
|
||||
```
|
||||
@plugin-engineer Create the core plugin files for [PluginName].
|
||||
|
||||
Plugin details:
|
||||
- Type: [effect/synth/midi]
|
||||
- Name: [PluginName]
|
||||
- Manufacturer: [CompanyName]
|
||||
- Description: [brief description]
|
||||
|
||||
Create:
|
||||
1. Source/PluginProcessor.h/cpp - AudioProcessor subclass
|
||||
2. Source/PluginEditor.h/cpp - AudioProcessorEditor subclass
|
||||
3. Source/Parameters/Parameters.h/cpp - Parameter definitions
|
||||
4. Basic parameter layout with common parameters for [type]
|
||||
|
||||
Follow JUCE best practices and ensure realtime safety.
|
||||
```
|
||||
|
||||
The plugin engineer will create:
|
||||
- `Source/PluginProcessor.h`
|
||||
- `Source/PluginProcessor.cpp`
|
||||
- `Source/PluginEditor.h`
|
||||
- `Source/PluginEditor.cpp`
|
||||
- `Source/Parameters/Parameters.h`
|
||||
- `Source/Parameters/Parameters.cpp`
|
||||
|
||||
### 7. Add Basic DSP Structure (if effect or synth)
|
||||
|
||||
If the plugin is an effect or synth, create basic DSP scaffolding:
|
||||
|
||||
**For Effects:**
|
||||
```cpp
|
||||
// Source/DSP/AudioProcessor.h
|
||||
#pragma once
|
||||
#include <juce_audio_processors/juce_audio_processors.h>
|
||||
|
||||
namespace DSP {
|
||||
|
||||
class Processor {
|
||||
public:
|
||||
void prepare(double sampleRate, int maxBlockSize);
|
||||
void process(juce::AudioBuffer<float>& buffer);
|
||||
void reset();
|
||||
|
||||
private:
|
||||
double sampleRate = 44100.0;
|
||||
// Add DSP state here
|
||||
};
|
||||
|
||||
} // namespace DSP
|
||||
```
|
||||
|
||||
**For Synths:**
|
||||
```cpp
|
||||
// Source/DSP/Voice.h
|
||||
#pragma once
|
||||
#include <juce_audio_processors/juce_audio_processors.h>
|
||||
|
||||
namespace DSP {
|
||||
|
||||
class Voice : public juce::SynthesiserVoice {
|
||||
public:
|
||||
bool canPlaySound(juce::SynthesiserSound*) override;
|
||||
void startNote(int midiNoteNumber, float velocity,
|
||||
juce::SynthesiserSound*, int currentPitchWheelPosition) override;
|
||||
void stopNote(float velocity, bool allowTailOff) override;
|
||||
void pitchWheelMoved(int newPitchWheelValue) override;
|
||||
void controllerMoved(int controllerNumber, int newControllerValue) override;
|
||||
void renderNextBlock(juce::AudioBuffer<float>&, int startSample, int numSamples) override;
|
||||
|
||||
private:
|
||||
// Oscillator, envelope, etc.
|
||||
};
|
||||
|
||||
} // namespace DSP
|
||||
```
|
||||
|
||||
### 8. Delegate to Test Automation Engineer
|
||||
|
||||
Invoke `@test-automation-engineer` to set up testing:
|
||||
|
||||
```
|
||||
@test-automation-engineer Set up testing infrastructure for [PluginName].
|
||||
|
||||
Create:
|
||||
1. Unit test structure using JUCE UnitTest framework or Catch2
|
||||
2. Basic processor tests (initialization, parameter changes, state save/load)
|
||||
3. CMake test targets
|
||||
4. CI integration for running tests
|
||||
|
||||
Follow testing best practices for audio plugins.
|
||||
```
|
||||
|
||||
This creates:
|
||||
- `Tests/DSPTests.cpp`
|
||||
- `Tests/PluginTests.cpp`
|
||||
- Test CMake configuration
|
||||
- GitHub Actions test workflow
|
||||
|
||||
### 9. Create Documentation Files
|
||||
|
||||
Create essential documentation:
|
||||
|
||||
**README.md:**
|
||||
```markdown
|
||||
# [PluginName]
|
||||
|
||||
[Brief description of the plugin]
|
||||
|
||||
## Features
|
||||
|
||||
- Feature 1
|
||||
- Feature 2
|
||||
- Feature 3
|
||||
|
||||
## Building
|
||||
|
||||
### Prerequisites
|
||||
- CMake 3.22 or higher
|
||||
- JUCE 7.x
|
||||
- C++17 compatible compiler
|
||||
- (macOS) Xcode 13+
|
||||
- (Windows) Visual Studio 2019+
|
||||
|
||||
### Build Instructions
|
||||
|
||||
\`\`\`bash
|
||||
# Clone with submodules
|
||||
git clone --recurse-submodules [repo-url]
|
||||
cd [PluginName]
|
||||
|
||||
# Configure
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
# Build
|
||||
cmake --build build --config Release
|
||||
|
||||
# Run tests
|
||||
ctest --test-dir build -C Release
|
||||
\`\`\`
|
||||
|
||||
## Supported Formats
|
||||
|
||||
- [x] VST3
|
||||
- [x] AU (macOS)
|
||||
- [x] AAX
|
||||
- [x] Standalone
|
||||
|
||||
## License
|
||||
|
||||
[License information]
|
||||
|
||||
## Credits
|
||||
|
||||
Developed with [JUCE](https://juce.com/)
|
||||
```
|
||||
|
||||
**CHANGELOG.md:**
|
||||
```markdown
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- Initial project structure
|
||||
- Basic plugin processor and editor
|
||||
- Parameter framework
|
||||
- Testing infrastructure
|
||||
- CI/CD with GitHub Actions
|
||||
```
|
||||
|
||||
### 10. Set Up JUCE as Submodule
|
||||
|
||||
Add JUCE framework:
|
||||
|
||||
```bash
|
||||
git submodule add https://github.com/juce-framework/JUCE.git
|
||||
git submodule update --init --recursive
|
||||
git add .gitmodules JUCE
|
||||
git commit -m "chore: add JUCE framework as submodule"
|
||||
```
|
||||
|
||||
### 11. Verify Build
|
||||
|
||||
Test that everything builds:
|
||||
|
||||
```bash
|
||||
cmake -B build
|
||||
cmake --build build
|
||||
|
||||
# If tests are set up:
|
||||
ctest --test-dir build
|
||||
```
|
||||
|
||||
### 12. Create Initial Commit
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "feat: initial [PluginName] plugin setup
|
||||
|
||||
- CMake build configuration for VST3/AU/AAX
|
||||
- Basic plugin processor and editor
|
||||
- Parameter framework
|
||||
- DSP scaffolding
|
||||
- Unit test structure
|
||||
- CI/CD pipeline
|
||||
- Documentation
|
||||
|
||||
Generated with Claude Code JUCE Dev Team
|
||||
"
|
||||
```
|
||||
|
||||
### 13. Provide Summary
|
||||
|
||||
Present a comprehensive summary to the user:
|
||||
|
||||
```
|
||||
✅ [PluginName] Plugin Project Created Successfully!
|
||||
|
||||
📂 Project Structure:
|
||||
[PluginName]/
|
||||
├── Source/
|
||||
│ ├── PluginProcessor.h/cpp ✓ Audio processor
|
||||
│ ├── PluginEditor.h/cpp ✓ UI editor
|
||||
│ ├── Parameters/ ✓ Parameter definitions
|
||||
│ └── DSP/ ✓ DSP processing
|
||||
├── Tests/ ✓ Unit tests
|
||||
├── Resources/ ✓ Assets
|
||||
├── Scripts/ ✓ Build scripts
|
||||
├── .github/workflows/ ✓ CI/CD
|
||||
├── CMakeLists.txt ✓ Build config
|
||||
├── README.md ✓ Documentation
|
||||
└── CHANGELOG.md ✓ Version history
|
||||
|
||||
🔧 Build System: CMake
|
||||
📦 Plugin Formats: VST3, AU, AAX, Standalone
|
||||
🧪 Tests: Configured and ready
|
||||
|
||||
🚀 Next Steps:
|
||||
|
||||
1. Build the project:
|
||||
cmake -B build && cmake --build build
|
||||
|
||||
2. Run tests:
|
||||
ctest --test-dir build
|
||||
|
||||
3. Start developing:
|
||||
- Add DSP code to Source/DSP/
|
||||
- Define parameters in Source/Parameters/
|
||||
- Design UI in Source/PluginEditor.cpp
|
||||
|
||||
4. Consult experts:
|
||||
@dsp-engineer for DSP implementation
|
||||
@ui-engineer for interface design
|
||||
@test-automation-engineer for testing
|
||||
|
||||
📚 Documentation:
|
||||
- README.md for project overview
|
||||
- /docs/juce-api/ for JUCE API reference
|
||||
- /docs/dsp-resources/ for DSP algorithms
|
||||
|
||||
Happy plugin development! 🎵
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
If any step fails:
|
||||
|
||||
1. **JUCE submodule fails**: Provide manual installation instructions
|
||||
2. **CMake configuration fails**: Check CMake version and provide troubleshooting
|
||||
3. **Build fails**: Invoke @build-engineer to debug
|
||||
4. **Test setup fails**: Invoke @test-automation-engineer for alternative approach
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Project directory structure created
|
||||
- [ ] Git repository initialized with .gitignore
|
||||
- [ ] CMake build configuration complete
|
||||
- [ ] Core plugin files (Processor, Editor, Parameters) created
|
||||
- [ ] Basic DSP scaffolding in place
|
||||
- [ ] Unit test structure set up
|
||||
- [ ] CI/CD pipeline configured
|
||||
- [ ] README and CHANGELOG created
|
||||
- [ ] JUCE framework integrated (submodule or otherwise)
|
||||
- [ ] Project builds successfully without errors
|
||||
- [ ] Tests run (even if minimal)
|
||||
- [ ] All files committed to git
|
||||
- [ ] User provided with clear next steps
|
||||
|
||||
## Agent Orchestration
|
||||
|
||||
This command delegates to multiple agents:
|
||||
|
||||
1. **@technical-lead** - Architecture decisions and best practices
|
||||
2. **@build-engineer** - CMake configuration and CI/CD setup
|
||||
3. **@plugin-engineer** - Core plugin boilerplate code
|
||||
4. **@test-automation-engineer** - Testing infrastructure
|
||||
|
||||
Each agent brings specialized expertise to ensure the project starts with a solid foundation.
|
||||
|
||||
## Customization Options
|
||||
|
||||
Ask the user if they want to customize:
|
||||
|
||||
- **Parameter set**: Custom parameters for their specific plugin type
|
||||
- **DSP algorithm**: Specific effect or synth algorithm to scaffold
|
||||
- **UI style**: Minimal, skeuomorphic, or modern flat design
|
||||
- **Licensing**: Integration with licensing SDK from the start
|
||||
- **Analytics**: Telemetry setup for crash reporting
|
||||
|
||||
## Follow-up Commands
|
||||
|
||||
After creating the project, suggest:
|
||||
|
||||
- `/setup-offline-docs` - Set up local documentation
|
||||
- `/build-all-formats` - Build all plugin formats
|
||||
- `/run-pluginval` - Validate the plugin
|
||||
- `@dsp-engineer implement [algorithm]` - Start DSP work
|
||||
- `@ui-engineer design interface` - Start UI work
|
||||
638
commands/release-build.md
Normal file
638
commands/release-build.md
Normal file
@@ -0,0 +1,638 @@
|
||||
---
|
||||
argument-hint: "<version> [options]"
|
||||
description: "Complete release build automation with code signing, notarization, installers, and distribution-ready artifacts"
|
||||
allowed-tools: Bash, Read, Write, AskUserQuestion, Task
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
# /release-build
|
||||
|
||||
Complete release build automation for JUCE audio plugins. Builds all formats, signs binaries, notarizes macOS builds, creates installers, and prepares release artifacts.
|
||||
|
||||
## Purpose
|
||||
|
||||
Orchestrate the full release workflow from testing to distribution-ready installers. This command automates the complex, error-prone process of creating production releases with proper code signing and platform-specific packaging.
|
||||
|
||||
## Arguments
|
||||
|
||||
```
|
||||
/release-build <version> [options]
|
||||
<version> Semantic version (e.g., 1.0.0, 2.1.0-beta1)
|
||||
|
||||
Options:
|
||||
--skip-tests Skip test suite (not recommended for releases)
|
||||
--skip-qa Skip manual QA validation prompts
|
||||
--platforms Platforms to build: all, mac, win, linux (default: all)
|
||||
--formats Formats to build: all, vst3, au, aax, standalone (default: all)
|
||||
--create-dmg Create macOS DMG installer
|
||||
--create-exe Create Windows NSIS installer
|
||||
--sign Enable code signing (default: true)
|
||||
--notarize Enable macOS notarization (default: true for mac)
|
||||
--upload Upload to distribution server after build
|
||||
--changelog Path to changelog file (default: CHANGELOG.md)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Standard release build (all platforms, all formats)
|
||||
/release-build 1.0.0
|
||||
|
||||
# macOS-only release with DMG
|
||||
/release-build 1.0.0 --platforms mac --create-dmg
|
||||
|
||||
# Beta release without notarization
|
||||
/release-build 2.0.0-beta1 --notarize false
|
||||
|
||||
# Quick rebuild (skip tests, QA)
|
||||
/release-build 1.0.1 --skip-tests --skip-qa
|
||||
|
||||
# Windows release with installer
|
||||
/release-build 1.0.0 --platforms win --create-exe
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
The release build process follows a strict sequence to ensure quality and proper signing:
|
||||
|
||||
### Phase 1: Pre-Release Validation
|
||||
|
||||
1. **Version Validation**
|
||||
- Verify version follows semantic versioning
|
||||
- Check version doesn't already exist in git tags
|
||||
- Ensure CHANGELOG.md has entry for this version
|
||||
- Verify all version numbers in code match
|
||||
|
||||
2. **Test Suite Execution**
|
||||
- Delegate to **@test-automation-engineer** to run full test suite:
|
||||
```
|
||||
@test-automation-engineer Run the complete test suite including:
|
||||
- All unit tests (DSP, parameters, state serialization)
|
||||
- Integration tests
|
||||
- Audio correctness tests (null test, frequency response)
|
||||
- Memory leak detection
|
||||
- Thread safety validation
|
||||
|
||||
Report any failures and block release if tests don't pass.
|
||||
```
|
||||
|
||||
3. **Pluginval Validation**
|
||||
- Run pluginval at strictness level 10 (maximum):
|
||||
```bash
|
||||
/run-pluginval all 10
|
||||
```
|
||||
- Block release if validation fails
|
||||
|
||||
4. **Manual QA Check** (unless --skip-qa)
|
||||
- Delegate to **@qa-engineer**:
|
||||
```
|
||||
@qa-engineer Please execute pre-release QA validation:
|
||||
|
||||
1. Load plugin in at least 3 major DAWs
|
||||
2. Test all parameters function correctly
|
||||
3. Verify presets load properly
|
||||
4. Check automation recording and playback
|
||||
5. Test state save/load (save project, reopen)
|
||||
6. Verify offline rendering matches realtime
|
||||
7. Check CPU usage is reasonable
|
||||
8. Listen for audio artifacts (clicks, pops, aliasing)
|
||||
|
||||
Provide go/no-go recommendation for release.
|
||||
```
|
||||
|
||||
### Phase 2: Clean Build
|
||||
|
||||
5. **Build Environment Setup**
|
||||
- Delegate to **@build-engineer**:
|
||||
```
|
||||
@build-engineer Prepare clean build environment:
|
||||
|
||||
1. Clean all build directories: rm -rf build/
|
||||
2. Verify JUCE submodule is at correct version
|
||||
3. Check CMakeLists.txt version matches <version>
|
||||
4. Ensure all dependencies are available
|
||||
5. Set CMAKE_BUILD_TYPE=Release
|
||||
6. Enable link-time optimization (LTO)
|
||||
7. Configure for all target formats: VST3, AU, AAX, Standalone
|
||||
|
||||
Platform-specific:
|
||||
- macOS: Set deployment target to 10.13+
|
||||
- Windows: Set /MT runtime, enable whole program optimization
|
||||
- Linux: Set -march=x86-64, enable static linking where possible
|
||||
```
|
||||
|
||||
6. **Build All Formats**
|
||||
- Execute multi-platform builds:
|
||||
```bash
|
||||
# macOS
|
||||
cmake -B build-mac -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"
|
||||
cmake --build build-mac --config Release --parallel
|
||||
|
||||
# Windows
|
||||
cmake -B build-win -G "Visual Studio 17 2022" -A x64
|
||||
cmake --build build-win --config Release --parallel
|
||||
|
||||
# Linux
|
||||
cmake -B build-linux -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build-linux --config Release --parallel
|
||||
```
|
||||
|
||||
7. **Post-Build Validation**
|
||||
- Verify all binaries were created
|
||||
- Check binary sizes are reasonable
|
||||
- Run `file` command to verify architectures
|
||||
- Ensure no debug symbols in Release builds
|
||||
|
||||
### Phase 3: Code Signing
|
||||
|
||||
8. **macOS Code Signing**
|
||||
- Delegate to **@security-engineer**:
|
||||
```
|
||||
@security-engineer Sign macOS binaries with Developer ID:
|
||||
|
||||
1. Verify Developer ID certificate is installed:
|
||||
security find-identity -v -p codesigning
|
||||
|
||||
2. Sign all plugin formats with hardened runtime:
|
||||
codesign --force --sign "Developer ID Application: <Name>" \
|
||||
--options runtime \
|
||||
--entitlements Resources/Entitlements.plist \
|
||||
--timestamp \
|
||||
MyPlugin.vst3
|
||||
|
||||
codesign --force --sign "Developer ID Application: <Name>" \
|
||||
--options runtime \
|
||||
--timestamp \
|
||||
MyPlugin.component
|
||||
|
||||
(Repeat for AAX if applicable)
|
||||
|
||||
3. Verify signatures:
|
||||
codesign --verify --deep --strict MyPlugin.vst3
|
||||
codesign --display --verbose=4 MyPlugin.vst3
|
||||
|
||||
4. Check Gatekeeper acceptance:
|
||||
spctl --assess --type execute --verbose MyPlugin.vst3
|
||||
|
||||
Report any signing errors immediately.
|
||||
```
|
||||
|
||||
9. **Windows Code Signing**
|
||||
- Delegate to **@security-engineer**:
|
||||
```
|
||||
@security-engineer Sign Windows binaries with Authenticode:
|
||||
|
||||
1. Verify code signing certificate is available:
|
||||
certutil -store "My"
|
||||
|
||||
2. Sign all plugin formats:
|
||||
signtool sign /f certificate.pfx /p <password> \
|
||||
/tr http://timestamp.digicert.com \
|
||||
/td sha256 /fd sha256 \
|
||||
MyPlugin.vst3
|
||||
|
||||
(Repeat for AAX, Standalone .exe)
|
||||
|
||||
3. Verify signatures:
|
||||
signtool verify /pa /v MyPlugin.vst3
|
||||
|
||||
Report any signing errors immediately.
|
||||
```
|
||||
|
||||
### Phase 4: macOS Notarization
|
||||
|
||||
10. **Submit for Notarization** (macOS only, if --notarize true)
|
||||
- Delegate to **@build-engineer**:
|
||||
```
|
||||
@build-engineer Notarize macOS builds with Apple:
|
||||
|
||||
1. Create ZIP archives for notarization:
|
||||
ditto -c -k --keepParent MyPlugin.vst3 MyPlugin-vst3.zip
|
||||
ditto -c -k --keepParent MyPlugin.component MyPlugin-au.zip
|
||||
|
||||
2. Submit to Apple notary service:
|
||||
xcrun notarytool submit MyPlugin-vst3.zip \
|
||||
--apple-id <email> \
|
||||
--team-id <team-id> \
|
||||
--password <app-specific-password> \
|
||||
--wait
|
||||
|
||||
(Repeat for AU)
|
||||
|
||||
3. If successful, staple the notarization ticket:
|
||||
xcrun stapler staple MyPlugin.vst3
|
||||
xcrun stapler staple MyPlugin.component
|
||||
|
||||
4. Verify notarization:
|
||||
spctl -a -vvv -t install MyPlugin.vst3
|
||||
|
||||
Notarization can take 5-30 minutes. Monitor progress and report status.
|
||||
```
|
||||
|
||||
### Phase 5: Installer Creation
|
||||
|
||||
11. **Create macOS DMG Installer** (if --create-dmg)
|
||||
- Delegate to **@build-engineer**:
|
||||
```
|
||||
@build-engineer Create macOS DMG installer:
|
||||
|
||||
1. Prepare installer directory structure:
|
||||
mkdir -p installer-mac/MyPlugin
|
||||
cp -R MyPlugin.vst3 installer-mac/MyPlugin/
|
||||
cp -R MyPlugin.component installer-mac/MyPlugin/
|
||||
cp README.txt installer-mac/MyPlugin/
|
||||
cp LICENSE.txt installer-mac/MyPlugin/
|
||||
|
||||
2. Create DMG with hdiutil:
|
||||
hdiutil create -volname "MyPlugin <version>" \
|
||||
-srcfolder installer-mac/MyPlugin \
|
||||
-ov -format UDZO \
|
||||
MyPlugin-<version>-macOS.dmg
|
||||
|
||||
3. Sign the DMG:
|
||||
codesign --sign "Developer ID Application: <Name>" \
|
||||
--timestamp \
|
||||
MyPlugin-<version>-macOS.dmg
|
||||
|
||||
4. Verify DMG:
|
||||
hdiutil verify MyPlugin-<version>-macOS.dmg
|
||||
codesign --verify MyPlugin-<version>-macOS.dmg
|
||||
```
|
||||
|
||||
12. **Create Windows NSIS Installer** (if --create-exe)
|
||||
- Delegate to **@build-engineer**:
|
||||
```
|
||||
@build-engineer Create Windows NSIS installer:
|
||||
|
||||
1. Install NSIS if not available:
|
||||
choco install nsis
|
||||
|
||||
2. Create installer script (MyPlugin.nsi):
|
||||
```nsis
|
||||
!include "MUI2.nsh"
|
||||
|
||||
Name "MyPlugin"
|
||||
OutFile "MyPlugin-<version>-Windows.exe"
|
||||
InstallDir "$PROGRAMFILES64\Common Files\VST3\MyPlugin.vst3"
|
||||
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_LICENSE "LICENSE.txt"
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
Section "Install"
|
||||
SetOutPath "$INSTDIR"
|
||||
File /r "MyPlugin.vst3"
|
||||
SectionEnd
|
||||
```
|
||||
|
||||
3. Compile installer:
|
||||
makensis MyPlugin.nsi
|
||||
|
||||
4. Sign the installer:
|
||||
signtool sign /f certificate.pfx /p <password> \
|
||||
/tr http://timestamp.digicert.com \
|
||||
/td sha256 /fd sha256 \
|
||||
MyPlugin-<version>-Windows.exe
|
||||
```
|
||||
|
||||
### Phase 6: Release Artifacts
|
||||
|
||||
13. **Generate Checksums**
|
||||
- Create SHA256 checksums for all artifacts:
|
||||
```bash
|
||||
# macOS
|
||||
shasum -a 256 MyPlugin-<version>-macOS.dmg > checksums.txt
|
||||
|
||||
# Windows
|
||||
certutil -hashfile MyPlugin-<version>-Windows.exe SHA256 >> checksums.txt
|
||||
|
||||
# Individual binaries
|
||||
shasum -a 256 MyPlugin.vst3 >> checksums.txt
|
||||
shasum -a 256 MyPlugin.component >> checksums.txt
|
||||
```
|
||||
|
||||
14. **Prepare Release Notes**
|
||||
- Delegate to **@support-engineer**:
|
||||
```
|
||||
@support-engineer Prepare release notes for version <version>:
|
||||
|
||||
1. Extract relevant section from CHANGELOG.md
|
||||
|
||||
2. Format release notes with:
|
||||
- What's New: New features and improvements
|
||||
- Bug Fixes: Issues resolved
|
||||
- Known Issues: Any current limitations
|
||||
- System Requirements: Minimum OS, DAW compatibility
|
||||
- Installation Instructions: How to install
|
||||
|
||||
3. Include upgrade notes if migrating from older versions
|
||||
|
||||
4. Add download links and checksums
|
||||
|
||||
Save as RELEASE_NOTES_<version>.md
|
||||
```
|
||||
|
||||
15. **Create Git Tag**
|
||||
- Tag the release in git:
|
||||
```bash
|
||||
git tag -a v<version> -m "Release version <version>"
|
||||
git push origin v<version>
|
||||
```
|
||||
|
||||
### Phase 7: Distribution
|
||||
|
||||
16. **Upload to Distribution** (if --upload)
|
||||
- Upload artifacts to distribution server:
|
||||
```bash
|
||||
# Example: Upload to S3
|
||||
aws s3 cp MyPlugin-<version>-macOS.dmg s3://releases/myplugin/<version>/
|
||||
aws s3 cp MyPlugin-<version>-Windows.exe s3://releases/myplugin/<version>/
|
||||
aws s3 cp checksums.txt s3://releases/myplugin/<version>/
|
||||
aws s3 cp RELEASE_NOTES_<version>.md s3://releases/myplugin/<version>/
|
||||
```
|
||||
|
||||
17. **Final Verification**
|
||||
- Download artifacts from distribution server
|
||||
- Verify checksums match
|
||||
- Test install on clean machine (macOS and Windows)
|
||||
- Confirm plugins load in DAWs
|
||||
|
||||
## Output
|
||||
|
||||
The command generates:
|
||||
|
||||
### Build Artifacts
|
||||
|
||||
```
|
||||
release/
|
||||
├── v<version>/
|
||||
│ ├── macOS/
|
||||
│ │ ├── MyPlugin.vst3/ # Signed, notarized VST3
|
||||
│ │ ├── MyPlugin.component/ # Signed, notarized AU
|
||||
│ │ └── MyPlugin-<version>-macOS.dmg # Signed installer
|
||||
│ ├── Windows/
|
||||
│ │ ├── MyPlugin.vst3/ # Signed VST3
|
||||
│ │ └── MyPlugin-<version>-Windows.exe # Signed installer
|
||||
│ ├── Linux/
|
||||
│ │ └── MyPlugin.vst3/ # VST3 binary
|
||||
│ ├── checksums.txt # SHA256 checksums
|
||||
│ └── RELEASE_NOTES_<version>.md # Formatted release notes
|
||||
```
|
||||
|
||||
### Console Report
|
||||
|
||||
```
|
||||
========================================
|
||||
Release Build Summary
|
||||
========================================
|
||||
Version: 1.0.0
|
||||
Build Date: 2025-01-14 10:30:00 UTC
|
||||
Git Commit: abc123def456
|
||||
|
||||
Tests: PASSED (152/152)
|
||||
Pluginval: PASSED (Strictness 10)
|
||||
Manual QA: APPROVED
|
||||
|
||||
Platforms Built:
|
||||
✓ macOS (arm64, x86_64)
|
||||
✓ Windows (x64)
|
||||
✓ Linux (x86_64)
|
||||
|
||||
Formats Built:
|
||||
✓ VST3
|
||||
✓ AU (macOS)
|
||||
✓ AAX
|
||||
✓ Standalone
|
||||
|
||||
Code Signing:
|
||||
✓ macOS binaries signed (Developer ID)
|
||||
✓ Windows binaries signed (Authenticode)
|
||||
✓ macOS notarization complete
|
||||
✓ DMG installer signed
|
||||
✓ NSIS installer signed
|
||||
|
||||
Artifacts:
|
||||
MyPlugin-1.0.0-macOS.dmg (42.5 MB)
|
||||
MyPlugin-1.0.0-Windows.exe (38.2 MB)
|
||||
|
||||
Git Tag: v1.0.0
|
||||
Distribution: ✓ Uploaded to s3://releases/myplugin/1.0.0/
|
||||
|
||||
========================================
|
||||
Release Ready for Distribution
|
||||
========================================
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### macOS Code Signing
|
||||
|
||||
1. **Apple Developer Account** with Developer ID certificate
|
||||
2. **Xcode Command Line Tools** installed
|
||||
3. **App-specific password** for notarization:
|
||||
```bash
|
||||
# Generate at appleid.apple.com
|
||||
# Store in keychain:
|
||||
xcrun notarytool store-credentials "notary-profile" \
|
||||
--apple-id <email> \
|
||||
--team-id <team-id> \
|
||||
--password <app-specific-password>
|
||||
```
|
||||
|
||||
4. **Entitlements file** (Resources/Entitlements.plist):
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
||||
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
### Windows Code Signing
|
||||
|
||||
1. **Code signing certificate** (EV or standard certificate)
|
||||
2. **Windows SDK** installed (for signtool.exe)
|
||||
3. **Certificate installed** in Windows certificate store or .pfx file
|
||||
4. **Timestamp server** access (e.g., DigiCert, Sectigo)
|
||||
|
||||
### NSIS Installer (Windows)
|
||||
|
||||
1. Install NSIS:
|
||||
```bash
|
||||
# Windows (Chocolatey)
|
||||
choco install nsis
|
||||
|
||||
# Or download from: https://nsis.sourceforge.io/
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Code Signing Best Practices
|
||||
|
||||
1. **Never commit signing credentials** to version control
|
||||
2. **Use environment variables** for passwords:
|
||||
```bash
|
||||
export APPLE_ID="developer@example.com"
|
||||
export NOTARIZATION_PASSWORD="xxxx-xxxx-xxxx-xxxx"
|
||||
export WIN_CERT_PASSWORD="..."
|
||||
```
|
||||
|
||||
3. **Protect certificate files** with restricted permissions:
|
||||
```bash
|
||||
chmod 600 certificate.pfx
|
||||
```
|
||||
|
||||
4. **Use CI/CD secrets** for automated builds:
|
||||
- GitHub Actions: Repository Secrets
|
||||
- GitLab CI: CI/CD Variables (masked, protected)
|
||||
|
||||
### Notarization Tips
|
||||
|
||||
- **Notarization can fail** if binaries contain issues:
|
||||
- Unsigned nested frameworks
|
||||
- Missing entitlements
|
||||
- Invalid bundle structure
|
||||
|
||||
- **Check notary log** if submission fails:
|
||||
```bash
|
||||
xcrun notarytool log <submission-id> --apple-id <email>
|
||||
```
|
||||
|
||||
- **Common fixes**:
|
||||
- Sign all nested binaries before parent bundle
|
||||
- Use `--deep` flag cautiously (can cause issues)
|
||||
- Verify bundle structure with `pkgutil --check-signature`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Build Failures
|
||||
|
||||
**Symptom**: CMake configuration fails
|
||||
```
|
||||
Solution:
|
||||
1. Check JUCE submodule is initialized: git submodule update --init
|
||||
2. Verify CMakeLists.txt is valid
|
||||
3. Ensure all dependencies are installed
|
||||
4. Clear CMake cache: rm -rf build/ CMakeCache.txt
|
||||
```
|
||||
|
||||
**Symptom**: Linking errors in Release build
|
||||
```
|
||||
Solution:
|
||||
1. Check for missing symbols in DSP code
|
||||
2. Verify all source files are included in CMakeLists.txt
|
||||
3. Ensure static libraries are built before plugin
|
||||
4. Try disabling LTO temporarily to isolate issue
|
||||
```
|
||||
|
||||
### Code Signing Failures
|
||||
|
||||
**Symptom**: macOS codesign fails with "no identity found"
|
||||
```
|
||||
Solution:
|
||||
1. Check certificate is installed: security find-identity -v
|
||||
2. Verify certificate is valid (not expired)
|
||||
3. Ensure certificate is for "Developer ID Application"
|
||||
4. Import certificate if needed: double-click .p12 file
|
||||
```
|
||||
|
||||
**Symptom**: Windows signtool "file not found"
|
||||
```
|
||||
Solution:
|
||||
1. Ensure Windows SDK is installed
|
||||
2. Add signtool to PATH: C:\Program Files (x86)\Windows Kits\10\bin\<version>\x64
|
||||
3. Verify certificate is in store: certutil -store "My"
|
||||
```
|
||||
|
||||
### Notarization Failures
|
||||
|
||||
**Symptom**: "The binary is not signed with a valid Developer ID"
|
||||
```
|
||||
Solution:
|
||||
1. Re-sign with --force flag
|
||||
2. Ensure using "Developer ID Application" certificate (not "Mac Developer")
|
||||
3. Verify signature: codesign --verify --deep --strict MyPlugin.vst3
|
||||
```
|
||||
|
||||
**Symptom**: "The signature does not include a secure timestamp"
|
||||
```
|
||||
Solution:
|
||||
1. Add --timestamp flag to codesign command
|
||||
2. Ensure internet connection (timestamp server must be reachable)
|
||||
3. Retry if timestamp server is temporarily down
|
||||
```
|
||||
|
||||
**Symptom**: Notarization stuck "In Progress" for hours
|
||||
```
|
||||
Solution:
|
||||
1. Check status: xcrun notarytool info <submission-id>
|
||||
2. Apple's servers can be slow; wait up to 1 hour
|
||||
3. If genuinely stuck, cancel and resubmit
|
||||
```
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Version number validated (semantic versioning)
|
||||
- [ ] Git tag doesn't already exist
|
||||
- [ ] CHANGELOG.md has entry for this version
|
||||
- [ ] All unit tests pass
|
||||
- [ ] Pluginval passes at strictness 10
|
||||
- [ ] Manual QA approved (unless --skip-qa)
|
||||
- [ ] All target platforms built successfully
|
||||
- [ ] All target formats built (VST3, AU, AAX, Standalone)
|
||||
- [ ] macOS binaries signed with Developer ID
|
||||
- [ ] Windows binaries signed with Authenticode
|
||||
- [ ] macOS binaries notarized (if --notarize true)
|
||||
- [ ] macOS DMG created and signed (if --create-dmg)
|
||||
- [ ] Windows NSIS installer created and signed (if --create-exe)
|
||||
- [ ] SHA256 checksums generated
|
||||
- [ ] Release notes prepared
|
||||
- [ ] Git tag created and pushed
|
||||
- [ ] Artifacts uploaded (if --upload)
|
||||
- [ ] Final verification completed (download, install, test)
|
||||
|
||||
## Related Commands
|
||||
|
||||
- `/build-all-formats` - Build plugin formats without release packaging
|
||||
- `/run-pluginval` - Run plugin validation
|
||||
- Use JUCE Best Practices skill for realtime safety
|
||||
- Use Cross-Platform Builds skill for platform-specific details
|
||||
- See BUILD_GUIDE.md for detailed build instructions
|
||||
- See RELEASE_CHECKLIST.md for manual release steps
|
||||
|
||||
## Agent Delegation
|
||||
|
||||
This command orchestrates multiple expert agents:
|
||||
|
||||
- **@test-automation-engineer**: Runs comprehensive test suite
|
||||
- **@qa-engineer**: Executes manual validation and provides go/no-go
|
||||
- **@build-engineer**: Manages build environment, compilation, installers, notarization
|
||||
- **@security-engineer**: Handles code signing for macOS and Windows
|
||||
- **@support-engineer**: Prepares release notes and documentation
|
||||
- **@technical-lead**: Resolves any architectural issues during build
|
||||
|
||||
## Notes
|
||||
|
||||
- **Release builds should never skip tests** in production workflow
|
||||
- **Always test on clean machines** before distributing
|
||||
- **Keep signing credentials secure** - use environment variables or CI/CD secrets
|
||||
- **Notarization is required for macOS 10.15+** (Catalina and later)
|
||||
- **Windows code signing is optional** but highly recommended for trust
|
||||
- **AAX requires separate iLok signing** via PACE Eden system (not covered here)
|
||||
- **Use semantic versioning** for clarity: MAJOR.MINOR.PATCH
|
||||
- **Document breaking changes** in CHANGELOG.md and release notes
|
||||
|
||||
---
|
||||
|
||||
**For detailed build procedures**, see `BUILD_GUIDE.md`
|
||||
**For manual release checklist**, see `RELEASE_CHECKLIST.md`
|
||||
895
commands/run-daw-tests.md
Normal file
895
commands/run-daw-tests.md
Normal file
@@ -0,0 +1,895 @@
|
||||
---
|
||||
argument-hint: "[format] [platform] [--quick|--full]"
|
||||
description: "Comprehensive DAW compatibility testing across Logic Pro, Ableton Live, Pro Tools, Cubase, Reaper, FL Studio, Bitwig, and Ardour"
|
||||
allowed-tools: Bash, Read, Write, AskUserQuestion
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
# /run-daw-tests - DAW Compatibility Testing
|
||||
|
||||
Execute comprehensive compatibility testing across multiple DAWs to ensure your JUCE plugin works correctly in all major digital audio workstations.
|
||||
|
||||
## Overview
|
||||
|
||||
This command automates DAW compatibility testing, guiding you through validation in Logic Pro, Ableton Live, Pro Tools, Cubase, Reaper, FL Studio, Bitwig, and Ardour. It ensures automation, state save/load, offline rendering, and format-specific features work correctly across platforms.
|
||||
|
||||
## Syntax
|
||||
|
||||
```bash
|
||||
/run-daw-tests [format] [platform] [--quick|--full]
|
||||
```
|
||||
|
||||
### Arguments
|
||||
|
||||
- `format` (optional): Target format - `vst3`, `au`, `aax`, `standalone`, or `all` (default: `all`)
|
||||
- `platform` (optional): Target platform - `macos`, `windows`, `linux`, or `current` (default: `current`)
|
||||
- `--quick`: Run essential tests only (3 DAWs, 30 min)
|
||||
- `--full`: Run comprehensive test matrix (all DAWs, 2-3 hours)
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Quick test in 3 major DAWs on current platform
|
||||
/run-daw-tests --quick
|
||||
|
||||
# Full test matrix for VST3 on macOS
|
||||
/run-daw-tests vst3 macos --full
|
||||
|
||||
# Test all formats on current platform
|
||||
/run-daw-tests all current --full
|
||||
|
||||
# Test AU format only (macOS)
|
||||
/run-daw-tests au macos --quick
|
||||
```
|
||||
|
||||
## Instructions
|
||||
|
||||
### Step 1: Pre-Flight Validation
|
||||
|
||||
**@test-automation-engineer** - Verify builds are ready for DAW testing.
|
||||
|
||||
1. **Check plugin builds exist:**
|
||||
```bash
|
||||
# macOS
|
||||
ls -la ~/Library/Audio/Plug-Ins/VST3/MyPlugin.vst3
|
||||
ls -la ~/Library/Audio/Plug-Ins/Components/MyPlugin.component
|
||||
|
||||
# Windows
|
||||
dir "%CommonProgramFiles%\VST3\MyPlugin.vst3"
|
||||
|
||||
# Linux
|
||||
ls -la ~/.vst3/MyPlugin.vst3
|
||||
```
|
||||
|
||||
2. **Verify plugin loads in standalone validator:**
|
||||
```bash
|
||||
# Run pluginval first
|
||||
pluginval --strictness-level 10 --validate MyPlugin.vst3
|
||||
```
|
||||
|
||||
3. **Check for critical issues:**
|
||||
- Build is Release configuration (not Debug)
|
||||
- No debug assertions enabled
|
||||
- Splash screen disabled (if commercial JUCE license)
|
||||
- Code signed (macOS/Windows production builds)
|
||||
|
||||
**If pluginval fails, STOP and fix issues before DAW testing.**
|
||||
|
||||
### Step 2: DAW Testing Matrix
|
||||
|
||||
**@daw-compatibility-engineer** + **@qa-engineer** - Execute systematic testing across DAWs.
|
||||
|
||||
Claude will guide you through DAW-by-DAW testing with standardized test procedures.
|
||||
|
||||
---
|
||||
|
||||
## Platform-Specific Test Plans
|
||||
|
||||
### macOS DAW Testing
|
||||
|
||||
#### 1. Logic Pro (AU and VST3)
|
||||
|
||||
**Time Estimate:** 20-30 minutes
|
||||
|
||||
**Prerequisites:**
|
||||
- Logic Pro installed (latest version recommended)
|
||||
- AU format: `~/Library/Audio/Plug-Ins/Components/MyPlugin.component`
|
||||
- VST3 format: `~/Library/Audio/Plug-Ins/VST3/MyPlugin.vst3`
|
||||
|
||||
**Test Procedure:**
|
||||
|
||||
1. **AU Validation:**
|
||||
```bash
|
||||
# Run Apple's auval
|
||||
auval -v aufx Plug Manu # Replace with your plugin type, code, manufacturer
|
||||
# Must show "PASS" - if it fails, fix before continuing
|
||||
```
|
||||
|
||||
2. **Plugin Loading (AU):**
|
||||
- Open Logic Pro
|
||||
- Create new empty project
|
||||
- Add audio track
|
||||
- Load plugin from AU menu
|
||||
- **Verify:** Plugin window opens without errors
|
||||
- **Verify:** UI displays correctly on Retina displays
|
||||
- **Check:** No console errors: `Console.app → Filter: Logic`
|
||||
|
||||
3. **Plugin Loading (VST3):**
|
||||
- Reset plugin manager: `Logic Pro → Preferences → Plug-In Manager → Reset & Rescan`
|
||||
- Load plugin from VST3 menu
|
||||
- **Verify:** VST3 and AU versions don't conflict
|
||||
|
||||
4. **Automation Recording:**
|
||||
- Enable automation: `A` key
|
||||
- Adjust plugin parameter while playing
|
||||
- **Verify:** Automation curve appears in track
|
||||
- **Verify:** Playback follows automation smoothly
|
||||
|
||||
5. **Automation Playback:**
|
||||
- Create automation ramps (slow and fast)
|
||||
- **Test:** Parameter changes are smooth (no zipper noise)
|
||||
- **Test:** Modulation tracks automation precisely
|
||||
|
||||
6. **State Save/Load:**
|
||||
- Adjust several parameters
|
||||
- Save project: `⌘S`
|
||||
- Close Logic Pro
|
||||
- Reopen project
|
||||
- **Verify:** All parameters restored exactly
|
||||
- **Verify:** Plugin state is identical
|
||||
|
||||
7. **Offline Bounce:**
|
||||
- Set project tempo to 120 BPM
|
||||
- Create automation on tempo-synced parameter
|
||||
- Bounce: `⌘B` → set format
|
||||
- Also record realtime pass
|
||||
- **Verify:** Offline bounce matches realtime render (compare waveforms)
|
||||
|
||||
8. **Multiple Instances:**
|
||||
- Add 10+ instances of plugin
|
||||
- **Verify:** No crashes or performance issues
|
||||
- **Verify:** Each instance maintains independent state
|
||||
- **Check:** CPU meter stays reasonable
|
||||
|
||||
9. **Logic-Specific Features:**
|
||||
- **Verify:** Plugin appears in correct category
|
||||
- **Test:** Side-chain routing (if applicable)
|
||||
- **Test:** Plugin delay compensation works
|
||||
|
||||
**Report Issues:**
|
||||
- Screenshot any visual glitches
|
||||
- Note exact steps to reproduce any bugs
|
||||
- Check Console.app for crash logs: `~/Library/Logs/DiagnosticReports/`
|
||||
|
||||
---
|
||||
|
||||
#### 2. Ableton Live (VST3)
|
||||
|
||||
**Time Estimate:** 15-20 minutes
|
||||
|
||||
**Prerequisites:**
|
||||
- Ableton Live installed
|
||||
- VST3 format: `~/Library/Audio/Plug-Ins/VST3/MyPlugin.vst3`
|
||||
|
||||
**Test Procedure:**
|
||||
|
||||
1. **Plugin Loading:**
|
||||
- Launch Ableton Live
|
||||
- Rescan plugins: `Preferences → Plug-Ins → Rescan`
|
||||
- Drag plugin onto track
|
||||
- **Verify:** Device view displays correctly
|
||||
- **Verify:** Plugin responds to input
|
||||
|
||||
2. **Automation:**
|
||||
- Show automation lane
|
||||
- Record automation on key parameter
|
||||
- **Test:** Breakpoint automation (not just lines)
|
||||
- **Verify:** Automation playback is smooth
|
||||
|
||||
3. **Undo/Redo:**
|
||||
- Change multiple parameters
|
||||
- Undo: `⌘Z` repeatedly
|
||||
- Redo: `⌘⇧Z`
|
||||
- **Verify:** All parameter changes tracked correctly
|
||||
- **Verify:** No crashes on undo/redo
|
||||
|
||||
4. **Project Save/Load:**
|
||||
- Save Live set
|
||||
- Close and reopen
|
||||
- **Verify:** Plugin state restored
|
||||
- **Verify:** Automation preserved
|
||||
|
||||
5. **Freeze/Flatten:**
|
||||
- Freeze track with plugin
|
||||
- **Verify:** Frozen audio is correct
|
||||
- Flatten to audio
|
||||
- **Verify:** Result matches realtime
|
||||
|
||||
6. **CPU Efficiency:**
|
||||
- Check Live's CPU meter with plugin active
|
||||
- **Verify:** CPU usage is reasonable
|
||||
- Test with high track count (20+ instances)
|
||||
|
||||
**Ableton-Specific Tests:**
|
||||
- **Test:** Macro mapping (map plugin param to Live macro)
|
||||
- **Test:** Plug-in delay compensation indicator
|
||||
- **Verify:** Plugin works in both Arrangement and Session view
|
||||
|
||||
---
|
||||
|
||||
#### 3. Reaper (VST3 and AU)
|
||||
|
||||
**Time Estimate:** 15 minutes
|
||||
|
||||
**Prerequisites:**
|
||||
- Reaper installed
|
||||
- Both VST3 and AU formats available
|
||||
|
||||
**Test Procedure:**
|
||||
|
||||
1. **Plugin Scanning:**
|
||||
- `Preferences → Plug-ins → VST → Re-scan`
|
||||
- `Preferences → Plug-ins → AU → Re-scan`
|
||||
- **Verify:** Both formats appear
|
||||
|
||||
2. **Basic Functionality:**
|
||||
- Add plugin to track FX chain
|
||||
- **Verify:** UI displays correctly
|
||||
- **Test:** Parameter changes reflect immediately
|
||||
|
||||
3. **State Management:**
|
||||
- Adjust parameters
|
||||
- Save project
|
||||
- Reload project
|
||||
- **Verify:** State restored perfectly
|
||||
|
||||
4. **Automation:**
|
||||
- Show track envelope for plugin parameter
|
||||
- Draw automation curve
|
||||
- **Verify:** Playback follows automation
|
||||
- **Test:** Both slow and fast parameter changes
|
||||
|
||||
5. **Reaper-Specific:**
|
||||
- **Test:** Plugin works in FX chain and track input FX
|
||||
- **Test:** Offline processing mode
|
||||
- **Verify:** Plugin bypasses cleanly
|
||||
|
||||
---
|
||||
|
||||
#### 4. Pro Tools (AAX) - If Available
|
||||
|
||||
**Time Estimate:** 20 minutes
|
||||
|
||||
**Prerequisites:**
|
||||
- Pro Tools installed
|
||||
- AAX format code-signed with PACE iLok
|
||||
- iLok with valid developer account
|
||||
|
||||
**Test Procedure:**
|
||||
|
||||
1. **AAX Validation:**
|
||||
- Launch Pro Tools
|
||||
- Check plugin appears in correct category
|
||||
- **Verify:** No "damaged" or "unsigned" warnings
|
||||
|
||||
2. **Plugin Loading:**
|
||||
- Create audio track
|
||||
- Add plugin as insert
|
||||
- **Verify:** Plugin GUI opens
|
||||
- **Verify:** AAX wrapper reports correct latency
|
||||
|
||||
3. **Automation:**
|
||||
- Enable automation mode
|
||||
- Write automation (Latch mode)
|
||||
- **Verify:** Automation writes correctly
|
||||
- Switch to Read mode
|
||||
- **Verify:** Automation plays back accurately
|
||||
|
||||
4. **AudioSuite Mode (Offline Processing):**
|
||||
- Select audio region
|
||||
- `AudioSuite → [Your Plugin Category] → MyPlugin`
|
||||
- Process audio offline
|
||||
- **Verify:** Result matches realtime processing
|
||||
|
||||
5. **Session Save/Load:**
|
||||
- Save session
|
||||
- Close Pro Tools
|
||||
- Reopen session
|
||||
- **Verify:** Plugin state and automation restored
|
||||
|
||||
6. **Pro Tools Specifics:**
|
||||
- **Test:** Plugin delay compensation (PDC) reporting
|
||||
- **Verify:** No clicks on bypass enable/disable
|
||||
- **Test:** Works in both Mono and Stereo formats
|
||||
|
||||
---
|
||||
|
||||
### Windows DAW Testing
|
||||
|
||||
#### 5. Ableton Live (Windows - VST3)
|
||||
|
||||
**Time Estimate:** 15 minutes
|
||||
|
||||
**Prerequisites:**
|
||||
- Ableton Live (Windows)
|
||||
- VST3: `C:\Program Files\Common Files\VST3\MyPlugin.vst3`
|
||||
|
||||
**Test Procedure:**
|
||||
|
||||
1. **Plugin Loading:**
|
||||
- Launch Live
|
||||
- Rescan VST plugins
|
||||
- Load plugin
|
||||
- **Verify:** No missing dependencies (MSVC runtime)
|
||||
- **Verify:** UI displays on high-DPI displays (125%, 150%, 200%)
|
||||
|
||||
2. **Functionality Tests:**
|
||||
- Follow macOS Ableton tests (Steps 2-6 from above)
|
||||
- **Additional:** Test on multiple monitors
|
||||
|
||||
3. **Windows-Specific:**
|
||||
- **Verify:** No antivirus false positives
|
||||
- **Check:** Task Manager for memory leaks during long sessions
|
||||
|
||||
---
|
||||
|
||||
#### 6. FL Studio (VST3)
|
||||
|
||||
**Time Estimate:** 15 minutes
|
||||
|
||||
**Prerequisites:**
|
||||
- FL Studio installed
|
||||
- VST3 format in plugin path
|
||||
|
||||
**Test Procedure:**
|
||||
|
||||
1. **Plugin Loading:**
|
||||
- Add plugin to mixer track
|
||||
- **Verify:** Plugin loads without errors
|
||||
- **Verify:** Wrapper integration works correctly
|
||||
|
||||
2. **FL Studio Wrapper:**
|
||||
- **Test:** Generic wrapper GUI vs plugin GUI
|
||||
- **Verify:** Parameter automation works
|
||||
- **Check:** No conflicts with FL's internal routing
|
||||
|
||||
3. **State Save/Load:**
|
||||
- Save project (.flp)
|
||||
- Reload
|
||||
- **Verify:** Plugin state preserved
|
||||
- **Test:** Preset saving in FL's browser
|
||||
|
||||
4. **Multiple Instances:**
|
||||
- Load 10+ instances
|
||||
- **Verify:** No multi-instance issues (FL Studio has had issues here)
|
||||
- **Verify:** Each instance independent
|
||||
|
||||
5. **Rendering:**
|
||||
- Render to audio file
|
||||
- **Verify:** No artifacts or glitches
|
||||
- **Compare:** Realtime vs. offline render
|
||||
|
||||
---
|
||||
|
||||
#### 7. Cubase/Nuendo (VST3)
|
||||
|
||||
**Time Estimate:** 15 minutes
|
||||
|
||||
**Prerequisites:**
|
||||
- Cubase or Nuendo installed
|
||||
- VST3 format
|
||||
|
||||
**Test Procedure:**
|
||||
|
||||
1. **Plugin Loading:**
|
||||
- VST Plug-in Manager → Rescan
|
||||
- Add plugin to audio track
|
||||
- **Verify:** Plugin appears in correct category
|
||||
|
||||
2. **Automation:**
|
||||
- Show automation track
|
||||
- Write automation (W mode)
|
||||
- **Test:** Ramp automation
|
||||
- **Verify:** Playback is smooth
|
||||
|
||||
3. **Expression Maps (If Applicable):**
|
||||
- Test MIDI/parameter interactions
|
||||
- Verify plugin responds correctly
|
||||
|
||||
4. **Offline Processing:**
|
||||
- Direct Offline Processing
|
||||
- Apply plugin to region
|
||||
- **Verify:** Matches realtime
|
||||
|
||||
5. **Project Save/Load:**
|
||||
- Standard save/load test
|
||||
- **Verify:** State restoration
|
||||
|
||||
---
|
||||
|
||||
#### 8. Reaper (Windows - VST3)
|
||||
|
||||
**Time Estimate:** 10 minutes
|
||||
|
||||
**Prerequisites:**
|
||||
- Reaper (Windows)
|
||||
- VST3 format
|
||||
|
||||
**Test Procedure:**
|
||||
- Follow macOS Reaper tests (adapted for Windows paths)
|
||||
- **Verify:** No Windows-specific issues
|
||||
|
||||
---
|
||||
|
||||
### Linux DAW Testing
|
||||
|
||||
#### 9. Reaper (Linux - VST3)
|
||||
|
||||
**Time Estimate:** 10 minutes
|
||||
|
||||
**Prerequisites:**
|
||||
- Reaper for Linux
|
||||
- VST3: `~/.vst3/MyPlugin.vst3`
|
||||
|
||||
**Test Procedure:**
|
||||
|
||||
1. **Plugin Loading:**
|
||||
- Rescan VST3 plugins
|
||||
- Load plugin
|
||||
- **Verify:** No missing dependencies: `ldd MyPlugin.vst3`
|
||||
|
||||
2. **Basic Functionality:**
|
||||
- Parameter changes work
|
||||
- State save/load works
|
||||
- Automation works
|
||||
|
||||
3. **Linux-Specific:**
|
||||
- **Test:** Different desktop environments (GNOME, KDE, XFCE)
|
||||
- **Verify:** UI scaling on HiDPI displays
|
||||
- **Check:** No X11/Wayland issues
|
||||
|
||||
---
|
||||
|
||||
#### 10. Ardour (VST3)
|
||||
|
||||
**Time Estimate:** 10 minutes
|
||||
|
||||
**Prerequisites:**
|
||||
- Ardour installed
|
||||
- VST3 format
|
||||
|
||||
**Test Procedure:**
|
||||
|
||||
1. **Plugin Manager:**
|
||||
- Rescan plugins
|
||||
- Verify plugin appears
|
||||
|
||||
2. **Basic Tests:**
|
||||
- Add to track
|
||||
- Test automation
|
||||
- Save/load session
|
||||
- **Verify:** State preservation
|
||||
|
||||
3. **Ardour-Specific:**
|
||||
- **Test:** Plugin latency compensation
|
||||
- **Verify:** Works with Ardour's routing
|
||||
|
||||
---
|
||||
|
||||
#### 11. Bitwig Studio (VST3)
|
||||
|
||||
**Time Estimate:** 10 minutes
|
||||
|
||||
**Prerequisites:**
|
||||
- Bitwig Studio
|
||||
- VST3 format
|
||||
|
||||
**Test Procedure:**
|
||||
|
||||
1. **Plugin Loading:**
|
||||
- Rescan plugins
|
||||
- Load plugin on track
|
||||
- **Verify:** UI displays correctly
|
||||
|
||||
2. **Bitwig Modulation:**
|
||||
- Map Bitwig modulator to plugin parameter
|
||||
- **Verify:** Modulation works smoothly
|
||||
- **Test:** No conflicts with plugin's internal modulation
|
||||
|
||||
3. **Project Management:**
|
||||
- Save project
|
||||
- Reload
|
||||
- **Verify:** State restored
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Cross-DAW Compatibility Validation
|
||||
|
||||
**@daw-compatibility-engineer** - Verify consistency across DAWs.
|
||||
|
||||
After testing individual DAWs, perform cross-DAW validation:
|
||||
|
||||
### 1. Preset Compatibility
|
||||
|
||||
**Test:** Do presets work across all DAWs?
|
||||
|
||||
```bash
|
||||
# Save preset in Logic Pro (AU)
|
||||
# Load same preset in Ableton Live (VST3)
|
||||
# Verify parameters are identical
|
||||
```
|
||||
|
||||
**Expected:** Presets should transfer seamlessly between DAW formats.
|
||||
|
||||
**Common Issue:** AU `.aupreset` vs VST3 `.vstpreset` - ensure both save correctly.
|
||||
|
||||
### 2. Automation Consistency
|
||||
|
||||
**Test:** Does automation sound identical across DAWs?
|
||||
|
||||
- Create same automation curve in 3 different DAWs
|
||||
- Bounce/render each
|
||||
- Compare waveforms (should be bit-identical or very close)
|
||||
|
||||
**Expected:** Sample-accurate automation across DAWs.
|
||||
|
||||
**Common Issue:** Different smoothing algorithms can cause minor differences.
|
||||
|
||||
### 3. Offline vs Realtime Rendering
|
||||
|
||||
**Test:** Does offline rendering match realtime in all DAWs?
|
||||
|
||||
- Test in Logic Pro, Ableton Live, Reaper, Pro Tools
|
||||
- Compare realtime and offline bounces
|
||||
|
||||
**Expected:** Bit-perfect match (or extremely close).
|
||||
|
||||
**Red Flag:** If renders differ significantly, investigate:
|
||||
- Buffer size assumptions in DSP code
|
||||
- Tempo-sync calculations
|
||||
- Randomization/non-determinism
|
||||
|
||||
### 4. State Serialization Compatibility
|
||||
|
||||
**Test:** Can projects transfer between DAWs?
|
||||
|
||||
- Save plugin state in one DAW
|
||||
- Manually load that state data in another DAW
|
||||
- Verify parameter values match
|
||||
|
||||
**Expected:** Same underlying state representation.
|
||||
|
||||
**Implementation:** Ensure `getStateInformation()` / `setStateInformation()` are format-agnostic.
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Generate Compatibility Matrix
|
||||
|
||||
**@qa-engineer** - Document test results.
|
||||
|
||||
Create a compatibility matrix spreadsheet:
|
||||
|
||||
| DAW | Platform | Format | Load | Automation | State Save | Offline Render | Issues |
|
||||
|-----|----------|--------|------|------------|------------|----------------|--------|
|
||||
| Logic Pro | macOS | AU | ✅ | ✅ | ✅ | ✅ | None |
|
||||
| Logic Pro | macOS | VST3 | ✅ | ✅ | ✅ | ✅ | None |
|
||||
| Ableton Live | macOS | VST3 | ✅ | ✅ | ✅ | ✅ | None |
|
||||
| Ableton Live | Windows | VST3 | ✅ | ⚠️ | ✅ | ✅ | Minor: Undo lag |
|
||||
| Pro Tools | macOS | AAX | ✅ | ✅ | ✅ | ✅ | None |
|
||||
| Reaper | macOS | AU | ✅ | ✅ | ✅ | ✅ | None |
|
||||
| Reaper | macOS | VST3 | ✅ | ✅ | ✅ | ✅ | None |
|
||||
| FL Studio | Windows | VST3 | ✅ | ✅ | ⚠️ | ✅ | State lost on crash |
|
||||
| Cubase | Windows | VST3 | ✅ | ✅ | ✅ | ✅ | None |
|
||||
| Bitwig | Linux | VST3 | ✅ | ✅ | ✅ | ✅ | None |
|
||||
|
||||
**Legend:**
|
||||
- ✅ Pass
|
||||
- ⚠️ Pass with minor issues
|
||||
- ❌ Fail
|
||||
- ➖ Not tested
|
||||
|
||||
**Save to:** `test-results/daw-compatibility-matrix-[date].md`
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Issue Documentation and Triage
|
||||
|
||||
**@support-engineer** - Document issues for engineering.
|
||||
|
||||
For each issue found, create structured bug report:
|
||||
|
||||
### Bug Report Template
|
||||
|
||||
```markdown
|
||||
## Issue: [Brief description]
|
||||
|
||||
**DAW:** Logic Pro 11.0.1
|
||||
**Platform:** macOS 14.5 (Sonoma)
|
||||
**Format:** AU
|
||||
**Severity:** Medium
|
||||
|
||||
### Steps to Reproduce
|
||||
1. Load plugin on audio track
|
||||
2. Enable automation
|
||||
3. Record automation on Cutoff parameter
|
||||
4. Save project and reopen
|
||||
|
||||
### Expected Behavior
|
||||
Automation curve should be preserved and play back smoothly.
|
||||
|
||||
### Actual Behavior
|
||||
Automation curve appears but playback has zipper noise on parameter changes.
|
||||
|
||||
### Additional Info
|
||||
- Happens only in Logic Pro (not in Live or Reaper)
|
||||
- Only affects Cutoff parameter (other parameters fine)
|
||||
- Console shows warning: "Parameter smoothing issue"
|
||||
|
||||
### Files
|
||||
- Project file: `repro-logic-automation.logicx`
|
||||
- Screen recording: `automation-bug.mov`
|
||||
- Console log: `console-errors.txt`
|
||||
```
|
||||
|
||||
**@daw-compatibility-engineer** - Investigate root cause and implement fixes.
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Performance Benchmarking
|
||||
|
||||
**@qa-engineer** - Measure performance in each DAW.
|
||||
|
||||
Document CPU usage across DAWs:
|
||||
|
||||
1. **Single Instance CPU:**
|
||||
- Load plugin on single track
|
||||
- Play audio through it
|
||||
- Record CPU usage from DAW's performance meter
|
||||
|
||||
2. **Multi-Instance Stress Test:**
|
||||
- Load 50 instances
|
||||
- Measure total CPU
|
||||
- Check for performance degradation (should scale linearly)
|
||||
|
||||
3. **Latency Reporting:**
|
||||
- Verify plugin reports latency correctly
|
||||
- Check that DAW's latency compensation works
|
||||
|
||||
**Expected:** Consistent performance across DAWs (within 10% variance).
|
||||
|
||||
**Red Flag:** If one DAW shows 2x CPU usage, investigate wrapper or host-specific issues.
|
||||
|
||||
---
|
||||
|
||||
## Quick Test Mode (--quick)
|
||||
|
||||
For rapid validation (30 minutes), test these 3 DAWs only:
|
||||
|
||||
### macOS:
|
||||
1. Logic Pro (AU) - 10 min
|
||||
2. Ableton Live (VST3) - 10 min
|
||||
3. Reaper (VST3) - 10 min
|
||||
|
||||
### Windows:
|
||||
1. Ableton Live (VST3) - 10 min
|
||||
2. FL Studio (VST3) - 10 min
|
||||
3. Reaper (VST3) - 10 min
|
||||
|
||||
### Linux:
|
||||
1. Reaper (VST3) - 10 min
|
||||
2. Bitwig (VST3) - 10 min
|
||||
3. Ardour (VST3) - 10 min
|
||||
|
||||
Run core tests only:
|
||||
- Plugin loads
|
||||
- Automation works
|
||||
- State saves/loads
|
||||
- No crashes
|
||||
|
||||
---
|
||||
|
||||
## Full Test Mode (--full)
|
||||
|
||||
Comprehensive testing (2-3 hours):
|
||||
- All DAWs listed above
|
||||
- All test procedures
|
||||
- Cross-DAW validation
|
||||
- Performance benchmarking
|
||||
- Issue documentation
|
||||
|
||||
---
|
||||
|
||||
## Automated Checks (Where Possible)
|
||||
|
||||
Some tests can be scripted:
|
||||
|
||||
### 1. Plugin Availability Check
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
function check_plugin_installed() {
|
||||
local format=$1
|
||||
local name=$2
|
||||
|
||||
case $format in
|
||||
vst3)
|
||||
[ -d ~/Library/Audio/Plug-Ins/VST3/$name.vst3 ] && echo "✅ VST3 found" || echo "❌ VST3 missing"
|
||||
;;
|
||||
au)
|
||||
[ -d ~/Library/Audio/Plug-Ins/Components/$name.component ] && echo "✅ AU found" || echo "❌ AU missing"
|
||||
;;
|
||||
aax)
|
||||
[ -d "/Library/Application Support/Avid/Audio/Plug-Ins/$name.aaxplugin" ] && echo "✅ AAX found" || echo "❌ AAX missing"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_plugin_installed vst3 MyPlugin
|
||||
check_plugin_installed au MyPlugin
|
||||
```
|
||||
|
||||
### 2. AU Validation (macOS)
|
||||
|
||||
```bash
|
||||
# Automated AU validation
|
||||
auval -v aufx Plug Manu 2>&1 | tee auval-results.txt
|
||||
|
||||
if grep -q "PASSED" auval-results.txt; then
|
||||
echo "✅ AU Validation Passed"
|
||||
else
|
||||
echo "❌ AU Validation Failed"
|
||||
cat auval-results.txt
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
### 3. Check for Missing Dependencies (Windows)
|
||||
|
||||
```powershell
|
||||
# Check for DLL dependencies
|
||||
$dllCheck = dumpbin /dependents "C:\Program Files\Common Files\VST3\MyPlugin.vst3\Contents\x86_64-win\MyPlugin.vst3"
|
||||
|
||||
if ($dllCheck -match "MSVCP|VCRUNTIME") {
|
||||
Write-Host "⚠️ Warning: MSVC runtime dependencies detected" -ForegroundColor Yellow
|
||||
Write-Host "Ensure static linking or distribute runtime"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Integration with CI/CD
|
||||
|
||||
Add DAW testing to GitHub Actions workflow:
|
||||
|
||||
```yaml
|
||||
# .github/workflows/daw-testing.yml
|
||||
name: DAW Compatibility Testing
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
daw-tests-macos:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Build plugin
|
||||
run: |
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build
|
||||
|
||||
- name: Install plugin
|
||||
run: |
|
||||
cp -r build/MyPlugin_artefacts/VST3/MyPlugin.vst3 ~/Library/Audio/Plug-Ins/VST3/
|
||||
cp -r build/MyPlugin_artefacts/AU/MyPlugin.component ~/Library/Audio/Plug-Ins/Components/
|
||||
|
||||
- name: Run auval
|
||||
run: |
|
||||
auval -v aufx Plug Manu
|
||||
|
||||
# Manual DAW testing must be done locally
|
||||
- name: Reminder
|
||||
run: echo "⚠️ Manual DAW testing required - see /run-daw-tests command"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
DAW testing is complete when:
|
||||
|
||||
- ✅ All targeted DAWs tested (quick or full mode)
|
||||
- ✅ Compatibility matrix generated and saved
|
||||
- ✅ All critical issues documented with repro steps
|
||||
- ✅ Performance benchmarks recorded
|
||||
- ✅ Cross-DAW consistency verified (presets, automation, rendering)
|
||||
- ✅ Results shared with team for triage
|
||||
- ✅ Regression testing plan created for future releases
|
||||
|
||||
---
|
||||
|
||||
## Common Issues and Solutions
|
||||
|
||||
### Issue: Plugin doesn't appear in DAW
|
||||
|
||||
**Cause:** Plugin not in correct location or not scanned.
|
||||
|
||||
**Solution:**
|
||||
- Verify plugin path (see platform-specific paths above)
|
||||
- Rescan plugins in DAW preferences
|
||||
- Check file permissions (should be readable)
|
||||
- macOS: Remove quarantine attribute: `xattr -dr com.apple.quarantine MyPlugin.vst3`
|
||||
|
||||
### Issue: AU validation fails on macOS
|
||||
|
||||
**Cause:** Apple's auval is very strict.
|
||||
|
||||
**Solution:**
|
||||
- Check `JucePlugin_*` defines in PluginProcessor.h
|
||||
- Ensure manufacturer code and plugin code are correct
|
||||
- Verify bundle ID matches: `com.yourcompany.pluginname`
|
||||
- Check Info.plist in AU bundle
|
||||
|
||||
### Issue: Automation has zipper noise
|
||||
|
||||
**Cause:** Insufficient parameter smoothing.
|
||||
|
||||
**Solution:**
|
||||
```cpp
|
||||
// In PluginProcessor.cpp
|
||||
void prepareToPlay(double sampleRate, int samplesPerBlock) {
|
||||
// Smooth parameters over ~20ms
|
||||
parameterSmoother.reset(sampleRate, 0.02);
|
||||
}
|
||||
|
||||
void processBlock(AudioBuffer<float>& buffer, MidiBuffer&) {
|
||||
auto cutoffTarget = *cutoffParam;
|
||||
auto smoothedCutoff = parameterSmoother.getNextValue(cutoffTarget);
|
||||
// Use smoothedCutoff in DSP
|
||||
}
|
||||
```
|
||||
|
||||
### Issue: Offline render doesn't match realtime
|
||||
|
||||
**Cause:** Non-deterministic behavior or tempo-sync assumptions.
|
||||
|
||||
**Solution:**
|
||||
- Remove any randomization or ensure seeded RNG
|
||||
- Use `getPlayHead()` for tempo info, don't assume fixed tempo
|
||||
- Ensure `prepareToPlay()` resets all state
|
||||
|
||||
### Issue: State doesn't restore correctly
|
||||
|
||||
**Cause:** `getStateInformation()` / `setStateInformation()` mismatch.
|
||||
|
||||
**Solution:**
|
||||
- Use `ValueTree::toXmlString()` and `ValueTree::fromXml()` for robust serialization
|
||||
- Test round-trip: save → load → save → compare
|
||||
- Version your state format for backward compatibility
|
||||
|
||||
---
|
||||
|
||||
## Expert Help
|
||||
|
||||
Delegate DAW testing tasks:
|
||||
|
||||
- **@daw-compatibility-engineer** - Lead DAW testing, investigate compatibility issues
|
||||
- **@qa-engineer** - Execute manual test procedures, document results
|
||||
- **@support-engineer** - Triage and document bug reports
|
||||
- **@test-automation-engineer** - Automate checks where possible
|
||||
- **@technical-lead** - Review critical issues and prioritize fixes
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- **TESTING_STRATEGY.md** - Overall testing approach
|
||||
- **RELEASE_CHECKLIST.md** - Pre-release validation (includes DAW testing)
|
||||
- **daw-compatibility-guide** skill - DAW-specific quirks and solutions
|
||||
- `/run-pluginval` command - Plugin format validation
|
||||
|
||||
---
|
||||
|
||||
**Remember:** DAW compatibility testing is critical for user satisfaction. Each DAW has unique quirks and behaviors. Thorough testing prevents support headaches and builds trust with users.
|
||||
558
commands/run-pluginval.md
Normal file
558
commands/run-pluginval.md
Normal file
@@ -0,0 +1,558 @@
|
||||
---
|
||||
argument-hint: "[format: vst3|au|aax|all] [strictness: 1-10]"
|
||||
description: "Run industry-standard pluginval validation tool on JUCE plugins with comprehensive tests and detailed reports"
|
||||
allowed-tools: Bash, Read, AskUserQuestion
|
||||
---
|
||||
|
||||
# Run Pluginval Validation
|
||||
|
||||
This command runs pluginval, the industry-standard JUCE plugin validation tool, on your built plugins. It automatically detects plugin formats, runs comprehensive tests, and generates detailed validation reports.
|
||||
|
||||
## Instructions
|
||||
|
||||
You are tasked with validating JUCE audio plugins using pluginval. Execute the following steps:
|
||||
|
||||
### 1. Check Pluginval Installation
|
||||
|
||||
Verify pluginval is installed and available:
|
||||
|
||||
```bash
|
||||
if ! command -v pluginval &> /dev/null; then
|
||||
echo "❌ pluginval not found"
|
||||
echo ""
|
||||
echo "Install pluginval:"
|
||||
echo ""
|
||||
echo "macOS:"
|
||||
echo " brew install pluginval"
|
||||
echo ""
|
||||
echo "Or download from:"
|
||||
echo " https://github.com/Tracktion/pluginval/releases"
|
||||
echo ""
|
||||
echo "After installing, ensure pluginval is in your PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify version
|
||||
pluginval_version=$(pluginval --version 2>&1 | head -1 || echo "unknown")
|
||||
echo "✓ pluginval found: $pluginval_version"
|
||||
```
|
||||
|
||||
### 2. Detect Built Plugins
|
||||
|
||||
Find all built plugin binaries:
|
||||
|
||||
```bash
|
||||
echo ""
|
||||
echo "🔍 Scanning for built plugins..."
|
||||
echo ""
|
||||
|
||||
# Find VST3 plugins
|
||||
vst3_plugins=$(find build -name "*.vst3" -type d 2>/dev/null)
|
||||
vst3_count=$(echo "$vst3_plugins" | grep -c ".vst3" || echo "0")
|
||||
|
||||
# Find AU plugins (macOS only)
|
||||
au_plugins=$(find build -name "*.component" -type d 2>/dev/null)
|
||||
au_count=$(echo "$au_plugins" | grep -c ".component" || echo "0")
|
||||
|
||||
# Find AAX plugins
|
||||
aax_plugins=$(find build -name "*.aaxplugin" -type d 2>/dev/null)
|
||||
aax_count=$(echo "$aax_plugins" | grep -c ".aaxplugin" || echo "0")
|
||||
|
||||
total_plugins=$((vst3_count + au_count + aax_count))
|
||||
|
||||
if [ $total_plugins -eq 0 ]; then
|
||||
echo "❌ No built plugins found in build/ directory"
|
||||
echo ""
|
||||
echo "Build your plugin first:"
|
||||
echo " /build-all-formats release"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Found $total_plugins plugin(s):"
|
||||
[ $vst3_count -gt 0 ] && echo " - $vst3_count VST3"
|
||||
[ $au_count -gt 0 ] && echo " - $au_count AU"
|
||||
[ $aax_count -gt 0 ] && echo " - $aax_count AAX"
|
||||
```
|
||||
|
||||
### 3. Determine Validation Scope
|
||||
|
||||
Use arguments or ask user which formats to validate:
|
||||
|
||||
```bash
|
||||
format_arg="${1:-all}"
|
||||
strictness="${2:-5}"
|
||||
|
||||
if [ "$format_arg" != "all" ] && [ "$format_arg" != "vst3" ] && [ "$format_arg" != "au" ] && [ "$format_arg" != "aax" ]; then
|
||||
echo "Invalid format: $format_arg"
|
||||
echo "Valid options: vst3, au, aax, all"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Validation Configuration:"
|
||||
echo " Format: $format_arg"
|
||||
echo " Strictness: $strictness/10 (higher = more thorough)"
|
||||
echo ""
|
||||
```
|
||||
|
||||
### 4. Configure Pluginval Options
|
||||
|
||||
Set up validation parameters based on strictness:
|
||||
|
||||
```bash
|
||||
# Base options (always used)
|
||||
pluginval_opts=(
|
||||
"--verbose"
|
||||
"--validate-in-process"
|
||||
"--output-dir" "build/pluginval-reports"
|
||||
)
|
||||
|
||||
# Strictness-based timeout (higher strictness = longer timeout)
|
||||
timeout=$((strictness * 30)) # 30 seconds per level
|
||||
pluginval_opts+=("--timeout-ms" "$((timeout * 1000))")
|
||||
|
||||
# Add strictness-specific tests
|
||||
if [ $strictness -ge 7 ]; then
|
||||
# Strict mode - enable all tests
|
||||
pluginval_opts+=("--strictness-level" "10")
|
||||
pluginval_opts+=("--random-seed" "42") # Reproducible random tests
|
||||
elif [ $strictness -ge 4 ]; then
|
||||
# Standard mode
|
||||
pluginval_opts+=("--strictness-level" "5")
|
||||
else
|
||||
# Quick validation
|
||||
pluginval_opts+=("--strictness-level" "1")
|
||||
pluginval_opts+=("--skip-gui-tests") # Skip GUI for speed
|
||||
fi
|
||||
|
||||
# Create output directory
|
||||
mkdir -p build/pluginval-reports
|
||||
```
|
||||
|
||||
### 5. Run Validation on Each Plugin
|
||||
|
||||
Execute pluginval for each detected plugin:
|
||||
|
||||
```bash
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "Starting Plugin Validation"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
passed=0
|
||||
failed=0
|
||||
skipped=0
|
||||
|
||||
validate_plugin() {
|
||||
local plugin_path="$1"
|
||||
local plugin_name=$(basename "$plugin_path")
|
||||
local format_type="$2"
|
||||
|
||||
echo "──────────────────────────────────────────"
|
||||
echo "Validating: $plugin_name ($format_type)"
|
||||
echo "──────────────────────────────────────────"
|
||||
echo ""
|
||||
|
||||
# Check if this format should be validated
|
||||
if [ "$format_arg" != "all" ] && [ "$format_arg" != "$format_type" ]; then
|
||||
echo "⊘ Skipped (format filter: $format_arg)"
|
||||
echo ""
|
||||
((skipped++))
|
||||
return
|
||||
fi
|
||||
|
||||
# Run pluginval
|
||||
local report_file="build/pluginval-reports/${plugin_name%.${format_type}}_${format_type}_report.txt"
|
||||
|
||||
if pluginval "${pluginval_opts[@]}" "$plugin_path" > "$report_file" 2>&1; then
|
||||
echo "✅ PASSED - All tests passed"
|
||||
((passed++))
|
||||
else
|
||||
echo "❌ FAILED - Validation issues detected"
|
||||
echo ""
|
||||
echo "Top issues:"
|
||||
grep -i "error\|fail\|warning" "$report_file" | head -10 || echo " (see full report)"
|
||||
((failed++))
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Full report: $report_file"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Validate VST3 plugins
|
||||
if [ -n "$vst3_plugins" ]; then
|
||||
while IFS= read -r plugin; do
|
||||
[ -n "$plugin" ] && validate_plugin "$plugin" "vst3"
|
||||
done <<< "$vst3_plugins"
|
||||
fi
|
||||
|
||||
# Validate AU plugins
|
||||
if [ -n "$au_plugins" ]; then
|
||||
while IFS= read -r plugin; do
|
||||
[ -n "$plugin" ] && validate_plugin "$plugin" "au"
|
||||
done <<< "$au_plugins"
|
||||
fi
|
||||
|
||||
# Validate AAX plugins
|
||||
if [ -n "$aax_plugins" ]; then
|
||||
while IFS= read -r plugin; do
|
||||
[ -n "$plugin" ] && validate_plugin "$plugin" "aax"
|
||||
done <<< "$aax_plugins"
|
||||
fi
|
||||
```
|
||||
|
||||
### 6. Generate Summary Report
|
||||
|
||||
Create comprehensive validation summary:
|
||||
|
||||
```bash
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "Validation Summary"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
total_validated=$((passed + failed))
|
||||
pass_rate=0
|
||||
if [ $total_validated -gt 0 ]; then
|
||||
pass_rate=$(( (passed * 100) / total_validated ))
|
||||
fi
|
||||
|
||||
echo "Results:"
|
||||
echo " ✅ Passed: $passed"
|
||||
echo " ❌ Failed: $failed"
|
||||
echo " ⊘ Skipped: $skipped"
|
||||
echo " ──────────────"
|
||||
echo " Total: $total_validated validated"
|
||||
echo ""
|
||||
echo "Pass Rate: $pass_rate%"
|
||||
echo ""
|
||||
|
||||
# Create markdown summary report
|
||||
cat > build/pluginval-reports/SUMMARY.md << EOF
|
||||
# Pluginval Validation Summary
|
||||
|
||||
**Date**: $(date '+%Y-%m-%d %H:%M:%S')
|
||||
**Strictness**: $strictness/10
|
||||
**Format Filter**: $format_arg
|
||||
|
||||
## Results
|
||||
|
||||
| Status | Count |
|
||||
|--------|-------|
|
||||
| ✅ Passed | $passed |
|
||||
| ❌ Failed | $failed |
|
||||
| ⊘ Skipped | $skipped |
|
||||
| **Total** | **$total_validated** |
|
||||
|
||||
**Pass Rate**: $pass_rate%
|
||||
|
||||
## Validated Plugins
|
||||
|
||||
### VST3
|
||||
$(if [ $vst3_count -gt 0 ]; then
|
||||
echo "$vst3_plugins" | while read plugin; do
|
||||
[ -n "$plugin" ] && echo "- $(basename "$plugin")"
|
||||
done
|
||||
else
|
||||
echo "None"
|
||||
fi)
|
||||
|
||||
### Audio Unit (AU)
|
||||
$(if [ $au_count -gt 0 ]; then
|
||||
echo "$au_plugins" | while read plugin; do
|
||||
[ -n "$plugin" ] && echo "- $(basename "$plugin")"
|
||||
done
|
||||
else
|
||||
echo "None"
|
||||
fi)
|
||||
|
||||
### AAX
|
||||
$(if [ $aax_count -gt 0 ]; then
|
||||
echo "$aax_plugins" | while read plugin; do
|
||||
[ -n "$plugin" ] && echo "- $(basename "$plugin")"
|
||||
done
|
||||
else
|
||||
echo "None"
|
||||
fi)
|
||||
|
||||
## Pluginval Configuration
|
||||
|
||||
\`\`\`
|
||||
Strictness: $strictness/10
|
||||
Timeout: ${timeout}s per plugin
|
||||
Random Seed: 42 (reproducible)
|
||||
\`\`\`
|
||||
|
||||
## Next Steps
|
||||
|
||||
$(if [ $failed -gt 0 ]; then
|
||||
echo "### Failed Validation"
|
||||
echo ""
|
||||
echo "Review individual reports in \`build/pluginval-reports/\`"
|
||||
echo ""
|
||||
echo "Common issues:"
|
||||
echo "- Parameter ranges not normalized (0-1)"
|
||||
echo "- State save/load not working correctly"
|
||||
echo "- Audio glitches at buffer boundaries"
|
||||
echo "- Memory leaks or allocations in processBlock"
|
||||
echo "- Thread safety violations"
|
||||
echo ""
|
||||
echo "Get help:"
|
||||
echo "\`\`\`"
|
||||
echo "@daw-compatibility-engineer review pluginval failures and suggest fixes"
|
||||
echo "@technical-lead review plugin architecture for validation issues"
|
||||
echo "\`\`\`"
|
||||
else
|
||||
echo "### All Tests Passed! ✅"
|
||||
echo ""
|
||||
echo "Your plugin(s) passed validation. Next steps:"
|
||||
echo ""
|
||||
echo "1. Test in real DAWs: Load in Ableton, Logic, Pro Tools, etc."
|
||||
echo "2. Run stress tests: \`/stress-test\` (when available)"
|
||||
echo "3. Build release: \`/release-build\` (when available)"
|
||||
fi)
|
||||
|
||||
---
|
||||
Generated by JUCE Dev Team - Pluginval Validation
|
||||
EOF
|
||||
|
||||
echo "📄 Summary report: build/pluginval-reports/SUMMARY.md"
|
||||
echo ""
|
||||
```
|
||||
|
||||
### 7. Display Detailed Failure Analysis
|
||||
|
||||
If failures occurred, provide guidance:
|
||||
|
||||
```bash
|
||||
if [ $failed -gt 0 ]; then
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "Failure Analysis"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
echo "Common Pluginval Failures & Fixes:"
|
||||
echo ""
|
||||
echo "1. Parameter Range Issues"
|
||||
echo " ❌ Parameters not normalized to 0-1"
|
||||
echo " ✅ Fix: Use NormalisableRange and ensure getValue() returns 0-1"
|
||||
echo ""
|
||||
echo "2. State Save/Load"
|
||||
echo " ❌ getStateInformation/setStateInformation not working"
|
||||
echo " ✅ Fix: Implement proper XML/binary state serialization"
|
||||
echo ""
|
||||
echo "3. Audio Processing"
|
||||
echo " ❌ Glitches at buffer boundaries or sample rate changes"
|
||||
echo " ✅ Fix: Reset state in prepareToPlay, handle all buffer sizes"
|
||||
echo ""
|
||||
echo "4. Memory Issues"
|
||||
echo " ❌ Allocations in processBlock"
|
||||
echo " ✅ Fix: Pre-allocate in prepareToPlay, use /juce-best-practices"
|
||||
echo ""
|
||||
echo "5. Thread Safety"
|
||||
echo " ❌ UI calls from audio thread"
|
||||
echo " ✅ Fix: Use atomics/AsyncUpdater for thread communication"
|
||||
echo ""
|
||||
|
||||
echo "Get Expert Help:"
|
||||
echo ""
|
||||
echo " @daw-compatibility-engineer analyze pluginval failures"
|
||||
echo " @technical-lead review architecture for validation issues"
|
||||
echo " @plugin-engineer fix state save/load implementation"
|
||||
echo ""
|
||||
fi
|
||||
```
|
||||
|
||||
### 8. Set Exit Code
|
||||
|
||||
Return appropriate exit code for CI integration:
|
||||
|
||||
```bash
|
||||
if [ $failed -eq 0 ]; then
|
||||
echo "✅ All validations passed!"
|
||||
exit 0
|
||||
else
|
||||
echo "❌ $failed plugin(s) failed validation"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
## Strictness Levels Explained
|
||||
|
||||
| Level | Duration | Tests | Use Case |
|
||||
|-------|----------|-------|----------|
|
||||
| 1-3 | Quick (1-3 min) | Basic | Rapid development iteration |
|
||||
| 4-6 | Standard (5-10 min) | Comprehensive | Pre-commit validation |
|
||||
| 7-9 | Thorough (15-30 min) | Extensive | Pre-release validation |
|
||||
| 10 | Extreme (30+ min) | All + stress | Final release validation |
|
||||
|
||||
## Pluginval Tests
|
||||
|
||||
Pluginval validates:
|
||||
|
||||
- **Parameter System**: Range, normalization, automation, smoothing
|
||||
- **State Management**: Save/restore, versioning, backward compatibility
|
||||
- **Audio Processing**: Buffer handling, sample rates, silence, DC offset
|
||||
- **Threading**: Realtime safety, no allocations, no locks
|
||||
- **MIDI**: Note on/off, CC, pitch bend, program changes
|
||||
- **Latency**: Reporting and compensation
|
||||
- **GUI**: Opening, resizing, closing without crashes
|
||||
- **Preset Management**: Loading, saving, initialization
|
||||
|
||||
## Common Issues & Solutions
|
||||
|
||||
### Issue: "Plugin failed to load"
|
||||
|
||||
**Causes:**
|
||||
- Missing dependencies (JUCE modules, system libraries)
|
||||
- Incorrect bundle structure
|
||||
- Code signing issues (macOS)
|
||||
|
||||
**Solutions:**
|
||||
```bash
|
||||
# Check dependencies
|
||||
otool -L path/to/plugin.vst3/Contents/MacOS/plugin # macOS
|
||||
ldd path/to/plugin.so # Linux
|
||||
|
||||
# Verify bundle structure
|
||||
find path/to/plugin.vst3 # Should match VST3 spec
|
||||
|
||||
# Check code signature
|
||||
codesign -dv --verbose=4 path/to/plugin.vst3 # macOS
|
||||
```
|
||||
|
||||
### Issue: "Parameter range violations"
|
||||
|
||||
**Fix:**
|
||||
```cpp
|
||||
// WRONG
|
||||
auto param = std::make_unique<AudioParameterFloat>(
|
||||
"gain", "Gain", 0.0f, 2.0f, 1.0f); // Range > 1.0!
|
||||
|
||||
// CORRECT
|
||||
auto param = std::make_unique<AudioParameterFloat>(
|
||||
"gain", "Gain",
|
||||
NormalisableRange<float>(0.0f, 2.0f), // Internal range
|
||||
1.0f,
|
||||
"dB",
|
||||
AudioParameterFloat::genericParameter,
|
||||
[](float value, int) {
|
||||
return String(value * 2.0f, 2) + " dB"; // Display conversion
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### Issue: "State save/load failed"
|
||||
|
||||
**Fix:**
|
||||
```cpp
|
||||
void getStateInformation(MemoryBlock& destData) override {
|
||||
auto state = parameters.copyState();
|
||||
std::unique_ptr<XmlElement> xml(state.createXml());
|
||||
copyXmlToBinary(*xml, destData);
|
||||
}
|
||||
|
||||
void setStateInformation(const void* data, int sizeInBytes) override {
|
||||
std::unique_ptr<XmlElement> xml(getXmlFromBinary(data, sizeInBytes));
|
||||
if (xml && xml->hasTagName(parameters.state.getType())) {
|
||||
parameters.replaceState(ValueTree::fromXml(*xml));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Issue: "Audio glitches detected"
|
||||
|
||||
**Fix:**
|
||||
```cpp
|
||||
void prepareToPlay(double sampleRate, int maxBlockSize) override {
|
||||
// Reset all DSP state
|
||||
dspProcessor.reset();
|
||||
dspProcessor.prepare(sampleRate, maxBlockSize);
|
||||
|
||||
// Clear buffers
|
||||
tempBuffer.clear();
|
||||
}
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
Use in GitHub Actions:
|
||||
|
||||
```yaml
|
||||
- name: Validate Plugin
|
||||
run: /run-pluginval all 5
|
||||
continue-on-error: false # Fail build if validation fails
|
||||
```
|
||||
|
||||
## Platform Notes
|
||||
|
||||
### macOS
|
||||
- AU validation requires macOS
|
||||
- Run `auval` separately for additional AU validation
|
||||
- Check Gatekeeper/notarization if plugins won't load
|
||||
|
||||
### Windows
|
||||
- VST3 validation on Windows requires the plugin binary be accessible
|
||||
- Check Visual C++ runtime dependencies
|
||||
|
||||
### Linux
|
||||
- VST3 only (AU and AAX not available)
|
||||
- Ensure display server running for GUI tests (`DISPLAY=:0`)
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Pluginval installed and accessible
|
||||
- [ ] All built plugins detected
|
||||
- [ ] Validation executed for target formats
|
||||
- [ ] Reports generated in build/pluginval-reports/
|
||||
- [ ] Summary markdown created
|
||||
- [ ] Issues flagged with troubleshooting guidance
|
||||
- [ ] Appropriate exit code returned
|
||||
- [ ] User provided with next steps
|
||||
|
||||
## Follow-Up Actions
|
||||
|
||||
After validation:
|
||||
|
||||
**If Passed:**
|
||||
```
|
||||
1. Test in real DAWs manually
|
||||
2. Run @qa-engineer for comprehensive DAW testing
|
||||
3. Prepare for release: /release-build (when available)
|
||||
```
|
||||
|
||||
**If Failed:**
|
||||
```
|
||||
1. Review detailed reports in build/pluginval-reports/
|
||||
2. Consult @daw-compatibility-engineer for fixes
|
||||
3. Apply /juce-best-practices for realtime safety
|
||||
4. Fix issues and re-validate
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Validate Specific Plugin
|
||||
|
||||
```bash
|
||||
pluginval --validate-in-process path/to/MyPlugin.vst3
|
||||
```
|
||||
|
||||
### Custom Strictness
|
||||
|
||||
```bash
|
||||
/run-pluginval vst3 10 # Maximum strictness, VST3 only
|
||||
```
|
||||
|
||||
### Skip GUI Tests
|
||||
|
||||
Modify pluginval_opts to add:
|
||||
```bash
|
||||
pluginval_opts+=("--skip-gui-tests")
|
||||
```
|
||||
|
||||
### Reproducible Random Tests
|
||||
|
||||
Already included with `--random-seed 42` for strictness >= 7.
|
||||
553
commands/setup-offline-docs.md
Normal file
553
commands/setup-offline-docs.md
Normal file
@@ -0,0 +1,553 @@
|
||||
---
|
||||
argument-hint: ""
|
||||
description: "Build offline HTML documentation for JUCE and download essential reference materials for audio plugin development"
|
||||
allowed-tools: Bash, Read, Write, AskUserQuestion
|
||||
---
|
||||
|
||||
# Setup Offline Documentation for JUCE Development
|
||||
|
||||
This command builds offline HTML documentation for JUCE and downloads essential reference materials for audio plugin development. All documentation will be stored in the plugin's `docs/` directory for offline access.
|
||||
|
||||
## Instructions
|
||||
|
||||
You are tasked with setting up comprehensive offline documentation for JUCE audio plugin development. Follow these steps carefully:
|
||||
|
||||
### 1. Verify Prerequisites
|
||||
|
||||
Check if required tools are installed:
|
||||
- **Doxygen** - Documentation generator
|
||||
- **Python** - Scripting support
|
||||
- **Make** - Build automation
|
||||
- **Graphviz** - Inheritance diagram generation
|
||||
- **curl** or **wget** - For downloading resources
|
||||
|
||||
If any tools are missing, provide installation instructions for the user's platform:
|
||||
- **macOS**: `brew install doxygen graphviz python`
|
||||
- **Linux**: `sudo apt install doxygen graphviz python3 make` (Debian/Ubuntu)
|
||||
- **Windows**: Install via Chocolatey or download from websites
|
||||
|
||||
### 2. Set Up JUCE Repository
|
||||
|
||||
**Option A: Use Existing JUCE Installation**
|
||||
If the user already has JUCE installed, ask for the path to their JUCE directory.
|
||||
|
||||
**Option B: Clone Fresh JUCE Repository**
|
||||
```bash
|
||||
cd /tmp
|
||||
git clone --depth 1 https://github.com/juce-framework/JUCE.git
|
||||
cd JUCE
|
||||
```
|
||||
|
||||
### 3. Build JUCE HTML Documentation
|
||||
|
||||
Navigate to the doxygen directory and build:
|
||||
```bash
|
||||
cd docs/doxygen
|
||||
make
|
||||
```
|
||||
|
||||
This will create a `doc/` subdirectory containing the complete HTML documentation.
|
||||
|
||||
**After successful build:**
|
||||
```bash
|
||||
# Copy built docs to plugin docs directory
|
||||
mkdir -p plugins/juce-dev-team/docs/juce-api
|
||||
cp -r doc/* plugins/juce-dev-team/docs/juce-api/
|
||||
|
||||
echo "✓ JUCE API documentation built and copied"
|
||||
echo " Location: plugins/juce-dev-team/docs/juce-api/index.html"
|
||||
```
|
||||
|
||||
### 4. Download Plugin Format Specifications
|
||||
|
||||
Create a directory structure and download official specs:
|
||||
|
||||
```bash
|
||||
cd plugins/juce-dev-team/docs
|
||||
|
||||
# Create directories
|
||||
mkdir -p plugin-formats/{vst3,audio-unit,aax}
|
||||
mkdir -p dsp-resources
|
||||
|
||||
# VST3 Documentation
|
||||
echo "Downloading VST3 documentation..."
|
||||
# Note: VST3 docs are available online at https://steinbergmedia.github.io/vst3_doc/
|
||||
# We can clone the VST3 SDK which includes documentation
|
||||
cd plugin-formats/vst3
|
||||
curl -L https://github.com/steinbergmedia/vst3sdk/archive/refs/heads/master.zip -o vst3sdk.zip
|
||||
unzip vst3sdk.zip
|
||||
mv vst3sdk-master/doc vst3-docs
|
||||
rm -rf vst3sdk-master vst3sdk.zip
|
||||
cd ../..
|
||||
|
||||
# Audio Unit Documentation
|
||||
echo "Setting up Audio Unit documentation links..."
|
||||
cat > plugin-formats/audio-unit/README.md << 'EOF'
|
||||
# Audio Unit Documentation
|
||||
|
||||
## Official Apple Documentation
|
||||
|
||||
Audio Unit programming documentation requires an Apple Developer account.
|
||||
However, key resources include:
|
||||
|
||||
### Online Resources
|
||||
- Audio Unit Programming Guide: https://developer.apple.com/library/archive/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/
|
||||
- Core Audio Overview: https://developer.apple.com/library/archive/documentation/MusicAudio/Conceptual/CoreAudioOverview/
|
||||
- Audio Unit Properties Reference: https://developer.apple.com/documentation/audiounit
|
||||
|
||||
### JUCE Audio Unit Wrapper
|
||||
The JUCE framework includes an Audio Unit wrapper implementation:
|
||||
- Location in JUCE: `modules/juce_audio_plugin_client/AU/`
|
||||
- This provides a practical reference for AU implementation
|
||||
|
||||
### Key Concepts
|
||||
- Component Manager registration
|
||||
- AU parameter system
|
||||
- Property system
|
||||
- Audio processing callbacks
|
||||
- AUv2 vs AUv3 differences
|
||||
|
||||
### Testing Tools
|
||||
- auval (Audio Unit Validation Tool) - included with macOS
|
||||
- AU Lab - Free from Apple for testing Audio Units
|
||||
EOF
|
||||
|
||||
# AAX Documentation
|
||||
echo "Setting up AAX documentation info..."
|
||||
cat > plugin-formats/aax/README.md << 'EOF'
|
||||
# AAX SDK Documentation
|
||||
|
||||
## Obtaining AAX SDK
|
||||
|
||||
The AAX (Avid Audio eXtension) SDK requires registration with Avid:
|
||||
|
||||
1. Create an account at https://www.avid.com/alliance-partner-program
|
||||
2. Register as a developer (free tier available)
|
||||
3. Download the AAX SDK from the Avid Developer portal
|
||||
|
||||
## What's Included
|
||||
|
||||
The AAX SDK includes:
|
||||
- Complete API documentation
|
||||
- Example plugins
|
||||
- AAX Library source code
|
||||
- AAX Build tools
|
||||
- Pro Tools integration guides
|
||||
|
||||
## Key Resources
|
||||
|
||||
### JUCE AAX Wrapper
|
||||
JUCE includes AAX wrapper implementation:
|
||||
- Location: `modules/juce_audio_plugin_client/AAX/`
|
||||
|
||||
### Important Notes
|
||||
- AAX plugins require signing with Avid-issued certificates
|
||||
- Development signing available for free
|
||||
- Release signing requires pace.com iLok account
|
||||
|
||||
### AAX Concepts
|
||||
- AAX Native vs AAX DSP
|
||||
- Parameter automation system
|
||||
- Stem formats and channel I/O
|
||||
- AAX-specific GUI considerations
|
||||
EOF
|
||||
|
||||
echo "✓ Plugin format documentation downloaded/configured"
|
||||
```
|
||||
|
||||
### 5. Download DSP Resources
|
||||
|
||||
Download essential DSP references:
|
||||
|
||||
```bash
|
||||
cd plugins/juce-dev-team/docs/dsp-resources
|
||||
|
||||
# Audio EQ Cookbook (Robert Bristow-Johnson)
|
||||
echo "Downloading Audio EQ Cookbook..."
|
||||
curl -L "https://webaudio.github.io/Audio-EQ-Cookbook/audio-eq-cookbook.html" -o audio-eq-cookbook.html
|
||||
|
||||
# Create index of Julius O. Smith's DSP Books
|
||||
cat > julius-smith-dsp-books.md << 'EOF'
|
||||
# Julius O. Smith III - DSP Books Collection
|
||||
|
||||
Professor Julius O. Smith III (Stanford CCRMA) has made his comprehensive DSP textbooks available online.
|
||||
|
||||
## Online Books (Free Access)
|
||||
|
||||
All books are available at: https://ccrma.stanford.edu/~jos/
|
||||
|
||||
### 1. Mathematics of the Discrete Fourier Transform (DFT)
|
||||
https://ccrma.stanford.edu/~jos/mdft/
|
||||
- DFT fundamentals
|
||||
- Complex numbers and sinusoids
|
||||
- Spectrum analysis
|
||||
|
||||
### 2. Introduction to Digital Filters
|
||||
https://ccrma.stanford.edu/~jos/filters/
|
||||
- Filter basics and terminology
|
||||
- Elementary filter sections
|
||||
- Analysis and design methods
|
||||
|
||||
### 3. Physical Audio Signal Processing
|
||||
https://ccrma.stanford.edu/~jos/pasp/
|
||||
- Vibrating strings
|
||||
- Digital waveguide models
|
||||
- Virtual musical instruments
|
||||
|
||||
### 4. Spectral Audio Signal Processing
|
||||
https://ccrma.stanford.edu/~jos/sasp/
|
||||
- STFT and sinusoidal modeling
|
||||
- Spectrum analysis
|
||||
- Audio applications
|
||||
|
||||
## Usage
|
||||
|
||||
These books are essential references for understanding:
|
||||
- Filter design theory
|
||||
- Digital waveguides
|
||||
- Spectral processing
|
||||
- Physical modeling synthesis
|
||||
|
||||
## Download Option
|
||||
|
||||
Each book can be downloaded as PDF from the respective website.
|
||||
To download all books locally, visit each URL and save as PDF.
|
||||
EOF
|
||||
|
||||
# DAFX Book Reference
|
||||
cat > dafx-reference.md << 'EOF'
|
||||
# DAFX - Digital Audio Effects
|
||||
|
||||
"DAFX: Digital Audio Effects" edited by Udo Zölzer is a comprehensive reference for audio effects algorithms.
|
||||
|
||||
## Book Information
|
||||
|
||||
- **Title**: DAFX: Digital Audio Effects (2nd Edition)
|
||||
- **Editor**: Udo Zölzer
|
||||
- **Publisher**: Wiley
|
||||
- **ISBN**: 978-0-470-66599-2
|
||||
|
||||
## Content Overview
|
||||
|
||||
The book covers:
|
||||
- Filters (parametric EQ, shelving, etc.)
|
||||
- Dynamics processors (compressors, limiters, gates)
|
||||
- Modulation effects (chorus, flanger, phaser)
|
||||
- Delay-based effects (echo, reverb)
|
||||
- Spectral processing
|
||||
- Source-filter models
|
||||
- Spatial effects
|
||||
|
||||
## Availability
|
||||
|
||||
This is a commercial textbook available through:
|
||||
- Wiley Publishers
|
||||
- Amazon
|
||||
- Academic bookstores
|
||||
|
||||
## Online Resources
|
||||
|
||||
Companion website may include:
|
||||
- MATLAB code examples
|
||||
- Audio examples
|
||||
- Supplementary materials
|
||||
EOF
|
||||
|
||||
# Cytomic Technical Papers
|
||||
cat > cytomic-filter-designs.md << 'EOF'
|
||||
# Cytomic Technical Papers - Filter Designs
|
||||
|
||||
Andy Simper (Cytomic) has published excellent papers on filter design.
|
||||
|
||||
## Key Papers
|
||||
|
||||
### State Variable Filters
|
||||
- SVF (State Variable Filter) topology
|
||||
- Nonlinear filter designs
|
||||
- Parameter interpolation methods
|
||||
|
||||
## Online Resources
|
||||
|
||||
Check Cytomic's website for technical papers:
|
||||
- https://cytomic.com/
|
||||
|
||||
## KVR Audio Forum Posts
|
||||
|
||||
Andy Simper has shared valuable filter design information on KVR Audio forums:
|
||||
- Search for "Andy Simper" on https://www.kvraudio.com/forum/
|
||||
|
||||
## Topics Covered
|
||||
|
||||
- Linear vs nonlinear SVF designs
|
||||
- Coefficient calculation for stable filters
|
||||
- Parameter smoothing techniques
|
||||
- Zero-delay feedback filters
|
||||
EOF
|
||||
|
||||
# Will Pirkle Resources
|
||||
cat > will-pirkle-resources.md << 'EOF'
|
||||
# Will Pirkle - Audio Plugin Development Resources
|
||||
|
||||
Will Pirkle is an expert in audio DSP and plugin development.
|
||||
|
||||
## Books
|
||||
|
||||
### Designing Audio Effect Plugins in C++
|
||||
- Comprehensive guide to audio plugin development
|
||||
- Covers VST, AU, AAX plugin formats
|
||||
- Includes DSP algorithms and implementations
|
||||
- C++ code examples
|
||||
|
||||
### Designing Software Synthesizer Plugins in C++
|
||||
- Virtual analog synthesis
|
||||
- Wavetable synthesis
|
||||
- FM synthesis
|
||||
- Filter designs
|
||||
|
||||
## Availability
|
||||
|
||||
Books available through:
|
||||
- Routledge/Focal Press
|
||||
- Amazon
|
||||
- Academic bookstores
|
||||
|
||||
## Companion Resources
|
||||
|
||||
- Website: http://www.willpirkle.com/
|
||||
- Code examples and projects
|
||||
- Teaching materials
|
||||
EOF
|
||||
|
||||
# Faust Programming Language Resources
|
||||
cat > faust-dsp-resources.md << 'EOF'
|
||||
# Faust Programming Language
|
||||
|
||||
Faust (Functional Audio Stream) is a functional programming language for DSP.
|
||||
|
||||
## Official Resources
|
||||
|
||||
- Website: https://faust.grame.fr/
|
||||
- Online IDE: https://faustide.grame.fr/
|
||||
- Documentation: https://faustdoc.grame.fr/
|
||||
|
||||
## Why Faust for JUCE Developers?
|
||||
|
||||
- Faust code can be compiled to C++ and integrated with JUCE
|
||||
- Excellent for prototyping DSP algorithms
|
||||
- Large library of ready-made effects and synths
|
||||
- Visual block diagrams from code
|
||||
|
||||
## Libraries
|
||||
|
||||
Faust includes extensive DSP libraries:
|
||||
- Filters (all types)
|
||||
- Delays and reverbs
|
||||
- Oscillators
|
||||
- Envelope generators
|
||||
- Analyzers
|
||||
|
||||
## JUCE + Faust Integration
|
||||
|
||||
Faust can generate JUCE-compatible C++ code for easy integration.
|
||||
EOF
|
||||
|
||||
echo "✓ DSP resources documented and references created"
|
||||
```
|
||||
|
||||
### 6. Create Documentation Index
|
||||
|
||||
Create a master index file:
|
||||
|
||||
```bash
|
||||
cd plugins/juce-dev-team/docs
|
||||
|
||||
cat > INDEX.md << 'EOF'
|
||||
# JUCE Dev Team - Offline Documentation Index
|
||||
|
||||
This directory contains offline documentation and references for JUCE audio plugin development.
|
||||
|
||||
## 📚 Documentation Structure
|
||||
|
||||
### JUCE API Documentation
|
||||
**Location**: `juce-api/index.html`
|
||||
- Complete JUCE framework API reference
|
||||
- Generated with Doxygen from JUCE source
|
||||
- Open `juce-api/index.html` in your browser for offline access
|
||||
|
||||
### Plugin Format Specifications
|
||||
|
||||
#### VST3
|
||||
**Location**: `plugin-formats/vst3/`
|
||||
- Steinberg VST3 SDK documentation
|
||||
- API reference
|
||||
- Plugin structure and lifecycle
|
||||
|
||||
#### Audio Unit (AU)
|
||||
**Location**: `plugin-formats/audio-unit/README.md`
|
||||
- Links to Apple's official AU documentation
|
||||
- JUCE AU wrapper reference
|
||||
- Key AU concepts and testing tools
|
||||
|
||||
#### AAX
|
||||
**Location**: `plugin-formats/aax/README.md`
|
||||
- How to obtain AAX SDK from Avid
|
||||
- AAX concepts and requirements
|
||||
- JUCE AAX wrapper reference
|
||||
|
||||
### DSP Resources
|
||||
|
||||
**Location**: `dsp-resources/`
|
||||
|
||||
#### Essential References
|
||||
- `audio-eq-cookbook.html` - Robert Bristow-Johnson's filter cookbook
|
||||
- `julius-smith-dsp-books.md` - Links to J.O. Smith's online DSP books
|
||||
- `dafx-reference.md` - DAFX book information
|
||||
- `cytomic-filter-designs.md` - Andy Simper's filter design papers
|
||||
- `will-pirkle-resources.md` - Will Pirkle's books on plugin development
|
||||
- `faust-dsp-resources.md` - Faust programming language for DSP
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Browse JUCE API
|
||||
```bash
|
||||
open juce-api/index.html # macOS
|
||||
xdg-open juce-api/index.html # Linux
|
||||
start juce-api/index.html # Windows
|
||||
```
|
||||
|
||||
### Search JUCE API
|
||||
Use your browser's search feature in the JUCE API docs, or use `grep`:
|
||||
```bash
|
||||
grep -r "AudioProcessor" juce-api/
|
||||
```
|
||||
|
||||
## 📖 Recommended Reading Order
|
||||
|
||||
### For Beginners
|
||||
1. JUCE Tutorials (in JUCE API docs)
|
||||
2. Julius O. Smith - Introduction to Digital Filters
|
||||
3. Audio EQ Cookbook
|
||||
4. JUCE AudioProcessor class documentation
|
||||
|
||||
### For DSP Implementation
|
||||
1. Audio EQ Cookbook (filter basics)
|
||||
2. Julius O. Smith - Introduction to Digital Filters
|
||||
3. DAFX book chapters (for specific effects)
|
||||
4. Cytomic papers (advanced filter designs)
|
||||
|
||||
### For Plugin Development
|
||||
1. JUCE AudioProcessor and AudioProcessorEditor docs
|
||||
2. Will Pirkle's books
|
||||
3. VST3/AU/AAX specifications for target formats
|
||||
4. JUCE plugin examples in API docs
|
||||
|
||||
## 🔍 Finding Information
|
||||
|
||||
### JUCE Classes
|
||||
Navigate to `juce-api/index.html` → Classes → Find class name
|
||||
|
||||
### DSP Algorithms
|
||||
1. Check Audio EQ Cookbook for filters
|
||||
2. Consult Julius O. Smith's books for theory
|
||||
3. Review DAFX book for audio effects
|
||||
4. Check Faust libraries for example implementations
|
||||
|
||||
### Plugin Formats
|
||||
1. Start with JUCE wrapper documentation (in API docs)
|
||||
2. Consult format-specific docs for detailed requirements
|
||||
3. Review JUCE plugin examples
|
||||
|
||||
## 🛠️ Updating Documentation
|
||||
|
||||
To rebuild JUCE docs after JUCE updates:
|
||||
```bash
|
||||
cd /path/to/JUCE/docs/doxygen
|
||||
make clean
|
||||
make
|
||||
cp -r doc/* /path/to/plugins/juce-dev-team/docs/juce-api/
|
||||
```
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
- JUCE API docs are built from source and may vary by JUCE version
|
||||
- Plugin format specs may require developer accounts (AAX, AU)
|
||||
- DSP book recommendations are for commercial/academic texts
|
||||
- Online resources are linked but can be cached locally
|
||||
|
||||
## 💡 Tips
|
||||
|
||||
- Bookmark `juce-api/index.html` in your browser
|
||||
- Use browser search (Cmd/Ctrl+F) within API docs
|
||||
- Keep DSP resources handy when implementing algorithms
|
||||
- Reference plugin format specs when debugging DAW issues
|
||||
EOF
|
||||
|
||||
echo "✓ Documentation index created"
|
||||
```
|
||||
|
||||
### 7. Verify and Report
|
||||
|
||||
After completing the setup:
|
||||
|
||||
1. **Check that documentation was created successfully:**
|
||||
```bash
|
||||
ls -lh plugins/juce-dev-team/docs/
|
||||
```
|
||||
|
||||
2. **Display summary for user:**
|
||||
```
|
||||
✅ Offline Documentation Setup Complete
|
||||
|
||||
📂 Documentation Location: plugins/juce-dev-team/docs/
|
||||
|
||||
✓ JUCE API Documentation: docs/juce-api/index.html
|
||||
✓ Plugin Format Specs: docs/plugin-formats/
|
||||
✓ DSP Resources: docs/dsp-resources/
|
||||
✓ Master Index: docs/INDEX.md
|
||||
|
||||
🚀 Quick Start:
|
||||
open plugins/juce-dev-team/docs/juce-api/index.html
|
||||
open plugins/juce-dev-team/docs/INDEX.md
|
||||
```
|
||||
|
||||
3. **Provide next steps:**
|
||||
- Open INDEX.md to explore all resources
|
||||
- Bookmark JUCE API docs in browser for quick access
|
||||
- Download commercial books if needed (DAFX, Will Pirkle)
|
||||
- Save Julius O. Smith's books as PDFs for offline use
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] All prerequisites verified or installation instructions provided
|
||||
- [ ] JUCE HTML documentation built successfully
|
||||
- [ ] Documentation copied to plugin docs/ directory
|
||||
- [ ] Plugin format specifications downloaded/documented
|
||||
- [ ] DSP resources documented with links and references
|
||||
- [ ] INDEX.md created with complete navigation guide
|
||||
- [ ] User provided with clear summary and next steps
|
||||
- [ ] Verification that docs/ directory is properly structured
|
||||
|
||||
## Error Handling
|
||||
|
||||
If any step fails, provide clear error messages and solutions:
|
||||
|
||||
**Doxygen build fails:**
|
||||
- Ensure all dependencies are installed
|
||||
- Check JUCE version compatibility
|
||||
- Verify PATH includes doxygen, python, make, graphviz
|
||||
|
||||
**Download failures:**
|
||||
- Check internet connection
|
||||
- Use alternative download methods (browser, wget vs curl)
|
||||
- Provide manual download instructions
|
||||
|
||||
**Permission errors:**
|
||||
- Check directory write permissions
|
||||
- Use sudo if necessary (but warn user)
|
||||
|
||||
## Maintenance
|
||||
|
||||
Document that users should:
|
||||
- Rebuild JUCE docs when updating JUCE framework
|
||||
- Check for updated plugin format specifications periodically
|
||||
- Download updated DSP resources as new editions are published
|
||||
Reference in New Issue
Block a user