#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 "misc/query_timer.h" #include "thread_message/thread_message_hubs.h" IMPL_SINGLETON_INSTANCE(mixer) void mixer_thread_cache::add_track(mixer_track* track) { std::lock_guard lock(mutex_); tracks_.push_back(track); } void mixer_thread_cache::remove_track(mixer_track* track) { std::lock_guard lock(mutex_); if (const auto it = std::ranges::find(tracks_, track); it != tracks_.end()) { tracks_.erase(it); } processor_.remove_track(track); on_remove_track.broadcast(track); g_main_thread_hub.push_message([track, this]() { on_remove_track_main_thread.broadcast(track); track_pool::free(track); }); } void mixer_thread_cache::process(uint32_t in_frames, circular_buffer_vector_type& out_buffer) { std::lock_guard lock(mutex_); processor_.process(in_frames); processor_.pop_master(in_frames, out_buffer); ready_ = true; } void mixer_thread_cache::reset() { std::lock_guard lock(mutex_); for (const auto track : tracks_) { track->clear(); } } void mixer_thread_cache::add_link(mixer_track* in_source, mixer_track* in_target, float in_gain) { std::lock_guard lock(mutex_); processor_.add_link(in_source, in_target, in_gain); } void mixer_thread_cache::remove_link(mixer_track* in_source, mixer_track* in_target) { std::lock_guard lock(mutex_); processor_.remove_link(in_source, in_target); } void mixer_thread_cache::build_process_node() { std::lock_guard lock(mutex_); processor_.update_all(); } void mixer_thread_cache::update_latency() { std::lock_guard lock(mutex_); processor_.update_latency(); } 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_ = track_pool::construct(); zero_track_->init(); master_ = create_dummy_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(); track_pool::free_all(); } dummy_track* mixer::create_dummy_track(const std::string& in_name, bool register_to_manager) { auto* track = track_pool::construct(); track->init(); track->rename(in_name); if (register_to_manager) { mixer_thread_cache_.add_track(track); mixer_thread_cache_.add_link(track, get_master(), 1.0f); } return track; } instrument_track* mixer::create_instrument_track(plugin_host* in_instrument, bool register_to_manager) { auto* track = track_pool::construct(in_instrument); track->init(); if (register_to_manager) { mixer_thread_cache_.add_track(track); mixer_thread_cache_.add_link(track, get_master(), 1.0f); } return track; } void mixer::remove_track(mixer_track* track) { mixer_thread_cache_.remove_track(track); if (track == selected_track) selected_track = nullptr; } void mixer::on_mixer_latency_changed() { mixer_thread_cache_.update_latency(); }