Files
Alicho/docs/api/plugin_interface.md
2025-10-28 10:27:49 +08:00

47 KiB
Raw Permalink Blame History

插件接口API参考

目录

概述

插件系统是音频端的核心组件之一,提供了一个安全且可扩展的插件架构。该系统采用多进程隔离设计,可以安全地加载和运行第三方插件,同时保护主系统免受插件崩溃或恶意行为的影响。

核心特性:

  • 多进程沙盒隔离:通过独立进程运行插件,避免崩溃影响主系统
  • 资源配额管理限制插件的CPU、内存、磁盘和网络使用
  • 安全通信机制:经过验证的跨进程消息传递
  • 统一插件接口标准化的API支持音频处理、参数控制和GUI
  • 跨平台沙盒实现支持Windows、Linux和macOS的平台特定隔离机制
  • 故障检测与恢复:自动检测和处理插件崩溃
  • 性能监控:实监控插件资源使用情况

插件系统架构图:

┌─────────────────────────────────┐     ┌─────────────────────────────────┐
│      音频引擎核心进程            │     │         插件沙盒进程 1           │
│                                 │     │                                 │
│  ┌─────────────────────────┐    │     │  ┌─────────────────────────┐    │
│  │    插件宿主管理器        │    │     │  │        沙盒运行时        │    │
│  └───────────┬─────────────┘    │     │  └───────────┬─────────────┘    │
│              │                  │     │              │                  │
│  ┌───────────▼─────────────┐    │     │  ┌───────────▼─────────────┐    │
│  │     安全通信代理         │◄───┼─────┼─►│     安全通信代理         │    │
│  └───────────┬─────────────┘    │     │  └───────────┬─────────────┘    │
│              │                  │     │              │                  │
│  ┌───────────▼─────────────┐    │     │  ┌───────────▼─────────────┐    │
│  │     音频处理管线         │    │     │  │       插件实例           │    │
│  └─────────────────────────┘    │     │  └─────────────────────────┘    │
└─────────────────────────────────┘     └─────────────────────────────────┘
                                        
                                        ┌─────────────────────────────────┐
                                        │         插件沙盒进程 2           │
                                        │                                 │
                                        │  ┌─────────────────────────┐    │
                                        │  │        沙盒运行时        │    │
                                        │  └───────────┬─────────────┘    │
                                        │              │                  │
                                        │  ┌───────────▼─────────────┐    │
                                        │  │     安全通信代理         │    │
                                        │  └───────────┬─────────────┘    │
                                        │              │                  │
                                        │  ┌───────────▼─────────────┐    │
                                        │  │       插件实例           │    │
                                        │  └─────────────────────────┘    │
                                        └─────────────────────────────────┘

插件接口核心

IPlugin接口

IPlugin是所有插件必须实现的核心接口,定义了插件的基本功能和生命周期:

class IPlugin {
public:
    virtual ~IPlugin() = default;
    
    // 基本信息
    virtual std::unique_ptr<PluginInfo> get_plugin_info() const = 0;
    virtual PluginId get_plugin_id() const = 0;
    virtual std::string get_name() const = 0;
    virtual std::string get_vendor() const = 0;
    virtual Version get_version() const = 0;
    virtual PluginCategory get_category() const = 0;
    virtual PluginType get_type() const = 0;
    virtual PluginCapability get_capabilities() const = 0;
    
    // 生命周期管理
    virtual common::ErrorCode initialize(const engine::AudioConfig& config) = 0;
    virtual common::ErrorCode shutdown() = 0;
    virtual common::ErrorCode activate() = 0;
    virtual common::ErrorCode deactivate() = 0;
    virtual common::ErrorCode suspend() = 0;
    virtual common::ErrorCode resume() = 0;
    virtual common::ErrorCode reset() = 0;
    virtual PluginState get_state() const = 0;
    
    // 音频处理
    virtual common::ErrorCode prepare_to_play(double sample_rate, uint32_t max_block_size) = 0;
    virtual ProcessingResult process_audio(
        const engine::AudioBuffer& input,
        engine::AudioBuffer& output,
        const std::vector<MidiEvent>& midi_in,
        std::vector<MidiEvent>& midi_out,
        const PluginProcessContext& context) = 0;
    virtual ProcessingResult process_midi(
        const std::vector<MidiEvent>& midi_in,
        std::vector<MidiEvent>& midi_out,
        const PluginProcessContext& context) = 0;
    virtual uint32_t get_latency_samples() const = 0;
    virtual uint32_t get_tail_length_samples() const = 0;
    virtual common::ErrorCode set_bypass(bool bypass) = 0;
    virtual bool is_bypassed() const = 0;
    
    // 音频配置
    virtual std::vector<uint16_t> get_supported_input_channels() const = 0;
    virtual std::vector<uint16_t> get_supported_output_channels() const = 0;
    virtual common::ErrorCode set_channel_configuration(uint16_t input_channels, uint16_t output_channels) = 0;
    virtual std::pair<uint16_t, uint16_t> get_channel_configuration() const = 0;
    
    // 参数管理
    virtual size_t get_parameter_count() const = 0;
    virtual std::unique_ptr<PluginParameter> get_parameter_info(size_t index) const = 0;
    virtual std::unique_ptr<PluginParameter> get_parameter_by_id(const std::string& parameter_id) const = 0;
    virtual common::ErrorCode set_parameter(const std::string& parameter_id, const std::any& value) = 0;
    virtual std::any get_parameter(const std::string& parameter_id) const = 0;
    virtual common::ErrorCode reset_parameter(const std::string& parameter_id) = 0;
    virtual common::ErrorCode reset_all_parameters() = 0;
    
