Browse Source

Add some more vst3sdk files

Signed-off-by: falkTX <falktx@gmail.com>
tags/v2.1-alpha1-winvst
parent
commit
6fa44324dd
100 changed files with 23112 additions and 0 deletions
  1. +220
    -0
      source/includes/vst3sdk/CMakeLists.txt
  2. +41
    -0
      source/includes/vst3sdk/LICENSE.txt
  3. +92
    -0
      source/includes/vst3sdk/README.md
  4. +85
    -0
      source/includes/vst3sdk/public.sdk/CMakeLists.txt
  5. +27
    -0
      source/includes/vst3sdk/public.sdk/LICENSE.txt
  6. +319
    -0
      source/includes/vst3sdk/public.sdk/source/common/memorystream.cpp
  7. +80
    -0
      source/includes/vst3sdk/public.sdk/source/common/memorystream.h
  8. +117
    -0
      source/includes/vst3sdk/public.sdk/source/common/pluginview.cpp
  9. +102
    -0
      source/includes/vst3sdk/public.sdk/source/common/pluginview.h
  10. +105
    -0
      source/includes/vst3sdk/public.sdk/source/main/dllmain.cpp
  11. +80
    -0
      source/includes/vst3sdk/public.sdk/source/main/linuxmain.cpp
  12. +3
    -0
      source/includes/vst3sdk/public.sdk/source/main/macexport.exp
  13. +113
    -0
      source/includes/vst3sdk/public.sdk/source/main/macmain.cpp
  14. +278
    -0
      source/includes/vst3sdk/public.sdk/source/main/pluginfactoryvst3.cpp
  15. +175
    -0
      source/includes/vst3sdk/public.sdk/source/main/pluginfactoryvst3.h
  16. +4
    -0
      source/includes/vst3sdk/public.sdk/source/main/winexport.def
  17. +32
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/CMakeLists.txt
  18. +92
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/NSDataIBStream.h
  19. +206
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/NSDataIBStream.mm
  20. +41
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/CMakeLists.txt
  21. +117
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/Info.plist
  22. +61
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/audiounitconfig.h
  23. +51
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/config/again.xcconfig
  24. +38
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/config/again_debug.xcconfig
  25. +38
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/config/again_release.xcconfig
  26. +52
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/doc.cpp
  27. +83
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/aucarbonview.h
  28. +167
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/aucarbonview.mm
  29. +68
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/aucocoaview.h
  30. +232
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/aucocoaview.mm
  31. +85
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/auresource.r
  32. +84
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/ausdk.mm
  33. +340
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/auwrapper.h
  34. +2582
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/auwrapper.mm
  35. +38
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/auwrapper_prefix.pch
  36. +38
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/config/ausdkpath.xcconfig
  37. +44
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/config/auwrapper.xcconfig
  38. +40
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/config/auwrapper_debug.xcconfig
  39. +40
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/config/auwrapper_release.xcconfig
  40. +23
    -0
      source/includes/vst3sdk/public.sdk/source/vst/auwrapper/generateCocoaClassNamePrefix.rb
  41. +105
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/eventlist.cpp
  42. +73
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/eventlist.h
  43. +316
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/hostclasses.cpp
  44. +112
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/hostclasses.h
  45. +284
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/module.cpp
  46. +193
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/module.h
  47. +277
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/module_linux.cpp
  48. +299
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/module_mac.mm
  49. +192
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/module_win32.cpp
  50. +123
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/optional.h
  51. +323
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/parameterchanges.cpp
  52. +142
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/parameterchanges.h
  53. +320
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/plugprovider.cpp
  54. +96
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/plugprovider.h
  55. +223
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/processdata.cpp
  56. +199
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/processdata.h
  57. +148
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/stringconvert.cpp
  58. +132
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/stringconvert.h
  59. +292
    -0
      source/includes/vst3sdk/public.sdk/source/vst/hosting/uid.h
  60. +151
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/AudioIO.h
  61. +551
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/AudioIO.mm
  62. +29
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/CMakeLists.txt
  63. +93
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/HostApp.h
  64. +169
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/HostApp.mm
  65. +27
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/LaunchScreen.storyboard
  66. +92
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/MidiIO.h
  67. +223
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/MidiIO.mm
  68. +69
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetBrowserView.xib
  69. +59
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetBrowserViewController.h
  70. +272
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetBrowserViewController.mm
  71. +92
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetManager.h
  72. +281
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetManager.mm
  73. +67
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetSaveView.xib
  74. +54
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetSaveViewController.h
  75. +171
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetSaveViewController.mm
  76. +77
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/SettingsView.xib
  77. +49
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/SettingsViewController.h
  78. +144
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/SettingsViewController.mm
  79. +83
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/VST3Editor.h
  80. +129
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/VST3Editor.mm
  81. +144
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/VST3Plugin.h
  82. +607
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/VST3Plugin.mm
  83. +57
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/VSTInterAppAudioAppDelegateBase.h
  84. +210
    -0
      source/includes/vst3sdk/public.sdk/source/vst/interappaudio/VSTInterAppAudioAppDelegateBase.mm
  85. +2742
    -0
      source/includes/vst3sdk/public.sdk/source/vst/testsuite/vsttestsuite.cpp
  86. +720
    -0
      source/includes/vst3sdk/public.sdk/source/vst/testsuite/vsttestsuite.h
  87. +3105
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vst2wrapper/vst2wrapper.cpp
  88. +335
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vst2wrapper/vst2wrapper.h
  89. +47
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vst2wrapper/vst2wrapper.sdk.cpp
  90. +196
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vstaudioeffect.cpp
  91. +130
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vstaudioeffect.h
  92. +300
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vstaudioprocessoralgo.h
  93. +104
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vstbus.cpp
  94. +164
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vstbus.h
  95. +353
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vstbypassprocessor.cpp
  96. +118
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vstbypassprocessor.h
  97. +214
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vstcomponent.cpp
  98. +118
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vstcomponent.h
  99. +179
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vstcomponentbase.cpp
  100. +105
    -0
      source/includes/vst3sdk/public.sdk/source/vst/vstcomponentbase.h

+ 220
- 0
source/includes/vst3sdk/CMakeLists.txt View File

@@ -0,0 +1,220 @@

cmake_minimum_required (VERSION 3.4.3)

#-------------------------------------------------------------------------------
# Includes
#-------------------------------------------------------------------------------

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")

include(Global)
include(AddVST3Library)
include(Bundle)
include(ExportedSymbols)
include(PrefixHeader)
include(PlatformIOS)

# do not build VST2 by default
option(SMTG_CREATE_VST2_VERSION "Use VST2" OFF)

#-------------------------------------------------------------------------------
# SDK Project
#-------------------------------------------------------------------------------
set(VST_SDK TRUE)
project(vstsdk)

if (LINUX)
option(SMTG_ADD_ADDRESS_SANITIZER_CONFIG "Add AddressSanitizer Config (Linux only)" OFF)
if(SMTG_ADD_ADDRESS_SANITIZER_CONFIG)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES};ASan")
add_compile_options($<$<CONFIG:ASan>:-DDEVELOPMENT=1>)
add_compile_options($<$<CONFIG:ASan>:-fsanitize=address>)
add_compile_options($<$<CONFIG:ASan>:-DVSTGUI_LIVE_EDITING=1>)
add_compile_options($<$<CONFIG:ASan>:-g>)
add_compile_options($<$<CONFIG:ASan>:-O0>)
set(ASAN_LIBRARY asan)
link_libraries($<$<CONFIG:ASan>:${ASAN_LIBRARY}>)
endif()
endif()

if(UNIX)
if(XCODE)
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
elseif(APPLE)
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -stdlib=libc++")
link_libraries(c++)
else()
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wno-multichar")
link_libraries(stdc++fs pthread dl)
endif()

elseif(WIN)
add_definitions(-D_UNICODE)
add_compile_options(/fp:fast)
add_compile_options($<$<CONFIG:Release>:/Oi>) # Enable Intrinsic Functions (Yes)
add_compile_options($<$<CONFIG:Release>:/Ot>) # Favor Size Or Speed (Favor fast code)
#add_compile_options($<$<CONFIG:Release>:/Ox>) # Optimization (/O2: Maximise Speed /0x: Full Optimization)
add_compile_options($<$<CONFIG:Release>:/GF>) # Enable String Pooling
add_compile_options($<$<CONFIG:Release>:/EHa>) # Enable C++ Exceptions
add_compile_options($<$<CONFIG:Release>:/Oy>) # Omit Frame Pointers
endif()

set(ROOT "${CMAKE_CURRENT_SOURCE_DIR}")

# here you can define where the VST3 SDK is located
set(SDK_ROOT "${ROOT}")

# here you can define where the VSTGUI is located
set(VSTGUI_ROOT "${ROOT}")

include_directories(${ROOT} ${SDK_ROOT})

set(SDK_IDE_LIBS_FOLDER FOLDER "Libraries")
set(SDK_IDE_PLUGIN_EXAMPLES_FOLDER FOLDER "PlugInExamples")
set(SDK_IDE_HOSTING_EXAMPLES_FOLDER FOLDER "HostingExamples")

#-------------------------------------------------------------------------------
if(MAC AND XCODE)
if(NOT SMTG_COREAUDIO_SDK_PATH)
# Check if the CoreAudio SDK is next to the VST3SDK:
if(EXISTS "${SDK_ROOT}/../CoreAudio/AudioUnits/AUPublic/AUBase/AUBase.cpp")
set(SMTG_COREAUDIO_SDK_PATH "${SDK_ROOT}/../CoreAudio")
else()
if(EXISTS "${SDK_ROOT}/external.apple.coreaudio/AudioUnits/AUPublic/AUBase/AUBase.cpp")
set(SMTG_COREAUDIO_SDK_PATH "${SDK_ROOT}/external.apple.coreaudio")
endif()
endif()
else()
if(NOT IS_ABSOLUTE ${SMTG_COREAUDIO_SDK_PATH})
get_filename_component(SMTG_COREAUDIO_SDK_PATH "${SDK_ROOT}/${SMTG_COREAUDIO_SDK_PATH}" ABSOLUTE)
endif()
if(NOT EXISTS "${SMTG_COREAUDIO_SDK_PATH}/AudioUnits/AUPublic/AUBase/AUBase.cpp")
message(FATAL_ERROR "SMTG_COREAUDIO_SDK_PATH is set but does not point to an expected location")
endif()
endif()
if(SMTG_COREAUDIO_SDK_PATH)
message(STATUS "SMTG_COREAUDIO_SDK_PATH is set to : " ${SMTG_COREAUDIO_SDK_PATH})
endif()
endif()

#-------------------------------------------------------------------------------
# Projects
#-------------------------------------------------------------------------------

add_subdirectory(base)
add_subdirectory(public.sdk)
add_subdirectory(public.sdk/source/vst/auwrapper)
add_subdirectory(public.sdk/source/vst/auwrapper/again)
add_subdirectory(public.sdk/source/vst/interappaudio)
add_subdirectory(public.sdk/samples/vst/again)
add_subdirectory(public.sdk/samples/vst/adelay)
add_subdirectory(public.sdk/samples/vst/channelcontext)
add_subdirectory(public.sdk/samples/vst/hostchecker)
add_subdirectory(public.sdk/samples/vst/editorhost)
add_subdirectory(public.sdk/samples/vst/mda-vst3)
add_subdirectory(public.sdk/samples/vst/note_expression_synth)
add_subdirectory(public.sdk/samples/vst/note_expression_text)
add_subdirectory(public.sdk/samples/vst/pitchnames)
add_subdirectory(public.sdk/samples/vst/prefetchablesupport)
add_subdirectory(public.sdk/samples/vst/programchange)
add_subdirectory(public.sdk/samples/vst/validator)
add_subdirectory(public.sdk/samples/vst/InterAppAudio)

set(VSTGUI_DISABLE_UNITTESTS 1)
add_subdirectory(vstgui4/vstgui)

#-------------------------------------------------------------------------------
# VSTGUI Support Library
#-------------------------------------------------------------------------------
add_compile_options($<$<CONFIG:Debug>:-DVSTGUI_LIVE_EDITING=1>)
set(VST3_VSTGUI_SOURCES
${VSTGUI_ROOT}/vstgui4/vstgui/plugin-bindings/vst3groupcontroller.cpp
${VSTGUI_ROOT}/vstgui4/vstgui/plugin-bindings/vst3groupcontroller.h
${VSTGUI_ROOT}/vstgui4/vstgui/plugin-bindings/vst3padcontroller.cpp
${VSTGUI_ROOT}/vstgui4/vstgui/plugin-bindings/vst3padcontroller.h
${VSTGUI_ROOT}/vstgui4/vstgui/plugin-bindings/vst3editor.cpp
${VSTGUI_ROOT}/vstgui4/vstgui/plugin-bindings/vst3editor.h
${SDK_ROOT}/public.sdk/source/vst/vstguieditor.cpp
)
add_library(vstgui_support STATIC ${VST3_VSTGUI_SOURCES})
target_include_directories(vstgui_support PUBLIC ${VSTGUI_ROOT}/vstgui4)
target_link_libraries(vstgui_support PRIVATE vstgui_uidescription)
if(MAC)
if(XCODE)
target_link_libraries(vstgui_support PRIVATE "-framework Cocoa" "-framework OpenGL" "-framework Accelerate" "-framework QuartzCore" "-framework Carbon")
else()
find_library(COREFOUNDATION_FRAMEWORK CoreFoundation)
find_library(COCOA_FRAMEWORK Cocoa)
find_library(OPENGL_FRAMEWORK OpenGL)
find_library(ACCELERATE_FRAMEWORK Accelerate)
find_library(QUARTZCORE_FRAMEWORK QuartzCore)
find_library(CARBON_FRAMEWORK Carbon)
target_link_libraries(vstgui_support PRIVATE ${COREFOUNDATION_FRAMEWORK} ${COCOA_FRAMEWORK} ${OPENGL_FRAMEWORK} ${ACCELERATE_FRAMEWORK} ${QUARTZCORE_FRAMEWORK} ${CARBON_FRAMEWORK})
endif()
endif()

#-------------------------------------------------------------------------------
# IDE sorting
#-------------------------------------------------------------------------------
set_target_properties(vstgui_support PROPERTIES ${SDK_IDE_LIBS_FOLDER})
set_target_properties(sdk PROPERTIES ${SDK_IDE_LIBS_FOLDER})
set_target_properties(base PROPERTIES ${SDK_IDE_LIBS_FOLDER})
set_target_properties(vstgui PROPERTIES ${SDK_IDE_LIBS_FOLDER})
set_target_properties(vstgui_uidescription PROPERTIES ${SDK_IDE_LIBS_FOLDER})

if (TARGET again)
set_target_properties(again PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()
if (TARGET againsimple)
set_target_properties(againsimple PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()
if (TARGET adelay)
set_target_properties(adelay PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()
if (TARGET channelcontext)
set_target_properties(channelcontext PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()
if (TARGET hostchecker)
set_target_properties(hostchecker PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()
if (TARGET mda-vst3)
set_target_properties(mda-vst3 PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()
if (TARGET noteexpressionsynth)
set_target_properties(noteexpressionsynth PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()
if (TARGET noteexpressiontext)
set_target_properties(noteexpressiontext PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()
if (TARGET pitchnames)
set_target_properties(pitchnames PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()
if (TARGET prefetchablesupport)
set_target_properties(prefetchablesupport PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()
if (TARGET programchange)
set_target_properties(programchange PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()

if (TARGET editorhost)
set_target_properties(editorhost PROPERTIES ${SDK_IDE_HOSTING_EXAMPLES_FOLDER})
endif()
if (TARGET validator)
set_target_properties(validator PROPERTIES ${SDK_IDE_HOSTING_EXAMPLES_FOLDER})
endif ()

if(MAC AND XCODE)
if(SMTG_COREAUDIO_SDK_PATH)
set_target_properties(auwrapper PROPERTIES ${SDK_IDE_LIBS_FOLDER})
set_target_properties(again_au PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()
if(IOS_DEVELOPMENT_TEAM)
set_target_properties(sdk_ios PROPERTIES ${SDK_IDE_LIBS_FOLDER})
set_target_properties(base_ios PROPERTIES ${SDK_IDE_LIBS_FOLDER})
set_target_properties(interappaudio PROPERTIES ${SDK_IDE_LIBS_FOLDER})
set_target_properties(noteexpressionsynth_ios PROPERTIES ${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
endif()
endif()

+ 41
- 0
source/includes/vst3sdk/LICENSE.txt View File

@@ -0,0 +1,41 @@
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
This license applies only to files referencing this license,
for other files of the Software Development Kit the respective embedded license text
is applicable. The license can be found at: www.steinberg.net/sdklicenses_vst3
This Software Development Kit is licensed under the terms of the Steinberg VST3 License,
or alternatively under the terms of the General Public License (GPL) Version 3.
You may use the Software Development Kit according to either of these licenses as it is
most appropriate for your project on a case-by-case basis (commercial or not).
a) Proprietary Steinberg VST3 License
The Software Development Kit may not be distributed in parts or its entirety
without prior written agreement by Steinberg Media Technologies GmbH.
The SDK must not be used to re-engineer or manipulate any technology used
in any Steinberg or Third-party application or software module,
unless permitted by law.
Neither the name of the Steinberg Media Technologies GmbH nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
Before publishing a software under the proprietary license, you need to obtain a copy
of the License Agreement signed by Steinberg Media Technologies GmbH.
The Steinberg VST SDK License Agreement can be found at:
www.steinberg.net/en/company/developers.html
THE SDK IS PROVIDED BY STEINBERG MEDIA TECHNOLOGIES GMBH "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL STEINBERG MEDIA TECHNOLOGIES GMBH BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
b) General Public License (GPL) Version 3
Details of these licenses can be found at: www.gnu.org/licenses/gpl-3.0.html
//----------------------------------------------------------------------------------

+ 92
- 0
source/includes/vst3sdk/README.md View File

@@ -0,0 +1,92 @@
# Welcome to VST SDK 3.6.7
## The VST SDK package contains:
- The VST 3 API
- VST 3 Implementation Helper Classes
- AU and VST2 wrappers
- VST 3 Plug-ins Examples
The full VST 3 SDK is available [here!](https://www.steinberg.net/en/company/developers.html). It contains a VST 3 Plug-in Test Host Application/Validator.
## System requirements
Supported OS:
- Microsoft Windows 7-10
- Apple OSX 10.7-10.12
- Apple iOS 8-9
- Linux (Preview)
Supported IDE:
- Visual Studio 2013/2015
- Xcode 6/7
- Qt Creator
---
## About VST Plug-ins in general
A VST Plug-in is an audio processing component that is utilized within a host application. This host application provides the audio or/and event streams that are processed by the Plug-in's code. Generally speaking, a VST Plug-in can take a stream of audio data, apply a process to the audio, and return the result to the host application. A VST Plug-in performs its process normally using the processor of the computer. The audio stream is broken down into a series of blocks. The host supplies the blocks in sequence. The host and its current environment control the block-size. The VST Plug-in maintains the status of all its own parameters relating to the running process: The host does not maintain any information about what the Plug-in did with the last block of data it processed.
From the host application's point of view, a VST Plug-in is a black box with an arbitrary number of inputs, outputs (Event (MIDI) or Audio), and associated parameters. The host needs no implicit knowledge of the Plug-in's process to be able to use it. The Plug-in process can use whatever parameters it wishes, internally to the process, but depending on the capabilities of the host, it can allow the changes to user parameters to be automated by the host.
The source code of a VST Plug-in is platform independent, but the delivery system depends on the platform architecture:
- On **Windows**, a VST Plug-in is a multi-threaded DLL (Dynamic Link Library).
- On **Mac OS X**, a VST Plug-in is a Mach-O Bundle
- On **Linux**, a VST Plug-in is a package
To learn more about VST you can subscribe to the [VST Developer Forum](https://sdk.steinberg.net) - check the 3rd Party Developer Support section at [www.steinberg.net](www.steinberg.net).
---
## About VST 3
VST 3 is a general rework of the long-serving VST Plug-in interface. It is not compatible with the older VST versions, but it includes some new features and possibilities. We have redesigned the API to make it not only far easier and more reliable for developers to work with, but have also provided completely new possibilities for Plug-ins. These include:
### 1. Improved Performance with the Silence Flag
Processing can optionally be applied to Plug-ins only when audio signals are present on their respective inputs, so VST 3 Plug-ins can apply their processing economically and only when it is needed.
### 2. Multiple Dynamic I/Os
VST 3 Plug-ins are no longer limited to a fixed number of inputs and outputs, and their I/O configuration can dynamically adapt to the channel configuration. Side-chains are also very easily realizable. This includes the possibility to deactivate unused buses after loading and even reactivate those when needed. This cleans up the mixer and further helps to reduce CPU load.
### 3. Sample-accurate Automation
VST 3 also features vastly improved parameter automation with sample accuracy and support for ramped automation data, allowing completely accurate and rapid parameter automation changes.
### 4. Logical Parameter Organization
The VST 3 Plug-in parameters are displayed in a tree structure. Parameters are grouped into sections which represent the structure of the Plug-in. Plug-ins can communicate their internal structure for the purpose of overview, but also for some associated functionality (eg. program-lists).
### 5. Resizeable UI Editor
VST 3 defines a way to allow resizing of the Plug-in editor by a user.
### 6. Mouse Over Support
The Host could ask the Plug-in which parameter is under the mouse.
### 7. Context Menu Support
VST 3 defines a way to allow the host to add its own entries in the Plug-in context menu of a specific parameter.
### 8. Channel Context Information
A VST 3 Plug-in could access some channel information where it is instantiated: name, color,...
### 9. Note Expression
VST 3 defines with Note Expression a new way of event controller editing. The Plug-in is able to break free from the limitations of MIDI controller events by providing access to new VST 3 controller events that circumvent the laws of MIDI and provide articulation information for each individual note (event) in a polyphonic arrangement according to its noteId.
### 10. 3D Support
VST 3 supports new speaker configurations like Atmos, Auro 3D or 22.2.
### 11. Factory Concept
VST 3 Plug-in library could export multiple Plug-ins and in this way replaces the shell concept of VST 2 (kPlugCategShell).
### 12. Support Remote control Representation
VST 3 Plug-in can deliver a specific parameter mapping for remote controls like Nuage.
### 13. Others
While designing VST 3, we performed a careful analysis of the existing functionality of VST and rewrote the interfaces from scratch. In doing so, we focused a lot on providing clear interfaces and their documentation in order to avoid usage errors from the deepest possible layer.
Some more features implemented specifically for developers include:
- More stable technical Host/Plug-in environment
- Advanced technical definition of the standard
- Modular approach
- Separation of UI and processing
- Advanced Preset System
- Multiple Plug-ins per Library
- Test Host included
- Automated Testing Environment
- Validator (small command line Test Host) and Plug-in examples code included.
---
## License
More details are found at [www.steinberg.net/sdklicenses_vst3](www.steinberg.net/sdklicenses_vst3)

+ 85
- 0
source/includes/vst3sdk/public.sdk/CMakeLists.txt View File

@@ -0,0 +1,85 @@

set(sdk_sources
source/common/pluginview.cpp
source/main/pluginfactoryvst3.cpp
source/vst/vstaudioeffect.cpp
source/vst/vstbus.cpp
source/vst/vstbypassprocessor.cpp
source/vst/vstcomponent.cpp
source/vst/vstcomponentbase.cpp
source/vst/vsteditcontroller.cpp
source/vst/vstinitiids.cpp
source/vst/vstnoteexpressiontypes.cpp
source/vst/vstparameters.cpp
source/vst/vstpresetfile.cpp
source/vst/vstrepresentation.cpp
)

set(pluginterfaces_sources
${SDK_ROOT}/pluginterfaces/base/falignpop.h
${SDK_ROOT}/pluginterfaces/base/falignpush.h
${SDK_ROOT}/pluginterfaces/base/fplatform.h
${SDK_ROOT}/pluginterfaces/base/fstrdefs.h
${SDK_ROOT}/pluginterfaces/base/ftypes.h
${SDK_ROOT}/pluginterfaces/base/funknown.h
${SDK_ROOT}/pluginterfaces/base/futils.h
${SDK_ROOT}/pluginterfaces/base/fvariant.h
${SDK_ROOT}/pluginterfaces/base/geoconstants.h
${SDK_ROOT}/pluginterfaces/base/ibstream.h
${SDK_ROOT}/pluginterfaces/base/icloneable.h
${SDK_ROOT}/pluginterfaces/base/ierrorcontext.h
${SDK_ROOT}/pluginterfaces/base/ipersistent.h
${SDK_ROOT}/pluginterfaces/base/ipluginbase.h
${SDK_ROOT}/pluginterfaces/base/istringresult.h
${SDK_ROOT}/pluginterfaces/base/iupdatehandler.h
${SDK_ROOT}/pluginterfaces/base/keycodes.h
${SDK_ROOT}/pluginterfaces/base/pluginbasefwd.h
${SDK_ROOT}/pluginterfaces/base/smartpointer.h
${SDK_ROOT}/pluginterfaces/base/ucolorspec.h
${SDK_ROOT}/pluginterfaces/base/conststringtable.cpp
${SDK_ROOT}/pluginterfaces/base/conststringtable.h
${SDK_ROOT}/pluginterfaces/base/funknown.cpp
${SDK_ROOT}/pluginterfaces/base/ustring.cpp
${SDK_ROOT}/pluginterfaces/base/ustring.h
)

set(vst_includes
${SDK_ROOT}/pluginterfaces/gui/iplugview.h
${SDK_ROOT}/pluginterfaces/gui/iplugviewcontentscalesupport.h
${SDK_ROOT}/pluginterfaces/vst/ivstattributes.h
${SDK_ROOT}/pluginterfaces/vst/ivstaudioprocessor.h
${SDK_ROOT}/pluginterfaces/vst/ivstautomationstate.h
${SDK_ROOT}/pluginterfaces/vst/ivstchannelcontextinfo.h
${SDK_ROOT}/pluginterfaces/vst/ivstcomponent.h
${SDK_ROOT}/pluginterfaces/vst/ivstcontextmenu.h
${SDK_ROOT}/pluginterfaces/vst/ivsteditcontroller.h
${SDK_ROOT}/pluginterfaces/vst/ivstevents.h
${SDK_ROOT}/pluginterfaces/vst/ivsthostapplication.h
${SDK_ROOT}/pluginterfaces/vst/ivstinterappaudio.h
${SDK_ROOT}/pluginterfaces/vst/ivstmessage.h
${SDK_ROOT}/pluginterfaces/vst/ivstmidicontrollers.h
${SDK_ROOT}/pluginterfaces/vst/ivstnoteexpression.h
${SDK_ROOT}/pluginterfaces/vst/ivstparameterchanges.h
${SDK_ROOT}/pluginterfaces/vst/ivstplugview.h
${SDK_ROOT}/pluginterfaces/vst/ivstprefetchablesupport.h
${SDK_ROOT}/pluginterfaces/vst/ivstprocesscontext.h
${SDK_ROOT}/pluginterfaces/vst/ivstrepresentation.h
${SDK_ROOT}/pluginterfaces/vst/ivstunits.h
${SDK_ROOT}/pluginterfaces/vst/vstpresetkeys.h
${SDK_ROOT}/pluginterfaces/vst/vstpshpack4.h
${SDK_ROOT}/pluginterfaces/vst/vsttypes.h
)

add_library(sdk STATIC ${sdk_sources} ${pluginterfaces_sources} ${vst_includes})
target_link_libraries(sdk PRIVATE base)

# iOS target
if(MAC AND XCODE AND IOS_DEVELOPMENT_TEAM)
add_library(sdk_ios STATIC ${sdk_sources} ${pluginterfaces_sources} ${vst_includes})
smtg_set_platform_ios(sdk_ios)
target_link_libraries(sdk_ios PRIVATE base_ios)
endif()

source_group("public.sdk" FILES ${sdk_sources})
source_group("vst" FILES ${vst_includes})
source_group("base" FILES ${pluginterfaces_sources})

+ 27
- 0
source/includes/vst3sdk/public.sdk/LICENSE.txt View File

@@ -0,0 +1,27 @@
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

+ 319
- 0
source/includes/vst3sdk/public.sdk/source/common/memorystream.cpp View File

@@ -0,0 +1,319 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : Common Classes
// Filename : public.sdk/source/common/memorystream.cpp
// Created by : Steinberg, 03/2008
// Description : IBStream Implementation for memory blocks
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "memorystream.h"
#include "pluginterfaces/base/futils.h"
#include <stdlib.h>

namespace Steinberg {

//-----------------------------------------------------------------------------
IMPLEMENT_FUNKNOWN_METHODS (MemoryStream, IBStream, IBStream::iid)
static const TSize kMemGrowAmount = 4096;

//-----------------------------------------------------------------------------
MemoryStream::MemoryStream (void* data, TSize length)
: memory ((char*)data)
, memorySize (length)
, size (length)
, cursor (0)
, ownMemory (false)
, allocationError (false)
{
FUNKNOWN_CTOR
}

//-----------------------------------------------------------------------------
MemoryStream::MemoryStream ()
: memory (nullptr)
, memorySize (0)
, size (0)
, cursor (0)
, ownMemory (true)
, allocationError (false)
{
FUNKNOWN_CTOR
}

//-----------------------------------------------------------------------------
MemoryStream::~MemoryStream ()
{
if (ownMemory && memory)
::free (memory);

FUNKNOWN_DTOR
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API MemoryStream::read (void* data, int32 numBytes, int32* numBytesRead)
{
if (memory == nullptr)
{
if (allocationError)
return kOutOfMemory;
numBytes = 0;
}
else
{
// Does read exceed size ?
if (cursor + numBytes > size)
{
int32 maxBytes = int32 (size - cursor);

// Has length become zero or negative ?
if (maxBytes <= 0)
{
cursor = size;
numBytes = 0;
}
else
numBytes = maxBytes;
}
if (numBytes)
{
memcpy (data, &memory[cursor], numBytes);
cursor += numBytes;
}
}

if (numBytesRead)
*numBytesRead = numBytes;

return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API MemoryStream::write (void* buffer, int32 numBytes, int32* numBytesWritten)
{
if (allocationError)
return kOutOfMemory;
if (buffer == nullptr)
return kInvalidArgument;

// Does write exceed size ?
TSize requiredSize = cursor + numBytes;
if (requiredSize > size)
{
if (requiredSize > memorySize)
setSize (requiredSize);
else
size = requiredSize;
}
// Copy data
if (memory && cursor >= 0 && numBytes > 0)
{
memcpy (&memory[cursor], buffer, numBytes);
// Update cursor
cursor += numBytes;
}
else
numBytes = 0;

if (numBytesWritten)
*numBytesWritten = numBytes;

return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API MemoryStream::seek (int64 pos, int32 mode, int64* result)
{
switch (mode)
{
case kIBSeekSet:
cursor = pos;
break;
case kIBSeekCur:
cursor = cursor + pos;
break;
case kIBSeekEnd:
cursor = size + pos;
break;
}

if (ownMemory == false)
if (cursor > memorySize)
cursor = memorySize;

if (result)
*result = cursor;

return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API MemoryStream::tell (int64* pos)
{
if (!pos)
return kInvalidArgument;

*pos = cursor;
return kResultTrue;
}

//------------------------------------------------------------------------
TSize MemoryStream::getSize ()
{
return size;
}

//------------------------------------------------------------------------
void MemoryStream::setSize (TSize s)
{
if (s <= 0)
{
if (ownMemory && memory)
free (memory);

memory = nullptr;
memorySize = 0;
size = 0;
cursor = 0;
return;
}

TSize newMemorySize = (((Max (memorySize, s) - 1) / kMemGrowAmount) + 1) * kMemGrowAmount;
if (newMemorySize == memorySize)
{
size = s;
return;
}

if (memory && ownMemory == false)
{
allocationError = true;
return;
}

ownMemory = true;
char* newMemory = nullptr;

if (memory)
{
newMemory = (char*)realloc (memory, (size_t)newMemorySize);
if (newMemory == nullptr && newMemorySize > 0)
{
newMemory = (char*)malloc ((size_t)newMemorySize);
if (newMemory)
{
memcpy (newMemory, memory, (size_t)Min (newMemorySize, memorySize));
free (memory);
}
}
}
else
newMemory = (char*)malloc ((size_t)newMemorySize);

if (newMemory == nullptr)
{
if (newMemorySize > 0)
allocationError = true;

memory = nullptr;
memorySize = 0;
size = 0;
cursor = 0;
}
else
{
memory = newMemory;
memorySize = newMemorySize;
size = s;
}
}

//------------------------------------------------------------------------
char* MemoryStream::getData ()
{
return memory;
}

//------------------------------------------------------------------------
char* MemoryStream::detachData ()
{
if (ownMemory)
{
char* result = memory;
memory = nullptr;
memorySize = 0;
size = 0;
cursor = 0;
return result;
}
return nullptr;
}

//------------------------------------------------------------------------
bool MemoryStream::truncate ()
{
if (ownMemory == false)
return false;

if (memorySize == size)
return true;

memorySize = size;
if (memorySize == 0)
{
if (memory)
{
free (memory);
memory = nullptr;
}
}
else
{
if (memory)
{
char* newMemory = (char*)realloc (memory, (size_t)memorySize);
if (newMemory)
memory = newMemory;
}
}
return true;
}

//------------------------------------------------------------------------
bool MemoryStream::truncateToCursor ()
{
size = cursor;
return truncate ();
}

} // namespace

+ 80
- 0
source/includes/vst3sdk/public.sdk/source/common/memorystream.h View File

@@ -0,0 +1,80 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : Common Classes
// Filename : public.sdk/source/common/memorystream.h
// Created by : Steinberg, 03/2008
// Description : IBStream Implementation for memory blocks
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/base/ibstream.h"

namespace Steinberg {

//------------------------------------------------------------------------
/** Memory based Stream for IBStream implementation (using malloc).
\ingroup sdkBase
*/
//------------------------------------------------------------------------
class MemoryStream : public IBStream
{
public:
//------------------------------------------------------------------------
MemoryStream ();
MemoryStream (void* memory, TSize memorySize); ///< reuse a given memory without getting ownership
virtual ~MemoryStream ();

//---IBStream---------------------------------------
virtual tresult PLUGIN_API read (void* buffer, int32 numBytes, int32* numBytesRead) SMTG_OVERRIDE;
virtual tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten) SMTG_OVERRIDE;
virtual tresult PLUGIN_API seek (int64 pos, int32 mode, int64* result) SMTG_OVERRIDE;
virtual tresult PLUGIN_API tell (int64* pos) SMTG_OVERRIDE;

TSize getSize (); ///< returns the current memory size
void setSize (TSize size); ///< set the memory size, a realloc will occur if memory already used
char* getData (); ///< returns the memory pointer
char* detachData (); ///< returns the memory pointer and give up ownership
bool truncate (); ///< realloc to the current use memory size if needed
bool truncateToCursor (); ///< truncate memory at current cursor position

//------------------------------------------------------------------------
DECLARE_FUNKNOWN_METHODS
protected:
char* memory; // memory block
TSize memorySize; // size of the memory block
TSize size; // size of the stream
int64 cursor; // stream pointer
bool ownMemory; // stream has allocated memory itself
bool allocationError; // stream invalid
};

} // namespace

+ 117
- 0
source/includes/vst3sdk/public.sdk/source/common/pluginview.cpp View File

@@ -0,0 +1,117 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : Common Base Classes
// Filename : public.sdk/source/common/pluginview.cpp
// Created by : Steinberg, 01/2004
// Description : Plug-In View Implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "pluginview.h"

namespace Steinberg {

//------------------------------------------------------------------------
// CPluginView implementation
//------------------------------------------------------------------------
CPluginView::CPluginView (const ViewRect* _rect)
: rect (0, 0, 0, 0)
, systemWindow (0)
, plugFrame (0)
{
//TODO FUNKNOWN_CTOR
if (_rect)
rect = *_rect;
}

//------------------------------------------------------------------------
CPluginView::~CPluginView ()
{
//TODO FUNKNOWN_DTOR
}

//------------------------------------------------------------------------
// TODO IMPLEMENT_REFCOUNT (CPluginView)

//------------------------------------------------------------------------
/* TODO
tresult PLUGIN_API CPluginView::queryInterface (const char* iid, void** obj)
{
QUERY_INTERFACE (iid, obj, Steinberg::FUnknown::iid, IPlugView)
QUERY_INTERFACE (iid, obj, Steinberg::IPlugView::iid, IPlugView)
*obj = 0;
return kNoInterface;
}*/


//------------------------------------------------------------------------
tresult PLUGIN_API CPluginView::isPlatformTypeSupported (FIDString /*type*/)
{
return kNotImplemented;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginView::attached (void* parent, FIDString /*type*/)
{
systemWindow = parent;
attachedToParent ();
return kResultOk;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginView::removed ()
{
systemWindow = 0;

removedFromParent ();
return kResultOk;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginView::onSize (ViewRect* newSize)
{
if (newSize)
rect = *newSize;
return kResultTrue;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginView::getSize (ViewRect* size)
{
if (size)
{
*size = rect;
return kResultTrue;
}
return kInvalidArgument;
}

} // end of namespace

+ 102
- 0
source/includes/vst3sdk/public.sdk/source/common/pluginview.h View File

@@ -0,0 +1,102 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
//
// Category : Common Base Classes
// Filename : public.sdk/source/common/pluginview.h
// Created by : Steinberg, 01/2004
// Description : Plug-In View Implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/gui/iplugview.h"
#include "base/source/fobject.h"

namespace Steinberg {

//------------------------------------------------------------------------
/** Plug-In view default implementation.
\ingroup sdkBase
Can be used as base class for an IPlugView implementation. */
//------------------------------------------------------------------------
class CPluginView: public FObject,
public IPlugView
{
public:
//------------------------------------------------------------------------
CPluginView (const ViewRect* rect = 0);
virtual ~CPluginView ();

/** Returns its current frame rectangle. */
const ViewRect& getRect () const { return rect; }
/** Sets a new frame rectangle. */
void setRect (const ViewRect& r) { rect = r; }

/** Checks if this view is attached to its parent view. */
bool isAttached () const { return systemWindow != 0; }

/** Calls when this view will be attached to its parent view. */
virtual void attachedToParent () {}

/** Calls when this view will be removed from its parent view. */
virtual void removedFromParent () {}

//---from IPlugView-------
tresult PLUGIN_API isPlatformTypeSupported (FIDString type) SMTG_OVERRIDE;
tresult PLUGIN_API attached (void* parent, FIDString type) SMTG_OVERRIDE;
tresult PLUGIN_API removed () SMTG_OVERRIDE;

tresult PLUGIN_API onWheel (float /*distance*/) SMTG_OVERRIDE { return kResultFalse; }
tresult PLUGIN_API onKeyDown (char16 /*key*/, int16 /*keyMsg*/, int16 /*modifiers*/) SMTG_OVERRIDE { return kResultFalse; }
tresult PLUGIN_API onKeyUp (char16 /*key*/, int16 /*keyMsg*/, int16 /*modifiers*/) SMTG_OVERRIDE { return kResultFalse; }
tresult PLUGIN_API getSize (ViewRect* size) SMTG_OVERRIDE;
tresult PLUGIN_API onSize (ViewRect* newSize) SMTG_OVERRIDE;

tresult PLUGIN_API onFocus (TBool /*state*/) SMTG_OVERRIDE { return kResultFalse; }
tresult PLUGIN_API setFrame (IPlugFrame* frame) SMTG_OVERRIDE { plugFrame = frame; return kResultTrue; }

tresult PLUGIN_API canResize () SMTG_OVERRIDE { return kResultFalse; }
tresult PLUGIN_API checkSizeConstraint (ViewRect* /*rect*/) SMTG_OVERRIDE { return kResultFalse; }

//---Interface------
OBJ_METHODS (CPluginView, FObject)
DEFINE_INTERFACES
DEF_INTERFACE (IPlugView)
END_DEFINE_INTERFACES (FObject)
REFCOUNT_METHODS(FObject)
//------------------------------------------------------------------------
protected:
ViewRect rect;
void* systemWindow;
IPlugFrame* plugFrame;
};

} // namespace

+ 105
- 0
source/includes/vst3sdk/public.sdk/source/main/dllmain.cpp View File

@@ -0,0 +1,105 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
// Version : 1.0
//
// Category : Common Base Classes
// Filename : public.sdk/source/main/dllmain.cpp
// Created by : Steinberg, 01/2004
// Description : Windows DLL Entry
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "pluginterfaces/base/ftypes.h"

#include <windows.h>

#if defined (_MSC_VER) && defined (DEVELOPMENT)
#include <crtdbg.h>
#endif

#ifdef UNICODE
#define tstrrchr wcsrchr
#else
#define tstrrchr strrchr
#endif

//------------------------------------------------------------------------
HINSTANCE ghInst = 0;
void* moduleHandle = 0;
Steinberg::tchar gPath[MAX_PATH] = {0};

//------------------------------------------------------------------------
#define DllExport __declspec( dllexport )

//------------------------------------------------------------------------
extern bool InitModule (); ///< must be provided by Plug-in: called when the library is loaded
extern bool DeinitModule (); ///< must be provided by Plug-in: called when the library is unloaded

//------------------------------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif
bool DllExport InitDll () ///< must be called from host right after loading dll
{
return InitModule ();
}
bool DllExport ExitDll () ///< must be called from host right before unloading dll
{
return DeinitModule ();
}
#ifdef __cplusplus
} // extern "C"
#endif

//------------------------------------------------------------------------
BOOL WINAPI DllMain (HINSTANCE hInst, DWORD dwReason, LPVOID /*lpvReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
#if defined (_MSC_VER) && defined (DEVELOPMENT)
_CrtSetReportMode ( _CRT_WARN, _CRTDBG_MODE_DEBUG );
_CrtSetReportMode ( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
_CrtSetReportMode ( _CRT_ASSERT, _CRTDBG_MODE_DEBUG );
int flag = _CrtSetDbgFlag (_CRTDBG_REPORT_FLAG);
_CrtSetDbgFlag (flag | _CRTDBG_LEAK_CHECK_DF);
#endif

moduleHandle = ghInst = hInst;

// gets the path of the component
if (GetModuleFileName (ghInst, gPath, MAX_PATH) > 0)
{
Steinberg::tchar* bkslash = tstrrchr (gPath, TEXT ('\\'));
if (bkslash)
gPath[bkslash - gPath + 1] = 0;
}
}

return TRUE;
}

+ 80
- 0
source/includes/vst3sdk/public.sdk/source/main/linuxmain.cpp View File

@@ -0,0 +1,80 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
// Version : 1.0
//
// Category : Common Base Classes
// Filename : public.sdk/source/main/linuxmain.cpp
// Created by : Steinberg, 01/2004
// Description : Linux Component Entry
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
#define EXPORT __attribute__ ((visibility ("default")))
#else
#define EXPORT
#endif

//------------------------------------------------------------------------
void* moduleHandle = 0;

//------------------------------------------------------------------------
bool InitModule (); ///< must be provided by Plug-in: called when the library is loaded
bool DeinitModule (); ///< must be provided by Plug-in: called when the library is unloaded

//------------------------------------------------------------------------
extern "C"
{
EXPORT bool ModuleEntry (void*);
EXPORT bool ModuleExit (void);
}

static int counter {0};

//------------------------------------------------------------------------
bool ModuleEntry (void* sharedLibraryHandle)
{
if (++counter == 1)
{
moduleHandle = sharedLibraryHandle;
return InitModule ();
}
return true;
}

//------------------------------------------------------------------------
bool ModuleExit (void)
{
if (--counter == 0)
{
moduleHandle = nullptr;
return DeinitModule ();
}
return true;
}

+ 3
- 0
source/includes/vst3sdk/public.sdk/source/main/macexport.exp View File

@@ -0,0 +1,3 @@
_GetPluginFactory
_bundleEntry
_bundleExit

+ 113
- 0
source/includes/vst3sdk/public.sdk/source/main/macmain.cpp View File

@@ -0,0 +1,113 @@
//-----------------------------------------------------------------------------
// Project : SDK Core
// Version : 1.0
//
// Category : Common Base Classes
// Filename : public.sdk/source/main/macmain.cpp
// Created by : Steinberg, 01/2004
// Description : Mac OS X Bundle Entry
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#ifndef __CF_USE_FRAMEWORK_INCLUDES__
#define __CF_USE_FRAMEWORK_INCLUDES__ 1
#endif

#include <CoreFoundation/CoreFoundation.h>

#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
#define EXPORT __attribute__ ((visibility ("default")))
#else
#define EXPORT
#endif

//------------------------------------------------------------------------
CFBundleRef ghInst = 0;
unsigned int bundleRefCounter = 0; // counting for bundleEntry/bundleExit pairs
void* moduleHandle = 0;
#define MAX_PATH 2048
char gPath[MAX_PATH] = {0};

//------------------------------------------------------------------------
bool InitModule (); ///< must be provided by Plug-in: called when the library is loaded
bool DeinitModule (); ///< must be provided by Plug-in: called when the library is unloaded

//------------------------------------------------------------------------
extern "C"
{
EXPORT bool bundleEntry (CFBundleRef);
EXPORT bool bundleExit (void);
}

#include <vector>

std::vector< CFBundleRef > gBundleRefs;

//------------------------------------------------------------------------
bool bundleEntry (CFBundleRef ref)
{
if (ref)
{
bundleRefCounter++;
CFRetain (ref);
// hold all bundle refs until plug-in is fully uninitialized
gBundleRefs.push_back (ref);
if (!moduleHandle)
{
ghInst = ref;
moduleHandle = ref;
// optain the bundle path
CFURLRef tempURL = CFBundleCopyBundleURL (ref);
CFURLGetFileSystemRepresentation (tempURL, true, (UInt8*)gPath, MAX_PATH);
CFRelease (tempURL);
}
}
return InitModule ();
}

//------------------------------------------------------------------------
bool bundleExit (void)
{
if (DeinitModule ())
{
if (--bundleRefCounter == 0)
{ // release the CFBundleRef's once all bundleExit clients called in
// there is no way to identify the proper CFBundleRef of the bundleExit call
for (size_t i = 0; i < gBundleRefs.size(); i++)
CFRelease (gBundleRefs[i]);
gBundleRefs.clear();
}
return true;
}
return false;
}

+ 278
- 0
source/includes/vst3sdk/public.sdk/source/main/pluginfactoryvst3.cpp View File

@@ -0,0 +1,278 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Common Base Classes
// Filename : public.sdk/source/main/pluginfactoryvst3.cpp
// Created by : Steinberg, 01/2004
// Description : Standard Plug-in Factory
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "pluginfactoryvst3.h"
#include "pluginterfaces/gui/iplugview.h"
#include "pluginterfaces/base/ibstream.h"

#include <stdlib.h>

namespace Steinberg {

CPluginFactory* gPluginFactory = 0;

DEF_CLASS_IID (IPluginBase)
DEF_CLASS_IID (IPlugView)
DEF_CLASS_IID (IPlugViewIdleHandler)
DEF_CLASS_IID (IPlugFrame)
DEF_CLASS_IID (IPlugFrameIdle)
DEF_CLASS_IID (IBStream)
DEF_CLASS_IID (IPluginFactory)
DEF_CLASS_IID (IPluginFactory2)
DEF_CLASS_IID (IPluginFactory3)
//------------------------------------------------------------------------
// CPluginFactory implementation
//------------------------------------------------------------------------
CPluginFactory::CPluginFactory (const PFactoryInfo& info)
: classes (0)
, classCount (0)
, maxClassCount (0)
{
FUNKNOWN_CTOR

factoryInfo = info;
}

//------------------------------------------------------------------------
CPluginFactory::~CPluginFactory ()
{
if (gPluginFactory == this)
gPluginFactory = 0;

if (classes)
free (classes);

FUNKNOWN_DTOR
}

//------------------------------------------------------------------------
IMPLEMENT_REFCOUNT (CPluginFactory)

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::queryInterface (FIDString _iid, void** obj)
{
QUERY_INTERFACE (_iid, obj, IPluginFactory::iid, IPluginFactory)
QUERY_INTERFACE (_iid, obj, IPluginFactory2::iid, IPluginFactory2)
QUERY_INTERFACE (_iid, obj, IPluginFactory3::iid, IPluginFactory3)
QUERY_INTERFACE (_iid, obj, FUnknown::iid, IPluginFactory)
*obj = 0;
return kNoInterface;
}

//------------------------------------------------------------------------
bool CPluginFactory::registerClass (const PClassInfo* info,
FUnknown* (*createFunc)(void*), void* context)
{
if (!info || !createFunc)
return false;

PClassInfo2 info2;
memcpy (&info2, info, sizeof (PClassInfo));
return registerClass (&info2, createFunc, context);
}

//------------------------------------------------------------------------
bool CPluginFactory::registerClass (const PClassInfo2* info,
FUnknown* (*createFunc)(void*), void* context)
{
if (!info || !createFunc)
return false;

if (classCount >= maxClassCount)
{
if (!growClasses ())
return false;
}

PClassEntry& entry = classes[classCount];
entry.info8 = *info;
entry.info16.fromAscii (*info);
entry.createFunc = createFunc;
entry.context = context;
entry.isUnicode = false;

classCount++;
return true;
}

//------------------------------------------------------------------------
bool CPluginFactory::registerClass (const PClassInfoW* info,
FUnknown* (*createFunc)(void*), void* context)
{
if (!info || !createFunc)
return false;

if (classCount >= maxClassCount)
{
if (!growClasses ())
return false;
}

PClassEntry& entry = classes[classCount];
entry.info16 = *info;
entry.createFunc = createFunc;
entry.context = context;
entry.isUnicode = true;

classCount++;
return true;
}

//------------------------------------------------------------------------
bool CPluginFactory::growClasses ()
{
static const int32 delta = 10;

size_t size = (maxClassCount + delta) * sizeof (PClassEntry);
void* memory = classes;

if (!memory)
memory = malloc (size);
else
memory = realloc (memory, size);

if (!memory)
return false;

classes = (PClassEntry*)memory;
maxClassCount += delta;
return true;
}

//------------------------------------------------------------------------
bool CPluginFactory::isClassRegistered (const FUID& cid)
{
for (int32 i = 0; i < classCount; i++)
{
if (cid == classes[i].info16.cid)
return true;
}
return false;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::getFactoryInfo (PFactoryInfo* info)
{
if (info)
memcpy (info, &factoryInfo, sizeof (PFactoryInfo));
return kResultOk;
}

//------------------------------------------------------------------------
int32 PLUGIN_API CPluginFactory::countClasses ()
{
return classCount;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::getClassInfo (int32 index, PClassInfo* info)
{
if (info && (index >= 0 && index < classCount))
{
if (classes[index].isUnicode)
{
memset (info, 0, sizeof (PClassInfo));
return kResultFalse;
}

memcpy (info, &classes[index].info8, sizeof (PClassInfo));
return kResultOk;
}
return kInvalidArgument;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::getClassInfo2 (int32 index, PClassInfo2* info)
{
if (info && (index >= 0 && index < classCount))
{
if (classes[index].isUnicode)
{
memset (info, 0, sizeof (PClassInfo2));
return kResultFalse;
}

memcpy (info, &classes[index].info8, sizeof (PClassInfo2));
return kResultOk;
}
return kInvalidArgument;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::getClassInfoUnicode (int32 index, PClassInfoW* info)
{
if (info && (index >= 0 && index < classCount))
{
memcpy (info, &classes[index].info16, sizeof (PClassInfoW));
return kResultOk;
}
return kInvalidArgument;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::createInstance (FIDString cid, FIDString _iid, void** obj)
{
for (int32 i = 0; i < classCount; i++)
{
if (memcmp (classes[i].info16.cid, cid, sizeof (TUID)) == 0)
{
FUnknown* instance = classes[i].createFunc (classes[i].context);
if (instance)
{
if (instance->queryInterface (_iid, obj) == kResultOk)
{
instance->release ();
return kResultOk;
}
else
instance->release ();
}
break;
}
}

*obj = 0;
return kNoInterface;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::setHostContext (FUnknown* /*context*/)
{
return kNotImplemented;
}

} // namespace Steinberg

+ 175
- 0
source/includes/vst3sdk/public.sdk/source/main/pluginfactoryvst3.h View File

@@ -0,0 +1,175 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Common Base Classes
// Filename : public.sdk/source/main/pluginfactoryvst3.h
// Created by : Steinberg, 01/2004
// Description : Standard Plug-in Factory
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/base/ipluginbase.h"

namespace Steinberg {

//------------------------------------------------------------------------
/** Default Class Factory implementation.
\ingroup sdkBase
\see \ref classFactoryMacros */
//------------------------------------------------------------------------
class CPluginFactory : public IPluginFactory3
{
public:
//------------------------------------------------------------------------
CPluginFactory (const PFactoryInfo& info);
virtual ~CPluginFactory ();

//------------------------------------------------------------------------
/** Registers a Plug-in class with classInfo version 1, returns true for success. */
bool registerClass (const PClassInfo* info,
FUnknown* (*createFunc)(void*),
void* context = 0);

/** Registers a Plug-in class with classInfo version 2, returns true for success. */
bool registerClass (const PClassInfo2* info,
FUnknown* (*createFunc)(void*),
void* context = 0);

/** Registers a Plug-in class with classInfo Unicode version, returns true for success. */
bool registerClass (const PClassInfoW* info,
FUnknown* (*createFunc)(void*),
void* context = 0);


/** Check if a class for a given classId is already registered. */
bool isClassRegistered (const FUID& cid);

//------------------------------------------------------------------------
DECLARE_FUNKNOWN_METHODS

//---from IPluginFactory------
tresult PLUGIN_API getFactoryInfo (PFactoryInfo* info) SMTG_OVERRIDE;
int32 PLUGIN_API countClasses () SMTG_OVERRIDE;
tresult PLUGIN_API getClassInfo (int32 index, PClassInfo* info) SMTG_OVERRIDE;
tresult PLUGIN_API createInstance (FIDString cid, FIDString _iid, void** obj) SMTG_OVERRIDE;

//---from IPluginFactory2-----
tresult PLUGIN_API getClassInfo2 (int32 index, PClassInfo2* info) SMTG_OVERRIDE;

//---from IPluginFactory3-----
tresult PLUGIN_API getClassInfoUnicode (int32 index, PClassInfoW* info) SMTG_OVERRIDE;
tresult PLUGIN_API setHostContext (FUnknown* context) SMTG_OVERRIDE;

//------------------------------------------------------------------------
protected:
/// @cond
struct PClassEntry
{
//-----------------------------------
PClassInfo2 info8;
PClassInfoW info16;

FUnknown* (*createFunc)(void*);
void* context;
bool isUnicode;
//-----------------------------------
};
/// @endcond

PFactoryInfo factoryInfo;
PClassEntry* classes;
int32 classCount;
int32 maxClassCount;

bool growClasses ();
};

extern CPluginFactory* gPluginFactory;
//------------------------------------------------------------------------
} // namespace Steinberg


//------------------------------------------------------------------------
#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
#define EXPORT_FACTORY __attribute__ ((visibility ("default")))
#else
#define EXPORT_FACTORY
#endif

//------------------------------------------------------------------------
/** \defgroup classFactoryMacros Macros for defining the class factory
\ingroup sdkBase

\b Example - How to use the class factory macros:
\code
BEGIN_FACTORY ("Steinberg Technologies",
"http://www.steinberg.de",
"mailto:info@steinberg.de",
PFactoryInfo::kNoFlags)

DEF_CLASS (INLINE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000),
PClassInfo::kManyInstances,
"Service",
"Test Service",
TestService::newInstance)

END_FACTORY
\endcode

@{*/

#define BEGIN_FACTORY(vendor,url,email,flags) using namespace Steinberg; \
EXPORT_FACTORY IPluginFactory* PLUGIN_API GetPluginFactory () { \
if (!gPluginFactory) \
{ static PFactoryInfo factoryInfo (vendor,url,email,flags); \
gPluginFactory = new CPluginFactory (factoryInfo); \

#define DEF_CLASS(cid,cardinality,category,name,createMethod) \
{ TUID lcid = cid; static PClassInfo componentClass (lcid,cardinality,category,name); \
gPluginFactory->registerClass (&componentClass,createMethod); }

#define DEF_CLASS1(cid,cardinality,category,name,createMethod) \
{ static PClassInfo componentClass (cid,cardinality,category,name); \
gPluginFactory->registerClass (&componentClass,createMethod); }

#define DEF_CLASS2(cid,cardinality,category,name,classFlags,subCategories,version,sdkVersion,createMethod) \
{ TUID lcid = cid; static PClassInfo2 componentClass (lcid,cardinality,category,name,classFlags,subCategories, 0 ,version,sdkVersion);\
gPluginFactory->registerClass (&componentClass,createMethod); }

#define DEF_CLASS_W(cid,cardinality,category,name,classFlags,subCategories,version,sdkVersion,createMethod) \
{ TUID lcid = cid; static PClassInfoUnicode componentClass (lcid,cardinality,category,name,classFlags,subCategories, 0,version,sdkVersion);\
gPluginFactory->registerClass (&componentClass,createMethod); }


#define END_FACTORY } else gPluginFactory->addRef (); \
return gPluginFactory; }

/** @} */

+ 4
- 0
source/includes/vst3sdk/public.sdk/source/main/winexport.def View File

@@ -0,0 +1,4 @@
EXPORTS
GetPluginFactory
InitDll
ExitDll

+ 32
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/CMakeLists.txt View File

@@ -0,0 +1,32 @@
if(MAC)
if (XCODE AND SMTG_COREAUDIO_SDK_PATH)
set(target auwrapper)
set(${target}_sources
aucarbonview.mm
aucarbonview.h
aucocoaview.mm
aucocoaview.h
ausdk.mm
auwrapper.mm
auwrapper.h
NSDataIBStream.mm
NSDataIBStream.h
${SDK_ROOT}/pluginterfaces/base/funknown.cpp
${SDK_ROOT}/pluginterfaces/base/ustring.cpp
${SDK_ROOT}/public.sdk/source/vst/hosting/eventlist.cpp
${SDK_ROOT}/public.sdk/source/vst/hosting/eventlist.h
${SDK_ROOT}/public.sdk/source/vst/hosting/hostclasses.cpp
${SDK_ROOT}/public.sdk/source/vst/hosting/hostclasses.h
${SDK_ROOT}/public.sdk/source/vst/hosting/parameterchanges.cpp
${SDK_ROOT}/public.sdk/source/vst/hosting/parameterchanges.h
${SDK_ROOT}/public.sdk/source/vst/hosting/processdata.cpp
${SDK_ROOT}/public.sdk/source/vst/hosting/processdata.h
)
add_library(${target} STATIC ${${target}_sources})
target_link_libraries(${target} PRIVATE base "-framework AudioUnit" "-framework CoreMIDI" "-framework AudioToolbox" "-framework CoreFoundation" "-framework Carbon" "-framework Cocoa" "-framework CoreAudio")
target_include_directories(${target} PRIVATE "${SMTG_COREAUDIO_SDK_PATH}/**")
add_custom_command(TARGET ${target} PRE_BUILD COMMAND /usr/bin/ruby "./generateCocoaClassNamePrefix.rb" "${CMAKE_CURRENT_LIST_DIR}" WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}")
else()
message("* To enable building the AudioUnit wrapper, you need to use the Xcode generator and set SMTG_COREAUDIO_SDK_PATH to the path of your installation of the CoreAudio SDK!")
endif()
endif()

+ 92
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/NSDataIBStream.h View File

@@ -0,0 +1,92 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/NSDataIBStream.h
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#pragma once

#import <Foundation/Foundation.h>
#import "pluginterfaces/base/ibstream.h"
#import "public.sdk/source/vst/hosting/hostclasses.h"

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
class NSDataIBStream : public IBStream, Vst::IStreamAttributes
{
public:
NSDataIBStream (NSData* data, bool hideAttributes = false);
virtual ~NSDataIBStream ();

//---from IBStream-------------------
tresult PLUGIN_API read (void* buffer, int32 numBytes, int32* numBytesRead = 0) SMTG_OVERRIDE;
tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten = 0) SMTG_OVERRIDE;
tresult PLUGIN_API seek (int64 pos, int32 mode, int64* result = 0) SMTG_OVERRIDE;
tresult PLUGIN_API tell (int64* pos) SMTG_OVERRIDE;

//---from Vst::IStreamAttributes-----
virtual tresult PLUGIN_API getFileName (String128 name) SMTG_OVERRIDE;
virtual IAttributeList* PLUGIN_API getAttributes () SMTG_OVERRIDE;

//------------------------------------------------------------------------
DECLARE_FUNKNOWN_METHODS
protected:
NSData* data;
int64 currentPos;
HostAttributeList attrList;
bool hideAttributes;
};

//------------------------------------------------------------------------
class NSMutableDataIBStream : public NSDataIBStream
{
public:
NSMutableDataIBStream (NSMutableData* data);
virtual ~NSMutableDataIBStream ();

tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten = 0);
//------------------------------------------------------------------------
protected:
NSMutableData* mdata;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

/// \endcond

+ 206
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/NSDataIBStream.mm View File

@@ -0,0 +1,206 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/NSDataIBStream.mm
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#include "NSDataIBStream.h"

#include "pluginterfaces/vst/ivstattributes.h"

#include <algorithm>

#if __clang__
#if __has_feature(objc_arc) && __clang_major__ >= 3
#define ARC_ENABLED 1
#endif // __has_feature(objc_arc)
#endif // __clang__

namespace Steinberg {
namespace Vst {

DEF_CLASS_IID(IStreamAttributes);

//------------------------------------------------------------------------
NSDataIBStream::NSDataIBStream (NSData* data, bool hideAttributes)
: data (data)
, currentPos (0)
, hideAttributes (hideAttributes)
{
FUNKNOWN_CTOR
#if !ARC_ENABLED
[data retain];
#endif
}

//------------------------------------------------------------------------
NSDataIBStream::~NSDataIBStream ()
{
#if !ARC_ENABLED
[data release];
#endif
FUNKNOWN_DTOR
}

//------------------------------------------------------------------------
IMPLEMENT_REFCOUNT (NSDataIBStream)

//------------------------------------------------------------------------
tresult PLUGIN_API NSDataIBStream::queryInterface (const TUID iid, void** obj)
{
QUERY_INTERFACE (iid, obj, FUnknown::iid, IBStream)
QUERY_INTERFACE (iid, obj, IBStream::iid, IBStream)
if (!hideAttributes)
QUERY_INTERFACE (iid, obj, IStreamAttributes::iid, IStreamAttributes)
*obj = 0;
return kNoInterface;
}

//------------------------------------------------------------------------
tresult PLUGIN_API NSDataIBStream::read (void* buffer, int32 numBytes, int32* numBytesRead)
{
int32 useBytes = std::min (numBytes, (int32)([data length] - currentPos));
if (useBytes > 0)
{
[data getBytes: buffer range: NSMakeRange (currentPos, useBytes)];
if (numBytesRead)
*numBytesRead = useBytes;
currentPos += useBytes;
return kResultTrue;
}
return kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API NSDataIBStream::write (void* buffer, int32 numBytes, int32* numBytesWritten)
{
return kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API NSDataIBStream::seek (int64 pos, int32 mode, int64* result)
{
switch (mode)
{
case kIBSeekSet:
{
if (pos <= [data length])
{
currentPos = pos;
if (result)
tell (result);
return kResultTrue;
}
break;
}
case kIBSeekCur:
{
if (currentPos + pos <= [data length])
{
currentPos += pos;
if (result)
tell (result);
return kResultTrue;
}
break;
}
case kIBSeekEnd:
{
if ([data length] + pos <= [data length])
{
currentPos = [data length] + pos;
if (result)
tell (result);
return kResultTrue;
}
break;
}
}
return kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API NSDataIBStream::tell (int64* pos)
{
if (pos)
{
*pos = currentPos;
return kResultTrue;
}
return kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API NSDataIBStream::getFileName (String128 name)
{
return kNotImplemented;
}

//------------------------------------------------------------------------
IAttributeList* PLUGIN_API NSDataIBStream::getAttributes ()
{
return hideAttributes ? 0 : &attrList;
}

//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
NSMutableDataIBStream::NSMutableDataIBStream (NSMutableData* data)
: NSDataIBStream (data, true)
, mdata (data)
{
}

//------------------------------------------------------------------------
NSMutableDataIBStream::~NSMutableDataIBStream ()
{
[mdata setLength:currentPos];
}

//------------------------------------------------------------------------
tresult PLUGIN_API NSMutableDataIBStream::write (void* buffer, int32 numBytes, int32* numBytesWritten)
{
[mdata replaceBytesInRange:NSMakeRange (currentPos, numBytes) withBytes:buffer];
if (numBytesWritten)
*numBytesWritten = numBytes;
currentPos += numBytes;
return kResultTrue;
}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

/// \endcond

+ 41
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/CMakeLists.txt View File

@@ -0,0 +1,41 @@
if(MAC AND XCODE AND SMTG_COREAUDIO_SDK_PATH)
set(target again_au)
set(${target}_sources
doc.cpp
audiounitconfig.h
Info.plist
)
add_library(${target} MODULE ${${target}_sources})
set_target_properties(${target} PROPERTIES BUNDLE TRUE)
set_target_properties(${target} PROPERTIES XCODE_ATTRIBUTE_GENERATE_MASTER_OBJECT_FILE "YES")
set_target_properties(${target} PROPERTIES XCODE_ATTRIBUTE_OTHER_LDFLAGS "-all_load")
set_target_properties(${target} PROPERTIES XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE "YES")
set_target_properties(${target} PROPERTIES XCODE_ATTRIBUTE_WRAPPER_EXTENSION "component")
set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${VST3_OUTPUT_DIR})
target_link_libraries(${target} PRIVATE auwrapper)
smtg_set_bundle(${target} INFOPLIST "${CMAKE_CURRENT_LIST_DIR}/Info.plist" PREPROCESS)
set(outputdir ${VST3_OUTPUT_DIR}/$<CONFIG>)
add_dependencies(${target} again)
add_custom_command(TARGET ${target} POST_BUILD COMMAND /bin/mkdir "-p" ${outputdir}/${target}.component/Contents/Resources)
add_custom_command(TARGET ${target} POST_BUILD COMMAND /bin/ln "-sf" "${outputdir}/again.vst3" "${outputdir}/${target}.component/Contents/Resources/plugin.vst3")
add_custom_command(TARGET ${target} POST_BUILD COMMAND /bin/ln "-sf" "${outputdir}/${target}.component" "~/Library/Audio/Plug-Ins/Components/")

execute_process(COMMAND xcrun --find Rez OUTPUT_VARIABLE OSX_REZ_COMMAND OUTPUT_STRIP_TRAILING_WHITESPACE)
add_custom_command(TARGET ${target} POST_BUILD COMMAND "${OSX_REZ_COMMAND}"
"-d" "SystemSevenOrLater=1"
"-script" "Roman"
"-d" "i386_YES"
"-d" "x86_64_YES"
"-is" "${CMAKE_OSX_SYSROOT}"
"-I" "${CMAKE_OSX_SYSROOT}/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers"
"-I" "/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers"
"-I" "${SMTG_COREAUDIO_SDK_PATH}/AudioUnits/AUPublic/AUBase"
"-I" "${CMAKE_CURRENT_LIST_DIR}"
"-o" "${outputdir}/${target}.component/Contents/Resources/again_au.rsrc"
"-useDF"
"${CMAKE_CURRENT_LIST_DIR}/../auresource.r"
)

endif()

+ 117
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/Info.plist View File

@@ -0,0 +1,117 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/again/Info.plist
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "audiounitconfig.h"

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>kAudioUnitBundleIdentifier</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CSResourcesFileMapped</key>
<string>yes</string>

/*
The "AudioUnit SupportedNumChannels" key is only necessary if you build an effect not an instrument.
You should describe all supported channel configurations.
This example says that it supports Stereo/Stereo or Mono/Mono.
*/

<key>AudioUnit SupportedNumChannels</key>
<array>
<dict>
<key>Outputs</key>
<string>2</string>
<key>Inputs</key>
<string>2</string>
</dict>
<dict>
<key>Outputs</key>
<string>0</string>
<key>Inputs</key>
<string>1</string>
</dict>
<dict>
<key>Outputs</key>
<string>1</string>
<key>Inputs</key>
<string>1</string>
</dict>
</array>

<key>AudioUnit Version</key>
<string>kAudioUnitVersion</string>

/*
Support for the new AUPlugIn model in Mac OS X 10.7
*/
<key>AudioComponents</key>
<array>
<dict>
<key>description</key>
<string>kAUPluginDescription</string>
<key>factoryFunction</key>
<string>AUWrapperFactory</string>
<key>manufacturer</key>
<string>kAUPluginManufacturer</string>
<key>name</key>
<string>kAUPluginName</string>
<key>subtype</key>
<string>kAUPluginSubType</string>
<key>type</key>
<string>kAUPluginType</string>
<key>version</key>
<integer>kAudioUnitVersion</integer>
</dict>
</array>

</dict>
</plist>

+ 61
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/audiounitconfig.h View File

@@ -0,0 +1,61 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/again/audiounitconfig.h
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

// AUWRAPPER_CHANGE

/* Bundle Identifier */
#define kAudioUnitBundleIdentifier com.steinberg.vst3plugin.again.audiounit
/* Version Number (needs to be in hex)*/
#define kAudioUnitVersion 0xFFFFFFFF
/* Company Name + Effect Name */
#define kAUPluginName Steinberg: AGain
/* Effect Description */
#define kAUPluginDescription AGain
/* Audio Unit Type */
#define kAUPluginType aufx
/* Unique ID */
#define kAUPluginSubType gain
/* Registered Company ID */
#define kAUPluginManufacturer Stgb

// Definitions for the resource file
#define kAudioUnitName "Steinberg: AGain" // same as kAUPluginName
#define kAudioUnitDescription "AGain" // same as kAUPluginDescription
#define kAudioUnitType 'aufx' //kAudioUnitType_Effect // same as kAUPluginType
#define kAudioUnitComponentSubType 'gain' // same as kAUPluginSubType
#define kAudioUnitComponentManuf 'Stgb' // same as kAUPluginManufacturer

#define kAudioUnitCarbonView 1 // if 0 no Carbon view support will be added

+ 51
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/config/again.xcconfig View File

@@ -0,0 +1,51 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : again.xcconfig
// Created by : Steinberg, 5/24/12
// Description : Xcode configuration file, VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "../../config/ausdkpath" // AUWRAPPER_CHANGE

PRODUCT_NAME = again // AUWRAPPER_CHANGE
WRAPPER_EXTENSION = component

STRIP_STYLE = non-global
OTHER_LDFLAGS = -all_load
GENERATE_MASTER_OBJECT_FILE = YES
KEEP_PRIVATE_EXTERNS = YES
SEPARATE_SYMBOL_EDIT = YES
OTHER_REZFLAGS = -d ppc_$ppc -d i386_$i386 -d ppc64_$ppc64 -d x86_64_$x86_64 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I /$DEVELOPER_DIR/Examples/CoreAudio/AudioUnits/AUPublic/AUBase -I /$DEVELOPER_DIR/Extras/CoreAudio/AudioUnits/AUPublic/AUBase -I $(CUSTOM_AU_SDK_PATH)/AudioUnits/AUPublic/AUBase
INFOPLIST_PREPROCESS = YES
PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
INSTALL_PATH = /Library/Audio/Plug-Ins/Components/

+ 38
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/config/again_debug.xcconfig View File

@@ -0,0 +1,38 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : again_debug.xcconfig
// Created by : Steinberg, 5/24/12
// Description : Xcode configuration file, VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "../../../../../base/mac/config/debug" // AUWRAPPER_CHANGE
#include "again"

+ 38
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/config/again_release.xcconfig View File

@@ -0,0 +1,38 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : again_release.xcconfig
// Created by : Steinberg, 5/24/12
// Description : Xcode configuration file, VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "../../../../../base/mac/config/release" // AUWRAPPER_CHANGE
#include "again"

+ 52
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/again/doc.cpp View File

@@ -0,0 +1,52 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/again/doc.cpp
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/*

TODO: cmake adaption needed

How-To use the VST3->AU Wrapper:
- Make a copy of this project
- search trough the project files for "AUWRAPPER_CHANGE". You may need to change the stuff there especially
if you have moved the project so that some paths are invalid
- edit audiounitconfig.h see comments there
- edit Info.plist see comments there
- edit the "Make Links Script" for easier debugging/development
- For the release version, you must place a copy or an alias of your vst3 plugin in the resource folder of the bundle named "plugin.vst3"

*/

+ 83
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/aucarbonview.h View File

@@ -0,0 +1,83 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/aucarbonview.h
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#pragma once

#if !__LP64__

#include "AUPublic/AUCarbonViewBase/AUCarbonViewBase.h"
#include "pluginterfaces/vst/ivsteditcontroller.h"
#include "base/source/fobject.h"
#include "pluginterfaces/gui/iplugview.h"

namespace Steinberg {
namespace Vst {
class AUCarbonPlugFrame;

//------------------------------------------------------------------------
class AUCarbonView : public AUCarbonViewBase, public IPlugFrame, public FObject
{
public:
AUCarbonView (AudioUnitCarbonView auv);
~AUCarbonView ();

OSStatus CreateUI (Float32 xoffset, Float32 yoffset);

OBJ_METHODS(AUCarbonView, FObject)
DEF_INTERFACES_1(IPlugFrame, FObject)
REFCOUNT_METHODS(FObject)

protected:
tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* vr);

static OSStatus HIViewAdded (EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* inUserData);

IEditController* editController;
AUCarbonPlugFrame* plugFrame;
IPlugView* plugView;
HIViewRef hiPlugView;
EventHandlerRef eventHandler;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

#endif // !__LP64__

/// \endcond

+ 167
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/aucarbonview.mm View File

@@ -0,0 +1,167 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/aucarbonview.mm
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#include "aucarbonview.h"

#if !__LP64__

namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
AUCarbonView::AUCarbonView (AudioUnitCarbonView auv)
: AUCarbonViewBase (auv)
, editController (0)
, plugView (0)
, hiPlugView (0)
{
}

//------------------------------------------------------------------------
AUCarbonView::~AUCarbonView ()
{
if (plugView)
{
plugView->setFrame (0);
plugView->removed ();
plugView->release ();
}
}

//------------------------------------------------------------------------
OSStatus AUCarbonView::HIViewAdded (EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
UInt32 eventClass = GetEventClass (inEvent);
UInt32 eventKind = GetEventKind (inEvent);
if (eventClass == kEventClassControl && eventKind == kEventControlAddedSubControl)
{
HIViewRef newControl;
if (GetEventParameter (inEvent, kEventParamControlSubControl, typeControlRef, NULL, sizeof (HIViewRef) , NULL , &newControl) == noErr)
{
AUCarbonView* wrapper = (AUCarbonView*)inUserData;
wrapper->hiPlugView = newControl;
RemoveEventHandler (wrapper->eventHandler);
wrapper->eventHandler = 0;
}
}
return eventNotHandledErr;
}

//------------------------------------------------------------------------
OSStatus AUCarbonView::CreateUI (Float32 xoffset, Float32 yoffset)
{
AudioUnit unit = GetEditAudioUnit ();
if (unit)
{
if (!editController)
{
UInt32 size = sizeof (IEditController*);
if (AudioUnitGetProperty (unit, 64000, kAudioUnitScope_Global, 0, &editController, &size) != noErr)
return kAudioUnitErr_NoConnection;
}
if (editController)
{
plugView = editController->createView (ViewType::kEditor);
if (!plugView)
return kAudioUnitErr_NoConnection;

HIViewRef contentView;
const EventTypeSpec eventTypes[] = {
{ kEventClassControl, kEventControlAddedSubControl },
};
OSStatus err = HIViewFindByID (HIViewGetRoot (GetCarbonWindow ()), kHIViewWindowContentID, &contentView);
err = InstallControlEventHandler (contentView, HIViewAdded, 1, eventTypes, this, &eventHandler);

plugView->setFrame (this);

if (plugView->attached (GetCarbonWindow (), kPlatformTypeHIView) == kResultTrue)
{
HIViewRemoveFromSuperview (hiPlugView);
EmbedControl (hiPlugView);
HIViewMoveBy (hiPlugView, xoffset, yoffset);
return noErr;
}
else
plugView->setFrame (0);
}
}
return kAudioUnitErr_NoConnection;
}

//------------------------------------------------------------------------
tresult PLUGIN_API AUCarbonView::resizeView (IPlugView* view, ViewRect* vr)
{
if (vr == 0 || view != plugView)
return kInvalidArgument;

HIViewRef hiView = GetCarbonPane ();
if (hiView)
{
HIRect r;
if (HIViewGetFrame (hiView, &r) != noErr)
return kResultFalse;
r.size.width = vr->right - vr->left;
r.size.height = vr->bottom - vr->top;
if (HIViewSetFrame (hiView, &r) != noErr)
return kResultFalse;
if (plugView)
plugView->onSize (vr);
return kResultTrue;
}
return kResultFalse;
}

//------------------------------------------------------------------------
//COMPONENT_ENTRY(AUCarbonView)
//------------------------------------------------------------------------
extern "C" {
ComponentResult AUCarbonViewEntry(ComponentParameters *params, AUCarbonView *obj);
__attribute__ ((visibility ("default"))) ComponentResult AUCarbonViewEntry(ComponentParameters *params, AUCarbonView *obj)
{
return ComponentEntryPoint<AUCarbonView>::Dispatch(params, obj);
}
}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg
#endif

/// \endcond

+ 68
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/aucocoaview.h View File

@@ -0,0 +1,68 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/aucocoaview.h
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#pragma once

#import "aucocoaclassprefix.h"

#import <Cocoa/Cocoa.h>
#import <AudioUnit/AUCocoaUIView.h>

#ifndef SMTG_AU_NAMESPACE
# error define SMTG_AU_NAMESPACE
#endif

//-----------------------------------------------------------------------------
#define SMTG_AU_PLUGIN_NAMESPACE0(x) x
#define SMTG_AU_PLUGIN_NAMESPACE1(a, b) a##_##b
#define SMTG_AU_PLUGIN_NAMESPACE2(a, b) SMTG_AU_PLUGIN_NAMESPACE1(a,b)
#define SMTG_AU_PLUGIN_NAMESPACE(name) SMTG_AU_PLUGIN_NAMESPACE2(SMTG_AU_PLUGIN_NAMESPACE0(name), SMTG_AU_PLUGIN_NAMESPACE0(SMTG_AU_NAMESPACE))

//-----------------------------------------------------------------------------
// SMTG_AU_PLUGIN_NAMESPACE (SMTGAUPluginCocoaView)
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
@interface SMTG_AU_PLUGIN_NAMESPACE (SMTGAUPluginCocoaView) : NSObject <AUCocoaUIBase>
{
}

//-----------------------------------------------------------------------------
@end

/// \endcond

+ 232
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/aucocoaview.mm View File

@@ -0,0 +1,232 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/aucocoaview.mm
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

#import "aucocoaview.h"
#import "auwrapper.h"
#import "pluginterfaces/vst/ivsteditcontroller.h"
#import "pluginterfaces/gui/iplugview.h"
#import "base/source/fobject.h"

namespace Steinberg {
DEF_CLASS_IID(IPlugFrame)

//------------------------------------------------------------------------
class AUPlugFrame : public FObject, public IPlugFrame
//------------------------------------------------------------------------
{
public:
AUPlugFrame (NSView* parent) : parent (parent) {}
tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* vr) SMTG_OVERRIDE
{
NSRect newSize = NSMakeRect ([parent frame].origin.x, [parent frame].origin.y, vr->right - vr->left, vr->bottom - vr->top);
[parent setFrame:newSize];
return kResultTrue;
}
OBJ_METHODS(AUPlugFrame, FObject)
DEF_INTERFACES_1(IPlugFrame, FObject)
REFCOUNT_METHODS(FObject)
protected:
NSView* parent;
};
} // namespace Steinberg

using namespace Steinberg;

//------------------------------------------------------------------------
@interface SMTGCocoa_NSViewWrapperForAU : NSView {
//------------------------------------------------------------------------
IPlugView* plugView;
Vst::IEditController* editController;
AudioUnit audioUnit;
FObject* dynlib;
AUPlugFrame* plugFrame;
BOOL isAttached;
}

- (id) initWithEditController: (Vst::IEditController*) editController audioUnit: (AudioUnit) au preferredSize: (NSSize) size;

@end

//------------------------------------------------------------------------
// SMTG_AU_PLUGIN_NAMESPACE (SMTGAUPluginCocoaView)
//------------------------------------------------------------------------

//------------------------------------------------------------------------
@implementation SMTG_AU_PLUGIN_NAMESPACE (SMTGAUPluginCocoaView)

//------------------------------------------------------------------------
- (unsigned) interfaceVersion
{
return 0;
}

//------------------------------------------------------------------------
- (NSString *) description
{
return @"Cocoa View";
}

//------------------------------------------------------------------------
- (NSView *)uiViewForAudioUnit:(AudioUnit)inAU withSize:(NSSize)inPreferredSize
{
Vst::IEditController* editController = 0;
UInt32 size = sizeof (Vst::IEditController*);
if (AudioUnitGetProperty (inAU, 64000, kAudioUnitScope_Global, 0, &editController, &size) != noErr)
return nil;
return [[[SMTGCocoa_NSViewWrapperForAU alloc] initWithEditController:editController audioUnit:inAU preferredSize:inPreferredSize] autorelease];
}

@end

//------------------------------------------------------------------------
@implementation SMTGCocoa_NSViewWrapperForAU
//------------------------------------------------------------------------
- (id) initWithEditController: (Vst::IEditController*) _editController audioUnit: (AudioUnit) au preferredSize: (NSSize) size
{
self = [super initWithFrame: NSMakeRect (0, 0, size.width, size.height)];
if (self)
{
editController = _editController;
editController->addRef ();
audioUnit = au;
plugView = editController->createView (Vst::ViewType::kEditor);
if (!plugView || plugView->isPlatformTypeSupported (kPlatformTypeNSView) != kResultTrue)
{
[self dealloc];
return nil;
}
plugFrame = NEW AUPlugFrame (self);
plugView->setFrame (plugFrame);
if (plugView->attached (self, kPlatformTypeNSView) != kResultTrue)
{
[self dealloc];
return nil;
}
ViewRect vr;
if (plugView->getSize (&vr) == kResultTrue)
{
NSRect newSize = NSMakeRect (0, 0, vr.right - vr.left, vr.bottom - vr.top);
[self setFrame:newSize];
}

isAttached = YES;
UInt32 size = sizeof (FObject*);
if (AudioUnitGetProperty (audioUnit, 64001, kAudioUnitScope_Global, 0, &dynlib, &size) == noErr)
dynlib->addRef ();
}
return self;
}


//------------------------------------------------------------------------
- (void) setFrame: (NSRect) newSize
{
[super setFrame: newSize];
ViewRect viewRect (0, 0, newSize.size.width, newSize.size.height);
if (plugView)
plugView->onSize (&viewRect);
}


//------------------------------------------------------------------------
- (BOOL)isFlipped { return YES; }

//------------------------------------------------------------------------
- (void)viewDidMoveToSuperview
{
if (plugView)
{
if ([self superview])
{
if (!isAttached)
{
isAttached = plugView->attached (self, kPlatformTypeNSView) == kResultTrue;
}
}
else
{
if (isAttached)
{
plugView->removed ();
isAttached = NO;
}
}
}
}

//------------------------------------------------------------------------
- (void) dealloc
{
if (plugView)
{
if (isAttached)
{
plugView->setFrame (0);
plugView->removed ();
}
plugView->release ();
if (plugFrame)
plugFrame->release ();
if (editController)
{
Steinberg::uint32 refCount= editController->addRef ();
if (refCount == 2)
editController->terminate ();
editController->release ();
editController->release ();
editController = 0;
}
}
if (dynlib)
dynlib->release ();
[super dealloc];
}

@end

/// \endcond

+ 85
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/auresource.r View File

@@ -0,0 +1,85 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/auresource.r
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include <AudioUnit/AudioUnit.r>
#include <AudioUnit/AudioUnitCarbonView.r>

#include "audiounitconfig.h"
/* ----------------------------------------------------------------------------------------------------------------------------------------
// audiounitconfig.h needs the following definitions:
#define kAudioUnitVersion 0xFFFFFFFF // Version Number, needs to be in hex
#define kAudioUnitName "Steinberg: MyVST3 as AudioUnit" // Company Name + Effect Name
#define kAudioUnitDescription "My VST3 as AudioUnit" // Effect Description
#define kAudioUnitType kAudioUnitType_Effect // can be kAudioUnitType_Effect or kAudioUnitType_MusicDevice
#define kAudioUnitComponentSubType 'test' // unique id
#define kAudioUnitComponentManuf 'SMTG' // registered company id
#define kAudioUnitCarbonView 1 // if 0 no Carbon view support will be added
*/


#define kAudioUnitResID_Processor 1000
#define kAudioUnitResID_CarbonView 9000

//----------------------Processor----------------------------------------------

#define RES_ID kAudioUnitResID_Processor
#define COMP_TYPE kAudioUnitType
#define COMP_SUBTYPE kAudioUnitComponentSubType
#define COMP_MANUF kAudioUnitComponentManuf

#define VERSION kAudioUnitVersion
#define NAME kAudioUnitName
#define DESCRIPTION kAudioUnitDescription
#define ENTRY_POINT "AUWrapperEntry"

#include "AUResources.r"

#if kAudioUnitCarbonView
//----------------------View----------------------------------------------

#define RES_ID kAudioUnitResID_CarbonView
#define COMP_TYPE kAudioUnitCarbonViewComponentType
#define COMP_SUBTYPE kAudioUnitComponentSubType
#define COMP_MANUF kAudioUnitComponentManuf

#define VERSION kAudioUnitVersion
#define NAME "CarbonView"
#define DESCRIPTION "CarbonView"
#define ENTRY_POINT "AUCarbonViewEntry"

#include "AUResources.r"

#endif

+ 84
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/ausdk.mm View File

@@ -0,0 +1,84 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/ausdk.mm
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

#ifndef MAC_OS_X_VERSION_10_7
#define MAC_OS_X_VERSION_10_7 1070
#endif

#import "PublicUtility/CAAudioChannelLayout.cpp"
#import "PublicUtility/CABundleLocker.cpp"
#import "PublicUtility/CAHostTimeBase.cpp"
#import "PublicUtility/CAStreamBasicDescription.cpp"
#import "PublicUtility/CAVectorUnit.cpp"
#import "PublicUtility/CAAUParameter.cpp"

#import "AUPublic/AUBase/ComponentBase.cpp"
#import "AUPublic/AUBase/AUScopeElement.cpp"
#import "AUPublic/AUBase/AUOutputElement.cpp"
#import "AUPublic/AUBase/AUInputElement.cpp"
#import "AUPublic/AUBase/AUBase.cpp"

#if !__LP64__
#import "AUPublic/AUCarbonViewBase/AUCarbonViewBase.cpp"
#import "AUPublic/AUCarbonViewBase/AUCarbonViewControl.cpp"
#import "AUPublic/AUCarbonViewBase/AUCarbonViewDispatch.cpp"
#import "AUPublic/AUCarbonViewBase/AUControlGroup.cpp"
#import "AUPublic/AUCarbonViewBase/CarbonEventHandler.cpp"
#endif

#import "AUPublic/Utility/AUTimestampGenerator.cpp"
#import "AUPublic/Utility/AUBuffer.cpp"
#import "AUPublic/Utility/AUBaseHelper.cpp"

#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
#import "AUPublic/OtherBases/AUMIDIEffectBase.cpp"
#import "AUPublic/Utility/AUDebugDispatcher.cpp"
#else
#import "AUPublic/AUBase/AUPlugInDispatch.cpp"
#endif

#if !CA_USE_AUDIO_PLUGIN_ONLY
#import "AUPublic/AUBase/AUDispatch.cpp"
#import "AUPublic/OtherBases/MusicDeviceBase.cpp"
#import "AUPublic/OtherBases/AUMIDIBase.cpp"
#import "AUPublic/OtherBases/AUEffectBase.cpp"
#endif

/// \endcond

+ 340
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/auwrapper.h View File

@@ -0,0 +1,340 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/auwrapper.h
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/**
***************************
\page auwrapper AudioUnit Wrapper
***************************
\section AUIntroduction Introduction
***************************
The VST 3 SDK comes with an AudioUnit wrapper, which can wrap one VST 3 Audio Processor and Edit Controller as an AudioUnit effect/instrument.

The wrapper is a small dynamic library which loads the VST 3 Plug-in.
As AudioUnits store some important information in their resource fork, this library must be compiled for every VST 3 Plug-in.
\n\n
***************************
\section AUhowdoesitwork How does it work ?
***************************

- build the auwrapper project (public.sdk/source/vst/auwrapper/auwrapper.xcodeproj)
- create a copy of the again AU wrapper example project directory (public.sdk/source/vst/auwrapper/again/)
- rename the copy to your needs
- edit the target settings of the project and change
- Product Name
- Library search path so that it points to the directory where libauwrapper.a exists
- architecture setting so that it only includes architectures the VST 3 Plug-in supports

- search in the project for AUWRAPPER_CHANGE and change the settings to your needs, especially in :
- edit audiounitconfig.h see comments there
- edit Info.plist see comments there
- edit the "Make Links Script" for easier debugging/development
- build your project
- done... that is all!

For the release version, you must place a copy or an alias of your VST 3 Plug-in in the resource folder of the bundle named "plugin.vst3"

*/
/// \cond ignore

#pragma once

#if CA_USE_AUDIO_PLUGIN_ONLY
#include "AudioUnits/AUPublic/AUBase/AUBase.h"
#define AUWRAPPER_BASE_CLASS AUBase
#else
#include "AudioUnits/AUPublic/OtherBases/MusicDeviceBase.h"
#define AUWRAPPER_BASE_CLASS MusicDeviceBase
#endif
#include "pluginterfaces/vst/ivstaudioprocessor.h"
#include "pluginterfaces/vst/ivsteditcontroller.h"
#include "pluginterfaces/vst/ivstprocesscontext.h"
#include "pluginterfaces/vst/ivstunits.h"
#include "public.sdk/source/vst/hosting/parameterchanges.h"
#include "public.sdk/source/vst/hosting/processdata.h"
#include "public.sdk/source/vst/hosting/eventlist.h"
#include "base/source/timer.h"
#include "base/source/fstring.h"
#include "base/source/flock.h"
#include <Cocoa/Cocoa.h>
#include <AudioToolbox/AudioToolbox.h>
#include <vector>
#include <map>

namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
typedef struct MIDIMessageInfoStruct {
UInt8 status;
UInt8 channel;
UInt8 data1;
UInt8 data2;
UInt32 startFrame;
} MIDIMessageInfoStruct;

//------------------------------------------------------------------------
class MIDIOutputCallbackHelper
{
public:
MIDIOutputCallbackHelper ()
{
mMIDIMessageList.reserve (16);
mMIDICallbackStruct.midiOutputCallback = NULL;
}
virtual ~MIDIOutputCallbackHelper () {};

void SetCallbackInfo (AUMIDIOutputCallback callback, void* userData)
{
mMIDICallbackStruct.midiOutputCallback = callback;
mMIDICallbackStruct.userData = userData;
}

void AddEvent (UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2, UInt32 inStartFrame)
{
MIDIMessageInfoStruct info = {status, channel, data1, data2, inStartFrame};
mMIDIMessageList.push_back (info);
}

void FireAtTimeStamp (const AudioTimeStamp& inTimeStamp)
{
if (!mMIDIMessageList.empty () && mMIDICallbackStruct.midiOutputCallback != 0)
{
// synthesize the packet list and call the MIDIOutputCallback
// iterate through the vector and get each item
std::vector<MIDIMessageInfoStruct>::iterator myIterator;
MIDIPacketList* pktlist = PacketList ();

for (myIterator = mMIDIMessageList.begin (); myIterator != mMIDIMessageList.end (); myIterator++)
{
MIDIMessageInfoStruct item = *myIterator;
MIDIPacket* pkt = MIDIPacketListInit (pktlist);
bool tooBig = false;
Byte data[3] = { item.status, item.data1, item.data2 };
if ((pkt = MIDIPacketListAdd (pktlist, sizeof (mBuffersAllocated), pkt, item.startFrame, 4, const_cast<Byte*>(data))) == NULL)
tooBig = true;

if (tooBig)
{ // send what we have and then clear the buffer and send again
// issue the callback with what we got
OSStatus result = mMIDICallbackStruct.midiOutputCallback (mMIDICallbackStruct.userData, &inTimeStamp, 0, pktlist);
if (result != noErr)
printf ("error calling output callback: %d", (int) result);

// clear stuff we've already processed, and fire again
mMIDIMessageList.erase (mMIDIMessageList.begin (), myIterator);
this->FireAtTimeStamp (inTimeStamp);
return;
}
}
// fire callback
OSStatus result = mMIDICallbackStruct.midiOutputCallback (mMIDICallbackStruct.userData, &inTimeStamp, 0, pktlist);
if (result != noErr)
printf ("error calling output callback: %d", (int) result);

mMIDIMessageList.clear ();
}
}

protected:
typedef std::vector<MIDIMessageInfoStruct> MIDIMessageList;

private:
MIDIPacketList* PacketList () {return (MIDIPacketList*)mBuffersAllocated;}

Byte mBuffersAllocated[1024];
AUMIDIOutputCallbackStruct mMIDICallbackStruct;
MIDIMessageList mMIDIMessageList;
};


//------------------------------------------------------------------------
//------------------------------------------------------------------------
class AUWrapper
: public AUWRAPPER_BASE_CLASS
, public IComponentHandler
, public ITimerCallback
{
public:
AUWrapper (ComponentInstanceRecord* ci);
~AUWrapper ();

//---ComponentBase---------------------
ComponentResult Version () SMTG_OVERRIDE;
void PostConstructor () SMTG_OVERRIDE;

//---AUBase-----------------------------
void Cleanup () SMTG_OVERRIDE;
ComponentResult Initialize () SMTG_OVERRIDE;
AUElement* CreateElement (AudioUnitScope scope, AudioUnitElement element) SMTG_OVERRIDE;
UInt32 SupportedNumChannels (const AUChannelInfo** outInfo) SMTG_OVERRIDE;
bool StreamFormatWritable (AudioUnitScope scope, AudioUnitElement element) SMTG_OVERRIDE;
ComponentResult ChangeStreamFormat (AudioUnitScope inScope, AudioUnitElement inElement, const CAStreamBasicDescription& inPrevFormat, const CAStreamBasicDescription& inNewFormat) SMTG_OVERRIDE;
ComponentResult SetConnection (const AudioUnitConnection& inConnection) SMTG_OVERRIDE;
ComponentResult GetParameterInfo (AudioUnitScope inScope, AudioUnitParameterID inParameterID, AudioUnitParameterInfo& outParameterInfo) SMTG_OVERRIDE;
ComponentResult SetParameter (AudioUnitParameterID inID, AudioUnitScope inScope, AudioUnitElement inElement, AudioUnitParameterValue inValue, UInt32 inBufferOffsetInFrames) SMTG_OVERRIDE;

ComponentResult SaveState (CFPropertyListRef* outData) SMTG_OVERRIDE;
ComponentResult RestoreState (CFPropertyListRef inData) SMTG_OVERRIDE;

ComponentResult Render (AudioUnitRenderActionFlags &ioActionFlags, const AudioTimeStamp &inTimeStamp, UInt32 inNumberFrames) SMTG_OVERRIDE;
void processOutputEvents (const AudioTimeStamp &inTimeStamp);

int GetNumCustomUIComponents () SMTG_OVERRIDE;
void GetUIComponentDescs (ComponentDescription* inDescArray) SMTG_OVERRIDE;

ComponentResult GetPropertyInfo (AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, UInt32 &outDataSize, Boolean &outWritable) SMTG_OVERRIDE;
ComponentResult GetProperty (AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void* outData) SMTG_OVERRIDE;
ComponentResult SetProperty (AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, const void* inData, UInt32 inDataSize) SMTG_OVERRIDE;
bool CanScheduleParameters() const; // Not in the base class anymore in newer CoreAudio SDKs

Float64 GetLatency () SMTG_OVERRIDE;
Float64 GetTailTime () SMTG_OVERRIDE;

//---Factory presets
OSStatus GetPresets (CFArrayRef* outData) const SMTG_OVERRIDE;
OSStatus NewFactoryPresetSet (const AUPreset& inNewFactoryPreset) SMTG_OVERRIDE;

//---MusicDeviceBase-------------------------
ComponentResult StartNote (MusicDeviceInstrumentID inInstrument, MusicDeviceGroupID inGroupID, NoteInstanceID* outNoteInstanceID, UInt32 inOffsetSampleFrame, const MusicDeviceNoteParams &inParams) SMTG_OVERRIDE;
ComponentResult StopNote (MusicDeviceGroupID inGroupID, NoteInstanceID inNoteInstanceID, UInt32 inOffsetSampleFrame) SMTG_OVERRIDE;
OSStatus GetInstrumentCount (UInt32 &outInstCount) const SMTG_OVERRIDE;

//---AUMIDIBase------------------------------
OSStatus HandleNonNoteEvent (UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2, UInt32 inStartFrame) SMTG_OVERRIDE;
//---custom----------------------------------
void setControllerParameter (ParamID pid, ParamValue value);

// return for a given midiChannel the unitID and the ProgramListID
bool getProgramListAndUnit (int32 midiChannel, UnitID& unitId, ProgramListID& programListId);

// restore preset state, add StateType "Project" to stream if loading from project
ComponentResult restoreState (CFPropertyListRef inData, bool fromProject);

//------------------------------------------------------------------------
#if !CA_USE_AUDIO_PLUGIN_ONLY
static ComponentResult ComponentEntryDispatch (ComponentParameters* params, AUWrapper* This);
#endif
//------------------------------------------------------------------------
static CFBundleRef gBundleRef;
//------------------------------------------------------------------------
DECLARE_FUNKNOWN_METHODS

protected:
//---from IComponentHandler-------------------
tresult PLUGIN_API beginEdit (ParamID tag) SMTG_OVERRIDE;
tresult PLUGIN_API performEdit (ParamID tag, ParamValue valueNormalized) SMTG_OVERRIDE;
tresult PLUGIN_API endEdit (ParamID tag) SMTG_OVERRIDE;
tresult PLUGIN_API restartComponent (int32 flags) SMTG_OVERRIDE;

//---from ITimerCallback----------------------
void onTimer (Timer* timer) SMTG_OVERRIDE;

// internal helpers
double getSampleRate () const { return sampleRate; }
void updateProcessContext ();
void syncParameterValues ();
void cacheParameterValues ();
void clearParameterValueCache ();
virtual IPluginFactory* getFactory ();
void loadVST3Module ();
void unloadVST3Module ();
bool validateChannelPair (int inChannelsIn, int inChannelsOut, const AUChannelInfo* info, UInt32 numChanInfo) const;


IAudioProcessor* audioProcessor;
IEditController* editController;
IMidiMapping* midiMapping;

Timer* timer;

HostProcessData processData;
ParameterChanges processParamChanges;
ParameterChanges outputParamChanges;
ParameterChangeTransfer transferParamChanges;
ParameterChangeTransfer outputParamTransfer;
ProcessContext processContext;
EventList eventList;

typedef std::map<uint32, AudioUnitParameterInfo> CachedParameterInfoMap;
typedef std::map<UnitID, UnitInfo> UnitInfoMap;
typedef std::vector<String> ClumpGroupVector;

UnitInfoMap unitInfos;
ClumpGroupVector clumpGroups;
CachedParameterInfoMap cachedParameterInfos;
FLock parameterCacheChanging;

NoteInstanceID noteCounter;
double sampleRate;
ParamID bypassParamID;

AUPreset* presets;
int32 numPresets;
ParamID factoryProgramChangedID;

bool isInstrument;
bool isBypassed;

AUParameterListenerRef paramListenerRef;
static const int32 kMaxProgramChangeParameters = 16;
ParamID programChangeParameters[kMaxProgramChangeParameters]; // for each midi channel

int32 midiOutCount; // currently only 0 or 1 supported
MIDIOutputCallbackHelper mCallbackHelper;
EventList outputEvents;
private:
void buildUnitInfos (IUnitInfo* unitInfoController, UnitInfoMap& units) const;
};

//------------------------------------------------------------------------
class AutoreleasePool
{
public:
AutoreleasePool () { ap = [[NSAutoreleasePool alloc] init]; }
~AutoreleasePool () { [ap drain]; }
//------------------------------------------------------------------------
protected:
NSAutoreleasePool* ap;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

/// \endcond

+ 2582
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/auwrapper.mm
File diff suppressed because it is too large
View File


+ 38
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/auwrapper_prefix.pch View File

@@ -0,0 +1,38 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/auwrapper/auwrapper_prefix.pch
// Created by : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include <CoreFoundation/CoreFoundation.h>
#include <CoreAudio/CoreAudio.h>

+ 38
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/config/ausdkpath.xcconfig View File

@@ -0,0 +1,38 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : ausdkpath.xcconfig
// Created by : Steinberg, 5/24/12
// Description : Xcode configuration file to specify paths to the AU SDK files, VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

// If you are building with Xcode >= 4.x please add the path to your downloaded Audio Tools for Xcode
CUSTOM_AU_SDK_PATH=/Applications/Xcode.app/Contents/Developer/Extras/CoreAudio/ // AUWRAPPER_CHANGE

+ 44
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/config/auwrapper.xcconfig View File

@@ -0,0 +1,44 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : auwrapper.xcconfig
// Created by : Steinberg, 5/24/12
// Description : Xcode configuration file to specify paths to the AU SDK files, VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "../../../../../base/mac/config/libc++base"
#include "ausdkpath"

PRODUCT_NAME = auwrapper

HEADER_SEARCH_PATHS = ../../../../ $(CUSTOM_AU_SDK_PATH)/** $(DEVELOPER_DIR)/Examples/CoreAudio/** $(DEVELOPER_DIR)/Extras/CoreAudio/** $(DEVELOPER_DIR)/Extras/CoreAudio/AudioUnits/AUPublic/AUViewBase/** ../../../../libraries/source/CoreAudio/**
GCC_PREFIX_HEADER = auwrapper_prefix.pch
GCC_PRECOMPILE_PREFIX_HEADER = YES

+ 40
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/config/auwrapper_debug.xcconfig View File

@@ -0,0 +1,40 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : ausdkpath_debug.xcconfig
// Created by : Steinberg, 5/24/12
// Description : Xcode configuration file to specify paths to the AU SDK files, VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "../../../../../base/mac/config/debug"

GCC_OPTIMIZATION_LEVEL = 0
DEPLOYMENT_POSTPROCESSING = NO

+ 40
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/config/auwrapper_release.xcconfig View File

@@ -0,0 +1,40 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : auwrapper_release.xcconfig
// Created by : Steinberg, 5/24/12
// Description : Xcode configuration file to specify paths to the AU SDK files, VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "../../../../../base/mac/config/release"

GCC_OPTIMIZATION_LEVEL = 3
DEPLOYMENT_POSTPROCESSING = NO

+ 23
- 0
source/includes/vst3sdk/public.sdk/source/vst/auwrapper/generateCocoaClassNamePrefix.rb View File

@@ -0,0 +1,23 @@
#!/usr/bin/ruby

require 'time'

cocoaClassPrefixDir=ARGV[0]

cocoaClassPrefixDir = ARGV[0]
if cocoaClassPrefixDir == nil
$stdout << "Cannot resolve output directory\n"
exit(-1)
end

$stdout << "Generating new class prefix for Objective-C classes in #{cocoaClassPrefixDir}\n"
File.open("#{cocoaClassPrefixDir}/aucocoaclassprefix.h", "w+") do |stream|
t = Time.now.to_i
t.round
id = t.to_s
stream << "#define SMTG_AU_NAMESPACE\t"
stream << "SMTGAUCocoa#{id}_\n"
end


+ 105
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/eventlist.cpp View File

@@ -0,0 +1,105 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/eventlist.cpp
// Created by : Steinberg, 03/05/2008.
// Description : VST 3 event list implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "eventlist.h"

namespace Steinberg {
namespace Vst {

//-----------------------------------------------------------------------------
IMPLEMENT_FUNKNOWN_METHODS (EventList, IEventList, IEventList::iid)

//-----------------------------------------------------------------------------
EventList::EventList (int32 maxSize) : events (nullptr), maxSize (maxSize), fillCount (0)
{
FUNKNOWN_CTOR
setMaxSize (maxSize);
}

//-----------------------------------------------------------------------------
EventList::~EventList ()
{
setMaxSize (0);
FUNKNOWN_DTOR
}

//-----------------------------------------------------------------------------
void EventList::setMaxSize (int32 _maxSize)
{
if (events)
{
delete[] events;
events = nullptr;
}
if (_maxSize > 0)
events = new Event[_maxSize];
maxSize = _maxSize;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API EventList::getEvent (int32 index, Event& e)
{
if (fillCount > index)
{
memcpy (&e, &events[index], sizeof (Event));
return kResultTrue;
}
return kResultFalse;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API EventList::addEvent (Event& e)
{
if (maxSize > fillCount)
{
memcpy (&events[fillCount], &e, sizeof (Event));
fillCount++;
return kResultTrue;
}
return kResultFalse;
}

//-----------------------------------------------------------------------------
Event* EventList::getEventByIndex (int32 index)
{
if (index < fillCount)
return &events[index];
return nullptr;
}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 73
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/eventlist.h View File

@@ -0,0 +1,73 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/eventlist.h
// Created by : Steinberg, 03/05/2008.
// Description : VST 3 event list implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/vst/ivstevents.h"

namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
/** Implementation's example of IEventList.
\ingroup sdkBase
*/
class EventList : public IEventList
{
public:
EventList (int32 maxSize = 50);
virtual ~EventList ();

void clear () { fillCount = 0; }

int32 PLUGIN_API getEventCount () SMTG_OVERRIDE { return fillCount; }
tresult PLUGIN_API getEvent (int32 index, Event& e) SMTG_OVERRIDE;
tresult PLUGIN_API addEvent (Event& e) SMTG_OVERRIDE;

Event* getEventByIndex (int32 index);
void setMaxSize (int32 maxSize);

//------------------------------------------------------------------------
DECLARE_FUNKNOWN_METHODS
protected:
Event* events;
int32 maxSize;
int32 fillCount;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 316
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/hostclasses.cpp View File

@@ -0,0 +1,316 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/hostclasses.cpp
// Created by : Steinberg, 03/05/2008.
// Description : VST 3 hostclasses, example implementations for IHostApplication, IAttributeList and IMessage
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "hostclasses.h"

#include <algorithm>

namespace Steinberg {
namespace Vst {

//-----------------------------------------------------------------------------
tresult PLUGIN_API HostApplication::getName (String128 name)
{
String str ("My VST3 HostApplication");
str.copyTo16 (name, 0, 127);
return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API HostApplication::createInstance (TUID cid, TUID _iid, void** obj)
{
FUID classID (cid);
FUID interfaceID (_iid);
if (classID == IMessage::iid && interfaceID == IMessage::iid)
{
*obj = new HostMessage;
return kResultTrue;
}
else if (classID == IAttributeList::iid && interfaceID == IAttributeList::iid)
{
*obj = new HostAttributeList;
return kResultTrue;
}
*obj = 0;
return kResultFalse;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API HostApplication::queryInterface (const char* _iid, void** obj)
{
QUERY_INTERFACE (_iid, obj, FUnknown::iid, IHostApplication)
QUERY_INTERFACE (_iid, obj, IHostApplication::iid, IHostApplication)
*obj = 0;
return kResultFalse;
}

//-----------------------------------------------------------------------------
uint32 PLUGIN_API HostApplication::addRef ()
{
return 1;
}

//-----------------------------------------------------------------------------
uint32 PLUGIN_API HostApplication::release ()
{
return 1;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
IMPLEMENT_FUNKNOWN_METHODS (HostMessage, IMessage, IMessage::iid)
//-----------------------------------------------------------------------------
HostMessage::HostMessage () : messageId (0), attributeList (0)
{
FUNKNOWN_CTOR
}

//-----------------------------------------------------------------------------
HostMessage::~HostMessage ()
{
setMessageID (0);
if (attributeList)
attributeList->release ();
FUNKNOWN_DTOR
}

//-----------------------------------------------------------------------------
const char* PLUGIN_API HostMessage::getMessageID ()
{
return messageId;
}

//-----------------------------------------------------------------------------
void PLUGIN_API HostMessage::setMessageID (const char* mid)
{
if (messageId)
delete[] messageId;
messageId = 0;
if (mid)
{
size_t len = strlen (mid) + 1;
messageId = new char[len];
strcpy (messageId, mid);
}
}

//-----------------------------------------------------------------------------
IAttributeList* PLUGIN_API HostMessage::getAttributes ()
{
if (!attributeList)
attributeList = new HostAttributeList;
return attributeList;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
class HostAttribute
{
public:
enum Type
{
kInteger,
kFloat,
kString,
kBinary
};

HostAttribute (int64 value) : size (0), type (kInteger) { v.intValue = value; }
HostAttribute (double value) : size (0), type (kFloat) { v.floatValue = value; }
HostAttribute (const TChar* value, uint32 size) : size (size), type (kString)
{
v.stringValue = new TChar[size];
memcpy (v.stringValue, value, size * sizeof (TChar));
}
HostAttribute (const void* value, uint32 size) : size (size), type (kBinary)
{
v.binaryValue = new char[size];
memcpy (v.binaryValue, value, size);
}
~HostAttribute ()
{
if (size)
delete[] v.binaryValue;
}

int64 intValue () const { return v.intValue; }
double floatValue () const { return v.floatValue; }
const TChar* stringValue (uint32& stringSize)
{
stringSize = size;
return v.stringValue;
}
const void* binaryValue (uint32& binarySize)
{
binarySize = size;
return v.binaryValue;
}

Type getType () const { return type; }

protected:
union v
{
int64 intValue;
double floatValue;
TChar* stringValue;
char* binaryValue;
} v;
uint32 size;
Type type;
};

typedef std::map<String, HostAttribute*>::iterator mapIterator;

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
IMPLEMENT_FUNKNOWN_METHODS (HostAttributeList, IAttributeList, IAttributeList::iid)
//-----------------------------------------------------------------------------
HostAttributeList::HostAttributeList ()
{
FUNKNOWN_CTOR
}

//-----------------------------------------------------------------------------
HostAttributeList::~HostAttributeList ()
{
std::map<String, HostAttribute*>::reverse_iterator it = list.rbegin ();
while (it != list.rend ())
{
delete it->second;
it++;
}
FUNKNOWN_DTOR
}

//-----------------------------------------------------------------------------
void HostAttributeList::removeAttrID (AttrID aid)
{
mapIterator it = list.find (aid);
if (it != list.end ())
{
delete it->second;
list.erase (it);
}
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API HostAttributeList::setInt (AttrID aid, int64 value)
{
removeAttrID (aid);
list[aid] = new HostAttribute (value);
return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API HostAttributeList::getInt (AttrID aid, int64& value)
{
mapIterator it = list.find (aid);
if (it != list.end () && it->second)
{
value = it->second->intValue ();
return kResultTrue;
}
return kResultFalse;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API HostAttributeList::setFloat (AttrID aid, double value)
{
removeAttrID (aid);
list[aid] = new HostAttribute (value);
return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API HostAttributeList::getFloat (AttrID aid, double& value)
{
mapIterator it = list.find (aid);
if (it != list.end () && it->second)
{
value = it->second->floatValue ();
return kResultTrue;
}
return kResultFalse;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API HostAttributeList::setString (AttrID aid, const TChar* string)
{
removeAttrID (aid);
list[aid] = new HostAttribute (string, String (const_cast<TChar*> (string)).length ());
return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API HostAttributeList::getString (AttrID aid, TChar* string, uint32 size)
{
mapIterator it = list.find (aid);
if (it != list.end () && it->second)
{
uint32 stringSize = 0;
const TChar* _string = it->second->stringValue (stringSize);
memcpy (string, _string, std::min<uint32> (stringSize, size) * sizeof (TChar));
return kResultTrue;
}
return kResultFalse;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API HostAttributeList::setBinary (AttrID aid, const void* data, uint32 size)
{
removeAttrID (aid);
list[aid] = new HostAttribute (data, size);
return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API HostAttributeList::getBinary (AttrID aid, const void*& data, uint32& size)
{
mapIterator it = list.find (aid);
if (it != list.end () && it->second)
{
data = it->second->binaryValue (size);
return kResultTrue;
}
size = 0;
return kResultFalse;
}
}
} // namespace

+ 112
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/hostclasses.h View File

@@ -0,0 +1,112 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/hostclasses.h
// Created by : Steinberg, 03/05/2008.
// Description : VST 3 hostclasses, example implementations for IHostApplication, IAttributeList and IMessage
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/vst/ivsthostapplication.h"

#include "base/source/fstring.h"

#include <map>

namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
/** Implementation's example of IHostApplication.
\ingroup hostingBase
*/
class HostApplication : public IHostApplication
{
public:
HostApplication () { FUNKNOWN_CTOR }
virtual ~HostApplication () { FUNKNOWN_DTOR }

tresult PLUGIN_API getName (String128 name) SMTG_OVERRIDE;
tresult PLUGIN_API createInstance (TUID cid, TUID _iid, void** obj) SMTG_OVERRIDE;

DECLARE_FUNKNOWN_METHODS
};

class HostAttribute;
//------------------------------------------------------------------------
/** Implementation's example of IAttributeList.
\ingroup hostingBase
*/
class HostAttributeList : public IAttributeList
{
public:
HostAttributeList ();
virtual ~HostAttributeList ();

tresult PLUGIN_API setInt (AttrID aid, int64 value) SMTG_OVERRIDE;
tresult PLUGIN_API getInt (AttrID aid, int64& value) SMTG_OVERRIDE;
tresult PLUGIN_API setFloat (AttrID aid, double value) SMTG_OVERRIDE;
tresult PLUGIN_API getFloat (AttrID aid, double& value) SMTG_OVERRIDE;
tresult PLUGIN_API setString (AttrID aid, const TChar* string) SMTG_OVERRIDE;
tresult PLUGIN_API getString (AttrID aid, TChar* string, uint32 size) SMTG_OVERRIDE;
tresult PLUGIN_API setBinary (AttrID aid, const void* data, uint32 size) SMTG_OVERRIDE;
tresult PLUGIN_API getBinary (AttrID aid, const void*& data, uint32& size) SMTG_OVERRIDE;

DECLARE_FUNKNOWN_METHODS
protected:
void removeAttrID (AttrID aid);
std::map<String, HostAttribute*> list;
};

//------------------------------------------------------------------------
/** Implementation's example of IMessage.
\ingroup hostingBase
*/
class HostMessage : public IMessage
{
public:
HostMessage ();
virtual ~HostMessage ();

const char* PLUGIN_API getMessageID () SMTG_OVERRIDE;
void PLUGIN_API setMessageID (const char* messageID) SMTG_OVERRIDE;
IAttributeList* PLUGIN_API getAttributes () SMTG_OVERRIDE;

DECLARE_FUNKNOWN_METHODS
protected:
char* messageId;
HostAttributeList* attributeList;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 284
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/module.cpp View File

@@ -0,0 +1,284 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/module.cpp
// Created by : Steinberg, 08/2016
// Description : hosting module classes
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "module.h"
#include "stringconvert.h"
#include <sstream>
#include <utility>

//------------------------------------------------------------------------
namespace VST3 {
namespace Hosting {

//------------------------------------------------------------------------
FactoryInfo::FactoryInfo (PFactoryInfo&& other) noexcept
{
*this = std::move (other);
}

//------------------------------------------------------------------------
FactoryInfo& FactoryInfo::operator= (FactoryInfo&& other) noexcept
{
info = std::move (other.info);
other.info = {};
return *this;
}

//------------------------------------------------------------------------
FactoryInfo& FactoryInfo::operator= (PFactoryInfo&& other) noexcept
{
info = std::move (other);
other = {};
return *this;
}

//------------------------------------------------------------------------
std::string FactoryInfo::vendor () const noexcept
{
return StringConvert::convert (info.vendor, PFactoryInfo::kNameSize);
}

//------------------------------------------------------------------------
std::string FactoryInfo::url () const noexcept
{
return StringConvert::convert (info.url, PFactoryInfo::kURLSize);
}

//------------------------------------------------------------------------
std::string FactoryInfo::email () const noexcept
{
return StringConvert::convert (info.email, PFactoryInfo::kEmailSize);
}

//------------------------------------------------------------------------
Steinberg::int32 FactoryInfo::flags () const noexcept
{
return info.flags;
}

//------------------------------------------------------------------------
bool FactoryInfo::classesDiscardable () const noexcept
{
return (info.flags & PFactoryInfo::kClassesDiscardable) != 0;
}

//------------------------------------------------------------------------
bool FactoryInfo::licenseCheck () const noexcept
{
return (info.flags & PFactoryInfo::kLicenseCheck) != 0;
}

//------------------------------------------------------------------------
bool FactoryInfo::componentNonDiscardable () const noexcept
{
return (info.flags & PFactoryInfo::kComponentNonDiscardable) != 0;
}

//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
PluginFactory::PluginFactory (const PluginFactoryPtr& factory) noexcept : factory (factory)
{
}

//------------------------------------------------------------------------
void PluginFactory::setHostContext (Steinberg::FUnknown* context) const noexcept
{
if (auto f = Steinberg::FUnknownPtr<Steinberg::IPluginFactory3> (factory))
f->setHostContext (context);
}

//------------------------------------------------------------------------
FactoryInfo PluginFactory::info () const noexcept
{
Steinberg::PFactoryInfo i;
factory->getFactoryInfo (&i);
return FactoryInfo (std::move (i));
}

//------------------------------------------------------------------------
uint32_t PluginFactory::classCount () const noexcept
{
auto count = factory->countClasses ();
assert (count >= 0);
return static_cast<uint32_t> (count);
}

//------------------------------------------------------------------------
PluginFactory::ClassInfos PluginFactory::classInfos () const noexcept
{
auto count = classCount ();
ClassInfos classes;
classes.reserve (count);
auto f3 = Steinberg::FUnknownPtr<Steinberg::IPluginFactory3> (factory);
auto f2 = Steinberg::FUnknownPtr<Steinberg::IPluginFactory2> (factory);
Steinberg::PClassInfo ci;
Steinberg::PClassInfo2 ci2;
Steinberg::PClassInfoW ci3;
for (uint32_t i = 0; i < count; ++i)
{
if (f3 && f3->getClassInfoUnicode (i, &ci3) == Steinberg::kResultTrue)
classes.emplace_back (ci3);
else if (f2 && f2->getClassInfo2 (i, &ci2) == Steinberg::kResultTrue)
classes.emplace_back (ci2);
else if (factory->getClassInfo (i, &ci) == Steinberg::kResultTrue)
classes.emplace_back (ci);
auto& classInfo = classes.back ();
if (classInfo.vendor ().empty ())
classInfo.get ().vendor = info ().vendor ();
}
return classes;
}

//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
const UID& ClassInfo::ID () const noexcept
{
return data.classID;
}

//------------------------------------------------------------------------
int32_t ClassInfo::cardinality () const noexcept
{
return data.cardinality;
}

//------------------------------------------------------------------------
const std::string& ClassInfo::category () const noexcept
{
return data.category;
}

//------------------------------------------------------------------------
const std::string& ClassInfo::name () const noexcept
{
return data.name;
}

//------------------------------------------------------------------------
const std::string& ClassInfo::vendor () const noexcept
{
return data.vendor;
}

//------------------------------------------------------------------------
const std::string& ClassInfo::version () const noexcept
{
return data.version;
}

//------------------------------------------------------------------------
const std::string& ClassInfo::sdkVersion () const noexcept
{
return data.sdkVersion;
}

//------------------------------------------------------------------------
const ClassInfo::SubCategories& ClassInfo::subCategories () const noexcept
{
return data.subCategories;
}

//------------------------------------------------------------------------
Steinberg::uint32 ClassInfo::classFlags () const noexcept
{
return data.classFlags;
}

//------------------------------------------------------------------------
ClassInfo::ClassInfo (const PClassInfo& info) noexcept
{
data.classID = info.cid;
data.cardinality = info.cardinality;
data.category = StringConvert::convert (info.category, PClassInfo::kCategorySize);
data.name = StringConvert::convert (info.name, PClassInfo::kNameSize);
}

//------------------------------------------------------------------------
ClassInfo::ClassInfo (const PClassInfo2& info) noexcept
{
data.classID = info.cid;
data.cardinality = info.cardinality;
data.category = StringConvert::convert (info.category, PClassInfo::kCategorySize);
data.name = StringConvert::convert (info.name, PClassInfo::kNameSize);
data.vendor = StringConvert::convert (info.vendor, PClassInfo2::kVendorSize);
data.version = StringConvert::convert (info.version, PClassInfo2::kVersionSize);
data.sdkVersion = StringConvert::convert (info.sdkVersion, PClassInfo2::kVersionSize);
parseSubCategories (
StringConvert::convert (info.subCategories, PClassInfo2::kSubCategoriesSize));
data.classFlags = info.classFlags;
}

//------------------------------------------------------------------------
ClassInfo::ClassInfo (const PClassInfoW& info) noexcept
{
data.classID = info.cid;
data.cardinality = info.cardinality;
data.category = StringConvert::convert (info.category, PClassInfo::kCategorySize);
data.name = StringConvert::convert (info.name, PClassInfo::kNameSize);
data.vendor = StringConvert::convert (info.vendor, PClassInfo2::kVendorSize);
data.version = StringConvert::convert (info.version, PClassInfo2::kVersionSize);
data.sdkVersion = StringConvert::convert (info.sdkVersion, PClassInfo2::kVersionSize);
parseSubCategories (
StringConvert::convert (info.subCategories, PClassInfo2::kSubCategoriesSize));
data.classFlags = info.classFlags;
}

//------------------------------------------------------------------------
void ClassInfo::parseSubCategories (const std::string& str) noexcept
{
std::stringstream stream (str);
std::string item;
while (std::getline (stream, item, '|'))
data.subCategories.emplace_back (move (item));
}

//------------------------------------------------------------------------
std::string ClassInfo::subCategoriesString () const noexcept
{
std::string result;
if (data.subCategories.empty ())
return result;
result = data.subCategories[0];
for (auto index = 1u; index < data.subCategories.size (); ++index)
result += "|" + data.subCategories[index];
return result;
}

//------------------------------------------------------------------------
} // Hosting
} // VST3

+ 193
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/module.h View File

@@ -0,0 +1,193 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/module.h
// Created by : Steinberg, 08/2016
// Description : hosting module classes
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "uid.h"
#include "pluginterfaces/base/ipluginbase.h"
#include <utility>
#include <vector>

//------------------------------------------------------------------------
namespace VST3 {
namespace Hosting {

//------------------------------------------------------------------------
class FactoryInfo
{
public:
//------------------------------------------------------------------------
using PFactoryInfo = Steinberg::PFactoryInfo;

FactoryInfo () noexcept {}
~FactoryInfo () noexcept {}
FactoryInfo (const FactoryInfo&) noexcept = default;
FactoryInfo (PFactoryInfo&&) noexcept;
FactoryInfo (FactoryInfo&&) noexcept = default;
FactoryInfo& operator= (const FactoryInfo&) noexcept = default;
FactoryInfo& operator= (FactoryInfo&&) noexcept;
FactoryInfo& operator= (PFactoryInfo&&) noexcept;

std::string vendor () const noexcept;
std::string url () const noexcept;
std::string email () const noexcept;
Steinberg::int32 flags () const noexcept;
bool classesDiscardable () const noexcept;
bool licenseCheck () const noexcept;
bool componentNonDiscardable () const noexcept;

PFactoryInfo& get () noexcept { return info; }
//------------------------------------------------------------------------
private:
PFactoryInfo info {};
};

//------------------------------------------------------------------------
class ClassInfo
{
public:
//------------------------------------------------------------------------
using SubCategories = std::vector<std::string>;
using PClassInfo = Steinberg::PClassInfo;
using PClassInfo2 = Steinberg::PClassInfo2;
using PClassInfoW = Steinberg::PClassInfoW;

//------------------------------------------------------------------------
ClassInfo () noexcept {}
explicit ClassInfo (const PClassInfo& info) noexcept;
explicit ClassInfo (const PClassInfo2& info) noexcept;
explicit ClassInfo (const PClassInfoW& info) noexcept;
ClassInfo (const ClassInfo&) = default;
ClassInfo& operator= (const ClassInfo&) = default;
ClassInfo (ClassInfo&&) = default;
ClassInfo& operator= (ClassInfo&&) = default;

const UID& ID () const noexcept;
int32_t cardinality () const noexcept;
const std::string& category () const noexcept;
const std::string& name () const noexcept;
const std::string& vendor () const noexcept;
const std::string& version () const noexcept;
const std::string& sdkVersion () const noexcept;
const SubCategories& subCategories () const noexcept;
std::string subCategoriesString () const noexcept;
Steinberg::uint32 classFlags () const noexcept;

struct Data
{
UID classID;
int32_t cardinality;
std::string category;
std::string name;
std::string vendor;
std::string version;
std::string sdkVersion;
SubCategories subCategories;
Steinberg::uint32 classFlags = 0;
};

Data& get () noexcept { return data; }
//------------------------------------------------------------------------
private:
void parseSubCategories (const std::string& str) noexcept;
Data data {};
};

//------------------------------------------------------------------------
class PluginFactory
{
public:
//------------------------------------------------------------------------
using ClassInfos = std::vector<ClassInfo>;
using PluginFactoryPtr = Steinberg::IPtr<Steinberg::IPluginFactory>;

//------------------------------------------------------------------------
explicit PluginFactory (const PluginFactoryPtr& factory) noexcept;

void setHostContext (Steinberg::FUnknown* context) const noexcept;

FactoryInfo info () const noexcept;
uint32_t classCount () const noexcept;
ClassInfos classInfos () const noexcept;

template <typename T>
Steinberg::IPtr<T> createInstance (const UID& classID) const noexcept;

const PluginFactoryPtr& get () const noexcept { return factory; }
//------------------------------------------------------------------------
private:
PluginFactoryPtr factory;
};

//------------------------------------------------------------------------
class Module
{
public:
//------------------------------------------------------------------------
using Ptr = std::shared_ptr<Module>;
using PathList = std::vector<std::string>;

//------------------------------------------------------------------------
static Ptr create (const std::string& path, std::string& errorDescription);
static PathList getModulePaths ();

const std::string& getName () const noexcept { return name; }
const std::string& getPath () const noexcept { return path; }
const PluginFactory& getFactory () const noexcept { return factory; }
//------------------------------------------------------------------------
protected:
virtual ~Module () noexcept = default;
virtual bool load (const std::string& path, std::string& errorDescription) = 0;

PluginFactory factory {nullptr};
std::string name;
std::string path;
};

//------------------------------------------------------------------------
template <typename T>
inline Steinberg::IPtr<T> PluginFactory::createInstance (const UID& classID) const noexcept
{
T* obj = nullptr;
if (factory->createInstance (classID.data (), T::iid, reinterpret_cast<void**> (&obj)) ==
Steinberg::kResultTrue)
return Steinberg::owned (obj);
return nullptr;
}

//------------------------------------------------------------------------
} // Hosting
} // VST3

+ 277
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/module_linux.cpp View File

@@ -0,0 +1,277 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category :
// Filename : public.sdk/source/vst/hosting/module_linux.cpp
// Created by : Steinberg, 08/2016
// Description : hosting module classes (linux implementation)
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "stringconvert.h"
#include "module.h"
#include "optional.h"
#include <dlfcn.h>
#include <algorithm>
#include <experimental/filesystem>
#include <sys/utsname.h>
#include <sys/types.h>
#include <unistd.h>

//------------------------------------------------------------------------
extern "C" {
typedef bool (PLUGIN_API* ModuleEntryFunc) (void*);
typedef bool (PLUGIN_API* ModuleExitFunc) ();
}

//------------------------------------------------------------------------
namespace VST3 {
namespace Hosting {

//------------------------------------------------------------------------
namespace {

//------------------------------------------------------------------------
Optional<std::string> getCurrentMachineName ()
{
struct utsname unameData;

int res = uname (&unameData);
if (res != 0)
return {};

return {unameData.machine};
}

using Path = std::experimental::filesystem::path;
//------------------------------------------------------------------------
Optional<Path> getApplicationPath ()
{
std::string appPath = "";

pid_t pid = getpid ();
char buf[10];
sprintf (buf, "%d", pid);
std::string _link = "/proc/";
_link.append (buf);
_link.append ("/exe");
char proc[1024];
int ch = readlink (_link.c_str (), proc, 1024);
if (ch == -1)
return {};

proc[ch] = 0;
appPath = proc;
std::string::size_type t = appPath.find_last_of ("/");
appPath = appPath.substr (0, t);

return Path {appPath};
}

//------------------------------------------------------------------------
class LinuxModule : public Module
{
public:
template <typename T>
T getFunctionPointer (const char* name)
{
return reinterpret_cast<T> (dlsym (module, name));
}

~LinuxModule ()
{
factory = PluginFactory (nullptr);

if (module)
{
if (auto moduleExit = getFunctionPointer<ModuleExitFunc> ("ModuleExit"))
moduleExit ();

dlclose (module);
}
}

static Optional<Path> getSOPath (const std::string& inPath)
{
using namespace std::experimental;

Path modulePath {inPath};
if (!filesystem::is_directory (modulePath))
return {};

auto stem = modulePath.stem ();

modulePath /= "Contents";
if (!filesystem::is_directory (modulePath))
return {};

auto machine = getCurrentMachineName ();
if (!machine)
return {};

modulePath /= *machine + "-linux";
if (!filesystem::is_directory (modulePath))
return {};

stem.replace_extension (".so");
modulePath /= stem;
return Optional<Path> (std::move (modulePath));
}

bool load (const std::string& inPath, std::string& errorDescription) override
{
auto modulePath = getSOPath (inPath);
if (!modulePath)
{
errorDescription = inPath + " is not a module directory.";
return false;
}

module = dlopen (modulePath->generic_u8string ().data (), RTLD_LAZY);
if (!module)
{
errorDescription = "dlopen failed.\n";
errorDescription += dlerror ();
return false;
}

auto factoryProc = getFunctionPointer<GetFactoryProc> ("GetPluginFactory");
if (!factoryProc)
{
errorDescription =
"The shared library does not export the required 'GetPluginFactory' function";
return false;
}
auto moduleEntry = getFunctionPointer<ModuleEntryFunc> ("ModuleEntry");
if (!moduleEntry)
{
errorDescription =
"The shared library does not export the required 'ModuleEntry' function";
return false;
}
if (!moduleEntry (module))
{
errorDescription = "Calling 'ModuleEntry' failed";
return false;
}
auto f = Steinberg::FUnknownPtr<Steinberg::IPluginFactory> (factoryProc ());
if (!f)
{
errorDescription = "Calling 'GetPluginFactory' returned nullptr";
return false;
}
factory = PluginFactory (f);
return true;
}

void* module {nullptr};
};

//------------------------------------------------------------------------
void findFilesWithExt (const std::string& path, const std::string& ext, Module::PathList& pathList)
{
try
{
using namespace std::experimental;
for (auto& p : filesystem::recursive_directory_iterator (path))
{
if (p.path ().extension () == ext && filesystem::is_directory (p))
{
pathList.push_back (p.path ().generic_u8string ());
}
}
}
catch (...)
{
}
}

//------------------------------------------------------------------------
void findModules (const std::string& path, Module::PathList& pathList)
{
findFilesWithExt (path, ".vst3", pathList);
}

//------------------------------------------------------------------------
} // anonymous

//------------------------------------------------------------------------
Module::Ptr Module::create (const std::string& path, std::string& errorDescription)
{
auto module = std::make_shared<LinuxModule> ();
if (module->load (path, errorDescription))
{
auto it = std::find_if (path.rbegin (), path.rend (),
[] (const std::string::value_type& c) { return c == '/'; });
if (it != path.rend ())
module->name = {it.base (), path.end ()};
return module;
}
return nullptr;
}

//------------------------------------------------------------------------
Module::PathList Module::getModulePaths ()
{
/* VST3 component locations on linux :
* User privately installed : $HOME/.vst3/
* Distribution installed : /usr/lib/vst3/
* Locally installed : /usr/local/lib/vst3/
* Application : /$APPFOLDER/vst3/
*/

const auto systemPaths = {"/usr/lib/vst3/", "/usr/local/lib/vst3/"};

// 32bit Plug-ins on 64bit OS
// const auto systemPaths = {"/usr/lib32/vst3/", "/usr/local/lib32/vst3/"};

PathList list;
if (auto homeDir = getenv ("HOME"))
{
std::experimental::filesystem::path homePath (homeDir);
homePath /= ".vst3";
findModules (homePath.generic_u8string (), list);
}
for (auto path : systemPaths)
findModules (path, list);

// application level
auto appPath = getApplicationPath ();
if (appPath)
{
*appPath /= "vst3";
findModules (appPath->generic_u8string (), list);
}

return list;
}

//------------------------------------------------------------------------
} // Hosting
} // VST3

+ 299
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/module_mac.mm View File

@@ -0,0 +1,299 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/module_mac.mm
// Created by : Steinberg, 08/2016
// Description : hosting module classes (macOS implementation)
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import "module.h"

#import <Cocoa/Cocoa.h>
#import <CoreFoundation/CoreFoundation.h>

//------------------------------------------------------------------------
extern "C" {
typedef bool (*BundleEntryFunc) (CFBundleRef);
typedef bool (*BundleExitFunc) ();
}

//------------------------------------------------------------------------
namespace VST3 {
namespace Hosting {

//------------------------------------------------------------------------
namespace {

//------------------------------------------------------------------------
template <typename T>
class CFPtr
{
public:
inline CFPtr (const T& obj = nullptr) : obj (obj) {}
inline CFPtr (CFPtr&& other) { *this = other; }
inline ~CFPtr ()
{
if (obj)
CFRelease (obj);
}

inline CFPtr& operator= (CFPtr&& other)
{
obj = other.obj;
other.obj = nullptr;
return *this;
}
inline CFPtr& operator= (const T& o)
{
if (obj)
CFRelease (obj);
obj = o;
return *this;
}
inline operator T () const { return obj; } // act as T
private:
CFPtr (const CFPtr& other) = delete;
CFPtr& operator= (const CFPtr& other) = delete;

T obj = nullptr;
};

//------------------------------------------------------------------------
class MacModule : public Module
{
public:
template <typename T>
T getFunctionPointer (const char* name)
{
assert (bundle);
CFPtr<CFStringRef> functionName {
CFStringCreateWithCString (kCFAllocatorDefault, name, kCFStringEncodingASCII)};
return reinterpret_cast<T> (CFBundleGetFunctionPointerForName (bundle, functionName));
}

bool loadInternal (const std::string& path, std::string& errorDescription)
{
CFPtr<CFURLRef> url (CFURLCreateFromFileSystemRepresentation (
kCFAllocatorDefault, reinterpret_cast<const UInt8*> (path.data ()), path.length (),
true));
if (!url)
return false;
bundle = CFBundleCreate (kCFAllocatorDefault, url);
CFErrorRef error = nullptr;
if (!bundle || !CFBundleLoadExecutableAndReturnError (bundle, &error))
{
if (error)
{
CFPtr<CFStringRef> errorString (CFErrorCopyDescription (error));
if (errorString)
{
auto stringLength = CFStringGetLength (errorString);
auto maxSize =
CFStringGetMaximumSizeForEncoding (stringLength, kCFStringEncodingUTF8);
auto buffer = std::make_unique<char[]> (maxSize);
if (CFStringGetCString (errorString, buffer.get (), maxSize,
kCFStringEncodingUTF8))
errorDescription = buffer.get ();
CFRelease (error);
}
}
else
{
errorDescription = "Could not create Bundle for path: " + path;
}
return false;
}
auto bundleEntry = getFunctionPointer<BundleEntryFunc> ("bundleEntry");
if (!bundleEntry)
{
errorDescription = "Bundle does not export the required 'bundleEntry' function";
return false;
}
auto bundleExit = getFunctionPointer<BundleExitFunc> ("bundleExit");
if (!bundleExit)
{
errorDescription = "Bundle does not export the required 'bundleExit' function";
return false;
}
auto factoryProc = getFunctionPointer<GetFactoryProc> ("GetPluginFactory");
if (!factoryProc)
{
errorDescription = "Bundle does not export the required 'GetPluginFactory' function";
return false;
}
if (!bundleEntry (bundle))
{
errorDescription = "Calling 'bundleEntry' failed";
return false;
}
auto f = Steinberg::FUnknownPtr<Steinberg::IPluginFactory> (factoryProc ());
if (!f)
{
errorDescription = "Calling 'GetPluginFactory' returned nullptr";
return false;
}
factory = PluginFactory (f);
return true;
}

bool load (const std::string& path, std::string& errorDescription) override
{
if (!path.empty () && path[0] != '/')
{
auto buffer = std::make_unique<char[]> (PATH_MAX);
auto workDir = getcwd (buffer.get (), PATH_MAX);
if (workDir)
{
std::string wd (workDir);
wd += "/";
return loadInternal (wd + path, errorDescription);
}
}
return loadInternal (path, errorDescription);
}

~MacModule ()
{
factory = PluginFactory (nullptr);
if (bundle)
{
if (auto bundleExit = getFunctionPointer<BundleExitFunc> ("bundleExit"))
bundleExit ();
if (CFBundleIsExecutableLoaded ((CFBundleRef)bundle))
{
CFBundleUnloadExecutable ((CFBundleRef)bundle);
}
}
}

CFPtr<CFBundleRef> bundle;
};

//------------------------------------------------------------------------
void getModules (NSSearchPathDomainMask domain, Module::PathList& result)
{
NSURL* libraryUrl = [[NSFileManager defaultManager] URLForDirectory:NSLibraryDirectory
inDomain:domain
appropriateForURL:nil
create:NO
error:nil];
if (libraryUrl == nil)
return;
NSURL* audioUrl = [libraryUrl URLByAppendingPathComponent:@"Audio"];
if (audioUrl == nil)
return;
NSURL* plugInsUrl = [audioUrl URLByAppendingPathComponent:@"Plug-Ins"];
if (plugInsUrl == nil)
return;
NSURL* vst3Url =
[[plugInsUrl URLByAppendingPathComponent:@"VST3"] URLByResolvingSymlinksInPath];
if (vst3Url == nil)
return;
NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager]
enumeratorAtURL:[vst3Url URLByResolvingSymlinksInPath]
includingPropertiesForKeys:nil
options:NSDirectoryEnumerationSkipsPackageDescendants
errorHandler:nil];
for (NSURL* url in enumerator)
{
if ([[[url lastPathComponent] pathExtension] isEqualToString:@"vst3"])
{
result.emplace_back ([url.path UTF8String]);
}
}
}

//------------------------------------------------------------------------
void getApplicationModules (Module::PathList& result)
{
auto bundle = CFBundleGetMainBundle ();
if (!bundle)
return;
auto bundleUrl = static_cast<NSURL*> (CFBundleCopyBundleURL (bundle));
if (!bundleUrl)
return;
auto resUrl = [bundleUrl URLByAppendingPathComponent:@"Contents"];
if (!resUrl)
return;
auto vst3Url = [resUrl URLByAppendingPathComponent:@"VST3"];
if (!vst3Url)
return;
NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager]
enumeratorAtURL:[vst3Url URLByResolvingSymlinksInPath]
includingPropertiesForKeys:nil
options:NSDirectoryEnumerationSkipsPackageDescendants
errorHandler:nil];
for (NSURL* url in enumerator)
{
if ([[[url lastPathComponent] pathExtension] isEqualToString:@"vst3"])
{
result.emplace_back ([url.path UTF8String]);
}
}
}

//------------------------------------------------------------------------
} // anonymous

//------------------------------------------------------------------------
Module::Ptr Module::create (const std::string& path, std::string& errorDescription)
{
auto module = std::make_shared<MacModule> ();
if (module->load (path, errorDescription))
{
module->path = path;
auto it = std::find_if (path.rbegin (), path.rend (),
[] (const std::string::value_type& c) { return c == '/'; });
if (it != path.rend ())
module->name = {it.base (), path.end ()};
return module;
}
return nullptr;
}

//------------------------------------------------------------------------
Module::PathList Module::getModulePaths ()
{
PathList list;
getModules (NSUserDomainMask, list);
getModules (NSLocalDomainMask, list);
// TODO getModules (NSNetworkDomainMask, list);
getApplicationModules (list);
return list;
}

//------------------------------------------------------------------------
} // Hosting
} // VST3

+ 192
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/module_win32.cpp View File

@@ -0,0 +1,192 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category :
// Filename : public.sdk/source/vst/hosting/module_win32.cpp
// Created by : Steinberg, 08/2016
// Description : hosting module classes (win32 implementation)
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "stringconvert.h"
#include "module.h"
#include <Windows.h>
#include <Shlobj.h>
#include <algorithm>
#include <experimental/filesystem>

#pragma comment(lib, "Shell32")

//------------------------------------------------------------------------
extern "C" {
typedef bool (PLUGIN_API* InitModuleFunc) ();
typedef bool (PLUGIN_API* ExitModuleFunc) ();
}

using namespace std::experimental;

//------------------------------------------------------------------------
namespace VST3 {
namespace Hosting {

//------------------------------------------------------------------------
namespace {

//------------------------------------------------------------------------
class Win32Module : public Module
{
public:
template <typename T>
T getFunctionPointer (const char* name)
{
return reinterpret_cast<T> (GetProcAddress (module, name));
}

~Win32Module ()
{
factory = PluginFactory (nullptr);

if (module)
{
if (auto dllExit = getFunctionPointer<ExitModuleFunc> ("ExitDll"))
dllExit ();

FreeLibrary ((HMODULE)module);
}
}

bool load (const std::string& inPath, std::string& errorDescription) override
{
auto wideStr = StringConvert::convert (inPath);
module = LoadLibraryW (reinterpret_cast<LPCWSTR> (wideStr.data ()));
if (!module)
{
// TODO: is there an API to get more information about the failure ?
errorDescription = "LoadLibray failed.";
return false;
}

auto dllEntry = getFunctionPointer<InitModuleFunc> ("InitDll");
auto factoryProc = getFunctionPointer<GetFactoryProc> ("GetPluginFactory");
if (!factoryProc)
{
errorDescription = "dll does not export the required 'GetPluginFactory' function";
return false;
}
if (dllEntry && !dllEntry ())
{
errorDescription = "Calling 'InitDll' failed";
return false;
}
auto f = Steinberg::FUnknownPtr<Steinberg::IPluginFactory> (factoryProc ());
if (!f)
{
errorDescription = "Calling 'GetPluginFactory' returned nullptr";
return false;
}
factory = PluginFactory (f);
return true;
}

HINSTANCE module {nullptr};
};

//------------------------------------------------------------------------
Optional<std::string> getKnownFolder (REFKNOWNFOLDERID folderID)
{
PWSTR wideStr {};
if (FAILED (SHGetKnownFolderPath (folderID, 0, nullptr, &wideStr)))
return {};
return StringConvert::convert (wideStr);
}

//------------------------------------------------------------------------
void findFilesWithExt (const std::string& path, const std::string& ext, Module::PathList& pathList)
{
for (auto& p : filesystem::recursive_directory_iterator (path))
{
if (p.path ().extension () == ext)
{
pathList.push_back (p.path ().generic_u8string ());
}
}
}

//------------------------------------------------------------------------
void findModules (const std::string& path, Module::PathList& pathList)
{
findFilesWithExt (path, ".vst3", pathList);
}

//------------------------------------------------------------------------
} // anonymous

//------------------------------------------------------------------------
Module::Ptr Module::create (const std::string& path, std::string& errorDescription)
{
auto module = std::make_shared<Win32Module> ();
if (module->load (path, errorDescription))
{
module->path = path;
auto it = std::find_if (path.rbegin (), path.rend (),
[] (const std::string::value_type& c) { return c == '/'; });
if (it != path.rend ())
module->name = {it.base (), path.end ()};
return module;
}
return nullptr;
}

//------------------------------------------------------------------------
Module::PathList Module::getModulePaths ()
{
// find plug-ins located in common/VST3
PathList list;
if (auto knownFolder = getKnownFolder (FOLDERID_ProgramFilesCommon))
{
filesystem::path p (*knownFolder);
p.append ("VST3");
findModules (p.generic_u8string (), list);
}

// find plug-ins located in VST3 (application folder)
WCHAR modulePath[MAX_PATH + 1];
GetModuleFileNameW (nullptr, modulePath, MAX_PATH);
auto appPath = StringConvert::convert (modulePath);
filesystem::path path (appPath);
path = path.parent_path ();
path = path.append ("VST3");
findModules (path.generic_u8string (), list);

return list;
}

//------------------------------------------------------------------------
} // Hosting
} // VST3

+ 123
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/optional.h View File

@@ -0,0 +1,123 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/optional.h
// Created by : Steinberg, 08/2016
// Description : optional helper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include <memory>
#include <cassert>
#include <utility>

//------------------------------------------------------------------------
namespace VST3 {

//------------------------------------------------------------------------
template <typename T>
struct Optional
{
Optional () noexcept : valid (false) {}
explicit Optional (const T& v) noexcept : value (v), valid (true) {}
Optional (T&& v) noexcept : value (std::move (v)), valid (true) {}

Optional (Optional&& other) noexcept { *this = std::move (other); }
Optional& operator= (Optional&& other) noexcept
{
valid = other.valid;
value = std::move (other.value);
return *this;
}

explicit operator bool () const noexcept
{
setValidationChecked ();
return valid;
}

const T& operator* () const noexcept
{
checkValid ();
return value;
}

const T* operator-> () const noexcept
{
checkValid ();
return &value;
}

T& operator* () noexcept
{
checkValid ();
return value;
}

T* operator-> () noexcept
{
checkValid ();
return &value;
}

void swap (T& other) noexcept
{
checkValid ();
auto tmp = std::move (other);
other = std::move (value);
value = std::move (tmp);
}

private:
T value {};
bool valid;

#if !defined(NDEBUG)
mutable bool validationChecked {false};
#endif

void setValidationChecked () const
{
#if !defined(NDEBUG)
validationChecked = true;
#endif
}
void checkValid () const
{
#if !defined(NDEBUG)
assert (validationChecked);
#endif
}
};

//------------------------------------------------------------------------
}

+ 323
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/parameterchanges.cpp View File

@@ -0,0 +1,323 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/parameterchanges.cpp
// Created by : Steinberg, 03/05/2008.
// Description : VST 3 parameter changes implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "parameterchanges.h"

namespace Steinberg {
namespace Vst {

//-----------------------------------------------------------------------------
IMPLEMENT_FUNKNOWN_METHODS (ParameterChanges, IParameterChanges, IParameterChanges::iid)
IMPLEMENT_FUNKNOWN_METHODS (ParameterValueQueue, IParamValueQueue, IParamValueQueue::iid)


const int32 kQueueReservedPoints = 5;

//-----------------------------------------------------------------------------
ParameterValueQueue::ParameterValueQueue (ParamID paramID)
: paramID (paramID)
{
values.reserve (kQueueReservedPoints);
FUNKNOWN_CTOR
}

//-----------------------------------------------------------------------------
ParameterValueQueue::~ParameterValueQueue ()
{
FUNKNOWN_DTOR
}

//-----------------------------------------------------------------------------
void ParameterValueQueue::clear ()
{
values.clear ();
}

//-----------------------------------------------------------------------------
int32 PLUGIN_API ParameterValueQueue::getPointCount ()
{
return (int32)values.size ();
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API ParameterValueQueue::getPoint (int32 index, int32& sampleOffset, ParamValue& value)
{
if (index < (int32)values.size ())
{
const ParameterQueueValue& queueValue = values[index];
sampleOffset = queueValue.sampleOffset;
value = queueValue.value;
return kResultTrue;
}
return kResultFalse;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API ParameterValueQueue::addPoint (int32 sampleOffset, ParamValue value, int32& index)
{
int32 destIndex = (int32)values.size ();
for (uint32 i = 0; i < values.size (); i++)
{
if (values[i].sampleOffset == sampleOffset)
{
values[i].value = value;
index = i;
return kResultTrue;
}
else if (values[i].sampleOffset > sampleOffset)
{
destIndex = i;
break;
}
}

// need new point
ParameterQueueValue queueValue (value, sampleOffset);
if (destIndex == (int32)values.size ())
values.push_back (queueValue);
else
values.insert (values.begin () + destIndex, queueValue);

index = destIndex;

return kResultTrue;
}

//-----------------------------------------------------------------------------
// ParameterChanges
//-----------------------------------------------------------------------------
ParameterChanges::ParameterChanges (int32 maxParameters)
: usedQueueCount (0)
{
FUNKNOWN_CTOR
setMaxParameters (maxParameters);
}

//-----------------------------------------------------------------------------
ParameterChanges::~ParameterChanges ()
{
setMaxParameters (0);

FUNKNOWN_DTOR
}

//-----------------------------------------------------------------------------
void ParameterChanges::setMaxParameters (int32 maxParameters)
{
if (maxParameters < 0)
return;

while ((int32)queues.size () < maxParameters)
{
ParameterValueQueue* valueQueue = new ParameterValueQueue (0xffffffff);
queues.push_back (valueQueue);
}

while ((int32)queues.size () > maxParameters)
{
queues.back ()->release ();
queues.pop_back ();
}
if (usedQueueCount > maxParameters)
usedQueueCount = maxParameters;
}

//-----------------------------------------------------------------------------
void ParameterChanges::clearQueue ()
{
usedQueueCount = 0;
}

//-----------------------------------------------------------------------------
int32 PLUGIN_API ParameterChanges::getParameterCount ()
{
return usedQueueCount;
}

//-----------------------------------------------------------------------------
IParamValueQueue* PLUGIN_API ParameterChanges::getParameterData (int32 index)
{
if (index < usedQueueCount)
return queues[index];
return nullptr;
}

//-----------------------------------------------------------------------------
IParamValueQueue* PLUGIN_API ParameterChanges::addParameterData (const ParamID& pid, int32& index)
{
for (int32 i = 0; i < usedQueueCount; i++)
{
if (queues[i]->getParameterId () == pid)
{
index = i;
return queues[i];
}
}
ParameterValueQueue* valueQueue = nullptr;
if (usedQueueCount < (int32)queues.size ())
{
valueQueue = queues[usedQueueCount];
valueQueue->setParamID (pid);
valueQueue->clear ();
}
else
{
valueQueue = new ParameterValueQueue (pid);
queues.push_back (valueQueue);
}
index = usedQueueCount;
usedQueueCount++;
return valueQueue;
}


//-----------------------------------------------------------------------------
// ParameterChangeTransfer
//-----------------------------------------------------------------------------
ParameterChangeTransfer::ParameterChangeTransfer (int32 maxParameters)
: size (0)
, changes (nullptr)
, readIndex (0)
, writeIndex (0)
{
setMaxParameters (maxParameters);
}
//-----------------------------------------------------------------------------
ParameterChangeTransfer::~ParameterChangeTransfer ()
{
setMaxParameters (0);
}

//-----------------------------------------------------------------------------
void ParameterChangeTransfer::setMaxParameters (int32 maxParameters)
{
// reserve memory for twice the amount of all parameters
int32 newSize = maxParameters * 2;
if (size != newSize)
{
if (changes)
delete [] changes;
changes = nullptr;
size = newSize;
if (size > 0)
changes = new ParameterChange [size];
}
}

//-----------------------------------------------------------------------------
void ParameterChangeTransfer::addChange (ParamID pid, ParamValue value, int32 sampleOffset)
{
if (changes)
{
changes[writeIndex].id = pid;
changes[writeIndex].value = value;
changes[writeIndex].sampleOffset = sampleOffset;

int32 newWriteIndex = writeIndex + 1;
if (newWriteIndex >= size)
newWriteIndex = 0;
if (readIndex != newWriteIndex)
writeIndex = newWriteIndex;
}
}

//-----------------------------------------------------------------------------
bool ParameterChangeTransfer::getNextChange (ParamID& pid, ParamValue& value, int32& sampleOffset)
{
if (!changes)
return false;
int32 currentWriteIndex = writeIndex;
if (readIndex != currentWriteIndex)
{
pid = changes [readIndex].id;
value = changes [readIndex].value;
sampleOffset = changes [readIndex].sampleOffset;

int32 newReadIndex = readIndex + 1;
if (newReadIndex >= size)
newReadIndex = 0;
readIndex = newReadIndex;
return true;
}
return false;
}

//-----------------------------------------------------------------------------
void ParameterChangeTransfer::transferChangesTo (ParameterChanges& dest)
{
ParamID pid;
ParamValue value;
int32 sampleOffset;
int32 index;
while (getNextChange (pid, value, sampleOffset))
{
IParamValueQueue* queue = dest.addParameterData (pid, index);
if (queue)
{
queue->addPoint (sampleOffset, value, index);
}
}
}

//-----------------------------------------------------------------------------
void ParameterChangeTransfer::transferChangesFrom (ParameterChanges& source)
{
ParamValue value;
int32 sampleOffset;
for (int32 i = 0; i < source.getParameterCount (); i++)
{
IParamValueQueue* queue = source.getParameterData (i);
if (queue)
{
for (int32 j = 0; j < queue->getPointCount (); j++)
{
if (queue->getPoint (j, sampleOffset, value) == kResultTrue)
{
addChange (queue->getParameterId (), value, sampleOffset);
}
}
}
}
}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 142
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/parameterchanges.h View File

@@ -0,0 +1,142 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/parameterchanges.h
// Created by : Steinberg, 03/05/2008.
// Description : VST 3 parameter changes implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/vst/ivstparameterchanges.h"
#include <vector>

namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
/** Implementation's example of IParamValueQueue - not threadsave!.
\ingroup hostingBase
*/
class ParameterValueQueue : public IParamValueQueue
{
public:
//------------------------------------------------------------------------
ParameterValueQueue (ParamID paramID);
virtual ~ParameterValueQueue ();

ParamID PLUGIN_API getParameterId () SMTG_OVERRIDE { return paramID; }
int32 PLUGIN_API getPointCount () SMTG_OVERRIDE;
tresult PLUGIN_API getPoint (int32 index, int32& sampleOffset, ParamValue& value) SMTG_OVERRIDE;
tresult PLUGIN_API addPoint (int32 sampleOffset, ParamValue value, int32& index) SMTG_OVERRIDE;

void setParamID (ParamID pID) {paramID = pID;}
void clear ();
//------------------------------------------------------------------------
DECLARE_FUNKNOWN_METHODS
protected:
ParamID paramID;

struct ParameterQueueValue
{
ParameterQueueValue (ParamValue value, int32 sampleOffset) : value (value), sampleOffset (sampleOffset) {}
ParamValue value;
int32 sampleOffset;
};
std::vector<ParameterQueueValue> values;
};

//------------------------------------------------------------------------
/** Implementation's example of IParameterChanges - not threadsave!.
\ingroup hostingBase
*/
class ParameterChanges : public IParameterChanges
{
public:
//------------------------------------------------------------------------
ParameterChanges (int32 maxParameters = 0);
virtual ~ParameterChanges ();

void clearQueue ();
void setMaxParameters (int32 maxParameters);

//---IParameterChanges-----------------------------
int32 PLUGIN_API getParameterCount () SMTG_OVERRIDE;
IParamValueQueue* PLUGIN_API getParameterData (int32 index) SMTG_OVERRIDE;
IParamValueQueue* PLUGIN_API addParameterData (const ParamID& pid, int32& index) SMTG_OVERRIDE;
//------------------------------------------------------------------------
DECLARE_FUNKNOWN_METHODS
protected:
std::vector<ParameterValueQueue*> queues;
int32 usedQueueCount;
};


//------------------------------------------------------------------------
/** Ring buffer for transferring parameter changes from a writer to a read thread .
\ingroup hostingBase
*/
class ParameterChangeTransfer
{
public:
//------------------------------------------------------------------------
ParameterChangeTransfer (int32 maxParameters = 0);
virtual ~ParameterChangeTransfer ();

void setMaxParameters (int32 maxParameters);

void addChange (ParamID pid, ParamValue value, int32 sampleOffset);
bool getNextChange (ParamID& pid, ParamValue& value, int32& sampleOffset);

void transferChangesTo (ParameterChanges& dest);
void transferChangesFrom (ParameterChanges& source);

void removeChanges () { writeIndex = readIndex; }

//------------------------------------------------------------------------
protected:
struct ParameterChange
{
ParamID id;
ParamValue value;
int32 sampleOffset;
};
int32 size;
ParameterChange* changes;

volatile int32 readIndex;
volatile int32 writeIndex;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 320
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/plugprovider.cpp View File

@@ -0,0 +1,320 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : plugprovider.cpp
// Created by : Steinberg, 08/2016
// Description : VST 3 Plug-in Provider class
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "plugprovider.h"

#include "pluginterfaces/vst/ivstcomponent.h"
#include "pluginterfaces/vst/ivsteditcontroller.h"
#include "pluginterfaces/vst/ivstmessage.h"

namespace Steinberg {
extern FUnknown* gStandardPluginContext;

FUnknown* getPluginContext ()
{
return gStandardPluginContext;
}
}

#include <cstdio>
#include <iostream>

static std::ostream* errorStream = &std::cout;

namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
class ConnectionProxy : public FObject, public IConnectionPoint
{
public:
ConnectionProxy (IConnectionPoint* srcConnection);
virtual ~ConnectionProxy ();

//--- from IConnectionPoint
tresult PLUGIN_API connect (IConnectionPoint* other) override;
tresult PLUGIN_API disconnect (IConnectionPoint* other) override;
tresult PLUGIN_API notify (IMessage* message) override;

bool disconnect ();

OBJ_METHODS (ConnectionProxy, FObject)
REFCOUNT_METHODS (FObject)
DEF_INTERFACES_1 (IConnectionPoint, FObject)

protected:
IPtr<IConnectionPoint> srcConnection;
IPtr<IConnectionPoint> dstConnection;
};

//------------------------------------------------------------------------
ConnectionProxy::ConnectionProxy (IConnectionPoint* srcConnection)
: srcConnection (srcConnection) // share it
{
}

//------------------------------------------------------------------------
ConnectionProxy::~ConnectionProxy ()
{
}

//------------------------------------------------------------------------
tresult PLUGIN_API ConnectionProxy::connect (IConnectionPoint* other)
{
if (other == nullptr)
return kInvalidArgument;
if (dstConnection)
return kResultFalse;

dstConnection = other; // share it
tresult res = srcConnection->connect (this);
if (res != kResultTrue)
dstConnection = nullptr;
return res;
}

//------------------------------------------------------------------------
tresult PLUGIN_API ConnectionProxy::disconnect (IConnectionPoint* other)
{
if (!other)
return kInvalidArgument;

if (other == dstConnection)
{
if (srcConnection)
srcConnection->disconnect (this);
dstConnection = nullptr;
return kResultTrue;
}

return kInvalidArgument;
}

//------------------------------------------------------------------------
tresult PLUGIN_API ConnectionProxy::notify (IMessage* message)
{
if (dstConnection)
{
// TODO we should test if we are in UI main thread else postpone the message
return dstConnection->notify (message);
}
return kResultFalse;
}

//------------------------------------------------------------------------
bool ConnectionProxy::disconnect ()
{
return disconnect (dstConnection) == kResultTrue;
}

//------------------------------------------------------------------------
// PlugProvider
//------------------------------------------------------------------------
PlugProvider::PlugProvider (const PluginFactory& factory, ClassInfo classInfo, bool plugIsGlobal)
: factory (factory)
, component (nullptr)
, controller (nullptr)
, classInfo (classInfo)
, plugIsGlobal (plugIsGlobal)
{
if (plugIsGlobal)
{
setupPlugin (getPluginContext ());
}
}

//------------------------------------------------------------------------
PlugProvider::~PlugProvider ()
{
terminatePlugin ();
}

//------------------------------------------------------------------------
IComponent* PlugProvider::getComponent ()
{
if (!component)
setupPlugin (getPluginContext ());

if (component)
component->addRef ();

return component;
}

//------------------------------------------------------------------------
IEditController* PlugProvider::getController ()
{
if (controller)
controller->addRef ();

// 'iController == 0' is allowed! In this case the plug has no controller
return controller;
}

//------------------------------------------------------------------------
tresult PlugProvider::getPluginUID (FUID& uid) const
{
uid = classInfo.ID ().data ();
return kResultOk;
}

//------------------------------------------------------------------------
tresult PlugProvider::releasePlugIn (IComponent* iComponent, IEditController* iController)
{
if (iComponent)
iComponent->release ();

if (iController)
iController->release ();

if (!plugIsGlobal)
{
terminatePlugin ();
}

return kResultOk;
}

//------------------------------------------------------------------------
bool PlugProvider::setupPlugin (FUnknown* hostContext)
{
bool res = false;

//---create Plug-in here!--------------
// create its component part
component = factory.createInstance<IComponent> (classInfo.ID ());
if (component)
{
// initialize the component with our context
res = (component->initialize (hostContext) == kResultOk);

// try to create the controller part from the component
// (for Plug-ins which did not succeed to separate component from controller)
if (component->queryInterface (IEditController::iid, (void**)&controller) != kResultTrue)
{
TUID controllerCID;

// ask for the associated controller class ID
if (component->getControllerClassId (controllerCID) == kResultTrue)
{
// create its controller part created from the factory
controller = factory.createInstance<IEditController> (VST3::UID (controllerCID));
if (controller)
{
// initialize the component with our context
res = (controller->initialize (hostContext) == kResultOk);
}
}
}
}
else if (errorStream)
{
*errorStream << "Failed to create instance of " << classInfo.name () << "!\n";
}

if (res)
connectComponents ();

return res;
}

//------------------------------------------------------------------------
bool PlugProvider::connectComponents ()
{
if (!component || !controller)
return false;

FUnknownPtr<IConnectionPoint> compICP (component);
FUnknownPtr<IConnectionPoint> contrICP (controller);
if (!compICP || !contrICP)
return false;

bool res = false;

componentCP = NEW ConnectionProxy (compICP);
controllerCP = NEW ConnectionProxy (contrICP);

if (componentCP->connect (contrICP) != kResultTrue)
{
// TODO: Alert or what for non conformant plugin ?
}
else
{
if (controllerCP->connect (compICP) != kResultTrue)
{
// TODO: Alert or what for non conformant plugin ?
}
else
res = true;
}
return res;
}

//------------------------------------------------------------------------
bool PlugProvider::disconnectComponents ()
{
if (!componentCP || !controllerCP)
return false;

bool res = componentCP->disconnect ();
res &= controllerCP->disconnect ();

componentCP = nullptr;
controllerCP = nullptr;

return res;
}

//------------------------------------------------------------------------
void PlugProvider::terminatePlugin ()
{
disconnectComponents ();

bool controllerIsComponent = false;
if (component)
{
controllerIsComponent = FUnknownPtr<IEditController> (component).getInterface () != 0;
component->terminate ();
}

if (controller && controllerIsComponent == false)
controller->terminate ();

component = nullptr;
controller = nullptr;
}
}
} // namespaces

+ 96
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/plugprovider.h View File

@@ -0,0 +1,96 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : plugprovider.h
// Created by : Steinberg, 04/2005
// Description : VST 3 Plug-in Provider class
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "base/source/fobject.h"
#include "public.sdk/source/vst/hosting/module.h"
#include "public.sdk/source/vst/testsuite/vsttestsuite.h" // for IPlugProvider

namespace Steinberg {
namespace Vst {

class IComponent;
class IEditController;
class ConnectionProxy;

//------------------------------------------------------------------------
/** Helper for creating and initializing component.
\ingroup Validator */
//------------------------------------------------------------------------
class PlugProvider : public FObject, public IPlugProvider
{
public:
using ClassInfo = VST3::Hosting::ClassInfo;
using PluginFactory = VST3::Hosting::PluginFactory;

//--- ---------------------------------------------------------------------
PlugProvider (const PluginFactory& factory, ClassInfo info, bool plugIsGlobal = true);
virtual ~PlugProvider ();

//--- from IPlugProvider ------------------
IComponent* getComponent () SMTG_OVERRIDE;
IEditController* getController () SMTG_OVERRIDE;
tresult releasePlugIn (IComponent* component, IEditController* controller) SMTG_OVERRIDE;
const char8* getSubCategories () const SMTG_OVERRIDE
{
return classInfo.subCategoriesString ().data ();
}
tresult getPluginUID (FUID& uid) const SMTG_OVERRIDE;

//--- ---------------------------------------------------------------------
OBJ_METHODS (PlugProvider, FObject)
REFCOUNT_METHODS (FObject)
DEF_INTERFACES_1 (IPlugProvider, FObject)
//------------------------------------------------------------------------
protected:
bool setupPlugin (FUnknown* hostContext);
bool connectComponents ();
bool disconnectComponents ();
void terminatePlugin ();

PluginFactory factory;
IPtr<IComponent> component;
IPtr<IEditController> controller;
ClassInfo classInfo;

OPtr<ConnectionProxy> componentCP;
OPtr<ConnectionProxy> controllerCP;

bool plugIsGlobal;
};
}
} // namespaces

+ 223
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/processdata.cpp View File

@@ -0,0 +1,223 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/processdata.cpp
// Created by : Steinberg, 10/2005
// Description : VST Hosting Utilities
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "processdata.h"

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
// HostProcessData
//------------------------------------------------------------------------
HostProcessData::~HostProcessData ()
{
unprepare ();
}

//------------------------------------------------------------------------
bool HostProcessData::prepare (IComponent& component, int32 bufferSamples,
int32 _symbolicSampleSize)
{
if (checkIfReallocationNeeded (component, bufferSamples, _symbolicSampleSize))
{
unprepare ();

symbolicSampleSize = _symbolicSampleSize;
channelBufferOwner = bufferSamples > 0;

numInputs = createBuffers (component, inputs, kInput, bufferSamples);
numOutputs = createBuffers (component, outputs, kOutput, bufferSamples);
}
else
{
// reset silence flags
for (int32 i = 0; i < numInputs; i++)
{
inputs[i].silenceFlags = 0;
}
for (int32 i = 0; i < numOutputs; i++)
{
outputs[i].silenceFlags = 0;
}
}

return true;
}

//------------------------------------------------------------------------
void HostProcessData::unprepare ()
{
destroyBuffers (inputs, numInputs);
destroyBuffers (outputs, numOutputs);

channelBufferOwner = false;
}

//------------------------------------------------------------------------
bool HostProcessData::checkIfReallocationNeeded (IComponent& component, int32 bufferSamples,
int32 _symbolicSampleSize)
{
if (channelBufferOwner != (bufferSamples > 0))
return true;
if (symbolicSampleSize != _symbolicSampleSize)
return true;

int32 inBusCount = component.getBusCount (kAudio, kInput);
if (inBusCount != numInputs)
return true;

int32 outBusCount = component.getBusCount (kAudio, kOutput);
if (outBusCount != numOutputs)
return true;

for (int32 i = 0; i < inBusCount; i++)
{
BusInfo busInfo = {0};

if (component.getBusInfo (kAudio, kInput, i, busInfo) == kResultTrue)
{
if (inputs[i].numChannels != busInfo.channelCount)
return true;
}
}
for (int32 i = 0; i < outBusCount; i++)
{
BusInfo busInfo = {0};

if (component.getBusInfo (kAudio, kOutput, i, busInfo) == kResultTrue)
{
if (outputs[i].numChannels != busInfo.channelCount)
return true;
}
}
return false;
}

//-----------------------------------------------------------------------------
int32 HostProcessData::createBuffers (IComponent& component, AudioBusBuffers*& buffers,
BusDirection dir, int32 bufferSamples)
{
int32 busCount = component.getBusCount (kAudio, dir);
if (busCount > 0)
{
buffers = new AudioBusBuffers[busCount];

for (int32 i = 0; i < busCount; i++)
{
BusInfo busInfo = {0};

if (component.getBusInfo (kAudio, dir, i, busInfo) == kResultTrue)
{
buffers[i].numChannels = busInfo.channelCount;

// allocate for each channel
if (busInfo.channelCount > 0)
{
if (symbolicSampleSize == kSample64)
buffers[i].channelBuffers64 = new Sample64*[busInfo.channelCount];
else
buffers[i].channelBuffers32 = new Sample32*[busInfo.channelCount];

for (int32 j = 0; j < busInfo.channelCount; j++)
{
if (symbolicSampleSize == kSample64)
{
if (bufferSamples > 0)
buffers[i].channelBuffers64[j] = new Sample64[bufferSamples];
else
buffers[i].channelBuffers64[j] = 0;
}
else
{
if (bufferSamples > 0)
buffers[i].channelBuffers32[j] = new Sample32[bufferSamples];
else
buffers[i].channelBuffers32[j] = 0;
}
}
}
}
}
}
return busCount;
}

//-----------------------------------------------------------------------------
void HostProcessData::destroyBuffers (AudioBusBuffers*& buffers, int32& busCount)
{
if (buffers)
{
for (int32 i = 0; i < busCount; i++)
{
if (channelBufferOwner)
{
for (int32 j = 0; j < buffers[i].numChannels; j++)
{
if (symbolicSampleSize == kSample64)
{
if (buffers[i].channelBuffers64[j])
delete[] buffers[i].channelBuffers64[j];
}
else
{
if (buffers[i].channelBuffers32[j])
delete[] buffers[i].channelBuffers32[j];
}
}
}

if (symbolicSampleSize == kSample64)
{
if (buffers[i].channelBuffers64)
delete[] buffers[i].channelBuffers64;
}
else
{
if (buffers[i].channelBuffers32)
delete[] buffers[i].channelBuffers32;
}
}

delete[] buffers;
buffers = 0;
}
busCount = 0;
}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 199
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/processdata.h View File

@@ -0,0 +1,199 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/processdata.h
// Created by : Steinberg, 10/2005
// Description : VST Hosting Utilities
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/vst/ivstcomponent.h"
#include "pluginterfaces/vst/ivstaudioprocessor.h"

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
/** Implementation's example of ProcessData.
\ingroup hostingBase
*/
class HostProcessData : public ProcessData
{
public:
//------------------------------------------------------------------------
HostProcessData () : channelBufferOwner (false) {}
virtual ~HostProcessData ();

/** Prepare buffer containers for all buses. If bufferSamples is not null buffers will be
* created. */
bool prepare (IComponent& component, int32 bufferSamples = 0,
int32 _symbolicSampleSize = kSample32);

/** Remove bus buffers. */
void unprepare ();

/** Sets one sample buffer for all channels inside a bus. */
void setChannelBuffers (BusDirection dir, int32 busIndex, Sample32* sampleBuffer);
void setChannelBuffers64 (BusDirection dir, int32 busIndex, Sample64* sampleBuffer);

/** Sets individual sample buffers per channel inside a bus. */
void setChannelBuffers (BusDirection dir, int32 busIndex, Sample32* sampleBuffers[],
int32 bufferCount);
void setChannelBuffers64 (BusDirection dir, int32 busIndex, Sample64* sampleBuffers[],
int32 bufferCount);

/** Sets one sample buffer for a given channel inside a bus. */
void setChannelBuffer (BusDirection dir, int32 busIndex, int32 channelIndex,
Sample32* sampleBuffer);
void setChannelBuffer64 (BusDirection dir, int32 busIndex, int32 channelIndex,
Sample64* sampleBuffer);

static const uint64 kAllChannelsSilent =
#if MAC
0xffffffffffffffffULL;
#else
0xffffffffffffffffUL;
#endif

//------------------------------------------------------------------------
protected:
int32 createBuffers (IComponent& component, AudioBusBuffers*& buffers, BusDirection dir,
int32 bufferSamples);
void destroyBuffers (AudioBusBuffers*& buffers, int32& busCount);
bool checkIfReallocationNeeded (IComponent& component, int32 bufferSamples,
int32 _symbolicSampleSize);

bool channelBufferOwner;
};

//------------------------------------------------------------------------
// inline
//------------------------------------------------------------------------
inline void HostProcessData::setChannelBuffers (BusDirection dir, int32 busIndex,
Sample32* sampleBuffer)
{
if (channelBufferOwner)
return;
if (dir == kInput && (!inputs || busIndex >= numInputs))
return;
if (dir == kOutput && (!outputs || busIndex >= numOutputs))
return;

AudioBusBuffers& busBuffers = dir == kInput ? inputs[busIndex] : outputs[busIndex];
for (int32 i = 0; i < busBuffers.numChannels; i++)
busBuffers.channelBuffers32[i] = sampleBuffer;
}

//------------------------------------------------------------------------
inline void HostProcessData::setChannelBuffers64 (BusDirection dir, int32 busIndex,
Sample64* sampleBuffer)
{
if (channelBufferOwner)
return;
if (dir == kInput && (!inputs || busIndex >= numInputs))
return;
if (dir == kOutput && (!outputs || busIndex >= numOutputs))
return;

AudioBusBuffers& busBuffers = dir == kInput ? inputs[busIndex] : outputs[busIndex];
for (int32 i = 0; i < busBuffers.numChannels; i++)
busBuffers.channelBuffers64[i] = sampleBuffer;
}

//------------------------------------------------------------------------
inline void HostProcessData::setChannelBuffers (BusDirection dir, int32 busIndex,
Sample32* sampleBuffers[], int32 bufferCount)
{
if (channelBufferOwner)
return;
if (dir == kInput && (!inputs || busIndex >= numInputs))
return;
if (dir == kOutput && (!outputs || busIndex >= numOutputs))
return;

AudioBusBuffers& busBuffers = dir == kInput ? inputs[busIndex] : outputs[busIndex];
int32 count = bufferCount < busBuffers.numChannels ? bufferCount : busBuffers.numChannels;
for (int32 i = 0; i < count; i++)
busBuffers.channelBuffers32[i] = sampleBuffers ? sampleBuffers[i] : 0;
}

//------------------------------------------------------------------------
inline void HostProcessData::setChannelBuffers64 (BusDirection dir, int32 busIndex,
Sample64* sampleBuffers[], int32 bufferCount)
{
if (channelBufferOwner)
return;
if (dir == kInput && (!inputs || busIndex >= numInputs))
return;
if (dir == kOutput && (!outputs || busIndex >= numOutputs))
return;

AudioBusBuffers& busBuffers = dir == kInput ? inputs[busIndex] : outputs[busIndex];
int32 count = bufferCount < busBuffers.numChannels ? bufferCount : busBuffers.numChannels;
for (int32 i = 0; i < count; i++)
busBuffers.channelBuffers64[i] = sampleBuffers ? sampleBuffers[i] : 0;
}

//------------------------------------------------------------------------
inline void HostProcessData::setChannelBuffer (BusDirection dir, int32 busIndex, int32 channelIndex,
Sample32* sampleBuffer)
{
if (dir == kInput && (!inputs || busIndex >= numInputs))
return;
if (dir == kOutput && (!outputs || busIndex >= numOutputs))
return;

AudioBusBuffers& busBuffers = dir == kInput ? inputs[busIndex] : outputs[busIndex];
if (channelIndex >= busBuffers.numChannels)
return;
busBuffers.channelBuffers32[channelIndex] = sampleBuffer;
}

//------------------------------------------------------------------------
inline void HostProcessData::setChannelBuffer64 (BusDirection dir, int32 busIndex,
int32 channelIndex, Sample64* sampleBuffer)
{
if (dir == kInput && (!inputs || busIndex >= numInputs))
return;
if (dir == kOutput && (!outputs || busIndex >= numOutputs))
return;

AudioBusBuffers& busBuffers = dir == kInput ? inputs[busIndex] : outputs[busIndex];
if (channelIndex >= busBuffers.numChannels)
return;
busBuffers.channelBuffers64[channelIndex] = sampleBuffer;
}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 148
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/stringconvert.cpp View File

@@ -0,0 +1,148 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/hosting/stringconvert.cpp
// Created by : Steinberg, 11/2014
// Description : c++11 unicode string convert functions
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "stringconvert.h"
#include <codecvt>
#include <locale>
#include <istream>

//------------------------------------------------------------------------
namespace VST3 {
namespace StringConvert {

//------------------------------------------------------------------------
namespace {

#if defined(_MSC_VER) && _MSC_VER >= 1900
#define USE_WCHAR_AS_UTF16TYPE
using UTF16Type = wchar_t;
#else
using UTF16Type = char16_t;
#endif

using Coverter = std::wstring_convert<std::codecvt_utf8_utf16<UTF16Type>, UTF16Type>;

//------------------------------------------------------------------------
Coverter& converter ()
{
static Coverter conv;
return conv;
}

//------------------------------------------------------------------------
} // anonymous

//------------------------------------------------------------------------
std::u16string convert (const std::string& utf8Str)
{
#if defined(USE_WCHAR_AS_UTF16TYPE)
auto wstr = converter ().from_bytes (utf8Str);
return {wstr.data (), wstr.data () + wstr.size ()};
#else
return converter ().from_bytes (utf8Str);
#endif
}

//------------------------------------------------------------------------
bool convert (const std::string& utf8Str, Steinberg::Vst::String128 str)
{
return convert (utf8Str, str, 128);
}

//------------------------------------------------------------------------
bool convert (const std::string& utf8Str, Steinberg::Vst::TChar* str, uint32_t maxCharacters)
{
auto ucs2 = convert (utf8Str);
if (ucs2.length () < maxCharacters)
{
ucs2.copy (reinterpret_cast<char16_t*> (str), ucs2.length ());
str[ucs2.length ()] = 0;
return true;
}
return false;
}

//------------------------------------------------------------------------
std::string convert (const Steinberg::Vst::TChar* str)
{
return converter ().to_bytes (reinterpret_cast<const UTF16Type*> (str));
}

//------------------------------------------------------------------------
std::string convert (const Steinberg::Vst::TChar* str, uint32_t max)
{
std::string result;
if (str)
{
Steinberg::Vst::TChar tmp[2] {};
for (uint32_t i = 0; i < max; ++i, ++str)
{
tmp[0] = *str;
if (tmp[0] == 0)
break;
result += convert (tmp);
}
}
return result;
}

//------------------------------------------------------------------------
std::string convert (const std::u16string& str)
{
return converter ().to_bytes (reinterpret_cast<const UTF16Type*> (str.data ()),
reinterpret_cast<const UTF16Type*> (str.data () + str.size ()));
}

//------------------------------------------------------------------------
std::string convert (const char* str, uint32_t max)
{
std::string result;
if (str)
{
result.reserve (max);
for (uint32_t i = 0; i < max; ++i, ++str)
{
if (*str == 0)
break;
result += *str;
}
}
return result;
}

//------------------------------------------------------------------------
} // String
} // VST3

+ 132
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/stringconvert.h View File

@@ -0,0 +1,132 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category :
// Filename : public.sdk/source/vst/hosting/stringconvert.h
// Created by : Steinberg, 11/2014
// Description : c++11 unicode string convert functions
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/vst/vsttypes.h"
#include <string>

//------------------------------------------------------------------------
namespace VST3 {
namespace StringConvert {

//------------------------------------------------------------------------
/**
* convert an UTF-8 string to an UTF-16 string
*
* @param utf8Str UTF-8 string
*
* @return UTF-16 string
*/
extern std::u16string convert (const std::string& utf8Str);

//------------------------------------------------------------------------
/**
* convert an UTF-8 string to an UTF-16 string buffer with max 127 characters
*
* @param utf8Str UTF-8 string
* @param str UTF-16 string buffer
*
* @return true on success
*/
extern bool convert (const std::string& utf8Str, Steinberg::Vst::String128 str);

//------------------------------------------------------------------------
/**
* convert an UTF-8 string to an UTF-16 string buffer
*
* @param utf8Str UTF-8 string
* @param str UTF-16 string buffer
* @param maxCharacters max characters that fit into str
*
* @return true on success
*/
extern bool convert (const std::string& utf8Str, Steinberg::Vst::TChar* str,
uint32_t maxCharacters);

//------------------------------------------------------------------------
/**
* convert an UTF-16 string buffer to an UTF-8 string
*
* @param str UTF-16 string buffer
*
* @return UTF-8 string
*/
extern std::string convert (const Steinberg::Vst::TChar* str);

//------------------------------------------------------------------------
/**
* convert an UTF-16 string buffer to an UTF-8 string
*
* @param str UTF-16 string buffer
* @param max maximum characters in str
*
* @return UTF-8 string
*/
extern std::string convert (const Steinberg::Vst::TChar* str, uint32_t max);

//------------------------------------------------------------------------
/**
* convert an UTF-16 string to an UTF-8 string
*
* @param str UTF-16 string
*
* @return UTF-8 string
*/
extern std::string convert (const std::u16string& str);

//------------------------------------------------------------------------
/**
* convert a ASCII string buffer to an UTF-8 string
*
* @param str ASCII string buffer
* @param max maximum characters in str
*
* @return UTF-8 string
*/
extern std::string convert (const char* str, uint32_t max);

//------------------------------------------------------------------------
} // String

//------------------------------------------------------------------------
inline const Steinberg::Vst::TChar* toTChar (const std::u16string& str)
{
return reinterpret_cast<const Steinberg::Vst::TChar*> (str.data ());
}

//------------------------------------------------------------------------
} // VST3

+ 292
- 0
source/includes/vst3sdk/public.sdk/source/vst/hosting/uid.h View File

@@ -0,0 +1,292 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category :
// Filename : public.sdk/source/vst/hosting/uid.h
// Created by : Steinberg, 08/2016
// Description : UID
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "optional.h"
#include "pluginterfaces/base/funknown.h"
#include <string>

//------------------------------------------------------------------------
namespace VST3 {

//------------------------------------------------------------------------
struct UID
{
#if defined(WINDOWS) && WINDOWS == 1
static constexpr bool defaultComFormat = true;
#else
static constexpr bool defaultComFormat = false;
#endif

using TUID = Steinberg::TUID;

constexpr UID () noexcept = default;
UID (uint32_t l1, uint32_t l2, uint32_t l3, uint32_t l4, bool comFormat = defaultComFormat)
noexcept;
UID (const TUID& uid) noexcept;
UID (const UID& uid) noexcept;
UID& operator= (const UID& uid) noexcept;
UID& operator= (const TUID& uid) noexcept;

constexpr const TUID& data () const noexcept;
constexpr size_t size () const noexcept;

std::string toString (bool comFormat = defaultComFormat) const noexcept;
static Optional<UID> fromString (const std::string& str,
bool comFormat = defaultComFormat) noexcept;

static UID fromTUID (const TUID _uid) noexcept;
//------------------------------------------------------------------------
private:
Steinberg::TUID _data {};

struct GUID
{
uint32_t Data1;
uint16_t Data2;
uint16_t Data3;
uint8_t Data4[8];
};
};

//------------------------------------------------------------------------
inline bool operator== (const UID& uid1, const UID& uid2)
{
const uint64_t* p1 = reinterpret_cast<const uint64_t*> (uid1.data ());
const uint64_t* p2 = reinterpret_cast<const uint64_t*> (uid2.data ());
return p1[0] == p2[0] && p1[1] == p2[1];
}

//------------------------------------------------------------------------
inline bool operator!= (const UID& uid1, const UID& uid2)
{
return !(uid1 == uid2);
}

//------------------------------------------------------------------------
inline bool operator< (const UID& uid1, const UID& uid2)
{
const uint64_t* p1 = reinterpret_cast<const uint64_t*> (uid1.data ());
const uint64_t* p2 = reinterpret_cast<const uint64_t*> (uid2.data ());
return (p1[0] < p2[0]) && (p1[1] < p2[1]);
}

//------------------------------------------------------------------------
inline UID::UID (uint32_t l1, uint32_t l2, uint32_t l3, uint32_t l4, bool comFormat) noexcept
{
if (comFormat)
{
_data[0] = static_cast<int8_t> ((l1 & 0x000000FF));
_data[1] = static_cast<int8_t> ((l1 & 0x0000FF00) >> 8);
_data[2] = static_cast<int8_t> ((l1 & 0x00FF0000) >> 16);
_data[3] = static_cast<int8_t> ((l1 & 0xFF000000) >> 24);
_data[4] = static_cast<int8_t> ((l2 & 0x00FF0000) >> 16);
_data[5] = static_cast<int8_t> ((l2 & 0xFF000000) >> 24);
_data[6] = static_cast<int8_t> ((l2 & 0x000000FF));
_data[7] = static_cast<int8_t> ((l2 & 0x0000FF00) >> 8);
_data[8] = static_cast<int8_t> ((l3 & 0xFF000000) >> 24);
_data[9] = static_cast<int8_t> ((l3 & 0x00FF0000) >> 16);
_data[10] = static_cast<int8_t> ((l3 & 0x0000FF00) >> 8);
_data[11] = static_cast<int8_t> ((l3 & 0x000000FF));
_data[12] = static_cast<int8_t> ((l4 & 0xFF000000) >> 24);
_data[13] = static_cast<int8_t> ((l4 & 0x00FF0000) >> 16);
_data[14] = static_cast<int8_t> ((l4 & 0x0000FF00) >> 8);
_data[15] = static_cast<int8_t> ((l4 & 0x000000FF));
}
else
{
_data[0] = static_cast<int8_t> ((l1 & 0xFF000000) >> 24);
_data[1] = static_cast<int8_t> ((l1 & 0x00FF0000) >> 16);
_data[2] = static_cast<int8_t> ((l1 & 0x0000FF00) >> 8);
_data[3] = static_cast<int8_t> ((l1 & 0x000000FF));
_data[4] = static_cast<int8_t> ((l2 & 0xFF000000) >> 24);
_data[5] = static_cast<int8_t> ((l2 & 0x00FF0000) >> 16);
_data[6] = static_cast<int8_t> ((l2 & 0x0000FF00) >> 8);
_data[7] = static_cast<int8_t> ((l2 & 0x000000FF));
_data[8] = static_cast<int8_t> ((l3 & 0xFF000000) >> 24);
_data[9] = static_cast<int8_t> ((l3 & 0x00FF0000) >> 16);
_data[10] = static_cast<int8_t> ((l3 & 0x0000FF00) >> 8);
_data[11] = static_cast<int8_t> ((l3 & 0x000000FF));
_data[12] = static_cast<int8_t> ((l4 & 0xFF000000) >> 24);
_data[13] = static_cast<int8_t> ((l4 & 0x00FF0000) >> 16);
_data[14] = static_cast<int8_t> ((l4 & 0x0000FF00) >> 8);
_data[15] = static_cast<int8_t> ((l4 & 0x000000FF));
}
}

//------------------------------------------------------------------------
inline UID::UID (const TUID& uid) noexcept
{
*this = uid;
}

//------------------------------------------------------------------------
inline UID::UID (const UID& uid) noexcept
{
*this = uid;
}

//------------------------------------------------------------------------
inline UID& UID::operator= (const UID& uid) noexcept
{
*this = uid.data ();
return *this;
}

//------------------------------------------------------------------------
inline UID& UID::operator= (const TUID& uid) noexcept
{
uint64_t* p1 = reinterpret_cast<uint64_t*> (_data);
const uint64_t* p2 = reinterpret_cast<const uint64_t*> (uid);
p1[0] = p2[0];
p1[1] = p2[1];
return *this;
}

//------------------------------------------------------------------------
inline constexpr auto UID::data () const noexcept -> const TUID&
{
return _data;
}

//------------------------------------------------------------------------
inline constexpr size_t UID::size () const noexcept
{
return sizeof (TUID);
}

//------------------------------------------------------------------------
inline std::string UID::toString (bool comFormat) const noexcept
{
std::string result;
result.reserve (32);
if (comFormat)
{
const auto& g = reinterpret_cast<const GUID*> (_data);

char tmp[21] {};
sprintf (tmp, "%08X%04X%04X", g->Data1, g->Data2, g->Data3);
result = tmp;

for (uint32_t i = 0; i < 8; ++i)
{
char s[3] {};
sprintf (s, "%02X", g->Data4[i]);
result += s;
}
}
else
{
for (uint32_t i = 0; i < 16; ++i)
{
char s[3] {};
sprintf (s, "%02X", static_cast<uint8_t> (_data[i]));
result += s;
}
}
return result;
}

//------------------------------------------------------------------------
inline Optional<UID> UID::fromString (const std::string& str, bool comFormat) noexcept
{
if (str.length () != 32)
return {};
// TODO: this is a copy from FUID. there are no input validation checks !!!
if (comFormat)
{
TUID uid {};
GUID g;
char s[33];

strcpy (s, str.data ());
s[8] = 0;
sscanf (s, "%x", &g.Data1);
strcpy (s, str.data () + 8);
s[4] = 0;
sscanf (s, "%hx", &g.Data2);
strcpy (s, str.data () + 12);
s[4] = 0;
sscanf (s, "%hx", &g.Data3);

memcpy (uid, &g, 8);

for (uint32_t i = 8; i < 16; ++i)
{
char s2[3] {};
s2[0] = str[i * 2];
s2[1] = str[i * 2 + 1];

int32_t d = 0;
sscanf (s2, "%2x", &d);
uid[i] = static_cast<char> (d);
}
return {uid};
}
else
{
TUID uid {};
for (uint32_t i = 0; i < 16; ++i)
{
char s[3] {};
s[0] = str[i * 2];
s[1] = str[i * 2 + 1];

int32_t d = 0;
sscanf (s, "%2x", &d);
uid[i] = static_cast<char> (d);
}
return {uid};
}
return {};
}

//------------------------------------------------------------------------
inline UID UID::fromTUID (const TUID _uid) noexcept
{
UID result;

uint64_t* p1 = reinterpret_cast<uint64_t*> (result._data);
const uint64_t* p2 = reinterpret_cast<const uint64_t*> (_uid);
p1[0] = p2[0];
p1[1] = p2[1];

return result;
}

//------------------------------------------------------------------------
} // VST3

+ 151
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/AudioIO.h View File

@@ -0,0 +1,151 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/AudioIO.h
// Created by : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

/// \cond ignore

#include <AudioUnit/AUComponent.h>
#include <AudioToolbox/AudioToolbox.h>
#include "pluginterfaces/base/funknown.h"
#include "pluginterfaces/vst/vsttypes.h"
#include <vector>

#ifndef __OBJC__
struct UIImage;
struct NSString;
#endif

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

class AudioIO;

//------------------------------------------------------------------------
class IMidiProcessor
{
public:
virtual void onMIDIEvent (UInt32 status, UInt32 data1, UInt32 data2, UInt32 sampleOffset, bool withinRealtimeThread) = 0;
};

//------------------------------------------------------------------------
class IAudioIOProcessor : public IMidiProcessor
{
public:
virtual void willStartAudio (AudioIO* audioIO) = 0;
virtual void didStopAudio (AudioIO* audioIO) = 0;

virtual void process (const AudioTimeStamp* timeStamp, UInt32 busNumber, UInt32 numFrames, AudioBufferList* ioData, bool& outputIsSilence, AudioIO* audioIO) = 0;
};

//------------------------------------------------------------------------
class AudioIO
{
public:
static AudioIO* instance ();

tresult init (OSType type, OSType subType, OSType manufacturer, CFStringRef name);

bool switchToHost ();
bool sendRemoteControlEvent (AudioUnitRemoteControlEvent event);
UIImage* getHostIcon ();
tresult start ();
tresult stop ();

tresult addProcessor (IAudioIOProcessor* processor);
tresult removeProcessor (IAudioIOProcessor* processor);
// accessors
AudioUnit getRemoteIO () const { return remoteIO; }
SampleRate getSampleRate () const { return sampleRate; }
bool getInterAppAudioConnected () const { return interAppAudioConnected; }

// host context information
bool getBeatAndTempo (Float64& beat, Float64& tempo);
bool getMusicalTimeLocation (UInt32& deltaSampleOffset, Float32& timeSigNumerator, UInt32& timeSigDenominator, Float64& downBeat);
bool getTransportState (Boolean& isPlaying, Boolean& isRecording, Boolean& transportStateChanged, Float64& sampleInTimeLine, Boolean& isCycling, Float64& cycleStartBeat, Float64& cycleEndBeat);

void setStaticFallbackTempo (Float64 tempo) {staticTempo = tempo; }
Float64 getStaticFallbackTempo () const { return staticTempo; }

static NSString* kConnectionStateChange;
//------------------------------------------------------------------------
protected:
AudioIO ();
~AudioIO ();

static OSStatus inputCallbackStatic (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
static OSStatus renderCallbackStatic (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
static void propertyChangeStatic (void *inRefCon, AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement);
static void midiEventCallbackStatic (void *inRefCon, UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame);

OSStatus inputCallback (AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
OSStatus renderCallback (AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
void midiEventCallback (UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame);

void remoteIOPropertyChanged (AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement);

void setAudioSessionActive (bool state);
tresult setupRemoteIO (OSType type);
tresult setupAUGraph (OSType type);
void updateInterAppAudioConnectionState ();
AudioUnit remoteIO;
AUGraph graph;
AudioBufferList* ioBufferList;
HostCallbackInfo hostCallback;
UInt32 maxFrames;
Float64 staticTempo;
SampleRate sampleRate;
bool interAppAudioConnected;
std::vector<IAudioIOProcessor*> audioProcessors;

enum InternalState {
kUninitialized,
kInitialized,
kStarted,
};
InternalState internalState;
};

//------------------------------------------------------------------------
} // namespace InterAppAudio
} // namespace Vst
} // namespace Steinberg

/// \endcond

+ 551
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/AudioIO.mm View File

@@ -0,0 +1,551 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/AudioIO.mm
// Created by : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import "AudioIO.h"
#import "MidiIO.h"
#import "pluginterfaces/base/fstrdefs.h"
#import <AudioUnit/AudioUnit.h>
#import <AVFoundation/AVAudioSession.h>
#import <UIKit/UIKit.h>

#define FORCE_INLINE __attribute__((always_inline))

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

//------------------------------------------------------------------------
static AudioBufferList* createBuffers (uint32 numChannels, uint32 maxFrames, uint32 frameSize)
{
AudioBufferList* result = (AudioBufferList*) malloc (sizeof (AudioBufferList) + sizeof (AudioBuffer) * numChannels);
result->mNumberBuffers = numChannels;
for (int32 i = 0; i < numChannels; i++)
{
result->mBuffers[i].mDataByteSize = maxFrames * sizeof (float);
result->mBuffers[i].mData = calloc (1, result->mBuffers[i].mDataByteSize);
result->mBuffers[i].mNumberChannels = 1;
}
return result;
}

//------------------------------------------------------------------------
static void freeAudioBufferList (AudioBufferList* audioBufferList)
{
for (uint32 i = 0; i < audioBufferList->mNumberBuffers; i++)
{
free (audioBufferList->mBuffers[i].mData);
}
free (audioBufferList);
}

//------------------------------------------------------------------------
NSString* AudioIO::kConnectionStateChange = @"AudioIO::kConnectionStateChange";

//------------------------------------------------------------------------
AudioIO::AudioIO ()
: remoteIO (0)
, graph (0)
, ioBufferList (0)
, maxFrames (4096)
, staticTempo (120.)
, interAppAudioConnected (false)
, internalState (kUninitialized)
{
sampleRate = [[AVAudioSession sharedInstance] sampleRate];
memset (&hostCallback, 0, sizeof (HostCallbackInfo));
MidiIO::instance ();
}

//------------------------------------------------------------------------
AudioIO::~AudioIO ()
{
if (ioBufferList)
freeAudioBufferList (ioBufferList);
}

//------------------------------------------------------------------------
AudioIO* AudioIO::instance ()
{
static AudioIO gInstance;
return &gInstance;
}

//------------------------------------------------------------------------
tresult AudioIO::setupRemoteIO (OSType type)
{
if (remoteIO != 0)
{
AudioStreamBasicDescription streamFormat = {};
streamFormat.mChannelsPerFrame = 2;
streamFormat.mSampleRate = sampleRate;
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
streamFormat.mBytesPerFrame = streamFormat.mBytesPerPacket = sizeof(Float32);
streamFormat.mBitsPerChannel = 32;
streamFormat.mFramesPerPacket = 1;
OSStatus status = AudioUnitSetProperty (remoteIO,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
1,
&streamFormat,
sizeof(streamFormat));
if (status != noErr)
return kInternalError;

status = AudioUnitSetProperty ( remoteIO,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&streamFormat,
sizeof(streamFormat));
if (status != noErr)
return kInternalError;
status = AudioUnitSetProperty ( remoteIO,
kAudioUnitProperty_MaximumFramesPerSlice,
kAudioUnitScope_Global,
1,
&maxFrames,
sizeof(maxFrames));

if (status != noErr)
return kInternalError;

bool needInput = (type == kAudioUnitType_RemoteGenerator || type == kAudioUnitType_RemoteInstrument) == false;
UInt32 flag = 1;
if (needInput)
{
// enable IO Input
status = AudioUnitSetProperty (remoteIO,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
1,
&flag,
sizeof(flag));
if (status != noErr)
return kInternalError;
}
// enable IO Output
status = AudioUnitSetProperty (remoteIO,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
0,
&flag,
sizeof(flag));
if (status != noErr)
return kInternalError;

AURenderCallbackStruct renderCallback = {};
if (needInput)
{
renderCallback.inputProc = inputCallbackStatic;
renderCallback.inputProcRefCon = this;
status = AudioUnitSetProperty (remoteIO, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 1, &renderCallback, sizeof (renderCallback));
if (status != noErr)
return kInternalError;
}

renderCallback.inputProc = renderCallbackStatic;
renderCallback.inputProcRefCon = this;
status = AudioUnitSetProperty (remoteIO, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, 0, &renderCallback, sizeof (renderCallback));
if (status != noErr)
return kInternalError;

if (type == kAudioUnitType_RemoteInstrument || type == kAudioUnitType_RemoteMusicEffect)
{
AudioOutputUnitMIDICallbacks callBackStruct = {};
callBackStruct.userData = this;
callBackStruct.MIDIEventProc = midiEventCallbackStatic;
status = AudioUnitSetProperty (remoteIO, kAudioOutputUnitProperty_MIDICallbacks, kAudioUnitScope_Global, 0, &callBackStruct, sizeof (callBackStruct));
if (status != noErr)
{
NSLog (@"Setting MIDICallback on OutputUnit failed");
}
}

if (ioBufferList)
freeAudioBufferList (ioBufferList);
ioBufferList = createBuffers (streamFormat.mChannelsPerFrame, maxFrames, streamFormat.mBytesPerFrame);
if (ioBufferList == 0)
return kOutOfMemory;

status = AudioUnitAddPropertyListener (remoteIO, kAudioUnitProperty_IsInterAppConnected, propertyChangeStatic, this);
status = AudioUnitAddPropertyListener (remoteIO, kAudioOutputUnitProperty_HostTransportState, propertyChangeStatic, this);

return kResultTrue;
}
return kResultFalse;
}

//------------------------------------------------------------------------
tresult AudioIO::setupAUGraph (OSType type)
{
if (graph == 0)
{
OSStatus status = NewAUGraph (&graph);
if (status != noErr)
return kInternalError;
AudioComponentDescription iOUnitDescription;
iOUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
iOUnitDescription.componentFlags = 0;
iOUnitDescription.componentFlagsMask = 0;
iOUnitDescription.componentType = kAudioUnitType_Output;
iOUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO;

AUNode remoteIONode;
status = AUGraphAddNode (graph, &iOUnitDescription, &remoteIONode);
if (status != noErr)
return kInternalError;
status = AUGraphOpen(graph);
if (status != noErr)
return kInternalError;
status = AUGraphNodeInfo (graph, remoteIONode, 0, &remoteIO);
if (status != noErr)
return kInternalError;
return setupRemoteIO (type);
}
return kResultFalse;
}

//------------------------------------------------------------------------
void AudioIO::updateInterAppAudioConnectionState ()
{
if (remoteIO)
{
UInt32 connected;
UInt32 dataSize = sizeof (connected);
OSStatus status = AudioUnitGetProperty(remoteIO, kAudioUnitProperty_IsInterAppConnected, kAudioUnitScope_Global, 0, &connected, &dataSize);
if (status == noErr)
{
if (interAppAudioConnected != connected)
{
if (connected)
{
UInt32 size = sizeof (HostCallbackInfo);
status = AudioUnitGetProperty (remoteIO, kAudioUnitProperty_HostCallbacks, kAudioUnitScope_Global, 0, &hostCallback, &size);
}
else
{
memset (&hostCallback, 0, sizeof (HostCallbackInfo));
}
interAppAudioConnected = connected > 0 ? true : false;
[[NSNotificationCenter defaultCenter] postNotificationName:kConnectionStateChange object:nil];
}
}
}
}

//------------------------------------------------------------------------
tresult AudioIO::init (OSType type, OSType subType, OSType manufacturer, CFStringRef name)
{
tresult result = setupAUGraph (type);
if (result != kResultTrue)
return result;

AudioComponentDescription desc = { type, subType, manufacturer, 0, 0 };
OSStatus status = AudioOutputUnitPublish (&desc, name, 0, remoteIO);
if (status != noErr)
{
NSLog (@"AudioOutputUnitPublish failed with status:%d", (int)status);
}
internalState = kInitialized;

return result;
}

//------------------------------------------------------------------------
void AudioIO::setAudioSessionActive (bool state)
{
NSError* error;
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setPreferredSampleRate: sampleRate error:&error];
[session setCategory: AVAudioSessionCategoryPlayback withOptions: AVAudioSessionCategoryOptionMixWithOthers error:&error];
[session setActive:(state ? YES : NO) error:&error];
}

//------------------------------------------------------------------------
tresult AudioIO::start ()
{
if (internalState == kInitialized)
{
bool appIsActive = [UIApplication sharedApplication].applicationState == UIApplicationStateActive;
if (!(appIsActive || interAppAudioConnected))
{
return kResultFalse;
}
setAudioSessionActive (true);
Boolean graphInitialized = true;
OSStatus status = AUGraphIsInitialized (graph, &graphInitialized);
if (status != noErr)
return kInternalError;
if (graphInitialized == false)
{
status = AUGraphInitialize (graph);
if (status != noErr)
return kInternalError;
updateInterAppAudioConnectionState ();
}
for (auto processor : audioProcessors)
{
processor->willStartAudio (this);
}
status = AUGraphStart (graph);
if (status == noErr)
{
internalState = kStarted;
updateInterAppAudioConnectionState ();
return kResultTrue;
}
return kInternalError;
}
return kResultFalse;
}

//------------------------------------------------------------------------
tresult AudioIO::stop ()
{
if (internalState == kStarted)
{
if (AUGraphStop (graph) == noErr)
{
for (auto processor : audioProcessors)
{
processor->didStopAudio (this);
}
internalState = kInitialized;
if (interAppAudioConnected == false)
setAudioSessionActive (false);
return kResultTrue;
}
}
return kResultFalse;
}

//------------------------------------------------------------------------
tresult AudioIO::addProcessor (IAudioIOProcessor* processor)
{
if (internalState == kInitialized)
{
audioProcessors.push_back (processor);
MidiIO::instance ().addProcessor (processor);
return kResultTrue;
}
return kResultFalse;
}

//------------------------------------------------------------------------
tresult AudioIO::removeProcessor (IAudioIOProcessor* processor)
{
if (internalState == kInitialized)
{
auto it = std::find (audioProcessors.begin (), audioProcessors.end (), processor);
if (it != audioProcessors.end ())
{
audioProcessors.erase (it);
MidiIO::instance ().removeProcessor (processor);
return kResultTrue;
}
}
return kResultFalse;
}

//------------------------------------------------------------------------
bool AudioIO::switchToHost ()
{
if (remoteIO && interAppAudioConnected)
{
CFURLRef instrumentUrl;
UInt32 dataSize = sizeof(instrumentUrl);
OSStatus result = AudioUnitGetProperty (remoteIO, kAudioUnitProperty_PeerURL, kAudioUnitScope_Global, 0, &instrumentUrl, &dataSize);
if (result == noErr)
{
[[UIApplication sharedApplication] openURL:(__bridge NSURL*)instrumentUrl];
return true;
}
}
return false;
}

//------------------------------------------------------------------------
bool AudioIO::sendRemoteControlEvent (AudioUnitRemoteControlEvent event)
{
if (remoteIO && interAppAudioConnected)
{
UInt32 controlEvent = event;
UInt32 dataSize = sizeof (controlEvent);
OSStatus status = AudioUnitSetProperty (remoteIO, kAudioOutputUnitProperty_RemoteControlToHost, kAudioUnitScope_Global, 0, &controlEvent, dataSize);
return status == noErr;
}
return false;
}

//------------------------------------------------------------------------
UIImage* AudioIO::getHostIcon ()
{
if (remoteIO && interAppAudioConnected)
{
return AudioOutputUnitGetHostIcon (remoteIO, 128);
}
return nil;
}

//------------------------------------------------------------------------
bool AudioIO::getBeatAndTempo (Float64& beat, Float64& tempo)
{
if (hostCallback.beatAndTempoProc)
{
if (hostCallback.beatAndTempoProc (hostCallback.hostUserData, &beat, &tempo) == noErr)
return true;
}
tempo = staticTempo;
beat = 0;
return true;
}

//------------------------------------------------------------------------
bool AudioIO::getMusicalTimeLocation (UInt32& deltaSampleOffset, Float32& timeSigNumerator, UInt32& timeSigDenominator, Float64& downBeat)
{
if (hostCallback.musicalTimeLocationProc)
{
if (hostCallback.musicalTimeLocationProc (hostCallback.hostUserData, &deltaSampleOffset, &timeSigNumerator, &timeSigDenominator, &downBeat) == noErr)
return true;
}
return false;
}

//------------------------------------------------------------------------
bool AudioIO::getTransportState (Boolean& isPlaying, Boolean& isRecording, Boolean& transportStateChanged, Float64& sampleInTimeLine, Boolean& isCycling, Float64& cycleStartBeat, Float64& cycleEndBeat)
{
if (hostCallback.transportStateProc2)
{
if (hostCallback.transportStateProc2 (hostCallback.hostUserData, &isPlaying, &isRecording, &transportStateChanged, &sampleInTimeLine, &isCycling, &cycleStartBeat, &cycleEndBeat) == noErr)
return true;
}
return false;
}

//------------------------------------------------------------------------
FORCE_INLINE void AudioIO::remoteIOPropertyChanged (AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement)
{
if (inID == kAudioUnitProperty_IsInterAppConnected)
{
bool wasConnected = interAppAudioConnected;
updateInterAppAudioConnectionState ();
if (wasConnected != interAppAudioConnected)
{
stop ();
start ();
}
}
}

//------------------------------------------------------------------------
FORCE_INLINE OSStatus AudioIO::renderCallback (AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
if (ioData->mNumberBuffers == ioBufferList->mNumberBuffers)
{
for (uint32 i = 0; i < ioData->mNumberBuffers; i++)
{
memcpy (ioData->mBuffers[i].mData, ioBufferList->mBuffers[i].mData, ioData->mBuffers[i].mDataByteSize);
}
bool outputIsSilence = ioActionFlags ? *ioActionFlags & kAudioUnitRenderAction_OutputIsSilence : false;
for (auto processor : audioProcessors)
{
outputIsSilence = false;
processor->process (inTimeStamp, inBusNumber, inNumberFrames, ioData, outputIsSilence, this);
}
if (ioActionFlags)
{
*ioActionFlags = outputIsSilence ? kAudioUnitRenderAction_OutputIsSilence : 0;
}
}
return noErr;
}

//------------------------------------------------------------------------
FORCE_INLINE OSStatus AudioIO::inputCallback (AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
OSStatus status = AudioUnitRender (remoteIO, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioBufferList);
return status;
}

//------------------------------------------------------------------------
FORCE_INLINE void AudioIO::midiEventCallback (UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame)
{
for (auto processor : audioProcessors)
{
processor->onMIDIEvent (inStatus, inData1, inData2, inOffsetSampleFrame, true);
}
}

//------------------------------------------------------------------------
OSStatus AudioIO::inputCallbackStatic (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
AudioIO* io = (AudioIO*)inRefCon;
return io->inputCallback (ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData);
}

//------------------------------------------------------------------------
OSStatus AudioIO::renderCallbackStatic (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
AudioIO* io = (AudioIO*)inRefCon;
return io->renderCallback (ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData);
}

//------------------------------------------------------------------------
void AudioIO::propertyChangeStatic (void *inRefCon, AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement)
{
AudioIO* audioIO = (AudioIO*)inRefCon;
audioIO->remoteIOPropertyChanged(inID, inScope, inElement);
}

//------------------------------------------------------------------------
void AudioIO::midiEventCallbackStatic (void *inRefCon, UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame)
{
AudioIO* audioIO = (AudioIO*)inRefCon;
audioIO->midiEventCallback(inStatus, inData1, inData2, inOffsetSampleFrame);
}

}}}

+ 29
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/CMakeLists.txt View File

@@ -0,0 +1,29 @@
if(MAC AND XCODE AND IOS_DEVELOPMENT_TEAM)
set(target interappaudio)

set(${target}_sources
AudioIO.mm
AudioIO.h
HostApp.mm
HostApp.h
MidiIO.mm
MidiIO.h
PresetBrowserViewController.mm
PresetBrowserViewController.h
PresetManager.mm
PresetManager.h
PresetSaveViewController.mm
PresetSaveViewController.h
SettingsViewController.mm
SettingsViewController.h
VST3Editor.mm
VST3Editor.h
VST3Plugin.mm
VST3Plugin.h
VSTInterAppAudioAppDelegateBase.mm
VSTInterAppAudioAppDelegateBase.h
)
add_library(${target} STATIC ${${target}_sources})
smtg_set_platform_ios(${target})
target_link_libraries(${target} PRIVATE sdk_ios "-framework CoreGraphics" "-framework UIKit" "-framework CoreMIDI" "-framework AudioToolbox" "-framework AVFoundation")
endif()

+ 93
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/HostApp.h View File

@@ -0,0 +1,93 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/HostApp.h
// Created by : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

/// \cond ignore

#import "base/source/fobject.h"
#import "public.sdk/source/vst/hosting/hostclasses.h"
#import "pluginterfaces/vst/ivstinterappaudio.h"

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

class VST3Plugin;

//-----------------------------------------------------------------------------
class InterAppAudioHostApp : public FObject, public HostApplication, public IInterAppAudioHost
{
public:
//-----------------------------------------------------------------------------
static InterAppAudioHostApp* instance ();

void setPlugin (VST3Plugin* plugin);
VST3Plugin* getPlugin () const { return plugin; }

//-----------------------------------------------------------------------------
// IInterAppAudioHost
tresult PLUGIN_API getScreenSize (ViewRect* size, float* scale) override;
tresult PLUGIN_API connectedToHost () override;
tresult PLUGIN_API switchToHost () override;
tresult PLUGIN_API sendRemoteControlEvent (uint32 event) override;
tresult PLUGIN_API getHostIcon (void** icon) override;
tresult PLUGIN_API scheduleEventFromUI (Event& event) override;
IInterAppAudioPresetManager* PLUGIN_API createPresetManager (const TUID& cid) override;
tresult PLUGIN_API showSettingsView () override;

//-----------------------------------------------------------------------------
// HostApplication
tresult PLUGIN_API getName (String128 name) override;

OBJ_METHODS(InterAppAudioHostApp, FObject)
REFCOUNT_METHODS(FObject)
DEFINE_INTERFACES
DEF_INTERFACE(IHostApplication)
DEF_INTERFACE(IInterAppAudioHost)
END_DEFINE_INTERFACES(FObject)
protected:
InterAppAudioHostApp ();
VST3Plugin* plugin;
};

//------------------------------------------------------------------------
} // namespace InterAppAudio
} // namespace Vst
} // namespace Steinberg

/// \endcond

+ 169
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/HostApp.mm View File

@@ -0,0 +1,169 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/HostApp.mm
// Created by : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import "HostApp.h"
#import "AudioIO.h"
#import "VST3Plugin.h"
#import "PresetManager.h"
#import "SettingsViewController.h"
#import "base/source/updatehandler.h"
#import "pluginterfaces/gui/iplugview.h"

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

//------------------------------------------------------------------------
InterAppAudioHostApp* InterAppAudioHostApp::instance ()
{
static InterAppAudioHostApp gInstance;
return &gInstance;
}

//-----------------------------------------------------------------------------
InterAppAudioHostApp::InterAppAudioHostApp ()
: plugin (0)
{
}

//-----------------------------------------------------------------------------
void InterAppAudioHostApp::setPlugin (VST3Plugin* plugin)
{
this->plugin = plugin;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API InterAppAudioHostApp::getName (String128 name)
{
String str ("InterAppAudioHost");
str.copyTo (name, 0, 127);
return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API InterAppAudioHostApp::getScreenSize (ViewRect* size, float* scale)
{
if (size)
{
UIScreen* screen = [UIScreen mainScreen];
CGSize s = [screen currentMode].size;
UIWindow* window = [[[UIApplication sharedApplication] windows] objectAtIndex:0];
if (window)
{
NSArray* subViews = [window subviews];
if ([subViews count] == 1)
{
s = [[subViews objectAtIndex:0] bounds].size;
}
}
size->left = 0;
size->top = 0;
size->right = s.width;
size->bottom = s.height;
if (scale)
{
*scale = screen.scale;
}
return kResultTrue;
}
return kInvalidArgument;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API InterAppAudioHostApp::connectedToHost ()
{
return AudioIO::instance ()->getInterAppAudioConnected () ? kResultTrue : kResultFalse;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API InterAppAudioHostApp::switchToHost ()
{
return AudioIO::instance ()->switchToHost () ? kResultTrue : kResultFalse;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API InterAppAudioHostApp::sendRemoteControlEvent (uint32 event)
{
return AudioIO::instance ()->sendRemoteControlEvent (
static_cast<AudioUnitRemoteControlEvent> (event)) ?
kResultTrue :
kResultFalse;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API InterAppAudioHostApp::getHostIcon (void** icon)
{
if (icon)
{
UIImage* hostIcon = AudioIO::instance ()->getHostIcon ();
if (hostIcon)
{
CGImageRef cgImage = [hostIcon CGImage];
if (cgImage)
{
*icon = cgImage;
return kResultTrue;
}
}
return kNotImplemented;
}
return kInvalidArgument;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API InterAppAudioHostApp::scheduleEventFromUI (Event& event)
{
if (plugin)
{
return plugin->scheduleEventFromUI (event);
}
return kNotInitialized;
}

//-----------------------------------------------------------------------------
IInterAppAudioPresetManager* PLUGIN_API InterAppAudioHostApp::createPresetManager (const TUID& cid)
{
return plugin ? new PresetManager (plugin, cid) : nullptr;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API InterAppAudioHostApp::showSettingsView ()
{
showIOSettings ();
return kResultTrue;
}

}}}

+ 27
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/LaunchScreen.storyboard View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

+ 92
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/MidiIO.h View File

@@ -0,0 +1,92 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/MidiIO.h
// Created by : Steinberg, 09/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include <CoreMIDI/CoreMIDI.h>
#include "AudioIO.h"
#include <vector>

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

//-----------------------------------------------------------------------------
class MidiIO
{
public:
static MidiIO& instance ();
bool setEnabled (bool state);
bool isEnabled () const;

// MIDI Network is experimental, don't use yet
void setMidiNetworkEnabled (bool state);
bool isMidiNetworkEnabled () const;
void setMidiNetworkPolicy (MIDINetworkConnectionPolicy policy);
MIDINetworkConnectionPolicy getMidiNetworkPolicy () const;

void addProcessor (IMidiProcessor* processor);
void removeProcessor (IMidiProcessor* processor);

//-----------------------------------------------------------------------------
private:
MidiIO ();
~MidiIO ();

void onInput (const MIDIPacketList *pktlist);
void onSourceAdded (MIDIObjectRef source);
void onSetupChanged ();
void disconnectSources ();
MIDIClientRef client;
MIDIPortRef inputPort;
MIDIEndpointRef destPort;

typedef std::vector<IMidiProcessor*> MidiProcessors;
MidiProcessors midiProcessors;

typedef std::vector<MIDIEndpointRef> ConnectionList;
ConnectionList connectedSources;

static void readProc (const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon);
static void notifyProc (const MIDINotification *message, void *refCon);
};

//------------------------------------------------------------------------
} // namespace InterAppAudio
} // namespace Vst
} // namespace Steinberg

+ 223
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/MidiIO.mm View File

@@ -0,0 +1,223 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/MidiIO.mm
// Created by : Steinberg, 09/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import "MidiIO.h"
#import <CoreMIDI/MIDINetworkSession.h>

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

//-----------------------------------------------------------------------------
MidiIO& MidiIO::instance ()
{
static MidiIO gInstance;
return gInstance;
}

//-----------------------------------------------------------------------------
MidiIO::MidiIO ()
: client (0)
, inputPort (0)
, destPort (0)
{
}

//-----------------------------------------------------------------------------
MidiIO::~MidiIO ()
{
setEnabled (false);
}

//-----------------------------------------------------------------------------
void MidiIO::addProcessor (IMidiProcessor* processor)
{
midiProcessors.push_back (processor);
}

//-----------------------------------------------------------------------------
void MidiIO::removeProcessor (IMidiProcessor* processor)
{
auto it = std::find (midiProcessors.begin (), midiProcessors.end (), processor);
if (it != midiProcessors.end ())
{
midiProcessors.erase (it);
}
}

//-----------------------------------------------------------------------------
bool MidiIO::isEnabled () const
{
return client != 0;
}

//-----------------------------------------------------------------------------
bool MidiIO::setEnabled (bool state)
{
if (state)
{
if (client)
return true;
OSStatus err;
NSString* name = [[NSBundle mainBundle] bundleIdentifier];
if (err = MIDIClientCreate ((__bridge CFStringRef)name, notifyProc, this, &client) != noErr)
return false;
if (err = MIDIInputPortCreate (client, CFSTR("Input"), readProc, this, &inputPort) != noErr)
{
MIDIClientDispose (client);
client = 0;
return false;
}
name = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleDisplayName"];
if (err = MIDIDestinationCreate (client, (__bridge CFStringRef)name, readProc, this, &destPort) != noErr)
{
MIDIPortDispose (inputPort);
inputPort = 0;
MIDIClientDispose (client);
client = 0;
return false;
}
}
else
{
if (client == 0)
return true;
disconnectSources ();
MIDIEndpointDispose (destPort);
destPort = 0;
MIDIPortDispose (inputPort);
inputPort = 0;
MIDIClientDispose (client);
client = 0;
}
return true;
}

//-----------------------------------------------------------------------------
void MidiIO::setMidiNetworkEnabled (bool state)
{
if (inputPort && isMidiNetworkEnabled() != state)
{
if (!state)
{
MIDIPortDisconnectSource (inputPort, [MIDINetworkSession defaultSession].sourceEndpoint);
}
[MIDINetworkSession defaultSession].enabled = state;
if (state)
{
MIDIPortConnectSource (inputPort, [MIDINetworkSession defaultSession].sourceEndpoint, 0);
}
}
}

//-----------------------------------------------------------------------------
bool MidiIO::isMidiNetworkEnabled () const
{
return [MIDINetworkSession defaultSession].isEnabled;
}

//-----------------------------------------------------------------------------
void MidiIO::setMidiNetworkPolicy (MIDINetworkConnectionPolicy policy)
{
[MIDINetworkSession defaultSession].connectionPolicy = policy;
}

//-----------------------------------------------------------------------------
MIDINetworkConnectionPolicy MidiIO::getMidiNetworkPolicy () const
{
return [MIDINetworkSession defaultSession].connectionPolicy;
}

//-----------------------------------------------------------------------------
void MidiIO::onInput (const MIDIPacketList *pktlist)
{
const MIDIPacket* packet = &pktlist->packet[0];
for (UInt32 i = 0; i < pktlist->numPackets; i++)
{
for (auto processor : midiProcessors)
{
processor->onMIDIEvent (packet->data[0], packet->data[1], packet->data[2], 0, false);
}
packet = MIDIPacketNext (packet);
}
}

//-----------------------------------------------------------------------------
void MidiIO::onSourceAdded (MIDIObjectRef source)
{
connectedSources.push_back ((MIDIEndpointRef)source);
MIDIPortConnectSource (inputPort, (MIDIEndpointRef)source, NULL);
}

//-----------------------------------------------------------------------------
void MidiIO::disconnectSources ()
{
for (auto source : connectedSources)
MIDIPortDisconnectSource (inputPort, source);
connectedSources.clear ();
}

//-----------------------------------------------------------------------------
void MidiIO::onSetupChanged ()
{
disconnectSources ();
ItemCount numSources = MIDIGetNumberOfSources ();
for (ItemCount i = 0; i < numSources; i++)
{
onSourceAdded (MIDIGetSource (i));
}
}

//-----------------------------------------------------------------------------
void MidiIO::readProc (const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon)
{
MidiIO* io = static_cast<MidiIO*>(readProcRefCon);
io->onInput (pktlist);
}

//-----------------------------------------------------------------------------
void MidiIO::notifyProc (const MIDINotification *message, void *refCon)
{
if (message->messageID == kMIDIMsgSetupChanged)
{
MidiIO* mio = (MidiIO*)refCon;
mio->onSetupChanged ();
}
}

}}} // namespaces

+ 69
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetBrowserView.xib View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="10117" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PresetBrowserViewController">
<connections>
<outlet property="containerView" destination="klJ-ou-M84" id="oc3-yW-Wj1"/>
<outlet property="presetTableView" destination="7ve-UC-DYv" id="DY3-Yy-Nem"/>
<outlet property="view" destination="2" id="3"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="2">
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="RKH-M0-6se">
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<state key="normal" title="Button">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="cancel:" destination="-1" eventType="touchUpInside" id="HBx-cS-lfH"/>
</connections>
</button>
<view opaque="NO" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="klJ-ou-M84">
<rect key="frame" x="163" y="30" width="698" height="708"/>
<subviews>
<tableView opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="7ve-UC-DYv">
<rect key="frame" x="20" y="20" width="658" height="630"/>
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="separatorColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<outlet property="dataSource" destination="-1" id="FIu-tQ-zaK"/>
<outlet property="delegate" destination="-1" id="Wmb-vA-YdQ"/>
</connections>
</tableView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IWt-40-Jgp">
<rect key="frame" x="20" y="668" width="48" height="30"/>
<state key="normal" title="Edit">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="toggleEditMode:" destination="-1" eventType="touchUpInside" id="uii-wI-Qvl"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="z3K-EZ-Ed5">
<rect key="frame" x="630" y="668" width="48" height="30"/>
<state key="normal" title="Cancel">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="cancel:" destination="-2" eventType="touchUpInside" id="2I9-2I-AWP"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="0.95000000000000007" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
</view>
</objects>
</document>

+ 59
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetBrowserViewController.h View File

@@ -0,0 +1,59 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/PresetBrowserViewController.h
// Created by : Steinberg, 09/2013
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

/// \cond ignore

#ifdef __OBJC__

#import <UIKit/UIKit.h>
#import <functional>

//-----------------------------------------------------------------------------
@interface PresetBrowserViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
//-----------------------------------------------------------------------------

- (id)initWithCallback:(std::function<void (const char* presetPath)>)callback;

- (void)setFactoryPresets:(NSArray*)factoryPresets userPresets:(NSArray*)userPresets;

@end

#endif // __OBJC__

/// \endcond


+ 272
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetBrowserViewController.mm View File

@@ -0,0 +1,272 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/PresetBrowserViewController.mm
// Created by : Steinberg, 09/2013
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------


#import "PresetBrowserViewController.h"
#import "pluginterfaces/base/funknown.h"

static NSTimeInterval kAnimationTime = 0.2;

//------------------------------------------------------------------------
@interface PresetBrowserViewController ()
//------------------------------------------------------------------------
{
IBOutlet UITableView* presetTableView;
IBOutlet UIView* containerView;

std::function<void (const char* presetPath)> callback;
Steinberg::FUID uid;
}

@property (strong) NSArray* factoryPresets;
@property (strong) NSArray* userPresets;
@property (strong) NSArray* displayPresets;
@property (assign) BOOL editMode;

@end

//------------------------------------------------------------------------
@implementation PresetBrowserViewController
//------------------------------------------------------------------------

//------------------------------------------------------------------------
- (id)initWithCallback:(std::function<void (const char* presetPath)>)_callback
{
self = [super initWithNibName:@"PresetBrowserView" bundle:nil];
if (self)
{
callback = _callback;

self.view.alpha = 0.;
UIViewController* rootViewController = [[UIApplication sharedApplication].windows[0] rootViewController];
[rootViewController addChildViewController:self];
[rootViewController.view addSubview:self.view];
[UIView animateWithDuration:kAnimationTime animations:^{
self.view.alpha = 1.;
}];
}
return self;
}

//------------------------------------------------------------------------
- (void)setFactoryPresets:(NSArray*)factoryPresets userPresets:(NSArray*)userPresets
{
self.factoryPresets = factoryPresets;
self.userPresets = userPresets;
[self updatePresetArray];
dispatch_async (dispatch_get_main_queue (), ^{
[presetTableView reloadData];
});
}

//------------------------------------------------------------------------
- (void)viewDidLoad
{
[super viewDidLoad];
containerView.layer.shadowOpacity = 0.5;
containerView.layer.shadowOffset = CGSizeMake (5, 5);
containerView.layer.shadowRadius = 5;
}

//------------------------------------------------------------------------
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}

//------------------------------------------------------------------------
- (void)updatePresetArray
{
if (self.userPresets)
{
self.displayPresets = [[self.factoryPresets arrayByAddingObjectsFromArray:self.userPresets] sortedArrayUsingComparator:^NSComparisonResult (NSURL* obj1, NSURL* obj2) {
return [[obj1 lastPathComponent] caseInsensitiveCompare:[obj2 lastPathComponent]];
}];
}
else
{
self.displayPresets = self.factoryPresets;
}
}

//------------------------------------------------------------------------
- (void)removeSelf
{
[UIView animateWithDuration:kAnimationTime animations:^{
self.view.alpha = 0.;
} completion:^(BOOL finished) {
[self.view removeFromSuperview];
[self removeFromParentViewController];
}];
}

//------------------------------------------------------------------------
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSURL* url = [self.displayPresets objectAtIndex:indexPath.row];
if (url)
{
callback ([[url path] UTF8String]);
}
[self removeSelf];
}

//------------------------------------------------------------------------
- (IBAction)toggleEditMode:(id)sender
{
self.editMode = !self.editMode;
if (self.editMode)
{
NSMutableArray* indexPaths = [NSMutableArray new];
for (NSURL* url in self.factoryPresets)
{
NSUInteger index = [self.displayPresets indexOfObjectIdenticalTo:url];
[indexPaths addObject:[NSIndexPath indexPathForRow:index inSection:0]];
}
[presetTableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
}
else
{
[self updatePresetArray];
NSMutableArray* indexPaths = [NSMutableArray new];
for (NSURL* url in self.factoryPresets)
{
NSUInteger index = [self.displayPresets indexOfObjectIdenticalTo:url];
[indexPaths addObject:[NSIndexPath indexPathForRow:index inSection:0]];
}
[presetTableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
}
[presetTableView setEditing:self.editMode animated:YES];
}

//------------------------------------------------------------------------
- (IBAction)cancel:(id)sender
{
if (callback)
{
callback (0);
}
[self removeSelf];
}

//------------------------------------------------------------------------
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.editMode)
{
return [self.userPresets count];
}
return [self.displayPresets count];
}

//------------------------------------------------------------------------
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PresetBrowserCell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"PresetBrowserCell"];
}

cell.backgroundColor = [UIColor clearColor];
NSURL* presetUrl = nil;
if (self.editMode)
{
presetUrl = [self.userPresets objectAtIndex:indexPath.row];
cell.detailTextLabel.text = @"User";
}
else
{
presetUrl = [self.displayPresets objectAtIndex:indexPath.row];
if ([self.factoryPresets indexOfObject:presetUrl] == NSNotFound)
{
cell.detailTextLabel.text = @"User";
}
else
{
cell.detailTextLabel.text = @"Factory";
}
}

cell.textLabel.text = [[presetUrl lastPathComponent] stringByDeletingPathExtension];

return cell;
}

//------------------------------------------------------------------------
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.editMode)
{
return YES;
}
return NO;
}

//------------------------------------------------------------------------
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSURL* presetUrl = [self.userPresets objectAtIndex:indexPath.row];
if (presetUrl)
{
NSFileManager* fs = [NSFileManager defaultManager];
NSError* error = nil;
if ([fs removeItemAtURL:presetUrl error:&error] == NO)
{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:[error localizedDescription]
message:[error localizedRecoverySuggestion]
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Dismiss", @"")
otherButtonTitles:nil];
[alert show];
}
else
{
NSMutableArray* newArray = [NSMutableArray arrayWithArray:self.userPresets];
[newArray removeObject:presetUrl];
self.userPresets = newArray;
[presetTableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
}

@end

+ 92
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetManager.h View File

@@ -0,0 +1,92 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/PresetManager.h
// Created by : Steinberg, 10/2013
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "VST3Plugin.h"
#include "pluginterfaces/vst/ivstinterappaudio.h"
#include "base/source/fstring.h"

#if __OBJC__
@class NSArray, PresetBrowserViewController, PresetSaveViewController;
#else
struct NSArray;
struct PresetBrowserViewController;
struct PresetSaveViewController;
#endif

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

class PresetManager : public FObject, public IInterAppAudioPresetManager
{
public:
PresetManager (VST3Plugin* plugin, const TUID& cid);

tresult PLUGIN_API runLoadPresetBrowser () override;
tresult PLUGIN_API runSavePresetBrowser () override;
tresult PLUGIN_API loadNextPreset () override;
tresult PLUGIN_API loadPreviousPreset () override;

DEFINE_INTERFACES
DEF_INTERFACE(IInterAppAudioPresetManager)
END_DEFINE_INTERFACES(FObject)
REFCOUNT_METHODS(FObject)

private:
enum PresetPathType {
kFactory,
kUser
};
NSArray* getPresetPaths (PresetPathType type);

tresult loadPreset (bool next);
tresult loadPreset (const char* path);
void savePreset (const char* path);

VST3Plugin* plugin;
PresetBrowserViewController* visiblePresetBrowserViewController;
PresetSaveViewController* visibleSavePresetViewController;
FUID cid;
String lastPreset;
};

//------------------------------------------------------------------------
} // namespace InterAppAudio
} // namespace Vst
} // namespace Steinberg


+ 281
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetManager.mm View File

@@ -0,0 +1,281 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/PresetManager.mm
// Created by : Steinberg, 10/2013
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import "PresetManager.h"
#import "public.sdk/source/vst/vstpresetfile.h"
#import "pluginterfaces/vst/ivstattributes.h"
#import "PresetBrowserViewController.h"
#import "PresetSaveViewController.h"

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

//-----------------------------------------------------------------------------
class PresetStream : public ReadOnlyBStream, public IStreamAttributes
{
public:
PresetStream (IBStream* sourceStream, TSize sourceOffset, TSize sectionSize, const char* utf8Path)
: ReadOnlyBStream (sourceStream, sourceOffset, sectionSize)
, fileName (utf8Path)
{
fileName.toWideString (kCP_Utf8);
}

virtual tresult PLUGIN_API getFileName (String128 name)
{
if (fileName.length () > 0)
{
fileName.copyTo (name, 0, 128);
return kResultTrue;
}
return kResultFalse;
}
virtual IAttributeList* PLUGIN_API getAttributes () { return 0; }

DEF_INTERFACES_1(IStreamAttributes, ReadOnlyBStream)
REFCOUNT_METHODS(ReadOnlyBStream)
protected:
String fileName;
};

//-----------------------------------------------------------------------------
PresetManager::PresetManager (VST3Plugin* plugin, const TUID& cid)
: plugin (plugin)
, visiblePresetBrowserViewController (nil)
, visibleSavePresetViewController (nil)
, cid (cid)
{
id obj = [[NSUserDefaults standardUserDefaults] objectForKey:@"PresetManager|lastPreset"];
if (obj && [obj isKindOfClass:[NSString class]])
{
lastPreset = [obj UTF8String];
}
}

//-----------------------------------------------------------------------------
NSArray* PresetManager::getPresetPaths (PresetPathType type)
{
if (type == kFactory)
{
return [[NSBundle mainBundle] URLsForResourcesWithExtension:@"vstpreset" subdirectory:@"Presets"];
}
NSFileManager* fs = [NSFileManager defaultManager];
NSURL* documentsUrl = [fs URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:Nil create:YES error:NULL];
if (documentsUrl)
{
NSMutableArray* userUrls = [NSMutableArray new];
NSDirectoryEnumerator* enumerator = [fs enumeratorAtURL:documentsUrl includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsSubdirectoryDescendants errorHandler:nil];
for (NSURL* url in enumerator.allObjects)
{
if ([[url pathExtension] isEqualToString:@"vstpreset"])
{
[userUrls addObject:url];
}
}
return [userUrls sortedArrayUsingComparator:^NSComparisonResult (NSURL* obj1, NSURL* obj2) {
return [[obj1 lastPathComponent] caseInsensitiveCompare:[obj2 lastPathComponent]];
}];
}
return nil;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API PresetManager::runLoadPresetBrowser ()
{
if (visiblePresetBrowserViewController != nil)
return kResultFalse;

addRef ();
visiblePresetBrowserViewController = [[PresetBrowserViewController alloc] initWithCallback:[this](const char* path) {
loadPreset (path);
visiblePresetBrowserViewController = nil;
release ();
}];
addRef ();
dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (visiblePresetBrowserViewController)
{
[visiblePresetBrowserViewController setFactoryPresets:getPresetPaths (kFactory) userPresets:getPresetPaths (kUser)];
}
release ();
});
return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API PresetManager::runSavePresetBrowser ()
{
if (visibleSavePresetViewController != nil)
return kResultFalse;

addRef ();
visibleSavePresetViewController = [[PresetSaveViewController alloc] initWithCallback:[this](const char* path) {
savePreset (path);
visibleSavePresetViewController = nil;
release ();
}];
return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API PresetManager::loadNextPreset ()
{
return loadPreset (true);
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API PresetManager::loadPreviousPreset ()
{
return loadPreset (false);
}

//-----------------------------------------------------------------------------
tresult PresetManager::loadPreset (bool next)
{
NSArray* presets = [[getPresetPaths (kFactory) arrayByAddingObjectsFromArray:getPresetPaths (kUser)] sortedArrayUsingComparator:^NSComparisonResult (NSURL* obj1, NSURL* obj2) {
return [[obj1 lastPathComponent] caseInsensitiveCompare:[obj2 lastPathComponent]];
}];

__block NSUInteger index = NSNotFound;
if (lastPreset.isEmpty() == false)
{
NSURL* lastUrl = [[NSURL fileURLWithPath:[NSString stringWithUTF8String:lastPreset]] fileReferenceURL];
if (lastUrl)
{
[presets enumerateObjectsUsingBlock:^(NSURL* obj, NSUInteger idx, BOOL *stop) {
if ([[obj fileReferenceURL] isEqual:lastUrl])
{
index = idx;
*stop = YES;
}
}];
}
}
if (index == NSNotFound)
{
if (next)
index = [presets count] - 1;
else
index = 1;
}
if (index != NSNotFound)
{
if (next)
{
if (index >= [presets count] - 1)
index = 0;
else
index++;
}
else
{
if (index == 0)
index = [presets count] - 1;
else
index--;
}
return loadPreset ([[[presets objectAtIndex:index] path] UTF8String]);
}
return kResultFalse;
}

//-----------------------------------------------------------------------------
tresult PresetManager::loadPreset (const char* path)
{
if (path)
{
IPtr<IBStream> stream = owned (FileStream::open (path, "r"));
if (stream)
{
[[NSUserDefaults standardUserDefaults] setObject:[NSString stringWithUTF8String:path] forKey:@"PresetManager|lastPreset"];
lastPreset = path;
FUnknownPtr<IComponent> component (plugin->getAudioProcessor ());
IEditController* controller = plugin->getEditController ();
if (component)
{
PresetFile pf (stream);
if (!pf.readChunkList ())
return kResultFalse;
if (pf.getClassID () != cid)
return kResultFalse;
const PresetFile::Entry* e = pf.getEntry (kComponentState);
if (e == 0)
return kResultFalse;
char* filename = strrchr (path, '/');
if (filename)
filename++;
IPtr<PresetStream> readOnlyBStream = owned (new PresetStream (stream, e->offset, e->size, filename));
tresult result = component->setState (readOnlyBStream);
if ((result == kResultTrue || result == kNotImplemented) && controller)
{
readOnlyBStream->seek (0, IBStream::kIBSeekSet);
controller->setComponentState (readOnlyBStream);
if (pf.contains (kControllerState))
{
e = pf.getEntry (kControllerState);
if (e)
{
readOnlyBStream = owned (new PresetStream (stream, e->offset, e->size, filename));
controller->setState (readOnlyBStream);
}
}
}
return result;
}
}
}
return kResultFalse;
}

//-----------------------------------------------------------------------------
void PresetManager::savePreset (const char* path)
{
IBStream* stream = FileStream::open (path, "w");
if (stream)
{
FUnknownPtr<IComponent> component (plugin->getAudioProcessor ());
IEditController* controller = plugin->getEditController ();
if (component)
{
PresetFile::savePreset (stream, cid, component, controller);
}
stream->release ();
loadPreset (path);
}
}

}}} // namespaces

+ 67
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetSaveView.xib View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="4510" systemVersion="12F37" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PresetSaveViewController">
<connections>
<outlet property="containerView" destination="SIT-sP-q5k" id="Pam-4d-cjt"/>
<outlet property="presetName" destination="4mQ-Y5-WZh" id="MJT-bn-9QR"/>
<outlet property="view" destination="2" id="0Me-yB-Sts"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="2">
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view opaque="NO" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SIT-sP-q5k">
<rect key="frame" x="256" y="192" width="512" height="104"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Preset Name :" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EGr-Dl-Wf3">
<rect key="frame" x="20" y="20" width="119" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="4mQ-Y5-WZh">
<rect key="frame" x="147" y="16" width="345" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<connections>
<outlet property="delegate" destination="-1" id="LIF-nc-eQa"/>
</connections>
</textField>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="v51-mb-0Tu">
<rect key="frame" x="446" y="71" width="46" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Save"/>
<connections>
<action selector="save:" destination="-1" eventType="touchUpInside" id="J1n-Ix-DQA"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SBt-7v-tI9">
<rect key="frame" x="20" y="71" width="54" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Cancel">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="cancel:" destination="-1" eventType="touchUpInside" id="ibs-yW-oi5"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="0.95000000000000007" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
</view>
</objects>
</document>

+ 54
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetSaveViewController.h View File

@@ -0,0 +1,54 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/PresetSaveViewController.h
// Created by : Steinberg, 09/2013
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

/// \cond ignore

#ifdef __OBJC__

#import <UIKit/UIKit.h>
#import <functional>

@interface PresetSaveViewController : UIViewController<UIAlertViewDelegate, UITextFieldDelegate>

- (id)initWithCallback:(std::function<void (const char* presetPath)>)callback;

@end

#endif //__OBJC__

/// \endcond

+ 171
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/PresetSaveViewController.mm View File

@@ -0,0 +1,171 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/PresetSaveViewController.mm
// Created by : Steinberg, 09/2013
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import "PresetSaveViewController.h"
#import "pluginterfaces/base/funknown.h"

static NSTimeInterval kAnimationTime = 0.2;

//------------------------------------------------------------------------
@interface PresetSaveViewController ()
//------------------------------------------------------------------------
{
IBOutlet UIView* containerView;
IBOutlet UITextField* presetName;

std::function<void (const char* presetPath)> callback;
Steinberg::FUID uid;
}
@end

//------------------------------------------------------------------------
@implementation PresetSaveViewController
//------------------------------------------------------------------------

//------------------------------------------------------------------------
- (id)initWithCallback:(std::function<void (const char* presetPath)>)_callback
{
self = [super initWithNibName:@"PresetSaveView" bundle:nil];
if (self)
{
callback = _callback;

self.view.alpha = 0.;
UIViewController* rootViewController = [[UIApplication sharedApplication].windows[0] rootViewController];
[rootViewController addChildViewController:self];
[rootViewController.view addSubview:self.view];
[UIView animateWithDuration:kAnimationTime animations:^{
self.view.alpha = 1.;
} completion:^(BOOL finished) {
[self showKeyboard];
}];
}
return self;
}

//------------------------------------------------------------------------
- (void)viewDidLoad
{
[super viewDidLoad];

containerView.layer.shadowOpacity = 0.5;
containerView.layer.shadowOffset = CGSizeMake (5, 5);
containerView.layer.shadowRadius = 5;
}

//------------------------------------------------------------------------
- (void)showKeyboard
{
[presetName becomeFirstResponder];
}

//------------------------------------------------------------------------
- (void)removeSelf
{
[UIView animateWithDuration:kAnimationTime animations:^{
self.view.alpha = 0.;
} completion:^(BOOL finished) {
[self.view removeFromSuperview];
[self removeFromParentViewController];
}];
}

//------------------------------------------------------------------------
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex != alertView.cancelButtonIndex)
{
callback ([[[self presetURL] path] UTF8String]);
[self removeSelf];
}
}

//------------------------------------------------------------------------
- (NSURL*)presetURL
{
NSFileManager* fs = [NSFileManager defaultManager];
NSURL* documentsUrl = [fs URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:Nil create:YES error:NULL];
if (documentsUrl)
{
NSURL* presetPath = [[documentsUrl URLByAppendingPathComponent:presetName.text] URLByAppendingPathExtension:@"vstpreset"];
return presetPath;
}
return nil;
}

//------------------------------------------------------------------------
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if ([textField.text length] > 0)
{
[self save:textField];
return YES;
}
return NO;
}

//------------------------------------------------------------------------
- (IBAction)save:(id)sender
{
if (callback)
{
NSURL* presetPath = [self presetURL];
NSFileManager* fs = [NSFileManager defaultManager];
if ([fs fileExistsAtPath:[presetPath path]])
{
// alert for overwrite
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"A Preset with this name already exists" message:@"Save it anyway ?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Save", nil];
[alert show];
return;
}
callback ([[presetPath path] UTF8String]);
}
[self removeSelf];
}

//------------------------------------------------------------------------
- (IBAction)cancel:(id)sender
{
if (callback)
{
callback (0);
}
[self removeSelf];
}

@end

+ 77
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/SettingsView.xib View File

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="4510" systemVersion="12F45" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SettingsViewController">
<connections>
<outlet property="containerView" destination="RNQ-ag-wXs" id="Snq-jH-mGX"/>
<outlet property="midiOnSwitch" destination="RUK-3J-c68" id="fsn-qn-B1b"/>
<outlet property="tempoView" destination="7Wa-1f-ZEh" id="aAo-kk-UXa"/>
<outlet property="view" destination="2" id="3"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="2">
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view opaque="NO" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RNQ-ag-wXs">
<rect key="frame" x="272" y="266" width="481" height="236"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RUK-3J-c68">
<rect key="frame" x="165" y="92" width="51" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<connections>
<action selector="enableMidi:" destination="-1" eventType="valueChanged" id="W1y-Cl-XZT"/>
</connections>
</switch>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Enable MIDI Input" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uh8-Ad-fHW">
<rect key="frame" x="20" y="97" width="137" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gsH-Se-9I1">
<rect key="frame" x="220" y="186" width="40" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" title="Close">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="close:" destination="-1" eventType="touchUpInside" id="8fR-1E-VU7"/>
</connections>
</button>
<pickerView contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7Wa-1f-ZEh">
<rect key="frame" x="329" y="0.0" width="86" height="216"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<connections>
<outlet property="dataSource" destination="-1" id="kTa-mw-jgX"/>
<outlet property="delegate" destination="-1" id="afl-U5-l43"/>
</connections>
</pickerView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="BPM" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ccr-8n-eGh">
<rect key="frame" x="423" y="97" width="38" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Tempo" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jiY-aT-q6h">
<rect key="frame" x="267" y="97" width="52" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="0.95000000000000007" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
</view>
</objects>
</document>

+ 49
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/SettingsViewController.h View File

@@ -0,0 +1,49 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/SettingsViewController.h
// Created by : Steinberg, 09/2013
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#ifdef __OBJC__

#import <UIKit/UIKit.h>

@interface SettingsViewController : UIViewController<UIPickerViewDataSource, UIPickerViewDelegate>

@end

#endif // __OBJC__

extern void showIOSettings ();

+ 144
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/SettingsViewController.mm View File

@@ -0,0 +1,144 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/SettingsViewController.mm
// Created by : Steinberg, 09/2013
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import "SettingsViewController.h"
#import "MidiIO.h"
#import "AudioIO.h"
#import <CoreMIDI/MIDINetworkSession.h>

using namespace Steinberg::Vst::InterAppAudio;

static const NSTimeInterval kAnimationTime = 0.2;
static const NSUInteger kMinTempo = 30;

//------------------------------------------------------------------------
@interface SettingsViewController ()
//------------------------------------------------------------------------
{
IBOutlet UIView* containerView;
IBOutlet UISwitch* midiOnSwitch;
IBOutlet UIPickerView* tempoView;
}
@end

//------------------------------------------------------------------------
@implementation SettingsViewController
//------------------------------------------------------------------------

//------------------------------------------------------------------------
- (id)init
{
self = [super initWithNibName:@"SettingsView" bundle:nil];
if (self)
{
// Custom initialization
}
return self;
}

//------------------------------------------------------------------------
- (void)viewDidLoad
{
[super viewDidLoad];

containerView.layer.shadowOpacity = 0.5;
containerView.layer.shadowOffset = CGSizeMake (5, 5);
containerView.layer.shadowRadius = 5;

midiOnSwitch.on = MidiIO::instance ().isEnabled ();

Float64 tempo = AudioIO::instance()->getStaticFallbackTempo ();
[tempoView selectRow:tempo - kMinTempo inComponent:0 animated:YES];
}

//------------------------------------------------------------------------
- (IBAction)enableMidi:(id)sender
{
BOOL state = midiOnSwitch.on;
MidiIO::instance().setEnabled (state);
}

//------------------------------------------------------------------------
- (IBAction)close:(id)sender
{
[UIView animateWithDuration:kAnimationTime animations:^{
self.view.alpha = 0.;
} completion:^(BOOL finished) {
[self.view removeFromSuperview];
[self removeFromParentViewController];
}];
}

//------------------------------------------------------------------------
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
AudioIO::instance()->setStaticFallbackTempo (row + kMinTempo);
}

//------------------------------------------------------------------------
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}

//------------------------------------------------------------------------
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 301 - kMinTempo;
}

//------------------------------------------------------------------------
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [@(row + kMinTempo) stringValue];
}

@end

//------------------------------------------------------------------------
void showIOSettings ()
{
SettingsViewController* controller = [[SettingsViewController alloc] init];
controller.view.alpha = 0.;
UIViewController* rootViewController = [[UIApplication sharedApplication].windows[0] rootViewController];
[rootViewController addChildViewController:controller];
[rootViewController.view addSubview:controller.view];
[UIView animateWithDuration:kAnimationTime animations:^{
controller.view.alpha = 1.;
}];
}

+ 83
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/VST3Editor.h View File

@@ -0,0 +1,83 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/VST3Editor.h
// Created by : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

/// \cond ignore

#import "base/source/fobject.h"
#import "pluginterfaces/gui/iplugview.h"
#import <UIKit/UIKit.h>

namespace Steinberg {
namespace Vst {
class IEditController;

namespace InterAppAudio {

//------------------------------------------------------------------------
class VST3Editor : public FObject, public IPlugFrame
{
public:
//------------------------------------------------------------------------
VST3Editor ();
virtual ~VST3Editor ();
bool init (const CGRect& frame);
bool attach (IEditController* editController);

UIViewController* getViewController () const { return viewController; }
OBJ_METHODS(VST3Editor, FObject)
REFCOUNT_METHODS(FObject)
DEFINE_INTERFACES
DEF_INTERFACE(IPlugFrame)
END_DEFINE_INTERFACES(FObject)
protected:

// IPlugFrame
tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* newSize) override;

IPlugView* plugView;
UIViewController* viewController;
};

//------------------------------------------------------------------------
} // namespace InterAppAudio
} // namespace Vst
} // namespace Steinberg

/// \endcond

+ 129
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/VST3Editor.mm View File

@@ -0,0 +1,129 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/VST3Editor.mm
// Created by : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import "VST3Editor.h"
#import "pluginterfaces/vst/ivsteditcontroller.h"

//------------------------------------------------------------------------
@interface VST3EditorViewController : UIViewController
//------------------------------------------------------------------------

@end

//------------------------------------------------------------------------
@implementation VST3EditorViewController
//------------------------------------------------------------------------

- (BOOL)prefersStatusBarHidden { return YES; }
- (BOOL)shouldAutorotate { return YES; }
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft|UIInterfaceOrientationMaskLandscapeRight;
}

@end

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

//------------------------------------------------------------------------
VST3Editor::VST3Editor ()
: plugView (0)
, viewController (0)
{
}

//------------------------------------------------------------------------
VST3Editor::~VST3Editor ()
{
if (plugView)
{
plugView->release ();
}
}

//------------------------------------------------------------------------
bool VST3Editor::init (const CGRect& frame)
{
viewController = [VST3EditorViewController new];
viewController.view = [[UIView alloc] initWithFrame:frame];
return true;
}

//------------------------------------------------------------------------
bool VST3Editor::attach (IEditController* editController)
{
FUnknownPtr<IEditController2> ec2 (editController);
if (ec2)
{
ec2->setKnobMode (kLinearMode);
}
plugView = editController->createView (ViewType::kEditor);
if (plugView)
{
if (plugView->isPlatformTypeSupported (kPlatformTypeUIView) == kResultTrue)
{
plugView->setFrame (this);
if (plugView->attached ((__bridge void*)viewController.view, kPlatformTypeUIView) == kResultTrue)
{
return true;
}
}
plugView->release ();
plugView = 0;
}
return false;
}

//------------------------------------------------------------------------
tresult PLUGIN_API VST3Editor::resizeView (IPlugView* view, ViewRect* newSize)
{
if (newSize && plugView && plugView == view)
{
if (view->onSize (newSize) == kResultTrue)
return kResultTrue;
return kResultFalse;
}
return kInvalidArgument;
}

//------------------------------------------------------------------------
} // InterAppAudio
} // Vst
} // Steinberg

+ 144
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/VST3Plugin.h View File

@@ -0,0 +1,144 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/VST3Plugin.h
// Created by : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

/// \cond ignore

#import "AudioIO.h"
#import "base/source/fobject.h"
#import "base/source/timer.h"
#import "base/source/tringbuffer.h"
#import "pluginterfaces/vst/ivstaudioprocessor.h"
#import "pluginterfaces/vst/ivsteditcontroller.h"
#import "pluginterfaces/vst/ivstprocesscontext.h"
#import "public.sdk/source/vst/hosting/processdata.h"
#import "public.sdk/source/vst/hosting/parameterchanges.h"
#import "public.sdk/source/vst/hosting/eventlist.h"
#import <atomic>
#import <map>

#ifndef __OBJC__
struct NSData;
#endif

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

static const int32 kMaxUIEvents = 100;

//------------------------------------------------------------------------
class VST3Plugin : public FObject, public IComponentHandler, public IAudioIOProcessor, public ITimerCallback
{
public:
//------------------------------------------------------------------------
VST3Plugin ();
virtual ~VST3Plugin ();

bool init ();

IEditController* getEditController () const { return editController; }
IAudioProcessor* getAudioProcessor () const { return processor; }

tresult scheduleEventFromUI (Event& event);

NSData* getProcessorState ();
bool setProcessorState (NSData* data);

NSData* getControllerState ();
bool setControllerState (NSData* data);

OBJ_METHODS(VST3Plugin, FObject)
REFCOUNT_METHODS(FObject)
DEFINE_INTERFACES
DEF_INTERFACE(IComponentHandler)
END_DEFINE_INTERFACES(FObject)
protected:
typedef std::map<uint32, uint32> NoteIDPitchMap;
typedef uint32 ChannelAndCtrlNumber;
typedef std::map<ChannelAndCtrlNumber, ParamID> MIDIControllerToParamIDMap;

void createProcessorAndController ();

void updateProcessContext (AudioIO* audioIO);
MIDIControllerToParamIDMap createMIDIControllerToParamIDMap ();

// IComponentHandler
tresult PLUGIN_API beginEdit (ParamID id) override;
tresult PLUGIN_API performEdit (ParamID id, ParamValue valueNormalized) override;
tresult PLUGIN_API endEdit (ParamID id) override;
tresult PLUGIN_API restartComponent (int32 flags) override;

// IAudioIOProcessor
void willStartAudio (AudioIO* audioIO) override;
void didStopAudio (AudioIO* audioIO) override;
void onMIDIEvent (UInt32 status, UInt32 data1, UInt32 data2, UInt32 sampleOffset, bool withinRealtimeThread) override;
void process (const AudioTimeStamp* timeStamp, UInt32 busNumber, UInt32 numFrames, AudioBufferList* ioData, bool& outputIsSilence, AudioIO* audioIO) override;

// ITimerCallback
void onTimer (Timer* timer) override;

IAudioProcessor* processor;
IEditController* editController;
Timer* timer;
HostProcessData processData;
ProcessContext processContext;
ParameterChangeTransfer inputParamChangeTransfer;
ParameterChangeTransfer outputParamChangeTransfer;
ParameterChanges inputParamChanges;
ParameterChanges outputParamChanges;
EventList inputEvents;
NoteIDPitchMap noteIDPitchMap;
std::atomic<int32> lastNodeID {0};
bool processing;
MIDIControllerToParamIDMap midiControllerToParamIDMap;

TRingBuffer<Event> uiScheduledEvents;
static ChannelAndCtrlNumber channelAndCtrlNumber (uint16 channel, CtrlNumber ctrler) { return (channel << 16) + ctrler; }
};

//------------------------------------------------------------------------
} // namespace InterAppAudio
} // namespace Vst
} // namespace Steinberg

/// \endcond

+ 607
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/VST3Plugin.mm View File

@@ -0,0 +1,607 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/VST3Plugin.mm
// Created by : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import "VST3Plugin.h"
#import "HostApp.h"
#import "pluginterfaces/base/ipluginbase.h"
#import "pluginterfaces/vst/ivstmessage.h"
#import "pluginterfaces/vst/ivstmidicontrollers.h"
#import "pluginterfaces/vst/ivstinterappaudio.h"
#import "public.sdk/source/vst/auwrapper/NSDataIBStream.h"
#import "public.sdk/source/vst/hosting/hostclasses.h"
#import "base/source/updatehandler.h"
#import <libkern/OSAtomic.h>

//------------------------------------------------------------------------
extern "C"
{
bool bundleEntry (CFBundleRef);
bool bundleExit (void);
}

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

//------------------------------------------------------------------------
__attribute__((constructor))
static void InitUpdateHandler ()
{
UpdateHandler::instance ();
}

//------------------------------------------------------------------------
VST3Plugin::VST3Plugin ()
: processor (0)
, editController (0)
, timer (0)
, processing (false)
{
processData.processContext = &processContext;
processData.inputParameterChanges = &inputParamChanges;
processData.outputParameterChanges = &outputParamChanges;
processData.inputEvents = &inputEvents;

}

//------------------------------------------------------------------------
VST3Plugin::~VST3Plugin ()
{
}

//------------------------------------------------------------------------
bool VST3Plugin::init ()
{
if (processor == 0 && editController == 0)
{
::bundleEntry (CFBundleGetMainBundle ());
createProcessorAndController ();
}
return processor && editController;
}

//------------------------------------------------------------------------
void VST3Plugin::createProcessorAndController ()
{
Steinberg::IPluginFactory* factory = GetPluginFactory ();
if (factory == 0)
return;
IComponent* component = 0;
PClassInfo classInfo;
int32 classCount = factory->countClasses ();
for (int32 i = 0; i < classCount; i++)
{
if (factory->getClassInfo (i, &classInfo) != kResultTrue)
return;
if (strcmp (classInfo.category, kVstAudioEffectClass) == 0)
{
if (factory->createInstance (classInfo.cid, IComponent::iid, (void **)&component) != kResultTrue)
{
return;
}
break;
}
}
if (component)
{
if (component->initialize (InterAppAudioHostApp::instance ()->unknownCast ()) != kResultTrue)
{
component->release ();
return;
}
if (component->queryInterface (IEditController::iid, (void**)&editController) != kResultTrue)
{
FUID controllerCID;
if (component->getControllerClassId (controllerCID) == kResultTrue && controllerCID.isValid ())
{
if (factory->createInstance (controllerCID, IEditController::iid, (void**)&editController) != kResultTrue)
return;
editController->setComponentHandler (this);
if (editController->initialize (InterAppAudioHostApp::instance ()->unknownCast ()) != kResultTrue)
{
component->release ();
editController->release ();
editController = 0;
return;
}
FUnknownPtr<IConnectionPoint> compConnection (component);
FUnknownPtr<IConnectionPoint> ctrlerConnection (editController);
if (compConnection && ctrlerConnection)
{
compConnection->connect (ctrlerConnection);
ctrlerConnection->connect (compConnection);
}
}
else
{
component->release ();
return;
}
}
component->queryInterface (IAudioProcessor::iid, (void**)&processor);
if (processor == 0)
{
if (editController)
{
editController->release ();
editController = 0;
}
}
else
{
NSMutableData* data = [NSMutableData new];
NSMutableDataIBStream state (data);
if (component->getState (&state) == kResultTrue)
{
state.seek (0, IBStream::kIBSeekSet);
editController->setComponentState (&state);
}
int32 paramCount = editController->getParameterCount ();
inputParamChanges.setMaxParameters (paramCount);
inputParamChangeTransfer.setMaxParameters (paramCount);
outputParamChanges.setMaxParameters (paramCount);
outputParamChangeTransfer.setMaxParameters (paramCount);
midiControllerToParamIDMap = createMIDIControllerToParamIDMap ();
uiScheduledEvents.resize (kMaxUIEvents);
}
component->release ();
}
}

//------------------------------------------------------------------------
VST3Plugin::MIDIControllerToParamIDMap VST3Plugin::createMIDIControllerToParamIDMap ()
{
MIDIControllerToParamIDMap newMap;

FUnknownPtr<IMidiMapping> midiMapping (editController);
if (midiMapping)
{
uint16 channelCount = 0;
FUnknownPtr<IComponent> component (processor);
if (component)
{
int32 busCount = component->getBusCount (kEvent, kInput);
if (busCount > 0)
{
BusInfo busInfo;
if (component->getBusInfo (kEvent, kInput, 0, busInfo) == kResultTrue)
{
channelCount = busInfo.channelCount;
}
}
}
ParamID paramID;
for (int32 channel = 0; channel < channelCount; channel++)
{
for (CtrlNumber ctrler = 0; ctrler < kCountCtrlNumber; ctrler++)
{
if (midiMapping->getMidiControllerAssignment (0, channel, ctrler, paramID) == kResultTrue)
{
newMap.insert (std::make_pair (channelAndCtrlNumber (channel, ctrler), paramID));
}
}
}
}
return newMap;
}

//------------------------------------------------------------------------
tresult VST3Plugin::scheduleEventFromUI (Event& event)
{
if (event.type == Event::kNoteOnEvent)
event.noteOn.noteId = lastNodeID++;
return uiScheduledEvents.write (event) ? kResultTrue : kResultFalse;
}

//------------------------------------------------------------------------
NSData* VST3Plugin::getProcessorState ()
{
if (processor)
{
NSMutableData* data = [NSMutableData new];
NSMutableDataIBStream state (data);
FUnknownPtr<IComponent> comp (processor);
if (comp->getState (&state) == kResultTrue)
{
return data;
}
}
return nil;
}

//------------------------------------------------------------------------
bool VST3Plugin::setProcessorState (NSData* data)
{
if (editController && processor)
{
NSDataIBStream stream (data);
FUnknownPtr<IComponent> comp (processor);
if (comp->setState (&stream) == kResultTrue)
{
stream.seek (0, IBStream::kIBSeekSet);
editController->setComponentState (&stream);
return true;
}
}
return false;
}

//------------------------------------------------------------------------
NSData* VST3Plugin::getControllerState ()
{
if (editController)
{
NSMutableData* data = [NSMutableData new];
NSMutableDataIBStream state (data);
if (editController->getState (&state) == kResultTrue)
{
return data;
}
}
return nil;
}

//------------------------------------------------------------------------
bool VST3Plugin::setControllerState (NSData* data)
{
if (editController)
{
NSDataIBStream stream (data);
if (editController->setState (&stream) == kResultTrue)
{
return true;
}
}
return false;
}

//------------------------------------------------------------------------
void VST3Plugin::willStartAudio (AudioIO* audioIO)
{
noteIDPitchMap.clear ();
lastNodeID.store (0);

ProcessSetup setup;
setup.processMode = kRealtime;
setup.symbolicSampleSize = kSample32;
setup.maxSamplesPerBlock = 4096;// TODO:
setup.sampleRate = audioIO->getSampleRate ();
processor->setupProcessing (setup);
SpeakerArrangement inputs[1];
SpeakerArrangement outputs[1];
inputs[0] = SpeakerArr::kStereo;
outputs[0] = SpeakerArr::kStereo;
processor->setBusArrangements (inputs, 1, outputs, 1);
FUnknownPtr<IComponent> comp (processor);
comp->setActive (true);

processData.prepare (*comp);

FUnknownPtr<IInterAppAudioConnectionNotification> iaaConnectionNotification (editController);
if (iaaConnectionNotification)
{
iaaConnectionNotification->onInterAppAudioConnectionStateChange (audioIO->getInterAppAudioConnected () ? true : false);
}

timer = Timer::create (this, 16);
}

//------------------------------------------------------------------------
void VST3Plugin::didStopAudio (AudioIO* audioIO)
{
processor->setProcessing (false); // TODO: currently not called in Audio Thread as it should according to the VST3 spec
processing = false;
FUnknownPtr<IComponent> comp (processor);
comp->setActive (false);
timer->release ();
timer = 0;
}

//------------------------------------------------------------------------
void VST3Plugin::onMIDIEvent (UInt32 inStatus, UInt32 data1, UInt32 data2, UInt32 sampleOffset, bool withinRealtimeThread)
{
Event e = {};
e.flags = Event::kIsLive;
uint16 status = inStatus & 0xF0;
uint16 channel = inStatus & 0x0F;
if (status == 0x90 && data2 != 0) // note on
{
auto noteID = noteIDPitchMap.find ((channel << 8) + data1);
if (noteID != noteIDPitchMap.end ())
{
// for now, we just turn off the old note on
Event e2 = {};
e2.type = Event::kNoteOffEvent;
e2.noteOff.noteId = noteID->second;
e2.noteOff.channel = channel;
e2.noteOff.pitch = data1;
e2.noteOff.velocity = (float)data2 / 128.f;
e2.sampleOffset = 0;
inputEvents.addEvent (e2);
noteIDPitchMap.erase (noteID);
}
e.type = Event::kNoteOnEvent;
e.noteOn.channel = channel;
e.noteOn.pitch = data1;
e.noteOn.velocity = (float)data2 / 128.f;
e.noteOn.length = -1;
e.sampleOffset = sampleOffset;
if (withinRealtimeThread)
{
e.noteOn.noteId = lastNodeID++;
inputEvents.addEvent (e);
noteIDPitchMap.insert (std::make_pair ((channel << 8) + data1, e.noteOn.noteId));
}
else
{
scheduleEventFromUI (e);
}
}
else if (status == 0x80 || (status == 0x90 && data2 == 0)) // note off
{
auto noteID = noteIDPitchMap.find ((channel << 8) + data1);
if (noteID != noteIDPitchMap.end())
{
e.type = Event::kNoteOffEvent;
e.noteOff.noteId = noteID->second;
e.noteOff.channel = channel;
e.noteOff.pitch = data1;
e.noteOff.velocity = (float)data2 / 128.f;
e.sampleOffset = sampleOffset;
if (withinRealtimeThread)
{
inputEvents.addEvent (e);
noteIDPitchMap.erase (noteID);
}
else
{
scheduleEventFromUI (e);
}
}
else
{
NSLog (@"NoteID not found:%d", (unsigned int)data1);
}
}
else if (status == 0xb0 && data1 < kAfterTouch) // controller
{
auto it = midiControllerToParamIDMap.find (channelAndCtrlNumber (channel, data1));
if (it != midiControllerToParamIDMap.end ())
{
ParamValue value = (ParamValue)data2 / 128.;
if (withinRealtimeThread)
{
int32 index;
IParamValueQueue* queue = inputParamChanges.addParameterData (it->second, index);
if (queue)
{
queue->addPoint (sampleOffset, value, index);
}
}
else
{
inputParamChangeTransfer.addChange (it->second, value, sampleOffset);
}
}
}
else if (status == 0xe0) // pitch bend
{
auto it = midiControllerToParamIDMap.find (channelAndCtrlNumber (channel, kPitchBend));
if (it != midiControllerToParamIDMap.end ())
{
uint16 _14bit;
_14bit = (uint16)data2;
_14bit <<= 7;
_14bit |= (uint16)data1;
ParamValue value = (double)_14bit / (double)0x3fff;

if (withinRealtimeThread)
{
int32 index;
IParamValueQueue* queue = inputParamChanges.addParameterData (it->second, index);
if (queue)
{
queue->addPoint (sampleOffset, value, index);
}
}
else
{
inputParamChangeTransfer.addChange (it->second, value, sampleOffset);
}
}
}
else if (status == 0xd0) // aftertouch
{
auto it = midiControllerToParamIDMap.find (channelAndCtrlNumber (channel, kAfterTouch));
if (it != midiControllerToParamIDMap.end ())
{
ParamValue value = (ParamValue)data1 / 128.;
if (withinRealtimeThread)
{
int32 index;
IParamValueQueue* queue = inputParamChanges.addParameterData (it->second, index);
if (queue)
{
queue->addPoint (sampleOffset, value, index);
}
}
else
{
inputParamChangeTransfer.addChange (it->second, value, sampleOffset);
}
}
}
}

//------------------------------------------------------------------------
void VST3Plugin::process (const AudioTimeStamp* timeStamp, UInt32 busNumber, UInt32 numFrames, AudioBufferList* ioData, bool& outputIsSilence, AudioIO* audioIO)
{
if (processing == false)
{
processor->setProcessing (true);
processing = true;
}
updateProcessContext (audioIO);
if (timeStamp)
processContext.systemTime = timeStamp->mHostTime;

// TODO: silence state update
for (UInt32 i = 0; i < ioData->mNumberBuffers; i++)
{
processData.setChannelBuffer (kInput, 0, i, (float*)ioData->mBuffers[i].mData);
processData.setChannelBuffer (kOutput, 0, i, (float*)ioData->mBuffers[i].mData);
}
Event e;
while (uiScheduledEvents.read (e))
{
inputEvents.addEvent (e);
if (e.type == Event::kNoteOnEvent)
{
auto noteID = noteIDPitchMap.find ((e.noteOn.channel << 8) + e.noteOn.pitch);
if (noteID == noteIDPitchMap.end ())
noteIDPitchMap.insert (std::make_pair ((e.noteOn.channel << 8) + e.noteOn.pitch, e.noteOn.noteId));
}
}
processData.numSamples = numFrames;
inputParamChangeTransfer.transferChangesTo (inputParamChanges);
if (processor->process (processData) == kResultTrue)
{
inputParamChanges.clearQueue ();
outputParamChangeTransfer.transferChangesFrom (outputParamChanges);
outputParamChanges.clearQueue ();
inputEvents.clear ();
}
}

//------------------------------------------------------------------------
void VST3Plugin::updateProcessContext (AudioIO* audioIO)
{
memset (&processContext, 0, sizeof (ProcessContext));
processContext.sampleRate = audioIO->getSampleRate ();
Float64 beat = 0., tempo = 0.;
if (audioIO->getBeatAndTempo (beat, tempo))
{
processContext.state |= ProcessContext::kTempoValid | ProcessContext::kProjectTimeMusicValid;
processContext.tempo = tempo;
processContext.projectTimeMusic = beat;
}
else
{
processContext.state |= ProcessContext::kTempoValid;
processContext.tempo = 120.;
}
UInt32 deltaSampleOffsetToNextBeat = 0;
Float32 timeSigNumerator = 0;
UInt32 timeSigDenominator = 0;
Float64 currentMeasureDownBeat = 0;
if (audioIO->getMusicalTimeLocation (deltaSampleOffsetToNextBeat, timeSigNumerator, timeSigDenominator, currentMeasureDownBeat))
{
processContext.state |= ProcessContext::kTimeSigValid | ProcessContext::kBarPositionValid | ProcessContext::kClockValid;
processContext.timeSigNumerator = timeSigNumerator;
processContext.timeSigDenominator = timeSigDenominator;
processContext.samplesToNextClock = deltaSampleOffsetToNextBeat;
processContext.barPositionMusic = currentMeasureDownBeat;
}
Boolean isPlaying;
Boolean isRecording;
Boolean transportStateChanged;
Float64 currentSampleInTimeLine;
Boolean isCycling;
Float64 cycleStartBeat;
Float64 cycleEndBeat;
if (audioIO->getTransportState (isPlaying, isRecording, transportStateChanged, currentSampleInTimeLine, isCycling, cycleStartBeat, cycleEndBeat))
{
processContext.state |= ProcessContext::kCycleValid;
processContext.cycleStartMusic = cycleStartBeat;
processContext.cycleEndMusic = cycleEndBeat;
processContext.projectTimeSamples = currentSampleInTimeLine;
if (isPlaying)
processContext.state |= ProcessContext::kPlaying;
if (isCycling)
processContext.state |= ProcessContext::kCycleActive;
if (isRecording)
processContext.state |= ProcessContext::kRecording;
}
}

//------------------------------------------------------------------------
tresult PLUGIN_API VST3Plugin::beginEdit (ParamID id)
{
return kResultTrue;
}

//------------------------------------------------------------------------
tresult PLUGIN_API VST3Plugin::performEdit (ParamID id, ParamValue valueNormalized)
{
inputParamChangeTransfer.addChange (id, valueNormalized, 0);
return kResultTrue;
}

//------------------------------------------------------------------------
tresult PLUGIN_API VST3Plugin::endEdit (ParamID id)
{
return kResultTrue;
}

//------------------------------------------------------------------------
tresult PLUGIN_API VST3Plugin::restartComponent (int32 flags)
{
tresult result = kNotImplemented;

return result;
}

//------------------------------------------------------------------------
void VST3Plugin::onTimer (Timer* timer)
{
ParamID paramID;
ParamValue paramValue;
int32 sampleOffset;
while (outputParamChangeTransfer.getNextChange (paramID, paramValue, sampleOffset))
{
editController->setParamNormalized (paramID, paramValue);
}
UpdateHandler::instance ()->triggerDeferedUpdates ();
}

}}}

+ 57
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/VSTInterAppAudioAppDelegateBase.h View File

@@ -0,0 +1,57 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/VSTInterAppAudioAppDelegateBase.h
// Created by : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import <UIKit/UIKit.h>

//------------------------------------------------------------------------
/** Base UIApplicationDelegate class.
* This class provides the base handling of the audio engine, plug-in and plug-in editor\n
* You should subclass it for customization\n
* Make sure to call the methods of this class if you override one in your subclass !
*/
//------------------------------------------------------------------------
@interface VSTInterAppAudioAppDelegateBase : UIResponder <UIApplicationDelegate>
//------------------------------------------------------------------------
@property (strong, nonatomic) UIWindow *window;

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder;
- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder;
- (void)applicationDidBecomeActive:(UIApplication *)application;
- (void)applicationWillResignActive:(UIApplication *)application;

@end

+ 210
- 0
source/includes/vst3sdk/public.sdk/source/vst/interappaudio/VSTInterAppAudioAppDelegateBase.mm View File

@@ -0,0 +1,210 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/VSTInterAppAudioAppDelegateBase.mm
// Created by : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import "VSTInterAppAudioAppDelegateBase.h"

#import "public.sdk/source/vst/interappaudio/AudioIO.h"
#import "public.sdk/source/vst/interappaudio/MidiIO.h"
#import "public.sdk/source/vst/interappaudio/VST3Plugin.h"
#import "public.sdk/source/vst/interappaudio/VST3Editor.h"
#import "public.sdk/source/vst/interappaudio/HostApp.h"

using namespace Steinberg::Vst::InterAppAudio;

//------------------------------------------------------------------------
static OSType fourCharCodeToOSType (NSString* inCode)
{
OSType rval = 0;
NSData* data = [inCode dataUsingEncoding: NSMacOSRomanStringEncoding];
[data getBytes:&rval length:sizeof(rval)];
HTONL(rval);
return rval;
}

//------------------------------------------------------------------------
@interface VSTInterAppAudioAppDelegateBase ()
//------------------------------------------------------------------------
{
VST3Plugin plugin;
VST3Editor editor;
BOOL audioIOInitialized;
}
@end

//------------------------------------------------------------------------
@implementation VSTInterAppAudioAppDelegateBase
//------------------------------------------------------------------------

//------------------------------------------------------------------------
- (BOOL)initAudioIO
{
id auArray = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AudioComponents"];
if (auArray)
{
id desc = [auArray objectAtIndex:0];
if (desc)
{
NSString* typeStr = [desc objectForKey:@"type"];
NSString* subtypeStr = [desc objectForKey:@"subtype"];
NSString* manufacturerStr = [desc objectForKey:@"manufacturer"];
NSString* nameStr = [desc objectForKey:@"name"];
if (typeStr && subtypeStr && manufacturerStr && nameStr)
{
OSType type = fourCharCodeToOSType (typeStr);
OSType subtype = fourCharCodeToOSType (subtypeStr);
OSType manufacturer = fourCharCodeToOSType (manufacturerStr);
AudioIO* audioIO = AudioIO::instance ();
if (audioIO->init (type, subtype, manufacturer, (__bridge CFStringRef)nameStr) == Steinberg::kResultTrue)
{
if (plugin.init ())
{
InterAppAudioHostApp::instance ()->setPlugin (&plugin);
audioIO->addProcessor (&plugin);
audioIOInitialized = YES;
return YES;
}
}
}
}
}
return NO;
}

//------------------------------------------------------------------------
- (BOOL)createUI
{
if (audioIOInitialized)
{
[UIApplication sharedApplication].statusBarHidden = YES;
self.window = [UIWindow new];
self.window.backgroundColor = [UIColor redColor];
CGRect screenSize = self.window.bounds;

if (editor.init (screenSize))
{
self.window.rootViewController = editor.getViewController ();
[self.window makeKeyAndVisible];
if (editor.attach (plugin.getEditController ()) == false)
{
return NO;
}
}
return YES;
}
return NO;
}

//------------------------------------------------------------------------
- (void)savePluginState:(NSCoder*)coder
{
NSData* processorState = plugin.getProcessorState ();
NSData* controllerState = plugin.getControllerState ();
if (processorState)
[coder encodeObject:processorState forKey:@"VST3ProcessorState"];
if (controllerState)
[coder encodeObject:controllerState forKey:@"VST3ControllerState"];
}

//------------------------------------------------------------------------
- (void)restorePluginState:(NSCoder*)coder
{
NSData* processorState = [coder decodeObjectForKey:@"VST3ProcessorState"];
if (processorState)
{
plugin.setProcessorState (processorState);
}
NSData* controllerState = [coder decodeObjectForKey:@"VST3ControllerState"];
if (controllerState)
{
plugin.setControllerState (controllerState);
}
}

//------------------------------------------------------------------------
// UIApplicationDelegate methods
//------------------------------------------------------------------------
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return [self initAudioIO];
}

//------------------------------------------------------------------------
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
BOOL result = [self createUI];
if (result)
{
AudioIO::instance ()->start ();
}
return result;
}

//------------------------------------------------------------------------
- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder
{
[self savePluginState:coder];
[coder encodeBool:MidiIO::instance ().isEnabled () forKey:@"MIDI Enabled"];
return YES;
}

//------------------------------------------------------------------------
- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder
{
[self restorePluginState:coder];
BOOL midiEnabled = [coder decodeBoolForKey:@"MIDI Enabled"];
MidiIO::instance ().setEnabled (midiEnabled);
return YES;
}

//------------------------------------------------------------------------
- (void)applicationDidBecomeActive:(UIApplication *)application
{
AudioIO* audioIO = AudioIO::instance ();
audioIO->start ();
}

//------------------------------------------------------------------------
- (void)applicationWillResignActive:(UIApplication *)application
{
AudioIO* audioIO = AudioIO::instance ();
if (audioIO->getInterAppAudioConnected () == false && MidiIO::instance().isEnabled () == false)
{
audioIO->stop ();
}
}

@end

+ 2742
- 0
source/includes/vst3sdk/public.sdk/source/vst/testsuite/vsttestsuite.cpp
File diff suppressed because it is too large
View File


+ 720
- 0
source/includes/vst3sdk/public.sdk/source/vst/testsuite/vsttestsuite.h View File

@@ -0,0 +1,720 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Validator
// Filename : public.sdk/source/vst/vsttestsuite.h
// Created by : Steinberg, 04/2005
// Description : VST Test Suite
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/test/itest.h"
#include "public.sdk/source/vst/hosting/processdata.h"

// VST 3 interfaces
#include "pluginterfaces/base/ipluginbase.h"
#include "pluginterfaces/vst/ivstcomponent.h"
#include "pluginterfaces/vst/ivstaudioprocessor.h"
#include "pluginterfaces/vst/ivsteditcontroller.h"
#include "pluginterfaces/vst/ivstparameterchanges.h"

namespace Steinberg {
namespace Vst {

typedef int32 ProcessSampleSize;

//------------------------------------------------------------------------
#define DECLARE_VSTTEST(name) \
virtual const char* getName () const SMTG_OVERRIDE { return name; }

/** Set from outside the plug-in context (simulating a host context) */
extern void setStandardPluginContext (FUnknown* context);

//------------------------------------------------------------------------
/** Test Helper.
\ingroup TestClass */
//------------------------------------------------------------------------
class IPlugProvider : public FUnknown
{
public:
//------------------------------------------------------------------------
virtual IComponent* getComponent () = 0;
virtual IEditController* getController () = 0;
virtual tresult releasePlugIn (IComponent* component, IEditController* controller) = 0;
virtual const char8* getSubCategories () const = 0;
virtual tresult getPluginUID (FUID& uid) const = 0;

//------------------------------------------------------------------------
static const FUID iid;
};

DECLARE_CLASS_IID (IPlugProvider, 0xDB014121, 0x09144BAA, 0x87627896, 0xBE41AF5D)

//------------------------------------------------------------------------
/** VstAutomationTest helper classes.
\ingroup TestClass */
class ParamPoint
{
public:
ParamPoint () : offsetSamples (-1), value (0.), read (false) {}
void set (int32 offsetSamples, double value)
{
this->offsetSamples = offsetSamples;
this->value = value;
}
void get (int32& offsetSamples, double& value)
{
offsetSamples = this->offsetSamples;
value = this->value;
read = true;
}
bool wasRead () const { return read; }

private:
int32 offsetSamples;
double value;
bool read;
};

//------------------------------------------------------------------------
/** VstAutomationTest helper classes: implementation of IParamValueQueue.
\ingroup TestClass */
class ParamChanges : public IParamValueQueue
{
public:
ParamChanges () : id (-1), numPoints (0), numUsedPoints (0), processedFrames (0), points (nullptr)
{
FUNKNOWN_CTOR
}
virtual ~ParamChanges ()
{
if (points)
delete[] points;
FUNKNOWN_DTOR
}

DECLARE_FUNKNOWN_METHODS

void init (ParamID id, int32 numPoints)
{
this->id = id;
this->numPoints = numPoints;
numUsedPoints = 0;
if (points)
delete[] points;
points = new ParamPoint[numPoints];
processedFrames = 0;
}
bool setPoint (int32 index, int32 offsetSamples, double value)
{
if (points && (index >= 0) && (index == numUsedPoints) && (index < numPoints))
{
points[index].set (offsetSamples, value);
numUsedPoints++;
return true;
}
if (!points)
return true;
return false;
}
void resetPoints ()
{
numUsedPoints = 0;
processedFrames = 0;
}
int32 getProcessedFrames () const { return processedFrames; }
void setProcessedFrames (int32 amount) { processedFrames = amount; }
bool havePointsBeenRead (bool atAll)
{
for (int32 i = 0; i < getPointCount (); ++i)
{
if (points[i].wasRead ())
{
if (atAll)
return true;
}
else if (!atAll)
return false;
}
return !atAll;
}

//---for IParamValueQueue-------------------------
ParamID PLUGIN_API getParameterId () SMTG_OVERRIDE { return id; }
int32 PLUGIN_API getPointCount () SMTG_OVERRIDE { return numUsedPoints; }
tresult PLUGIN_API getPoint (int32 index, int32& offsetSamples, double& value) SMTG_OVERRIDE
{
if (points && (index < numUsedPoints) && (index >= 0))
{
points[index].get (offsetSamples, value);
return kResultTrue;
}
return kResultFalse;
}
tresult PLUGIN_API addPoint (int32 offsetSamples, double value, int32& index) SMTG_OVERRIDE
{
return kResultFalse;
}
//---------------------------------------------------------

private:
ParamID id;
int32 numPoints;
int32 numUsedPoints;
int32 processedFrames;
ParamPoint* points;
};

//------------------------------------------------------------------------
/** Test Helper.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstTestBase: public ITest
{
public:
//------------------------------------------------------------------------
VstTestBase (IPlugProvider* plugProvider);
virtual ~VstTestBase ();
virtual const char* getName () const = 0;
DECLARE_FUNKNOWN_METHODS

bool PLUGIN_API setup () SMTG_OVERRIDE;
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE {return false;} // implement me
bool PLUGIN_API teardown () SMTG_OVERRIDE;
//------------------------------------------------------------------------
protected:
IPlugProvider* plugProvider;
IComponent* vstPlug;
IEditController* controller;

private:
VstTestBase ();
};

//------------------------------------------------------------------------
/** Test Helper.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstTestEnh : public VstTestBase
{
public:
//------------------------------------------------------------------------
VstTestEnh (IPlugProvider* plugProvider, ProcessSampleSize sampl);
virtual ~VstTestEnh ();

enum AudioDefaults
{
kBlockSize = 64,
kMaxSamplesPerBlock = 8192,
kSampleRate = 44100,
};

bool PLUGIN_API setup () SMTG_OVERRIDE;
bool PLUGIN_API teardown () SMTG_OVERRIDE;
//------------------------------------------------------------------------
protected:
// interfaces
IAudioProcessor* audioEffect;

ProcessSetup processSetup;
};

//------------------------------------------------------------------------
/** Test Suspend/Resume.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstSuspendResumeTest: public VstTestEnh
{
public:
//------------------------------------------------------------------------
VstSuspendResumeTest (IPlugProvider* plugProvider, ProcessSampleSize sampl);

DECLARE_VSTTEST ("Suspend/Resume")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};


//------------------------------------------------------------------------
/** Test Terminate/Initialize.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstTerminateInitializeTest: public VstTestBase
{
public:
//------------------------------------------------------------------------
VstTerminateInitializeTest (IPlugProvider* plugProvider);

DECLARE_VSTTEST ("Terminate/Initialize")

bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Test Scan Buses.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstScanBussesTest: public VstTestBase
{
public:
//------------------------------------------------------------------------
VstScanBussesTest (IPlugProvider* plugProvider);

DECLARE_VSTTEST ("Scan Buses")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Test Scan Parameters.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstScanParametersTest: public VstTestBase
{
public:
//------------------------------------------------------------------------
VstScanParametersTest (IPlugProvider* plugProvider);

DECLARE_VSTTEST ("Scan Parameters")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Test MIDI Mapping.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstMidiMappingTest: public VstTestBase
{
public:
//------------------------------------------------------------------------
VstMidiMappingTest (IPlugProvider* plugProvider);

DECLARE_VSTTEST ("MIDI Mapping")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};



//------------------------------------------------------------------------
/** Test Note Expression.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstNoteExpressionTest: public VstTestBase
{
public:
//------------------------------------------------------------------------
VstNoteExpressionTest (IPlugProvider* plugProvider);

DECLARE_VSTTEST ("Note Expression")

bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Test Keyswitch.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstKeyswitchTest: public VstTestBase
{
public:
//------------------------------------------------------------------------
VstKeyswitchTest (IPlugProvider* plugProvider);

DECLARE_VSTTEST ("Keyswitch")

bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Test Scan Editor Classes.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstEditorClassesTest: public VstTestBase
{
public:
//------------------------------------------------------------------------
VstEditorClassesTest (IPlugProvider* plugProvider);

DECLARE_VSTTEST ("Scan Editor Classes")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Test Scan Units.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstUnitInfoTest: public VstTestBase
{
public:
//------------------------------------------------------------------------
VstUnitInfoTest (IPlugProvider* plugProvider);

DECLARE_VSTTEST ("Scan Units")
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Test Scan Programs.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstProgramInfoTest: public VstTestBase
{
public:
//------------------------------------------------------------------------
VstProgramInfoTest (IPlugProvider* plugProvider);

DECLARE_VSTTEST ("Scan Programs")

bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Test Check Unit Structure.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstUnitStructureTest: public VstTestBase
{
public:
//------------------------------------------------------------------------
VstUnitStructureTest (IPlugProvider* plugProvider);

DECLARE_VSTTEST ("Check Unit Structure")

bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Test Process Test.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstProcessTest : public VstTestEnh
{
public:
//------------------------------------------------------------------------
VstProcessTest (IPlugProvider* plugProvider, ProcessSampleSize sampl);

DECLARE_VSTTEST ("Process Test")
// ITest
bool PLUGIN_API setup () SMTG_OVERRIDE;
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
bool PLUGIN_API teardown () SMTG_OVERRIDE;

//------------------------------------------------------------------------
protected:
virtual bool prepareProcessing (); ///< setup ProcessData and allocate buffers
virtual bool unprepareProcessing (); ///< free dynamic memory of ProcessData
virtual bool preProcess (ITestResult* testResult); ///< is called just before the process call
virtual bool postProcess (ITestResult* testResult); ///< is called right after the process call

bool setupBuffers (int32 numBusses, AudioBusBuffers* audioBuffers, BusDirection dir);
bool setupBuffers (AudioBusBuffers& audioBuffers);
bool freeBuffers (int32 numBuses, AudioBusBuffers* buses);
bool canProcessSampleSize (ITestResult* testResult); ///< audioEffect has to be available

HostProcessData processData;
};

//------------------------------------------------------------------------
/** Test Speaker Arrangement.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstSpeakerArrangementTest : public VstProcessTest
{
public:
//------------------------------------------------------------------------
VstSpeakerArrangementTest (IPlugProvider* plugProvider, ProcessSampleSize sampl, SpeakerArrangement inSpArr, SpeakerArrangement outSpArr);

const char* getName () const SMTG_OVERRIDE;
static const char* getSpeakerArrangementName (SpeakerArrangement spArr);
// ITest
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

//------------------------------------------------------------------------
protected:
bool prepareProcessing () SMTG_OVERRIDE;
bool verifySA (int32 numBusses, AudioBusBuffers* buses, SpeakerArrangement spArr, ITestResult* testResult);
private:
SpeakerArrangement inSpArr;
SpeakerArrangement outSpArr;
};


class ParamChanges;
//------------------------------------------------------------------------
/** Test Automation.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstAutomationTest : public VstProcessTest, public IParameterChanges
{
public:
//------------------------------------------------------------------------
VstAutomationTest (IPlugProvider* plugProvider, ProcessSampleSize sampl, int32 everyNSamples, int32 numParams, bool sampleAccuracy);
virtual ~VstAutomationTest ();

DECLARE_FUNKNOWN_METHODS
const char* getName () const SMTG_OVERRIDE;
// ITest
bool PLUGIN_API setup () SMTG_OVERRIDE;
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
bool PLUGIN_API teardown () SMTG_OVERRIDE;

// IParameterChanges
int32 PLUGIN_API getParameterCount () SMTG_OVERRIDE;
IParamValueQueue* PLUGIN_API getParameterData (int32 index) SMTG_OVERRIDE;
IParamValueQueue* PLUGIN_API addParameterData (const ParamID& id, int32& index) SMTG_OVERRIDE;

//------------------------------------------------------------------------
protected:
bool preProcess (ITestResult* testResult) SMTG_OVERRIDE;
bool postProcess (ITestResult* testResult) SMTG_OVERRIDE;
ParamID bypassId;

ParamChanges* paramChanges;
int32 countParamChanges;
int32 everyNSamples;
int32 numParams;
bool sampleAccuracy;
bool onceExecuted;
};

//------------------------------------------------------------------------
/** Test Valid State Transition.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstValidStateTransitionTest : public VstTestBase
{
public:
VstValidStateTransitionTest (IPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

DECLARE_VSTTEST ("Valid State Transition")
};

//------------------------------------------------------------------------
/** Test Invalid State Transition.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstInvalidStateTransitionTest : public VstTestBase
{
public:
VstInvalidStateTransitionTest (IPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

DECLARE_VSTTEST ("Invalid State Transition")
};

//------------------------------------------------------------------------
/** Test Repeat Identical State Transition.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstRepeatIdenticalStateTransitionTest : public VstTestBase
{
public:
VstRepeatIdenticalStateTransitionTest (IPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

DECLARE_VSTTEST ("Repeat Identical State Transition")
};

//------------------------------------------------------------------------
/** Test Bus Consistency.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstBusConsistencyTest : public VstTestBase
{
public:
VstBusConsistencyTest (IPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

DECLARE_VSTTEST ("Bus Consistency")
};

//------------------------------------------------------------------------
/** Test Bus Invalid Index.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstBusInvalidIndexTest : public VstTestBase
{
public:
VstBusInvalidIndexTest (IPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

DECLARE_VSTTEST ("Bus Invalid Index")
};

//------------------------------------------------------------------------
/** Test Silence Flags.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstSilenceFlagsTest : public VstProcessTest
{
public:
VstSilenceFlagsTest (IPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

DECLARE_VSTTEST ("Silence Flags")
};

//------------------------------------------------------------------------
/** Test Silence Processing.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstSilenceProcessingTest : public VstProcessTest
{
public:
VstSilenceProcessingTest (IPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

DECLARE_VSTTEST ("Silence Processing")
protected:
bool isBufferSilent (void* buffer, int32 numSamples, ProcessSampleSize sampl);
};

//------------------------------------------------------------------------
/** Test Parameters Flush (no Buffer).
\ingroup TestClass */
//------------------------------------------------------------------------
class VstFlushParamTest : public VstAutomationTest
{
public:
VstFlushParamTest (IPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

DECLARE_VSTTEST ("Parameters Flush (no Buffer)")
};

//------------------------------------------------------------------------
/** Test Bus Activation.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstBusActivationTest : public VstTestBase
{
public:
VstBusActivationTest (IPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

DECLARE_VSTTEST ("Bus Activation")
};

//------------------------------------------------------------------------
/** Test Variable Block Size.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstVariableBlockSizeTest : public VstProcessTest
{
public:
VstVariableBlockSizeTest (IPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

DECLARE_VSTTEST ("Variable Block Size")
};

//------------------------------------------------------------------------
/** Test Process Format.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstProcessFormatTest : public VstProcessTest
{
public:
VstProcessFormatTest (IPlugProvider* plugProvider, ProcessSampleSize sampl);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

DECLARE_VSTTEST ("Process Format")
};

//------------------------------------------------------------------------
/** Test Check Audio Bus Arrangement.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstCheckAudioBusArrangementTest : public VstTestBase
{
public:
VstCheckAudioBusArrangementTest (IPlugProvider* plugProvider);
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;

DECLARE_VSTTEST ("Check Audio Bus Arrangement")
};


//------------------------------------------------------------------------
/** Test ProcesTail.
\ingroup TestClass */
//------------------------------------------------------------------------
class VstProcessTailTest : public VstProcessTest
{
public:
//------------------------------------------------------------------------
VstProcessTailTest (IPlugProvider* plugProvider, ProcessSampleSize sampl);
virtual ~VstProcessTailTest ();

DECLARE_VSTTEST ("Check Tail processing")

// ITest
bool PLUGIN_API setup () SMTG_OVERRIDE;
bool PLUGIN_API run (ITestResult* testResult) SMTG_OVERRIDE;
bool preProcess (ITestResult* testResult) SMTG_OVERRIDE;
bool postProcess (ITestResult* testResult) SMTG_OVERRIDE;
//------------------------------------------------------------------------
protected:
private:
uint32 mTailSamples;
uint32 mInTail;

float* dataPtrFloat;
double* dataPtrDouble;
bool mInSilenceInput;
bool mDontTest;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg


+ 3105
- 0
source/includes/vst3sdk/public.sdk/source/vst/vst2wrapper/vst2wrapper.cpp
File diff suppressed because it is too large
View File


+ 335
- 0
source/includes/vst3sdk/public.sdk/source/vst/vst2wrapper/vst2wrapper.h View File

@@ -0,0 +1,335 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vst2wrapper/vst2wrapper.h
// Created by : Steinberg, 01/2009
// Description : VST 3 -> VST 2 Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/**
**************************************
\page vst2xwrapper VST 2.x Wrapper
***************************
\section VST2Introduction Introduction
***************************
The VST 3 SDK comes with a helper class which wraps one VST 3 Audio Processor and Edit Controller to
a VST 2.x Plug-in.
\n\n
***************************
\section VST2howdoesitwork How does it work ?
***************************
You just need to add public.sdk/source/vst/vst2wrapper/vst2wrapper.sdk.cpp to your project and add
the following code somewhere in your sources:
\code

#include "public.sdk/source/vst/vst2wrapper/vst2wrapper.h"

//------------------------------------------------------------------------
::AudioEffect* createEffectInstance (audioMasterCallback audioMaster)
{
return Steinberg::Vst::Vst2Wrapper::create (GetPluginFactory (), kAudioProcessorCID, kVst2UniqueID, audioMaster);
}

\endcode
*/
/// \cond ignore

#pragma once

#include "pluginterfaces/base/ftypes.h"
#include "pluginterfaces/vst/ivstaudioprocessor.h"
#include "pluginterfaces/vst/ivsteditcontroller.h"
#include "pluginterfaces/vst/ivsthostapplication.h"
#include "pluginterfaces/vst/ivstprocesscontext.h"
#include "pluginterfaces/vst/ivstunits.h"

#include "public.sdk/source/common/memorystream.h"
#include "public.sdk/source/vst/hosting/eventlist.h"
#include "public.sdk/source/vst/hosting/parameterchanges.h"
#include "public.sdk/source/vst/hosting/processdata.h"
#include "public.sdk/source/vst2.x/audioeffectx.h"

#include "base/source/fstring.h"
#include "base/source/timer.h"

#include <map>
#include <vector>

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {

class Vst2MidiEventQueue;

//-------------------------------------------------------------------------------------------------------
class Vst2Wrapper : public ::AudioEffectX,
public IHostApplication,
public IComponentHandler,
public IUnitHandler,
public ITimerCallback,
public IVst3ToVst2Wrapper
{
public:
//--- -------------------------------------------------------------------------------------------------
// static creation method
static AudioEffect* create (IPluginFactory* factory, const TUID vst3ComponentID,
VstInt32 vst2ID, audioMasterCallback audioMaster);

Vst2Wrapper (IAudioProcessor* processor, IEditController* controller,
audioMasterCallback audioMaster, const TUID vst3ComponentID, VstInt32 vst2ID,
IPluginFactory* factory = 0);
~Vst2Wrapper ();

bool init ();

// AudioEffectX overrides -----------------------------------------------
virtual void suspend () SMTG_OVERRIDE; // Called when Plug-in is switched to off
virtual void resume () SMTG_OVERRIDE; // Called when Plug-in is switched to on
virtual VstInt32 startProcess () SMTG_OVERRIDE;
virtual VstInt32 stopProcess () SMTG_OVERRIDE;

virtual void setSampleRate (float newSamplerate)
SMTG_OVERRIDE; // Called when the sample rate changes (always in a suspend state)
virtual void setBlockSize (VstInt32 newBlockSize)
SMTG_OVERRIDE; // Called when the maximum block size changes
// (always in a suspend state). Note that the
// sampleFrames in Process Calls could be
// smaller than this block size, but NOT bigger.

virtual float getParameter (VstInt32 index) SMTG_OVERRIDE;
virtual void setParameter (VstInt32 index, float value) SMTG_OVERRIDE;

virtual void setProgram (VstInt32 program) SMTG_OVERRIDE;
virtual void setProgramName (char* name) SMTG_OVERRIDE;
virtual void getProgramName (char* name) SMTG_OVERRIDE;
virtual bool getProgramNameIndexed (VstInt32 category, VstInt32 index,
char* text) SMTG_OVERRIDE;

virtual void getParameterLabel (VstInt32 index, char* label) SMTG_OVERRIDE;
virtual void getParameterDisplay (VstInt32 index, char* text) SMTG_OVERRIDE;
virtual void getParameterName (VstInt32 index, char* text) SMTG_OVERRIDE;
virtual bool canParameterBeAutomated (VstInt32 index) SMTG_OVERRIDE;
virtual bool string2parameter (VstInt32 index, char* text) SMTG_OVERRIDE;
virtual bool getParameterProperties (VstInt32 index, VstParameterProperties* p) SMTG_OVERRIDE;

virtual VstInt32 getChunk (void** data, bool isPreset = false) SMTG_OVERRIDE;
virtual VstInt32 setChunk (void* data, VstInt32 byteSize, bool isPreset = false) SMTG_OVERRIDE;

virtual bool getInputProperties (VstInt32 index, VstPinProperties* properties) SMTG_OVERRIDE;
virtual bool getOutputProperties (VstInt32 index, VstPinProperties* properties) SMTG_OVERRIDE;
virtual bool setSpeakerArrangement (VstSpeakerArrangement* pluginInput,
VstSpeakerArrangement* pluginOutput) SMTG_OVERRIDE;
virtual bool getSpeakerArrangement (VstSpeakerArrangement** pluginInput,
VstSpeakerArrangement** pluginOutput) SMTG_OVERRIDE;
virtual bool setBypass (bool onOff) SMTG_OVERRIDE;

virtual bool setProcessPrecision (VstInt32 precision) SMTG_OVERRIDE;
virtual VstInt32 getNumMidiInputChannels () SMTG_OVERRIDE;
virtual VstInt32 getNumMidiOutputChannels () SMTG_OVERRIDE;
virtual VstInt32 getGetTailSize () SMTG_OVERRIDE;
virtual bool getEffectName (char* name) SMTG_OVERRIDE;
virtual bool getVendorString (char* text) SMTG_OVERRIDE;
virtual VstInt32 getVendorVersion () SMTG_OVERRIDE;
virtual VstIntPtr vendorSpecific (VstInt32 lArg, VstIntPtr lArg2, void* ptrArg,
float floatArg) SMTG_OVERRIDE;
virtual VstPlugCategory getPlugCategory () SMTG_OVERRIDE;
virtual VstInt32 canDo (char* text) SMTG_OVERRIDE;

virtual VstInt32 getMidiProgramName (VstInt32 channel,
MidiProgramName* midiProgramName) SMTG_OVERRIDE;
virtual VstInt32 getCurrentMidiProgram (VstInt32 channel,
MidiProgramName* currentProgram) SMTG_OVERRIDE;
virtual VstInt32 getMidiProgramCategory (VstInt32 channel,
MidiProgramCategory* category) SMTG_OVERRIDE;
virtual bool hasMidiProgramsChanged (VstInt32 channel) SMTG_OVERRIDE;
virtual bool getMidiKeyName (VstInt32 channel, MidiKeyName* keyName) SMTG_OVERRIDE;

// finally process...
virtual void processReplacing (float** inputs, float** outputs,
VstInt32 sampleFrames) SMTG_OVERRIDE;
virtual void processDoubleReplacing (double** inputs, double** outputs,
VstInt32 sampleFrames) SMTG_OVERRIDE;
virtual VstInt32 processEvents (VstEvents* events) SMTG_OVERRIDE;

// VST 3 Interfaces ------------------------------------------------------
// FUnknown
virtual tresult PLUGIN_API queryInterface (const char* iid, void** obj) SMTG_OVERRIDE;
virtual uint32 PLUGIN_API addRef () SMTG_OVERRIDE { return 1; }
virtual uint32 PLUGIN_API release () SMTG_OVERRIDE { return 1; }

// IHostApplication
virtual tresult PLUGIN_API getName (String128 name) SMTG_OVERRIDE;
virtual tresult PLUGIN_API createInstance (TUID cid, TUID iid, void** obj) SMTG_OVERRIDE;

// IComponentHandler
virtual tresult PLUGIN_API beginEdit (ParamID tag) SMTG_OVERRIDE;
virtual tresult PLUGIN_API performEdit (ParamID tag, ParamValue valueNormalized) SMTG_OVERRIDE;
virtual tresult PLUGIN_API endEdit (ParamID tag) SMTG_OVERRIDE;
virtual tresult PLUGIN_API restartComponent (int32 flags) SMTG_OVERRIDE;

// IUnitHandler
virtual tresult PLUGIN_API notifyUnitSelection (UnitID unitId) SMTG_OVERRIDE;
virtual tresult PLUGIN_API notifyProgramListChange (ProgramListID listId,
int32 programIndex) SMTG_OVERRIDE;

void setVendorName (char* name);
void setEffectName (char* name);
void setEffectVersion (char* version);
void setSubCategories (char* string);

// ITimer
virtual void onTimer (Timer* timer) SMTG_OVERRIDE;

//-------------------------------------------------------------------------------------------------------
protected:
void setupBuses ();
void setupParameters ();
void initMidiCtrlerAssignment ();
void getUnitPath (UnitID unitID, String& path);

int32 countMainBusChannels (BusDirection dir, uint64& mainBusBitset);

template <class T>
void setProcessingBuffers (T** inputs, T** outputs);
void setupProcessTimeInfo ();
void doProcess (VstInt32 sampleFrames);
void setEventPPQPositions ();
void processOutputEvents ();
void processMidiEvent (VstMidiEvent* midiEvent, int32 bus);

/** Returns the last param change from guiTransfer queue. */
bool getLastParamChange (ParamID id, ParamValue& value);

bool setupProcessing (int32 processModeOverwrite = -1);
void addParameterChange (ParamID id, ParamValue value, int32 sampleOffset);

bool getProgramListAndUnit (int32 midiChannel, UnitID& unitId, ProgramListID& programListId);
bool getProgramListInfoByProgramListID (ProgramListID programListId, ProgramListInfo& info);
int32 lookupProgramCategory (int32 midiChannel, String128 instrumentAttribute);
bool setupMidiProgram (int32 midiChannel, ProgramListID programListId,
MidiProgramName& midiProgramName);

bool getPinProperties (BusDirection dir, VstInt32 pinIndex, VstPinProperties* properties);
bool pinIndexToBusChannel (BusDirection dir, VstInt32 pinIndex, int32& busIndex,
int32& busChannel);
static VstInt32 vst3ToVst2SpeakerArr (SpeakerArrangement vst3Arr);
static SpeakerArrangement vst2ToVst3SpeakerArr (VstInt32 vst2Arr);
static VstInt32 vst3ToVst2Speaker (Speaker vst3Speaker);
static void setupVst2Arrangement (VstSpeakerArrangement*& vst2arr,
Vst::SpeakerArrangement vst3Arrangement);

struct ProgramCategory
{
MidiProgramCategory vst2Category;
String128 vst3InstrumentAttribute;
};
std::vector<std::vector<ProgramCategory>> mProgramCategories;
void setupProgramCategories ();
static uint32 makeCategoriesRecursive (std::vector<ProgramCategory>& channelCategories,
String128 vst3Category);

static const int32 kMaxProgramChangeParameters = 16;
ParamID mProgramChangeParameterIDs[kMaxProgramChangeParameters]; // for each midi channel
int32 mProgramChangeParameterIdxs[kMaxProgramChangeParameters]; // for each midi channel

VstSpeakerArrangement* mVst2InputArrangement;
VstSpeakerArrangement* mVst2OutputArrangement;

FUID mVst3EffectClassID;

// vst3 data
IAudioProcessor* mProcessor;
IComponent* mComponent;
IEditController* mController;
IUnitInfo* mUnitInfo;
IMidiMapping* mMidiMapping;

bool componentInitialized;
bool controllerInitialized;
bool componentsConnected;
bool processing;
bool hasEventInputBuses;
bool hasEventOutputBuses;

int32 mVst3SampleSize;
int32 mVst3processMode;

char mName[PClassInfo::kNameSize];
char mVendor[PFactoryInfo::kNameSize];
char mSubCategories[PClassInfo2::kSubCategoriesSize];
int32 mVersion;

struct ParamMapEntry
{
ParamID vst3ID;
int32 vst3Index;
};

std::vector<ParamMapEntry> mParameterMap;
std::map<ParamID, int32> mParamIndexMap;
ParamID mBypassParameterID;
ParamID mProgramParameterID;
int32 mProgramParameterIdx;

HostProcessData mProcessData;
ProcessContext mProcessContext;
ParameterChanges mInputChanges;
ParameterChanges mOutputChanges;
EventList* mInputEvents;
EventList* mOutputEvents;
Vst2MidiEventQueue* mVst2OutputEvents;
uint64 mMainAudioInputBuses;
uint64 mMainAudioOutputBuses;

ParameterChangeTransfer mInputTransfer;
ParameterChangeTransfer mOutputTransfer;
ParameterChangeTransfer mGuiTransfer;

MemoryStream mChunk;

Timer* mTimer;
IPluginFactory* mFactory;

enum
{
kMaxMidiMappingBusses = 4
};
int32* mMidiCCMapping[kMaxMidiMappingBusses][16];
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

/** Must be implemented externally. */
extern ::AudioEffect* createEffectInstance (audioMasterCallback audioMaster);

/// \endcond

+ 47
- 0
source/includes/vst3sdk/public.sdk/source/vst/vst2wrapper/vst2wrapper.sdk.cpp View File

@@ -0,0 +1,47 @@
//------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vst2wrapper/vst2wrapper.sdk.cpp
// Created by : Steinberg, 01/2009
// Description : VST 3 -> VST 2 Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "public.sdk/source/vst/vst2wrapper/vst2wrapper.cpp"

#include "public.sdk/source/vst/hosting/processdata.cpp"
#include "public.sdk/source/vst/hosting/eventlist.cpp"
#include "public.sdk/source/vst/hosting/hostclasses.cpp"
#include "public.sdk/source/vst/hosting/parameterchanges.cpp"

#include "public.sdk/source/common/memorystream.cpp"

#include "public.sdk/source/vst2.x/audioeffectx.cpp"
#include "public.sdk/source/vst2.x/audioeffect.cpp"

+ 196
- 0
source/includes/vst3sdk/public.sdk/source/vst/vstaudioeffect.cpp View File

@@ -0,0 +1,196 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vstaudioeffect.cpp
// Created by : Steinberg, 04/2005
// Description : Basic Audio Effect Implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "vstaudioeffect.h"

namespace Steinberg {
namespace Vst {


//------------------------------------------------------------------------
// AudioEffect
//------------------------------------------------------------------------
AudioEffect::AudioEffect ()
{
processSetup.maxSamplesPerBlock = 1024;
processSetup.processMode = Vst::kRealtime;
processSetup.sampleRate = 44100.0;
processSetup.symbolicSampleSize = Vst::kSample32;
}

//------------------------------------------------------------------------
AudioBus* AudioEffect::addAudioInput (const TChar* name, SpeakerArrangement arr,
BusType busType, int32 flags)
{
AudioBus* newBus = new AudioBus (name, busType, flags, arr);
audioInputs.push_back (IPtr<Vst::Bus> (newBus, false));
return newBus;
}

//------------------------------------------------------------------------
AudioBus* AudioEffect::addAudioOutput (const TChar* name, SpeakerArrangement arr,
BusType busType, int32 flags)
{
AudioBus* newBus = new AudioBus (name, busType, flags, arr);
audioOutputs.push_back (IPtr<Vst::Bus> (newBus, false));
return newBus;
}

//------------------------------------------------------------------------
AudioBus* AudioEffect::getAudioInput (int32 index)
{
AudioBus* bus = FCast<Vst::AudioBus> (audioInputs.at (index));
return bus;
}

//------------------------------------------------------------------------
AudioBus* AudioEffect::getAudioOutput (int32 index)
{
AudioBus* bus = FCast<Vst::AudioBus> (audioOutputs.at (index));
return bus;
}

//------------------------------------------------------------------------
EventBus* AudioEffect::addEventInput (const TChar* name, int32 channels,
BusType busType, int32 flags)
{
EventBus* newBus = new EventBus (name, busType, flags, channels);
eventInputs.push_back (IPtr<Vst::Bus> (newBus, false));
return newBus;
}

//------------------------------------------------------------------------
EventBus* AudioEffect::addEventOutput (const TChar* name, int32 channels,
BusType busType, int32 flags)
{
EventBus* newBus = new EventBus (name, busType, flags, channels);
eventOutputs.push_back (IPtr<Vst::Bus> (newBus, false));
return newBus;
}

//------------------------------------------------------------------------
EventBus* AudioEffect::getEventInput (int32 index)
{
EventBus* bus = FCast<Vst::EventBus> (eventInputs.at (index));
return bus;
}

//------------------------------------------------------------------------
EventBus* AudioEffect::getEventOutput (int32 index)
{
EventBus* bus = FCast<Vst::EventBus> (eventOutputs.at (index));
return bus;
}

//------------------------------------------------------------------------
tresult PLUGIN_API AudioEffect::setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
SpeakerArrangement* outputs, int32 numOuts)
{
if (numIns < 0 || numOuts < 0)
return kInvalidArgument;

if (numIns > static_cast<int32> (audioInputs.size ()) ||
numOuts > static_cast<int32> (audioOutputs.size ()))
return kResultFalse;

for (int32 index = 0; index < audioInputs.size (); ++index)
{
if (index >= numIns)
break;
FCast<Vst::AudioBus> (audioInputs[index].get ())->setArrangement (inputs[index]);
}

for (int32 index = 0; index < audioOutputs.size (); ++index)
{
if (index >= numOuts)
break;
FCast<Vst::AudioBus> (audioOutputs[index].get ())->setArrangement (outputs[index]);
}

return kResultTrue;
}

//------------------------------------------------------------------------
tresult PLUGIN_API AudioEffect::getBusArrangement (BusDirection dir, int32 busIndex, SpeakerArrangement& arr)
{
BusList* busList = getBusList (kAudio, dir);
if (!busList || busIndex < 0 || busList->size () <= busIndex)
return kInvalidArgument;
AudioBus* audioBus = FCast<Vst::AudioBus> (busList->at (busIndex));
if (audioBus)
{
arr = audioBus->getArrangement ();
return kResultTrue;
}
return kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API AudioEffect::setupProcessing (ProcessSetup& newSetup)
{
processSetup.maxSamplesPerBlock = newSetup.maxSamplesPerBlock;
processSetup.processMode = newSetup.processMode;
processSetup.sampleRate = newSetup.sampleRate;

if (canProcessSampleSize (newSetup.symbolicSampleSize) != kResultTrue)
return kResultFalse;

processSetup.symbolicSampleSize = newSetup.symbolicSampleSize;

return kResultOk;
}

//------------------------------------------------------------------------
tresult PLUGIN_API AudioEffect::setProcessing (TBool /*state*/)
{
return kNotImplemented;
}

//------------------------------------------------------------------------
tresult PLUGIN_API AudioEffect::canProcessSampleSize (int32 symbolicSampleSize)
{
return symbolicSampleSize == kSample32 ? kResultTrue : kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API AudioEffect::process (ProcessData& /*data*/)
{
return kNotImplemented;
}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 130
- 0
source/includes/vst3sdk/public.sdk/source/vst/vstaudioeffect.h View File

@@ -0,0 +1,130 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vstaudioeffect.h
// Created by : Steinberg, 04/2005
// Description : Basic Audio Effect Implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "public.sdk/source/vst/vstcomponent.h"
#include "public.sdk/source/vst/vstbus.h"
#include "pluginterfaces/vst/ivstaudioprocessor.h"

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {


//------------------------------------------------------------------------
/** Default implementation for a VST 3 audio effect.
\ingroup vstClasses
Can be used as base class for a VST 3 effect implementation. */
//------------------------------------------------------------------------
class AudioEffect: public Component,
public IAudioProcessor
{
public:
//------------------------------------------------------------------------
/** Constructor */
AudioEffect ();

//---Internal Methods-----------
/** Creates and adds a new Audio input bus with a given speaker arrangement, busType (kMain or kAux). */
AudioBus* addAudioInput (const TChar* name, SpeakerArrangement arr,
BusType busType = kMain, int32 flags = BusInfo::kDefaultActive);

/** Creates and adds a new Audio output bus with a given speaker arrangement, busType (kMain or kAux). */
AudioBus* addAudioOutput (const TChar* name, SpeakerArrangement arr,
BusType busType = kMain, int32 flags = BusInfo::kDefaultActive);

/** Retrieves an Audio Input Bus by index. */
AudioBus* getAudioInput (int32 index);

/** Retrieves an Audio Output Bus by index. */
AudioBus* getAudioOutput (int32 index);

/** Creates and adds a new Event input bus with a given speaker arrangement, busType (kMain or kAux). */
EventBus* addEventInput (const TChar* name, int32 channels = 16,
BusType busType = kMain, int32 flags = BusInfo::kDefaultActive);

/** Creates and adds a new Event output bus with a given speaker arrangement, busType (kMain or kAux). */
EventBus* addEventOutput (const TChar* name, int32 channels = 16,
BusType busType = kMain, int32 flags = BusInfo::kDefaultActive);

/** Retrieves an Event Input Bus by index. */
EventBus* getEventInput (int32 index);

/** Retrieves an Event Output Bus by index. */
EventBus* getEventOutput (int32 index);

//---from IAudioProcessor-------
tresult PLUGIN_API setBusArrangements (SpeakerArrangement* inputs, int32 numIns, SpeakerArrangement* outputs, int32 numOuts) SMTG_OVERRIDE;
tresult PLUGIN_API getBusArrangement (BusDirection dir, int32 busIndex, SpeakerArrangement& arr) SMTG_OVERRIDE;
tresult PLUGIN_API canProcessSampleSize (int32 symbolicSampleSize) SMTG_OVERRIDE;
uint32 PLUGIN_API getLatencySamples () SMTG_OVERRIDE { return 0; }
tresult PLUGIN_API setupProcessing (ProcessSetup& setup) SMTG_OVERRIDE;
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API process (ProcessData& data) SMTG_OVERRIDE;
uint32 PLUGIN_API getTailSamples () SMTG_OVERRIDE { return kNoTail; }

//---Interface---------
OBJ_METHODS (AudioEffect, Component)
DEFINE_INTERFACES
DEF_INTERFACE (IAudioProcessor)
END_DEFINE_INTERFACES (Component)
REFCOUNT_METHODS(Component)

//---helpers---------
/** Return the current channelBuffers used (depending of symbolicSampleSize). */
void** getChannelBuffersPointer (const AudioBusBuffers& bufs) const
{
if (processSetup.symbolicSampleSize == kSample32)
return (void**)bufs.channelBuffers32;
return (void**)bufs.channelBuffers64;
}
/** Return the size in bytes of numSamples for one channel depending of symbolicSampleSize.*/
uint32 getSampleFramesSizeInBytes (int32 numSamples)
{
if (processSetup.symbolicSampleSize == kSample32)
return numSamples * sizeof (Sample32);
return numSamples * sizeof (Sample64);
}

//------------------------------------------------------------------------
protected:
ProcessSetup processSetup;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 300
- 0
source/includes/vst3sdk/public.sdk/source/vst/vstaudioprocessoralgo.h View File

@@ -0,0 +1,300 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vstaudioprocessoralgo.h
// Created by : Steinberg, 04/2015
// Description : Helper algo for AudioBusBuffers
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/vst/ivstaudioprocessor.h"
#include "pluginterfaces/vst/ivstparameterchanges.h"
#include <algorithm>
#include <cmath>

namespace Steinberg {
namespace Vst {
namespace Algo {

//------------------------------------------------------------------------
template <typename T>
inline void foreach (AudioBusBuffers* audioBusBuffers, int32 busCount, const T& func)
{
if (!audioBusBuffers)
return;

for (int32 busIndex = 0; busIndex < busCount; ++busIndex)
{
func (audioBusBuffers[busIndex]);
}
}

//------------------------------------------------------------------------
template <typename T>
inline void foreach32 (AudioBusBuffers& audioBuffer, const T& func)
{
for (int32 channelIndex = 0; channelIndex < audioBuffer.numChannels; ++channelIndex)
{
if (!audioBuffer.channelBuffers32[channelIndex])
return;

func (audioBuffer.channelBuffers32[channelIndex]);
}
}

//------------------------------------------------------------------------
template <typename T>
inline void foreach64 (AudioBusBuffers& audioBuffer, const T& func)
{
for (int32 channelIndex = 0; channelIndex < audioBuffer.numChannels; ++channelIndex)
{
if (!audioBuffer.channelBuffers64[channelIndex])
return;

func (audioBuffer.channelBuffers64[channelIndex]);
}
}

//------------------------------------------------------------------------
template <typename T>
inline void foreach32 (AudioBusBuffers& buffer1, AudioBusBuffers& buffer2, const T& func)
{
int32 numChannels = std::min<int32> (buffer1.numChannels, buffer2.numChannels);

for (int32 channelIndex = 0; channelIndex < numChannels; ++channelIndex)
{
func (buffer1.channelBuffers32[channelIndex], buffer2.channelBuffers32[channelIndex],
channelIndex);
}
}

//------------------------------------------------------------------------
template <typename T>
inline void foreach64 (AudioBusBuffers& buffer1, AudioBusBuffers& buffer2, const T& func)
{
int32 numChannels = std::min<int32> (buffer1.numChannels, buffer2.numChannels);

for (int32 channelIndex = 0; channelIndex < numChannels; ++channelIndex)
{
func (buffer1.channelBuffers64[channelIndex], buffer2.channelBuffers64[channelIndex],
channelIndex);
}
}

//------------------------------------------------------------------------
inline void copy32 (AudioBusBuffers* src, AudioBusBuffers* dest, int32 sliceSize, int32 startIndex)
{
if (!src || !dest)
return;

int32 numChannels = std::min<int32> (src->numChannels, dest->numChannels);
size_t numBytes = sliceSize * sizeof (Sample32);
for (int32 chIdx = 0; chIdx < numChannels; ++chIdx)
{
memcpy (&dest->channelBuffers32[chIdx][startIndex], src->channelBuffers32[chIdx], numBytes);
}
}

//------------------------------------------------------------------------
inline void copy64 (AudioBusBuffers* src, AudioBusBuffers* dest, int32 sliceSize, int32 startIndex)
{
if (!src || !dest)
return;

int32 numChannels = std::min<int32> (src->numChannels, dest->numChannels);
size_t numBytes = sliceSize * sizeof (Sample64);
for (int32 chIdx = 0; chIdx < numChannels; ++chIdx)
{
memcpy (&dest->channelBuffers64[chIdx][startIndex], src->channelBuffers64[chIdx], numBytes);
}
}

//------------------------------------------------------------------------
inline void clear32 (AudioBusBuffers* audioBusBuffers, int32 sampleCount, int32 busCount = 1)
{
if (!audioBusBuffers)
return;

const int32 numBytes = sampleCount * sizeof (Sample32);
foreach (audioBusBuffers, busCount, [&] (AudioBusBuffers& audioBuffer) {
foreach32 (audioBuffer, [&] (Sample32* channelBuffer) {
memset (channelBuffer, 0, numBytes);
});
});
}

//------------------------------------------------------------------------
inline void clear64 (AudioBusBuffers* audioBusBuffers, int32 sampleCount, int32 busCount = 1)
{
if (!audioBusBuffers)
return;

const int32 numBytes = sampleCount * sizeof (Sample64);
foreach (audioBusBuffers, busCount, [&](AudioBusBuffers& audioBuffer) {
foreach64 (audioBuffer, [&](Sample64* channelBuffer) {
memset (channelBuffer, 0, numBytes);
});
});
}

//------------------------------------------------------------------------
inline void mix32 (AudioBusBuffers& src, AudioBusBuffers& dest, int32 sampleCount)
{
foreach32 (src, dest, [&] (Sample32* srcBuffer, Sample32* destBuffer, int32 /*channelIndex*/) {
for (int32 sampleIndex = 0; sampleIndex < sampleCount; ++sampleIndex)
destBuffer[sampleIndex] += srcBuffer[sampleIndex];
});
}

//------------------------------------------------------------------------
inline void mix64 (AudioBusBuffers& src, AudioBusBuffers& dest, int32 sampleCount)
{
foreach64 (src, dest, [&] (Sample64* srcBuffer, Sample64* destBuffer, int32 /*channelIndex*/) {
for (int32 sampleIndex = 0; sampleIndex < sampleCount; ++sampleIndex)
destBuffer[sampleIndex] += srcBuffer[sampleIndex];
});
}

//------------------------------------------------------------------------
inline bool isSilent32 (AudioBusBuffers& audioBuffer, int32 sampleCount, int32 startIndex = 0)
{
const float epsilon = 1e-10f; // under -200dB...

sampleCount += startIndex;
for (int32 channelIndex = 0; channelIndex < audioBuffer.numChannels; ++channelIndex)
{
if (!audioBuffer.channelBuffers32[channelIndex])
return true;

for (int32 sampleIndex = startIndex; sampleIndex < sampleCount; ++sampleIndex)
{
float val = audioBuffer.channelBuffers32[channelIndex][sampleIndex];
if (std::abs (val) > epsilon)
return false;
}
}

return true;
}

//------------------------------------------------------------------------
inline bool isSilent64 (AudioBusBuffers& audioBuffer, int32 sampleCount, int32 startIndex = 0)
{
const double epsilon = 1e-10f; // under -200dB...

sampleCount += startIndex;
for (int32 channelIndex = 0; channelIndex < audioBuffer.numChannels; ++channelIndex)
{
if (!audioBuffer.channelBuffers64[channelIndex])
return true;

for (int32 sampleIndex = startIndex; sampleIndex < sampleCount; ++sampleIndex)
{
double val = audioBuffer.channelBuffers64[channelIndex][sampleIndex];
if (std::abs (val) > epsilon)
return false;
}
}

return true;
}

//------------------------------------------------------------------------
//------------------------------------------------------------------------
template <typename T>
inline void foreach (IEventList* eventList, const T& func)
{
if (!eventList)
return;

auto eventCount = eventList->getEventCount ();
for (int32 eventIndex = 0; eventIndex < eventCount; ++eventIndex)
{
Event event = {0};
if (eventList->getEvent (eventIndex, event) != kResultOk)
continue;

func (event);
}
}

//------------------------------------------------------------------------
template <typename T>
inline void foreach (IParamValueQueue& paramQueue, const T& func)
{
auto paramId = paramQueue.getParameterId ();
auto numPoints = paramQueue.getPointCount ();
for (int32 pointIndex = 0; pointIndex < numPoints; ++pointIndex)
{
int32 sampleOffset = 0;
ParamValue value = 0;
if (paramQueue.getPoint (pointIndex, sampleOffset, value) != kResultOk)
continue;

func (paramId, sampleOffset, value);
}
}

//------------------------------------------------------------------------
template <typename T>
inline void foreachLast (IParamValueQueue& paramQueue, const T& func)
{
auto paramId = paramQueue.getParameterId ();
auto numPoints = paramQueue.getPointCount ();
int32 sampleOffset = 0;
ParamValue value = 0;
if (paramQueue.getPoint (numPoints - 1, sampleOffset, value) == kResultOk)
func (paramId, sampleOffset, value);
}

//------------------------------------------------------------------------
template <typename T>
inline void foreach (IParameterChanges* changes, const T& func)
{
if (!changes)
return;

auto paramCount = changes->getParameterCount ();
for (int32 paramIndex = 0; paramIndex < paramCount; ++paramIndex)
{
auto paramValueQueue = changes->getParameterData (paramIndex);
if (!paramValueQueue)
continue;

func (*paramValueQueue);
}
}

//------------------------------------------------------------------------
} // namespace Algo
} // namespace Vst
} // namespace Steinberg

+ 104
- 0
source/includes/vst3sdk/public.sdk/source/vst/vstbus.cpp View File

@@ -0,0 +1,104 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vstbus.cpp
// Created by : Steinberg, 03/2008
// Description : VST Bus Implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "vstbus.h"

namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
// Bus Implementation
//------------------------------------------------------------------------
Bus::Bus (const TChar* _name, BusType _busType, int32 _flags)
: name (_name)
, busType (_busType)
, flags (_flags)
, active (false)
{}

//------------------------------------------------------------------------
bool Bus::getInfo (BusInfo& info)
{
name.copyTo16 (info.name, 0, str16BufferSize (info.name) - 1);
info.busType = busType;
info.flags = flags;
return true;
}


//------------------------------------------------------------------------
// EventBus Implementation
//------------------------------------------------------------------------
EventBus::EventBus (const TChar* name, BusType busType, int32 flags, int32 channelCount)
: Bus (name, busType, flags)
, channelCount (channelCount)
{}

//------------------------------------------------------------------------
bool EventBus::getInfo (BusInfo& info)
{
info.channelCount = channelCount;
return Bus::getInfo (info);
}


//------------------------------------------------------------------------
// AudioBus Implementation
//------------------------------------------------------------------------
AudioBus::AudioBus (const TChar* name, BusType busType, int32 flags, SpeakerArrangement arr)
: Bus (name, busType, flags)
, speakerArr (arr)
{}

//------------------------------------------------------------------------
bool AudioBus::getInfo (BusInfo& info)
{
info.channelCount = SpeakerArr::getChannelCount (speakerArr);
return Bus::getInfo (info);
}


//------------------------------------------------------------------------
// BusList Implementation
//------------------------------------------------------------------------
BusList::BusList (MediaType type, BusDirection dir)
: type (type)
, direction (dir)
{}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 164
- 0
source/includes/vst3sdk/public.sdk/source/vst/vstbus.h View File

@@ -0,0 +1,164 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vstbus.h
// Created by : Steinberg, 03/2008
// Description : VST Bus Implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "base/source/fobject.h"
#include "base/source/fstring.h"
#include "pluginterfaces/vst/ivstcomponent.h"
#include "pluginterfaces/vst/ivstaudioprocessor.h"

#include <vector>

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
/** Basic Bus object.
\ingroup vstClasses */
//------------------------------------------------------------------------
class Bus: public FObject
{
public:
//------------------------------------------------------------------------
/** Constructor. */
Bus (const TChar* name, BusType busType, int32 flags);

/** Returns true if the bus is active. */
TBool isActive () const { return active; }

/** Activates the bus. */
void setActive (TBool state) { active = state; }

/** Sets a new name for this bus. */
void setName (String newName) { name = newName; }

/** Sets a new busType for this bus. */
void setBusType (BusType newBusType) { busType = newBusType; }

/** Sets a new flags for this bus. */
void setFlags (uint32 newFlags) { flags = newFlags; }

/** Gets the BusInfo of this bus. */
virtual bool getInfo (BusInfo&);

OBJ_METHODS (Vst::Bus, FObject)
//------------------------------------------------------------------------
protected:
String name; ///< name
BusType busType; ///< kMain or kAux, see \ref BusTypes
int32 flags; ///< flags, see \ref BusFlags
TBool active; ///< activation state
};

//------------------------------------------------------------------------
/** Description of an Event Bus.
\ingroup vstClasses */
//------------------------------------------------------------------------
class EventBus: public Bus
{
public:
//------------------------------------------------------------------------
/** Constructor of an EventBus. */
EventBus (const TChar* name, BusType busType, int32 flags, int32 channelCount);

//---from Bus-------
/** Gets the BusInfo associated to this Event bus. */
virtual bool getInfo (BusInfo& info) SMTG_OVERRIDE;

OBJ_METHODS (Vst::EventBus, Vst::Bus);

//------------------------------------------------------------------------
protected:
int32 channelCount;
};

//------------------------------------------------------------------------
/** Description of an Audio Bus.
\ingroup vstClasses */
//------------------------------------------------------------------------
class AudioBus: public Bus
{
public:
//------------------------------------------------------------------------
AudioBus (const TChar* name, BusType busType, int32 flags, SpeakerArrangement arr);

/** Gets the speaker arrangement defining this Audio bus. */
SpeakerArrangement getArrangement () const { return speakerArr; }

/** Sets the speaker arrangement defining this Audio bus. */
void setArrangement (const SpeakerArrangement& arr) { speakerArr = arr; }

//---from Bus---------------------
/** Gets the BusInfo associated to this Audio bus. */
virtual bool getInfo (BusInfo& info) SMTG_OVERRIDE;

OBJ_METHODS (Vst::AudioBus, Vst::Bus)

//------------------------------------------------------------------------
protected:
SpeakerArrangement speakerArr;
};

//------------------------------------------------------------------------
/** List of Buses.
\ingroup vstClasses */
//------------------------------------------------------------------------
class BusList: public FObject, public std::vector<IPtr<Vst::Bus> >
{
public:
//------------------------------------------------------------------------
/** Constructor. */
BusList (MediaType type, BusDirection dir);

/** Returns the BusList Type. See \ref MediaType */
MediaType getType () const { return type; }

/** Returns the BusList direction. See \ref BusDirection */
BusDirection getDirection () const { return direction; }

OBJ_METHODS (Vst::BusList, FObject);

//------------------------------------------------------------------------
protected:
MediaType type;
BusDirection direction;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 353
- 0
source/includes/vst3sdk/public.sdk/source/vst/vstbypassprocessor.cpp View File

@@ -0,0 +1,353 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vstbypassprocessor.cpp
// Created by : Steinberg, 04/2015
// Description : Example of bypass support Implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "vstbypassprocessor.h"
#include "vstspeakerarray.h"

#include <cstdlib>

namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
static bool delay (int32 sampleFrames, float* inStream, float* outStream, float* delayBuffer,
int32 bufferSize, int32 bufferInPos, int32 bufferOutPos)
{
// delay inStream
int32 remain, inFrames, outFrames;
float* bufIn;
float* bufOut;

remain = sampleFrames;
while (remain > 0)
{
bufIn = delayBuffer + bufferInPos;
bufOut = delayBuffer + bufferOutPos;

if (bufferInPos > bufferOutPos)
inFrames = bufferSize - bufferInPos;
else
inFrames = bufferOutPos - bufferInPos;

outFrames = bufferSize - bufferOutPos;

if (inFrames > remain)
inFrames = remain;

if (outFrames > inFrames)
outFrames = inFrames;

// order important for in-place processing!
memcpy (bufIn, inStream, inFrames * sizeof (float)); // copy to buffer
memcpy (outStream, bufOut, outFrames * sizeof (float)); // copy from buffer

inStream += inFrames;
outStream += outFrames;

bufferInPos += inFrames;
if (bufferInPos >= bufferSize)
bufferInPos -= bufferSize;
bufferOutPos += outFrames;
if (bufferOutPos >= bufferSize)
bufferOutPos -= bufferSize;

if (inFrames > outFrames)
{
// still some output to copy
bufOut = delayBuffer + bufferOutPos;
outFrames = inFrames - outFrames;

memcpy (outStream, bufOut, outFrames * sizeof (float)); // copy from buffer

outStream += outFrames;

bufferOutPos += outFrames;
if (bufferOutPos >= bufferSize)
bufferOutPos -= bufferSize;
}

remain -= inFrames;
}

return true;
}


//------------------------------------------------------------------------
// AudioBuffer Implementation
//------------------------------------------------------------------------
AudioBuffer::AudioBuffer ()
: mBuffer (nullptr)
, mMaxSamples (0)
{}

//------------------------------------------------------------------------
AudioBuffer::~AudioBuffer ()
{
resize (0);
}

//------------------------------------------------------------------------
void AudioBuffer::resize (int32 _maxSamples)
{
if (mMaxSamples != _maxSamples)
{
mMaxSamples = _maxSamples;
if (mMaxSamples <= 0)
{
if (mBuffer)
free (mBuffer),
mBuffer = nullptr;
}
else
{
if (mBuffer)
mBuffer = (float*)realloc (mBuffer, mMaxSamples * sizeof (float));
else
mBuffer = (float*)malloc (mMaxSamples * sizeof (float));
}
}
}

//------------------------------------------------------------------------
void AudioBuffer::clear (int32 numSamples)
{
if (mBuffer)
{
int32 count = numSamples < mMaxSamples ? numSamples : mMaxSamples;
memset (mBuffer, 0, count * sizeof (float));
}
}

//------------------------------------------------------------------------
//------------------------------------------------------------------------
// BypassProcessor Implementation
//------------------------------------------------------------------------
BypassProcessor::BypassProcessor () : mActive (false), mMainIOBypass (false)
{
for (int32 i = 0; i < kMaxChannelsSupported; i++)
{
mInputPinLookup[i] = -1;
mDelays[i] = nullptr;
}
}

//------------------------------------------------------------------------
BypassProcessor::~BypassProcessor () { reset (); }

//------------------------------------------------------------------------
void BypassProcessor::setup (IAudioProcessor& audioProcessor, ProcessSetup& processSetup,
int32 delaySamples)
{
reset ();
SpeakerArrangement inputArr = 0;
bool hasInput = audioProcessor.getBusArrangement (kInput, 0, inputArr) == kResultOk;

SpeakerArrangement outputArr = 0;
bool hasOutput = audioProcessor.getBusArrangement (kOutput, 0, outputArr) == kResultOk;

mMainIOBypass = hasInput && hasOutput;
if (!mMainIOBypass)
return;

// create lookup table (in <- out) and delays...
SpeakerArray inArray (inputArr);
SpeakerArray outArray (outputArr);

// security check (todo)
if (outArray.total () >= kMaxChannelsSupported)
return;

for (int32 i = 0; i < outArray.total (); i++)
{
if (outArray.at (i) == Vst::kSpeakerL)
{
if (inArray.total () == 1 && inArray.at (0) == Vst::kSpeakerM)
{
mInputPinLookup[i] = 0;
}
else
mInputPinLookup[i] = inArray.getSpeakerIndex (outArray.at (i));
}
else
mInputPinLookup[i] = inArray.getSpeakerIndex (outArray.at (i));

mDelays[i] = new Delay (processSetup.maxSamplesPerBlock, delaySamples);
mDelays[i]->flush ();
}
}

//------------------------------------------------------------------------
void BypassProcessor::reset ()
{
mMainIOBypass = false;

for (int32 i = 0; i < kMaxChannelsSupported; i++)
{
mInputPinLookup[i] = -1;
if (mDelays[i])
{
delete mDelays[i];
mDelays[i] = nullptr;
}
}
}

//------------------------------------------------------------------------
void BypassProcessor::setActive (bool state)
{
if (mActive == state)
return;

mActive = state;

// flush delays when turning on
if (state && mMainIOBypass)
for (int32 i = 0; i < kMaxChannelsSupported; i++)
{
if (!mDelays[i])
break;
mDelays[i]->flush ();
}
}

//------------------------------------------------------------------------
void BypassProcessor::process (ProcessData& data)
{
if (mMainIOBypass)
{
AudioBusBuffers& inBus = data.inputs[0];
AudioBusBuffers& outBus = data.outputs[0];

for (int32 channel = 0; channel < outBus.numChannels; channel++)
{
float* src = nullptr;
bool silent = true;
float* dst = outBus.channelBuffers32[channel];
if (!dst)
continue;

int inputChannel = mInputPinLookup[channel];
if (inputChannel != -1)
{
silent = (inBus.silenceFlags & (1ll << inputChannel)) != 0;
src = inBus.channelBuffers32[inputChannel];
}

if (mDelays[channel]->process (src, dst, data.numSamples, silent))
{
outBus.silenceFlags |= (1ll << channel);
}
else
{
outBus.silenceFlags = 0;
}
}
}

// clear all other outputs
for (int32 outBusIndex = mMainIOBypass ? 1 : 0; outBusIndex < data.numOutputs; outBusIndex++)
{
AudioBusBuffers& outBus = data.outputs[outBusIndex];
if (!outBus.channelBuffers32)
continue;

for (int32 channel = 0; channel < outBus.numChannels; channel++)
{
float* dst = outBus.channelBuffers32[channel];
if (dst)
{
memset (dst, 0, data.numSamples * sizeof (float));
outBus.silenceFlags |= 1ll << channel;
}
}
}
}

//------------------------------------------------------------------------
void BypassProcessor::Delay::flush ()
{
mDelayBuffer.clearAll ();

mInPos = mOutPos = 0;
if (hasDelay ())
mOutPos = getBufferSamples () - mDelaySamples; // must be != inPos
}

//------------------------------------------------------------------------
bool BypassProcessor::Delay::process (float* src, float* dst, int32 numSamples, bool silentIn)
{
bool silentOut = false;

if (hasDelay () && src)
{
int32 bufferSize = getBufferSamples ();
delay (numSamples, src, dst, mDelayBuffer, bufferSize, mInPos, mOutPos);

// update inPos, outPos
mInPos += numSamples;
if (mInPos >= bufferSize)
mInPos -= bufferSize;
mOutPos += numSamples;
if (mOutPos >= bufferSize)
mOutPos -= bufferSize;
}
else
{
if (src != dst)
{
if (src && !silentIn)
{
memcpy (dst, src, numSamples * sizeof (float));
}
else
{
memset (dst, 0, numSamples * sizeof (float));
silentOut = true;
}
}
else
{
silentOut = silentIn;
}
}
return silentOut;
}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 118
- 0
source/includes/vst3sdk/public.sdk/source/vst/vstbypassprocessor.h View File

@@ -0,0 +1,118 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vstbypassprocessor.h
// Created by : Steinberg, 04/2015
// Description : Example of bypass support Implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/vst/ivstaudioprocessor.h"

namespace Steinberg {
namespace Vst {

#define kMaxChannelsSupported 64

//------------------------------------------------------------------------
// AudioBuffer
//------------------------------------------------------------------------
class AudioBuffer
{
public:
//------------------------------------------------------------------------
AudioBuffer ();
~AudioBuffer ();

int32 getMaxSamples () const { return mMaxSamples; }
void resize (int32 _maxSamples);
void release () { resize (0); }
void clear (int32 numSamples);
void clearAll () { if (mMaxSamples > 0) clear (mMaxSamples); }

operator float* () { return mBuffer; }
//------------------------------------------------------------------------
protected:
float* mBuffer;
int32 mMaxSamples;
};

//------------------------------------------------------------------------
// BypassProcessor
//------------------------------------------------------------------------
class BypassProcessor
{
public:
//------------------------------------------------------------------------
BypassProcessor ();
~BypassProcessor ();

void setup (IAudioProcessor& audioProcessor, ProcessSetup& processSetup, int32 delaySamples);
void reset ();

bool isActive () const { return mActive; }
void setActive (bool state);

void process (ProcessData& data);
//------------------------------------------------------------------------
protected:
bool mActive;
bool mMainIOBypass;
int32 mInputPinLookup[kMaxChannelsSupported];

struct Delay
{
AudioBuffer mDelayBuffer;
int32 mDelaySamples;
int32 mInPos;
int32 mOutPos;

Delay (int32 maxSamplesPerBlock, int32 delaySamples)
: mDelaySamples (delaySamples), mInPos (-1), mOutPos (-1)
{
if (mDelaySamples > 0)
mDelayBuffer.resize (maxSamplesPerBlock + mDelaySamples);
}

bool hasDelay () const { return mDelaySamples > 0; }
int32 getBufferSamples () const { return mDelayBuffer.getMaxSamples (); }

bool process (float* src, float* dst, int32 numSamples, bool silentIn);
void flush ();
};

Delay* mDelays[kMaxChannelsSupported];
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 214
- 0
source/includes/vst3sdk/public.sdk/source/vst/vstcomponent.cpp View File

@@ -0,0 +1,214 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vstcomponent.cpp
// Created by : Steinberg, 04/2005
// Description : Basic VST Plug-in Implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "vstcomponent.h"

namespace Steinberg {
namespace Vst {


//------------------------------------------------------------------------
// Component Implementation
//------------------------------------------------------------------------
Component::Component ()
: audioInputs (kAudio, kInput)
, audioOutputs (kAudio, kOutput)
, eventInputs (kEvent, kInput)
, eventOutputs (kEvent, kOutput)
{}

//------------------------------------------------------------------------
tresult PLUGIN_API Component::initialize (FUnknown* context)
{
return ComponentBase::initialize (context);
}

//------------------------------------------------------------------------
tresult PLUGIN_API Component::terminate ()
{
// remove all buses
removeAllBusses ();

return ComponentBase::terminate ();
}

//------------------------------------------------------------------------
BusList* Component::getBusList (MediaType type, BusDirection dir)
{
if (type == kAudio)
return dir == kInput ? &audioInputs : &audioOutputs;
else if (type == kEvent)
return dir == kInput ? &eventInputs : &eventOutputs;
return 0;
}

//------------------------------------------------------------------------
tresult Component::removeAudioBusses ()
{
audioInputs.clear ();
audioOutputs.clear ();

return kResultOk;
}

//------------------------------------------------------------------------
tresult Component::removeEventBusses ()
{
eventInputs.clear ();
eventOutputs.clear ();

return kResultOk;
}

//------------------------------------------------------------------------
tresult Component::removeAllBusses ()
{
removeAudioBusses ();
removeEventBusses ();

return kResultOk;
}

//------------------------------------------------------------------------
tresult PLUGIN_API Component::getControllerClassId (TUID classID)
{
if (controllerClass.isValid ())
{
controllerClass.toTUID (classID);
return kResultTrue;
}
return kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API Component::setIoMode (IoMode /*mode*/)
{
return kNotImplemented;
}

//------------------------------------------------------------------------
int32 PLUGIN_API Component::getBusCount (MediaType type, BusDirection dir)
{
BusList* busList = getBusList (type, dir);
return busList ? static_cast<int32> (busList->size ()) : 0;
}

//------------------------------------------------------------------------
tresult PLUGIN_API Component::getBusInfo (MediaType type, BusDirection dir, int32 index, BusInfo& info)
{
if (index < 0)
return kInvalidArgument;
BusList* busList = getBusList (type, dir);
if (busList == 0)
return kInvalidArgument;
if (index >= static_cast<int32> (busList->size ()))
return kInvalidArgument;

Bus* bus = busList->at (index);
info.mediaType = type;
info.direction = dir;
if (bus->getInfo (info))
return kResultTrue;
return kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API Component::getRoutingInfo (RoutingInfo& /*inInfo*/, RoutingInfo& /*outInfo*/)
{
return kNotImplemented;
}

//------------------------------------------------------------------------
tresult PLUGIN_API Component::activateBus (MediaType type, BusDirection dir, int32 index, TBool state)
{
if (index < 0)
return kInvalidArgument;
BusList* busList = getBusList (type, dir);
if (busList == 0)
return kInvalidArgument;
if (index >= static_cast<int32> (busList->size ()))
return kInvalidArgument;
Bus* bus = busList->at (index);
bus->setActive (state);
return kResultTrue;
}

//------------------------------------------------------------------------
tresult PLUGIN_API Component::setActive (TBool /*state*/)
{
return kResultOk;
}

//------------------------------------------------------------------------
tresult PLUGIN_API Component::setState (IBStream* /*state*/)
{
return kNotImplemented;
}

//------------------------------------------------------------------------
tresult PLUGIN_API Component::getState (IBStream* /*state*/)
{
return kNotImplemented;
}

//------------------------------------------------------------------------
tresult Component::renameBus (MediaType type, BusDirection dir, int32 index, const String128 newName)
{
if (index < 0)
return kInvalidArgument;
BusList* busList = getBusList (type, dir);
if (busList == 0)
return kInvalidArgument;
if (index >= static_cast<int32> (busList->size ()))
return kInvalidArgument;
Bus* bus = busList->at (index);
bus->setName (newName);
return kResultTrue;
}


//------------------------------------------------------------------------
// Helpers Implementation
//------------------------------------------------------------------------
tresult getSpeakerChannelIndex (SpeakerArrangement arrangement, uint64 speaker, int32& channel)
{
channel = SpeakerArr::getSpeakerIndex (speaker, arrangement);
return channel < 0 ? kResultFalse : kResultTrue;
}
} // namespace Vst
} // namespace Steinberg

+ 118
- 0
source/includes/vst3sdk/public.sdk/source/vst/vstcomponent.h View File

@@ -0,0 +1,118 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vstcomponent.h
// Created by : Steinberg, 04/2005
// Description : Basic VST Plug-in Implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "public.sdk/source/vst/vstcomponentbase.h"
#include "public.sdk/source/vst/vstbus.h"
#include "pluginterfaces/vst/ivstcomponent.h"

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {


//------------------------------------------------------------------------
/** Default implementation for a VST 3 Component.
\ingroup vstClasses
Can be used as base class for a VST 3 component implementation. */
//------------------------------------------------------------------------
class Component: public ComponentBase,
public IComponent
{
public:
//------------------------------------------------------------------------
/** Constructor */
Component ();

//---Internal Methods-------
/** Sets the controller Class ID associated to its component. */
void setControllerClass (const FUID& cid) { controllerClass = cid; }

/** Removes all Audio Buses. */
tresult removeAudioBusses ();

/** Removes all Event Buses. */
tresult removeEventBusses ();

/** Renames a specific bus. Do not forget to inform the host about this (see \ref IComponentHandler::restartComponent (kIoTitlesChanged)). */
tresult renameBus (MediaType type, BusDirection dir, int32 index, const String128 newName);

//---from IComponent--------
tresult PLUGIN_API getControllerClassId (TUID classID) SMTG_OVERRIDE;
tresult PLUGIN_API setIoMode (IoMode mode) SMTG_OVERRIDE;
int32 PLUGIN_API getBusCount (MediaType type, BusDirection dir) SMTG_OVERRIDE;
tresult PLUGIN_API getBusInfo (MediaType type, BusDirection dir, int32 index, BusInfo& info) SMTG_OVERRIDE;
tresult PLUGIN_API getRoutingInfo (RoutingInfo& inInfo, RoutingInfo& outInfo) SMTG_OVERRIDE;
tresult PLUGIN_API activateBus (MediaType type, BusDirection dir, int32 index, TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
tresult PLUGIN_API setState (IBStream* state) SMTG_OVERRIDE;
tresult PLUGIN_API getState (IBStream* state) SMTG_OVERRIDE;

//---from ComponentBase------
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
tresult PLUGIN_API terminate () SMTG_OVERRIDE;

//---Interface---------
OBJ_METHODS (Component, ComponentBase)
DEFINE_INTERFACES
DEF_INTERFACE (IComponent)
END_DEFINE_INTERFACES (ComponentBase)
REFCOUNT_METHODS(ComponentBase)

//------------------------------------------------------------------------
protected:
FUID controllerClass;
BusList audioInputs;
BusList audioOutputs;
BusList eventInputs;
BusList eventOutputs;

BusList* getBusList (MediaType type, BusDirection dir);
tresult removeAllBusses ();
};


//------------------------------------------------------------------------
// some Helper functions....
//------------------------------------------------------------------------

/** Gets the channel index of a given speaker in a arrangement, returns kResultFalse if speaker not part of the arrangement else returns kResultTrue. */
tresult getSpeakerChannelIndex (SpeakerArrangement arrangement, uint64 speaker, int32& channel);

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 179
- 0
source/includes/vst3sdk/public.sdk/source/vst/vstcomponentbase.cpp View File

@@ -0,0 +1,179 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vstcomponentbase.cpp
// Created by : Steinberg, 05/2005
// Description : Base class for VST Component and Edit Controller
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "vstcomponentbase.h"
#include "base/source/fstring.h"

namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
// ComponentBase Implementation
//------------------------------------------------------------------------
ComponentBase::ComponentBase ()
: hostContext (0)
, peerConnection (0)
{}

//------------------------------------------------------------------------
ComponentBase::~ComponentBase ()
{}

//------------------------------------------------------------------------
tresult PLUGIN_API ComponentBase::initialize (FUnknown* context)
{
// check if already initialized
if (hostContext)
return kResultFalse;

hostContext = context;
if (hostContext)
hostContext->addRef ();

return kResultOk;
}

//------------------------------------------------------------------------
tresult PLUGIN_API ComponentBase::terminate ()
{
// release host interfaces
if (hostContext)
{
hostContext->release ();
hostContext = 0;
}

// in case host did not disconnect us,
// release peer now
if (peerConnection)
{
peerConnection->disconnect (this);
peerConnection->release ();
peerConnection = 0;
}

return kResultOk;
}

//------------------------------------------------------------------------
tresult PLUGIN_API ComponentBase::connect (IConnectionPoint* other)
{
if (!other)
return kInvalidArgument;

// check if already connected
if (peerConnection)
return kResultFalse;

peerConnection = other;
peerConnection->addRef ();
return kResultOk;
}

//------------------------------------------------------------------------
tresult PLUGIN_API ComponentBase::disconnect (IConnectionPoint* other)
{
if (peerConnection && other == peerConnection)
{
peerConnection->release (),
peerConnection = 0;
return kResultOk;
}
return kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API ComponentBase::notify (IMessage* message)
{
if (!message)
return kInvalidArgument;

if (!strcmp (message->getMessageID (), "TextMessage"))
{
TChar string[256] = {0};
if (message->getAttributes ()->getString ("Text", string, sizeof (string) / sizeof (char16)) == kResultOk)
{
String tmp (string);
tmp.toMultiByte (kCP_Utf8);
return receiveText (tmp.text8 ());
}
}

return kResultFalse;
}

//------------------------------------------------------------------------
IMessage* ComponentBase::allocateMessage ()
{
FUnknownPtr<IHostApplication> hostApp (hostContext);
if (hostApp)
return Vst::allocateMessage (hostApp);
return 0;
}

//------------------------------------------------------------------------
tresult ComponentBase::sendMessage (IMessage* message)
{
if (message != 0 && getPeer () != 0)
return getPeer ()->notify (message);
return kResultFalse;
}

//------------------------------------------------------------------------
tresult ComponentBase::sendTextMessage (const char8* text)
{
IMessage* message = allocateMessage ();
if (!message)
return kResultFalse;

FReleaser msgReleaser (message);
message->setMessageID ("TextMessage");
String tmp (text, kCP_Utf8);
if (tmp.length () >= 256)
tmp.remove (255);
message->getAttributes ()->setString ("Text", tmp.text16 ());
return sendMessage (message);
}

//------------------------------------------------------------------------
tresult ComponentBase::receiveText (const char8* /*text*/)
{
return kResultOk;
}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

+ 105
- 0
source/includes/vst3sdk/public.sdk/source/vst/vstcomponentbase.h View File

@@ -0,0 +1,105 @@
//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/vstcomponentbase.h
// Created by : Steinberg, 05/2005
// Description : Base class for Component and Edit Controller
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Steinberg Media Technologies nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/base/ipluginbase.h"
#include "pluginterfaces/vst/ivstmessage.h"
#include "pluginterfaces/vst/ivsthostapplication.h"
#include "base/source/fobject.h"

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
/** Base class for VST 3 Component and Edit Controller.
\ingroup vstClasses */
//------------------------------------------------------------------------
class ComponentBase: public FObject,
public IPluginBase,
public IConnectionPoint
{
public:
//------------------------------------------------------------------------
ComponentBase ();
virtual ~ComponentBase ();

//--- Internal Methods------
/** Returns the hostContext (set by the host during initialize call). */
FUnknown* getHostContext () { return hostContext; }

/** Returns the peer for the messaging communication (you can only use IConnectionPoint::notify for communicate between peers, do not try to cast peerConnection. */
IConnectionPoint* getPeer () { return peerConnection; }

/** Allocates a message instance (don't forget to release it). */
IMessage* allocateMessage ();

/** Sends the given message to the peer. */
tresult sendMessage (IMessage* message);

/** Sends a simple text message to the peer (max 255 characters). Text is interpreted as UTF-8. */
tresult sendTextMessage (const char8* text);

/** Receives a simple text message from the peer (max 255 characters). Text is UTF-8 encoded. */
virtual tresult receiveText (const char8* text);

//---from IPluginBase------
virtual tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
virtual tresult PLUGIN_API terminate () SMTG_OVERRIDE;

//---from IConnectionPoint-----------
tresult PLUGIN_API connect (IConnectionPoint* other) SMTG_OVERRIDE;
tresult PLUGIN_API disconnect (IConnectionPoint* other) SMTG_OVERRIDE;
tresult PLUGIN_API notify (IMessage* message) SMTG_OVERRIDE;

//---Interface------
OBJ_METHODS (ComponentBase, FObject)
DEFINE_INTERFACES
DEF_INTERFACE (IPluginBase)
DEF_INTERFACE (IConnectionPoint)
END_DEFINE_INTERFACES (FObject)
REFCOUNT_METHODS(FObject)

//------------------------------------------------------------------------
protected:
FUnknown* hostContext;
IConnectionPoint* peerConnection;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save