Skip to content

AudioLab Preset System: Variation Generator

Overview

The Variation Generator creates intelligent variations of presets through controlled randomization, evolutionary algorithms, and design rules. Built on top of the Morphing Engine, it enables rapid sound design exploration while maintaining musical coherence.

Features

Core Capabilities

  • Random Variation - Controlled randomization within bounds
  • Evolutionary Generation - Genetic algorithms for preset evolution
  • Rule-Based Generation - Sound design rules and constraints
  • Similarity Control - Keep variations musically related
  • Batch Generation - Generate multiple variations efficiently
  • Quality Filtering - Automatic quality assessment

Advanced Features

  • Parameter Groups - Group-aware variation (e.g., oscillator section)
  • Constraint System - Musical and technical constraints
  • Fitness Functions - Custom evaluation criteria
  • Crossover & Mutation - Genetic operators for evolution
  • Diversity Metrics - Ensure variation diversity
  • Preset DNA - Encode/decode preset characteristics

Architecture

┌─────────────────────────────────────────────────────────────┐
│                  Variation Generator                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌──────────────────┐      ┌──────────────────┐          │
│  │ VariationEngine  │◄─────┤  MorphingEngine  │          │
│  └────────┬─────────┘      └──────────────────┘          │
│           │                                                │
│           │                                                │
│  ┌────────▼─────────┐      ┌──────────────────┐          │
│  │ RandomGenerator  │      │  RuleEngine      │          │
│  └──────────────────┘      └──────────────────┘          │
│                                                             │
│  ┌──────────────────┐      ┌──────────────────┐          │
│  │ GeneticAlgorithm │      │ ConstraintSystem │          │
│  └──────────────────┘      └──────────────────┘          │
│                                                             │
│  ┌──────────────────┐      ┌──────────────────┐          │
│  │ QualityEvaluator │      │  DiversityMetric │          │
│  └──────────────────┘      └──────────────────┘          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Components

1. VariationEngine

Purpose: Main engine for generating preset variations.

Generation Modes: - Random - Controlled randomization - Subtle - Small, musical changes - Dramatic - Significant transformations - Evolutionary - Genetic algorithm-based - Hybrid - Mix of multiple strategies

Example:

VariationEngine engine;

// Generate random variation
VariationConfig config;
config.mode = VariationMode::Random;
config.amount = 0.3f;  // 30% variation
config.preserve_character = true;

PresetSchema variation = engine.generate(base_preset, config);

// Generate batch
std::vector<PresetSchema> variations =
    engine.generateBatch(base_preset, config, 10);

2. RandomGenerator

Purpose: Controlled randomization with bounds and distributions.

Features: - Gaussian distribution for natural variation - Uniform distribution for exploration - Parameter-specific bounds - Correlation preservation - Seed control for reproducibility

Example:

RandomGenerator rng;

// Generate variation with specific distribution
RandomConfig config;
config.distribution = DistributionType::Gaussian;
config.std_deviation = 0.2f;
config.preserve_correlations = true;

PresetSchema varied = rng.generateVariation(base_preset, config);

3. GeneticAlgorithm

Purpose: Evolutionary preset generation through selection and breeding.

Genetic Operators: - Crossover - Blend parameters from two parents - Mutation - Random parameter changes - Selection - Fitness-based parent selection - Elitism - Preserve best presets

Evolution Process:

GeneticAlgorithm ga;

// Configure genetic algorithm
GeneticConfig config;
config.population_size = 50;
config.generations = 20;
config.mutation_rate = 0.1f;
config.crossover_rate = 0.7f;
config.elitism_count = 5;

// Define fitness function
config.fitness_function = [](const PresetSchema& preset) {
    // Evaluate preset quality (0.0 - 1.0)
    return evaluateQuality(preset);
};

// Evolve presets
std::vector<PresetSchema> population = ga.evolve(seed_presets, config);

4. RuleEngine

Purpose: Apply sound design rules and constraints.

Rule Types: - Musical Rules - Harmonic relationships, tuning - Technical Rules - Parameter ranges, correlations - Genre Rules - Style-specific constraints - Safety Rules - Prevent problematic combinations

Example:

RuleEngine rules;

// Add rules
rules.addRule("cutoff_resonance", [](PresetSchema& preset) {
    // High resonance requires controlled cutoff
    if (preset.params["resonance"] > 0.8f) {
        preset.params["cutoff"] = std::min(
            preset.params["cutoff"], 0.7f
        );
    }
});

// Apply rules
PresetSchema safe_variation = rules.applyRules(variation);

5. ConstraintSystem

Purpose: Define and enforce constraints on variations.

Constraint Types: - Hard Constraints - Must be satisfied - Soft Constraints - Preferences, can be violated - Parameter Constraints - Value ranges - Relationship Constraints - Between parameters - Temporal Constraints - Time-based limits

