新增glfw, 用于创建插件窗口

This commit is contained in:
Nanako 2024-05-20 23:21:11 +08:00
parent 9c165fecb6
commit cc44f2bbae
16 changed files with 186 additions and 29 deletions

3
.gitmodules vendored
View File

@ -7,3 +7,6 @@
[submodule "third_party/rtaudio"]
path = third_party/rtaudio
url = https://github.com/thestk/rtaudio.git
[submodule "third_party/glfw"]
path = third_party/glfw
url = https://github.com/glfw/glfw.git

View File

@ -36,4 +36,5 @@ add_subdirectory(third_party/rtaudio)
add_subdirectory(third_party/spdlog)
add_subdirectory(third_party/mempool)
add_subdirectory(third_party/taskflow)
add_subdirectory(third_party/glfw)

View File

@ -8,10 +8,10 @@ retrieve_files(${CMAKE_CURRENT_SOURCE_DIR} ALL_FILES)
add_library(${PROJECT_NAME} SHARED ${ALL_FILES})
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} rtaudio spdlog mempool Taskflow)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} rtaudio spdlog mempool Taskflow)
target_link_libraries(${PROJECT_NAME} PUBLIC rtaudio spdlog mempool Taskflow)
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(${PROJECT_NAME} PUBLIC rtaudio spdlog mempool Taskflow glfw)
add_definitions(-Dcore_EXPORTS)
@ -26,9 +26,9 @@ endif ()
# platform micros
if (WIN32)
target_compile_definitions(${PROJECT_NAME} PUBLIC PLATFORM_WINDOWS=1 PLATFORM_MACOS=0 PLATFORM_LINUX=0)
target_compile_definitions(${PROJECT_NAME} PUBLIC PLATFORM_WINDOWS=1 PLATFORM_MACOS=0 PLATFORM_LINUX=0 GLFW_EXPOSE_NATIVE_WIN32)
elseif(APPLE)
target_compile_definitions(${PROJECT_NAME} PUBLIC PLATFORM_WINDOWS=0 PLATFORM_MACOS=1 PLATFORM_LINUX=0)
target_compile_definitions(${PROJECT_NAME} PUBLIC PLATFORM_WINDOWS=0 PLATFORM_MACOS=1 PLATFORM_LINUX=0 GLFW_EXPOSE_NATIVE_COCOA)
elseif(UNIX AND NOT APPLE)
target_compile_definitions(${PROJECT_NAME} PUBLIC PLATFORM_WINDOWS=0 PLATFORM_MACOS=0 PLATFORM_LINUX=1)
target_compile_definitions(${PROJECT_NAME} PUBLIC PLATFORM_WINDOWS=0 PLATFORM_MACOS=0 PLATFORM_LINUX=1 GLFW_EXPOSE_NATIVE_X11)
endif()

View File

@ -23,6 +23,7 @@ void audio_device_manager::init(singleton_initliazer& initliazer) {
audio_ = new RtAudio();
log_all_devices();
output_params_.deviceId = audio_->getDefaultOutputDevice();
output_params_.deviceId = 131;
output_params_.nChannels = get_output_channel_count();
spdlog::info("using output device id: {}", output_params_.deviceId);
}

View File

@ -22,6 +22,7 @@ public:
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);
void reset();

View File