    // 预设管理
    virtual size_t get_preset_count() const = 0;
    virtual std::unique_ptr<PluginPreset> get_preset_info(size_t index) const = 0;
    virtual common::ErrorCode load_preset(const std::string& preset_id) = 0;
    virtual common::ErrorCode save_preset(const std::string& preset_id, const std::string& name) = 0;
    virtual std::string get_current_preset_id() const = 0;
    
    // 状态保存和恢复
    virtual std::vector<uint8_t> get_state_data() const = 0;
    virtual common::ErrorCode set_state_data(const std::vector<uint8_t>& data) = 0;
    virtual size_t get_state_data_size() const = 0;
    
    // GUI支持
    virtual bool has_gui() const = 0;
    virtual void* create_gui(void* parent_window) = 0;
    virtual common::ErrorCode destroy_gui() = 0;
    virtual common::ErrorCode set_gui_visible(bool visible) = 0;
    virtual bool is_gui_visible() const = 0;
    virtual std::pair<uint32_t, uint32_t> get_gui_size() const = 0;
    virtual common::ErrorCode set_gui_size(uint32_t width, uint32_t height) = 0;
    
    // 事件处理
    virtual void set_event_listener(std::shared_ptr<IPluginEventListener> listener) = 0;
    virtual void remove_event_listener() = 0;
    
    // 性能和诊断
    virtual double get_cpu_usage() const = 0;
    virtual size_t get_memory_usage() const = 0;
    virtual std::chrono::nanoseconds get_average_processing_time() const = 0;
    virtual std::chrono::nanoseconds get_max_processing_time() const = 0;
    virtual void reset_performance_statistics() = 0;
    
    // 扩展功能
    template<typename T>
    T* get_extension();
    
protected:
    virtual void* get_extension_impl(const std::type_info& type);
};

生命周期管理

插件生命周期包括以下状态和转换:

  1. 初始化(Initialize):首次加载插件后,进行初始化配置

    • 分配资源
    • 加载配置
    • 准备状态
  2. 激活(Activate):准备音频处理

    • 申请实时处理资源
    • 初始化处理状态
    • 准备缓冲区
  3. 停用(Deactivate):暂停音频处理

    • 释放实时处理资源
    • 保持状态
  4. 挂起(Suspend):系统节能或不需要处理

    • 释放部分资源
    • 保持核心状态
  5. 恢复(Resume):从挂起状态恢复

    • 重新申请资源
    • 恢复到之前状态
  6. 关闭(Shutdown):完全卸载插件

    • 释放所有资源
    • 关闭所有连接

插件状态转换图

音频处理

音频处理是插件的核心功能,通过process_audio方法实现:

ProcessingResult process_audio(
    const engine::AudioBuffer& input,    // 输入音频缓冲区
    engine::AudioBuffer& output,         // 输出音频缓冲区
    const std::vector<MidiEvent>& midi_in, // 输入MIDI事件
    std::vector<MidiEvent>& midi_out,    // 输出MIDI事件
    const PluginProcessContext& context  // 处理上下文
);

处理上下文提供了重要的信息,如播放位置、速度等:

struct PluginProcessContext {
    // 时间信息
    uint64_t sample_position = 0;          // 当前样本位置
    double sample_rate = 44100.0;          // 采样率
    uint32_t block_size = 512;             // 块大小
    
    // 传输状态
    bool is_playing = false;               // 是否播放中
    bool is_recording = false;             // 是否录制中
    bool is_looping = false;               // 是否循环中
    double tempo = 120.0;                  // 速度BPM
    
    // 小节信息
    int32_t time_signature_numerator = 4;  // 拍号分子
    int32_t time_signature_denominator = 4; // 拍号分母
    double ppq_position = 0.0;             // PPQ位置
    double bar_start_position = 0.0;       // 小节开始位置
    
    // 系统信息
    uint64_t system_time = 0;              // 系统时间
    bool is_realtime = true;               // 是否实时处理
};

MIDI事件由以下结构表示

struct MidiEvent {
    uint32_t timestamp;     // 时间戳(样本偏移)
    uint8_t data[4];        // MIDI数据
    uint8_t size;           // 数据大小
    
    // MIDI消息类型检测
    bool is_note_on() const;
    bool is_note_off() const;
    bool is_control_change() const;
    bool is_program_change() const;
    bool is_pitch_bend() const;
    
    uint8_t get_channel() const;
    uint8_t get_note() const;
    uint8_t get_velocity() const;
    uint8_t get_controller() const;
    uint8_t get_value() const;
};

参数管理

插件参数提供了用户控制插件行为的机制:

// 获取参数数量
size_t get_parameter_count() const;

// 获取参数信息
std::unique_ptr<PluginParameter> get_parameter_info(size_t index) const;

// 根据ID获取参数信息
std::unique_ptr<PluginParameter> get_parameter_by_id(const std::string& parameter_id) const;

// 设置参数值
common::ErrorCode set_parameter(const std::string& parameter_id, const std::any& value);

// 获取参数值
std::any get_parameter(const std::string& parameter_id) const;

插件宿主管理器

PluginHostManager

