Skip to content

🚀 Getting Started with AudioLab Hierarchy Framework

Your First Steps into Structured Audio Architecture


📋 Prerequisites

System Requirements

  • C++ Compiler: C++20 or later (GCC 11+, Clang 13+, MSVC 2022+)
  • CMake: 3.20 or later
  • Build System: Make, Ninja, or Visual Studio
  • Operating System: Linux, macOS, or Windows

Optional Dependencies

  • Catch2 (v3+) - For running tests
  • vcpkg or Conan - For dependency management

📥 Installation

Option 1: CMake Integration

Add to your project's CMakeLists.txt:

# Add as subdirectory
add_subdirectory(external/audiolab/hierarchy_framework)

# Link to your target
target_link_libraries(your_project
    PRIVATE
        hierarchy_framework
)

Option 2: Manual Include

Copy the framework directory and include the unified header:

#include <audiolab/hierarchy/hierarchy_framework.hpp>

Option 3: System Installation

cd hierarchy_framework
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
make install

Then in your project:

#include <audiolab/hierarchy/hierarchy_framework.hpp>
find_package(HierarchyFramework REQUIRED)
target_link_libraries(your_project PRIVATE HierarchyFramework::framework)

🎯 Your First Validation

Step 1: Include the Framework

#include <audiolab/hierarchy/hierarchy_framework.hpp>
#include <iostream>

using namespace audiolab::hierarchy;

Step 2: Define Your Modules

int main() {
    // Create module metadata map
    std::map<std::string, ModuleMetadata> modules;

    // L0 - Kernel (no dependencies)
    ModuleMetadata oscillator;
    oscillator.name = "Oscillator";
    oscillator.level = ModuleLevel::L0_KERNEL;
    oscillator.description = "Sine wave generator";
    modules["Oscillator"] = oscillator;

    // L1 - Atom (depends on L0)
    ModuleMetadata voice;
    voice.name = "Voice";
    voice.level = ModuleLevel::L1_ATOM;
    voice.description = "Single synthesizer voice";
    voice.dependencies = {"Oscillator"};  // ✅ Valid (L1 → L0)
    modules["Voice"] = voice;

    // L2 - Cell (depends on L1)
    ModuleMetadata synth;
    synth.name = "Synth";
    synth.level = ModuleLevel::L2_CELL;
    synth.description = "Polyphonic synthesizer";
    synth.dependencies = {"Voice"};  // ✅ Valid (L2 → L1)
    modules["Synth"] = synth;

    return 0;
}

Step 3: Validate Architecture

Quick Check

// Simple validation
if (validate(modules)) {
    std::cout << "✅ Architecture is valid!\n";
} else {
    std::cout << "❌ Architecture has violations\n";
}

Get Health Score

double health = get_health_score(modules);
std::cout << "Architecture Health: " << health << "/100\n";

Get Summary

std::cout << summary(modules);

Output:

Architecture Validation Summary:
  Status: ✅ VALID
  Overall Health: 95.0/100
  Rule Violations: 0
  Anti-Patterns: 0
  Good Patterns: 2

Step 4: Comprehensive Analysis

HierarchyFramework framework;
auto result = framework.validate_architecture(modules);

std::cout << result.summary() << "\n";

// Access detailed results
std::cout << "\nDetailed Metrics:\n";
std::cout << "  Total Modules: " << result.metrics.dependency.total_modules << "\n";
std::cout << "  Total Dependencies: " << result.metrics.dependency.total_dependencies << "\n";
std::cout << "  Max Depth: " << result.metrics.complexity.max_depth << "\n";
std::cout << "  Good Patterns: " << result.good_patterns.size() << "\n";

🛠️ Complete Example

#include <audiolab/hierarchy/hierarchy_framework.hpp>
#include <iostream>

using namespace audiolab::hierarchy;

