89 lines
3.0 KiB
C++
89 lines
3.0 KiB
C++
#pragma once
|
|
#include "misc/delegates.h"
|
|
#include "misc/singleton/singleton.h"
|
|
|
|
#include <string>
|
|
#include <unordered_map>
|
|
|
|
#include "../../misc/mempool.h"
|
|
#include "mixer_processor.h"
|
|
#include "mixer_track.h"
|
|
#include "taskflow/taskflow.hpp"
|
|
|
|
class plugin_host;
|
|
class channel_interface;
|
|
class mixer_track;
|
|
|
|
using track_pool = inherit_obj_pool<mixer_track, zero_track, dummy_track, instrument_track>;
|
|
inline multicast_delegate<mixer_track*> on_add_track;
|
|
inline multicast_delegate<mixer_track*> on_add_track_main_thread;
|
|
inline multicast_delegate<mixer_track*> on_remove_track;
|
|
inline multicast_delegate<mixer_track*> on_remove_track_main_thread;
|
|
|
|
class mixer_thread_cache {
|
|
public:
|
|
void add_track(mixer_track* track);
|
|
void remove_track(mixer_track* track);
|
|
void process(uint32_t in_frames, circular_buffer_vector_type& out_buffer);
|
|
void reset();
|
|
|
|
void add_link(mixer_track* in_source, mixer_track* in_target, float in_gain);
|
|
void remove_link(mixer_track* in_source, mixer_track* in_target);
|
|
|
|
void build_process_node();
|
|
void update_latency();
|
|
|
|
auto get_tracks() -> const std::vector<mixer_track*>& {
|
|
return tracks_;
|
|
}
|
|
auto begin() {
|
|
return tracks_.begin();
|
|
}
|
|
auto end() {
|
|
return tracks_.end();
|
|
}
|
|
private:
|
|
std::vector<mixer_track*> tracks_;
|
|
mixer_processor processor_;
|
|
std::atomic<bool> ready_ = false;
|
|
std::mutex mutex_;
|
|
};
|
|
|
|
class mixer : public singleton_t<mixer> {
|
|
typedef std::pair<int32_t, std::vector<mixer_track*>> layer_type;
|
|
public:
|
|
void init(singleton_initliazer& initliazer) override;
|
|
void begin_release(singleton_release_guard &release_guard) override;
|
|
void release(singleton_release_guard& release_guard) override;
|
|
const char* get_name() override { return "mixer"; }
|
|
|
|
dummy_track* create_dummy_track(const std::string& in_name, bool register_to_manager = true);
|
|
instrument_track* create_instrument_track(plugin_host* in_instrument, bool register_to_manager = true);
|
|
void remove_track(mixer_track* track);
|
|
|
|
void process(uint32_t in_frames, circular_buffer_vector_type& out_buffer) {
|
|
if (need_build_process_node_) {
|
|
mixer_thread_cache_.build_process_node();
|
|
need_build_process_node_ = false;
|
|
}
|
|
mixer_thread_cache_.process(in_frames, out_buffer);
|
|
}
|
|
void reset() { mixer_thread_cache_.reset(); }
|
|
void request_build_process_node() { need_build_process_node_ = true; }
|
|
auto get_tracks() -> const std::vector<mixer_track*>& { return mixer_thread_cache_.get_tracks(); }
|
|
|
|
[[nodiscard]] auto get_master() const -> dummy_track* { return master_; }
|
|
[[nodiscard]] auto get_zero_track() const -> zero_track* { return zero_track_; }
|
|
|
|
mixer_track* selected_track = nullptr;
|
|
private:
|
|
void on_mixer_latency_changed();
|
|
|
|
dummy_track* master_ = nullptr;
|
|
zero_track* zero_track_ = nullptr; // 用于没有任何音频输出的通道
|
|
std::atomic<bool> need_build_process_node_ = false;
|
|
mixer_thread_cache mixer_thread_cache_;
|
|
};
|
|
|
|
DEFINE_SINGLETON_INSTANCE(mixer)
|