PluginHostManager负责管理插件的完整生命周期,包括加载、初始化、音频处理和卸载:

class PluginHostManager {
public:
    explicit PluginHostManager(const PluginHostConfig& config);
    ~PluginHostManager();
    
    // 初始化和关闭
    common::ErrorCode initialize();
    common::ErrorCode shutdown();
    
    // 插件加载和卸载
    common::ErrorCode load_plugin(
        const std::string& plugin_path, 
        const std::string& instance_id,
        const SandboxConfig& sandbox_config = SandboxConfig(),
        bool auto_activate = false);
    
    common::ErrorCode unload_plugin(
        const std::string& instance_id,
        bool force = false);
    
    // 插件控制
    common::ErrorCode activate_plugin(const std::string& instance_id);
    common::ErrorCode deactivate_plugin(const std::string& instance_id);
    common::ErrorCode reset_plugin(const std::string& instance_id);
    
    // 音频处理
    ProcessingResult process_plugin_audio(
        const std::string& instance_id,
        const engine::AudioBuffer& input,
        engine::AudioBuffer& output,
        const std::vector<MidiEvent>& midi_in,
        std::vector<MidiEvent>& midi_out,
        const PluginProcessContext& context);
    
    // 参数控制
    common::ErrorCode set_plugin_parameter(
        const std::string& instance_id, 
        const std::string& parameter_id, 
        const std::any& value);
    
    std::any get_plugin_parameter(
        const std::string& instance_id,
        const std::string& parameter_id);
    
    // 预设管理
    common::ErrorCode load_plugin_preset(
        const std::string& instance_id,
        const std::string& preset_id);
    
    // 插件状态管理
    common::ErrorCode save_plugin_state(
        const std::string& instance_id,
        const std::string& file_path);
    
    common::ErrorCode load_plugin_state(
        const std::string& instance_id,
        const std::string& file_path);
    
    // 插件查询
    bool has_plugin(const std::string& instance_id) const;
    PluginState get_plugin_state(const std::string& instance_id) const;
    std::vector<std::string> get_loaded_plugins() const;
    std::unique_ptr<PluginInfo> get_plugin_info(const std::string& instance_id) const;
    
    // 插件统计
    PluginStatistics get_plugin_statistics(const std::string& instance_id) const;
    
    // 沙盒控制
    common::ErrorCode restart_plugin_sandbox(const std::string& instance_id);
    common::ErrorCode update_sandbox_limits(
        const std::string& instance_id, 
        const SandboxLimits& new_limits);
};

宿主配置

PluginHostConfig定义了插件宿主的配置选项:

struct PluginHostConfig {
    // 沙盒设置
    bool enable_sandbox_isolation = true;  // 启用沙盒隔离
    bool allow_non_sandboxed_plugins = false;  // 允许不使用沙盒运行插件
    
    // 默认沙盒配置
    SandboxConfig default_sandbox_config;  // 默认沙盒配置
    
    // 性能设置
    uint32_t max_plugins = 100;            // 最大插件数量
    uint32_t max_processing_time_ms = 500; // 最大处理时间限制
    
    // 路径设置
    std::string plugin_search_paths;       // 插件搜索路径
    std::string preset_storage_path;       // 预设存储路径
    
    // 日志设置
    bool enable_detailed_logging = false;  // 启用详细日志
};

工厂函数

系统提供了几个便捷的工厂函数来创建预配置的插件宿主:

// 创建默认配置的插件宿主管理器
std::shared_ptr<PluginHostManager> create_plugin_host_manager();

// 创建严格安全模式的插件宿主管理器
std::shared_ptr<PluginHostManager> create_strict_plugin_host_manager();

// 创建宽松模式的插件宿主管理器(用于调试)
std::shared_ptr<PluginHostManager> create_relaxed_plugin_host_manager();

// 创建自定义配置的插件宿主管理器
std::shared_ptr<PluginHostManager> create_custom_plugin_host_manager(
    const PluginHostConfig& custom_config);

同样,还有用于创建不同类型插件沙盒配置的工厂函数:

// 创建用于音频效果器的沙盒配置
SandboxConfig create_audio_effect_sandbox_config();

// 创建用于乐器的沙盒配置
SandboxConfig create_instrument_sandbox_config();

// 创建用于分析器的沙盒配置
SandboxConfig create_analyzer_sandbox_config();

沙盒隔离机制

沙盒类型

系统支持多种沙盒类型,以适应不同的隔离需求:

enum class SandboxType {
    None,       // 无沙盒(不推荐用于生产环境)
    Process,    // 进程级隔离(标准)
    Container,  // 容器级隔离Linux特定
    Thread,     // 线程级隔离(有限保护,仅用于调试)
    VM          // 虚拟机隔离(最高安全性,但开销大)
};

资源限制

沙盒可以对插件使用的资源进行限制:

struct SandboxLimits {
    // 内存限制
    size_t max_memory_bytes = 256 * 1024 * 1024;  // 256MB
    
    // CPU限制
    double max_cpu_percent = 25.0;  // 最大CPU使用率百分比
    size_t max_threads = 4;         // 最大线程数
    
    // 时间限制
    uint32_t max_processing_time_ms = 10;  // 最大处理时间(毫秒)
    
    // 文件系统限制
    size_t max_file_size_bytes = 10 * 1024 * 1024;  // 最大文件大小
    size_t max_file_descriptors = 32;  // 最大文件描述符数
    
