Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 09:08:03 +08:00
commit a886924d29
29 changed files with 11395 additions and 0 deletions

View 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
![Baseline Flame Graph](flamegraph-baseline.svg)
![Optimized Flame Graph](flamegraph-optimized.svg)
## 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!

View 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
View 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
View 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
View 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
View 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.

View 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