Skip to content

05_10_CELLS_L2 - Integration Guide

Version: 1.0.0 Date: 2025-10-15


Quick Start Integration

1. Basic Setup

#include "cells/synthesis/SubtractiveOscCell.h"
#include "voice/VoiceManager.h"
#include "pool/ResourcePool.h"
#include "performance/PerformanceMode.h"

class AudioEngine {
public:
    void initialize(double sampleRate, int blockSize) {
        // Performance management
        perfManager.setQualityLevel(QualityLevel::MEDIUM);
        perfManager.setAutoScalingEnabled(true);

        // Resource pooling
        bufferPool.initialize(128, 2, blockSize);

        // Voice management
        voiceManager.initialize(128, VoiceManager::PlaybackMode::POLYPHONIC);

        // Synthesis cell
        oscCell.initialize(sampleRate, blockSize);
        oscCell.loadPreset("warm_analog");
    }

    void processBlock(float** output, int numSamples) {
        auto buffer = bufferPool.allocate();
        if (!buffer) return;

        oscCell.process(buffer->channels, numSamples);

        // Copy to output
        for (int ch = 0; ch < 2; ++ch) {
            memcpy(output[ch], buffer->channels[ch], numSamples * sizeof(float));
        }

        perfManager.updateCPUStats(processingTime, bufferDuration);
    }

private:
    PerformanceManager perfManager;
    AudioBufferPool bufferPool;
    VoiceManager voiceManager;
    SubtractiveOscCell oscCell;
};

2. Complete Instrument

class Synthesizer {
public:
    void initialize(double sr, int bs) {
        sampleRate = sr;
        blockSize = bs;

        // Setup all components
        setupPerformance();
        setupResources();
        setupVoices();
        setupCells();
        setupRouting();
        setupModulation();
        setupState();
    }

private:
    void setupPerformance() {
        perfManager.setQualityLevel(QualityLevel::MEDIUM);
        perfManager.setAutoScalingEnabled(true);
        perfManager.setCPUThreshold(80.0f);
    }

    void setupResources() {
        bufferPool.initialize(128, 2, blockSize);
        voicePool = std::make_unique<ObjectPool<Voice, 128>>();
    }

    void setupVoices() {
        voiceManager.initialize(128, VoiceManager::PlaybackMode::POLYPHONIC);
        voiceManager.setStealingStrategy(VoiceManager::StealingStrategy::QUIETEST);
    }

    void setupCells() {
        // Oscillator
        oscCell.initialize(sampleRate, blockSize);

        // Filter
        filterCell.initialize(sampleRate, blockSize);
        filterCell.loadPreset("moog_ladder");

        // Effects
        delayCell.initialize(sampleRate, blockSize);
        delayCell.loadPreset("stereo_delay");
    }

    void setupRouting() {
        router.initialize(8, 8);
        router.setupSerialChain(0, {1, 2, 3});  // Osc → Filter → Delay → Out
    }

    void setupModulation() {
        modMatrix.initialize();
        modMatrix.createRouting(0, 1, 0.5f, ModulationMatrixCell::CURVE_LINEAR);
    }

    void setupState() {
        stateCoord.initialize(8, 128);
        stateCoord.setConflictResolution(StateCoordinator::ConflictResolution::NEWEST_WINS);
    }

    void processAudio(float** output, int numSamples) {
        auto oscBuf = bufferPool.allocate();
        auto filterBuf = bufferPool.allocate();
        auto delayBuf = bufferPool.allocate();

        // Signal chain
        oscCell.process(oscBuf->channels, numSamples);
        filterCell.process(oscBuf->channels, filterBuf->channels, numSamples);
        delayCell.process(filterBuf->channels, delayBuf->channels, numSamples);

        // Route to output
        router.process(delayBuf->channels, output, numSamples);
    }

    double sampleRate;
    int blockSize;

    PerformanceManager perfManager;
    AudioBufferPool bufferPool;
    std::unique_ptr<ObjectPool<Voice, 128>> voicePool;
    VoiceManager voiceManager;

    SubtractiveOscCell oscCell;
    FilterCell filterCell;
    DelayCell delayCell;

    AudioRouter router;
    ModulationMatrixCell modMatrix;
    StateCoordinator stateCoord;
};

3. MIDI Integration

class MIDISynth {
public:
    void noteOn(int note, int velocity) {
        // Allocate voice
        int voiceIdx = voiceManager.allocateVoice(note, velocity);
        if (voiceIdx == -1) return;  // No voice available

        // Trigger synthesis cell
        oscCell.noteOn(note, velocity);
        filterCell.noteOn(note, velocity);
    }

    void noteOff(int note, int velocity) {
        voiceManager.releaseVoice(note);
        oscCell.noteOff(note);
    }