    // 网络限制
    bool allow_outbound_connections = false;  // 允许出站连接
    size_t max_network_bytes_per_second = 0;  // 最大网络带宽(字节/秒)
};

安全策略

沙盒安全策略定义了插件的权限和访问控制:

struct SandboxSecurity {
    // 访问控制
    bool allow_network_access = false;       // 允许网络访问
    bool allow_file_system_access = false;   // 允许文件系统访问
    std::vector<std::string> allowed_paths;  // 允许访问的路径列表
    
    // 内存保护
    bool enable_address_randomization = true;  // 启用地址空间布局随机化
    bool enable_data_execution_prevention = true;  // 启用数据执行保护
    
    // 进程隔离
    bool enable_system_call_filtering = true;  // 启用系统调用过滤
    bool enable_privilege_dropping = true;     // 启用权限下降
};

跨平台实现

沙盒系统针对不同操作系统采用不同的实现机制:

  1. Windows

    • Job Objects资源限制进程监控
    • Restricted Tokens降低权限
    • AppContainer应用程序容器
    • Integrity Levels完整性级别
  2. Linux

    • Namespaces进程隔离
    • cgroups资源限制
    • seccomp系统调用过滤
    • capabilities细粒度权限控制
  3. macOS

    • Sandbox应用程序沙盒
    • XPC跨进程通信
    • Entitlements权限控制

插件元数据

PluginInfo

PluginInfo包含插件的基本描述信息:

class PluginInfo {
public:
    // 基本信息
    PluginId id;                   // 唯一标识符
    std::string name;              // 名称
    std::string vendor;            // 供应商
    Version version;               // 版本
    PluginCategory category;       // 分类
    PluginType type;               // 类型
    PluginFormat format;           // 格式
    
    // 描述
    std::string description;       // 描述
    std::string copyright;         // 版权
    std::string website;           // 网站
    std::string email;             // 联系邮箱
    
    // 技术信息
    PluginCapability capabilities; // 能力标志
    std::vector<uint16_t> supported_input_channels;  // 支持的输入声道配置
    std::vector<uint16_t> supported_output_channels; // 支持的输出声道配置
    bool has_gui;                  // 是否有GUI
    uint32_t latency_samples;      // 延迟(样本数)
    
    // 路径信息
    std::string file_path;         // 文件路径
    
    // 兼容性信息
    std::string sdk_version;       // SDK版本
};

PluginParameter

PluginParameter定义了插件参数的特性:

class PluginParameter {
public:
    // 基本信息
    std::string id;                // 唯一标识符
    std::string name;              // 显示名称
    std::string unit;              // 单位
    std::string description;       // 描述
    
    // 值范围
    double min_value;              // 最小值
    double max_value;              // 最大值
    double default_value;          // 默认值
    double step_size;              // 步进大小
    
    // 类型信息
    ParameterType type;            // 参数类型
    ParameterCategory category;    // 参数分类
    ParameterFlags flags;          // 参数标志
    
    // 枚举参数选项(对于离散参数)
    std::vector<std::string> enum_values;  // 枚举值
};

PluginPreset

PluginPreset定义了件预设的属性:

class PluginPreset {
public:
    // 基本信息
    std::string id;                // 唯一标识符
    std::string name;              // 名称
    std::string category;          // 分类
    std::string description;       // 描述
    
    // 元数据
    std::string author;            // 作者
    std::string tags;              // 标签
    std::string date_created;      // 创建日期
    
    // 路径
    std::string file_path;         // 文件路径(如果是文件预设)
    
    // 状态
    bool is_factory;               // 是否为出厂预设
    bool is_modified;              // 是否已修改
};

安全通信代理

通信原理

插件沙盒与宿主进程之间的通信使用了安全通信代理,确保所有消息都经过验证和过滤:

┌──────────────────┐                        ┌──────────────────┐
│ 宿主进程         │                        │ 沙盒进程         │
│                  │                        │                  │
│ ┌──────────────┐ │      消息验证         │ ┌──────────────┐ │
│ │              │ │      权限检查         │ │              │ │
│ │ 安全通信代理  ├─┼────────────────────┬─►│ 安全通信代理  │ │
│ │              │ │      过滤和转发     │  │              │ │
│ └──────┬───────┘ │                    │  └──────┬───────┘ │
│        │         │                    │          │         │
│        │         │      数据传输      │          │         │
│        │         │ ◄──────────────────┘          │         │
│ ┌──────▼───────┐ │                        ┌──────▼───────┐ │
│ │              │ │                        │              │ │
│ │ PluginHost   │ │                        │  Plugin实例  │ │
│ │              │ │                        │              │ │
│ └──────────────┘ │                        └──────────────┘ │
└──────────────────┘                        └──────────────────┘

消息过滤

安全通信代理对所有消息执行以下过滤:

  1. 消息类型验证:确保消息类型合法且符合预期
  2. 消息大小检查:防止过大消息导致的内存问题
  3. 消息频率限制防止DOS攻击
  4. 消息内容验证:检查消息内容的合法性

权限检查

安全通信代理根据插件的沙盒安全策略检查权限:

  • 资源访问权限检查插件是否有权访问特定资源
  • 操作权限:检查插件是否有权执行特定操作
  • 通信权限:检查插件是否有权进行特定通信

故障恢复机制

崩溃检测