Example:

ConstraintSystem constraints;

// Hard constraint: Keep bass frequency range
constraints.addHardConstraint("bass_range", [](const PresetSchema& p) {
    float freq = p.params["osc_frequency"];
    return freq >= 40.0f && freq <= 200.0f;
});

// Soft constraint: Prefer warm sounds
constraints.addSoftConstraint("warmth", [](const PresetSchema& p) {
    return p.params["filter_type"] == "lowpass" ? 1.0f : 0.5f;
}, 0.8f);  // Weight

// Validate variation
bool valid = constraints.validate(variation);

6. QualityEvaluator

Purpose: Assess variation quality and musical coherence.

Metrics: - Spectral Balance - Frequency distribution - Dynamic Range - Volume consistency - Harmonic Content - Overtone structure - Similarity to Source - Distance metric - Musical Coherence - Style consistency

Example:

QualityEvaluator evaluator;

// Evaluate variation
QualityMetrics metrics = evaluator.evaluate(variation);

std::cout << "Quality Score: " << metrics.overall_score << "\n";
std::cout << "Spectral Balance: " << metrics.spectral_balance << "\n";
std::cout << "Similarity: " << metrics.similarity_to_source << "\n";

// Filter by quality
auto high_quality = evaluator.filterByQuality(
    variations,
    0.7f  // Minimum quality threshold
);

7. DiversityMetric

Purpose: Measure and maintain diversity in variation sets.

Metrics: - Parameter Diversity - Spread across parameter space - Spectral Diversity - Different timbres - Category Diversity - Coverage of sound types - Novelty Score - Uniqueness measure

Example:

DiversityMetric diversity;

// Measure diversity of variation set
float div_score = diversity.calculateDiversity(variations);

// Ensure minimum diversity
auto diverse_set = diversity.ensureDiversity(
    variations,
    0.5f,  // Minimum diversity
    10     // Target count
);

Variation Modes

Random Mode

Description: Controlled randomization within specified bounds.

Parameters: - amount: Variation strength (0.0 - 1.0) - parameter_mask: Which parameters to vary - distribution: Gaussian, Uniform, or Custom

Use Case: Quick exploration, A/B testing

Example:

VariationConfig config;
config.mode = VariationMode::Random;
config.amount = 0.3f;
config.preserve_character = true;

auto variation = engine.generate(base_preset, config);

Subtle Mode

Description: Small, musical changes that preserve character.

Characteristics: - Low randomization (5-15%) - Preserves harmonic relationships - Maintains genre characteristics - Subtle timbre shifts

Use Case: Recall variations, micro-adjustments

Dramatic Mode

Description: Significant transformations for exploration.

Characteristics: - High randomization (40-70%) - Allows genre shifts - Explores extremes - May break rules intentionally

Use Case: Sound design, creative exploration

Evolutionary Mode

Description: Multi-generation genetic evolution.

Process: 1. Create initial population 2. Evaluate fitness 3. Select parents 4. Crossover & mutation 5. Repeat for N generations

Use Case: Optimization, discovery of novel sounds

Hybrid Mode

Description: Combines multiple strategies.

Mixing: - Random base + rules filtering - Evolutionary + constraint satisfaction - Subtle variation + quality selection

Use Case: Balanced exploration and quality

Use Cases

1. Preset Pack Generation

// Generate 100 bass presets from one seed
VariationEngine engine;

VariationConfig config;
config.mode = VariationMode::Evolutionary;
config.generations = 10;
config.population_size = 20;

// Define bass-specific fitness
config.fitness_function = [](const PresetSchema& p) {
    float freq_score = isBassFrequency(p.params["frequency"]) ? 1.0f : 0.0f;
    float power_score = p.params["amplitude"] > 0.7f ? 1.0f : 0.5f;
    return (freq_score + power_score) / 2.0f;
};

auto bass_pack = engine.generateBatch(seed_bass, config, 100);

2. A/B Testing

// Generate subtle variations for comparison
VariationConfig config;
config.mode = VariationMode::Subtle;
config.amount = 0.1f;

auto variation_a = engine.generate(current_preset, config);
auto variation_b = engine.generate(current_preset, config);

// User picks best
PresetSchema chosen = userChoice(variation_a, variation_b);

3. Style Transfer

// Transfer characteristics from one preset to another
StyleTransferConfig config;
config.source_preset = edm_lead;
config.target_preset = classical_strings;
config.transfer_features = {
    "attack_time",
    "filter_cutoff",
    "modulation_depth"
};

auto hybrid = engine.transferStyle(edm_lead, classical_strings, config);

4. Preset Evolution

