122 lines
3.6 KiB
C++
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();
|
|
}
|