@soundor/vst3-host 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CMakeLists.txt +194 -0
- package/CMakePresets.json +115 -0
- package/LICENSE +21 -0
- package/NOTICE.md +17 -0
- package/README.md +40 -2
- package/cmake/Vst3HostDependencies.cmake +179 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +88 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/index.d.mts +586 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1 -0
- package/dist/prepare-ayjTVhfk.mjs +1149 -0
- package/dist/prepare-ayjTVhfk.mjs.map +1 -0
- package/native/src/Bundle.cpp +253 -0
- package/native/src/Bundle.h +32 -0
- package/native/src/EditorArea.h +92 -0
- package/native/src/EditorAreaMac.mm +52 -0
- package/native/src/EditorAreaWindows.cpp +66 -0
- package/native/src/EditorAreaX11.cpp +512 -0
- package/native/src/EditorWindow.h +72 -0
- package/native/src/EditorWindowMac.mm +134 -0
- package/native/src/EditorWindowWindows.cpp +148 -0
- package/native/src/EventLoop.h +50 -0
- package/native/src/EventLoopLinux.cpp +204 -0
- package/native/src/EventLoopMac.mm +146 -0
- package/native/src/EventLoopWindows.cpp +132 -0
- package/native/src/HostContext.cpp +217 -0
- package/native/src/HostContext.h +116 -0
- package/native/src/HostInterface.cpp +1026 -0
- package/native/src/HostInterface.h +138 -0
- package/native/src/HostWindow.cpp +901 -0
- package/native/src/HostWindow.h +187 -0
- package/native/src/Ipc.cpp +158 -0
- package/native/src/Ipc.h +91 -0
- package/native/src/Json.cpp +426 -0
- package/native/src/Json.h +85 -0
- package/native/src/LiveAudio.cpp +416 -0
- package/native/src/LiveAudio.h +121 -0
- package/native/src/Main.cpp +178 -0
- package/native/src/Paths.h +20 -0
- package/native/src/Plugin.cpp +1865 -0
- package/native/src/Plugin.h +321 -0
- package/native/src/Session.cpp +656 -0
- package/native/src/Session.h +82 -0
- package/native/src/Settings.cpp +93 -0
- package/native/src/Settings.h +23 -0
- package/native/src/Version.h.in +11 -0
- package/native/src/X11Library.cpp +127 -0
- package/native/src/X11Library.h +83 -0
- package/native/tools/Embed.cpp +49 -0
- package/package.json +58 -3
- package/protocol.json +7 -0
- package/targets.json +33 -0
package/CMakeLists.txt
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# soundor-vst3-host: the native executable of @soundor/vst3-host.
|
|
2
|
+
#
|
|
3
|
+
# cmake --workflow --preset dev Debug, tests, -Werror → build/dev
|
|
4
|
+
# cmake --workflow --preset release the shipped configuration → build/release
|
|
5
|
+
#
|
|
6
|
+
# The version comes from package.json and the protocol from protocol.json,
|
|
7
|
+
# so the executable and the Node client agree on both. Nothing here depends
|
|
8
|
+
# on JUCE, the Soundor engine or any other workspace package.
|
|
9
|
+
cmake_minimum_required(VERSION 3.25)
|
|
10
|
+
|
|
11
|
+
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/package.json" soundor_package)
|
|
12
|
+
string(JSON SOUNDOR_VST3_HOST_VERSION GET "${soundor_package}" version)
|
|
13
|
+
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/protocol.json" soundor_protocol)
|
|
14
|
+
string(JSON SOUNDOR_VST3_HOST_PROTOCOL GET "${soundor_protocol}" version)
|
|
15
|
+
string(JSON SOUNDOR_VST3_HOST_MAX_HEADER GET "${soundor_protocol}" maxHeaderBytes)
|
|
16
|
+
string(JSON SOUNDOR_VST3_HOST_MAX_PAYLOAD GET "${soundor_protocol}" defaultMaxPayloadBytes)
|
|
17
|
+
string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" soundor_numeric_version "${SOUNDOR_VST3_HOST_VERSION}")
|
|
18
|
+
|
|
19
|
+
# The oldest macOS the host runs on, in any build. CMake wants it before project().
|
|
20
|
+
if(APPLE AND NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET AND NOT DEFINED ENV{MACOSX_DEPLOYMENT_TARGET})
|
|
21
|
+
set(CMAKE_OSX_DEPLOYMENT_TARGET 12.0 CACHE STRING "The oldest macOS the host runs on")
|
|
22
|
+
endif()
|
|
23
|
+
|
|
24
|
+
project(SoundorVst3Host VERSION ${soundor_numeric_version} LANGUAGES C CXX)
|
|
25
|
+
if(APPLE)
|
|
26
|
+
enable_language(OBJCXX)
|
|
27
|
+
endif()
|
|
28
|
+
|
|
29
|
+
option(SOUNDOR_VST3_HOST_BUILD_TESTS "Build the self-test and the fixture plugins" OFF)
|
|
30
|
+
option(SOUNDOR_VST3_HOST_WARNINGS_AS_ERRORS "Treat warnings in the host's own sources as errors" OFF)
|
|
31
|
+
option(SOUNDOR_VST3_HOST_SANITIZERS "Build with AddressSanitizer and UndefinedBehaviorSanitizer" OFF)
|
|
32
|
+
option(SOUNDOR_VST3_HOST_CLANG_TIDY "Check the host's own sources with clang-tidy" OFF)
|
|
33
|
+
|
|
34
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
35
|
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
36
|
+
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
37
|
+
set(CMAKE_OBJCXX_STANDARD 20)
|
|
38
|
+
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
|
39
|
+
set(CMAKE_OBJCXX_VISIBILITY_PRESET hidden)
|
|
40
|
+
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
|
41
|
+
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
42
|
+
# A self-contained executable: no Visual C++ redistributable needed.
|
|
43
|
+
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
|
44
|
+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
45
|
+
|
|
46
|
+
find_package(Threads REQUIRED)
|
|
47
|
+
include(cmake/Vst3HostDependencies.cmake)
|
|
48
|
+
|
|
49
|
+
if(SOUNDOR_VST3_HOST_SANITIZERS AND NOT MSVC)
|
|
50
|
+
add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer -fno-sanitize-recover=undefined)
|
|
51
|
+
add_link_options(-fsanitize=address,undefined)
|
|
52
|
+
endif()
|
|
53
|
+
|
|
54
|
+
# ── The SDK's hosting helpers ───────────────────────────────────────────────
|
|
55
|
+
|
|
56
|
+
set(sdk "${SOUNDOR_VST3_SDK_DIR}")
|
|
57
|
+
add_library(soundor_vst3_sdk_hosting STATIC
|
|
58
|
+
"${sdk}/pluginterfaces/base/conststringtable.cpp"
|
|
59
|
+
"${sdk}/pluginterfaces/base/coreiids.cpp"
|
|
60
|
+
"${sdk}/pluginterfaces/base/funknown.cpp"
|
|
61
|
+
"${sdk}/pluginterfaces/base/ustring.cpp"
|
|
62
|
+
"${sdk}/public.sdk/source/common/commoniids.cpp"
|
|
63
|
+
"${sdk}/public.sdk/source/common/commonstringconvert.cpp"
|
|
64
|
+
"${sdk}/public.sdk/source/common/memorystream.cpp"
|
|
65
|
+
"${sdk}/public.sdk/source/vst/hosting/connectionproxy.cpp"
|
|
66
|
+
"${sdk}/public.sdk/source/vst/hosting/eventlist.cpp"
|
|
67
|
+
"${sdk}/public.sdk/source/vst/hosting/hostclasses.cpp"
|
|
68
|
+
"${sdk}/public.sdk/source/vst/hosting/module.cpp"
|
|
69
|
+
"${sdk}/public.sdk/source/vst/hosting/parameterchanges.cpp"
|
|
70
|
+
"${sdk}/public.sdk/source/vst/hosting/pluginterfacesupport.cpp"
|
|
71
|
+
"${sdk}/public.sdk/source/vst/utility/stringconvert.cpp"
|
|
72
|
+
"${sdk}/public.sdk/source/vst/vstinitiids.cpp")
|
|
73
|
+
if(WIN32)
|
|
74
|
+
target_sources(soundor_vst3_sdk_hosting PRIVATE
|
|
75
|
+
"${sdk}/public.sdk/source/vst/hosting/module_win32.cpp"
|
|
76
|
+
"${sdk}/public.sdk/source/common/threadchecker_win32.cpp")
|
|
77
|
+
target_link_libraries(soundor_vst3_sdk_hosting PUBLIC ole32 shell32)
|
|
78
|
+
# Written for C++17, where u8string() returns std::string.
|
|
79
|
+
set_source_files_properties("${sdk}/public.sdk/source/vst/hosting/module_win32.cpp"
|
|
80
|
+
PROPERTIES COMPILE_OPTIONS "$<$<CXX_COMPILER_ID:MSVC>:/Zc:char8_t->")
|
|
81
|
+
target_compile_definitions(soundor_vst3_sdk_hosting PUBLIC UNICODE _UNICODE NOMINMAX)
|
|
82
|
+
elseif(APPLE)
|
|
83
|
+
target_sources(soundor_vst3_sdk_hosting PRIVATE
|
|
84
|
+
"${sdk}/public.sdk/source/vst/hosting/module_mac.mm"
|
|
85
|
+
"${sdk}/public.sdk/source/common/threadchecker_mac.mm")
|
|
86
|
+
target_link_libraries(soundor_vst3_sdk_hosting PUBLIC "-framework CoreFoundation" "-framework Foundation")
|
|
87
|
+
# The SDK's Objective-C++ needs ARC; the host's own (EditorWindowMac.mm,
|
|
88
|
+
# EventLoopMac.mm) manages references itself.
|
|
89
|
+
set_source_files_properties("${sdk}/public.sdk/source/vst/hosting/module_mac.mm"
|
|
90
|
+
PROPERTIES COMPILE_OPTIONS -fobjc-arc)
|
|
91
|
+
else()
|
|
92
|
+
target_sources(soundor_vst3_sdk_hosting PRIVATE
|
|
93
|
+
"${sdk}/public.sdk/source/vst/hosting/module_linux.cpp"
|
|
94
|
+
"${sdk}/public.sdk/source/common/threadchecker_linux.cpp")
|
|
95
|
+
target_link_libraries(soundor_vst3_sdk_hosting PUBLIC ${CMAKE_DL_LIBS})
|
|
96
|
+
endif()
|
|
97
|
+
target_include_directories(soundor_vst3_sdk_hosting SYSTEM PUBLIC "${sdk}")
|
|
98
|
+
target_compile_definitions(soundor_vst3_sdk_hosting PUBLIC $<IF:$<CONFIG:Debug>,DEVELOPMENT=1,RELEASE=1>)
|
|
99
|
+
target_link_libraries(soundor_vst3_sdk_hosting PUBLIC Threads::Threads)
|
|
100
|
+
# Upstream code: its warnings are not ours to fix.
|
|
101
|
+
if(MSVC)
|
|
102
|
+
target_compile_options(soundor_vst3_sdk_hosting PRIVATE /W0)
|
|
103
|
+
else()
|
|
104
|
+
target_compile_options(soundor_vst3_sdk_hosting PRIVATE -w)
|
|
105
|
+
endif()
|
|
106
|
+
|
|
107
|
+
# ── Warnings for the host's own sources ─────────────────────────────────────
|
|
108
|
+
|
|
109
|
+
function(soundor_vst3_host_warnings target)
|
|
110
|
+
if(MSVC)
|
|
111
|
+
# Warnings are errors with Clang and GCC (the dev, release and tidy
|
|
112
|
+
# presets); MSVC's /W4 reports, but does not fail, the build.
|
|
113
|
+
target_compile_options(${target} PRIVATE /W4 /permissive- /utf-8)
|
|
114
|
+
else()
|
|
115
|
+
target_compile_options(${target} PRIVATE -Wall -Wextra -Wno-unused-parameter)
|
|
116
|
+
if(SOUNDOR_VST3_HOST_WARNINGS_AS_ERRORS)
|
|
117
|
+
target_compile_options(${target} PRIVATE -Werror)
|
|
118
|
+
endif()
|
|
119
|
+
endif()
|
|
120
|
+
if(SOUNDOR_VST3_HOST_CLANG_TIDY)
|
|
121
|
+
find_program(SOUNDOR_CLANG_TIDY_EXE NAMES clang-tidy-18 clang-tidy REQUIRED)
|
|
122
|
+
set_target_properties(${target} PROPERTIES
|
|
123
|
+
CXX_CLANG_TIDY "${SOUNDOR_CLANG_TIDY_EXE};--warnings-as-errors=*")
|
|
124
|
+
endif()
|
|
125
|
+
endfunction()
|
|
126
|
+
|
|
127
|
+
# Every configuration's outputs in one place (Visual Studio adds a
|
|
128
|
+
# per-configuration directory otherwise).
|
|
129
|
+
function(soundor_vst3_host_output target kind directory)
|
|
130
|
+
set_target_properties(${target} PROPERTIES ${kind}_OUTPUT_DIRECTORY "${directory}")
|
|
131
|
+
foreach(config IN ITEMS Debug Release RelWithDebInfo MinSizeRel)
|
|
132
|
+
string(TOUPPER ${config} upper)
|
|
133
|
+
set_target_properties(${target} PROPERTIES ${kind}_OUTPUT_DIRECTORY_${upper} "${directory}")
|
|
134
|
+
endforeach()
|
|
135
|
+
endfunction()
|
|
136
|
+
|
|
137
|
+
# ── The executable ──────────────────────────────────────────────────────────
|
|
138
|
+
|
|
139
|
+
configure_file(native/src/Version.h.in "${CMAKE_BINARY_DIR}/generated/Version.h" @ONLY)
|
|
140
|
+
|
|
141
|
+
add_executable(soundor-vst3-host
|
|
142
|
+
native/src/Bundle.cpp
|
|
143
|
+
native/src/HostContext.cpp
|
|
144
|
+
native/src/HostInterface.cpp
|
|
145
|
+
native/src/HostWindow.cpp
|
|
146
|
+
native/src/Ipc.cpp
|
|
147
|
+
native/src/Json.cpp
|
|
148
|
+
native/src/LiveAudio.cpp
|
|
149
|
+
native/src/Main.cpp
|
|
150
|
+
native/src/Plugin.cpp
|
|
151
|
+
native/src/Session.cpp
|
|
152
|
+
native/src/Settings.cpp
|
|
153
|
+
"${SOUNDOR_VST3_HOST_FONTS_SOURCE}")
|
|
154
|
+
if(WIN32)
|
|
155
|
+
target_sources(soundor-vst3-host PRIVATE native/src/EventLoopWindows.cpp native/src/EditorWindowWindows.cpp
|
|
156
|
+
native/src/EditorAreaWindows.cpp)
|
|
157
|
+
target_link_libraries(soundor-vst3-host PRIVATE user32 gdi32)
|
|
158
|
+
elseif(APPLE)
|
|
159
|
+
target_sources(soundor-vst3-host PRIVATE native/src/EventLoopMac.mm native/src/EditorWindowMac.mm
|
|
160
|
+
native/src/EditorAreaMac.mm)
|
|
161
|
+
target_link_libraries(soundor-vst3-host PRIVATE "-framework Cocoa")
|
|
162
|
+
else()
|
|
163
|
+
# Xlib's headers only: the library is loaded in UI mode (X11Library.cpp).
|
|
164
|
+
find_path(SOUNDOR_X11_INCLUDE_DIR X11/Xlib.h REQUIRED)
|
|
165
|
+
target_include_directories(soundor-vst3-host SYSTEM PRIVATE "${SOUNDOR_X11_INCLUDE_DIR}")
|
|
166
|
+
target_sources(soundor-vst3-host PRIVATE native/src/EventLoopLinux.cpp native/src/EditorAreaX11.cpp
|
|
167
|
+
native/src/X11Library.cpp)
|
|
168
|
+
# The C++ runtime inside the executable, in every build: it runs on
|
|
169
|
+
# distributions with an older libstdc++ than the build machine's. A failed
|
|
170
|
+
# check is not kept, so installing the library is enough.
|
|
171
|
+
include(CheckCXXSourceCompiles)
|
|
172
|
+
set(CMAKE_REQUIRED_LINK_OPTIONS -static-libstdc++ -static-libgcc)
|
|
173
|
+
check_cxx_source_compiles("#include <string>
|
|
174
|
+
int main(int argc, char** argv) { return static_cast<int>(std::string(argv[0]).size()) + argc; }" SOUNDOR_VST3_HOST_STATIC_CXX_RUNTIME)
|
|
175
|
+
unset(CMAKE_REQUIRED_LINK_OPTIONS)
|
|
176
|
+
if(NOT SOUNDOR_VST3_HOST_STATIC_CXX_RUNTIME)
|
|
177
|
+
unset(SOUNDOR_VST3_HOST_STATIC_CXX_RUNTIME CACHE)
|
|
178
|
+
message(FATAL_ERROR "Linux builds link the C++ runtime statically, and libstdc++.a wasn't found.\n"
|
|
179
|
+
"Fedora, RHEL: sudo dnf install libstdc++-static\n"
|
|
180
|
+
"Elsewhere: the package with your compiler's static C++ library.")
|
|
181
|
+
endif()
|
|
182
|
+
target_link_options(soundor-vst3-host PRIVATE -static-libstdc++ -static-libgcc)
|
|
183
|
+
endif()
|
|
184
|
+
target_include_directories(soundor-vst3-host PRIVATE native/src "${CMAKE_BINARY_DIR}/generated")
|
|
185
|
+
target_link_libraries(soundor-vst3-host PRIVATE soundor_vst3_sdk_hosting soundor_imgui SDL3::SDL3-static)
|
|
186
|
+
# A large generated array: nothing to lint.
|
|
187
|
+
set_source_files_properties("${SOUNDOR_VST3_HOST_FONTS_SOURCE}" PROPERTIES SKIP_LINTING ON)
|
|
188
|
+
soundor_vst3_host_warnings(soundor-vst3-host)
|
|
189
|
+
soundor_vst3_host_output(soundor-vst3-host RUNTIME "${CMAKE_BINARY_DIR}/bin")
|
|
190
|
+
|
|
191
|
+
if(SOUNDOR_VST3_HOST_BUILD_TESTS)
|
|
192
|
+
enable_testing()
|
|
193
|
+
add_subdirectory(native/tests)
|
|
194
|
+
endif()
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 6,
|
|
3
|
+
"cmakeMinimumRequired": {
|
|
4
|
+
"major": 3,
|
|
5
|
+
"minor": 25,
|
|
6
|
+
"patch": 0
|
|
7
|
+
},
|
|
8
|
+
"configurePresets": [
|
|
9
|
+
{
|
|
10
|
+
"name": "dev",
|
|
11
|
+
"displayName": "Debug build with the self-test and fixture plugins",
|
|
12
|
+
"binaryDir": "${sourceDir}/build/dev",
|
|
13
|
+
"cacheVariables": {
|
|
14
|
+
"CMAKE_BUILD_TYPE": "Debug",
|
|
15
|
+
"SOUNDOR_VST3_HOST_BUILD_TESTS": "ON",
|
|
16
|
+
"SOUNDOR_VST3_HOST_WARNINGS_AS_ERRORS": "ON"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "release",
|
|
21
|
+
"displayName": "The shipped configuration, with the fixtures for its tests",
|
|
22
|
+
"binaryDir": "${sourceDir}/build/release",
|
|
23
|
+
"cacheVariables": {
|
|
24
|
+
"CMAKE_BUILD_TYPE": "Release",
|
|
25
|
+
"SOUNDOR_VST3_HOST_BUILD_TESTS": "ON",
|
|
26
|
+
"SOUNDOR_VST3_HOST_WARNINGS_AS_ERRORS": "ON"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "sanitize",
|
|
31
|
+
"inherits": "dev",
|
|
32
|
+
"displayName": "Debug build with ASan + UBSan",
|
|
33
|
+
"binaryDir": "${sourceDir}/build/sanitize",
|
|
34
|
+
"cacheVariables": {
|
|
35
|
+
"SOUNDOR_VST3_HOST_SANITIZERS": "ON"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "tidy",
|
|
40
|
+
"inherits": "dev",
|
|
41
|
+
"displayName": "Debug build checked by clang-tidy",
|
|
42
|
+
"binaryDir": "${sourceDir}/build/tidy",
|
|
43
|
+
"cacheVariables": {
|
|
44
|
+
"SOUNDOR_VST3_HOST_CLANG_TIDY": "ON"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"buildPresets": [
|
|
49
|
+
{ "name": "dev", "configurePreset": "dev", "configuration": "Debug" },
|
|
50
|
+
{
|
|
51
|
+
"name": "release",
|
|
52
|
+
"configurePreset": "release",
|
|
53
|
+
"configuration": "Release"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "sanitize",
|
|
57
|
+
"configurePreset": "sanitize",
|
|
58
|
+
"configuration": "Debug"
|
|
59
|
+
},
|
|
60
|
+
{ "name": "tidy", "configurePreset": "tidy", "configuration": "Debug" }
|
|
61
|
+
],
|
|
62
|
+
"testPresets": [
|
|
63
|
+
{
|
|
64
|
+
"name": "dev",
|
|
65
|
+
"configurePreset": "dev",
|
|
66
|
+
"configuration": "Debug",
|
|
67
|
+
"output": { "outputOnFailure": true }
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"name": "release",
|
|
71
|
+
"configurePreset": "release",
|
|
72
|
+
"configuration": "Release",
|
|
73
|
+
"output": { "outputOnFailure": true }
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "sanitize",
|
|
77
|
+
"configurePreset": "sanitize",
|
|
78
|
+
"configuration": "Debug",
|
|
79
|
+
"output": { "outputOnFailure": true }
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"workflowPresets": [
|
|
83
|
+
{
|
|
84
|
+
"name": "dev",
|
|
85
|
+
"steps": [
|
|
86
|
+
{ "type": "configure", "name": "dev" },
|
|
87
|
+
{ "type": "build", "name": "dev" },
|
|
88
|
+
{ "type": "test", "name": "dev" }
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "release",
|
|
93
|
+
"steps": [
|
|
94
|
+
{ "type": "configure", "name": "release" },
|
|
95
|
+
{ "type": "build", "name": "release" },
|
|
96
|
+
{ "type": "test", "name": "release" }
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "sanitize",
|
|
101
|
+
"steps": [
|
|
102
|
+
{ "type": "configure", "name": "sanitize" },
|
|
103
|
+
{ "type": "build", "name": "sanitize" },
|
|
104
|
+
{ "type": "test", "name": "sanitize" }
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"name": "tidy",
|
|
109
|
+
"steps": [
|
|
110
|
+
{ "type": "configure", "name": "tidy" },
|
|
111
|
+
{ "type": "build", "name": "tidy" }
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Dmitrii Balakin and Egor Smirnov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/NOTICE.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Notices
|
|
2
|
+
|
|
3
|
+
`@soundor/vst3-host` is MIT-licensed (LICENSE). Its executable is built with
|
|
4
|
+
the following third-party code, under its own license:
|
|
5
|
+
|
|
6
|
+
| Component | Version | License | Notice |
|
|
7
|
+
| -------------------------------------------------------------------------------------------------- | -------------- | ------- | ------------------------------------------------------- |
|
|
8
|
+
| [VST3 SDK](https://github.com/steinbergmedia/vst3sdk) (pluginterfaces, public.sdk hosting helpers) | 3.8.1 build 84 | MIT | `licenses/vst3sdk/LICENSE.txt` in each platform package |
|
|
9
|
+
|
|
10
|
+
| [SDL](https://github.com/libsdl-org/SDL) | 3.4.18 | Zlib | `licenses/sdl/LICENSE.txt` in each platform package |
|
|
11
|
+
| [Dear ImGui](https://github.com/ocornut/imgui) | 1.92.9b | MIT | `licenses/imgui/LICENSE.txt` in each platform package |
|
|
12
|
+
| [Inter](https://github.com/rsms/inter) (font) | 4.1 | OFL-1.1 | `licenses/inter/LICENSE.txt` in each platform package |
|
|
13
|
+
|
|
14
|
+
VST is a registered trademark of Steinberg Media Technologies GmbH.
|
|
15
|
+
|
|
16
|
+
The test fixtures (`native/tests/fixtures`) additionally use the SDK's `base`
|
|
17
|
+
library (MIT); they are never shipped as binaries.
|
package/README.md
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @soundor/vst3-host
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A standalone VST3 host for tests and development: a native executable driven
|
|
4
|
+
from Node.js. It loads a `.vst3` bundle by path, processes audio offline
|
|
5
|
+
(parameters, MIDI, transport, state), and opens the plugin's editor in a
|
|
6
|
+
native window when asked. Any VST3 plugin, made with Soundor or not.
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
pnpm add -D @soundor/vst3-host
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { launchHost } from '@soundor/vst3-host';
|
|
14
|
+
|
|
15
|
+
const host = await launchHost({
|
|
16
|
+
plugin: 'build/MyPlugin.vst3',
|
|
17
|
+
sampleRate: 48_000,
|
|
18
|
+
blockSize: 512,
|
|
19
|
+
});
|
|
20
|
+
try {
|
|
21
|
+
const [first] = await host.getParameters();
|
|
22
|
+
await host.setParameter(first!.id, 0.5);
|
|
23
|
+
const input = new Float32Array(48_000);
|
|
24
|
+
const { outputs } = await host.process({ inputs: [[input, input]] });
|
|
25
|
+
} finally {
|
|
26
|
+
await host.close();
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The executable comes in a platform package installed with this one, at the
|
|
31
|
+
same version: Linux x64 (glibc), macOS (arm64 and x64) and Windows x64.
|
|
32
|
+
Installing compiles and downloads nothing else.
|
|
33
|
+
|
|
34
|
+
Documentation: [user guide](https://soundor.dev/docs/testing/vst3-host) and
|
|
35
|
+
[internals](https://soundor.dev/docs/contribute/vst3-host) (building from
|
|
36
|
+
source, prebuilt selection, releases).
|
|
37
|
+
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
MIT (LICENSE). The executable includes the VST3 SDK, under its own MIT license
|
|
41
|
+
(NOTICE.md). VST is a registered trademark of Steinberg Media Technologies GmbH.
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# The host's third-party dependencies.
|
|
2
|
+
#
|
|
3
|
+
# Each is fetched at configure time from an exact upstream commit or release,
|
|
4
|
+
# verified by SHA-256, and compiled into a private static target. The archives
|
|
5
|
+
# are kept in the user cache (SOUNDOR_CACHE, else ~/.cache/soundor,
|
|
6
|
+
# ~/Library/Caches/Soundor or %LOCALAPPDATA%\Soundor\cache), so a new build
|
|
7
|
+
# directory does not download them again.
|
|
8
|
+
#
|
|
9
|
+
# | Dependency | Version | License | Used for |
|
|
10
|
+
# | ---------------------------- | --------------- | -------- | --------------------------------- |
|
|
11
|
+
# | VST3 SDK pluginterfaces | 3.8.1 build 84 | MIT | VST3 interfaces (host, fixtures) |
|
|
12
|
+
# | VST3 SDK public.sdk | 3.8.1 build 84 | MIT | hosting helpers (host), plugin base classes (fixtures) |
|
|
13
|
+
# | VST3 SDK base | 3.8.1 build 84 | MIT | plugin base classes (fixtures only) |
|
|
14
|
+
# | SDL | 3.4.18 | zlib | the host window, live audio, file dialogs |
|
|
15
|
+
# | Dear ImGui | 1.92.9b | MIT | the host interface |
|
|
16
|
+
# | Inter | 4.1 | OFL-1.1 | the host interface's font |
|
|
17
|
+
#
|
|
18
|
+
# SDL is the one built by its own CMake project (as a static library, with only
|
|
19
|
+
# the subsystems the host uses): its platform configuration is not worth
|
|
20
|
+
# reproducing. ImGui and Inter are compiled and embedded by the host's CMake.
|
|
21
|
+
#
|
|
22
|
+
# The tag v3.8.1_build_84 of each repository: VST3 SDK 3.8 is the first
|
|
23
|
+
# release under the MIT license. Offline: -DFETCHCONTENT_SOURCE_DIR_SOUNDOR_VST3_<PART>=<checkout>.
|
|
24
|
+
|
|
25
|
+
include_guard(GLOBAL)
|
|
26
|
+
include(FetchContent)
|
|
27
|
+
|
|
28
|
+
set(SOUNDOR_VST3_SDK_VERSION "3.8.1")
|
|
29
|
+
set(SOUNDOR_VST3_PLUGINTERFACES_REVISION "4f547e8e102b47de4a8b8aaf343c73b700786372")
|
|
30
|
+
set(SOUNDOR_VST3_PLUGINTERFACES_SHA256 "ee70777eebb8450fc04fae2a6dd452f723d12bfb8222af443b8c1f8a9259089a")
|
|
31
|
+
set(SOUNDOR_VST3_PUBLIC_SDK_REVISION "586dc5e6c8012c3e4b01c79389375cbe96bdb1da")
|
|
32
|
+
set(SOUNDOR_VST3_PUBLIC_SDK_SHA256 "71319491b771068b8e2c5374c22830a339677e9d54c4cd33af4a0aa210e4c838")
|
|
33
|
+
set(SOUNDOR_VST3_BASE_REVISION "fcf9da0bd27a16f7f03773a3a39822f28f5c8477")
|
|
34
|
+
set(SOUNDOR_VST3_BASE_SHA256 "3753d45a79b5e324c2843d74a18c8f1117fe0b1118fa9312658aecf6360ec603")
|
|
35
|
+
|
|
36
|
+
function(soundor_vst3_host_cache_root out)
|
|
37
|
+
if(DEFINED ENV{SOUNDOR_CACHE} AND NOT "$ENV{SOUNDOR_CACHE}" STREQUAL "")
|
|
38
|
+
set(root "$ENV{SOUNDOR_CACHE}")
|
|
39
|
+
elseif(WIN32)
|
|
40
|
+
set(root "$ENV{LOCALAPPDATA}/Soundor/cache")
|
|
41
|
+
elseif(APPLE)
|
|
42
|
+
set(root "$ENV{HOME}/Library/Caches/Soundor")
|
|
43
|
+
elseif(DEFINED ENV{XDG_CACHE_HOME} AND NOT "$ENV{XDG_CACHE_HOME}" STREQUAL "")
|
|
44
|
+
set(root "$ENV{XDG_CACHE_HOME}/soundor")
|
|
45
|
+
else()
|
|
46
|
+
set(root "$ENV{HOME}/.cache/soundor")
|
|
47
|
+
endif()
|
|
48
|
+
file(TO_CMAKE_PATH "${root}" root)
|
|
49
|
+
set(${out} "${root}" PARENT_SCOPE)
|
|
50
|
+
endfunction()
|
|
51
|
+
|
|
52
|
+
# The SDK's sources include each other as "pluginterfaces/...",
|
|
53
|
+
# "public.sdk/source/..." and "base/source/...": the parts are laid out
|
|
54
|
+
# side by side under one root, as the SDK's umbrella repository does.
|
|
55
|
+
set(SOUNDOR_VST3_SDK_DIR "${CMAKE_BINARY_DIR}/_deps/vst3sdk")
|
|
56
|
+
soundor_vst3_host_cache_root(soundor_cache)
|
|
57
|
+
set(soundor_downloads "${soundor_cache}/vst3-host/downloads")
|
|
58
|
+
|
|
59
|
+
function(soundor_vst3_sdk_part name repository directory revision sha256)
|
|
60
|
+
FetchContent_Declare(
|
|
61
|
+
${name}
|
|
62
|
+
URL "https://github.com/steinbergmedia/${repository}/archive/${revision}.tar.gz"
|
|
63
|
+
URL_HASH "SHA256=${sha256}"
|
|
64
|
+
DOWNLOAD_NAME "${repository}-${revision}.tar.gz"
|
|
65
|
+
DOWNLOAD_DIR "${soundor_downloads}"
|
|
66
|
+
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
|
67
|
+
SOURCE_DIR "${SOUNDOR_VST3_SDK_DIR}/${directory}"
|
|
68
|
+
# Populate only: the host defines its own SDK targets.
|
|
69
|
+
SOURCE_SUBDIR "soundor-populate-only")
|
|
70
|
+
FetchContent_MakeAvailable(${name})
|
|
71
|
+
endfunction()
|
|
72
|
+
|
|
73
|
+
soundor_vst3_sdk_part(soundor_vst3_pluginterfaces vst3_pluginterfaces pluginterfaces
|
|
74
|
+
${SOUNDOR_VST3_PLUGINTERFACES_REVISION} ${SOUNDOR_VST3_PLUGINTERFACES_SHA256})
|
|
75
|
+
soundor_vst3_sdk_part(soundor_vst3_public_sdk vst3_public_sdk public.sdk
|
|
76
|
+
${SOUNDOR_VST3_PUBLIC_SDK_REVISION} ${SOUNDOR_VST3_PUBLIC_SDK_SHA256})
|
|
77
|
+
if(SOUNDOR_VST3_HOST_BUILD_TESTS)
|
|
78
|
+
soundor_vst3_sdk_part(soundor_vst3_base vst3_base base
|
|
79
|
+
${SOUNDOR_VST3_BASE_REVISION} ${SOUNDOR_VST3_BASE_SHA256})
|
|
80
|
+
endif()
|
|
81
|
+
|
|
82
|
+
# The notice every distributed host executable carries.
|
|
83
|
+
configure_file("${SOUNDOR_VST3_SDK_DIR}/pluginterfaces/LICENSE.txt"
|
|
84
|
+
"${CMAKE_BINARY_DIR}/licenses/vst3sdk/LICENSE.txt" COPYONLY)
|
|
85
|
+
|
|
86
|
+
# ── The host interface: SDL, Dear ImGui, Inter ──────────────────────────────
|
|
87
|
+
|
|
88
|
+
set(SOUNDOR_SDL_VERSION "3.4.18")
|
|
89
|
+
set(SOUNDOR_SDL_SHA256 "9c75cf16330322c217dedd2e0609f1124f1b54b8633e763467b4684d0f4334a3")
|
|
90
|
+
set(SOUNDOR_IMGUI_VERSION "1.92.9b")
|
|
91
|
+
set(SOUNDOR_IMGUI_SHA256 "21d8a0a565e85dce943e375db00812c2f3f0ab21f3f0f7964e364a63422d7f99")
|
|
92
|
+
set(SOUNDOR_INTER_VERSION "4.1")
|
|
93
|
+
set(SOUNDOR_INTER_SHA256 "9883fdd4a49d4fb66bd8177ba6625ef9a64aa45899767dde3d36aa425756b11e")
|
|
94
|
+
|
|
95
|
+
function(soundor_vst3_host_archive name url sha256 download_name out)
|
|
96
|
+
FetchContent_Declare(
|
|
97
|
+
${name}
|
|
98
|
+
URL "${url}"
|
|
99
|
+
URL_HASH "SHA256=${sha256}"
|
|
100
|
+
DOWNLOAD_NAME "${download_name}"
|
|
101
|
+
DOWNLOAD_DIR "${soundor_downloads}"
|
|
102
|
+
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
|
103
|
+
# Populate only: SDL is configured below; the other targets are ours.
|
|
104
|
+
SOURCE_SUBDIR "soundor-populate-only")
|
|
105
|
+
FetchContent_MakeAvailable(${name})
|
|
106
|
+
set(${out} "${${name}_SOURCE_DIR}" PARENT_SCOPE)
|
|
107
|
+
endfunction()
|
|
108
|
+
|
|
109
|
+
soundor_vst3_host_archive(soundor_sdl
|
|
110
|
+
"https://github.com/libsdl-org/SDL/releases/download/release-${SOUNDOR_SDL_VERSION}/SDL3-${SOUNDOR_SDL_VERSION}.tar.gz"
|
|
111
|
+
${SOUNDOR_SDL_SHA256} "SDL3-${SOUNDOR_SDL_VERSION}.tar.gz" SOUNDOR_SDL_DIR)
|
|
112
|
+
soundor_vst3_host_archive(soundor_imgui
|
|
113
|
+
"https://github.com/ocornut/imgui/archive/refs/tags/v${SOUNDOR_IMGUI_VERSION}.tar.gz"
|
|
114
|
+
${SOUNDOR_IMGUI_SHA256} "imgui-${SOUNDOR_IMGUI_VERSION}.tar.gz" SOUNDOR_IMGUI_DIR)
|
|
115
|
+
soundor_vst3_host_archive(soundor_inter
|
|
116
|
+
"https://github.com/rsms/inter/releases/download/v${SOUNDOR_INTER_VERSION}/Inter-${SOUNDOR_INTER_VERSION}.zip"
|
|
117
|
+
${SOUNDOR_INTER_SHA256} "Inter-${SOUNDOR_INTER_VERSION}.zip" SOUNDOR_INTER_DIR)
|
|
118
|
+
|
|
119
|
+
# SDL: a static library with the subsystems the host interface uses (video,
|
|
120
|
+
# rendering, events, audio, dialogs). On Linux, X11 only (VST3 editors are
|
|
121
|
+
# X11 windows), and every system library is loaded at run time, so headless
|
|
122
|
+
# mode needs none of them.
|
|
123
|
+
function(soundor_vst3_host_sdl)
|
|
124
|
+
set(BUILD_SHARED_LIBS OFF)
|
|
125
|
+
set(CMAKE_C_CLANG_TIDY "")
|
|
126
|
+
set(CMAKE_CXX_CLANG_TIDY "")
|
|
127
|
+
foreach(option IN ITEMS SDL_STATIC SDL_AUDIO SDL_VIDEO SDL_RENDER SDL_DEPS_SHARED SDL_DISABLE_INSTALL
|
|
128
|
+
SDL_X11_XSYNC)
|
|
129
|
+
set(${option} ON CACHE BOOL "" FORCE)
|
|
130
|
+
endforeach()
|
|
131
|
+
foreach(option IN ITEMS SDL_SHARED SDL_TEST_LIBRARY SDL_TESTS SDL_EXAMPLES SDL_INSTALL SDL_GPU SDL_CAMERA
|
|
132
|
+
SDL_HAPTIC SDL_HIDAPI SDL_POWER SDL_SENSOR SDL_TRAY SDL_VULKAN SDL_RENDER_VULKAN
|
|
133
|
+
SDL_RENDER_GPU SDL_WAYLAND SDL_KMSDRM SDL_OFFSCREEN SDL_DUMMYCAMERA SDL_LIBUDEV
|
|
134
|
+
SDL_IBUS SDL_JACK SDL_SNDIO SDL_OSS SDL_DISKAUDIO SDL_OPENVR SDL_RPI SDL_ROCKCHIP
|
|
135
|
+
SDL_VIVANTE SDL_LIBURING SDL_FRIBIDI SDL_LIBTHAI SDL_CLANG_TIDY SDL_RPATH
|
|
136
|
+
SDL_X11_XSCRNSAVER SDL_X11_XSHAPE SDL_X11_XDBE SDL_X11_XTEST)
|
|
137
|
+
set(${option} OFF CACHE BOOL "" FORCE)
|
|
138
|
+
endforeach()
|
|
139
|
+
add_subdirectory("${SOUNDOR_SDL_DIR}" "${CMAKE_BINARY_DIR}/_deps/sdl-build" EXCLUDE_FROM_ALL SYSTEM)
|
|
140
|
+
endfunction()
|
|
141
|
+
soundor_vst3_host_sdl()
|
|
142
|
+
|
|
143
|
+
add_library(soundor_imgui STATIC
|
|
144
|
+
"${SOUNDOR_IMGUI_DIR}/imgui.cpp"
|
|
145
|
+
"${SOUNDOR_IMGUI_DIR}/imgui_draw.cpp"
|
|
146
|
+
"${SOUNDOR_IMGUI_DIR}/imgui_tables.cpp"
|
|
147
|
+
"${SOUNDOR_IMGUI_DIR}/imgui_widgets.cpp"
|
|
148
|
+
"${SOUNDOR_IMGUI_DIR}/backends/imgui_impl_sdl3.cpp"
|
|
149
|
+
"${SOUNDOR_IMGUI_DIR}/backends/imgui_impl_sdlrenderer3.cpp")
|
|
150
|
+
target_include_directories(soundor_imgui SYSTEM PUBLIC "${SOUNDOR_IMGUI_DIR}" "${SOUNDOR_IMGUI_DIR}/backends")
|
|
151
|
+
# No demo window, no default font file, no shell or clipboard helpers the
|
|
152
|
+
# host does not use.
|
|
153
|
+
target_compile_definitions(soundor_imgui PUBLIC IMGUI_DISABLE_DEMO_WINDOWS IMGUI_DISABLE_DEBUG_TOOLS
|
|
154
|
+
IMGUI_DISABLE_OBSOLETE_FUNCTIONS)
|
|
155
|
+
target_link_libraries(soundor_imgui PUBLIC SDL3::SDL3-static)
|
|
156
|
+
if(MSVC)
|
|
157
|
+
target_compile_options(soundor_imgui PRIVATE /W0)
|
|
158
|
+
else()
|
|
159
|
+
target_compile_options(soundor_imgui PRIVATE -w)
|
|
160
|
+
endif()
|
|
161
|
+
|
|
162
|
+
# Inter's regular and semibold faces, embedded as byte arrays by a small
|
|
163
|
+
# build-time tool (CMake's string functions are too slow for fonts).
|
|
164
|
+
add_executable(soundor_vst3_host_embed "${CMAKE_CURRENT_LIST_DIR}/../native/tools/Embed.cpp")
|
|
165
|
+
set(SOUNDOR_VST3_HOST_FONTS_SOURCE "${CMAKE_BINARY_DIR}/generated/HostFonts.cpp")
|
|
166
|
+
add_custom_command(
|
|
167
|
+
OUTPUT "${SOUNDOR_VST3_HOST_FONTS_SOURCE}"
|
|
168
|
+
COMMAND soundor_vst3_host_embed "${SOUNDOR_VST3_HOST_FONTS_SOURCE}" soundor::vst3host::fonts
|
|
169
|
+
regular "${SOUNDOR_INTER_DIR}/extras/ttf/Inter-Regular.ttf"
|
|
170
|
+
semibold "${SOUNDOR_INTER_DIR}/extras/ttf/Inter-SemiBold.ttf"
|
|
171
|
+
DEPENDS soundor_vst3_host_embed
|
|
172
|
+
"${SOUNDOR_INTER_DIR}/extras/ttf/Inter-Regular.ttf"
|
|
173
|
+
"${SOUNDOR_INTER_DIR}/extras/ttf/Inter-SemiBold.ttf"
|
|
174
|
+
COMMENT "Embedding the host interface's fonts"
|
|
175
|
+
VERBATIM)
|
|
176
|
+
|
|
177
|
+
configure_file("${SOUNDOR_SDL_DIR}/LICENSE.txt" "${CMAKE_BINARY_DIR}/licenses/sdl/LICENSE.txt" COPYONLY)
|
|
178
|
+
configure_file("${SOUNDOR_IMGUI_DIR}/LICENSE.txt" "${CMAKE_BINARY_DIR}/licenses/imgui/LICENSE.txt" COPYONLY)
|
|
179
|
+
configure_file("${SOUNDOR_INTER_DIR}/LICENSE.txt" "${CMAKE_BINARY_DIR}/licenses/inter/LICENSE.txt" COPYONLY)
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { a as nativeInputs, i as resolveHost, l as Vst3HostError, r as launchHost, t as prepareHost } from "./prepare-ayjTVhfk.mjs";
|
|
3
|
+
import { parseArgs } from "node:util";
|
|
4
|
+
// src/cli.ts
|
|
5
|
+
const { positionals, values } = parseArgs({
|
|
6
|
+
allowPositionals: true,
|
|
7
|
+
options: {
|
|
8
|
+
mode: { type: "string" },
|
|
9
|
+
artifact: { type: "string" },
|
|
10
|
+
commit: { type: "string" },
|
|
11
|
+
class: { type: "string" },
|
|
12
|
+
bare: { type: "boolean" },
|
|
13
|
+
interface: { type: "boolean" },
|
|
14
|
+
"sample-rate": { type: "string" },
|
|
15
|
+
"block-size": { type: "string" }
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
const USAGE = `usage: soundor-vst3-host <command>
|
|
19
|
+
open <plugin.vst3> [--class <name>] [--bare | --interface] [--sample-rate <hz>] [--block-size <frames>]
|
|
20
|
+
prepare [--mode prebuilt|published|source] [--artifact <dir>] [--commit <sha>]
|
|
21
|
+
resolve
|
|
22
|
+
inputs`;
|
|
23
|
+
/** Opens a plugin's editor and waits until its window is closed. */
|
|
24
|
+
async function open() {
|
|
25
|
+
const plugin = positionals[1];
|
|
26
|
+
if (plugin === void 0) throw new Error("open needs a .vst3 bundle");
|
|
27
|
+
if (values.bare && values.interface) throw new Error("--bare and --interface are opposites");
|
|
28
|
+
const number = (name) => {
|
|
29
|
+
const text = values[name];
|
|
30
|
+
if (text === void 0) return void 0;
|
|
31
|
+
const value = Number(text);
|
|
32
|
+
if (!Number.isFinite(value)) throw new Error(`--${name} is a number`);
|
|
33
|
+
return value;
|
|
34
|
+
};
|
|
35
|
+
const host = await launchHost({
|
|
36
|
+
plugin,
|
|
37
|
+
className: values.class,
|
|
38
|
+
editor: true,
|
|
39
|
+
presentation: values.bare ? "editor" : values.interface ? "host" : null,
|
|
40
|
+
sampleRate: number("sample-rate"),
|
|
41
|
+
blockSize: number("block-size"),
|
|
42
|
+
requestTimeout: 2147483647,
|
|
43
|
+
onLog: (line) => console.error(line)
|
|
44
|
+
});
|
|
45
|
+
const closed = new Promise((resolve) => {
|
|
46
|
+
host.once("editorClosed", () => resolve());
|
|
47
|
+
host.once("exit", () => resolve());
|
|
48
|
+
process.once("SIGINT", () => resolve());
|
|
49
|
+
process.once("SIGTERM", () => resolve());
|
|
50
|
+
});
|
|
51
|
+
console.error(`${host.info.name}: close its window (or press Ctrl+C) to quit`);
|
|
52
|
+
await closed;
|
|
53
|
+
await host.close();
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
switch (positionals[0]) {
|
|
57
|
+
case "open":
|
|
58
|
+
await open();
|
|
59
|
+
break;
|
|
60
|
+
case "prepare": {
|
|
61
|
+
const mode = values.mode ?? "prebuilt";
|
|
62
|
+
if (mode !== "prebuilt" && mode !== "published" && mode !== "source") throw new Error(`--mode is "prebuilt", "published" or "source", not "${mode}"`);
|
|
63
|
+
await prepareHost({
|
|
64
|
+
mode,
|
|
65
|
+
artifact: values.artifact,
|
|
66
|
+
commit: values.commit
|
|
67
|
+
});
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
case "resolve": {
|
|
71
|
+
const resolved = resolveHost();
|
|
72
|
+
console.log(`${resolved.executable}\t(${resolved.source}: ${resolved.reason})`);
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case "inputs":
|
|
76
|
+
console.log(JSON.stringify(nativeInputs(), null, 2));
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
console.error(USAGE);
|
|
80
|
+
process.exitCode = 64;
|
|
81
|
+
}
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error(error instanceof Vst3HostError ? `error (${error.code}): ${error.message}` : `error: ${error.message}`);
|
|
84
|
+
process.exitCode = 1;
|
|
85
|
+
}
|
|
86
|
+
export {};
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=cli.mjs.map
|