    void pitchBend(float value) {  // -1 to +1
        oscCell.setPitchBend(value);
    }

    void controlChange(int controller, float value) {
        switch (controller) {
            case 1:  // Mod wheel
                modMatrix.setSourceValue(0, value);
                break;
            case 74:  // Filter cutoff
                filterCell.setParameter(0, value);
                break;
        }
    }

private:
    VoiceManager voiceManager;
    SubtractiveOscCell oscCell;
    FilterCell filterCell;
    ModulationMatrixCell modMatrix;
};

4. Parameter Management

class ParameterController {
public:
    void initialize() {
        // Aggregate 1024 params → 30 essential
        aggregator.initialize(8, 128);

        ParameterAggregator::ReductionConfig config;
        config.strategy = ParameterAggregator::STRATEGY_BALANCED;
        config.targetParameterCount = 30;

        essentialParams = aggregator.selectParameters(config);

        // Generate 8 macros
        MacroGenerator macroGen;
        macros = macroGen.generateMacros(aggregator, 8);
    }

    void setParameter(int cellIdx, int paramIdx, float value) {
        // Validate
        if (validator.validate(cellIdx, paramIdx, value)) {
            stateCoord.setState(cellIdx, paramIdx, value);
        }
    }

    void setMacro(int macroIdx, float value) {
        const auto& macro = macros[macroIdx];
        for (size_t i = 0; i < macro.mappedParameters.size(); ++i) {
            int paramIdx = macro.mappedParameters[i];
            float depth = macro.mappingDepths[i];
            float offset = macro.mappingOffsets[i];
            setParameter(0, paramIdx, value * depth + offset);
        }
    }

    std::vector<int> getEssentialParams() const {
        return essentialParams;
    }

private:
    ParameterAggregator aggregator;
    StateCoordinator stateCoord;
    StateValidator validator;
    std::vector<int> essentialParams;
    std::vector<MacroGenerator::MacroControl> macros;
};

5. Preset System

class PresetManager {
public:
    void savePreset(const std::string& name) {
        // Create state snapshot
        int snapshotId = stateCoord.createSnapshot(name, "User preset");

        // Export to JSON
        exportSnapshot(snapshotId, "presets/" + name + ".json");
    }

    void loadPreset(const std::string& name) {
        // Load from JSON
        auto preset = loadPresetFile("presets/" + name + ".json");

        // Apply to cells
        oscCell.loadPreset(preset.oscPreset);
        filterCell.loadPreset(preset.filterPreset);

        // Restore state
        stateCoord.restoreSnapshot(preset.snapshotId);
    }

    void morphPresets(int presetA, int presetB, float t) {
        const auto* snapA = stateCoord.getSnapshot(presetA);
        const auto* snapB = stateCoord.getSnapshot(presetB);

        // Interpolate
        for (int cell = 0; cell < numCells; ++cell) {
            for (int param = 0; param < numParams; ++param) {
                float valueA = snapA->cellStates[cell][param];
                float valueB = snapB->cellStates[cell][param];
                float morphed = valueA * (1.0f - t) + valueB * t;
                stateCoord.setState(cell, param, morphed);
            }
        }
    }

private:
    StateCoordinator stateCoord;
    SubtractiveOscCell oscCell;
    FilterCell filterCell;
    int numCells, numParams;
};

6. Performance Optimization

class OptimizedEngine {
public:
    void optimizeForLowLatency() {
        // Use ULTRA_LOW mode
        perfManager.setQualityLevel(QualityLevel::ULTRA_LOW);

        // Reduce voice count
        voiceManager.setMaxVoices(32);

        // Disable expensive effects
        perfManager.getConfig().enableEffects = false;

        // Smaller buffer pool
        bufferPool.initialize(32, 2, 128);
    }

    void optimizeForQuality() {
        // Use HIGH or ULTRA mode
        perfManager.setQualityLevel(QualityLevel::HIGH);

        // More voices
        voiceManager.setMaxVoices(256);

        // Enable oversampling
        perfManager.getConfig().oversampleFactor = 2;
    }

    void enableAutoOptimization() {
        // Adaptive controller
        adaptiveController.initialize(&perfManager);
        adaptiveController.setTargetCPU(70.0f);
        adaptiveController.setEnabled(true);

        // Auto-scaling
        perfManager.setAutoScalingEnabled(true);
        perfManager.setCPUThreshold(80.0f);
    }

    void updateOptimization(float deltaTime) {
        adaptiveController.update(deltaTime);
        perfManager.processAutoScaling();

        // Check stats
        auto stats = perfManager.getCPUStats();
        if (stats.dropoutCount > 0) {
            // Downgrade quality
            perfManager.setQualityLevel(QualityLevel::LOW);
        }
    }

private:
    PerformanceManager perfManager;
    AdaptiveQualityController adaptiveController;
    VoiceManager voiceManager;
    AudioBufferPool bufferPool;
};

