Skip to content

🔗 Core Interfaces Mapping

📖 Overview

Este documento mapea las interfaces de 08_PLUGINS (nivel plugin/integration) con las interfaces de 04_CORE (nivel foundation/atomic).

Filosofía: - 04_CORE → Interfaces atómicas y componibles (granulares) - 08_PLUGINS → Interfaces compuestas y específicas (agregadas)


🎯 Mapping Table

08_PLUGINS Interface Compone Interfaces de 04_CORE Añade Específico de Plugin
IPluginProcessor IAudioProcessor
IResettable
IComponent
getName()
getVersion()
getVendor()
supportsBypass()
setBypass()
IStateManager IStateful
ISerializable
IPresetable
migrateState()
Version management
Preset file I/O
IParameterHost IObservable
IMessageable
Parameter registration
Automation gestures
Normalized mapping
IAudioEngine IAudioProcessor
IActivatable
IResettable
Modulation support
isRealTimeSafe()
getTailLengthSeconds()
IModulationTarget IObservable Modulation routing
Depth control
IModulationSource interface
IUIController IObservable
IMessageable
Meter data
Spectrum data
UIMessage structure
Thread-safe queues

📋 Detailed Breakdown

1️⃣ IPluginProcessor

Hereda de:

// 04_CORE/04_01_core_interfaces/00_processing_interfaces/iaudio_processor.hpp
audiolab::core::IAudioProcessor

// 04_CORE/04_01_core_interfaces/01_lifecycle_interfaces/iresettable.hpp
audiolab::core::IResettable

// 04_CORE/04_01_core_interfaces/01_lifecycle_interfaces/icomponent.hpp
audiolab::core::IComponent

Reutiliza de 04_CORE: - prepareToPlay(sampleRate, maxBlockSize, numChannels) ✅ - releaseResources() ✅ - processBlock(AudioBuffer<float>&) ✅ - reset() ✅ - getLatencyInSamples() ✅ - getTailLengthInSamples() ✅ - isRealTimeSafe()

Añade específico de plugin: - initialize(float sampleRate, int maxBlockSize) - Simplificado - shutdown() - Alias de releaseResources - processReplacing(float**, float**, int) - Legacy API - getName() - Plugin identity - getVersion() - Plugin version - getVendor() - Plugin vendor - supportsBypass() - Bypass capability - setBypass(bool) - Bypass control

Composición propuesta:

namespace audiolab::plugins {

class IPluginProcessor : public core::IAudioProcessor,
                         public core::IResettable,
                         public core::IComponent {
public:
    // Identity (plugin-specific)
    virtual const char* getName() const = 0;
    virtual const char* getVersion() const = 0;
    virtual const char* getVendor() const = 0;

    // Bypass (plugin-specific)
    virtual bool supportsBypass() const = 0;
    virtual void setBypass(bool bypass) = 0;

    // Convenience aliases
    void initialize(float sampleRate, int maxBlockSize) {
        prepareToPlay(sampleRate, maxBlockSize, 2);  // Default stereo
    }

    void shutdown() {
        releaseResources();
    }

    // Legacy API (optional)
    virtual void processReplacing(float** inputs, float** outputs,
                                   int numSamples) {
        // Default implementation wraps processBlock
    }

    // Inherited from core::IAudioProcessor:
    // - prepareToPlay(double, uint32_t, uint32_t)
    // - processBlock(AudioBuffer<float>&)
    // - releaseResources()
    // - getLatencyInSamples()
    // - getTailLengthInSamples()
    // - isRealTimeSafe()

    // Inherited from core::IResettable:
    // - reset()

    // Inherited from core::IComponent:
    // - initialize() [conflicto con nuestra versión]
    // - shutdown() [conflicto con nuestra versión]
};

} // namespace audiolab::plugins


2️⃣ IStateManager

Hereda de:

// 04_CORE/04_01_core_interfaces/02_state_interfaces/istateful.hpp
audiolab::core::IStateful

// 04_CORE/04_01_core_interfaces/02_state_interfaces/iserializable.hpp
audiolab::core::ISerializable

// 04_CORE/04_01_core_interfaces/02_state_interfaces/ipresetable.hpp
audiolab::core::IPresetable

Reutiliza de 04_CORE: - serialize(SerializationFormat) ✅ - deserialize(ByteArray, SerializationFormat) ✅ - getSerializationVersion() ✅ - supportsFormat(SerializationFormat)

Añade específico de plugin: - saveState(MemoryBlock&) - DAW binary format - loadState(const void*, size_t) - DAW binary format - savePreset(const std::string&) - File I/O - loadPreset(const std::string&) - File I/O - canLoadVersion(int) - Version compatibility check - migrateState(int, int, void*, size_t&) - Migration logic