@ -13,7 +13,7 @@ void mixer_track::init() {
const uint32_t channel_count = g_audio_device_manager.get_output_channel_count();
buffer.resize(channel_count, g_audio_device_manager.get_buffer_size());
for (int i = 0; i < buffer.get_num_channels(); ++i) {
ui_buffers.emplace_back(g_audio_device_manager.get_buffer_size() * 2);
ui_buffers->emplace_back(g_audio_device_manager.get_buffer_size() * 2);
}
channel_interface_ = new mixer_channel_interface(this);
@ -52,7 +52,7 @@ void mixer_track::process(uint32_t in_frames) {
buffer.multiple(volume);
on_processed.broadcast(this);
for (int i = 0; i < buffer.get_num_channels(); ++i) {
ui_buffers[i].Push(buffer.get_headers()[i], in_frames);
(*ui_buffers)[i].Push(buffer.get_headers()[i], in_frames);
}
}

View File

@ -20,7 +20,9 @@ struct mixer_track_link {
class mixer_track {
public:
explicit mixer_track(mixer_track_type in_type) : type_(in_type) {}
explicit mixer_track(mixer_track_type in_type) : type_(in_type) {
ui_buffers = std::make_shared<std::vector<circular_audio_buffer<float>>>();
}
virtual ~mixer_track();
void init();
@ -41,7 +43,7 @@ public:
[[nodiscard]] channel_interface* get_channel_interface() const { return channel_interface_; }
audio_buffer buffer;
std::vector<circular_audio_buffer<float>> ui_buffers;
std::shared_ptr<std::vector<circular_audio_buffer<float>>> ui_buffers;
std::atomic<float> volume = 1.0f;
std::vector<plugin_host*> effects{};
std::vector<mixer_track_link> children{};

View File

@ -1,6 +1,7 @@
#include "plugin_host.h"
#include "audio/mixer/channel_interface.h"
#include "window/window_manager.h"
plugin_host::~plugin_host() {
delete channel;
@ -11,8 +12,7 @@ void plugin_host::try_open_editor() {
return;
if (editor_opened)
return;
// editor_window = g_window_manager.create_plugin_host_window(this);
// open_editor(editor_window);
create_and_open_editor();
editor_opened = true;
}
@ -21,9 +21,8 @@ void plugin_host::try_close_editor() {
return;
if (editor_opened == false)
return;
close_editor();
destroy_editor();
editor_opened = false;
// g_window_manager.destroy_plugin_host_window(this);
}
void plugin_host::toggle_editor() {
@ -38,3 +37,12 @@ void plugin_host::toggle_editor() {
void plugin_host::init_channel_interface() {
channel = new channel_interface(get_input_channels(), get_output_channels());
}
void plugin_host::create_and_open_editor() {
void* handle = get_window_manager()->create_plugin_window(this);
open_editor(handle);
}
void plugin_host::destroy_editor() {
get_window_manager()->destroy_plugin_window(this);
}

View File

@ -3,18 +3,20 @@
#include <string>
#include <vector>
#include "extern.h"
#include "misc/delegates.h"
class mixer_track;
class channel_interface;
class CORE_API plugin_host {
friend class window_manager;
public:
virtual ~plugin_host();
virtual bool load_plugin(const char* path) = 0;
virtual void set_enabled(bool enabled) = 0;
virtual bool is_enabled() const = 0;
[[nodiscard]] virtual bool is_enabled() const = 0;
virtual void on_update_sample_rate(double sample_rate) = 0;
virtual void on_update_buffer_size(int buffer_size) = 0;
@ -30,7 +32,7 @@ public:
virtual void idle_editor() {}
[[nodiscard]] virtual bool has_editor() const { return false; }
// [[nodiscard]] virtual ImVec2 get_editor_size() const { return ImVec2(0, 0); }
virtual void get_editor_size(uint32_t& width, uint32_t& height) const = 0;
[[nodiscard]] virtual std::string load_name() const { return ""; }
[[nodiscard]] virtual std::string load_vendor() const { return ""; }
@ -43,6 +45,8 @@ public:
std::vector<mixer_track*> owner_tracks;
bool editor_opened = false;
protected:
virtual void open_editor() = 0;
void create_and_open_editor();
void destroy_editor();
virtual void open_editor(void* window_handle) = 0;
virtual void close_editor() = 0;
};

View File

@ -10,6 +10,7 @@
#include "misc/singleton/singleton_manager.h"
#include "thread_message/thread_message_hubs.h"
#include "vst2/vst2_plugin_host.h"
#include "window/window_manager.h"
void plugin_host_manager::init(singleton_initliazer& initliazer) {
singleton_t<plugin_host_manager>::init(initliazer);

View File

@ -224,13 +224,16 @@ bool vst2_plugin_host::has_editor() const {
return effect_->flags & effFlagsHasEditor;
}
// ImVec2 vst2_plugin_host::get_editor_size() const {
// ERect* EditorRect = nullptr;
// dispatch(effEditGetRect, 0, 0, &EditorRect);
// if (EditorRect)
// return ImVec2(EditorRect->right - EditorRect->left, EditorRect->bottom - EditorRect->top);
// return ImVec2(0, 0);
// }
void vst2_plugin_host::get_editor_size(uint32_t& width, uint32_t& height) const {
ERect* EditorRect = nullptr;
dispatch(effEditGetRect, 0, 0, &EditorRect);
if (!EditorRect) {
width = height = 0;
return;
}
width = EditorRect->right - EditorRect->left;
height = EditorRect->bottom - EditorRect->top;
}
std::string vst2_plugin_host::load_name() const {
char buffer[256];
@ -244,12 +247,10 @@ std::string vst2_plugin_host::load_vendor() const {
return buffer;
}
void vst2_plugin_host::open_editor() {
void vst2_plugin_host::open_editor(void* window_handle) {
if (!has_editor())
return;
// void* window_handle = glfwGetWindowHandle(window);
// dispatch(effEditOpen, 0, 0, window_handle);
dispatch(effEditOpen, 0, 0, window_handle);
}
void vst2_plugin_host::close_editor() {

View File

@ -24,12 +24,13 @@ public:
void idle_editor() override;
[[nodiscard]] bool has_editor() const override;
void get_editor_size(uint32_t& width, uint32_t& height) const override;
// [[nodiscard]] ImVec2 get_editor_size() const override;
[[nodiscard]] std::string load_name() const override;
[[nodiscard]] std::string load_vendor() const override;
protected:
void open_editor() override;
void open_editor(void* window_handle) override;
void close_editor() override;
private:
VstIntPtr dispatch(VstInt32 opcode, VstInt32 index = 0, VstIntPtr value = 0, void* ptr = nullptr, float opt = 0) const;

View File

@ -0,0 +1,96 @@
#include "window_manager.h"
#include "audio/plugin_host/plugin_host.h"
#include "audio/plugin_host/plugin_host_manager.h"
#include "GLFW/glfw3.h"
#include "GLFW/glfw3native.h"
void window_manager::init(singleton_initliazer& initliazer) {
singleton_t<window_manager>::init(initliazer);
auto plugin_host = initliazer.require<plugin_host_manager>();
plugin_host->on_instrument_removed.add_raw(this, &window_manager::destroy_plugin_window);
if (!glfwInit())
return;
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
}
void window_manager::release(singleton_release_guard& release_guard) {
singleton_t<window_manager>::release(release_guard);
release_guard.require_release<plugin_host_manager>();
windows_.clear();
host_infos_.clear();
glfwTerminate();
}
std::shared_ptr<GLFWwindow> window_manager::create_window(int width, int height, const char* title) {
auto* window = glfwCreateWindow(width, height, title, nullptr, nullptr);
std::shared_ptr<GLFWwindow> w = std::shared_ptr<GLFWwindow>(window, [](GLFWwindow* w) {
glfwDestroyWindow(w);
});
windows_.push_back(w);
return w;
}
void* window_manager::create_plugin_window(plugin_host* host) {
uint32_t width, height;
host->get_editor_size(width, height);
if (width == 0 || height == 0)
return nullptr;
auto w = create_window(width, height, host->name.c_str());
host_info info;
host_info& window_info = host_infos_[host];
window_info.window = w;
glfwSetWindowCloseCallback(w.get(), [](GLFWwindow* window) {
get_window_manager()->on_host_window_close(window);
});
#if PLATFORM_WINDOWS
HWND hwnd = glfwGetWin32Window(w.get());
return hwnd;
#elif PLATFORM_LINUX
return glfwGetX11Window(w.get());
#elif PLATFORM_MACOS
return glfwGetCocoaWindow(w.get());
#endif
return nullptr;
}
void window_manager::destroy_plugin_window(plugin_host* host) {
const auto& find = host_infos_.find(host);
if (find == host_infos_.end()) {
return;
}
auto window = find->second.window;
if (!window)
return;
auto f = std::ranges::find_if(windows_, [window](const std::weak_ptr<GLFWwindow>& w) {
return w.lock() == window;
});
windows_.erase(f);
on_host_window_close(window.get());
}
void window_manager::update() {
glfwPollEvents();
for (auto& info : host_infos_) {
if (!info.second.window) {
continue;
}
info.first->idle_editor();
}
}
void window_manager::on_host_window_close(GLFWwindow* window) {
auto f = std::ranges::find_if(host_infos_, [window](const std::pair<plugin_host*, host_info>& info) {
return info.second.window.get() == window;
});
if (f != host_infos_.end()) {
f->first->close_editor();
int x, y;
glfwGetWindowPos(window, &x, &y);
f->second.x = x;
f->second.y = y;
f->second.window.reset();
}
}

View File

@ -0,0 +1,32 @@
#pragma once
#include "GLFW/glfw3.h"
#include "misc/singleton/singleton.h"
#include <map>
#include <memory>
#include <thread>
class plugin_host;
class CORE_API window_manager : public singleton_t<window_manager> {
public:
void init(singleton_initliazer& initliazer) override;
void release(singleton_release_guard& release_guard) override;
std::shared_ptr<GLFWwindow> create_window(int width, int height, const char* title);
void* create_plugin_window(plugin_host* host);
void destroy_plugin_window(plugin_host* host);
const char* get_name() override { return "window_manager"; }
void update();
private:
std::vector<std::weak_ptr<GLFWwindow>> windows_;
struct host_info {
int32_t x;
int32_t y;
std::shared_ptr<GLFWwindow> window;
};
void on_host_window_close(GLFWwindow* window);
std::map<plugin_host*, host_info> host_infos_;
};
DEFINE_SINGLETON_INSTANCE(window_manager)

1
third_party/glfw vendored Submodule

@ -0,0 +1 @@
Subproject commit 64b4f0f30c60f11aee715214a9d8faef4372d946

View File

@ -15,4 +15,9 @@ git checkout master
git pull
cd ..
cd glfw
git checkout master
git pull
cd ..
pause