🎯 IMPLEMENTATION PLAN: DSP Integration Layer (08_02)¶
📍 UBICACIÓN¶
Carpeta de trabajo: 4 - INTEGRATION/08_PLUGINS/08_02_dsp_integration_layer/
🤖 INSTRUCCIONES PARA LA IA¶
Prompt Inicial¶
Cuando comiences a trabajar en esta carpeta, di:
"Estoy trabajando en la carpeta
08_02_dsp_integration_layer. Voy a implementar el sistema de integración DSP para plugins. Déjame leer el IMPLEMENTATION_PLAN.md y organizarme en fases."
Workflow Automático¶
- Lee este archivo completo antes de empezar
- Organízate en las 5 FASES definidas abajo
- Cada fase = 1 prompt (aprox. 3-4 horas de trabajo)
- Al finalizar cada fase: Actualiza el checklist y haz commit
- Entre fases: Espera confirmación del usuario antes de continuar
📊 DIVISIÓN EN FASES (5 prompts totales)¶
FASE 1: Engine Instantiation (Prompt 1)¶
Duración estimada: 3-4 horas Objetivo: Sistema de creación y gestión de engines L3
Micro-pipeline:
1. Crear subdirectorio 08_02_00_engine_instantiation/
2. Implementar EngineFactory.hpp/.cpp - Factory pattern para engines
3. Implementar EnginePool.hpp/.cpp - Pool de engines reutilizables
4. Implementar EngineLifecycleManager.hpp/.cpp - Gestión de ciclo de vida
5. Implementar EngineDescriptor.hpp - Metadata de engines
6. Crear tests de instanciación
7. Crear CMakeLists.txt y README.md
8. Verificar compilación
Checklist: - [ ] EngineFactory implementado con registro dinámico - [ ] EnginePool con gestión de memoria eficiente - [ ] EngineLifecycleManager con state machine - [ ] EngineDescriptor con metadata completa - [ ] Tests de creación/destrucción funcionan - [ ] No hay memory leaks - [ ] CMakeLists.txt funcional
FASE 2: Signal Routing (Prompt 2)¶
Duración estimada: 4-5 horas Objetivo: Sistema de routing de señales audio con optimizaciones
Micro-pipeline:
1. Crear subdirectorio 08_02_01_signal_routing/
2. Implementar AudioGraph.hpp/.cpp - Grafo de routing
3. Implementar BufferManager.hpp/.cpp - Gestión automática de buffers
4. Implementar RoutingMatrix.hpp/.cpp - Matriz de conexiones
5. Implementar ZeroCopyOptimizer.hpp/.cpp - Optimizaciones zero-copy
6. Implementar ChannelMapper.hpp/.cpp - Mapeo de canales
7. Crear tests de routing con diferentes topologías
8. Crear benchmarks de performance
9. Verificar real-time safety
Checklist: - [ ] AudioGraph construye grafo correctamente - [ ] BufferManager evita allocaciones en RT - [ ] RoutingMatrix optimiza conexiones - [ ] ZeroCopyOptimizer detecta oportunidades - [ ] ChannelMapper maneja mono/stereo/multi - [ ] Tests con grafos complejos pasan - [ ] Benchmarks muestran overhead < 1% - [ ] RT-safe verificado
FASE 3: Modulation System (Prompt 3)¶
Duración estimada: 4-5 horas Objetivo: Sistema de modulación sample-accurate
Micro-pipeline:
1. Crear subdirectorio 08_02_02_modulation_system/
2. Implementar ModulationMatrix.hpp/.cpp - Matriz de routings
3. Implementar LFO.hpp/.cpp - Low Frequency Oscillator
4. Implementar Envelope.hpp/.cpp - ADSR Envelope
5. Implementar ModulationSource.hpp - Interface para sources
6. Implementar ModulationProcessor.hpp/.cpp - Procesador central
7. Implementar SampleAccurateInterpolator.hpp - Interpolación suave
8. Crear tests de modulación
9. Crear ejemplo de filtro modulado
Checklist: - [ ] ModulationMatrix enruta correctamente - [ ] LFO genera formas de onda (sine, saw, square, etc.) - [ ] Envelope implementa ADSR correctamente - [ ] ModulationSource interface clara - [ ] ModulationProcessor sample-accurate - [ ] Interpolación evita clicks - [ ] Tests de modulación pasan - [ ] Ejemplo suena bien
FASE 4: Optimization (Prompt 4)¶
Duración estimada: 3-4 horas Objetivo: Optimizaciones DSP avanzadas
Micro-pipeline:
1. Crear subdirectorio 08_02_03_optimization/
2. Implementar SIMDHelpers.hpp - Helpers para SSE/AVX
3. Implementar VectorizationHints.hpp - Hints para compiler
4. Implementar CacheOptimizer.hpp/.cpp - Layouts cache-friendly
5. Implementar BranchPredictor.hpp - Optimización de branches
6. Implementar AlignmentHelpers.hpp - Alineación de memoria
7. Crear benchmarks comparativos
8. Documentar optimizaciones aplicables
9. Crear guía de uso
Checklist: - [ ] SIMDHelpers para operaciones comunes - [ ] VectorizationHints documentados - [ ] CacheOptimizer mejora layouts - [ ] BranchPredictor reduce mispredictions - [ ] AlignmentHelpers para SIMD - [ ] Benchmarks muestran mejoras > 2x - [ ] Guía de optimización completa - [ ] Compatible con ARM/x86
FASE 5: Performance Tracking + Tests (Prompt 5)¶
Duración estimada: 3-4 horas Objetivo: Sistema de tracking y tests completos
Micro-pipeline:
1. Crear subdirectorio 08_02_04_performance_tracking/
2. Implementar CPUMonitor.hpp/.cpp - Monitoreo de CPU
3. Implementar RTSafetyValidator.hpp/.cpp - Validador RT-safety
4. Implementar PerformanceBudget.hpp/.cpp - Presupuestos de CPU
5. Implementar ProfileScope.hpp - Profiling por scope
6. Crear tests de integración completos
7. Crear benchmarks end-to-end
8. Escribir documentación completa
9. Commit final
Checklist: - [ ] CPUMonitor mide uso real - [ ] RTSafetyValidator detecta violaciones - [ ] PerformanceBudget rastrea presupuestos - [ ] ProfileScope no afecta performance - [ ] Tests de integración pasan - [ ] Benchmarks documentados - [ ] Documentación completa (4 docs) - [ ] Commit realizado
📝 TAREAS DETALLADAS¶
TAREA 1.1: EngineFactory¶
Archivo: 08_02_00_engine_instantiation/EngineFactory.hpp
#pragma once
#include "../../08_00_plugin_infrastructure/08_00_00_contracts/IAudioEngine.hpp"
#include <memory>
#include <functional>
#include <unordered_map>
#include <string>
namespace audiolab {
namespace plugins {
namespace dsp {
using EngineCreator = std::function<std::unique_ptr<IAudioEngine>(const std::string& config)>;
/**
* @brief Factory for creating DSP engines
*
* Supports dynamic registration of engine types at runtime.
* Thread-safe for concurrent engine creation.
*/
class EngineFactory {
public:
static EngineFactory& getInstance();
// Registration
void registerEngine(const std::string& engineType, EngineCreator creator);
bool isRegistered(const std::string& engineType) const;
// Creation
std::unique_ptr<IAudioEngine> createEngine(
const std::string& engineType,
const std::string& config = "");
// Query
std::vector<std::string> getRegisteredEngines() const;
private:
EngineFactory() = default;
std::unordered_map<std::string, EngineCreator> m_creators;
mutable std::mutex m_mutex;
};
// Registration macro
#define REGISTER_ENGINE(TYPE, CLASS) \
namespace { \
struct CLASS##_Registrar { \
CLASS##_Registrar() { \
EngineFactory::getInstance().registerEngine(TYPE, \
[](const std::string& cfg) { \
return std::make_unique<CLASS>(cfg); \
}); \
} \
}; \
static CLASS##_Registrar g_##CLASS##_registrar; \
}
} // namespace dsp
} // namespace plugins
} // namespace audiolab
Implementación en .cpp:
- Constructor singleton con lazy initialization
- registerEngine con lock
- createEngine con validación
- getRegisteredEngines thread-safe
Tiempo: 1 hora
TAREA 1.2: EnginePool¶
Archivo: 08_02_00_engine_instantiation/EnginePool.hpp
#pragma once
#include "EngineFactory.hpp"
#include <queue>
#include <mutex>
#include <condition_variable>
namespace audiolab {
namespace plugins {
namespace dsp {
/**
* @brief Pool de engines reutilizables
*
* Reduce allocaciones creando pool de engines pre-inicializados.
* Útil para plugins L5 con slots dinámicos.
*/
class EnginePool {
public:
EnginePool(const std::string& engineType, size_t initialSize = 4);
~EnginePool();
// Acquire/Release
std::unique_ptr<IAudioEngine> acquire();
void release(std::unique_ptr<IAudioEngine> engine);
// Configuration
void setMaxSize(size_t maxSize);
void preallocate(size_t count);
// Stats
size_t getActiveCount() const;
size_t getPoolSize() const;
private:
std::string m_engineType;
size_t m_maxSize;
std::queue<std::unique_ptr<IAudioEngine>> m_pool;
std::atomic<size_t> m_activeCount{0};
mutable std::mutex m_mutex;
std::condition_variable m_cv;
void createEngine();
};
} // namespace dsp
} // namespace plugins
} // namespace audiolab
Características: - Thread-safe acquire/release - Pre-allocation para evitar RT allocations - Límite máximo configurable - Stats para debugging
Tiempo: 1.5 horas
TAREA 1.3: EngineLifecycleManager¶
Archivo: 08_02_00_engine_instantiation/EngineLifecycleManager.hpp
#pragma once
#include "../../08_00_plugin_infrastructure/08_00_00_contracts/IAudioEngine.hpp"
#include <memory>
namespace audiolab {
namespace plugins {
namespace dsp {
/**
* @brief Gestiona el ciclo de vida completo de un engine
*
* State machine: Created → Prepared → Active → Suspended → Destroyed
*/
class EngineLifecycleManager {
public:
enum class State {
Created, // Instanciado pero no preparado
Prepared, // prepareToPlay() llamado
Active, // activate() llamado, procesando
Suspended, // deactivate() llamado, pausado
Destroyed // Destruido
};
explicit EngineLifecycleManager(std::unique_ptr<IAudioEngine> engine);
~EngineLifecycleManager();
// State transitions
bool prepare(double sampleRate, uint32_t blockSize, uint32_t numChannels);
bool activate();
bool suspend();
bool destroy();
// Queries
State getState() const { return m_state; }
bool isActive() const { return m_state == State::Active; }
IAudioEngine* getEngine() { return m_engine.get(); }
// Stats
uint64_t getProcessedBlocks() const { return m_processedBlocks; }
double getUptimeSeconds() const;
private:
std::unique_ptr<IAudioEngine> m_engine;
State m_state = State::Created;
std::atomic<uint64_t> m_processedBlocks{0};
std::chrono::steady_clock::time_point m_activateTime;
bool validateTransition(State from, State to) const;
};
} // namespace dsp
} // namespace plugins
} // namespace audiolab
Tiempo: 1 hora
TAREA 2.1: AudioGraph¶
Archivo: 08_02_01_signal_routing/AudioGraph.hpp
#pragma once
#include <vector>
#include <unordered_map>
#include <string>
namespace audiolab {
namespace plugins {
namespace dsp {
/**
* @brief Grafo de routing de señales audio
*
* Representa conexiones entre engines como un DAG.
* Optimiza orden de procesamiento mediante topological sort.
*/
class AudioGraph {
public:
struct Node {
std::string id;
IAudioEngine* engine;
std::vector<std::string> inputs; // IDs de nodos de entrada
std::vector<std::string> outputs; // IDs de nodos de salida
};
struct Connection {
std::string sourceNode;
uint32_t sourcePort;
std::string destNode;
uint32_t destPort;
float gain = 1.0f;
};
// Construction
void addNode(const std::string& id, IAudioEngine* engine);
void removeNode(const std::string& id);
void addConnection(const Connection& conn);
void removeConnection(const std::string& sourceNode, const std::string& destNode);
// Validation
bool validate() const;
bool hasCycles() const;
// Processing order
std::vector<std::string> getProcessingOrder() const;
void rebuild(); // Recalcula orden óptimo
// Queries
const Node* getNode(const std::string& id) const;
std::vector<Connection> getConnections(const std::string& nodeId) const;
private:
std::unordered_map<std::string, Node> m_nodes;
std::vector<Connection> m_connections;
std::vector<std::string> m_processingOrder;
bool topologicalSort(std::vector<std::string>& order) const;
bool dfsHasCycle(const std::string& nodeId,
std::unordered_set<std::string>& visited,
std::unordered_set<std::string>& recStack) const;
};
} // namespace dsp
} // namespace plugins
} // namespace audiolab
Tiempo: 2 horas
TAREA 2.2: BufferManager¶
Archivo: 08_02_01_signal_routing/BufferManager.hpp
#pragma once
#include "../../../../2 - FOUNDATION/04_CORE/04_05_buffer_management/00_buffer_types/AudioBuffer.hpp"
#include <vector>
namespace audiolab {
namespace plugins {
namespace dsp {
/**
* @brief Gestiona buffers de audio automáticamente
*
* Pre-alloca buffers para evitar allocaciones en real-time.
* Reusa buffers cuando es posible (zero-copy).
*/
class BufferManager {
public:
BufferManager(uint32_t maxChannels, uint32_t maxBlockSize);
~BufferManager();
// Adquisición de buffers
core::AudioBuffer<float>& acquire(uint32_t numChannels);
void release(core::AudioBuffer<float>& buffer);
// Zero-copy optimization
bool canReuse(const core::AudioBuffer<float>& buffer) const;
void markReusable(core::AudioBuffer<float>& buffer);
// Stats
size_t getTotalBuffers() const { return m_buffers.size(); }
size_t getActiveBuffers() const { return m_activeCount; }
private:
struct BufferSlot {
core::AudioBuffer<float> buffer;
bool inUse = false;
uint64_t lastUsedFrame = 0;
};
uint32_t m_maxChannels;
uint32_t m_maxBlockSize;
std::vector<BufferSlot> m_buffers;
std::atomic<size_t> m_activeCount{0};
std::atomic<uint64_t> m_frameCounter{0};
size_t findAvailableSlot(uint32_t numChannels);
};
} // namespace dsp
} // namespace plugins
} // namespace audiolab
Tiempo: 1.5 horas
TAREA 3.1: ModulationMatrix¶
Archivo: 08_02_02_modulation_system/ModulationMatrix.hpp
#pragma once
#include "../../08_00_plugin_infrastructure/08_00_00_contracts/IModulationTarget.hpp"
#include <vector>
#include <unordered_map>
namespace audiolab {
namespace plugins {
namespace dsp {
/**
* @brief Matriz de modulación N sources → M targets
*
* Enruta múltiples fuentes de modulación (LFOs, envelopes)
* a múltiples parámetros target con depth control.
*/
class ModulationMatrix {
public:
struct Routing {
std::string sourceId;
std::string targetParamId;
float depth = 1.0f;
bool bipolar = false; // -1..+1 vs 0..1
};
// Routing management
void addRouting(const Routing& routing);
void removeRouting(const std::string& sourceId, const std::string& targetParamId);
void setDepth(const std::string& sourceId, const std::string& targetParamId, float depth);
// Processing
void process(uint32_t numSamples);
// Registration
void registerSource(const std::string& id, IModulationSource* source);
void registerTarget(IModulationTarget* target);
// Queries
std::vector<Routing> getRoutings() const;
float getCurrentValue(const std::string& targetParamId) const;
private:
std::unordered_map<std::string, IModulationSource*> m_sources;
std::vector<IModulationTarget*> m_targets;
std::vector<Routing> m_routings;
// Cache para optimization
std::unordered_map<std::string, float> m_currentValues;
};
} // namespace dsp
} // namespace plugins
} // namespace audiolab
Tiempo: 2 horas
TAREA 3.2: LFO Implementation¶
Archivo: 08_02_02_modulation_system/LFO.hpp
#pragma once
#include "../../08_00_plugin_infrastructure/08_00_00_contracts/IModulationTarget.hpp"
namespace audiolab {
namespace plugins {
namespace dsp {
/**
* @brief Low Frequency Oscillator
*
* Genera formas de onda para modulación:
* - Sine, Triangle, Saw, Square, Sample&Hold
*/
class LFO : public IModulationSource {
public:
enum class Waveform {
Sine,
Triangle,
Saw,
Square,
SampleHold,
Noise
};
LFO();
// IModulationSource
float getSample(int sampleIndex) override;
void advance(int numSamples) override;
void reset() override;
// Configuration
void setWaveform(Waveform waveform);
void setFrequency(float hz);
void setPhase(float phase01); // 0..1
// Tempo sync
void setTempoSync(bool enable, float bpm, float divisions);
private:
Waveform m_waveform = Waveform::Sine;
double m_phase = 0.0;
double m_phaseIncrement = 0.0;
float m_sampleRate = 44100.0f;
float m_frequency = 1.0f;
// Sample & Hold
float m_sampleHoldValue = 0.0f;
int m_sampleHoldCounter = 0;
float generateSample();
float sine(double phase);
float triangle(double phase);
float saw(double phase);
float square(double phase);
};
} // namespace dsp
} // namespace plugins
} // namespace audiolab
Tiempo: 1.5 horas
TAREA 4.1: SIMD Helpers¶
Archivo: 08_02_03_optimization/SIMDHelpers.hpp
#pragma once
#include <immintrin.h> // SSE, AVX
#include <cstdint>
namespace audiolab {
namespace plugins {
namespace dsp {
namespace simd {
/**
* @brief SIMD helpers para operaciones DSP comunes
*
* Abstrae diferencias entre SSE/AVX/NEON.
* Auto-detects mejor instruction set disponible.
*/
// ═══════════════════════════════════════════════════════════════
// Vector Operations
// ═══════════════════════════════════════════════════════════════
// Add: dst[i] = a[i] + b[i]
void vectorAdd(float* dst, const float* a, const float* b, size_t count);
// Multiply: dst[i] = a[i] * b[i]
void vectorMultiply(float* dst, const float* a, const float* b, size_t count);
// Multiply-Add: dst[i] += a[i] * b[i]
void vectorMultiplyAdd(float* dst, const float* a, const float* b, size_t count);
// Gain: dst[i] = src[i] * gain
void vectorGain(float* dst, const float* src, float gain, size_t count);
// ═══════════════════════════════════════════════════════════════
// Utility
// ═══════════════════════════════════════════════════════════════
// Check if pointer is aligned for SIMD
bool isAligned(const void* ptr, size_t alignment = 16);
// Get optimal alignment for current CPU
size_t getOptimalAlignment();
// Check SIMD support
struct SIMDSupport {
bool sse = false;
bool sse2 = false;
bool sse3 = false;
bool sse41 = false;
bool sse42 = false;
bool avx = false;
bool avx2 = false;
bool fma = false;
bool avx512 = false;
};
SIMDSupport detectSIMDSupport();
// ═══════════════════════════════════════════════════════════════
// Implementation Macros
// ═══════════════════════════════════════════════════════════════
#if defined(__AVX2__)
#define AUDIOLAB_SIMD_AVX2
#define AUDIOLAB_SIMD_WIDTH 8
#elif defined(__AVX__)
#define AUDIOLAB_SIMD_AVX
#define AUDIOLAB_SIMD_WIDTH 8
#elif defined(__SSE4_1__)
#define AUDIOLAB_SIMD_SSE4
#define AUDIOLAB_SIMD_WIDTH 4
#elif defined(__ARM_NEON)
#define AUDIOLAB_SIMD_NEON
#define AUDIOLAB_SIMD_WIDTH 4
#else
#define AUDIOLAB_SIMD_SCALAR
#define AUDIOLAB_SIMD_WIDTH 1
#endif
} // namespace simd
} // namespace dsp
} // namespace plugins
} // namespace audiolab
Implementación: Versiones optimizadas para cada instruction set
Tiempo: 2 horas
TAREA 5.1: CPU Monitor¶
Archivo: 08_02_04_performance_tracking/CPUMonitor.hpp
#pragma once
#include <chrono>
#include <atomic>
#include <array>
namespace audiolab {
namespace plugins {
namespace dsp {
/**
* @brief Monitorea uso de CPU en real-time
*
* Mide tiempo de procesamiento vs tiempo disponible.
* No afecta performance (usa atomics lock-free).
*/
class CPUMonitor {
public:
CPUMonitor();
// Measurement
void startBlock(uint32_t blockSize, double sampleRate);
void endBlock();
// Stats
float getCurrentCPU() const; // Current block %
float getAverageCPU() const; // Moving average %
float getPeakCPU() const; // Peak %
bool isOverloaded() const; // CPU > 90%
// Configuration
void setWarningThreshold(float percent); // Default: 80%
void reset();
private:
using Clock = std::chrono::high_resolution_clock;
using TimePoint = Clock::time_point;
TimePoint m_startTime;
std::atomic<uint64_t> m_totalCycles{0};
std::atomic<uint64_t> m_availableCycles{0};
// Moving average (últimos 100 blocks)
std::array<float, 100> m_history;
std::atomic<size_t> m_historyIndex{0};
float m_peakCPU = 0.0f;
float m_warningThreshold = 80.0f;
};
// RAII helper para medir scopes
class CPUScope {
public:
CPUScope(CPUMonitor& monitor, uint32_t blockSize, double sampleRate)
: m_monitor(monitor) {
m_monitor.startBlock(blockSize, sampleRate);
}
~CPUScope() {
m_monitor.endBlock();
}
private:
CPUMonitor& m_monitor;
};
} // namespace dsp
} // namespace plugins
} // namespace audiolab
Tiempo: 1.5 horas
🎯 Criterios de Aceptación Final¶
Funcionalidad¶
- Engines se crean/destruyen correctamente
- Pool reutiliza engines eficientemente
- AudioGraph enruta señales correctamente
- Modulación es sample-accurate
- Optimizaciones SIMD funcionan
- CPU monitor preciso (±1%)
Performance¶
- Overhead routing < 1% CPU
- Zero allocaciones en RT thread
- SIMD mejora > 2x vs scalar
- Pool reduce latencia startup
Tests¶
- Cobertura > 85%
- Tests RT-safety pasan
- Benchmarks documentados
- No memory leaks
📦 Dependencias¶
Depende de: - ✅ 08_00 (Plugin Infrastructure) - IAudioEngine, IModulationTarget - ✅ 04_CORE (Buffer Management) - AudioBuffer
Bloqueante para: - 08_10 (L4 Architecture) - Usa engine instantiation - 08_11 (L5 Architecture) - Usa signal routing
💾 Commits Recomendados¶
# Fase 1
git commit -m "feat(08_02): add engine instantiation system
- Implement EngineFactory with dynamic registration
- Add EnginePool for resource reuse
- Add EngineLifecycleManager with state machine"
# Fase 2
git commit -m "feat(08_02): add signal routing system
- Implement AudioGraph with cycle detection
- Add BufferManager with zero-copy optimization
- Add RoutingMatrix for flexible connections"
# Fase 3
git commit -m "feat(08_02): add modulation system
- Implement ModulationMatrix for routing
- Add LFO with multiple waveforms
- Add Envelope (ADSR)
- Sample-accurate interpolation"
# Fase 4
git commit -m "feat(08_02): add DSP optimizations
- Add SIMD helpers (SSE/AVX/NEON)
- Add cache optimization utilities
- Add vectorization hints
- Benchmarks show 2-3x speedup"
# Fase 5
git commit -m "feat(08_02): add performance tracking and tests
- Add CPUMonitor for real-time measurement
- Add RT-safety validator
- Add comprehensive tests (85%+ coverage)
- Complete documentation"
Estado: 📝 LISTO PARA IMPLEMENTACIÓN Última actualización: 2025-10-08 Estimación total: 17-22 horas (5 fases de 3-4.5h cada una)