341 lines
14 KiB
C++
341 lines
14 KiB
C++
// ================================================================================================
|
|
// Audio Backend - 插件沙盒系统演示
|
|
// ================================================================================================
|
|
// 描述: 演示插件沙盒和隔离系统的完整使用方法
|
|
// ================================================================================================
|
|
|
|
#include <audio_backend/plugin_host.h>
|
|
#include <iostream>
|
|
#include <thread>
|
|
#include <chrono>
|
|
|
|
using namespace audio_backend::plugin;
|
|
|
|
// ================================================================================================
|
|
// 示例插件事件监听器
|
|
// ================================================================================================
|
|
class DemoPluginEventListener : public IPluginHostEventListener {
|
|
public:
|
|
void on_plugin_loaded(const std::string& instance_id, const PluginInfo& info) override {
|
|
std::cout << "[EVENT] 插件已加载: " << instance_id
|
|
<< " (" << info.plugin_name << " v" << info.plugin_version.to_string() << ")\n";
|
|
}
|
|
|
|
void on_plugin_unloaded(const std::string& instance_id) override {
|
|
std::cout << "[EVENT] 插件已卸载: " << instance_id << "\n";
|
|
}
|
|
|
|
void on_plugin_activated(const std::string& instance_id) override {
|
|
std::cout << "[EVENT] 插件已激活: " << instance_id << "\n";
|
|
}
|
|
|
|
void on_plugin_deactivated(const std::string& instance_id) override {
|
|
std::cout << "[EVENT] 插件已停用: " << instance_id << "\n";
|
|
}
|
|
|
|
void on_plugin_state_changed(
|
|
const std::string& instance_id,
|
|
PluginState old_state,
|
|
PluginState new_state) override {
|
|
std::cout << "[EVENT] 插件状态变化: " << instance_id
|
|
<< " " << get_state_name(old_state)
|
|
<< " -> " << get_state_name(new_state) << "\n";
|
|
}
|
|
|
|
void on_plugin_error(
|
|
const std::string& instance_id,
|
|
const ErrorInfo& error) override {
|
|
std::cout << "[ERROR] 插件错误: " << instance_id
|
|
<< " - " << error.to_string() << "\n";
|
|
}
|
|
|
|
void on_plugin_crashed(
|
|
const std::string& instance_id,
|
|
const std::string& crash_reason) override {
|
|
std::cout << "[CRASH] 插件崩溃: " << instance_id
|
|
<< " - " << crash_reason << "\n";
|
|
}
|
|
|
|
void on_plugin_performance_warning(
|
|
const std::string& instance_id,
|
|
const std::string& warning) override {
|
|
std::cout << "[WARN] 插件性能警告: " << instance_id
|
|
<< " - " << warning << "\n";
|
|
}
|
|
|
|
void on_sandbox_violation(
|
|
const std::string& instance_id,
|
|
const std::string& violation_type) override {
|
|
std::cout << "[SECURITY] 沙违规: " << instance_id
|
|
<< " - " << violation_type << "\n";
|
|
}
|
|
};
|
|
|
|
// ================================================================================================
|
|
// 系统信息演示
|
|
// ================================================================================================
|
|
void demo_system_info() {
|
|
std::cout << "\n=== 系统信息演示 ===\n";
|
|
|
|
// 打印插件宿主系统信息
|
|
print_plugin_host_info();
|
|
|
|
// 检查沙盒支持
|
|
auto sandbox_types = get_supported_sandbox_types();
|
|
std::cout << "\n当前平台支持沙盒类型:\n";
|
|
for (const auto& type : sandbox_types) {
|
|
std::cout << " - " << get_sandbox_type_name(type) << "\n";
|
|
}
|
|
|
|
std::cout << "推荐的沙盒类型: " << get_sandbox_type_name(get_recommended_sandbox_type()) << "\n";
|
|
}
|
|
|
|
// ================================================================================================
|
|
// 基本插件管理演示
|
|
// ================================================================================================
|
|
void demo_basic_plugin_management() {
|
|
std::cout << "\n=== 基本插件管理演示 ===\n";
|
|
|
|
// 创建插件宿主管理器
|
|
std::cout << "创建插件宿主管器...\n";
|
|
auto host_manager = create_plugin_host_manager();
|
|
|
|
if (!host_manager || !host_manager->is_initialized()) {
|
|
std::cerr << "插件宿主管理器始化失败!\n";
|
|
return;
|
|
}
|
|
|
|
// 添加事件监听器
|
|
auto listener = std::make_shared<DemoPluginEventListener>();
|
|
host_manager->add_event_listener(listener);
|
|
|
|
// 配置沙盒
|
|
auto effect_config = create_audio_effect_sandbox_config();
|
|
|
|
std::cout << "沙盒配置:\n";
|
|
std::cout << " 最大内存: " << effect_config.limits.max_memory_bytes / (1024 * 1024) << " MB\n";
|
|
std::cout << " 最大CPU: " << effect_config.limits.max_cpu_percent << "%\n";
|
|
std::cout << " 最大线程数: " << effect_config.limits.max_threads << "\n";
|
|
std::cout << " 网络访问: " << (effect_config.security.allow_network_access ? "允许" : "禁止") << "\n";
|
|
|
|
// 模拟插件路径(实际使用时需要真实的插件文件)
|
|
std::string demo_plugin_path = "demo_effect_plugin.dll";
|
|
std::string instance_id = "demo_effect_1";
|
|
|
|
std::cout << "\n尝试加载插件: " << demo_plugin_path << "\n";
|
|
|
|
// 同步加载插件(这里会失败,因为插件文件不存在,但演示了流程)
|
|
auto load_result = host_manager->load_plugin(
|
|
demo_plugin_path,
|
|
instance_id,
|
|
effect_config,
|
|
true // auto_activate
|
|
);
|
|
|
|
if (load_result == common::ErrorCode::SUCCESS) {
|
|
std::cout << "插件加载成功!\n";
|
|
|
|
// 获取插件信息
|
|
auto plugin_info = host_manager->get_plugin_instance_info(instance_id);
|
|
if (plugin_info) {
|
|
std::cout << "插件状态: " << get_state_name(plugin_info->current_state) << "\n";
|
|
}
|
|
|
|
// 获取性能指标
|
|
auto metrics = host_manager->get_plugin_metrics(instance_id);
|
|
std::cout << "性能指标:\n";
|
|
std::cout << " CPU使用率: " << metrics.cpu_usage << "%\n";
|
|
std::cout << " 内存使用: " << metrics.memory_usage / (1024 * 1024) << " MB\n";
|
|
|
|
// 等待一段时间模拟处理
|
|
std::this_thread::sleep_for(std::chrono::seconds(2));
|
|
|
|
// 卸载插件
|
|
std::cout << "\n卸载插件...\n";
|
|
host_manager->unload_plugin(instance_id, true);
|
|
|
|
} else {
|
|
std::cout << "插件加载失败 (预期的,因为演插件文件不存在): "
|
|
<< common::get_error_description(load_result) << "\n";
|
|
}
|
|
|
|
// 获取宿主统计信息
|
|
auto stats = host_manager->get_host_statistics();
|
|
std::cout << "\n宿主统计信息:\n";
|
|
std::cout << " 总加载插件数: " << stats.total_plugins_loaded << "\n";
|
|
std::cout << " 总卸载插件数: " << stats.total_plugins_unloaded << "\n";
|
|
std::cout << " 总崩溃次数: " << stats.total_plugin_crashes << "\n";
|
|
}
|
|
|
|
// ================================================================================================
|
|
// 沙盒配置演示
|
|
// ================================================================================================
|
|
void demo_sandbox_configurations() {
|
|
std::cout << "\n=== 沙盒配置演示 ===\n";
|
|
|
|
// 演示不同类型的沙盒配置
|
|
std::cout << "\n1. 音频效果器沙盒配置:\n";
|
|
auto effect_config = create_audio_effect_sandbox_config();
|
|
std::cout << " 内存限制: " << effect_config.limits.max_memory_bytes / (1024 * 1024) << " MB\n";
|
|
std::cout << " CPU限制: " << effect_config.limits.max_cpu_percent << "%\n";
|
|
std::cout << " 处理时间限制: " << effect_config.limits.max_processing_time_ms << " ms\n";
|
|
|
|
std::cout << "\n2. 乐器沙盒配置:\n";
|
|
auto instrument_config = create_instrument_sandbox_config();
|
|
std::cout << " 内存限制: " << instrument_config.limits.max_memory_bytes / (1024 * 1024) << " MB\n";
|
|
std::cout << " CPU限制: " << instrument_config.limits.max_cpu_percent << "%\n";
|
|
std::cout << " 处理时间限制: " << instrument_config.limits.max_processing_time_ms << " ms\n";
|
|
|
|
std::cout << "\n3. 分析器沙盒配置:\n";
|
|
auto analyzer_config = create_analyzer_sandbox_config();
|
|
std::cout << " 内存限制: " << analyzer_config.limits.max_memory_bytes / (1024 * 1024) << " MB\n";
|
|
std::cout << " CPU限制: " << analyzer_config.limits.max_cpu_percent << "%\n";
|
|
std::cout << " 文件访问: " << (analyzer_config.security.allow_file_system_access ? "允许" : "禁止") << "\n";
|
|
|
|
std::cout << "\n4. 严格安全模式配置:\n";
|
|
auto strict_config = SandboxConfig::strict();
|
|
std::cout << " 内存限制: " << strict_config.limits.max_memory_bytes / (1024 * 1024) << " MB\n";
|
|
std::cout << " CPU限制: " << strict_config.limits.max_cpu_percent << "%\n";
|
|
std::cout << " 网络访问: " << (strict_config.security.allow_network_access ? "允许" : "禁止") << "\n";
|
|
std::cout << " 文件系统访问: " << (strict_config.security.allow_file_system_access ? "允许" : "禁止") << "\n";
|
|
}
|
|
|
|
// ================================================================================================
|
|
// 音频处理演示
|
|
// ================================================================================================
|
|
void demo_audio_processing() {
|
|
std::cout << "\n=== 音频处理演示 ===\n";
|
|
|
|
// 创建音频缓冲区
|
|
engine::AudioConfig audio_config;
|
|
audio_config.sample_rate = 48000;
|
|
audio_config.channels = 2;
|
|
audio_config.format = engine::AudioFormat::FLOAT32;
|
|
audio_config.frames_per_buffer = 512;
|
|
|
|
engine::AudioBuffer input_buffer(audio_config);
|
|
engine::AudioBuffer output_buffer(audio_config);
|
|
|
|
std::cout << "音频配置:\n";
|
|
std::cout << " 采样率: " << audio_config.sample_rate << " Hz\n";
|
|
std::cout << " 声道数: " << audio_config.channels << "\n";
|
|
std::cout << " 格式: " << engine::get_format_name(audio_config.format) << "\n";
|
|
std::cout << " 缓冲区大小: " << audio_config.frames_per_buffer << " 帧\n";
|
|
std::cout << " 延迟: " << audio_config.get_latency_ms() << " ms\n";
|
|
|
|
// 创建处理上下文
|
|
PluginProcessContext context;
|
|
context.sample_rate = audio_config.sample_rate;
|
|
context.block_size = audio_config.frames_per_buffer;
|
|
context.is_playing = true;
|
|
context.tempo = 120.0;
|
|
|
|
// 创建MIDI事件
|
|
std::vector<MidiEvent> midi_in;
|
|
std::vector<MidiEvent> midi_out;
|
|
|
|
// 添加一些示例MIDI件
|
|
midi_in.emplace_back(0, 0x90, 60, 100); // Note On C4, velocity 100
|
|
midi_in.emplace_back(256, 0x80, 60, 0); // Note Off C4
|
|
|
|
std::cout << "\nMIDI事件:\n";
|
|
for (const auto& event : midi_in) {
|
|
if (event.is_note_on()) {
|
|
std::cout << " 时间戳 " << event.timestamp << ": Note On, 音符 "
|
|
<< (int)event.get_note() << ", 力度 " << (int)event.get_velocity() << "\n";
|
|
} else if (event.is_note_off()) {
|
|
std::cout << " 时间戳 " << event.timestamp << ": Note Off, 音符 "
|
|
<< (int)event.get_note() << "\n";
|
|
}
|
|
}
|
|
|
|
std::cout << "\n模拟音频处理...\n";
|
|
// 这里通常会调用插件的音频处理方法
|
|
// 由于没有真实插件,我们只是演示数据结构
|
|
|
|
std::cout << "输入缓冲区大小: " << input_buffer.size_bytes() << " 字节\n";
|
|
std::cout << "输出缓冲区大小: " << output_buffer.size_bytes() << " 字节\n";
|
|
}
|
|
|
|
// ================================================================================================
|
|
// 插件发现演示
|
|
// ================================================================================================
|
|
void demo_plugin_discovery() {
|
|
std::cout << "\n=== 插件发现演示 ===\n";
|
|
|
|
auto host_manager = create_plugin_host_manager();
|
|
if (!host_manager) {
|
|
std::cerr << "无法创建插件宿管理器\n";
|
|
return;
|
|
}
|
|
|
|
// 演示插件目录扫描
|
|
std::vector<std::string> search_paths = {
|
|
"/usr/lib/vst",
|
|
"/usr/local/lib/vst",
|
|
"C:/Program Files/VSTPlugins",
|
|
"C:/Program Files (x86)/VSTPlugins",
|
|
"/Library/Audio/Plug-Ins/VST",
|
|
"~/Library/Audio/Plug-Ins/VST"
|
|
};
|
|
|
|
std::cout << "搜索插件路径:\n";
|
|
for (const auto& path : search_paths) {
|
|
std::cout << " - " << path << "\n";
|
|
|
|
// 尝试扫描目录(大部分路径在演示环境中不存在)
|
|
try {
|
|
auto plugin_paths = host_manager->scan_plugin_directory(path, false);
|
|
std::cout << " 发现 " << plugin_paths.size() << " 个插件\n";
|
|
|
|
// 扫描前几个插件的信息
|
|
for (size_t i = 0; i < std::min(plugin_paths.size(), size_t(3)); ++i) {
|
|
auto info = host_manager->scan_plugin_info(plugin_paths[i]);
|
|
if (info) {
|
|
std::cout << " 插件: " << info->plugin_name
|
|
<< " v" << info->plugin_version.to_string()
|
|
<< " (" << get_format_name(info->plugin_format) << ")\n";
|
|
}
|
|
}
|
|
} catch (const std::exception& e) {
|
|
// 路径不存在或无法访问是正常的
|
|
std::cout << " (路径不存在或无访问)\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
// ================================================================================================
|
|
// 主函数
|
|
// ================================================================================================
|
|
int main() {
|
|
std::cout << "====================================\n";
|
|
std::cout << "Audio Backend 插件沙盒系统演示\n";
|
|
std::cout << "====================================\n";
|
|
|
|
try {
|
|
// 系统信息演示
|
|
demo_system_info();
|
|
|
|
// 沙盒配置演示
|
|
demo_sandbox_configurations();
|
|
|
|
// 音频处理演示
|
|
demo_audio_processing();
|
|
|
|
// 插件发现演示
|
|
demo_plugin_discovery();
|
|
|
|
// 基本插件管理演示
|
|
demo_basic_plugin_management();
|
|
|
|
std::cout << "\n====================================\n";
|
|
std::cout << "演示完成\n";
|
|
std::cout << "====================================\n";
|
|
|
|
} catch (const std::exception& e) {
|
|
std::cerr << "演示过程中发生误: " << e.what() << "\n";
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
} |