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

1409 lines
47 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 插件接口API参考
## 目录
- [概述](#概述)
- [插件接口核心](#插件接口核心)
- [IPlugin接口](#iplugin接口)
- [生命周期管理](#生命周期管理)
- [音频处理](#音频处理)
- [参数管理](#参数管理)
- [插件宿主管理器](#插件宿主管理器)
- [PluginHostManager](#pluginhostmanager)
- [宿主配置](#宿主配置)
- [工厂函数](#工厂函数)
- [沙盒隔离机制](#沙盒隔离机制)
- [沙盒类型](#沙盒类型)
- [资源限制](#资源限制)
- [安全策略](#安全策略)
- [跨平台实现](#跨平台实现)
- [插件元数据](#插件元数据)
- [PluginInfo](#plugininfo)
- [PluginParameter](#pluginparameter)
- [PluginPreset](#pluginpreset)
- [安全通信代理](#安全通信代理)
- [通信原理](#通信原理)
- [消息过滤](#消息过滤)
- [权限检查](#权限检查)
- [故障恢复机制](#障恢复机制)
- [崩溃检测](#崩溃检测)
- [自动重启](#自动重启)
- [降级模式](#降级模式)
- [实现示例](#实现示例)
- [基础插件实现](#基础插件实现)
- [沙盒插件集成](#沙盒插件集成)
- [自定义插件扩展](#自定义插件扩展)
- [性能优化](#性能优化)
- [资源管理](#资源理)
- [处理策略](#处理策略)
- [跨平台考虑](#跨台考虑)
- [Windows特定实现](#windows特定实现)
- [Linux特定实现](#linux特定实现)
- [macOS特定实现](#macos特定实现)
## 概述
插件系统是音频端的核心组件之一,提供了一个安全且可扩展的插件架构。该系统采用多进程隔离设计,可以安全地加载和运行第三方插件,同时保护主系统免受插件崩溃或恶意行为的影响。
核心特性:
- **多进程沙盒隔离**:通过独立进程运行插件,避免崩溃影响主系统
- **资源配额管理**限制插件的CPU、内存、磁盘和网络使用
- **安全通信机制**:经过验证的跨进程消息传递
- **统一插件接口**标准化的API支持音频处理、参数控制和GUI
- **跨平台沙盒实现**支持Windows、Linux和macOS的平台特定隔离机制
- **故障检测与恢复**:自动检测和处理插件崩溃
- **性能监控**:实监控插件资源使用情况
插件系统架构图:
```
┌─────────────────────────────────┐ ┌─────────────────────────────────┐
│ 音频引擎核心进程 │ │ 插件沙盒进程 1 │
│ │ │ │
│ ┌─────────────────────────┐ │ │ ┌─────────────────────────┐ │
│ │ 插件宿主管理器 │ │ │ │ 沙盒运行时 │ │
│ └───────────┬─────────────┘ │ │ └───────────┬─────────────┘ │
│ │ │ │ │ │
│ ┌───────────▼─────────────┐ │ │ ┌───────────▼─────────────┐ │
│ │ 安全通信代理 │◄───┼─────┼─►│ 安全通信代理 │ │
│ └───────────┬─────────────┘ │ │ └───────────┬─────────────┘ │
│ │ │ │ │ │
│ ┌───────────▼─────────────┐ │ │ ┌───────────▼─────────────┐ │
│ │ 音频处理管线 │ │ │ │ 插件实例 │ │
│ └─────────────────────────┘ │ │ └─────────────────────────┘ │
└─────────────────────────────────┘ └─────────────────────────────────┘
┌─────────────────────────────────┐
│ 插件沙盒进程 2 │
│ │
│ ┌─────────────────────────┐ │
│ │ 沙盒运行时 │ │
│ └───────────┬─────────────┘ │
│ │ │
│ ┌───────────▼─────────────┐ │
│ │ 安全通信代理 │ │
│ └───────────┬─────────────┘ │
│ │ │
│ ┌───────────▼─────────────┐ │
│ │ 插件实例 │ │
│ └─────────────────────────┘ │
└─────────────────────────────────┘
```
## 插件接口核心
### IPlugin接口
`IPlugin`是所有插件必须实现的核心接口,定义了插件的基本功能和生命周期:
```cpp
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`方法实现:
```cpp
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 // 处理上下文
);
```
处理上下文提供了重要的信息,如播放位置、速度等:
```cpp
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事件由以下结构表示
```cpp
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;
};
```
### 参数管理
插件参数提供了用户控制插件行为的机制:
```cpp
// 获取参数数量
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`负责管理插件的完整生命周期,包括加载、初始化、音频处理和卸载:
```cpp
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`定义了插件宿主的配置选项:
```cpp
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; // 启用详细日志
};
```
### 工厂函数
系统提供了几个便捷的工厂函数来创建预配置的插件宿主:
```cpp
// 创建默认配置的插件宿主管理器
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);
```
同样,还有用于创建不同类型插件沙盒配置的工厂函数:
```cpp
// 创建用于音频效果器的沙盒配置
SandboxConfig create_audio_effect_sandbox_config();
// 创建用于乐器的沙盒配置
SandboxConfig create_instrument_sandbox_config();
// 创建用于分析器的沙盒配置
SandboxConfig create_analyzer_sandbox_config();
```
## 沙盒隔离机制
### 沙盒类型
系统支持多种沙盒类型,以适应不同的隔离需求:
```cpp
enum class SandboxType {
None, // 无沙盒(不推荐用于生产环境)
Process, // 进程级隔离(标准)
Container, // 容器级隔离Linux特定
Thread, // 线程级隔离(有限保护,仅用于调试)
VM // 虚拟机隔离(最高安全性,但开销大)
};
```
### 资源限制
沙盒可以对插件使用的资源进行限制:
```cpp
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; // 最大网络带宽(字节/秒)
};
```
### 安全策略
沙盒安全策略定义了插件的权限和访问控制:
```cpp
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`包含插件的基本描述信息:
```cpp
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`定义了插件参数的特性:
```cpp
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`定义了件预设的属性:
```cpp
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. **资源限制**:进一步限制插件的资源使用
## 实现示例
### 基础插件实现
以下是一个简单效果器插件的实现示例:
```cpp
#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};
}
}
```
### 沙盒插件集成
以下是使用沙盒运行插件的示例:
```cpp
#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;
}
```
### 自定义插件扩展
利用扩展机制为插件添加自定义功能:
```cpp
// 定义自定义扩展接口
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**:限制进程权限
关键安全配置:
```cpp
// 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**:文件系统隔离
关键安全配置:
```cpp
// 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**:异常处理
关键安全配置:
```cpp
// 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服务...
}