系统通过以下机制检测插件崩溃:

  1. 心跳机制:插件定期发送心跳消息,如果连续多个心跳丢失则判定为崩溃
  2. 进程监控:直接监控沙盒进程的状态
  3. 超时检测:监控处理函数的执行时间,超时则判定为无响应

自动重启

当检测到插件崩溃时,系统可以自动重启插件:

  1. 创建新沙盒进程:启动新的沙盒进程
  2. 重新加载插件:在新进程中加载插件
  3. 恢复状态:尝试恢复插件的之前状态
  4. 重新连接:建立新的通信通道

降级模式

在多次崩溃后,系统可以进入降级模式:

  1. 功能限制:限插件的某些功能以提高稳定性
  2. 旁路处理:在插件失效时提供备用处理路径
  3. 资源限制:进一步限制插件的资源使用

实现示例

基础插件实现

以下是一个简单效果器插件的实现示例:

#include "audio_backend/plugin_host.h"

using namespace audio_backend::plugin_host;

class SimpleGainPlugin : public IPlugin {
public:
    SimpleGainPlugin() : initialized_(false), activated_(false), bypass_(false), gain_(1.0f) {}
    
    // 基本信息
    std::unique_ptr<PluginInfo> get_plugin_info() const override {
        auto info = std::make_unique<PluginInfo>();
        info->id = "com.example.simplegain";
        info->name = "Simple Gain";
        info->vendor = "Example Audio";
        info->version = {1, 0, 0};
        info->category = PluginCategory::Effect;
        info->type = PluginType::AudioEffect;
        info->description = "A simple gain adjustment plugin";
        
        info->capabilities = PluginCapability::AudioProcessing;
        info->supported_input_channels = {1, 2};  // 支持单声道和立体声
        info->supported_output_channels = {1, 2};
        info->has_gui = false;
        info->latency_samples = 0;  // 无延迟
        
        return info;
    }
    
    PluginId get_plugin_id() const override { return "com.example.simplegain"; }
    std::string get_name() const override { return "Simple Gain"; }
    std::string get_vendor() const override { return "Example Audio"; }
    Version get_version() const override { return {1, 0, 0}; }
    PluginCategory get_category() const override { return PluginCategory::Effect; }
    PluginType get_type() const override { return PluginType::AudioEffect; }
    PluginCapability get_capabilities() const override { return PluginCapability::AudioProcessing; }
    
    // 生命周期管理
    common::ErrorCode initialize(const engine::AudioConfig& config) override {
        if (initialized_) {
            return common::ErrorCode::ALREADY_INITIALIZED;
        }
        
        sample_rate_ = config.sample_rate;
        max_block_size_ = config.frames_per_buffer;
        num_channels_ = config.channels;
        
        initialized_ = true;
        return common::ErrorCode::SUCCESS;
    }
    
    common::ErrorCode shutdown() override {
        if (!initialized_) {
            return common::ErrorCode::NOT_INITIALIZED;
        }
        
        if (activated_) {
            deactivate();
        }
        
        initialized_ = false;
        return common::ErrorCode::SUCCESS;
    }
    
    common::ErrorCode activate() override {
        if (!initialized_) {
            return common::ErrorCode::NOT_INITIALIZED;
        }
        
        if (activated_) {
            return common::ErrorCode::ALREADY_INITIALIZED;
        }
        
        activated_ = true;
        return common::ErrorCode::SUCCESS;
    }
    
    common::ErrorCode deactivate() override {
        if (!activated_) {
            return common::ErrorCode::NOT_INITIALIZED;
        }
        
        activated_ = false;
        return common::ErrorCode::SUCCESS;
    }
    
    common::ErrorCode suspend() override {
        if (!activated_) {
            return common::ErrorCode::NOT_INITIALIZED;
        }
        
        return common::ErrorCode::SUCCESS;
    }
    
    common::ErrorCode resume() override {
        if (!initialized_) {
            return common::ErrorCode::NOT_INITIALIZED;
        }
        
        return common::ErrorCode::SUCCESS;
    }
    
    common::ErrorCode reset() override {
        gain_ = 1.0f;
        return common::ErrorCode::SUCCESS;
    }
    
    PluginState get_state() const override {
        if (!initialized_) return PluginState::Uninitialized;
        if (!activated_) return PluginState::Initialized;
        return PluginState::Active;
    }
    
    // 音频处理
    common::ErrorCode prepare_to_play(double sample_rate, uint32_t max_block_size) override {
        sample_rate_ = sample_rate;
        max_block_size_ = max_block_size;
        return common::ErrorCode::SUCCESS;
    }
    
    ProcessingResult process_audio(
        const engine::AudioBuffer& input,
        engine::AudioBuffer& output,
        const std::vector<MidiEvent>& midi_in,
        std::vector<MidiEvent>& midi_out,
        const PluginProcessContext& context) override {
        
        if (!activated_ || bypass_) {
            // 旁路模式,直接复制输入到输出
            input.copy_to(output);
            return ProcessingResult::Success;
        }
        
        // 应用增益
        input.copy_to(output);
        output.apply_gain(gain_);
        
        return ProcessingResult::Success;
    }
    
    ProcessingResult process_midi(
        const std::vector<MidiEvent>& midi_in,
        std::vector<MidiEvent>& midi_out,
        const PluginProcessContext& context) override {
        
        // 此简单插件不处理MIDI
        return ProcessingResult::Success;
    }
    
