Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/scripts/.build.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ build() {
macos-*)
cmake_args+=(--preset 'macos-ci' -DCMAKE_OSX_ARCHITECTURES:STRING=${target##*-})

local deps_version
read -r deps_version <<< "$(jq -r '.dependencies.prebuilt.version' "${buildspec_file}")"
cmake_args+=(-DVST3SDK_PATH:STRING=${project_root}/.deps/obs-deps-${deps_version}-universal/include/vst3sdk)

typeset -gx NSUnbufferedIO=YES

typeset -gx CODESIGN_IDENT="${CODESIGN_IDENT:--}"
Expand Down Expand Up @@ -212,6 +216,7 @@ build() {
--preset ubuntu-ci
-DENABLE_BROWSER:BOOL=ON
-DCEF_ROOT_DIR:PATH="${project_root}/.deps/cef_binary_${CEF_VERSION}_${target//ubuntu-/linux_}"
-DVST3SDK_PATH:PATH="${project_root}/.deps/vst3sdk"
)

cmake_build_args+=(build_${target%%-*} --config ${config} --parallel)
Expand Down
3 changes: 3 additions & 0 deletions .github/scripts/Build-Windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ function Build {

$CmakeArgs = @('--preset', "windows-ci-${Target}")

$DepsVersion = $BuildSpec.dependencies.prebuilt.version
$CmakeArgs += @("-DVST3SDK_PATH=${ProjectRoot}\.deps\obs-deps-${DepsVersion}-${Target}\include\vst3sdk")

$CmakeBuildArgs = @('--build')
$CmakeInstallArgs = @()

Expand Down
24 changes: 24 additions & 0 deletions .github/scripts/utils.zsh/setup_ubuntu
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,27 @@ sudo apt-get install -y --no-install-recommends \
libffmpeg-nvenc-dev librist-dev libsrt-openssl-dev \
qt6-base-dev libqt6svg6-dev qt6-base-private-dev \
libvpl-dev libvpl2

log_group 'Setting up VST3 SDK...'

pushd "${project_root}/.deps"

local _target="vst3sdk"
local _url="https://github.com/steinbergmedia/vst3sdk.git"
local _hash="9fad9770f2ae8542ab1a548a68c1ad1ac690abe0"

if [[ ! -d ${_target}/pluginterfaces ]]; then
log_status "Cloning Steinberg VST3 SDK..."
git clone --filter=blob:none --sparse --recurse-submodules=no "${_url}" "${_target}"

pushd "${_target}"
git checkout "${_hash}"
git submodule update --init base pluginterfaces public.sdk
popd

log_status "Steinberg VST3 SDK cloned successfully."
else
log_status "Steinberg VST3 SDK already present; skipping clone."
fi

popd
12 changes: 6 additions & 6 deletions buildspec.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"dependencies": {
"prebuilt": {
"version": "2025-08-23",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"version": "2025-10-31",
"baseUrl": "https://github.com/pkviet/obs-deps/releases/download",
"label": "Pre-Built obs-deps",
"hashes": {
"macos-universal": "9403bb43fb0a9bb215739a5659ca274fe884dbbbcd22bd9ca781c961fb041c42",
"windows-x64": "8de229cff6f1981508c0eb646b35e644633a5855787b9f5d3b90ae2aeb87ffc1",
"windows-x86": "fb3c68b75911f292b3206e346053638db1c73605957207445a0a92b33ab5e00a",
"windows-arm64": "dd87ba00a6cbc153182fb62b3678a3b5021d1d11eb2730442060937a645eb97e"
"macos-universal": "e16443746437a89e65916323308311335fcbe8975840fc8c676e509501c47723",
"windows-x64": "f547f1ae33db67f76d1600eaa4ea1688d0509af49f9713f090b866f4a1ebbe42",
"windows-x86": "16b29e40c2e0c5c5f53d9a1f634624a37677cd26745f0ccdb64f0271cd5cff9b",
"windows-arm64": "d593c015e5c50f7020dd60fbcf94acc2d17e2931df45267b04067e3bd90213e7"
}
},
"qt6": {
Expand Down
120 changes: 120 additions & 0 deletions cmake/finders/FindVST3SDK.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#[=======================================================================[.rst
FindVST3SDK
-----------

FindModule for VST3 SDK

Imported Targets
^^^^^^^^^^^^^^^^

.. versionadded:: 3.0

This module defines the :prop_tgt:`IMPORTED` target ``VST3::SDK``.


Result Variables
^^^^^^^^^^^^^^^^

This module sets the following variables:

``VST3SDK_FOUND``
True, if all required components and the core library were found.

``VST3SDK_PATH``
Path to the SDK.

``VST3SDK_REQUIRED_FILES``
List of required files.
#]=======================================================================]

include(FindPackageHandleStandardArgs)

find_path(
VST3SDK_PATH
NAMES pluginterfaces/base/funknown.h
PATHS ${VST3SDK_PATH} ${CMAKE_SOURCE_DIR}/plugins/obs-vst3/sdk ${CMAKE_SOURCE_DIR}/deps/vst3sdk
NO_DEFAULT_PATH
)

if(VST3SDK_PATH)
set(
VST3SDK_REQUIRED_FILES
pluginterfaces/base/funknown.cpp
pluginterfaces/base/coreiids.cpp
public.sdk/source/vst/vstinitiids.cpp
public.sdk/source/vst/hosting/connectionproxy.cpp
public.sdk/source/vst/hosting/eventlist.cpp
public.sdk/source/vst/hosting/hostclasses.cpp
public.sdk/source/vst/hosting/module.cpp
public.sdk/source/vst/hosting/parameterchanges.cpp
public.sdk/source/vst/hosting/pluginterfacesupport.cpp
public.sdk/source/vst/hosting/processdata.cpp
public.sdk/source/vst/hosting/plugprovider.cpp
public.sdk/source/common/commonstringconvert.cpp
public.sdk/source/common/memorystream.cpp
public.sdk/source/vst/utility/stringconvert.cpp
)

if(OS_WINDOWS)
list(
APPEND
VST3SDK_REQUIRED_FILES
public.sdk/source/vst/hosting/module_win32.cpp
public.sdk/source/common/threadchecker_win32.cpp
)
elseif(OS_MACOS)
list(
APPEND
VST3SDK_REQUIRED_FILES
public.sdk/source/vst/hosting/module_mac.mm
public.sdk/source/common/threadchecker_mac.mm
)
elseif(OS_LINUX)
list(
APPEND
VST3SDK_REQUIRED_FILES
public.sdk/source/vst/hosting/module_linux.cpp
public.sdk/source/common/threadchecker_linux.cpp
)
endif()

set(_vst3sdk_missing "")
foreach(_f IN LISTS VST3SDK_REQUIRED_FILES)
if(NOT EXISTS "${VST3SDK_PATH}/${_f}")
list(APPEND _vst3sdk_missing "${_f}")
endif()
endforeach()

if(_vst3sdk_missing)
message(STATUS "VST3 SDK candidate at ${VST3SDK_PATH} is incomplete:")
foreach(_m IN LISTS _vst3sdk_missing)
message(STATUS " Missing: ${_m}")
endforeach()
set(VST3SDK_FOUND FALSE)
else()
set(VST3SDK_FOUND TRUE)
endif()
endif()

find_package_handle_standard_args(
VST3SDK
REQUIRED_VARS VST3SDK_PATH VST3SDK_FOUND
REASON_FAILURE_MESSAGE
"Could not find a complete Steinberg VST3 SDK. Set VST3SDK_PATH to the SDK root containing base, pluginterfaces, public.sdk/source/vst/hosting."
)

if(VST3SDK_FOUND)
if(NOT TARGET VST3::SDK)
add_library(VST3::SDK INTERFACE IMPORTED)
set_target_properties(VST3::SDK PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${VST3SDK_PATH}")
message(STATUS "Found VST3 SDK: ${VST3SDK_PATH}")
endif()
endif()

include(FeatureSummary)
set_package_properties(
VST3SDK
PROPERTIES
URL "https://www.steinberg.net/developers/"
DESCRIPTION "The Steinberg VST3 SDK provides the headers and sources for hosting and developing VST3 plug-ins."
)
1 change: 1 addition & 0 deletions plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ add_obs_plugin(
PLATFORMS WINDOWS MACOS LINUX
WITH_MESSAGE
)
add_obs_plugin(obs-vst3 PLATFORMS WINDOWS MACOS LINUX)
add_obs_plugin(obs-webrtc)

check_obs_websocket()
Expand Down
134 changes: 134 additions & 0 deletions plugins/obs-vst3/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
cmake_minimum_required(VERSION 3.28...3.30)

option(ENABLE_VST3 "Enable building OBS with VST3 plugin" ON)

if(NOT ENABLE_VST3)
target_disable(obs-vst3)
return()
endif()

project(obs-vst3)

find_package(Qt6 REQUIRED Widgets)
set(CMAKE_AUTOMOC ON)

add_library(obs-vst3 MODULE)
add_library(OBS::vst3 ALIAS obs-vst3)

find_package(VST3SDK QUIET)

if(NOT VST3SDK_FOUND)
message(STATUS "VST3 SDK not found — disabling obs-vst3 plugin.")
target_disable(obs-vst3)
return()
endif()

# SDK compile warnings
set(
SDK_WARN_FLAGS
-Wno-cast-align
-Wno-conversion
-Wno-cpp
-Wno-delete-non-virtual-dtor
-Wno-deprecated
-Wno-deprecated-copy-dtor
-Wno-deprecated-declarations
-Wno-dangling-else
-Wno-extra
-Wno-extra-semi
-Wno-float-equal
-Wno-format
-Wno-format-security
-Wno-format-truncation
-Wno-ignored-qualifiers
-Wno-int-to-pointer-cast
-Wno-missing-braces
-Wno-missing-field-initializers
-Wno-non-virtual-dtor
-Wno-overloaded-virtual
-Wno-parentheses
-Wno-pedantic
-Wno-redundant-decls
-Wno-reorder
-Wno-shadow
-Wno-sign-compare
-Wno-sign-conversion
-Wno-switch-default
-Wno-type-limits
-Wno-unused-but-set-variable
-Wno-unused-function
-Wno-unused-parameter
-Wno-zero-as-null-pointer-constant
)

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
list(APPEND SDK_WARN_FLAGS -Wno-class-memaccess -Wno-maybe-uninitialized)
endif()

list(JOIN SDK_WARN_FLAGS " " SDK_WARN_FLAGS_STR)

# SDK sources
set(VST3_SDK_SOURCES)
foreach(_src IN LISTS VST3SDK_REQUIRED_FILES)
list(APPEND VST3_SDK_SOURCES "${VST3SDK_PATH}/${_src}")
endforeach()

# Main sources
set(VST3_MAIN_SOURCES obs-vst3.cpp VST3Scanner.cpp VST3Plugin.cpp)

# Editor window sources
set(VST3EDITORWINDOW_SRC)
if(OS_WINDOWS)
list(APPEND VST3EDITORWINDOW_SRC editor/win/VST3EditorWindow.cpp)
elseif(OS_MACOS)
list(APPEND VST3EDITORWINDOW_SRC editor/mac/VST3EditorWindow.mm)
elseif(OS_LINUX)
list(APPEND VST3EDITORWINDOW_SRC editor/linux/VST3EditorWindow.cpp editor/linux/RunLoopImpl.cpp)
endif()

# Add all sources
target_sources(obs-vst3 PRIVATE ${VST3_MAIN_SOURCES} ${VST3EDITORWINDOW_SRC} ${VST3_SDK_SOURCES})

# Disable warnings for SDK files
if(OS_LINUX OR OS_MACOS)
set_source_files_properties(${VST3_SDK_SOURCES} PROPERTIES COMPILE_FLAGS "${SDK_WARN_FLAGS_STR}")
endif()

# macOS ARC for all .mm files (editor + sdk)
if(OS_MACOS)
set_source_files_properties(
editor/mac/VST3EditorWindow.mm
"${VST3SDK_PATH}/public.sdk/source/vst/hosting/module_mac.mm"
"${VST3SDK_PATH}/public.sdk/source/common/threadchecker_mac.mm"
PROPERTIES COMPILE_OPTIONS "-fobjc-arc" COMPILE_FLAGS "${SDK_WARN_FLAGS_STR}"
)
target_link_libraries(obs-vst3 PRIVATE "-framework Cocoa" "-framework Foundation")
endif()

# Includes
target_include_directories(
obs-vst3
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${VST3SDK_PATH}
${VST3SDK_PATH}/base
${VST3SDK_PATH}/pluginterfaces
${VST3SDK_PATH}/public.sdk/source/vst
${VST3SDK_PATH}/public.sdk/source/vst/hosting
${VST3SDK_PATH}/public.sdk/source/vst/utility
)

target_link_libraries(obs-vst3 PRIVATE OBS::libobs Qt6::Widgets)

# Windows resources
if(OS_WINDOWS)
configure_file(cmake/windows/obs-module.rc.in obs-vst3.rc)
target_sources(obs-vst3 PRIVATE obs-vst3.rc)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows/obs-studio.ico
${CMAKE_CURRENT_BINARY_DIR}/obs-studio.ico
COPYONLY
)
endif()

set_target_properties_obs(obs-vst3 PROPERTIES FOLDER plugins PREFIX "")
38 changes: 38 additions & 0 deletions plugins/obs-vst3/VST3EditorWindow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* Copyright (c) 2025 pkv <[email protected]>
*
* This file uses the Steinberg VST3 SDK, which is licensed under MIT license.
* See https://github.com/steinbergmedia/vst3sdk for details.
*
* This file and all modifications by pkv <[email protected]> are licensed under
* the GNU General Public License, version 3 or later, to comply with the SDK license.
*/
#pragma once
#include "pluginterfaces/gui/iplugview.h"
#include "pluginterfaces/gui/iplugviewcontentscalesupport.h"
#include <string>
#ifdef __linux__
#include "editor/linux/RunLoopImpl.h"
#endif

class VST3EditorWindow {
public:
#ifdef __linux__
VST3EditorWindow(Steinberg::IPlugView *view, const std::string &title, Display *display, RunLoopImpl *runloop);
#else
VST3EditorWindow(Steinberg::IPlugView *view, const std::string &title);
#endif
~VST3EditorWindow();

bool create(int width, int height);
void show();
void close();
// Our design of the VST3 GUI is such that it is hidden when one clicks on the x (close), except for linux.
// The reason is that we want to retain position and size of the GUI. But this can create a desync of the
// visibility state. So we need to retrieve whether the GUI was closed with x.
bool getClosedState();
#if defined(__APPLE__)
void setClosedState(bool closed);
#endif
class Impl;
Impl *impl_;
};
Loading
Loading