Composición propuesta:

namespace audiolab::plugins {

class IStateManager : public core::ISerializable,
                      public core::IPresetable {
public:
    // DAW state format (plugin-specific)
    virtual bool saveState(MemoryBlock& destData) = 0;
    virtual bool loadState(const void* data, size_t sizeInBytes) = 0;

    // Version management (plugin-specific)
    virtual int getStateVersion() const = 0;
    virtual bool canLoadVersion(int version) const = 0;
    virtual bool migrateState(int fromVersion, int toVersion,
                             void* data, size_t& size) = 0;

    // Preset files (delegates to IPresetable or extends it)
    virtual bool savePreset(const std::string& path) = 0;
    virtual bool loadPreset(const std::string& path) = 0;

    // Inherited from core::ISerializable:
    // - serialize(SerializationFormat) const
    // - deserialize(const ByteArray&, SerializationFormat)
    // - getSerializationVersion() const [puede haber conflicto]
    // - supportsFormat(SerializationFormat) const
};

} // namespace audiolab::plugins


3️⃣ IParameterHost

Hereda de:

// 04_CORE/04_01_core_interfaces/03_communication_interfaces/iobservable.hpp
audiolab::core::IObservable

// 04_CORE/04_01_core_interfaces/03_communication_interfaces/imessageable.hpp
audiolab::core::IMessageable

Reutiliza de 04_CORE: - attach(IObserver*) → Para parameter listeners - detach(IObserver*) → Para parameter listeners - notify(uint32_t, void*) → Para parameter changes - sendMessage(const Message&) → Para automation events

Añade específico de plugin: - registerParameter(Parameter*) - Parameter management - unregisterParameter(const std::string&) - Parameter removal - getParameter(const std::string&) - Parameter access by ID - getParameterByIndex(int) - Parameter access by index - getParameterCount() - Parameter count - getParameterValue(const std::string&) - Value getter - setParameterValue(const std::string&, float) - Value setter - setParameterValueNormalized(const std::string&, float) - Normalized setter - beginParameterGesture(const std::string&) - Automation start - endParameterGesture(const std::string&) - Automation end - addParameterListener(IParameterListener*) - Type-safe listener - removeParameterListener(IParameterListener*) - Type-safe listener

Composición propuesta:

namespace audiolab::plugins {

// Forward declarations
class Parameter;
class IParameterListener;

class IParameterHost : public core::IObservable,
                       public core::IMessageable {
public:
    // Parameter registration (plugin-specific)
    virtual void registerParameter(Parameter* param) = 0;
    virtual void unregisterParameter(const std::string& id) = 0;

    // Parameter access (plugin-specific)
    virtual Parameter* getParameter(const std::string& id) = 0;
    virtual Parameter* getParameterByIndex(int index) = 0;
    virtual int getParameterCount() const = 0;

    // Parameter value manipulation (plugin-specific)
    virtual float getParameterValue(const std::string& id) const = 0;
    virtual void setParameterValue(const std::string& id, float value) = 0;
    virtual void setParameterValueNormalized(const std::string& id,
                                            float normalizedValue) = 0;

    // Automation gestures (plugin-specific)
    virtual void beginParameterGesture(const std::string& id) = 0;
    virtual void endParameterGesture(const std::string& id) = 0;

    // Type-safe listeners (wraps IObservable)
    virtual void addParameterListener(IParameterListener* listener) = 0;
    virtual void removeParameterListener(IParameterListener* listener) = 0;

    // Inherited from core::IObservable:
    // - attach(IObserver*)
    // - detach(IObserver*)
    // - notify(uint32_t, void*)

    // Inherited from core::IMessageable:
    // - sendMessage(const Message&)
    // - supportsMessageType(uint32_t)
};

// Type-safe listener (alternative to generic IObserver)
class IParameterListener {
public:
    virtual void onParameterChanged(const std::string& id, float value) = 0;
    virtual ~IParameterListener() = default;
};

} // namespace audiolab::plugins


4️⃣ IAudioEngine

Hereda de:

// 04_CORE/04_01_core_interfaces/00_processing_interfaces/iaudio_processor.hpp
audiolab::core::IAudioProcessor

// 04_CORE/04_01_core_interfaces/01_lifecycle_interfaces/iactivatable.hpp
audiolab::core::IActivatable

// 04_CORE/04_01_core_interfaces/01_lifecycle_interfaces/iresettable.hpp
audiolab::core::IResettable

Reutiliza de 04_CORE: - prepareToPlay(sampleRate, maxBlockSize, numChannels) ✅ - processBlock(AudioBuffer<float>&) ✅ - releaseResources() ✅ - getLatencyInSamples() ✅ - getTailLengthInSamples() ✅ - isRealTimeSafe() ✅ - reset()

