Product Templates¶
This directory contains templates for creating AudioLab products (plugins).
📁 Directory Structure¶
08_13_00_product_templates/
├── l4_template/ # L4 (simple plugin) template
│ ├── ProductTemplate_L4.hpp
│ └── ProductTemplate_L4.cpp
├── l5_template/ # L5 (suite plugin) template
│ ├── ProductTemplate_L5.hpp
│ └── ProductTemplate_L5.cpp
└── schemas/ # Product manifest schemas
├── product_manifest.schema.json
├── example_l4_manifest.json
└── example_l5_manifest.json
🎯 Quick Start¶
Creating an L4 Plugin¶
-
Copy the template:
-
Replace placeholders:
[PRODUCT_NAME]→ Your plugin class name (e.g.,MyCompressor)-
[PRODUCT_ID]→ Unique ID (e.g.,MY_Compressor) -
Implement DSP:
- Add state variables in private section
- Implement
process()method - Add parameters in
initParameters() -
Implement coefficient updates
-
Create manifest:
- Copy
schemas/example_l4_manifest.json - Fill in product info and parameters
- Define factory presets
Creating an L5 Suite¶
-
Copy the template:
-
Replace placeholders:
[SUITE_NAME]→ Your suite class name (e.g.,MyMasterSuite)[SUITE_ID]→ Unique ID (e.g.,MY_MasterSuite)-
[NUM_SLOTS]→ Number of plugin slots (e.g.,3) -
Configure slots:
- Define slot configuration in
initSlots() - Specify allowed plugins per slot
-
Set up routing topology
-
Add global parameters:
- Define in
initGlobalParameters() -
Implement global parameter handling
-
Create manifest:
- Copy
schemas/example_l5_manifest.json - Configure slot definitions
- Define routing strategy
📝 L4 Template Overview¶
Key Features¶
- IProcessor: Audio processing with prepare/process/reset
- IParameterable: Parameter management with automation support
- IPresetable: Preset loading/saving with factory presets
- Real-time safe: No allocations in audio thread
- Smooth parameters: Built-in parameter smoothing
Implementation Checklist¶
- Define DSP state variables
- Create parameters in
initParameters() - Implement
process()method - Implement
updateCoefficients() - Add parameter smoothing
- Create factory presets
- Implement preset serialization
- Test at multiple sample rates
- Test automation
Example: Simple Gain Plugin¶
// In header:
private:
struct Parameters {
std::unique_ptr<Parameter> gain;
} params_;
float gain_smooth_;
// In initParameters():
params_.gain = std::make_unique<Parameter>(
"gain", "Gain", "dB",
-24.0f, 24.0f, 0.0f,
Parameter::Scale::Linear
);
// In process():
void MyGain::process(const float* const* input,
float** output,
size_t num_samples)
{
const float target_gain = params_.gain->getValue();
const float alpha = 1.0f - std::exp(-1.0f / (0.01f * sample_rate_));
for (size_t i = 0; i < num_samples; ++i) {
gain_smooth_ = gain_smooth_ * (1.0f - alpha) + target_gain * alpha;
const float linear_gain = std::pow(10.0f, gain_smooth_ / 20.0f);
for (size_t ch = 0; ch < 2; ++ch) {
output[ch][i] = input[ch][i] * linear_gain;
}
}
}
📝 L5 Template Overview¶
Key Features¶
- Slot Management: Multiple plugin slots with enable/disable
- Inter-Plugin Routing: Serial, parallel, or custom routing
- Global Parameters: Suite-level parameters affecting all slots
- Unified Presets: Save/load entire suite configuration
- Parameter Aggregation: Access slot parameters via dot notation
Implementation Checklist¶
- Define slot configuration
- Implement slot loading/unloading
- Set up audio routing between slots
- Create global parameters
- Implement suite preset system
- Handle slot enable/bypass
- Aggregate slot parameters
- Calculate total latency
- Test slot combinations
Example: 3-Slot Mastering Chain¶
void MyMasterSuite::initSlots() {
slots_.resize(3);
slots_[0] = {"EQ", "TS_EQ", true, nullptr};
slots_[1] = {"Compressor", "TS_Compressor", true, nullptr};
slots_[2] = {"Limiter", "TS_Limiter", true, nullptr};
// Load default plugins
for (size_t i = 0; i < slots_.size(); ++i) {
loadPluginIntoSlot(i, slots_[i].plugin_id);
}
}
void MyMasterSuite::initGlobalParameters() {
global_params_.master_volume = std::make_unique<Parameter>(
"master_volume", "Master Volume", "dB",
-60.0f, 12.0f, 0.0f, Parameter::Scale::Linear
);
}
📋 Product Manifest Schema¶
The product manifest is a JSON file that describes your plugin's configuration.
Required Fields¶
product_info: Name, ID, version, manufacturerplugin_type: "L4" or "L5"version: Semantic version stringio_config: Input/output channel configurationparameters: Parameter definitions
Optional Fields¶
formats: VST3/AU/AAX supportpresets: Factory preset definitionsdsp: Latency, tail length, optimization flagsl5_config: Slot configuration (L5 only)ui: Window size and appearancesystem_requirements: Platform and sample rate limitslicensing: License type and trial settings
Validation¶
Use the JSON schema to validate your manifest:
# Using jsonschema (Python)
jsonschema -i your_product.json product_manifest.schema.json
# Using ajv (Node.js)
ajv validate -s product_manifest.schema.json -d your_product.json
🎨 Best Practices¶
Real-Time Safety¶
// ❌ BAD: Allocations in process()
void process(...) {
auto buffer = new float[num_samples]; // NO!
std::vector<float> temp(num_samples); // NO!
}
// ✅ GOOD: Pre-allocated buffers
class MyPlugin {
std::vector<float> temp_buffer_; // Allocated in prepare()
void prepare(double sr, size_t max_block) {
temp_buffer_.resize(max_block); // Allocate here
}
void process(...) {
// Use pre-allocated buffer
std::fill(temp_buffer_.begin(), temp_buffer_.end(), 0.0f);
}
};
Parameter Smoothing¶
// One-pole smoothing (simple)
const float alpha = 1.0f - std::exp(-1.0f / (time_constant_sec * sample_rate_));
smooth_value = smooth_value * (1.0f - alpha) + target_value * alpha;
// Sample-accurate modulation
for (size_t i = 0; i < num_samples; ++i) {
const float freq = frequency_param->getValue(i); // Per-sample
// Process with current value
}
Factory Presets¶
// Define meaningful presets that showcase your plugin
std::vector<Preset> createFactoryPresets() {
return {
{"Init", "Default", "AudioLab", /* default values */},
{"Punchy Drums", "Drums", "AudioLab", /* optimized for drums */},
{"Smooth Vocals", "Vocals", "AudioLab", /* vocal compression */},
{"Bus Glue", "Mix Bus", "AudioLab", /* subtle bus compression */},
// ... 6-10 more useful presets
};
}
Testing¶
// Test different sample rates
for (auto sr : {44100.0, 48000.0, 96000.0, 192000.0}) {
plugin.prepare(sr, 512);
// Test processing...
}
// Test different block sizes
for (auto bs : {32, 64, 128, 256, 512, 1024, 2048}) {
plugin.prepare(44100.0, bs);
// Test processing...
}
// Test parameter automation
for (size_t i = 0; i < num_samples; ++i) {
plugin.setParameterValue("gain", i / float(num_samples));
// Process one sample
}
📚 Additional Resources¶
- Core Interfaces:
2 - FOUNDATION/04_CORE/04_01_core_interfaces/ - Parameter System:
2 - FOUNDATION/04_CORE/04_08_parameter_system/ - L4 Architecture:
4 - INTEGRATION/08_PLUGINS/08_10_l4_plugin_architecture/ - L5 Architecture:
4 - INTEGRATION/08_PLUGINS/08_11_l5_suite_architecture/ - Testing Framework:
2 - FOUNDATION/03_INFRA/03_04_testing_framework/
🚀 Next Steps¶
After creating your product from these templates:
- Implement DSP: Add your audio processing algorithm
- Add Parameters: Define all user-controllable parameters
- Create Presets: Design 10+ factory presets
- Write Tests: Unit tests for all functionality
- Add Documentation: User manual and developer guide
- Optimize: Profile and optimize performance
- Package: Use asset selection system to build installer
💡 Examples¶
See the following products for complete examples:
- TS_Compressor: L4 dynamics compressor
- TS_Reverb: L4 reverb with visualization
- TS_MasterSuite: L5 mastering chain (EQ → Comp → Limiter)
Ready to build your AudioLab product! 🎛️