// ================================================================================================ // Audio Backend - 前端通信接口示例 // ================================================================================================ // 描述: 演示前端通信模块的使用方法 // 功能: 引擎连接、设备管理、网络发现、音频传输 // ================================================================================================ #include "audio_backend/frontend.h" #include #include #include #include #include #include using namespace audio_backend; using namespace audio_backend::frontend; // 全局退出标志 std::atomic g_running{true}; // 信号处理器 void signal_handler(int signal) { std::cout << "接收到信号: " << signal << ", 准备退出..." << std::endl; g_running = false; } // 事件监听器 class DemoEventListener : public IFrontendEventListener { public: void on_frontend_event(FrontendEvent event, const std::string& data) override { std::cout << "[事件] "; switch (event) { case FrontendEvent::EngineConnected: std::cout << "引擎已连接"; break; case FrontendEvent::EngineDisconnected: std::cout << "引擎已断开"; break; case FrontendEvent::DeviceAdded: std::cout << "设备已添加"; break; case FrontendEvent::DeviceRemoved: std::cout << "设备已移除"; break; case FrontendEvent::NetworkServiceFound: std::cout << "发现网络服务"; break; case FrontendEvent::NetworkServiceLost: std::cout << "丢失网络服务"; break; case FrontendEvent::AudioStreamStarted: std::cout << "音频流已开始"; break; case FrontendEvent::AudioStreamStopped: std::cout << "音频流已停止"; break; case FrontendEvent::ConfigurationChanged: std::cout << "配置已更改"; break; default: std::cout << "未知事件"; break; } if (!data.empty()) { std::cout << ": " << data; } std::cout << std::endl; } void on_audio_device_changed(const std::string& device_id, bool added) override { std::cout << "[设备] " << (added ? "添加" : "移除") << " 设备: " << device_id << std::endl; } void on_audio_stream_data(const engine::AudioBuffer& buffer) override { // 在实际应用中处理收到的音频数据 std::cout << "[音频] 收到音频数据: " << buffer.frames() << " 帧, " << buffer.channels() << " 声道" << std::endl; } void on_network_service_discovered(const std::string& service_name, const std::string& address, uint16_t port) override { std::cout << "[发现] 服务: " << service_name << " 地址: " << address << " 端口: " << port << std::endl; } void on_frontend_error(common::ErrorCode error, const std::string& message) override { std::cout << "[错误] 代码: " << static_cast(error) << " 消息: " << message << std::endl; } }; // ================================================================================================ // 本地音频引擎连接示例 // ================================================================================================ void local_engine_demo() { std::cout << "\n=== 本地音频引擎连接示例 ===\n" << std::endl; // 创建前端管理器 auto frontend = create_frontend_manager("demo_frontend"); if (!frontend) { std::cerr << "无法创建前端管理器" << std::endl; return; } // 添加事件监听器 auto listener = std::make_shared(); frontend->add_event_listener(listener); // 初始化前端 auto result = frontend->initialize(); if (result != common::ErrorCode::SUCCESS) { std::cerr << "前端初始化失败: " << static_cast(result) << std::endl; return; } std::cout << "前端初始化成功" << std::endl; // 连接到音频引擎 std::cout << "连接到本地音频引擎..." << std::endl; result = frontend->connect_to_engine("tcp://localhost:5555"); if (result != common::ErrorCode::SUCCESS) { std::cerr << "无法连接到音频引擎: " << static_cast(result) << std::endl; std::cout << "请确保音频引擎正在运行,继续演示其他功能..." << std::endl; } else { std::cout << "成功连接到音频引擎" << std::endl; } // 获取音频设备 std::cout << "\n获取音频设备列表..." << std::endl; auto devices = frontend->get_audio_devices(); if (devices.empty()) { std::cout << "未找到音频设备" << std::endl; } else { std::cout << "找到 " << devices.size() << " 个音频设备:" << std::endl; for (const auto& device : devices) { std::cout << " - " << device.name << " (ID: " << device.id << ")" << " [" << (device.is_input ? "输入" : "") << (device.is_output ? "输出" : "") << "]" << (device.is_default ? " 默认" : "") << std::endl; } // 如果找到默认输出设备,设置它 for (const auto& device : devices) { if (device.is_output && device.is_default) { std::cout << "\n设置默认输出设备: " << device.name << std::endl; frontend->set_output_device(device.id); break; } } } // 启动音频流(在实际环境中可能会开始播放声音) std::cout << "\n尝试启动音频..." << std::endl; result = frontend->start_audio_stream(); if (result != common::ErrorCode::SUCCESS) { std::cerr << "无法启动音频流: " << static_cast(result) << std::endl; } else { std::cout << "音频流已启动" << std::endl; // 保持音频流一小段时间 std::cout << "音频流运行中..." << std::endl; std::this_thread::sleep_for(std::chrono::seconds(2)); std::cout << "停止音频流..." << std::endl; frontend->stop_audio_stream(); } // 断开音频引擎 std::cout << "\n断开音频引擎..." << std::endl; frontend->disconnect_from_engine(); // 关闭前端 std::cout << "关闭前端..." << std::endl; frontend->shutdown(); std::cout << "本地音频引擎示例完成" << std::endl; } // ================================================================================================ // 网络服务发现示例 // ================================================================================================ void network_discovery_demo() { std::cout << "\n=== 网络服务发现示例 ===\n" << std::endl; // 创建前端管理器 auto frontend = create_frontend_manager("discovery_demo"); if (!frontend) { std::cerr << "无法创建前端管理器" << std::endl; return; } // 添加事件监听器 auto listener = std::make_shared(); frontend->add_event_listener(listener); // 初始化前端 auto result = frontend->initialize(); if (result != common::ErrorCode::SUCCESS) { std::cerr << "前端初始化失败: " << static_cast(result) << std::endl; return; } // 启动网络发现 std::cout << "启动网络服务发现..." << std::endl; result = frontend->start_network_discovery(); if (result != common::ErrorCode::SUCCESS) { std::cerr << "无法启动网络发现: " << static_cast(result) << std::endl; frontend->shutdown(); return; } // 等待并显示发现的服务 std::cout << "搜索网络音频服务 (5秒)..." << std::endl; std::this_thread::sleep_for(std::chrono::seconds(5)); auto services = frontend->get_discovered_services(); if (services.empty()) { std::cout << "未找到网络音频服务" << std::endl; } else { std::cout << "找到 " << services.size() << " 个网络音频服务:" << std::endl; for (const auto& service : services) { std::cout << " - " << service.service_name << " (类型: " << service.service_type << ")" << " 地址: " << service.address << " 端口: " << service.port << std::endl; } // 如果发现了服务,尝试连接第一个服务 if (!services.empty()) { const auto& first_service = services[0]; std::cout << "\n尝试连接到服务: " << first_service.service_name << std::endl; result = frontend->connect_to_network_service(first_service.service_id); if (result != common::ErrorCode::SUCCESS) { std::cerr << "无法连接到服务: " << static_cast(result) << std::endl; } else { std::cout << "成功连接到服务" << std::endl; // 在实际应用中,此处可以开始音频流传输 // frontend->start_network_audio_stream(...); std::cout << "断开服务连接..." << std::endl; frontend->disconnect_from_network_service(first_service.service_id); } } } // 停止网络发现 std::cout << "\n停止网络发现..." << std::endl; frontend->stop_network_discovery(); // 关闭前端 frontend->shutdown(); std::cout << "网络服务发现示例完成" << std::endl; } // ================================================================================================ // 音频流传输示例 // ================================================================================================ void audio_streaming_demo() { std::cout << "\n=== 音频流传输示例 ===\n" << std::endl; // 创建音频流发送器 auto sender_config = network::create_balanced_config(); auto sender = network::create_audio_stream_sender(sender_config); if (!sender) { std::cerr << "无法创建音频流发送器" << std::endl; return; } // 创建音频流接收器 auto receiver_config = network::create_balanced_config(); auto receiver = network::create_audio_stream_receiver(receiver_config); if (!receiver) { std::cerr << "无法创建音频流接收器" << std::endl; return; } // 创建UDP传输 auto transport_config = network::transport_factory::get_recommended_udp_config(); transport_config.local_port = 12345; // 发送端端口 auto transport = network::transport_factory::create_udp_transport(); if (!transport) { std::cerr << "无法创建UDP传输" << std::endl; return; } // 初始化传输 if (transport->initialize(transport_config) != common::ErrorCode::SUCCESS) { std::cerr << "无法初始化UDP传输" << std::endl; return; } // 绑定到本地端口 network::NetworkEndpoint local_endpoint("127.0.0.1", 12345, network::TransportProtocol::UDP); if (transport->bind(local_endpoint) != common::ErrorCode::SUCCESS) { std::cerr << "无法绑定到本地端口" << std::endl; return; } // 接收器的传输(在实际应用中,这会在不同机器上) auto receiver_transport = network::transport_factory::create_udp_transport(); transport_config.local_port = 12346; // 接收端端口 receiver_transport->initialize(transport_config); network::NetworkEndpoint receiver_endpoint("127.0.0.1", 12346, network::TransportProtocol::UDP); receiver_transport->bind(receiver_endpoint); // 初始化发送器和接收器 sender->initialize(transport); receiver->initialize(receiver_transport); std::cout << "音频流传输已设置,实际应用中会传输音频数据" << std::endl; std::cout << "发送器 -> 127.0.0.1:12345" << std::endl; std::cout << "接收器 <- 127.0.0.1:12346" << std::endl; // 在实际应用中,此处会有一个循环发送音频数据 /* // 示例代码(不会执行) engine::AudioConfig config; config.sample_rate = 48000; config.channels = 2; config.format = engine::AudioFormat::FLOAT32; config.frames_per_buffer = 480; // 10ms @ 48kHz engine::AudioBuffer buffer(config); while (running) { // 获取音频数据到buffer sender->send_audio(buffer); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } */ // 关闭发送器和接收器 std::cout << "\n关闭音频流..." << std::endl; sender->shutdown(); receiver->shutdown(); transport->shutdown(); receiver_transport->shutdown(); std::cout << "音频流传输示例成" << std::endl; } // ================================================================================================ // 编解码示例 // ================================================================================================ void codec_demo() { std::cout << "\n=== 音频编解码示例 ===\n" << std::endl; // 创建Opus编解码器 codec::CodecConfig opus_config; opus_config.codec_type = codec::CodecType::OPUS; opus_config.sample_rate = 48000; opus_config.channels = 2; opus_config.bitrate = 128000; // 128 kbps auto encoder = codec::create_codec(opus_config); if (!encoder) { std::cerr << "无法创建Opus编解码器" << std::endl; return; } // 初始化编码器 encoder->initialize(); // 创建测试音频缓冲区 engine::AudioConfig audio_config; audio_config.sample_rate = 48000; audio_config.channels = 2; audio_config.format = engine::AudioFormat::FLOAT32; audio_config.frames_per_buffer = 960; // 20ms @ 48kHz engine::AudioBuffer test_buffer(audio_config); // 生成正弦波测试数据 float* data = test_buffer.interleaved_data(); for (uint32_t i = 0; i < test_buffer.frames(); i++) { for (uint16_t c = 0; c < test_buffer.channels(); c++) { // 生成一个440Hz的正弦波 float sample = std::sin(2.0f * 3.14159f * 440.0f * i / 48000.0f); data[i * test_buffer.channels() + c] = sample * 0.5f; // 半音量 } } // 编码测试数据 std::vector encoded_data; auto result = encoder->encode(test_buffer, encoded_data); if (result != common::ErrorCode::SUCCESS) { std::cerr << "编码失败: " << static_cast(result) << std::endl; encoder->shutdown(); return; } std::cout << "音频编码结果:" << std::endl; std::cout << " - 原始大小: " << test_buffer.size_bytes() << " 字节" << std::endl; std::cout << " - 编码大小: " << encoded_data.size() << " 字节" << std::endl; std::cout << " - 压缩率: " << (100.0 * encoded_data.size() / test_buffer.size_bytes()) << "%" << std::endl; // 解码测试数据 engine::AudioBuffer decoded_buffer; result = encoder->decode(encoded_data, decoded_buffer); if (result != common::ErrorCode::SUCCESS) { std::cerr << "解码失败: " << static_cast(result) << std::endl; encoder->shutdown(); return; } std::cout << "音频解码结果:" << std::endl; std::cout << " - 解码后大小: " << decoded_buffer.size_bytes() << " 字节" << std::endl; std::cout << " - 帧数: " << decoded_buffer.frames() << std::endl; std::cout << " - 声道数: " << decoded_buffer.channels() << std::endl; // 关闭编解码器 encoder->shutdown(); std::cout << "音频编解码示例完成" << std::endl; } // ================================================================================================ // 主函数 // ================================================================================================ int main() { std::cout << "====================================\n"; std::cout << "Audio Backend 前端通信示例\n"; std::cout << "====================================\n"; // 设置信号处理 std::signal(SIGINT, signal_handler); // Ctrl+C std::signal(SIGTERM, signal_handler); // 终止信号 try { // 初始化前端系统 frontend::initialize_frontend(); // 运行各个示例 local_engine_demo(); network_discovery_demo(); audio_streaming_demo(); codec_demo(); // 关闭前端系统 frontend::shutdown_frontend(); std::cout << "\n====================================\n"; std::cout << "演示完成\n"; std::cout << "====================================\n"; } catch (const std::exception& e) { std::cerr << "演示过程中发生错误: " << e.what() << "\n"; return 1; } return 0; }