2024-08-04 14:55:40 +08:00

122 lines
3.6 KiB
C++

#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<mixer>::init(initliazer);
on_latency_offset_changed.add_raw(this, &mixer::on_mixer_latency_changed);
initliazer.require<audio_buffer_pool>();
initliazer.require<audio_device_manager>(); // 依赖音频设备管理器, 用于获取采样率和缓冲区大小
null_channel_node::init();
zero_track_ = track_pool::construct<zero_track>();
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<mixer>::release(release_guard);
release_guard.require_release<audio_device_manager>();
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<dummy_track>();
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<instrument_track>(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();
}