7. Thread Safety

class ThreadSafeEngine {
public:
    // AUDIO THREAD - Real-time safe
    void processAudio(float** output, int numSamples) {
        // ✅ Lock-free reads
        float cutoff = stateCoord.getState(0, 10);

        // ✅ Lock-free buffer allocation
        auto buffer = bufferPool.allocate();

        // ✅ Lock-free voice allocation
        auto voice = voicePool->allocate(note, velocity);

        // ❌ DO NOT: Write state (acquires lock)
        // stateCoord.setState(0, 10, newValue);  // WRONG!
    }

    // UI THREAD - Not real-time critical
    void onParameterChanged(int cell, int param, float value) {
        // ✅ OK: Write from UI thread
        stateCoord.setState(cell, param, value);

        // ✅ OK: Create snapshot
        stateCoord.createSnapshot("A/B test");

        // ✅ OK: Parameter aggregation
        aggregator.calculateImportance();
    }

    // PATTERN: Lock-free communication
    void setParameterFromUI(int cell, int param, float value) {
        // Write to lock-free queue
        parameterQueue.push({cell, param, value});
    }

    void processParameterQueue() {
        // In audio thread: drain queue
        ParameterChange change;
        while (parameterQueue.pop(change)) {
            applyParameter(change.cell, change.param, change.value);
        }
    }

private:
    StateCoordinator stateCoord;
    AudioBufferPool bufferPool;
    std::unique_ptr<ObjectPool<Voice, 128>> voicePool;
    ParameterAggregator aggregator;
    LockFreeQueue<ParameterChange> parameterQueue;
};

8. Error Handling

class RobustEngine {
public:
    bool initialize(double sr, int bs) {
        // Check parameters
        if (sr <= 0 || bs <= 0) {
            logError("Invalid sample rate or block size");
            return false;
        }

        // Initialize with error checking
        if (!bufferPool.initialize(128, 2, bs)) {
            logError("Buffer pool initialization failed");
            return false;
        }

        if (!voiceManager.initialize(128, VoiceManager::PlaybackMode::POLYPHONIC)) {
            logError("Voice manager initialization failed");
            return false;
        }

        return true;
    }

    void processAudioSafe(float** output, int numSamples) {
        try {
            // Allocate buffer
            auto buffer = bufferPool.allocate();
            if (!buffer) {
                // Pool exhausted - fill with silence
                fillSilence(output, numSamples);
                stats.allocationFailures++;
                return;
            }

            // Process
            oscCell.process(buffer->channels, numSamples);

            // Validate output
            if (!validateBuffer(buffer->channels, numSamples)) {
                fillSilence(output, numSamples);
                stats.validationFailures++;
                return;
            }

            // Copy to output
            copyBuffer(buffer->channels, output, numSamples);

        } catch (const std::exception& e) {
            logError("Audio processing exception: " + std::string(e.what()));
            fillSilence(output, numSamples);
            stats.exceptions++;
        }
    }

private:
    bool validateBuffer(float** buffer, int numSamples) {
        for (int ch = 0; ch < 2; ++ch) {
            for (int i = 0; i < numSamples; ++i) {
                if (std::isnan(buffer[ch][i]) || std::isinf(buffer[ch][i])) {
                    return false;
                }
            }
        }
        return true;
    }

    void fillSilence(float** buffer, int numSamples) {
        for (int ch = 0; ch < 2; ++ch) {
            memset(buffer[ch], 0, numSamples * sizeof(float));
        }
    }

    struct Stats {
        uint64_t allocationFailures = 0;
        uint64_t validationFailures = 0;
        uint64_t exceptions = 0;
    } stats;
};

Common Patterns

Pattern 1: Signal Chain

Osc  Filter  Effect  Output

Pattern 2: Parallel Processing

Osc1 ─┐
Osc2 ─┼→ Mixer  Filter  Output
Osc3 ─┘

Pattern 3: Send/Return

Main ──→ Delay ──┐
  └─────────────→ Mix  Output

Pattern 4: Modulation Routing

LFO ──→ ModMatrix ──→ Filter Cutoff
                   └──→ Osc Detune

Integration Checklist

  • Include correct headers
  • Initialize components in correct order
  • Set appropriate quality mode
  • Configure buffer pools (size = 2× max polyphony)
  • Setup voice management
  • Create signal routing
  • Implement MIDI handling
  • Add parameter control
  • Implement preset system
  • Add error handling
  • Verify thread safety
  • Profile performance
  • Test all quality modes
  • Validate real-time safety

Status: ✅ Ready for Integration

All components are production-ready and can be integrated into commercial audio applications.