🔗 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 | IAudioProcessorIResettableIComponent |
getName()getVersion()getVendor()supportsBypass()setBypass() |
| IStateManager | IStatefulISerializableIPresetable |
migrateState()Version management Preset file I/O |
| IParameterHost | IObservableIMessageable |
Parameter registration Automation gestures Normalized mapping |
| IAudioEngine | IAudioProcessorIActivatableIResettable |
Modulation supportisRealTimeSafe()getTailLengthSeconds() |
| IModulationTarget | IObservable |
Modulation routing Depth control IModulationSource interface |
| IUIController | IObservableIMessageable |
Meter data Spectrum data UIMessage structureThread-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¶
- ✅ Create this mapping document
- ⏳ Refactor interface headers to inherit from 04_CORE
- ⏳ Update CMakeLists.txt with dependencies
- ⏳ Create examples showing composition
- ⏳ Write tests validating interface compatibility
- ⏳ Update SPEC.md to reflect 04_CORE dependencies
Generated with AudioLab 🎵 Building on solid foundations