int main() {
    // Define architecture
    std::map<std::string, ModuleMetadata> modules;

    // L0 Kernels
    ModuleMetadata sine_osc;
    sine_osc.name = "SineOscillator";
    sine_osc.level = ModuleLevel::L0_KERNEL;
    modules["SineOscillator"] = sine_osc;

    ModuleMetadata filter;
    filter.name = "Filter";
    filter.level = ModuleLevel::L0_KERNEL;
    modules["Filter"] = filter;

    // L1 Atoms
    ModuleMetadata voice;
    voice.name = "Voice";
    voice.level = ModuleLevel::L1_ATOM;
    voice.dependencies = {"SineOscillator", "Filter"};
    modules["Voice"] = voice;

    // L2 Cells
    ModuleMetadata synth;
    synth.name = "Synth";
    synth.level = ModuleLevel::L2_CELL;
    synth.dependencies = {"Voice"};
    modules["Synth"] = synth;

    // L3 Engines
    ModuleMetadata plugin;
    plugin.name = "Plugin";
    plugin.level = ModuleLevel::L3_ENGINE;
    plugin.dependencies = {"Synth"};
    modules["Plugin"] = plugin;

    // Validate
    HierarchyFramework framework;
    auto result = framework.validate_architecture(modules);

    if (result.is_valid) {
        std::cout << "✅ Architecture is VALID\n";
        std::cout << "Health Score: " << result.overall_health << "/100\n";
        std::cout << "Good Patterns: " << result.good_patterns.size() << "\n";
    } else {
        std::cout << "❌ Architecture is INVALID\n";
        for (const auto& violation : result.rule_violations) {
            std::cout << "  - " << violation.description << "\n";
        }
    }

    return 0;
}

Build and Run

# Compile
g++ -std=c++20 -I/path/to/framework first_validation.cpp -o first_validation

# Run
./first_validation

Output:

✅ Architecture is VALID
Health Score: 92.5/100
Good Patterns: 3


🚨 Common First Mistakes

Mistake 1: Upward Dependency

// ❌ WRONG: L0 depends on L1
ModuleMetadata osc;
osc.level = ModuleLevel::L0_KERNEL;
osc.dependencies = {"Voice"};  // Voice is L1!

Error:

❌ UPWARD_DEPENDENCY: Oscillator (L0) → Voice (L1)

Fix:

// ✅ CORRECT: L1 depends on L0
ModuleMetadata voice;
voice.level = ModuleLevel::L1_ATOM;
voice.dependencies = {"Oscillator"};  // Oscillator is L0 ✓


Mistake 2: Circular Dependency

// ❌ WRONG: A → B → A
ModuleMetadata a;
a.dependencies = {"B"};

ModuleMetadata b;
b.dependencies = {"A"};  // Cycle!

Error:

❌ CIRCULAR_DEPENDENCY: Cycle detected: A → B → A

Fix:

// ✅ CORRECT: Break the cycle
ModuleMetadata base;
base.level = ModuleLevel::L0_KERNEL;  // No deps

ModuleMetadata a;
a.dependencies = {"Base"};

ModuleMetadata b;
b.dependencies = {"Base"};  // Both depend on base, no cycle


Mistake 3: Horizontal Dependency

// ⚠️  DISCOURAGED: Same-level dependency
ModuleMetadata voice1;
voice1.level = ModuleLevel::L1_ATOM;
voice1.dependencies = {"Voice2"};  // Voice2 is also L1

Warning:

⚠️  HORIZONTAL_DEPENDENCY: Voice1 (L1) → Voice2 (L1)

Fix:

// ✅ CORRECT: Extract common L0 dependency
ModuleMetadata common;
common.level = ModuleLevel::L0_KERNEL;

ModuleMetadata voice1;
voice1.level = ModuleLevel::L1_ATOM;
voice1.dependencies = {"Common"};

ModuleMetadata voice2;
voice2.level = ModuleLevel::L1_ATOM;
voice2.dependencies = {"Common"};


📊 Next Steps

Beginner Track

  1. ✅ Run the complete_workflow example:

    cd build/examples
    ./complete_workflow
    

  2. ✅ Read the Architecture Guide

  3. ✅ Study the Anti-Pattern Catalog

  4. ✅ Browse the FAQ

Intermediate Track

  1. Integrate framework into your project (Integration Guide)

  2. Set up metrics collection (Metrics Guide)

  3. Configure enforcement policies (Best Practices)

Advanced Track

  1. Create custom patterns/rules

  2. Set up CI/CD integration

  3. Implement exemption workflow

  4. Contribute to the framework


🆘 Getting Help

Documentation

Examples

  • Complete Workflow - Full example
  • Individual subsystem examples - See each subsystem's examples/ directory

Community

  • GitHub Issues
  • Discussion Forums
  • Stack Overflow (tag: audiolab-hierarchy)

✅ Checklist

Before moving on, make sure you can:

  • Include the framework header
  • Define modules with correct levels
  • Validate an architecture
  • Understand validation results
  • Fix basic violations (upward deps, cycles)
  • Get health scores
  • Build and run the complete_workflow example

Ready for more? → Architecture Guide