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.