๐๏ธ Parameter Aggregation System¶
๐ Overview¶
The Parameter Aggregation System provides hierarchical organization and efficient access to plugin parameters. It enables:
- Hierarchical grouping (tree structure)
- Fast O(1) lookup (hash map caching)
- Automatic discovery (introspection)
- State serialization (JSON/Binary)
๐ Components¶
08_03_00_aggregation_system/
โโโ include/
โ โโโ ParameterGroup.hpp โ Hierarchical parameter groups
โ โโโ ParameterTree.hpp โ Optimized tree with O(1) lookup
โ โโโ ParameterDiscovery.hpp โ Automatic parameter introspection
โ โโโ ParameterSerializer.hpp โ State save/load (JSON/Binary)
โ
โโโ tests/
โ โโโ test_aggregation.cpp โ Unit tests
โ
โโโ CMakeLists.txt โ Build configuration
๐ฏ Quick Start¶
Creating a Parameter Hierarchy¶
#include "ParameterGroup.hpp"
#include "ParameterTree.hpp"
using namespace audiolab::plugins::parameters;
// Create tree
ParameterTree tree;
auto* root = tree.createGroup("Root", "root");
tree.setRoot(root);
// Create EQ section
auto* eqGroup = tree.createGroup("EQ", "eq");
root->addChild(eqGroup);
// Create frequency bands
auto* lowBand = tree.createGroup("Low Band", "eq_low");
auto* midBand = tree.createGroup("Mid Band", "eq_mid");
auto* highBand = tree.createGroup("High Band", "eq_high");
eqGroup->addChild(lowBand);
eqGroup->addChild(midBand);
eqGroup->addChild(highBand);
// Add parameters to low band
auto* lowFreq = new Parameter("eq_low_freq", "Frequency", 20.0f, 2000.0f, 100.0f);
auto* lowGain = new Parameter("eq_low_gain", "Gain", -12.0f, 12.0f, 0.0f);
auto* lowQ = new Parameter("eq_low_q", "Q", 0.1f, 10.0f, 0.707f);
lowBand->addParameter(lowFreq);
lowBand->addParameter(lowGain);
lowBand->addParameter(lowQ);
// Rebuild cache for fast lookup
tree.rebuildCache();
Fast O(1) Parameter Lookup¶
// O(1) hash map lookup
Parameter* freq = tree.findParameter("eq_low_freq");
if (freq != nullptr) {
float currentValue = freq->getValue();
freq->setValue(500.0f); // Set new value
}
// Find group
ParameterGroup* lowBand = tree.findGroup("eq_low");
if (lowBand != nullptr) {
auto params = lowBand->getParameters();
std::cout << "Low band has " << params.size() << " parameters\n";
}
Discovering Parameters¶
#include "ParameterDiscovery.hpp"
ParameterDiscovery discovery;
// Get all parameters with metadata
std::vector<ParameterInfo> allParams = discovery.discoverParameters(&tree);
for (const auto& info : allParams) {
std::cout << info.groupName << " > " << info.name << "\n";
std::cout << " Range: [" << info.minValue << " - " << info.maxValue << "]\n";
std::cout << " Default: " << info.defaultValue << "\n";
}
// Get hierarchy structure
std::vector<GroupInfo> groups = discovery.discoverGroups(&tree);
for (const auto& info : groups) {
std::cout << std::string(info.depth * 2, ' ') << info.name
<< " (" << info.parameterCount << " params)\n";
}
// Count parameters per group
auto counts = discovery.countParametersByGroup(&tree);
for (const auto& [groupId, count] : counts) {
std::cout << groupId << ": " << count << " parameters\n";
}
Saving and Loading State¶
#include "ParameterSerializer.hpp"
ParameterSerializer serializer;
// === JSON Format (human-readable) ===
// Capture current state
PluginState state = serializer.captureState(&tree);
// Save to JSON file
std::string json = serializer.toJSON(state);
std::ofstream file("my_preset.json");
file << json;
file.close();
// Load from JSON file
std::ifstream loadFile("my_preset.json");
std::string loadedJson((std::istreambuf_iterator<char>(loadFile)),
std::istreambuf_iterator<char>());
loadFile.close();
PluginState loadedState = serializer.fromJSON(loadedJson);
serializer.applyState(&tree, loadedState);
// === Binary Format (fast, compact) ===
// Capture state
PluginState state = serializer.captureState(&tree);
// Serialize to binary
std::vector<uint8_t> binary = serializer.toBinary(state);
// Save to file
std::ofstream binFile("session.alpm", std::ios::binary);
binFile.write(reinterpret_cast<const char*>(binary.data()), binary.size());
binFile.close();
// Load from file
std::ifstream loadBinFile("session.alpm", std::ios::binary);
std::vector<uint8_t> loadedBinary((std::istreambuf_iterator<char>(loadBinFile)),
std::istreambuf_iterator<char>());
loadBinFile.close();
PluginState loadedState = serializer.fromBinary(loadedBinary.data(), loadedBinary.size());
serializer.applyState(&tree, loadedState);
๐๏ธ Architecture¶
ParameterGroup¶
Represents a logical group of parameters:
[Root]
โโโ [EQ]
โ โโโ [Low Band]
โ โ โโโ Frequency
โ โ โโโ Gain
โ โ โโโ Q
โ โโโ [Mid Band]
โ โ โโโ Frequency
โ โ โโโ Gain
โ โ โโโ Q
โ โโโ [High Band]
โ โโโ Frequency
โ โโโ Gain
โ โโโ Q
โโโ [Dynamics]
โโโ Threshold
โโโ Ratio
โโโ Attack
Features: - Parent-child hierarchy - Recursive search - Visibility control - Metadata (name, ID, description)
ParameterTree¶
Optimized wrapper with hash map caching:
Complexity:
- findParameter() โ O(1) with cache
- findGroup() โ O(1) with cache
- rebuildCache() โ O(n) where n = total params + groups
Memory:
- Two hash maps: m_paramCache, m_groupCache
- Typical overhead: ~50 bytes per parameter
ParameterDiscovery¶
Introspection and metadata extraction:
Use Cases: - Generic UI generation - Parameter documentation - DAW automation lists - Preset comparison
ParameterSerializer¶
State save/load in multiple formats:
| Format | Size | Speed | Human Readable | Use Case |
|---|---|---|---|---|
| JSON | Large | Slow | Yes | Presets, version control |
| Binary | Small | Fast | No | DAW sessions, undo/redo |
Binary Format:
[4 bytes] Magic: "ALPM"
[4 bytes] Version: uint32_t
[4 bytes] Param Count: uint32_t
For each parameter:
[2 bytes] ID Length: uint16_t
[N bytes] ID String (UTF-8)
[4 bytes] Value: float (IEEE 754)
๐งช Testing¶
cd tests
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
./test_aggregation
Test Coverage: - โ ParameterGroup hierarchy - โ ParameterTree O(1) lookup - โ ParameterDiscovery introspection - โ ParameterSerializer JSON/Binary
โก Performance¶
| Operation | Complexity | Typical Time |
|---|---|---|
tree.findParameter() |
O(1) | < 50ns |
tree.rebuildCache() |
O(n) | ~1ฮผs per 100 params |
tree.forEach() |
O(n) | ~10ns per param |
discovery.discoverParameters() |
O(n) | ~50ns per param |
serializer.captureState() |
O(n) | ~100ns per param |
serializer.toBinary() |
O(n) | ~200ns per param |
๐ Dependencies¶
- 08_00 - Plugin Infrastructure (IParameterHost, Parameter)
๐ Related¶
- 08_03_01_l5_hierarchy - L5 suite hierarchy
- 08_03_02_modulation_matrix - Modulation routing
- 08_03_03_daw_automation - DAW automation
Status: โ Complete Version: 1.0.0 Last Updated: 2025-10-09