79 lines
2.5 KiB
C++

#pragma once
#include "misc/delegates.h"
#include "misc/singleton/singleton.h"
#include <string>
#include <unordered_map>
#include "mempool.h"
#include "mixer_track.h"
#include "taskflow/taskflow.hpp"
class plugin_host;
class channel_interface;
class mixer_track;
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);
instrument_track* create_instrument_track(plugin_host* in_instrument);
void remove_track(mixer_track* track);
const std::vector<mixer_track*>& get_tracks() const { return tracks_; }
void process(uint32_t in_frames, circular_buffer_vector_type& out_buffer);
void reset();
[[nodiscard]] dummy_track* get_master() const { return reinterpret_cast<dummy_track*>(tracks_[0]); }
void request_build_process_node();
dummy_track zero_track; // 用于没有任何音频输出的通道
multicast_delegate<mixer_track*> on_add_track;
multicast_delegate<mixer_track*> on_add_track_main_thread;
multicast_delegate<mixer_track*> on_remove_track;
multicast_delegate<mixer_track*> on_remove_track_main_thread;
mixer_track* selected_track = nullptr;
private:
void push_track(mixer_track* track);
template<typename T>
auto alloc_track() -> T* {
auto* track = track_pool_[T::type].template alloc<T>();
track->init();
return track;
}
template<typename T, typename ...Args>
auto alloc_track(Args&&... args) -> T* {
auto* track = track_pool_[T::type].template alloc<T>(std::forward<Args>(args)...);
track->init();
return track;
}
void free_track(mixer_track* track) {
track_pool_[track->get_type()].free(track);
}
void thread_register_track(mixer_track* track);
void thread_remove_track(mixer_track* track);
void build_process_node();
void update_taskflow(uint32_t in_frames);
void update_tasks();
void update_tasks_immediate();
void on_mixer_latency_changed();
std::vector<mixer_track*> tracks_;
std::unordered_map<mixer_track_type, mempool<>> track_pool_;
std::vector<tf::Taskflow> taskflow_;
bool process_node_dirty_ = false;
};
DEFINE_SINGLETON_INSTANCE(mixer)