    uint32_t get_latency_samples() const override {
        return 0;  // 无延迟
    }
    
    uint32_t get_tail_length_samples() const override {
        return 0;  // 无尾部
    }
    
    common::ErrorCode set_bypass(bool bypass) override {
        bypass_ = bypass;
        return common::ErrorCode::SUCCESS;
    }
    
    bool is_bypassed() const override {
        return bypass_;
    }
    
    // 音频配置
    std::vector<uint16_t> get_supported_input_channels() const override {
        return {1, 2};  // 支持单声道和立体声
    }
    
    std::vector<uint16_t> get_supported_output_channels() const override {
        return {1, 2};  // 支持单声道和立体声
    }
    
    common::ErrorCode set_channel_configuration(uint16_t input_channels, uint16_t output_channels) override {
        // 检查是否支持请求的声道配置
        if ((input_channels != 1 && input_channels != 2) || 
            (output_channels != 1 && output_channels != 2)) {
            return common::ErrorCode::INVALID_ARGUMENT;
        }
        
        num_channels_ = input_channels;  // 简单起见,使用输入声道数
        return common::ErrorCode::SUCCESS;
    }
    
    std::pair<uint16_t, uint16_t> get_channel_configuration() const override {
        return {num_channels_, num_channels_};
    }
    
    // 参数管理
    size_t get_parameter_count() const override {
        return 1;  // 只有一个增益参数
    }
    
    std::unique_ptr<PluginParameter> get_parameter_info(size_t index) const override {
        if (index != 0) {
            return nullptr;
        }
        
        auto param = std::make_unique<PluginParameter>();
        param->id = "gain";
        param->name = "Gain";
        param->unit = "dB";
        param->description = "Adjusts the output volume";
        param->min_value = 0.0;     // 0.0 = -inf dB
        param->max_value = 2.0;     // 2.0 = +6 dB
        param->default_value = 1.0; // 1.0 = 0 dB
        param->step_size = 0.01;
        param->type = ParameterType::Float;
        param->category = ParameterCategory::Level;
        param->flags = ParameterFlags::Automatable;
        
        return param;
    }
    
    std::unique_ptr<PluginParameter> get_parameter_by_id(const std::string& parameter_id) const override {
        if (parameter_id != "gain") {
            return nullptr;
        }
        
        return get_parameter_info(0);
    }
    
    common::ErrorCode set_parameter(const std::string& parameter_id, const std::any& value) override {
        if (parameter_id != "gain") {
            return common::ErrorCode::INVALID_ARGUMENT;
        }
        
        try {
            gain_ = std::any_cast<float>(value);
            // 限制在有效范围内
            gain_ = std::max(0.0f, std::min(gain_, 2.0f));
            return common::ErrorCode::SUCCESS;
        } catch (const std::bad_any_cast&) {
            return common::ErrorCode::INVALID_ARGUMENT;
        }
    }
    
    std::any get_parameter(const std::string& parameter_id) const override {
        if (parameter_id != "gain") {
            return std::any();
        }
        
        return gain_;
    }
    
    common::ErrorCode reset_parameter(const std::string& parameter_id) override {
        if (parameter_id != "gain") {
            return common::ErrorCode::INVALID_ARGUMENT;
        }
        
        gain_ = 1.0f;
        return common::ErrorCode::SUCCESS;
    }
    
    common::ErrorCode reset_all_parameters() override {
        gain_ = 1.0f;
        return common::ErrorCode::SUCCESS;
    }
    
    // 预设管理
    size_t get_preset_count() const override {
        return 0;  // 没有预设
    }
    
    std::unique_ptr<PluginPreset> get_preset_info(size_t index) const override {
        return nullptr;  // 没有预设
    }
    
    common::ErrorCode load_preset(const std::string& preset_id) override {
        return common::ErrorCode::NOT_SUPPORTED;  // 没有预设
    }
    
    common::ErrorCode save_preset(const std::string& preset_id, const std::string& name) override {
        return common::ErrorCode::NOT_SUPPORTED;  // 没有预设
    }
    
    std::string get_current_preset_id() const override {
        return "";  // 没有预设
    }
    
    // 状态保存和恢复
    std::vector<uint8_t> get_state_data() const override {
        // 简单地将增益值序列化
        std::vector<uint8_t> data(sizeof(float));
        std::memcpy(data.data(), &gain_, sizeof(float));
        return data;
    }
    
    common::ErrorCode set_state_data(const std::vector<uint8_t>& data) override {
        if (data.size() != sizeof(float)) {
            return common::ErrorCode::INVALID_ARGUMENT;
        }
        
        std::memcpy(&gain_, data.data(), sizeof(float));
        return common::ErrorCode::SUCCESS;
    }
    
    size_t get_state_data_size() const override {
        return sizeof(float);
    }
    
    // GUI支持
    bool has_gui() const override {
        return false;  // 没有GUI
    }
    
    void* create_gui(void* parent_window) override {
        return nullptr;  // 没有GUI
    }
    
    common::ErrorCode destroy_gui() override {
        return common::ErrorCode::NOT_SUPPORTED;  // 没有GUI
    }
    
    common::ErrorCode set_gui_visible(bool visible) override {
        return common::ErrorCode::NOT_SUPPORTED;  // 没有GUI
    }
    
    bool is_gui_visible() const override {
        return false;  // 没有GUI
    }
    