Añade específico de engine: - setSampleRate(float) - Granular config - setBlockSize(int) - Granular config - processBlockWithModulation(AudioBuffer&, ModulationState&) - Modulation - getTailLengthSeconds() - Seconds instead of samples - supportsSidechain() - Sidechain capability

Composición propuesta:

namespace audiolab::plugins {

// Forward declaration
class ModulationState;

class IAudioEngine : public core::IAudioProcessor,
                     public core::IActivatable,
                     public core::IResettable {
public:
    // Granular configuration (plugin-specific)
    virtual void setSampleRate(float sampleRate) = 0;
    virtual void setBlockSize(int blockSize) = 0;

    // Modulation support (plugin-specific)
    virtual void processBlockWithModulation(AudioBuffer<float>& buffer,
                                           const ModulationState& modState) = 0;

    // Tail length in seconds (convenience)
    virtual float getTailLengthSeconds() const = 0;

    // Sidechain support (plugin-specific)
    virtual bool supportsSidechain() const = 0;

    // Inherited from core::IAudioProcessor:
    // - prepareToPlay(double, uint32_t, uint32_t)
    // - processBlock(AudioBuffer<float>&)
    // - releaseResources()
    // - getLatencyInSamples()
    // - getTailLengthInSamples()
    // - isRealTimeSafe()

    // Inherited from core::IActivatable:
    // - activate()
    // - deactivate()
    // - isActivated()

    // Inherited from core::IResettable:
    // - reset()
};

} // namespace audiolab::plugins


5️⃣ IModulationTarget

Hereda de:

// 04_CORE/04_01_core_interfaces/03_communication_interfaces/iobservable.hpp
audiolab::core::IObservable (para notificar cambios de modulation depth)

Añade específico de modulation: - addModulationSource(paramId, source, depth) - Routing - removeModulationSource(paramId, source) - Routing removal - setModulationDepth(paramId, source, depth) - Depth control - getModulationDepth(paramId, source) - Depth query - isModulatable(paramId) - Capability check - getModulationSourceCount(paramId) - Count sources - IModulationSource interface - Source abstraction

Composición propuesta:

namespace audiolab::plugins {

// Forward declaration
class IModulationSource;

class IModulationTarget : public core::IObservable {
public:
    // Modulation routing (plugin-specific)
    virtual void addModulationSource(const std::string& paramId,
                                    IModulationSource* source,
                                    float depth) = 0;
    virtual void removeModulationSource(const std::string& paramId,
                                       IModulationSource* source) = 0;

    // Modulation depth (plugin-specific)
    virtual void setModulationDepth(const std::string& paramId,
                                   IModulationSource* source,
                                   float depth) = 0;
    virtual float getModulationDepth(const std::string& paramId,
                                    IModulationSource* source) const = 0;

    // Queries (plugin-specific)
    virtual bool isModulatable(const std::string& paramId) const = 0;
    virtual int getModulationSourceCount(const std::string& paramId) const = 0;

    // Inherited from core::IObservable:
    // - attach(IObserver*) → Para depth change notifications
    // - detach(IObserver*)
    // - notify(uint32_t, void*)
};

// Modulation source interface (nuevo, específico de plugins)
class IModulationSource {
public:
    virtual float getSample(int sampleIndex) = 0;
    virtual void advance(int numSamples) = 0;
    virtual void reset() = 0;
    virtual ~IModulationSource() = default;
};

} // namespace audiolab::plugins


6️⃣ IUIController

Hereda de:

// 04_CORE/04_01_core_interfaces/03_communication_interfaces/iobservable.hpp
audiolab::core::IObservable

// 04_CORE/04_01_core_interfaces/03_communication_interfaces/imessageable.hpp
audiolab::core::IMessageable

Reutiliza de 04_CORE: - sendMessage(const Message&) → Para custom messages - attach(IObserver*) → Para UI updates - detach(IObserver*) → Para UI updates - notify(uint32_t, void*) → Para parameter changes

Añade específico de UI: - attachUI() - UI lifecycle - detachUI() - UI lifecycle - hasUI() - UI state query - notifyParameterChanged(id, value) - Type-safe notification - requestParameterUpdate(id) - Value request - getMeterValues(levels, numChannels) - Visualization data - getSpectrumData(magnitudes, numBins) - Visualization data - postMessage(UIMessage&) - Type-safe message - pollMessage(UIMessage&) - Type-safe message retrieval - UIMessage struct - Type-safe message structure

Composición propuesta:

namespace audiolab::plugins {

// Forward declaration
struct UIMessage;

class IUIController : public core::IObservable,
                      public core::IMessageable {
public:
    // UI lifecycle (plugin-specific)
    virtual void attachUI() = 0;
    virtual void detachUI() = 0;
    virtual bool hasUI() const = 0;

    // Type-safe parameter sync (wraps IObservable/IMessageable)
    virtual void notifyParameterChanged(const std::string& id, float value) = 0;
    virtual void requestParameterUpdate(const std::string& id) = 0;

    // Visualization data (plugin-specific)
    virtual bool getMeterValues(float* levels, int numChannels) = 0;
    virtual bool getSpectrumData(float* magnitudes, int numBins) = 0;

    // Type-safe custom messaging (wraps IMessageable)
    virtual void postMessage(const UIMessage& message) = 0;
    virtual bool pollMessage(UIMessage& outMessage) = 0;

    // Inherited from core::IObservable:
    // - attach(IObserver*)
    // - detach(IObserver*)
    // - notify(uint32_t, void*)

    // Inherited from core::IMessageable:
    // - sendMessage(const Message&)
    // - supportsMessageType(uint32_t)
};

// Type-safe message structure (plugin-specific)
struct UIMessage {
    enum Type {
        ParameterChanged,
        MeterUpdate,
        SpectrumUpdate,
        TempoDetected,
        Custom
    };

    Type type;
    std::string paramId;
    float value;

    union {
        float tempo;
        int noteNumber;
        void* customData;
    } data;
};

} // namespace audiolab::plugins


🔄 Refactoring Strategy

Step 1: Add 04_CORE Dependencies

# 08_PLUGINS/CMakeLists.txt
target_link_libraries(AudioLab_PluginContracts
    PUBLIC
        AudioLab::CoreInterfaces
)

Step 2: Update Namespace

// Before:
namespace audiolab {

// After:
namespace audiolab {
namespace plugins {  // Nuevo sub-namespace

Step 3: Inherit from Core

// Before:
class IPluginProcessor {
    virtual void process(AudioBuffer& buffer) = 0;
    // ...
};

// After:
class IPluginProcessor : public core::IAudioProcessor,
                         public core::IResettable {
    // Remove duplicate methods
    // Add only plugin-specific methods
    virtual const char* getName() const = 0;
    // ...
};

Step 4: Update Forward Declarations

// Add at top of files:
#include "04_CORE/04_01_core_interfaces/00_processing_interfaces/iaudio_processor.hpp"
#include "04_CORE/04_01_core_interfaces/01_lifecycle_interfaces/iresettable.hpp"
// etc...

// Update namespace references:
using AudioBuffer = core::AudioBuffer<float>;
using IObserver = core::IObserver;

Step 5: Test Compilation

cd "08_PLUGINS/08_00_plugin_infrastructure/08_00_00_contracts"
# Create test file that includes all interfaces
# Verify no compilation errors

✅ Benefits of This Approach

1. Code Reuse

  • No duplicate interface definitions
  • Inherit proven, tested interfaces
  • Consistent API across codebase

2. Composition Over Duplication

  • Plugin interfaces compose atomic interfaces
  • Clear separation: atomic (04_CORE) vs aggregate (08_PLUGINS)

3. Maintainability

  • Single source of truth for core interfaces
  • Changes to 04_CORE automatically propagate
  • Easier to extend with new interfaces

4. Type Safety

  • Compile-time checking of interface compatibility
  • Clear inheritance hierarchy
  • Automatic documentation via inheritance

5. Testing

  • Test atomic interfaces independently
  • Test composed interfaces for plugin-specific behavior
  • Reuse core interface test utilities

🚧 Potential Conflicts

Issue 1: Method Name Collisions

Problem:

// 04_CORE/IComponent
virtual void initialize() = 0;

// 08_PLUGINS/IPluginProcessor
virtual void initialize(float sampleRate, int blockSize) = 0;

Solution: Use different names or make wrapper

class IPluginProcessor : public core::IComponent {
    void initialize() override {
        // Call derived class's initialize(float, int)
    }

    virtual void initializeAudio(float sampleRate, int blockSize) = 0;
};

Issue 2: Version Number Conflicts

Problem:

// Both ISerializable and IStateManager have:
virtual uint32_t getSerializationVersion() const = 0;
virtual int getStateVersion() const = 0;

Solution: Alias or use one method

class IStateManager : public core::ISerializable {
    // Use ISerializable's version
    // Remove getStateVersion()
};


📝 Next Steps

  1. ✅ Create this mapping document
  2. ⏳ Refactor interface headers to inherit from 04_CORE
  3. ⏳ Update CMakeLists.txt with dependencies
  4. ⏳ Create examples showing composition
  5. ⏳ Write tests validating interface compatibility
  6. ⏳ Update SPEC.md to reflect 04_CORE dependencies

Generated with AudioLab 🎵 Building on solid foundations