修复退出时崩溃
This commit is contained in:
parent
fba1e94fb8
commit
065448c5a3
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -10,6 +10,3 @@
|
||||
[submodule "third_party/glfw"]
|
||||
path = third_party/glfw
|
||||
url = https://github.com/glfw/glfw.git
|
||||
[submodule "third_party/cppzmq"]
|
||||
path = third_party/cppzmq
|
||||
url = https://github.com/zeromq/cppzmq.git
|
||||
|
@ -136,18 +136,15 @@ void audio_device_manager::start_render_thread() {
|
||||
|
||||
void audio_device_manager::stop_render_thread() {
|
||||
render_thread_should_stop_ = true;
|
||||
if (render_thread_.joinable())
|
||||
render_thread_.join();
|
||||
// if (render_thread_.joinable())
|
||||
// render_thread_.join();
|
||||
// wait for render thread to stop
|
||||
while (render_thread_running_) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
std::scoped_lock lock(render_thread_mutex_);
|
||||
spdlog::info("port_audio render thread stopped");
|
||||
}
|
||||
|
||||
void audio_device_manager::render_thread() {
|
||||
set_thread_name("audio_render");
|
||||
render_thread_running_ = true;
|
||||
g_audio_thread_id = std::this_thread::get_id();
|
||||
dummy_track* master = g_mixer.get_master();
|
||||
|
||||
@ -162,6 +159,7 @@ void audio_device_manager::render_thread() {
|
||||
const float milliseconds = frames / rate * 1000; // 512 / 48000
|
||||
|
||||
while (!render_thread_should_stop_) {
|
||||
std::scoped_lock lock(render_thread_mutex_);
|
||||
g_audio_thread_hub.process_messages();
|
||||
if (render_buffers_[0].remainder() < frames) {
|
||||
// std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<uint64_t>(milliseconds)));
|
||||
@ -173,5 +171,4 @@ void audio_device_manager::render_thread() {
|
||||
g_plugin_host_manager.process(frames);
|
||||
g_mixer.process(frames, render_buffers_);
|
||||
}
|
||||
render_thread_running_ = false;
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ protected:
|
||||
void render_thread();
|
||||
std::thread render_thread_;
|
||||
circular_buffer_vector_type render_buffers_;
|
||||
std::atomic_bool render_thread_running_ = false;
|
||||
std::atomic_bool render_thread_should_stop_ = false;
|
||||
std::mutex render_thread_mutex_;
|
||||
#pragma endregion
|
||||
private:
|
||||
RtAudio::StreamParameters input_params_ = {};
|
||||
|
@ -11,12 +11,13 @@
|
||||
|
||||
IMPL_SINGLETON_INSTANCE(midi_sequencer)
|
||||
|
||||
smf::MidiFile midifile;
|
||||
|
||||
void midi_sequencer::test() {
|
||||
const char* path = R"(F:\VST\VST64\Serum_x64.dll)";
|
||||
const char* path = R"(F:\VST\VST64\Addictive Keys.dll)";
|
||||
// host->try_open_editor();
|
||||
|
||||
smf::MidiFile midifile("E:/Projects/AronaStudio/Arona/resources/1.mid");
|
||||
midifile.read("E:/Projects/AronaStudio/Arona/resources/1.mid");
|
||||
if (!midifile.status())
|
||||
spdlog::critical("Error reading MIDI file");
|
||||
midifile.doTimeAnalysis();
|
||||
@ -71,6 +72,7 @@ auto midi_sequencer::toggle_play() -> bool {
|
||||
}
|
||||
|
||||
auto midi_sequencer::create_clip_instance(clip* clip) -> clip_instance* {
|
||||
check(IS_AUDIO_THREAD());
|
||||
auto instance = new clip_instance(clip);
|
||||
clip_instances_.push_back(instance);
|
||||
return instance;
|
||||
|
@ -15,7 +15,7 @@ public:
|
||||
|
||||
void init(singleton_initliazer& initliazer) override;
|
||||
void process(double sample_rate, uint32_t delta_frames);
|
||||
auto toggle_play() -> bool ;
|
||||
auto toggle_play() -> bool;
|
||||
|
||||
template<class T>
|
||||
auto create_clip() -> T* {
|
||||
|
@ -12,6 +12,7 @@ void audio_buffer_pool::release(singleton_release_guard& release_guard) {
|
||||
for (auto& pool : pool_map_) {
|
||||
delete pool.second;
|
||||
}
|
||||
pool_map_.clear();
|
||||
}
|
||||
|
||||
sample_t* audio_buffer_pool::alloc(uint32_t block_size) {
|
||||
@ -22,5 +23,6 @@ sample_t* audio_buffer_pool::alloc(uint32_t block_size) {
|
||||
}
|
||||
|
||||
void audio_buffer_pool::free(sample_t* block, uint32_t block_size) {
|
||||
pool_map_[block_size]->deallocate(block);
|
||||
if (const auto pool = pool_map_[block_size])
|
||||
pool->deallocate(block);
|
||||
}
|
||||
|
@ -134,11 +134,11 @@ void channel_interface::remove_track(mixer_track* track) {
|
||||
}
|
||||
|
||||
mixer_channel_interface::mixer_channel_interface(mixer_track* track) : channel_interface(0, 2), track_(track) {
|
||||
node_ = new mixer_channel_node(this, track, 0);
|
||||
node_ = get_pool_obj<mixer_channel_node>(this, track, 0);
|
||||
set_output_channel(0, node_);
|
||||
}
|
||||
|
||||
mixer_channel_interface::~mixer_channel_interface() {
|
||||
delete node_;
|
||||
free_pool_obj(node_);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,60 @@
|
||||
|
||||
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);
|
||||
@ -17,17 +71,12 @@ void mixer::init(singleton_initliazer& initliazer) {
|
||||
|
||||
null_channel_node::init();
|
||||
|
||||
zero_track_ = new dummy_track();
|
||||
zero_track_->rename("zero");
|
||||
zero_track_ = track_pool::construct<zero_track>();
|
||||
zero_track_->init();
|
||||
|
||||
master_ = new dummy_track();
|
||||
master_->rename("master");
|
||||
master_->init();
|
||||
push_track(master_);
|
||||
master_ = create_dummy_track("master");
|
||||
}
|
||||
|
||||
void mixer::begin_release(singleton_release_guard &release_guard) {
|
||||
void mixer::begin_release(singleton_release_guard& release_guard) {
|
||||
singleton::begin_release(release_guard);
|
||||
on_latency_offset_changed.remove_object(this);
|
||||
}
|
||||
@ -36,90 +85,37 @@ 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();
|
||||
for (auto track : tracks_) {
|
||||
delete track;
|
||||
}
|
||||
delete zero_track_;
|
||||
tracks_.clear();
|
||||
track_pool::free_all();
|
||||
}
|
||||
|
||||
dummy_track* mixer::create_dummy_track(const std::string& in_name) {
|
||||
ready_dirty();
|
||||
auto* track = new dummy_track();
|
||||
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);
|
||||
|
||||
g_audio_thread_hub.push_message([track, this]() {
|
||||
processor_.add_link(track, get_master(), 1.0f);
|
||||
thread_register_track(track);
|
||||
});
|
||||
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) {
|
||||
ready_dirty();
|
||||
auto* track = new instrument_track(in_instrument);
|
||||
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();
|
||||
|
||||
// register track
|
||||
g_audio_thread_hub.push_message([track, this] {
|
||||
processor_.add_link(track, get_master(), 1.0f);
|
||||
thread_register_track(track);
|
||||
});
|
||||
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) {
|
||||
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);
|
||||
});
|
||||
mixer_thread_cache_.remove_track(track);
|
||||
if (track == selected_track) selected_track = nullptr;
|
||||
}
|
||||
|
||||
void mixer::on_mixer_latency_changed() {
|
||||
ready_dirty();
|
||||
g_audio_thread_hub.push_message([this] {
|
||||
processor_.update_latency();
|
||||
});
|
||||
mixer_thread_cache_.update_latency();
|
||||
}
|
||||
|
@ -14,6 +14,41 @@ 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:
|
||||
@ -22,38 +57,32 @@ public:
|
||||
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);
|
||||
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);
|
||||
[[nodiscard]] const std::vector<mixer_track*>& get_tracks() const { return tracks_; }
|
||||
|
||||
void process(uint32_t in_frames, circular_buffer_vector_type& out_buffer);
|
||||
void reset();
|
||||
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 -> dummy_track* { return zero_track_; }
|
||||
void request_build_process_node();
|
||||
bool is_ready() const { return ready_; }
|
||||
void ready_dirty() { ready_ = false; }
|
||||
|
||||
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;
|
||||
[[nodiscard]] auto get_zero_track() const -> zero_track* { return zero_track_; }
|
||||
|
||||
mixer_track* selected_track = nullptr;
|
||||
private:
|
||||
void push_track(mixer_track* track);
|
||||
|
||||
void thread_register_track(mixer_track* track);
|
||||
|
||||
void on_mixer_latency_changed();
|
||||
|
||||
dummy_track* master_;
|
||||
dummy_track* zero_track_; // 用于没有任何音频输出的通道
|
||||
std::vector<mixer_track*> tracks_;
|
||||
mixer_processor processor_;
|
||||
std::atomic<bool> ready_ = false;
|
||||
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)
|
||||
|
@ -7,8 +7,7 @@
|
||||
#include "thread_message/thread_message_hubs.h"
|
||||
|
||||
mixer_track::~mixer_track() {
|
||||
delete channel_interface_;
|
||||
channel_interface_ = nullptr;
|
||||
free_pool_obj(channel_interface_);
|
||||
for (auto e : effects_) {
|
||||
// e->on_latency_changed.remove_all(this);
|
||||
get_plugin_host_manager()->remove_effect_plugin_host(e);
|
||||
@ -25,7 +24,7 @@ void mixer_track::init() {
|
||||
buffer.set_capacity(block_size * 2);
|
||||
}
|
||||
|
||||
channel_interface_ = new mixer_channel_interface(this);
|
||||
channel_interface_ = get_pool_obj<mixer_channel_interface>(this);
|
||||
}
|
||||
|
||||
void mixer_track::add_effect(plugin_host* in_effect) {
|
||||
@ -67,7 +66,7 @@ void mixer_track::push_ui_buffer(const audio_buffer& in_buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
instrument_track::instrument_track(plugin_host* in_instrument): mixer_track(mixer_track_type::instrument)
|
||||
instrument_track::instrument_track(plugin_host* in_instrument): mixer_track(type)
|
||||
, instrument_(in_instrument) {}
|
||||
|
||||
void instrument_track::rename(const std::string& in_name) {
|
||||
|
@ -3,17 +3,16 @@
|
||||
#include <utility>
|
||||
|
||||
#include "latency_compensator.h"
|
||||
#include "../../misc/mempool.h"
|
||||
#include "audio/misc/audio_buffer.h"
|
||||
#include "audio/misc/circular_audio_buffer.h"
|
||||
#include "misc/delegates.h"
|
||||
|
||||
class channel_interface;
|
||||
class mixer_channel_interface;
|
||||
class mixer_track;
|
||||
class plugin_host;
|
||||
|
||||
enum class mixer_track_type {
|
||||
unknown,
|
||||
zero,
|
||||
dummy,
|
||||
instrument,
|
||||
};
|
||||
@ -48,7 +47,7 @@ public:
|
||||
|
||||
[[nodiscard]] auto get_type() const -> mixer_track_type { return type_; }
|
||||
|
||||
[[nodiscard]] auto get_channel_interface() const -> channel_interface* { return channel_interface_; }
|
||||
[[nodiscard]] auto get_channel_interface() const -> mixer_channel_interface* { return channel_interface_; }
|
||||
|
||||
void set_volume(float in_volume) { volume_ = in_volume; }
|
||||
[[nodiscard]] auto get_volume() const -> float { return volume_; }
|
||||
@ -69,12 +68,12 @@ private:
|
||||
circular_buffer_vector_type ui_buffers_;
|
||||
std::vector<plugin_host*> effects_{};
|
||||
audio_buffer buffer_;
|
||||
channel_interface* channel_interface_ = nullptr;
|
||||
mixer_channel_interface* channel_interface_ = nullptr;
|
||||
const uint64_t id_ = 0;
|
||||
float volume_ = 1.0f;
|
||||
};
|
||||
|
||||
class instrument_track : public mixer_track, public pool_obj<instrument_track> {
|
||||
class instrument_track : public mixer_track {
|
||||
public:
|
||||
static constexpr auto type = mixer_track_type::instrument;
|
||||
|
||||
@ -92,10 +91,10 @@ private:
|
||||
plugin_host* instrument_;
|
||||
};
|
||||
|
||||
class dummy_track : public mixer_track, public pool_obj<dummy_track> {
|
||||
class dummy_track : public mixer_track {
|
||||
public:
|
||||
static constexpr auto type = mixer_track_type::dummy;
|
||||
dummy_track() : mixer_track(mixer_track_type::dummy) {}
|
||||
dummy_track() : mixer_track(type) {}
|
||||
|
||||
void rename(const std::string& in_name) override { name_ = in_name; }
|
||||
[[nodiscard]] auto get_name() const -> std::string override { return name_; }
|
||||
@ -103,3 +102,14 @@ public:
|
||||
private:
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
class zero_track : public mixer_track {
|
||||
public:
|
||||
static constexpr auto type = mixer_track_type::zero;
|
||||
zero_track() : mixer_track(type) {}
|
||||
|
||||
[[nodiscard]] auto get_name() const -> std::string override { return "zero"; }
|
||||
void rename(const std::string& in_name) override {}
|
||||
private:
|
||||
|
||||
};
|
||||
|
@ -24,9 +24,11 @@ void plugin_host::on_update_buffer_size(int buffer_size)
|
||||
}
|
||||
}
|
||||
|
||||
void plugin_host::push_stop_all_notes(uint32_t frame_delta) {
|
||||
smf::MidiEvent event(0xB0, 0x7B, 0x00);
|
||||
push_midi(event, frame_delta);
|
||||
void plugin_host::push_stop_all_notes(uint8_t channel) {
|
||||
for (uint8_t i = 0; i < 127; ++i) {
|
||||
smf::MidiEvent event(0x80 | channel, i, 0x00);
|
||||
push_midi(event, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void plugin_host::try_open_editor() {
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
|
||||
virtual void process(uint32_t frame_num) = 0;
|
||||
virtual void push_midi(const smf::MidiEvent& event, uint32_t frame_delta) = 0;
|
||||
void push_stop_all_notes(uint32_t frame_delta = 0);
|
||||
void push_stop_all_notes(uint8_t channel = 0);
|
||||
|
||||
void try_open_editor();
|
||||
|
||||
|
@ -16,8 +16,7 @@ IMPL_SINGLETON_INSTANCE(plugin_host_manager)
|
||||
|
||||
void plugin_host_manager::init(singleton_initliazer& initliazer) {
|
||||
singleton_t::init(initliazer);
|
||||
auto* mixer_ptr = initliazer.require<mixer>();
|
||||
mixer_ptr->on_remove_track.add_raw(this, &plugin_host_manager::on_mixer_track_removed);
|
||||
on_remove_track.add_raw(this, &plugin_host_manager::on_mixer_track_removed);
|
||||
}
|
||||
|
||||
void plugin_host_manager::release(singleton_release_guard& release_guard) {
|
||||
@ -77,7 +76,7 @@ void plugin_host_manager::remove_instrument_plugin_host(plugin_host* host) {
|
||||
plugin_host* plugin_host_manager::load_plugin(const char* path) {
|
||||
auto host = new vst2_plugin_host();
|
||||
try {
|
||||
host->load_plugin(path);
|
||||
host->load(path);
|
||||
} catch (std::exception& e) {
|
||||
spdlog::error("Failed to load plugin: {}", e.what());
|
||||
delete host;
|
||||
@ -91,14 +90,15 @@ plugin_host* plugin_host_manager::load_plugin(const char* path) {
|
||||
}
|
||||
|
||||
void plugin_host_manager::register_instrument_plugin(plugin_host* host) {
|
||||
instrument_plugins_.push_back(host);
|
||||
g_audio_thread_hub.push_message([this, host]() {
|
||||
instrument_plugins_.push_back(host);
|
||||
instrument_track* instrument_track = g_mixer.create_instrument_track(host);
|
||||
host->channel->set_input_channel(instrument_track->get_channel_interface()->input_channel_nodes);
|
||||
host->channel->set_output_channel(instrument_track->get_channel_interface()->output_channel_nodes);
|
||||
host->owner_tracks.push_back(instrument_track);
|
||||
host->update_channel_node_name();
|
||||
update_taskflow(g_audio_device_manager.get_buffer_size());
|
||||
|
||||
g_main_thread_hub.push_message([host, this]() {
|
||||
on_instrument_added.broadcast(host);
|
||||
});
|
||||
@ -106,16 +106,19 @@ void plugin_host_manager::register_instrument_plugin(plugin_host* host) {
|
||||
}
|
||||
|
||||
void plugin_host_manager::process(uint32_t in_frames) {
|
||||
check(IS_AUDIO_THREAD());
|
||||
g_executor->run(taskflow_).wait();
|
||||
}
|
||||
|
||||
void plugin_host_manager::on_mixer_track_removed(mixer_track* track) {
|
||||
check(IS_AUDIO_THREAD());
|
||||
for (auto host : plugin_hosts_) {
|
||||
host->channel->remove_track(track);
|
||||
}
|
||||
}
|
||||
|
||||
void plugin_host_manager::update_taskflow(uint32_t in_frames) {
|
||||
check(IS_AUDIO_THREAD());
|
||||
tf::Taskflow taskflow;
|
||||
for (auto host : instrument_plugins_) {
|
||||
taskflow.emplace([host, in_frames] {
|
||||
|
@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
#include <coroutine>
|
||||
|
||||
#include "misc/delegates.h"
|
||||
#include "misc/singleton/singleton.h"
|
||||
#include "taskflow/taskflow.hpp"
|
||||
#include "plugin_host.h"
|
||||
#include "../../misc/mempool.h"
|
||||
#include <unordered_map>
|
||||
|
||||
class mixer_track;
|
||||
|
1
third_party/cppzmq
vendored
1
third_party/cppzmq
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 6164cf7dbc1df6d1bd8e4c6c5f8e52d7dea63aa7
|
Loading…
x
Reference in New Issue
Block a user