    std::pair<uint32_t, uint32_t> get_gui_size() const override {
        return {0, 0};  // 没有GUI
    }
    
    common::ErrorCode set_gui_size(uint32_t width, uint32_t height) override {
        return common::ErrorCode::NOT_SUPPORTED;  // 没有GUI
    }
    
    // 事件处理
    void set_event_listener(std::shared_ptr<IPluginEventListener> listener) override {
        listener_ = listener;
    }
    
    void remove_event_listener() override {
        listener_.reset();
    }
    
    // 性能和诊断
    double get_cpu_usage() const override {
        return 0.0;  // 简单插件,不实现
    }
    
    size_t get_memory_usage() const override {
        return 0;  // 简单插件,不实现
    }
    
    std::chrono::nanoseconds get_average_processing_time() const override {
        return std::chrono::nanoseconds(0);  // 简单插件,不实现
    }
    
    std::chrono::nanoseconds get_max_processing_time() const override {
        return std::chrono::nanoseconds(0);  // 简单插件,不实现
    }
    
    void reset_performance_statistics() override {
        // 简单插件,不实现
    }
    
private:
    bool initialized_;
    bool activated_;
    bool bypass_;
    float gain_;
    double sample_rate_;
    uint32_t max_block_size_;
    uint16_t num_channels_;
    std::shared_ptr<IPluginEventListener> listener_;
};

// 导出插件工厂函数
extern "C" {
    PLUGIN_EXPORT IPlugin* create_plugin() {
        return new SimpleGainPlugin();
    }
    
    PLUGIN_EXPORT void destroy_plugin(IPlugin* plugin) {
        delete plugin;
    }
    
    PLUGIN_EXPORT PluginVersion get_plugin_version() {
        return {1, 0, 0};
    }
}

沙盒插件集成

以下是使用沙盒运行插件的示例:

#include "audio_backend/plugin_host.h"
#include <iostream>

using namespace audio_backend::plugin;

int main() {
    // 创建插件宿主管理器
    auto host_manager = create_plugin_host_manager();
    
    // 创建效果器沙盒配置
    auto sandbox_config = create_audio_effect_sandbox_config();
    
    // 自定义沙盒限制
    sandbox_config.limits.max_memory_bytes = 128 * 1024 * 1024;  // 128MB
    sandbox_config.limits.max_cpu_percent = 10.0;                 // 10% CPU
    
    // 加载插件
    auto result = host_manager->load_plugin(
        "plugins/SimpleGain.dll",   // 插件路径
        "gain_instance_1",          // 实例ID
        sandbox_config,             // 沙盒配置
        true                        // 自动激活
    );
    
    if (result != common::ErrorCode::SUCCESS) {
        std::cerr << "插件加载失败: " << common::get_error_description(result) << std::endl;
        return 1;
    }
    
    // 设置参数
    host_manager->set_plugin_parameter("gain_instance_1", "gain", 1.5f);  // +3.5dB
    
    // 创建音频缓冲区
    engine::AudioConfig audio_config;
    audio_config.sample_rate = 48000;
    audio_config.channels = 2;
    audio_config.format = engine::AudioFormat::FLOAT32;
    audio_config.frames_per_buffer = 1024;
    
    engine::AudioBuffer input_buffer(audio_config);
    engine::AudioBuffer output_buffer(audio_config);
    
    // 生成测试音频1kHz正弦波
    float* input_data = input_buffer.interleaved_data<float>();
    const float frequency = 1000.0f;  // 1kHz
    const float amplitude = 0.5f;     // -6dB
    
    for (uint32_t i = 0; i < audio_config.frames_per_buffer; ++i) {
        float sample = amplitude * std::sin(2.0f * 3.14159f * frequency * i / audio_config.sample_rate);
        input_data[i * 2] = sample;      // 左声道
        input_data[i * 2 + 1] = sample;  // 右声道
    }
    
    // 创建处理上下文
    PluginProcessContext context;
    context.sample_rate = audio_config.sample_rate;
    context.block_size = audio_config.frames_per_buffer;
    context.is_playing = true;
    
    // 处理音频
    std::vector<MidiEvent> midi_in;  // 空MIDI输入
    std::vector<MidiEvent> midi_out; // 空MIDI输出
    
    auto process_result = host_manager->process_plugin_audio(
        "gain_instance_1", 
        input_buffer, 
        output_buffer, 
        midi_in, 
        midi_out, 
        context
    );
    
    if (process_result != ProcessingResult::Success) {
        std::cerr << "音频处理失败" << std::endl;
        return 1;
    }
    
    // 验证输出应该比输入大约高3.5dB
    float* output_data = output_buffer.interleaved_data<float>();
    float max_input = 0.0f;
    float max_output = 0.0f;
    
    for (uint32_t i = 0; i < audio_config.frames_per_buffer * audio_config.channels; ++i) {
        max_input = std::max(max_input, std::abs(input_data[i]));
        max_output = std::max(max_output, std::abs(output_data[i]));
    }
    
    std::cout << "最大输入振幅: " << max_input << std::endl;
    std::cout << "最大输出振幅: " << max_output << std::endl;
    std::cout << "增益比: " << max_output / max_input << std::endl;
    
    // 卸载插件
    host_manager->unload_plugin("gain_instance_1");
    
    return 0;
}

自定义插件扩展

利用扩展机制为插件添加自定义功能:

// 定义自定义扩展接口
class ISpectrumAnalyzerExtension {
public:
    virtual ~ISpectrumAnalyzerExtension() = default;
    
    // 获取频谱数据
    virtual void get_spectrum_data(float* output, size_t size, float scale = 1.0f) = 0;
    
    // 获取最大频率
    virtual float get_peak_frequency() const = 0;
    
    // 设置FFT大小
    virtual void set_fft_size(size_t fft_size) = 0;
};

// 在插件中实现扩展
class SpectrumAnalyzerPlugin : public IPlugin {
    // ... 常规插件方法实现 ...
    
protected:
    // 实现扩展接口
    void* get_extension_impl(const std::type_info& type) override {
        if (type == typeid(ISpectrumAnalyzerExtension)) {
            return static_cast<ISpectrumAnalyzerExtension*>(this);
        }
        return nullptr;
    }
    
public:
    // 实现扩展方法
    void get_spectrum_data(float* output, size_t size, float scale = 1.0f) override {
        // 实现频谱数据获取
        // ...
    }
    
    float get_peak_frequency() const override {
        // 实现峰值频率获取
        // ...
        return peak_frequency_;
    }
    
    void set_fft_size(size_t fft_size) override {
        // 设置FFT大小
        // ...
        fft_size_ = fft_size;
    }
    
private:
    float peak_frequency_ = 0.0f;
    size_t fft_size_ = 2048;
    // ...
};

// 使用扩展
void use_plugin_extension(PluginHostManager& host_manager, const std::string& instance_id) {
    // 获取插件接口
    IPlugin* plugin = host_manager.get_plugin_interface(instance_id);
    if (!plugin) {
        return;
    }
    
    // 尝试获取扩展
    auto spectrum = plugin->get_extension<ISpectrumAnalyzerExtension>();
    if (!spectrum) {
        std::cout << "插件不支持频谱分析扩展" << std::endl;
        return;
    }
    
    // 使用扩展功能
    spectrum->set_fft_size(4096);
    
    std::vector<float> spectrum_data(2048);
    spectrum->get_spectrum_data(spectrum_data.data(), spectrum_data.size());
    
    float peak_freq = spectrum->get_peak_frequency();
    std::cout << "峰值频率: " << peak_freq << " Hz" << std::endl;
}

性能优化

资源管理

插件系统采用了多种技术优化资源使用:

  1. 按需激活:插件仅在需要时才激活,减少空闲资源占用
  2. 资源池:通过资源池复用常用资源,减少分配/释放开销
  3. 预分配缓冲区:预先分配关键缓冲区,避免实时处理中的内存分配
  4. 处理延迟控制:限制每个插件的处理时间,确保实时性

处理策略

多线程处理策略:

  1. 并行处理:独立插件可并行处理
  2. 任务分割:大型处理任务分割成小任务
  3. 优先级调度:根据实时性要求调整处理优先级
  4. 负载均衡:动态调整资源分配,优化性能

跨平台考虑

Windows特定实现

Windows平台上的沙盒实现使用

  • Job Objects:进程组管理,资源限制
  • AppContainer:应用隔离
  • Low Integrity Level:降低权限
  • Token Restriction:限制进程权限

关键安全配置:

// Windows沙盒配置示例
void configure_windows_sandbox(HANDLE job_handle) {
    JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_limits = {};
    
    // 设置基本限制
    job_limits.BasicLimitInformation.LimitFlags = 
        JOB_OBJECT_LIMIT_PROCESS_MEMORY | 
        JOB_OBJECT_LIMIT_PROCESS_TIME |
        JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
    
    job_limits.ProcessMemoryLimit = 256 * 1024 * 1024;  // 256MB
    job_limits.BasicLimitInformation.PerProcessUserTimeLimit.QuadPart = 10000000;  // 1秒
    job_limits.BasicLimitInformation.ActiveProcessLimit = 1;  // 单进程
    
    SetInformationJobObject(
        job_handle, 
        JobObjectExtendedLimitInformation, 
        &job_limits, 
        sizeof(job_limits)
    );
}

Linux特定实现

Linux平台上的沙盒实现使用

  • Namespaces:进程离
  • cgroups:资源限制
  • seccomp:系统调用过滤
  • chroot/pivot_root:文件系统隔离

关键安全配置:

// Linux沙盒配置示例
void configure_linux_sandbox() {
    // 创建命名空间隔离
    if (unshare(CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWNS) < 0) {
        return; // 错误处理
    }
    
    // 配置seccomp过滤器
    struct sock_filter filter[] = {
        // 允许最小系统调用集合...
    };
    
    struct sock_fprog prog = {
        .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
        .filter = filter,
    };
    
    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
        return; // 错误处理
    }
    
    if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
        return; // 错误处理
    }
    
    // 配置cgroups资源限制...
}

macOS特定实现

macOS平台上的沙盒实现使用

  • App Sandbox:应用级隔离
  • XPC Services:安全进间通信
  • Entitlements:权限控制
  • Mach Exception Ports:异常处理

关键安全配置:

// macOS沙盒配置示例
void configure_macos_sandbox(const char* sandbox_profile) {
    char* error = NULL;
    int result = sandbox_init(sandbox_profile, SANDBOX_NAMED, &error);
    
    if (result != 0) {
        if (error != NULL) {
            sandbox_free_error(error);
        }
        return; // 错误处理
    }
    
    // 配置XPC服务...
}