// Evolve preset toward a goal
GeneticConfig config;
config.generations = 50;
config.target_characteristics = {
    {"brightness", 0.8f},
    {"warmth", 0.6f},
    {"aggression", 0.9f}
};

auto evolved = ga.evolveToward(starting_preset, config);

API Reference

VariationEngine

class VariationEngine {
public:
    // Single variation generation
    PresetSchema generate(
        const PresetSchema& base,
        const VariationConfig& config);

    // Batch generation
    std::vector<PresetSchema> generateBatch(
        const PresetSchema& base,
        const VariationConfig& config,
        size_t count);

    // Generate with quality filter
    std::vector<PresetSchema> generateQuality(
        const PresetSchema& base,
        const VariationConfig& config,
        size_t count,
        float min_quality);

    // Configuration
    void setMorphingEngine(const PresetMorpher& morpher);
    void setRuleEngine(const RuleEngine& rules);
    void setConstraints(const ConstraintSystem& constraints);
};

GeneticAlgorithm

class GeneticAlgorithm {
public:
    // Evolution
    std::vector<PresetSchema> evolve(
        const std::vector<PresetSchema>& seed_population,
        const GeneticConfig& config);

    // Single generation
    std::vector<PresetSchema> nextGeneration(
        const std::vector<PresetSchema>& current_generation);

    // Genetic operators
    PresetSchema crossover(
        const PresetSchema& parent1,
        const PresetSchema& parent2);

    PresetSchema mutate(
        const PresetSchema& preset,
        float mutation_rate);

    // Selection
    std::vector<PresetSchema> select(
        const std::vector<PresetSchema>& population,
        size_t count);
};

QualityEvaluator

class QualityEvaluator {
public:
    // Evaluate single preset
    QualityMetrics evaluate(const PresetSchema& preset);

    // Evaluate batch
    std::vector<QualityMetrics> evaluateBatch(
        const std::vector<PresetSchema>& presets);

    // Filter by quality
    std::vector<PresetSchema> filterByQuality(
        const std::vector<PresetSchema>& presets,
        float min_quality);

    // Custom metrics
    void addMetric(const std::string& name,
                  std::function<float(const PresetSchema&)> evaluator);
};

Performance Characteristics

Operation Time Complexity Notes
Random variation O(n) n = parameter count
Batch generation (k presets) O(k*n) Linear in count
Genetic evolution (p pop, g gen) O(p*g*n) Can be parallelized
Quality evaluation O(n) Per preset
Diversity calculation O(k²*n) Pairwise comparisons

Memory Usage: - VariationEngine: ~512 bytes - GeneticAlgorithm: ~1KB + population size - Population (50 presets): ~50KB - Quality cache: ~100 bytes per preset

Best Practices

1. Start Small

// Begin with subtle variations
config.amount = 0.1f;
config.preserve_character = true;

// Gradually increase if needed
for (float amount = 0.1f; amount <= 0.5f; amount += 0.1f) {
    config.amount = amount;
    auto variation = engine.generate(base, config);
    evaluate(variation);
}

2. Use Constraints

// Always define constraints for your use case
ConstraintSystem constraints;
constraints.addHardConstraint("valid_frequency", [](const auto& p) {
    return p.params["frequency"] >= 20.0f &&
           p.params["frequency"] <= 20000.0f;
});

engine.setConstraints(constraints);

3. Quality Filter

// Generate more than needed, filter by quality
auto candidates = engine.generateBatch(base, config, 50);
auto best = evaluator.filterByQuality(candidates, 0.7f);

// Keep top 10
best.resize(std::min(best.size(), size_t(10)));

4. Maintain Diversity

// Ensure variations are sufficiently different
auto diverse = diversity_metric.ensureDiversity(
    variations,
    0.5f,   // Minimum diversity
    20      // Desired count
);

Integration

With Morphing Engine

// Use morphing for controlled variation
PresetMorpher morpher;
auto random_target = generateRandomPreset();
auto variation = morpher.morph(base, random_target, 0.3f);

With Preset Browser

// Generate variations of search results
auto results = browser.search("bass");
for (const auto& result : results) {
    auto variations = engine.generateBatch(result, config, 5);
    saveVariations(variations);
}

With Validation System

// Validate generated variations
for (const auto& variation : variations) {
    auto report = validator.validate(variation);
    if (report.isValid()) {
        approved_variations.push_back(variation);
    }
}

Future Enhancements

  • Neural network-based variation
  • Style transfer using deep learning
  • Spectral morphing integration
  • Real-time variation UI
  • Collaborative filtering
  • User feedback learning
  • Cloud-based evolution

Dependencies

  • audiolab_preset_schemas - Preset data structures
  • audiolab_morphing_engine - Morphing functionality
  • nlohmann/json - JSON serialization
  • Catch2 (testing) - Unit test framework

License

Part of the AudioLab Preset System.