Skip to content

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

  1. Copy the template:

    cp -r l4_template/ ../my_new_plugin/
    

  2. Replace placeholders:

  3. [PRODUCT_NAME] → Your plugin class name (e.g., MyCompressor)
  4. [PRODUCT_ID] → Unique ID (e.g., MY_Compressor)

  5. Implement DSP:

  6. Add state variables in private section
  7. Implement process() method
  8. Add parameters in initParameters()
  9. Implement coefficient updates

  10. Create manifest:

  11. Copy schemas/example_l4_manifest.json
  12. Fill in product info and parameters
  13. Define factory presets

Creating an L5 Suite

  1. Copy the template:

    cp -r l5_template/ ../my_new_suite/
    

  2. Replace placeholders:

  3. [SUITE_NAME] → Your suite class name (e.g., MyMasterSuite)
  4. [SUITE_ID] → Unique ID (e.g., MY_MasterSuite)
  5. [NUM_SLOTS] → Number of plugin slots (e.g., 3)

  6. Configure slots:

  7. Define slot configuration in initSlots()
  8. Specify allowed plugins per slot
  9. Set up routing topology

  10. Add global parameters:

  11. Define in initGlobalParameters()
  12. Implement global parameter handling

  13. Create manifest:

  14. Copy schemas/example_l5_manifest.json
  15. Configure slot definitions
  16. 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, manufacturer
  • plugin_type: "L4" or "L5"
  • version: Semantic version string
  • io_config: Input/output channel configuration
  • parameters: Parameter definitions

Optional Fields

  • formats: VST3/AU/AAX support
  • presets: Factory preset definitions
  • dsp: Latency, tail length, optimization flags
  • l5_config: Slot configuration (L5 only)
  • ui: Window size and appearance
  • system_requirements: Platform and sample rate limits
  • licensing: 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:

  1. Implement DSP: Add your audio processing algorithm
  2. Add Parameters: Define all user-controllable parameters
  3. Create Presets: Design 10+ factory presets
  4. Write Tests: Unit tests for all functionality
  5. Add Documentation: User manual and developer guide
  6. Optimize: Profile and optimize performance
  7. 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! 🎛️