15 KiB
argument-hint, description, allowed-tools
| argument-hint | description | allowed-tools |
|---|---|---|
| [format: vst3|au|aax|all] [strictness: 1-10] | Run industry-standard pluginval validation tool on JUCE plugins with comprehensive tests and detailed reports | 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:
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:
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:
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:
# 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:
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:
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:
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:
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:
# 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:
// 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:
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:
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:
- 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
auvalseparately 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
pluginval --validate-in-process path/to/MyPlugin.vst3
Custom Strictness
/run-pluginval vst3 10 # Maximum strictness, VST3 only
Skip GUI Tests
Modify pluginval_opts to add:
pluginval_opts+=("--skip-gui-tests")
Reproducible Random Tests
Already included with --random-seed 42 for strictness >= 7.