#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::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_ = new dummy_track(); zero_track_->rename("zero"); zero_track_->init(); master_ = new dummy_track(); master_->rename("master"); master_->init(); 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 (auto track : tracks_) { delete track; } delete zero_track_; tracks_.clear(); } dummy_track* mixer::create_dummy_track(const std::string& in_name) { ready_dirty(); auto* track = new dummy_track(); track->init(); track->rename(in_name); g_audio_thread_hub.push_message([track, this]() { processor_.add_link(track, get_master(), 1.0f); thread_register_track(track); }); return track; } instrument_track* mixer::create_instrument_track(plugin_host* in_instrument) { ready_dirty(); auto* track = new instrument_track(in_instrument); track->init(); // register track g_audio_thread_hub.push_message([track, this] { processor_.add_link(track, get_master(), 1.0f); thread_register_track(track); }); return track; } void mixer::remove_track(mixer_track* track) { g_audio_thread_hub.push_message([track, this] { 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); if (track == selected_track) selected_track = nullptr; delete track; }); }); } void mixer::process(uint32_t in_frames, circular_buffer_vector_type& out_buffer) { processor_.process(in_frames); processor_.pop_master(in_frames, out_buffer); ready_ = true; } void mixer::reset() { for (const auto track : tracks_) { track->clear(); } } void mixer::request_build_process_node() { g_audio_thread_hub.push_message([this] { processor_.update_all(); }); } void mixer::push_track(mixer_track* track) { tracks_.push_back(track); } void mixer::thread_register_track(mixer_track* track) { push_track(track); processor_.update_all(); on_add_track.broadcast(track); g_main_thread_hub.push_message([track, this] { on_add_track_main_thread.broadcast(track); }); } void mixer::on_mixer_latency_changed() { ready_dirty(); g_audio_thread_hub.push_message([this] { processor_.update_latency(); }); }