#include "mixer.h" #include "channel_interface.h" #include "channel_node.h" #include "audio/device/audio_device_manager.h" #include "audio/misc/audio_buffer_pool.h" #include "audio/plugin_host/plugin_host.h" #include "audio/plugin_host/plugin_host_manager.h" #include "misc/query_timer.h" #include "misc/taskflow_singleton.h" #include "thread_message/thread_message_hubs.h" IMPL_SINGLETON_INSTANCE(mixer) void build_effect_channel_interface(mixer_track* track, const channel_interface* in_interface, std::unordered_map& processed_tracks) { int32_t& track_current_layer = processed_tracks[track]; auto& input_channel_nodes = in_interface->input_channel_nodes; auto& output_channel_nodes = in_interface->output_channel_nodes; // 如果这个效果器需要从其他轨道输入,那么目标轨道的深度就是这个轨道的深度+1 for (int i = 1; i < input_channel_nodes.size(); ++i) { channel_node* node = input_channel_nodes[i]; if (node->type != channel_node_type::mixer) continue; const mixer_channel_node* mixer_node = static_cast(node); auto* InputTrack = mixer_node->get_track(); int32_t& target_mixer_current_layer = processed_tracks[InputTrack]; target_mixer_current_layer = std::max(target_mixer_current_layer + 1, track_current_layer + 1); } // 如果这个效果器需要输出到其他轨道,那么这个轨道的深度就是目标轨道的深度+1 for (int i = 1; i < output_channel_nodes.size(); ++i) { auto* node = output_channel_nodes[i]; if (node->type != channel_node_type::mixer) continue; const auto* MixerChannelNode = static_cast(node); auto* MixerTrack = MixerChannelNode->get_track(); const int32_t& TargetMixerCurrentLayer = processed_tracks[MixerTrack]; track_current_layer = std::max(track_current_layer, TargetMixerCurrentLayer + 1); } } int32_t build_process_node_internal(mixer_track* track, std::unordered_map& processed_tracks, int32_t layer) { int32_t& track_current_layer = processed_tracks[track]; track_current_layer = std::max(track_current_layer, layer); for (const mixer_track_link& child_link : track->children) { mixer_track* ChildTrack = child_link.track; build_process_node_internal(ChildTrack, processed_tracks, layer + 1); for (const plugin_host* effect : ChildTrack->effects) { build_effect_channel_interface(ChildTrack, effect->channel, processed_tracks); } } return ++layer; } void build_instrument_process_node(const plugin_host* host, std::unordered_map& processed_tracks) { for (mixer_track* Track : host->owner_tracks) { build_effect_channel_interface(Track, host->channel, processed_tracks); } } void mixer::init(singleton_initliazer& initliazer) { singleton_t::init(initliazer); on_latency_offset_changed.add_raw(this, &mixer::on_mixer_latency_changed); initliazer.require(); initliazer.require(); // 依赖音频设备管理器, 用于获取采样率和缓冲区大小 null_channel_node::init(); zero_track.rename("zero"); zero_track.init(); auto* master = alloc_track(); master->rename("master"); push_track(master); } void mixer::begin_release(singleton_release_guard &release_guard) { singleton::begin_release(release_guard); on_latency_offset_changed.remove_object(this); } void mixer::release(singleton_release_guard& release_guard) { singleton_t::release(release_guard); release_guard.require_release(); null_channel_node::destroy(); for (mixer_track* track : tracks_) { free_track(track); } tracks_.clear(); } dummy_track* mixer::create_dummy_track(const std::string& in_name) { auto* track = alloc_track(); track->rename(in_name); g_audio_thread_hub.push_message([track, this]() { mixer_track_link link{}; link.track = track; link.send_level = 1.0f; get_master()->children.emplace_back(link); thread_register_track(track); }); return track; } instrument_track* mixer::create_instrument_track(plugin_host* in_instrument) { auto* track = alloc_track(in_instrument); // register track g_audio_thread_hub.push_message([track, this] { mixer_track_link link; link.track = track; link.send_level = 1.0f; get_master()->children.emplace_back(link); thread_register_track(track); }); return track; } void mixer::remove_track(mixer_track* track) { g_audio_thread_hub.push_message([track, this] { thread_remove_track(track); }); } void mixer::process(uint32_t in_frames, circular_buffer_vector_type& out_buffer) { for (auto& flow: taskflow_) { g_executor->run(flow).wait(); } get_master()->compensator_.pop(in_frames, out_buffer); } void mixer::reset() { if (process_node_dirty_) { g_executor->wait_for_all(); build_process_node(); update_taskflow(g_audio_device_manager.get_buffer_size()); process_node_dirty_ = false; } for (const auto track : tracks_) { track->clear(); } } void mixer::request_build_process_node() { g_audio_thread_hub.push_message([this] { update_tasks(); }); } void mixer::push_track(mixer_track* track) { tracks_.push_back(track); } void mixer::thread_register_track(mixer_track* track) { push_track(track); update_tasks(); on_add_track.broadcast(track); g_main_thread_hub.push_message([track, this] { on_add_track_main_thread.broadcast(track); }); } void mixer::thread_remove_track(mixer_track* track) { if (const auto it = std::ranges::find(tracks_, track); it != tracks_.end()) { tracks_.erase(it); } get_master()->remove_child(track); update_tasks(); on_remove_track.broadcast(track); g_main_thread_hub.push_message([track, this]() { on_remove_track_main_thread.broadcast(track); if (track == selected_track) selected_track = nullptr; free_track(track); }); } inline std::unordered_map> layer_tracks_; inline std::vector layer_order_; void mixer::build_process_node() { if (tracks_.empty()) return; std::unordered_map processed_tracks; auto* master = get_master(); build_process_node_internal(master, processed_tracks, 0); const auto& instruments = g_plugin_host_manager.get_instrument_hosts(); for (const plugin_host* instrument: instruments) { build_instrument_process_node(instrument, processed_tracks); } layer_tracks_.clear(); for (const auto& pair: processed_tracks) { layer_tracks_[pair.second].push_back(pair.first); } layer_order_.clear(); for (const auto& pair: layer_tracks_) { layer_order_.push_back(pair.first); } std::ranges::sort(layer_order_, std::greater()); } void mixer::update_taskflow(uint32_t in_frames) { taskflow_.clear(); for (int32_t order : layer_order_) { const auto& layer = layer_tracks_[order]; tf::Taskflow taskflow("mixer_update_layer" + std::to_string(order)); // 每层的轨道并行处理 for (mixer_track* track : layer) { taskflow.emplace([track, in_frames] { track->process(in_frames); }); } taskflow_.push_back(std::move(taskflow)); } } void mixer::update_tasks() { process_node_dirty_ = true; } void mixer::update_tasks_immediate() { g_executor->wait_for_all(); build_process_node(); update_taskflow(g_audio_device_manager.get_buffer_size()); } void mixer::on_mixer_latency_changed() { int32_t max_latency = 0; int32_t min_latency = 0; for (mixer_track* track : tracks_) { max_latency = std::max(max_latency, track->get_real_latency()); min_latency = std::min(min_latency, track->get_real_latency()); } for (size_t i = 1; i < tracks_.size(); i++) { mixer_track* track = tracks_[i]; track->compensator_.update_buffer(min_latency, max_latency); } }