Initial release
@@ -0,0 +1,67 @@
|
||||
|
||||
function(smtg_target_setup_options target)
|
||||
set(options)
|
||||
set(oneValueArgs
|
||||
BUNDLE_IDENTIFIER
|
||||
COMPANY_NAME
|
||||
)
|
||||
set(multiValueArgs)
|
||||
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
|
||||
|
||||
if(ARG_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: The following parameters are unrecognized: ${ARG_UNPARSED_ARGUMENTS}")
|
||||
endif()
|
||||
|
||||
if(NOT ARG_BUNDLE_IDENTIFIER)
|
||||
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: BUNDLE_IDENTIFIER must be specified")
|
||||
endif()
|
||||
|
||||
if(NOT ARG_COMPANY_NAME)
|
||||
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: ARG_COMPANY_NAME must be specified")
|
||||
endif()
|
||||
|
||||
smtg_target_configure_version_file(${target})
|
||||
|
||||
if(SMTG_MAC)
|
||||
smtg_target_set_bundle(${target}
|
||||
BUNDLE_IDENTIFIER "${ARG_BUNDLE_IDENTIFIER}"
|
||||
COMPANY_NAME "${ARG_COMPANY_NAME}"
|
||||
)
|
||||
elseif(SMTG_WIN)
|
||||
target_sources(${target}
|
||||
PRIVATE
|
||||
resource/info.rc
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${target}
|
||||
PRIVATE
|
||||
sdk
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(smtg_target_setup_as_vst3_example target)
|
||||
set_target_properties(${target}
|
||||
PROPERTIES
|
||||
${SDK_IDE_PLUGIN_EXAMPLES_FOLDER}
|
||||
)
|
||||
|
||||
target_compile_features(${target}
|
||||
PUBLIC
|
||||
cxx_std_17
|
||||
)
|
||||
|
||||
smtg_target_setup_options(${target}
|
||||
BUNDLE_IDENTIFIER "com.steinberg.vst3.${target}"
|
||||
COMPANY_NAME "Steinberg Media Technologies"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
if(ANDROID)
|
||||
add_subdirectory(adelay)
|
||||
return()
|
||||
endif(ANDROID)
|
||||
|
||||
include(SMTG_AddSubDirectories)
|
||||
|
||||
smtg_add_subdirectories()
|
||||
@@ -0,0 +1,2 @@
|
||||
/DerivedData
|
||||
/build
|
||||
@@ -0,0 +1,102 @@
|
||||
|
||||
# iOS target
|
||||
if(SMTG_MAC AND SMTG_BUILD_INTERAPPAUDIO)
|
||||
if(XCODE AND SMTG_ENABLE_IOS_TARGETS)
|
||||
set(target noteexpressionsynth_iaa_ios)
|
||||
set(${target}_xib_resources
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/resource/InterAppAudio/Images.xcassets
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/resource/InterAppAudio/LaunchScreen.storyboard
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/resource/InterAppAudio/noteexpressionsynth_ios.entitlements
|
||||
${SDK_ROOT}/public.sdk/source/vst/interappaudio/PresetBrowserView.xib
|
||||
${SDK_ROOT}/public.sdk/source/vst/interappaudio/PresetSaveView.xib
|
||||
${SDK_ROOT}/public.sdk/source/vst/interappaudio/SettingsView.xib
|
||||
InterAppAudioExample/VSTInterAppAudioHostUIControllerView.xib
|
||||
)
|
||||
set(${target}_sources
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/brownnoise.h
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/factory.cpp
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/filter.h
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/note_expression_synth_controller.cpp
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/note_expression_synth_controller.h
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/note_expression_synth_processor.cpp
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/note_expression_synth_processor.h
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/note_expression_synth_ui.cpp
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/note_expression_synth_ui.h
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/note_expression_synth_voice.cpp
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/note_expression_synth_voice.h
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/note_touch_controller.cpp
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/note_touch_controller.h
|
||||
${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/source/version.h
|
||||
${SDK_ROOT}/public.sdk/source/main/macmain.cpp
|
||||
${SDK_ROOT}/public.sdk/source/vst/auwrapper/NSDataIBStream.mm
|
||||
${SDK_ROOT}/public.sdk/source/vst/hosting/eventlist.cpp
|
||||
${SDK_ROOT}/public.sdk/source/vst/hosting/hostclasses.cpp
|
||||
${SDK_ROOT}/public.sdk/source/vst/hosting/parameterchanges.cpp
|
||||
${SDK_ROOT}/public.sdk/source/vst/hosting/pluginterfacesupport.cpp
|
||||
${SDK_ROOT}/public.sdk/source/vst/hosting/processdata.cpp
|
||||
${SDK_ROOT}/public.sdk/source/vst/vstguieditor.cpp
|
||||
${VSTGUI_ROOT}/vstgui4/vstgui/contrib/keyboardview.cpp
|
||||
${VSTGUI_ROOT}/vstgui4/vstgui/contrib/keyboardview.h
|
||||
${VSTGUI_ROOT}/vstgui4/vstgui/plugin-bindings/vst3editor.cpp
|
||||
${VSTGUI_ROOT}/vstgui4/vstgui/plugin-bindings/vst3editor.h
|
||||
${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/vstgui_ios.mm
|
||||
${VSTGUI_ROOT}/vstgui4/vstgui/vstgui_uidescription.cpp
|
||||
InterAppAudioExample/VSTInterAppAudioAppDelegate.mm
|
||||
InterAppAudioExample/VSTInterAppAudioHostUIControllerViewController.mm
|
||||
InterAppAudioExample/main.m
|
||||
)
|
||||
set(prefix_header ${SDK_ROOT}/public.sdk/samples/vst/InterAppAudio/InterAppAudioExample/InterAppAudioExample-Prefix.pch)
|
||||
add_executable(${target} ${${target}_sources} ${${target}_xib_resources})
|
||||
smtg_target_set_platform_ios(${target})
|
||||
target_compile_options(${target}
|
||||
PUBLIC
|
||||
-DVSTGUI_LIVE_EDITING=0
|
||||
) # NO VSTGUI LIVE EDITING SUPPORT FOR iOS
|
||||
set_target_properties(${target}
|
||||
PROPERTIES
|
||||
${SDK_IDE_PLUGIN_EXAMPLES_FOLDER}
|
||||
)
|
||||
set_target_properties(${target}
|
||||
PROPERTIES
|
||||
BUNDLE TRUE
|
||||
RESOURCE "${${target}_xib_resources}"
|
||||
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_LIST_DIR}/../note_expression_synth/resource/InterAppAudio/noteexpressionsynth_ios.entitlements"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${SMTG_CODE_SIGN_IDENTITY_IOS}"
|
||||
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO" # prevent warning
|
||||
XCODE_ATTRIBUTE_GCC_PREFIX_HEADER ${prefix_header}
|
||||
XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE "YES"
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ${SMTG_IOS_DEVELOPMENT_TEAM}
|
||||
)
|
||||
target_link_libraries(${target}
|
||||
PRIVATE
|
||||
interappaudio
|
||||
"-framework QuartzCore"
|
||||
"-framework MobileCoreServices"
|
||||
"-framework Accelerate"
|
||||
"-framework ImageIO"
|
||||
"-framework GLKit"
|
||||
"-framework CoreText"
|
||||
)
|
||||
smtg_target_set_bundle(${target} INFOPLIST "${CMAKE_CURRENT_LIST_DIR}/../note_expression_synth/resource/InterAppAudio/NoteExpressionSynthExample.plist" PREPROCESS)
|
||||
target_include_directories(${target}
|
||||
PUBLIC
|
||||
${ROOT}/vstgui4
|
||||
)
|
||||
|
||||
smtg_target_add_vst3_resource(${target} "${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/resource/about.png")
|
||||
smtg_target_add_vst3_resource(${target} "${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/resource/background.png")
|
||||
smtg_target_add_vst3_resource(${target} "${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/resource/groupframe.png")
|
||||
smtg_target_add_vst3_resource(${target} "${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/resource/knob big.png")
|
||||
smtg_target_add_vst3_resource(${target} "${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/resource/knob.png")
|
||||
smtg_target_add_vst3_resource(${target} "${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/resource/knob2.png")
|
||||
smtg_target_add_vst3_resource(${target} "${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/resource/note_expression_synth.uidesc")
|
||||
smtg_target_add_vst3_resource(${target} "${SDK_ROOT}/public.sdk/samples/vst/note_expression_synth/resource/vst3_logo_small.png")
|
||||
else()
|
||||
message("[SMTG] * To enable building the InterAppAudio NoteExpressionSynth example for iOS you need to set the SMTG_IOS_DEVELOPMENT_TEAM and use the Xcode generator")
|
||||
endif(XCODE AND SMTG_ENABLE_IOS_TARGETS)
|
||||
endif(SMTG_MAC AND SMTG_BUILD_INTERAPPAUDIO)
|
||||
@@ -0,0 +1,65 @@
|
||||
<?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>AudioComponents</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>manufacturer</key>
|
||||
<string>SMTG</string>
|
||||
<key>name</key>
|
||||
<string>ADelay VST3</string>
|
||||
<key>subtype</key>
|
||||
<string>adly</string>
|
||||
<key>type</key>
|
||||
<string>aurx</string>
|
||||
<key>version</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.steinberg.interappaudioexamples.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>audio</string>
|
||||
</array>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<true/>
|
||||
<key>UIStatusBarHidden~ipad</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,26 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/interappaudio/InterAppAudioExample/InterAppAudioExample-Prefix.pch
|
||||
// Created by : Steinberg, 08/2013
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#import <Availability.h>
|
||||
|
||||
#ifndef __IPHONE_3_0
|
||||
#warning "This project uses features only available in iOS SDK 3.0 and later."
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
<?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>inter-app-audio</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,26 @@
|
||||
// clang-format off
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/interappaudio/InterAppAudioExample/VSTInterAppAudioAppDelegate.h
|
||||
// Created by : Steinberg, 08/2013
|
||||
// Description :
|
||||
// Flags : clang-format SMTGSequencer
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
// clang-format on
|
||||
|
||||
#import "public.sdk/source/vst/interappaudio/VSTInterAppAudioAppDelegateBase.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@interface VSTInterAppAudioAppDelegate : VSTInterAppAudioAppDelegateBase
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,119 @@
|
||||
// clang-format off
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/interappaudio/InterAppAudioExample/VSTInterAppAudioAppDelegate.mm
|
||||
// Created by : Steinberg, 08/2013
|
||||
// Description :
|
||||
// Flags : clang-format SMTGSequencer
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
// clang-format on
|
||||
|
||||
#import "VSTInterAppAudioAppDelegate.h"
|
||||
|
||||
#import "VSTInterAppAudioHostUIControllerViewController.h"
|
||||
#import "public.sdk/source/vst/interappaudio/AudioIO.h"
|
||||
|
||||
using namespace Steinberg::Vst::InterAppAudio;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@interface VSTInterAppAudioAppDelegate ()
|
||||
//------------------------------------------------------------------------
|
||||
{
|
||||
UIButton* showHostView;
|
||||
}
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@implementation VSTInterAppAudioAppDelegate
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (BOOL)application:(UIApplication*)application
|
||||
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
|
||||
{
|
||||
if ([super application:application didFinishLaunchingWithOptions:launchOptions])
|
||||
{
|
||||
[self performSelector:@selector (createShowHostViewButton) withObject:nil afterDelay:0.2];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector (audioIOConnectionChanged)
|
||||
name:AudioIO::kConnectionStateChange
|
||||
object:nil];
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (NSUInteger)application:(UIApplication*)application
|
||||
supportedInterfaceOrientationsForWindow:(UIWindow*)window
|
||||
{
|
||||
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (void)audioIOConnectionChanged
|
||||
{
|
||||
showHostView.hidden = AudioIO::instance ()->getInterAppAudioConnected () == false;
|
||||
if (showHostView.hidden)
|
||||
{
|
||||
for (id childController in [self.window.rootViewController childViewControllers])
|
||||
{
|
||||
if ([childController
|
||||
isKindOfClass:[VSTInterAppAudioHostUIControllerViewController class]])
|
||||
{
|
||||
[childController hideView:self];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (void)createShowHostViewButton
|
||||
{
|
||||
showHostView = [UIButton buttonWithType:UIButtonTypeInfoDark];
|
||||
[showHostView addTarget:self
|
||||
action:@selector (showHostViewAction:)
|
||||
forControlEvents:UIControlEventTouchDown];
|
||||
|
||||
const CGFloat margin = 15;
|
||||
CGRect frame = showHostView.frame;
|
||||
frame.origin.y =
|
||||
[self.window.rootViewController.view bounds].size.height - (frame.size.height + margin);
|
||||
frame.origin.x = margin;
|
||||
showHostView.frame = frame;
|
||||
|
||||
[self.window.rootViewController.view addSubview:showHostView];
|
||||
|
||||
if (AudioIO::instance ()->getInterAppAudioConnected () == false)
|
||||
{
|
||||
showHostView.hidden = YES;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (void)showHostViewAction:(id)sender
|
||||
{
|
||||
VSTInterAppAudioHostUIControllerViewController* controller =
|
||||
[[VSTInterAppAudioHostUIControllerViewController alloc] init];
|
||||
[self.window.rootViewController addChildViewController:controller];
|
||||
CGRect frame = controller.view.frame;
|
||||
frame.origin.y = [self.window.rootViewController.view bounds].size.height;
|
||||
controller.view.frame = frame;
|
||||
|
||||
[self.window.rootViewController.view addSubview:controller.view];
|
||||
|
||||
frame.origin.y = [self.window.rootViewController.view bounds].size.height - frame.size.height;
|
||||
|
||||
[UIView animateWithDuration:0.3 animations:^{ controller.view.frame = frame; }];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="4471.1" systemVersion="12E55" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3697.3"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="VSTInterAppAudioHostUIControllerViewController">
|
||||
<connections>
|
||||
<outlet property="hostButton" destination="vf0-Cd-0Xg" id="wcF-LJ-CxA"/>
|
||||
<outlet property="view" destination="2" id="3"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="2">
|
||||
<rect key="frame" x="0.0" y="0.0" width="492" height="104"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vf0-Cd-0Xg">
|
||||
<rect key="frame" x="408" y="20" width="64" height="64"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="12"/>
|
||||
<state key="normal" title="Goto Host">
|
||||
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<state key="highlighted">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="switchToHost:" destination="-1" eventType="touchUpInside" id="ttD-Qy-eUd"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="s4k-Xf-tiu">
|
||||
<rect key="frame" x="0.0" y="60" width="73" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
|
||||
<state key="normal" title="Close">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<state key="highlighted">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="hideView:" destination="-1" eventType="touchUpInside" id="MDK-lh-cXb"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="b7T-FM-ORL">
|
||||
<rect key="frame" x="286" y="20" width="64" height="64"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="37"/>
|
||||
<state key="normal" title="▶">
|
||||
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<state key="highlighted">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="play:" destination="-1" eventType="touchUpInside" id="sTf-N9-aIV"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iQU-IE-WGe">
|
||||
<rect key="frame" x="214" y="20" width="64" height="64"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="37"/>
|
||||
<state key="normal" title="⏪">
|
||||
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<state key="highlighted">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="rewind:" destination="-1" eventType="touchUpInside" id="wCj-ym-Zbp"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="oIG-ts-Ybg">
|
||||
<rect key="frame" x="142" y="20" width="64" height="64"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="37"/>
|
||||
<state key="normal" title="🔴">
|
||||
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<state key="highlighted">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="record:" destination="-1" eventType="touchUpInside" id="FDc-fT-H5V"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="0.80000000000000004" colorSpace="calibratedRGB"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,34 @@
|
||||
// clang-format off
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/interappaudio/InterAppAudioExample/VSTInterAppAudioHostUIControllerViewController.h
|
||||
// Created by : Steinberg, 08/2013
|
||||
// Description :
|
||||
// Flags : clang-format SMTGSequencer
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
// clang-format on
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@interface VSTInterAppAudioHostUIControllerViewController : UIViewController
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
- (IBAction)hideView:(id)sender;
|
||||
|
||||
- (IBAction)switchToHost:(id)sender;
|
||||
- (IBAction)play:(id)sender;
|
||||
- (IBAction)rewind:(id)sender;
|
||||
- (IBAction)record:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
// clang-format off
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/interappaudio/InterAppAudioExample/VSTInterAppAudioHostUIControllerViewController.mm
|
||||
// Created by : Steinberg, 08/2013
|
||||
// Description :
|
||||
// Flags : clang-format SMTGSequencer
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
// clang-format on
|
||||
|
||||
#import "VSTInterAppAudioHostUIControllerViewController.h"
|
||||
|
||||
#import "public.sdk/source/vst/interappaudio/AudioIO.h"
|
||||
|
||||
using namespace Steinberg::Vst::InterAppAudio;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static UIImage* scaleImageToSize (UIImage* image, CGSize newSize)
|
||||
{
|
||||
UIGraphicsBeginImageContextWithOptions (newSize, NO, 0.0);
|
||||
[image drawInRect:CGRectMake (0, 0, newSize.width, newSize.height)];
|
||||
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext ();
|
||||
UIGraphicsEndImageContext ();
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@interface VSTInterAppAudioHostUIControllerViewController ()
|
||||
//------------------------------------------------------------------------
|
||||
@property (assign) IBOutlet UIButton* hostButton;
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@implementation VSTInterAppAudioHostUIControllerViewController
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (id)init
|
||||
{
|
||||
self = [super initWithNibName:@"VSTInterAppAudioHostUIControllerView" bundle:nil];
|
||||
if (self)
|
||||
{
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
UIImage* image = AudioIO::instance ()->getHostIcon ();
|
||||
if (image)
|
||||
{
|
||||
image = scaleImageToSize (image, self.hostButton.bounds.size);
|
||||
[self.hostButton setTitle:@"" forState:UIControlStateNormal];
|
||||
[self.hostButton setImage:image forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
self.view.layer.shadowColor = [[UIColor blackColor] CGColor];
|
||||
self.view.layer.shadowOpacity = 0.5;
|
||||
self.view.layer.shadowRadius = 5;
|
||||
self.view.layer.shadowOffset = CGSizeMake (5, -5);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (IBAction)hideView:(id)sender
|
||||
{
|
||||
[UIView animateWithDuration:0.3
|
||||
animations:^{
|
||||
CGRect frame = self.view.frame;
|
||||
frame.origin.y += frame.size.height;
|
||||
self.view.frame = frame;
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
[self.view removeFromSuperview];
|
||||
[self removeFromParentViewController];
|
||||
}];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (IBAction)switchToHost:(id)sender
|
||||
{
|
||||
AudioIO::instance ()->switchToHost ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (IBAction)play:(id)sender
|
||||
{
|
||||
AudioIO::instance ()->sendRemoteControlEvent (kAudioUnitRemoteControlEvent_TogglePlayPause);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (IBAction)rewind:(id)sender
|
||||
{
|
||||
AudioIO::instance ()->sendRemoteControlEvent (kAudioUnitRemoteControlEvent_Rewind);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (IBAction)record:(id)sender
|
||||
{
|
||||
AudioIO::instance ()->sendRemoteControlEvent (kAudioUnitRemoteControlEvent_ToggleRecord);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/interappaudio/InterAppAudioExample/main.m
|
||||
// Created by : Steinberg, 08/2013
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "VSTInterAppAudioAppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain (argc, argv, nil, NSStringFromClass ([VSTInterAppAudioAppDelegate class]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.25.0)
|
||||
|
||||
project(smtg-vst3-adelay
|
||||
VERSION ${vstsdk_VERSION}.0
|
||||
DESCRIPTION "Steinberg VST 3 ADelay example"
|
||||
)
|
||||
|
||||
smtg_add_vst3plugin(adelay
|
||||
source/adelaycontroller.cpp
|
||||
source/adelaycontroller.h
|
||||
source/adelayids.h
|
||||
source/adelayprocessor.cpp
|
||||
source/adelayprocessor.h
|
||||
source/exampletest.cpp
|
||||
source/factory.cpp
|
||||
source/version.h
|
||||
${SDK_ROOT}/public.sdk/source/vst/utility/test/ringbuffertest.cpp
|
||||
${SDK_ROOT}/public.sdk/source/vst/utility/test/versionparsertest.cpp
|
||||
)
|
||||
|
||||
smtg_target_setup_as_vst3_example(adelay)
|
||||
@@ -0,0 +1,18 @@
|
||||
# ADelay
|
||||
|
||||
## Introduction
|
||||
|
||||
**ADelay** is a simple FX plug-in with just one parameter for delay control.
|
||||
|
||||
> See also: [Online Documentation](https://steinbergmedia.github.io/vst3_dev_portal/pages/What+is+the+VST+3+SDK/Plug-in+Examples.html#adelay).
|
||||
|
||||
## Getting Started
|
||||
|
||||
This plug-in is part of the VST 3 SDK package. It is created with the VST 3 SDK root project.
|
||||
|
||||
> See the top-level README of the VST 3 SDK: https://github.com/steinbergmedia/vst3sdk.git
|
||||
|
||||
## Getting Help
|
||||
|
||||
* Read through the SDK documentation on the **[VST 3 Developer Portal](https://steinbergmedia.github.io/vst3_dev_portal/pages/index.html)**
|
||||
* Ask some real people in the official **[VST 3 Developer Forum](https://forums.steinberg.net/c/developer/103)**
|
||||
@@ -0,0 +1,45 @@
|
||||
#include <windows.h>
|
||||
#include "../source/version.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Version
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION MAJOR_VERSION_INT,SUB_VERSION_INT,RELEASE_NUMBER_INT,BUILD_NUMBER_INT
|
||||
PRODUCTVERSION MAJOR_VERSION_INT,SUB_VERSION_INT,RELEASE_NUMBER_INT,BUILD_NUMBER_INT
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040004e4"
|
||||
BEGIN
|
||||
VALUE "FileVersion", FULL_VERSION_STR
|
||||
VALUE "ProductVersion", FULL_VERSION_STR
|
||||
VALUE "OriginalFilename", stringOriginalFilename
|
||||
VALUE "FileDescription", stringFileDescription
|
||||
VALUE "InternalName", stringFileDescription
|
||||
VALUE "ProductName", stringFileDescription
|
||||
VALUE "CompanyName", stringCompanyName
|
||||
VALUE "LegalCopyright", stringLegalCopyright
|
||||
VALUE "LegalTrademarks", stringLegalTrademarks
|
||||
//VALUE "PrivateBuild", " \0"
|
||||
//VALUE "SpecialBuild", " \0"
|
||||
//VALUE "Comments", " \0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x400, 1252
|
||||
END
|
||||
END
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/adelay/source/adelaycontroller.cpp
|
||||
// Created by : Steinberg, 06/2009
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "adelaycontroller.h"
|
||||
#include "adelayids.h"
|
||||
#include "pluginterfaces/base/ibstream.h"
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#include "interappaudio/iosEditor.h"
|
||||
#endif
|
||||
#include "base/source/fstreamer.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
DEF_CLASS_IID (IDelayTestController)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayController::initialize (FUnknown* context)
|
||||
{
|
||||
tresult result = EditController::initialize (context);
|
||||
if (result == kResultTrue)
|
||||
{
|
||||
parameters.addParameter (STR16 ("Bypass"), nullptr, 1, 0, ParameterInfo::kCanAutomate|ParameterInfo::kIsBypass, kBypassId);
|
||||
|
||||
parameters.addParameter (STR16 ("Delay"), STR16 ("sec"), 0, 1, ParameterInfo::kCanAutomate, kDelayId);
|
||||
}
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
//-----------------------------------------------------------------------------
|
||||
IPlugView* PLUGIN_API ADelayController::createView (FIDString name)
|
||||
{
|
||||
if (FIDStringsEqual (name, ViewType::kEditor))
|
||||
{
|
||||
return new ADelayEditorForIOS (this);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayController::setComponentState (IBStream* state)
|
||||
{
|
||||
// we receive the current state of the component (processor part)
|
||||
// we read only the gain and bypass value...
|
||||
if (!state)
|
||||
return kResultFalse;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
float savedDelay = 0.f;
|
||||
if (streamer.readFloat (savedDelay) == false)
|
||||
return kResultFalse;
|
||||
setParamNormalized (kDelayId, static_cast<ParamValue> (savedDelay));
|
||||
|
||||
int32 bypassState = 0;
|
||||
if (streamer.readInt32 (bypassState) == false)
|
||||
{
|
||||
// could be an old version, continue
|
||||
}
|
||||
setParamNormalized (kBypassId, bypassState ? 1 : 0);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool PLUGIN_API ADelayController::doTest ()
|
||||
{
|
||||
// this is called when running thru the validator
|
||||
// we can now run our own test cases
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,70 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/adelay/source/adelaycontroller.h
|
||||
// Created by : Steinberg, 06/2009
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "public.sdk/source/vst/vsteditcontroller.h"
|
||||
|
||||
#if SMTG_OS_MACOS
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
class IDelayTestController : public FUnknown
|
||||
{
|
||||
public:
|
||||
virtual bool PLUGIN_API doTest () = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IDelayTestController, 0x9FC98F39, 0x27234512, 0x84FBC4AD, 0x618A14FD)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class ADelayController : public EditController, public IDelayTestController
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
// create function required for plug-in factory,
|
||||
// it will be called to create new instances of this controller
|
||||
//------------------------------------------------------------------------
|
||||
static FUnknown* createInstance (void*) { return (IEditController*)new ADelayController (); }
|
||||
|
||||
//---from IPluginBase--------
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
|
||||
//---from EditController-----
|
||||
#if TARGET_OS_IPHONE
|
||||
IPlugView* PLUGIN_API createView (FIDString name) SMTG_OVERRIDE;
|
||||
#endif
|
||||
tresult PLUGIN_API setComponentState (IBStream* state) SMTG_OVERRIDE;
|
||||
|
||||
bool PLUGIN_API doTest () SMTG_OVERRIDE;
|
||||
|
||||
//---Interface---------
|
||||
OBJ_METHODS (ADelayController, EditController)
|
||||
DEFINE_INTERFACES
|
||||
DEF_INTERFACE (IDelayTestController)
|
||||
END_DEFINE_INTERFACES (EditController)
|
||||
REFCOUNT_METHODS (EditController)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,34 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/adelay/source/adelayids.h
|
||||
// Created by : Steinberg, 06/2009
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
// parameter tags
|
||||
enum {
|
||||
kDelayId = 100,
|
||||
kBypassId = 101
|
||||
};
|
||||
|
||||
// unique class ids
|
||||
static DECLARE_UID (ADelayProcessorUID, 0x0CDBB669, 0x85D548A9, 0xBFD83719, 0x09D24BB3);
|
||||
static DECLARE_UID (ADelayControllerUID, 0x038E7FA9, 0x629A4EAA, 0x8541B889, 0x18E8952C);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,226 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/adelay/source/adelayprocessor.cpp
|
||||
// Created by : Steinberg, 06/2009
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "adelayprocessor.h"
|
||||
#include "adelayids.h"
|
||||
#include "base/source/fstreamer.h"
|
||||
#include "pluginterfaces/base/ibstream.h"
|
||||
#include "pluginterfaces/vst/ivstparameterchanges.h"
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ADelayProcessor::ADelayProcessor ()
|
||||
{
|
||||
setControllerClass (FUID::fromTUID (ADelayControllerUID));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayProcessor::initialize (FUnknown* context)
|
||||
{
|
||||
tresult result = AudioEffect::initialize (context);
|
||||
if (result == kResultTrue)
|
||||
{
|
||||
addAudioInput (STR16 ("AudioInput"), SpeakerArr::kStereo);
|
||||
addAudioOutput (STR16 ("AudioOutput"), SpeakerArr::kStereo);
|
||||
mNumChannels = 2;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayProcessor::setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs, int32 numOuts)
|
||||
{
|
||||
// we only support one in and output bus and these busses must have the same number of channels
|
||||
if (numIns == 1 && numOuts == 1 && inputs[0] == outputs[0])
|
||||
{
|
||||
tresult res = AudioEffect::setBusArrangements (inputs, numIns, outputs, numOuts);
|
||||
if (res == kResultOk)
|
||||
mNumChannels = SpeakerArr::getChannelCount (outputs[0]);
|
||||
return res;
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ADelayProcessor::resetDelay ()
|
||||
{
|
||||
if (!mBuffer)
|
||||
return false;
|
||||
|
||||
size_t size = static_cast<size_t> (processSetup.sampleRate * sizeof (float) + 0.5);
|
||||
for (int32 channel = 0; channel < mNumChannels; channel++)
|
||||
{
|
||||
if (mBuffer[channel])
|
||||
memset (mBuffer[channel], 0, size);
|
||||
}
|
||||
mBufferPos = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayProcessor::setActive (TBool state)
|
||||
{
|
||||
if (mBuffer)
|
||||
{
|
||||
for (int32 channel = 0; channel < mNumChannels; channel++)
|
||||
{
|
||||
std::free (mBuffer[channel]);
|
||||
}
|
||||
std::free (mBuffer);
|
||||
mBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (state)
|
||||
{
|
||||
mBuffer = (float**)std::malloc (mNumChannels * sizeof (float*));
|
||||
if (mBuffer)
|
||||
{
|
||||
size_t size = static_cast<size_t> (processSetup.sampleRate * sizeof (float) + 0.5);
|
||||
for (int32 channel = 0; channel < mNumChannels; channel++)
|
||||
{
|
||||
mBuffer[channel] = (float*)std::malloc (size); // 1 second delay max
|
||||
}
|
||||
resetDelay ();
|
||||
}
|
||||
}
|
||||
|
||||
return AudioEffect::setActive (state);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayProcessor::setProcessing (TBool state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
resetDelay ();
|
||||
}
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayProcessor::process (ProcessData& data)
|
||||
{
|
||||
if (data.inputParameterChanges)
|
||||
{
|
||||
int32 numParamsChanged = data.inputParameterChanges->getParameterCount ();
|
||||
for (int32 index = 0; index < numParamsChanged; index++)
|
||||
{
|
||||
if (IParamValueQueue* paramQueue = data.inputParameterChanges->getParameterData (index))
|
||||
{
|
||||
ParamValue value;
|
||||
int32 sampleOffset;
|
||||
int32 numPoints = paramQueue->getPointCount ();
|
||||
switch (paramQueue->getParameterId ())
|
||||
{
|
||||
case kDelayId:
|
||||
if (paramQueue->getPoint (numPoints - 1, sampleOffset, value) ==
|
||||
kResultTrue)
|
||||
mDelay = value;
|
||||
break;
|
||||
case kBypassId:
|
||||
if (paramQueue->getPoint (numPoints - 1, sampleOffset, value) ==
|
||||
kResultTrue)
|
||||
{
|
||||
mBypass = (value > 0.5f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data.numSamples > 0)
|
||||
{
|
||||
SpeakerArrangement arr;
|
||||
getBusArrangement (kOutput, 0, arr);
|
||||
int32 numChannels = SpeakerArr::getChannelCount (arr);
|
||||
|
||||
// TODO do something in Bypass : copy input to output if necessary...
|
||||
// you could use a BypassProcessor which is used in the SyncDelay example
|
||||
|
||||
// apply delay
|
||||
// we have a minimum of 1 sample delay here
|
||||
int32 delayInSamples = std::max<int32> (1, (int32) (mDelay * processSetup.sampleRate));
|
||||
for (int32 channel = 0; channel < numChannels; channel++)
|
||||
{
|
||||
float* inputChannel = data.inputs[0].channelBuffers32[channel];
|
||||
float* outputChannel = data.outputs[0].channelBuffers32[channel];
|
||||
|
||||
int32 tempBufferPos = mBufferPos;
|
||||
for (int32 sample = 0; sample < data.numSamples; sample++)
|
||||
{
|
||||
float tempSample = inputChannel[sample];
|
||||
outputChannel[sample] = mBuffer[channel][tempBufferPos];
|
||||
mBuffer[channel][tempBufferPos] = tempSample;
|
||||
tempBufferPos++;
|
||||
if (tempBufferPos >= delayInSamples)
|
||||
tempBufferPos = 0;
|
||||
}
|
||||
}
|
||||
mBufferPos += data.numSamples;
|
||||
while (delayInSamples && mBufferPos >= delayInSamples)
|
||||
mBufferPos -= delayInSamples;
|
||||
}
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayProcessor::setState (IBStream* state)
|
||||
{
|
||||
if (!state)
|
||||
return kResultFalse;
|
||||
|
||||
// called when we load a preset, the model has to be reloaded
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
float savedDelay = 0.f;
|
||||
if (streamer.readFloat (savedDelay) == false)
|
||||
return kResultFalse;
|
||||
|
||||
int32 savedBypass = 0;
|
||||
if (streamer.readInt32 (savedBypass) == false)
|
||||
{
|
||||
// could be an old version, continue
|
||||
}
|
||||
|
||||
mDelay = static_cast<ParamValue> (savedDelay);
|
||||
mBypass = savedBypass > 0;
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayProcessor::getState (IBStream* state)
|
||||
{
|
||||
// here we need to save the model
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
streamer.writeFloat (static_cast<float> (mDelay));
|
||||
streamer.writeInt32 (mBypass ? 1 : 0);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,57 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/adelay/source/adelayprocessor.cpp
|
||||
// Created by : Steinberg, 06/2009
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "public.sdk/source/vst/vstaudioeffect.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class ADelayProcessor : public AudioEffect
|
||||
{
|
||||
public:
|
||||
ADelayProcessor ();
|
||||
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs,
|
||||
int32 numOuts) SMTG_OVERRIDE;
|
||||
|
||||
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setProcessing (TBool state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API process (ProcessData& data) SMTG_OVERRIDE;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API setState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getState (IBStream* state) SMTG_OVERRIDE;
|
||||
|
||||
static FUnknown* createInstance (void*) { return (IAudioProcessor*)new ADelayProcessor (); }
|
||||
|
||||
protected:
|
||||
bool resetDelay ();
|
||||
|
||||
ParamValue mDelay {1.};
|
||||
float** mBuffer {nullptr};
|
||||
int32 mBufferPos {0};
|
||||
int32 mNumChannels {0};
|
||||
bool mBypass {false};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,51 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/adelay/source/exampletest.cpp
|
||||
// Created by : Steinberg, 10/2010
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "adelaycontroller.h"
|
||||
#include "adelayprocessor.h"
|
||||
#include "base/source/fstring.h"
|
||||
#include "public.sdk/source/main/moduleinit.h"
|
||||
#include "public.sdk/source/vst/testsuite/vsttestsuite.h"
|
||||
#include "public.sdk/source/vst/utility/testing.h"
|
||||
#include "pluginterfaces/base/funknownimpl.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static ModuleInitializer InitTests ([] () {
|
||||
registerTest ("ExampleTest", nullptr, [] (FUnknown* context, ITestResult* testResult) {
|
||||
auto plugProvider = U::cast<ITestPlugProvider> (context);
|
||||
if (plugProvider)
|
||||
{
|
||||
auto controller = plugProvider->getController ();
|
||||
auto testController = U::cast<IDelayTestController> (controller);
|
||||
if (!controller)
|
||||
{
|
||||
testResult->addErrorMessage (String ("Unknown IEditController"));
|
||||
return false;
|
||||
}
|
||||
bool result = testController->doTest ();
|
||||
plugProvider->releasePlugIn (nullptr, controller);
|
||||
|
||||
return (result);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
}} // namespaces
|
||||
@@ -0,0 +1,60 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/adelay/source/factory.cpp
|
||||
// Created by : Steinberg, 06/2009
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "adelaycontroller.h"
|
||||
#include "adelayids.h"
|
||||
#include "adelayprocessor.h"
|
||||
#include "version.h" // for versioning
|
||||
#include "public.sdk/source/main/pluginfactory_constexpr.h"
|
||||
#include "public.sdk/source/vst/utility/testing.h"
|
||||
|
||||
#define stringPluginName "ADelay"
|
||||
|
||||
BEGIN_FACTORY_DEF (stringCompanyName, stringCompanyWeb, stringCompanyEmail, 3)
|
||||
|
||||
DEF_CLASS (Steinberg::Vst::ADelayProcessorUID, Steinberg::PClassInfo::kManyInstances,
|
||||
kVstAudioEffectClass,
|
||||
stringPluginName,
|
||||
Steinberg::Vst::kDistributable,
|
||||
"Fx|Delay",
|
||||
FULL_VERSION_STR, // Plug-in version (to be changed)
|
||||
kVstVersionString,
|
||||
Steinberg::Vst::ADelayProcessor::createInstance,
|
||||
nullptr)
|
||||
|
||||
DEF_CLASS (Steinberg::Vst::ADelayControllerUID, Steinberg::PClassInfo::kManyInstances,
|
||||
kVstComponentControllerClass,
|
||||
stringPluginName "Controller", // controller name (can be the same as the component name)
|
||||
0, // not used here
|
||||
"", // not used here
|
||||
FULL_VERSION_STR, // Plug-in version (to be changed)
|
||||
kVstVersionString,
|
||||
Steinberg::Vst::ADelayController::createInstance,
|
||||
nullptr)
|
||||
|
||||
// add Test Factory
|
||||
DEF_CLASS (Steinberg::Vst::TestFactoryUID,
|
||||
Steinberg::PClassInfo::kManyInstances,
|
||||
kTestClass,
|
||||
stringPluginName "Test Factory",
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
Steinberg::Vst::createTestFactoryInstance,
|
||||
nullptr)
|
||||
|
||||
END_FACTORY
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="4488.2" systemVersion="12E55" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3715.3"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ADelayViewController">
|
||||
<connections>
|
||||
<outlet property="slider" destination="8qe-I8-OQ4" id="zbQ-xw-Cls"/>
|
||||
<outlet property="view" destination="1" id="cvV-er-vQe"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<slider opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="8qe-I8-OQ4">
|
||||
<rect key="frame" x="146" y="370" width="777" height="29"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<connections>
|
||||
<action selector="sliderChanged:" destination="-1" eventType="valueChanged" id="dXh-wG-NCY"/>
|
||||
</connections>
|
||||
</slider>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="blackOpaque"/>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,85 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/adelay/source/interappaudio/iosEditor.h
|
||||
// Created by : Steinberg, 08/2013
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2022, 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 __iosEditor__
|
||||
#define __iosEditor__
|
||||
|
||||
#include "base/source/fobject.h"
|
||||
#include "pluginterfaces/gui/iplugview.h"
|
||||
|
||||
#if __OBJC__
|
||||
@class ADelayViewController;
|
||||
#else
|
||||
struct ADelayViewController;
|
||||
#endif
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
class EditController;
|
||||
|
||||
class ADelayEditorForIOS : public FObject, public IPlugView
|
||||
{
|
||||
public:
|
||||
ADelayEditorForIOS (EditController* editController);
|
||||
|
||||
OBJ_METHODS(ADelayEditorForIOS, FObject)
|
||||
REFCOUNT_METHODS(FObject)
|
||||
DEFINE_INTERFACES
|
||||
DEF_INTERFACE(IPlugView)
|
||||
END_DEFINE_INTERFACES(FObject)
|
||||
protected:
|
||||
tresult PLUGIN_API isPlatformTypeSupported (FIDString type) override;
|
||||
tresult PLUGIN_API attached (void* parent, FIDString type) override;
|
||||
tresult PLUGIN_API removed () override;
|
||||
tresult PLUGIN_API onWheel (float distance) override;
|
||||
tresult PLUGIN_API onKeyDown (char16 key, int16 keyCode, int16 modifiers) override;
|
||||
tresult PLUGIN_API onKeyUp (char16 key, int16 keyCode, int16 modifiers) override;
|
||||
tresult PLUGIN_API getSize (ViewRect* size) override;
|
||||
tresult PLUGIN_API onSize (ViewRect* newSize) override;
|
||||
tresult PLUGIN_API onFocus (TBool state) override;
|
||||
tresult PLUGIN_API setFrame (IPlugFrame* frame) override;
|
||||
tresult PLUGIN_API canResize () override;
|
||||
tresult PLUGIN_API checkSizeConstraint (ViewRect* rect) override;
|
||||
|
||||
void PLUGIN_API update (FUnknown* changedUnknown, int32 message) override;
|
||||
|
||||
EditController* editController;
|
||||
ADelayViewController* viewController;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // __iosEditor__
|
||||
@@ -0,0 +1,203 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/adelay/source/interappaudio/iosEditor.mm
|
||||
// Created by : Steinberg, 08/2013
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2022, 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 "iosEditor.h"
|
||||
#import "public.sdk/source/vst/vsteditcontroller.h"
|
||||
#import "adelayids.h"
|
||||
|
||||
using namespace Steinberg::Vst;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@interface ADelayViewController : UIViewController
|
||||
{
|
||||
EditController* editController;
|
||||
}
|
||||
@property (assign) IBOutlet UISlider* slider;
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@implementation ADelayViewController
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (id)initWithVstEditController:(EditController*)_editController
|
||||
{
|
||||
self = [super initWithNibName:@"ADelayIPAD" bundle:nil];
|
||||
if (self)
|
||||
{
|
||||
editController = _editController;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (void)updateSlider
|
||||
{
|
||||
[self.slider setValue:editController->getParamNormalized (kDelayId)];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (IBAction)sliderChanged:(id)sender
|
||||
{
|
||||
editController->setParamNormalized (kDelayId, self.slider.value);
|
||||
editController->performEdit(kDelayId, self.slider.value);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
ADelayEditorForIOS::ADelayEditorForIOS (EditController* editController)
|
||||
: editController (editController)
|
||||
, viewController (nil)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void PLUGIN_API ADelayEditorForIOS::update (FUnknown* changedUnknown, int32 message)
|
||||
{
|
||||
Parameter* param = FCast<Parameter> (changedUnknown);
|
||||
if (param && viewController)
|
||||
{
|
||||
[viewController updateSlider];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayEditorForIOS::isPlatformTypeSupported (FIDString type)
|
||||
{
|
||||
if (strcmp (type, kPlatformTypeUIView) == 0)
|
||||
return kResultTrue;
|
||||
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayEditorForIOS::attached (void* parent, FIDString type)
|
||||
{
|
||||
if (strcmp (type, kPlatformTypeUIView) != 0)
|
||||
return kResultFalse;
|
||||
|
||||
UIView* parentView = (__bridge UIView*)parent;
|
||||
|
||||
viewController = [[ADelayViewController alloc] initWithVstEditController:editController];
|
||||
if (viewController && viewController.view)
|
||||
{
|
||||
[parentView addSubview:viewController.view];
|
||||
|
||||
[viewController updateSlider];
|
||||
Parameter* delayParam = editController->getParameterObject (kDelayId);
|
||||
if (delayParam)
|
||||
{
|
||||
delayParam->addDependent (this);
|
||||
}
|
||||
}
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayEditorForIOS::removed ()
|
||||
{
|
||||
[viewController.view removeFromSuperview];
|
||||
Parameter* delayParam = editController->getParameterObject (kDelayId);
|
||||
if (delayParam)
|
||||
{
|
||||
delayParam->removeDependent (this);
|
||||
}
|
||||
viewController = nil;
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayEditorForIOS::onWheel (float distance)
|
||||
{
|
||||
return kNotImplemented;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayEditorForIOS::onKeyDown (char16 key, int16 keyCode, int16 modifiers)
|
||||
{
|
||||
return kNotImplemented;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayEditorForIOS::onKeyUp (char16 key, int16 keyCode, int16 modifiers)
|
||||
{
|
||||
return kNotImplemented;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayEditorForIOS::getSize (ViewRect* size)
|
||||
{
|
||||
return kNotImplemented;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayEditorForIOS::onSize (ViewRect* newSize)
|
||||
{
|
||||
return kNotImplemented;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayEditorForIOS::onFocus (TBool state)
|
||||
{
|
||||
return kNotImplemented;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayEditorForIOS::setFrame (IPlugFrame* frame)
|
||||
{
|
||||
return kNotImplemented;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayEditorForIOS::canResize ()
|
||||
{
|
||||
return kNotImplemented;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API ADelayEditorForIOS::checkSizeConstraint (ViewRect* rect)
|
||||
{
|
||||
return kNotImplemented;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,35 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/adelay/source/version.h
|
||||
// Created by : Steinberg, 06/2009
|
||||
// Description : Example of handle the versioning and copyright info of adelay plugin
|
||||
// used for the resources (RC file for example)
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/fplatform.h"
|
||||
|
||||
// Plain project version file generated by cmake
|
||||
#include "projectversion.h"
|
||||
|
||||
#define stringOriginalFilename "adelay.vst3"
|
||||
#if SMTG_PLATFORM_64
|
||||
#define stringFileDescription "ADelay VST3-SDK (64Bit)"
|
||||
#else
|
||||
#define stringFileDescription "ADelay VST3-SDK"
|
||||
#endif
|
||||
#define stringCompanyWeb "http://www.steinberg.net"
|
||||
#define stringCompanyEmail "mailto:info@steinberg.de"
|
||||
#define stringCompanyName "Steinberg Media Technologies"
|
||||
#define stringLegalCopyright "© 2025 Steinberg Media Technologies"
|
||||
#define stringLegalTrademarks "VST is a trademark of Steinberg Media Technologies GmbH"
|
||||
@@ -0,0 +1,192 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.25.0)
|
||||
|
||||
project(smtg-vst3-again
|
||||
VERSION ${vstsdk_VERSION}.0
|
||||
DESCRIPTION "Steinberg VST 3 AGain example"
|
||||
)
|
||||
|
||||
if(NOT SMTG_ENABLE_VSTGUI_SUPPORT)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(again_sources
|
||||
source/again.cpp
|
||||
source/again.h
|
||||
source/againcids.h
|
||||
source/againcontroller.cpp
|
||||
source/againcontroller.h
|
||||
source/againentry.cpp
|
||||
source/againparamids.h
|
||||
source/againprocess.h
|
||||
source/againsidechain.cpp
|
||||
source/againsidechain.h
|
||||
source/againuimessagecontroller.h
|
||||
source/version.h
|
||||
resource/again.uidesc
|
||||
)
|
||||
|
||||
set(again_simple_sources
|
||||
${SDK_ROOT}/public.sdk/source/vst/vstsinglecomponenteffect.cpp
|
||||
${SDK_ROOT}/public.sdk/source/vst/vstsinglecomponenteffect.h
|
||||
source/againparamids.h
|
||||
source/againsimple.cpp
|
||||
source/againsimple.h
|
||||
source/version.h
|
||||
)
|
||||
|
||||
set(target again)
|
||||
|
||||
smtg_add_vst3plugin(${target} ${again_sources})
|
||||
smtg_target_configure_version_file(${target})
|
||||
|
||||
#smtg_add_vst3plugin(${target} PACKAGE_NAME "A Gain" SOURCES_LIST ${again_sources})
|
||||
set_target_properties(${target}
|
||||
PROPERTIES
|
||||
${SDK_IDE_PLUGIN_EXAMPLES_FOLDER}
|
||||
)
|
||||
|
||||
target_compile_features(${target}
|
||||
PUBLIC
|
||||
cxx_std_17
|
||||
)
|
||||
|
||||
target_link_libraries(${target}
|
||||
PRIVATE
|
||||
sdk
|
||||
vstgui_support
|
||||
)
|
||||
smtg_target_add_plugin_resources(${target}
|
||||
RESOURCES
|
||||
resource/again.uidesc
|
||||
resource/background.png
|
||||
resource/slider_background.png
|
||||
resource/slider_handle.png
|
||||
resource/slider_handle_2.0x.png
|
||||
resource/vu_on.png
|
||||
resource/vu_off.png
|
||||
)
|
||||
|
||||
smtg_target_add_plugin_snapshots (${target}
|
||||
RESOURCES
|
||||
resource/84E8DE5F92554F5396FAE4133C935A18_snapshot.png
|
||||
resource/84E8DE5F92554F5396FAE4133C935A18_snapshot_2.0x.png
|
||||
resource/41347FD6FED64094AFBB12B7DBA1D441_snapshot.png
|
||||
resource/41347FD6FED64094AFBB12B7DBA1D441_snapshot_2.0x.png
|
||||
)
|
||||
|
||||
if(SMTG_MAC)
|
||||
smtg_target_set_bundle(${target}
|
||||
BUNDLE_IDENTIFIER "com.steinberg.vst3.${target}"
|
||||
COMPANY_NAME "Steinberg Media Technologies"
|
||||
)
|
||||
elseif(SMTG_WIN)
|
||||
target_sources(${target}
|
||||
PRIVATE
|
||||
resource/again.rc
|
||||
)
|
||||
endif(SMTG_MAC)
|
||||
|
||||
# Add an AUv2 target
|
||||
if (SMTG_MAC AND XCODE AND SMTG_ENABLE_AUV2_BUILDS)
|
||||
include(SMTG_AddVST3AuV2)
|
||||
smtg_target_add_auv2(again-au
|
||||
BUNDLE_NAME again
|
||||
BUNDLE_IDENTIFIER com.steinberg.vst3plugin.again.audiounit
|
||||
INFO_PLIST_TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/resource/au-info.plist
|
||||
VST3_PLUGIN_TARGET again)
|
||||
endif(SMTG_MAC AND XCODE AND SMTG_ENABLE_AUV2_BUILDS)
|
||||
|
||||
if(SMTG_MAC AND XCODE AND SMTG_ENABLE_IOS_TARGETS)
|
||||
set(target again_ios)
|
||||
smtg_add_ios_vst3plugin(${target} "${SMTG_CODE_SIGN_IDENTITY_IOS}" "${target}" "${again_sources}")
|
||||
smtg_target_configure_version_file(${target})
|
||||
set_target_properties(${target}
|
||||
PROPERTIES
|
||||
${SDK_IDE_PLUGIN_EXAMPLES_FOLDER}
|
||||
)
|
||||
target_include_directories(${target}
|
||||
PUBLIC
|
||||
${SMTG_VSTGUI_SOURCE_DIR}
|
||||
)
|
||||
target_link_libraries(${target}
|
||||
PRIVATE
|
||||
base_ios
|
||||
sdk_ios
|
||||
"-framework UIKit"
|
||||
"-framework CoreGraphics"
|
||||
"-framework QuartzCore"
|
||||
"-framework CoreText"
|
||||
"-framework Accelerate"
|
||||
"-framework ImageIO"
|
||||
"-framework MobileCoreServices"
|
||||
)
|
||||
|
||||
smtg_target_add_plugin_resources(${target}
|
||||
RESOURCES
|
||||
resource/again.uidesc
|
||||
resource/background.png
|
||||
resource/slider_background.png
|
||||
resource/slider_handle.png
|
||||
resource/slider_handle_2.0x.png
|
||||
resource/vu_on.png
|
||||
resource/vu_off.png
|
||||
)
|
||||
|
||||
smtg_target_set_bundle(${target}
|
||||
BUNDLE_IDENTIFIER "com.steinberg.vst3.again"
|
||||
COMPANY_NAME "Steinberg Media Technologies"
|
||||
)
|
||||
target_sources(${target}
|
||||
PRIVATE
|
||||
${SMTG_VSTGUI_SOURCE_DIR}/vstgui/vstgui_uidescription.cpp
|
||||
${SMTG_VSTGUI_SOURCE_DIR}/vstgui/vstgui_ios.mm
|
||||
${SMTG_VSTGUI_SOURCE_DIR}/vstgui/plugin-bindings/vst3editor.cpp
|
||||
${SDK_ROOT}/public.sdk/source/vst/vstguieditor.cpp
|
||||
)
|
||||
target_compile_features(${target}
|
||||
PUBLIC
|
||||
cxx_std_17
|
||||
)
|
||||
endif(SMTG_MAC AND XCODE AND SMTG_ENABLE_IOS_TARGETS)
|
||||
|
||||
set(targetsimple again-simple)
|
||||
smtg_add_vst3plugin(${targetsimple} ${again_simple_sources})
|
||||
smtg_target_configure_version_file(${targetsimple})
|
||||
set_target_properties(${targetsimple}
|
||||
PROPERTIES
|
||||
${SDK_IDE_PLUGIN_EXAMPLES_FOLDER})
|
||||
target_link_libraries(${targetsimple}
|
||||
PUBLIC
|
||||
sdk
|
||||
vstgui_support
|
||||
)
|
||||
|
||||
smtg_target_add_plugin_resources(${targetsimple}
|
||||
RESOURCES
|
||||
resource/again.uidesc
|
||||
resource/background.png
|
||||
resource/slider_background.png
|
||||
resource/slider_handle.png
|
||||
resource/slider_handle_2.0x.png
|
||||
resource/vu_on.png
|
||||
resource/vu_off.png
|
||||
)
|
||||
|
||||
target_compile_features(${targetsimple}
|
||||
PUBLIC
|
||||
cxx_std_17
|
||||
)
|
||||
|
||||
if(SMTG_MAC)
|
||||
smtg_target_set_bundle(${targetsimple}
|
||||
BUNDLE_IDENTIFIER "com.steinberg.vst3.again-simple"
|
||||
COMPANY_NAME "Steinberg Media Technologies"
|
||||
)
|
||||
elseif(SMTG_WIN)
|
||||
target_sources(${targetsimple}
|
||||
PRIVATE
|
||||
resource/again.rc
|
||||
)
|
||||
endif(SMTG_MAC)
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# AGain VST 3
|
||||
|
||||
## Introduction
|
||||
|
||||
AGain VST 3 is the most simple FX plug-in with just one parameter for gain control.
|
||||
|
||||
There are several targets to show how the AGain plug-in can be built for different use cases.
|
||||
|
||||
* AGain VST 3
|
||||
* AGain VST 3 Simple (SingleComponent approach)
|
||||
* AGain AU (Audio Unit)
|
||||
* AGain iOS
|
||||
|
||||
> See also: [Online Documentation](https://steinbergmedia.github.io/vst3_dev_portal/pages/What+is+the+VST+3+SDK/Plug-in+Examples.html#again).
|
||||
|
||||
## Getting Started
|
||||
|
||||
This plug-in is part of the VST 3 SDK package. It is created with the VST 3 SDK root project.
|
||||
|
||||
> See the top-level README of the VST 3 SDK: https://github.com/steinbergmedia/vst3sdk.git
|
||||
|
||||
## Getting Help
|
||||
|
||||
* Read through the SDK documentation on the **[VST 3 Developer Portal](https://steinbergmedia.github.io/vst3_dev_portal/pages/index.html)**
|
||||
* Ask some real people in the official **[VST 3 Developer Forum](https://forums.steinberg.net/c/developer/103)**
|
||||
@@ -0,0 +1,28 @@
|
||||
<?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>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2018 Steinberg Media Technologies. All rights reserved.</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</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>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 40 KiB |
@@ -0,0 +1,45 @@
|
||||
#include <windows.h>
|
||||
#include "../source/version.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Version
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION MAJOR_VERSION_INT,SUB_VERSION_INT,RELEASE_NUMBER_INT,BUILD_NUMBER_INT
|
||||
PRODUCTVERSION MAJOR_VERSION_INT,SUB_VERSION_INT,RELEASE_NUMBER_INT,BUILD_NUMBER_INT
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040004e4"
|
||||
BEGIN
|
||||
VALUE "FileVersion", FULL_VERSION_STR
|
||||
VALUE "ProductVersion", FULL_VERSION_STR
|
||||
VALUE "OriginalFilename", stringOriginalFilename
|
||||
VALUE "FileDescription", stringFileDescription
|
||||
VALUE "InternalName", stringFileDescription
|
||||
VALUE "ProductName", stringFileDescription
|
||||
VALUE "CompanyName", stringCompanyName
|
||||
VALUE "LegalCopyright", stringLegalCopyright
|
||||
VALUE "LegalTrademarks", stringLegalTrademarks
|
||||
//VALUE "PrivateBuild", " \0"
|
||||
//VALUE "SpecialBuild", " \0"
|
||||
//VALUE "Comments", " \0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x400, 1252
|
||||
END
|
||||
END
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<vstgui-ui-description version="1">
|
||||
<fonts>
|
||||
</fonts>
|
||||
<colors>
|
||||
<color name="Focus" rgba="#279bffff"/>
|
||||
<color name="Title Background" rgba="#39393944"/>
|
||||
</colors>
|
||||
<template background-color="~ BlackCColor" background-color-draw-style="filled and stroked" bitmap="background" class="CViewContainer" maxSize="350, 120" minSize="350, 120" mouse-enabled="true" name="view" opacity="1" origin="0, 0" size="350, 120" transparent="false">
|
||||
<view back-color="Title Background" background-offset="0, 0" class="CTextLabel" default-value="0.5" font="~ NormalFontVeryBig" font-antialias="true" font-color="~ WhiteCColor" frame-color="Title Background" frame-width="1" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="10, 10" round-rect-radius="10" shadow-color="~ RedCColor" size="310, 28" style-3D-in="false" style-3D-out="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="true" style-shadow-text="false" text-alignment="center" text-inset="0, 0" text-rotation="0" title="VST3 AGain" transparent="false" value-precision="2" wheel-inc-value="0.1"/>
|
||||
<view background-color="~ BlackCColor" background-color-draw-style="filled and stroked" class="CViewContainer" mouse-enabled="true" opacity="1" origin="0, 45" size="330, 38" sub-controller="MessageController" transparent="true">
|
||||
<view back-color="~ BlackCColor" background-offset="0, 0" class="CTextLabel" default-value="0.5" font="~ NormalFont" font-antialias="true" font-color="~ WhiteCColor" frame-color="~ BlackCColor" frame-width="1" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="10, 10" round-rect-radius="6" shadow-color="~ BlackCColor" size="80, 18" style-3D-in="false" style-3D-out="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="false" style-shadow-text="true" text-alignment="left" text-inset="5, 0" text-rotation="0" title="IMessage:" transparent="true" value-precision="2" wheel-inc-value="0.1"/>
|
||||
<view back-color="~ BlackCColor" background-offset="0, 0" class="CTextEdit" default-value="0.5" font="~ NormalFontSmall" font-antialias="true" font-color="~ WhiteCColor" frame-color="~ GreyCColor" frame-width="1" immediate-text-change="false" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="90, 10" round-rect-radius="6" shadow-color="~ RedCColor" size="130, 18" style-3D-in="false" style-3D-out="false" style-doubleclick="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="false" style-shadow-text="false" text-alignment="center" text-inset="0, 0" text-rotation="0" transparent="false" value-precision="2" wheel-inc-value="0.1"/>
|
||||
<view background-offset="0, 0" class="CTextButton" control-tag="UI::SendMessage" default-value="0.5" font="~ SystemFont" frame-color="~ BlackCColor" frame-color-highlighted="~ BlackCColor" frame-width="1" gradient="Default TextButton Gradient" gradient-highlighted="Default TextButton Gradient Highlighted" icon-position="left" icon-text-margin="0" kick-style="false" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="230, 10" round-radius="6" size="90, 18" text-alignment="center" text-color="~ BlackCColor" text-color-highlighted="~ WhiteCColor" title="Send!" transparent="false" wheel-inc-value="0.1"/>
|
||||
</view>
|
||||
<view back-color="~ BlackCColor" background-offset="0, 0" class="CTextLabel" default-value="0.5" font="~ NormalFont" font-antialias="true" font-color="~ WhiteCColor" frame-color="~ BlackCColor" frame-width="1" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="10, 90" round-rect-radius="6" shadow-color="~ BlackCColor" size="80, 18" style-3D-in="false" style-3D-out="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="false" style-shadow-text="true" text-alignment="left" text-inset="5, 0" text-rotation="0" title="Gain:" transparent="true" value-precision="2" wheel-inc-value="0.1"/>
|
||||
<view background-offset="0, 0" bitmap="slider_background" bitmap-offset="0, 0" class="CSlider" control-tag="Unit1::Gain" default-value="0.5" draw-back="false" draw-back-color="~ WhiteCColor" draw-frame="false" draw-frame-color="~ WhiteCColor" draw-value="false" draw-value-color="~ WhiteCColor" draw-value-from-center="false" draw-value-inverted="false" handle-bitmap="slider_handle" handle-offset="0, 2" max-value="1" min-value="0" mode="free click" mouse-enabled="true" opacity="1" orientation="horizontal" origin="90, 90" reverse-orientation="false" size="130, 18" transparent="false" transparent-handle="true" wheel-inc-value="0.1" zoom-factor="10"/>
|
||||
<view back-color="~ BlackCColor" background-offset="0, 0" class="CTextEdit" control-tag="Unit1::Gain" default-value="0.5" font="~ NormalFontSmall" font-antialias="true" font-color="~ WhiteCColor" frame-color="~ GreyCColor" frame-width="1" immediate-text-change="false" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="230, 90" round-rect-radius="6" shadow-color="~ BlackCColor" size="90, 18" style-3D-in="false" style-3D-out="false" style-doubleclick="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="true" style-shadow-text="false" text-alignment="center" text-inset="5, 0" text-rotation="0" title="0.00" transparent="false" value-precision="2" wheel-inc-value="0.1"/>
|
||||
<view background-offset="0, 0" bitmap="vu_on" class="CVuMeter" control-tag="Root::VuPPM" decrease-step-value="0.1" default-value="0" max-value="1" min-value="0" mouse-enabled="false" num-led="100" off-bitmap="vu_off" opacity="1" orientation="vertical" origin="330, 7" size="12, 105" transparent="false" wheel-inc-value="0.1"/>
|
||||
</template>
|
||||
<variables/>
|
||||
<custom>
|
||||
<attributes color="Focus" enabled="true" name="FocusDrawing" width="1"/>
|
||||
<attributes Size="5, 5" name="UIGridController"/>
|
||||
<attributes SelectedTemplate="view" name="UITemplateController"/>
|
||||
<attributes EditViewScale="1" EditorSize="0, 0, 882, 716" SplitViewSize_0_0="0.6402877697841726778449356061173602938652" SplitViewSize_0_1="0.3309352517985611474848894886235939338803" SplitViewSize_1_0="0.506474820143884896239683257590513676405" SplitViewSize_1_1="0.486330935251798546214985208280268125236" SplitViewSize_2_0="0.636054421768707523021646466077072545886" SplitViewSize_2_1="0.3582766439909297329080573035753332078457" TabSwitchValue="0" Version="1" name="UIEditController"/>
|
||||
<attributes name="UIAttributesController"/>
|
||||
<attributes SelectedRow="23" name="UIViewCreatorDataSource"/>
|
||||
<attributes SelectedRow="4" name="UIBitmapsDataSource"/>
|
||||
<attributes Path="/Volumes/git_brauhaus/VST3Linux/public.sdk/samples/vst/again/resource/again.uidesc" name="VST3Editor"/>
|
||||
<attributes SelectedRow="2" name="UITagsDataSource"/>
|
||||
<attributes SelectedRow="0" name="UIColorsDataSource"/>
|
||||
<attributes SelectedRow="-1" name="UIGradientsDataSource"/>
|
||||
<attributes SelectedRow="-1" name="UIFontsDataSource"/>
|
||||
</custom>
|
||||
<bitmaps>
|
||||
<bitmap name="background" path="background.png"/>
|
||||
<bitmap name="slider_background" path="slider_background.png"/>
|
||||
<bitmap name="slider_handle" path="slider_handle.png"/>
|
||||
<bitmap name="slider_handle#2x" path="slider_handle_2.0x.png" scale-factor="2"/>
|
||||
<bitmap name="vu_off" path="vu_off.png"/>
|
||||
<bitmap name="vu_on" path="vu_on.png"/>
|
||||
</bitmaps>
|
||||
<control-tags>
|
||||
<control-tag name="Root::Bypass" tag="2"/>
|
||||
<control-tag name="Root::VuPPM" tag="1"/>
|
||||
<control-tag name="UI::SendMessage" tag="1000"/>
|
||||
<control-tag name="Unit1::Gain" tag="0"/>
|
||||
</control-tags>
|
||||
<gradients>
|
||||
<gradient name="Default TextButton Gradient">
|
||||
<color-stop rgba="#dcdcdcff" start="0"/>
|
||||
<color-stop rgba="#b4b4b4ff" start="1"/>
|
||||
</gradient>
|
||||
<gradient name="Default TextButton Gradient Highlighted">
|
||||
<color-stop rgba="#b4b4b4ff" start="0"/>
|
||||
<color-stop rgba="#646464ff" start="1"/>
|
||||
</gradient>
|
||||
</gradients>
|
||||
</vstgui-ui-description>
|
||||
@@ -0,0 +1,62 @@
|
||||
<?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>$(PRODUCT_BUNDLE_IDENTIFIER)</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>AudioComponents</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>factoryFunction</key>
|
||||
<string>AUWrapperFactory</string>
|
||||
<key>description</key>
|
||||
<string>AGain</string>
|
||||
<key>manufacturer</key>
|
||||
<string>Stgb</string>
|
||||
<key>name</key>
|
||||
<string>Steinberg: AGain</string>
|
||||
<key>subtype</key>
|
||||
<string>gain</string>
|
||||
<key>type</key>
|
||||
<string>aufx</string>
|
||||
<key>version</key>
|
||||
<integer>0xFFFFFFFF</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<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>
|
||||
</dict>
|
||||
</plist>
|
||||
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 724 B |
|
After Width: | Height: | Size: 540 B |
|
After Width: | Height: | Size: 918 B |
@@ -0,0 +1,471 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/again.cpp
|
||||
// Created by : Steinberg, 04/2005
|
||||
// Description : AGain Example for VST SDK 3
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "again.h"
|
||||
#include "againcids.h" // for class ids
|
||||
#include "againparamids.h"
|
||||
#include "againprocess.h"
|
||||
|
||||
#include "public.sdk/source/vst/vstaudioprocessoralgo.h"
|
||||
#include "public.sdk/source/vst/vsthelpers.h"
|
||||
|
||||
#include "pluginterfaces/base/ibstream.h"
|
||||
#include "pluginterfaces/vst/ivstevents.h"
|
||||
#include "pluginterfaces/vst/ivstparameterchanges.h"
|
||||
#include "pluginterfaces/vst/vstpresetkeys.h" // for use of IStreamAttributes
|
||||
|
||||
#include "base/source/fstreamer.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// AGain Implementation
|
||||
//------------------------------------------------------------------------
|
||||
AGain::AGain ()
|
||||
{
|
||||
// register its editor class (the same than used in againentry.cpp)
|
||||
setControllerClass (AGainControllerUID);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
AGain::~AGain ()
|
||||
{
|
||||
// nothing to do here yet..
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGain::initialize (FUnknown* context)
|
||||
{
|
||||
//---always initialize the parent-------
|
||||
tresult result = AudioEffect::initialize (context);
|
||||
// if everything Ok, continue
|
||||
if (result != kResultOk)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//---create Audio In/Out busses------
|
||||
// we want a stereo Input and a Stereo Output
|
||||
addAudioInput (STR16 ("Stereo In"), SpeakerArr::kStereo);
|
||||
addAudioOutput (STR16 ("Stereo Out"), SpeakerArr::kStereo);
|
||||
|
||||
//---create Event In/Out busses (1 bus with only 1 channel)------
|
||||
addEventInput (STR16 ("Event In"), 1);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGain::terminate ()
|
||||
{
|
||||
// nothing to do here yet...except calling our parent terminate
|
||||
return AudioEffect::terminate ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGain::setActive (TBool state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
sendTextMessage ("AGain::setActive (true)");
|
||||
}
|
||||
else
|
||||
{
|
||||
sendTextMessage ("AGain::setActive (false)");
|
||||
}
|
||||
|
||||
// reset the VuMeter value
|
||||
fVuPPMOld = 0.f;
|
||||
|
||||
// call our parent setActive
|
||||
return AudioEffect::setActive (state);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGain::process (ProcessData& data)
|
||||
{
|
||||
// finally the process function
|
||||
// In this example there are 4 steps:
|
||||
// 1) Read inputs parameters coming from host (in order to adapt our model values)
|
||||
// 2) Read inputs events coming from host (we apply a gain reduction depending of the velocity
|
||||
// of pressed key) 3) Process the gain of the input buffer to the output buffer 4) Write the new
|
||||
// VUmeter value to the output Parameters queue
|
||||
|
||||
//---1) Read inputs parameter changes-----------
|
||||
if (IParameterChanges* paramChanges = data.inputParameterChanges)
|
||||
{
|
||||
int32 numParamsChanged = paramChanges->getParameterCount ();
|
||||
// for each parameter which are some changes in this audio block:
|
||||
for (int32 i = 0; i < numParamsChanged; i++)
|
||||
{
|
||||
if (IParamValueQueue* paramQueue = paramChanges->getParameterData (i))
|
||||
{
|
||||
ParamValue value;
|
||||
int32 sampleOffset;
|
||||
int32 numPoints = paramQueue->getPointCount ();
|
||||
switch (paramQueue->getParameterId ())
|
||||
{
|
||||
case kGainId:
|
||||
// we use in this example only the last point of the queue.
|
||||
// in some wanted case for specific kind of parameter it makes sense to
|
||||
// retrieve all points and process the whole audio block in small blocks.
|
||||
if (paramQueue->getPoint (numPoints - 1, sampleOffset, value) ==
|
||||
kResultTrue)
|
||||
{
|
||||
fGain = (float)value;
|
||||
}
|
||||
break;
|
||||
|
||||
case kBypassId:
|
||||
if (paramQueue->getPoint (numPoints - 1, sampleOffset, value) ==
|
||||
kResultTrue)
|
||||
{
|
||||
bBypass = (value > 0.5f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---2) Read input events-------------
|
||||
if (IEventList* eventList = data.inputEvents)
|
||||
{
|
||||
int32 numEvent = eventList->getEventCount ();
|
||||
for (int32 i = 0; i < numEvent; i++)
|
||||
{
|
||||
Event event {};
|
||||
if (eventList->getEvent (i, event) == kResultOk)
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
//--- -------------------
|
||||
case Event::kNoteOnEvent:
|
||||
// use the velocity as gain modifier
|
||||
fGainReduction = event.noteOn.velocity;
|
||||
break;
|
||||
|
||||
//--- -------------------
|
||||
case Event::kNoteOffEvent:
|
||||
// noteOff reset the reduction
|
||||
fGainReduction = 0.f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--- ----------------------------------
|
||||
//---3) Process Audio---------------------
|
||||
//--- ----------------------------------
|
||||
if (data.numInputs == 0 || data.numOutputs == 0)
|
||||
{
|
||||
// nothing to do
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
// (simplification) we suppose in this example that we have the same input channel count than
|
||||
// the output
|
||||
int32 numChannels = data.inputs[0].numChannels;
|
||||
|
||||
//---get audio buffers----------------
|
||||
uint32 sampleFramesSize = getSampleFramesSizeInBytes (processSetup, data.numSamples);
|
||||
void** in = getChannelBuffersPointer (processSetup, data.inputs[0]);
|
||||
void** out = getChannelBuffersPointer (processSetup, data.outputs[0]);
|
||||
float fVuPPM = 0.f;
|
||||
|
||||
//---check if silence---------------
|
||||
// check if all channel are silent then process silent
|
||||
if (data.inputs[0].silenceFlags == getChannelMask (data.inputs[0].numChannels))
|
||||
{
|
||||
// mark output silence too (it will help the host to propagate the silence)
|
||||
data.outputs[0].silenceFlags = data.inputs[0].silenceFlags;
|
||||
|
||||
// the plug-in has to be sure that if it sets the flags silence that the output buffer are
|
||||
// clear
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
// do not need to be cleared if the buffers are the same (in this case input buffer are
|
||||
// already cleared by the host)
|
||||
if (in[i] != out[i])
|
||||
{
|
||||
memset (out[i], 0, sampleFramesSize);
|
||||
}
|
||||
}
|
||||
fVuPPM = 0.f;
|
||||
}
|
||||
else // we have to process (no silence)
|
||||
{
|
||||
// mark our outputs has not silent
|
||||
data.outputs[0].silenceFlags = 0;
|
||||
|
||||
//---in bypass mode outputs should be like inputs-----
|
||||
if (bBypass)
|
||||
{
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
// do not need to be copied if the buffers are the same
|
||||
if (in[i] != out[i])
|
||||
{
|
||||
memcpy (out[i], in[i], sampleFramesSize);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.symbolicSampleSize == kSample32)
|
||||
fVuPPM = processVuPPM<Sample32> ((Sample32**)in, numChannels, data.numSamples);
|
||||
else
|
||||
fVuPPM = static_cast<float> (
|
||||
processVuPPM<Sample64> ((Sample64**)(in), numChannels, data.numSamples));
|
||||
}
|
||||
else
|
||||
{
|
||||
//---apply gain factor----------
|
||||
float gain = (fGain - fGainReduction);
|
||||
if (bHalfGain)
|
||||
{
|
||||
gain = gain * 0.5f;
|
||||
}
|
||||
|
||||
// if the applied gain is nearly zero, we could say that the outputs are zeroed and we set
|
||||
// the silence flags.
|
||||
if (gain < 0.0000001)
|
||||
{
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
memset (out[i], 0, sampleFramesSize);
|
||||
}
|
||||
// this will set to 1 all channels
|
||||
data.outputs[0].silenceFlags = getChannelMask (data.outputs[0].numChannels);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data.symbolicSampleSize == kSample32)
|
||||
fVuPPM = processAudio<Sample32> ((Sample32**)in, (Sample32**)out, numChannels,
|
||||
data.numSamples, gain);
|
||||
else
|
||||
fVuPPM = static_cast<float> (processAudio<Sample64> (
|
||||
(Sample64**)in, (Sample64**)out, numChannels, data.numSamples, gain));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---3) Write outputs parameter changes-----------
|
||||
IParameterChanges* outParamChanges = data.outputParameterChanges;
|
||||
// a new value of VuMeter will be send to the host
|
||||
// (the host will send it back in sync to our controller for updating our editor)
|
||||
if (outParamChanges && fVuPPMOld != fVuPPM)
|
||||
{
|
||||
int32 index = 0;
|
||||
IParamValueQueue* paramQueue = outParamChanges->addParameterData (kVuPPMId, index);
|
||||
if (paramQueue)
|
||||
{
|
||||
int32 index2 = 0;
|
||||
paramQueue->addPoint (0, fVuPPM, index2);
|
||||
}
|
||||
}
|
||||
fVuPPMOld = fVuPPM;
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult AGain::receiveText (const char* text)
|
||||
{
|
||||
// received from Controller
|
||||
fprintf (stderr, "[AGain] received: ");
|
||||
fprintf (stderr, "%s", text);
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
bHalfGain = !bHalfGain;
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGain::setState (IBStream* state)
|
||||
{
|
||||
// called when we load a preset, the model has to be reloaded
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
float savedGain = 0.f;
|
||||
if (streamer.readFloat (savedGain) == false)
|
||||
return kResultFalse;
|
||||
|
||||
float savedGainReduction = 0.f;
|
||||
if (streamer.readFloat (savedGainReduction) == false)
|
||||
return kResultFalse;
|
||||
|
||||
int32 savedBypass = 0;
|
||||
if (streamer.readInt32 (savedBypass) == false)
|
||||
return kResultFalse;
|
||||
|
||||
fGain = savedGain;
|
||||
fGainReduction = savedGainReduction;
|
||||
bBypass = savedBypass > 0;
|
||||
|
||||
if (Helpers::isProjectState (state) == kResultTrue)
|
||||
{
|
||||
// we are in project loading context...
|
||||
|
||||
// Example of using the IStreamAttributes interface
|
||||
if (auto stream = U::cast<IStreamAttributes> (state))
|
||||
{
|
||||
if (IAttributeList* list = stream->getAttributes ())
|
||||
{
|
||||
// get the full file path of this state
|
||||
TChar fullPath[1024];
|
||||
memset (fullPath, 0, 1024 * sizeof (TChar));
|
||||
if (list->getString (PresetAttributes::kFilePathStringType, fullPath,
|
||||
1024 * sizeof (TChar)) == kResultTrue)
|
||||
{
|
||||
// here we have the full path ...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGain::getState (IBStream* state)
|
||||
{
|
||||
// here we need to save the model
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
streamer.writeFloat (fGain);
|
||||
streamer.writeFloat (fGainReduction);
|
||||
streamer.writeInt32 (bBypass ? 1 : 0);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGain::setupProcessing (ProcessSetup& newSetup)
|
||||
{
|
||||
// called before the process call, always in a disable state (not active)
|
||||
|
||||
// here we keep a trace of the processing mode (offline,...) for example.
|
||||
currentProcessMode = newSetup.processMode;
|
||||
|
||||
return AudioEffect::setupProcessing (newSetup);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGain::setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs, int32 numOuts)
|
||||
{
|
||||
if (numIns == 1 && numOuts == 1)
|
||||
{
|
||||
// the host wants Mono => Mono (or 1 channel -> 1 channel)
|
||||
if (SpeakerArr::getChannelCount (inputs[0]) == 1 &&
|
||||
SpeakerArr::getChannelCount (outputs[0]) == 1)
|
||||
{
|
||||
auto* bus = FCast<AudioBus> (audioInputs.at (0));
|
||||
if (bus)
|
||||
{
|
||||
// check if we are Mono => Mono, if not we need to recreate the busses
|
||||
if (bus->getArrangement () != inputs[0])
|
||||
{
|
||||
getAudioInput (0)->setArrangement (inputs[0]);
|
||||
getAudioInput (0)->setName (STR16 ("Mono In"));
|
||||
getAudioOutput (0)->setArrangement (outputs[0]);
|
||||
getAudioOutput (0)->setName (STR16 ("Mono Out"));
|
||||
}
|
||||
return kResultOk;
|
||||
}
|
||||
}
|
||||
// the host wants something else than Mono => Mono,
|
||||
// in this case we are always Stereo => Stereo
|
||||
else
|
||||
{
|
||||
auto* bus = FCast<AudioBus> (audioInputs.at (0));
|
||||
if (bus)
|
||||
{
|
||||
tresult result = kResultFalse;
|
||||
|
||||
// the host wants 2->2 (could be LsRs -> LsRs)
|
||||
if (SpeakerArr::getChannelCount (inputs[0]) == 2 &&
|
||||
SpeakerArr::getChannelCount (outputs[0]) == 2)
|
||||
{
|
||||
getAudioInput (0)->setArrangement (inputs[0]);
|
||||
getAudioInput (0)->setName (STR16 ("Stereo In"));
|
||||
getAudioOutput (0)->setArrangement (outputs[0]);
|
||||
getAudioOutput (0)->setName (STR16 ("Stereo Out"));
|
||||
result = kResultTrue;
|
||||
}
|
||||
// the host want something different than 1->1 or 2->2 : in this case we want stereo
|
||||
else if (bus->getArrangement () != SpeakerArr::kStereo)
|
||||
{
|
||||
getAudioInput (0)->setArrangement (SpeakerArr::kStereo);
|
||||
getAudioInput (0)->setName (STR16 ("Stereo In"));
|
||||
getAudioOutput (0)->setArrangement (SpeakerArr::kStereo);
|
||||
getAudioOutput (0)->setName (STR16 ("Stereo Out"));
|
||||
result = kResultFalse;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGain::canProcessSampleSize (int32 symbolicSampleSize)
|
||||
{
|
||||
if (symbolicSampleSize == kSample32)
|
||||
return kResultTrue;
|
||||
|
||||
// we support double processing
|
||||
if (symbolicSampleSize == kSample64)
|
||||
return kResultTrue;
|
||||
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGain::notify (IMessage* message)
|
||||
{
|
||||
if (!message)
|
||||
return kInvalidArgument;
|
||||
|
||||
if (strcmp (message->getMessageID (), "BinaryMessage") == 0)
|
||||
{
|
||||
const void* data;
|
||||
uint32 size;
|
||||
if (message->getAttributes ()->getBinary ("MyData", data, size) == kResultOk)
|
||||
{
|
||||
// we are in UI thread
|
||||
// size should be 100
|
||||
if (size == 100 && ((char*)data)[1] == 1) // yeah...
|
||||
{
|
||||
fprintf (stderr, "[AGain] received the binary message!\n");
|
||||
}
|
||||
return kResultOk;
|
||||
}
|
||||
}
|
||||
|
||||
return AudioEffect::notify (message);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,101 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/again.h
|
||||
// Created by : Steinberg, 04/2005
|
||||
// Description : AGain Example for VST SDK 3.0
|
||||
// Simple gain plug-in with gain, bypass values and 1 midi input
|
||||
// and the same plug-in with sidechain
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "public.sdk/source/vst/vstaudioeffect.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// AGain: directly derived from the helper class AudioEffect
|
||||
//------------------------------------------------------------------------
|
||||
class AGain : public AudioEffect
|
||||
{
|
||||
public:
|
||||
AGain ();
|
||||
~AGain () override;
|
||||
|
||||
//--- ---------------------------------------------------------------------
|
||||
// create function required for plug-in factory,
|
||||
// it will be called to create new instances of this plug-in
|
||||
//--- ---------------------------------------------------------------------
|
||||
static FUnknown* createInstance (void* /*context*/) { return (IAudioProcessor*)new AGain; }
|
||||
|
||||
//--- ---------------------------------------------------------------------
|
||||
// AudioEffect overrides:
|
||||
//--- ---------------------------------------------------------------------
|
||||
/** Called at first after constructor */
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
|
||||
/** Called at the end before destructor */
|
||||
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
|
||||
|
||||
/** Switch the plug-in on/off */
|
||||
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
|
||||
|
||||
/** Here we go...the process call */
|
||||
tresult PLUGIN_API process (ProcessData& data) SMTG_OVERRIDE;
|
||||
|
||||
/** Test of a communication channel between controller and component */
|
||||
tresult receiveText (const char* text) SMTG_OVERRIDE;
|
||||
|
||||
/** For persistence */
|
||||
tresult PLUGIN_API setState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getState (IBStream* state) SMTG_OVERRIDE;
|
||||
|
||||
/** Will be called before any process call */
|
||||
tresult PLUGIN_API setupProcessing (ProcessSetup& newSetup) SMTG_OVERRIDE;
|
||||
|
||||
/** Bus arrangement managing: in this example the 'again' will be mono for mono input/output and
|
||||
* stereo for other arrangements. */
|
||||
tresult PLUGIN_API setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs,
|
||||
int32 numOuts) SMTG_OVERRIDE;
|
||||
|
||||
/** Asks if a given sample size is supported see \ref SymbolicSampleSizes. */
|
||||
tresult PLUGIN_API canProcessSampleSize (int32 symbolicSampleSize) SMTG_OVERRIDE;
|
||||
|
||||
/** We want to receive message. */
|
||||
tresult PLUGIN_API notify (IMessage* message) SMTG_OVERRIDE;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
//==============================================================================
|
||||
template <typename SampleType>
|
||||
SampleType processAudio (SampleType** input, SampleType** output, int32 numChannels,
|
||||
int32 sampleFrames, float gain);
|
||||
|
||||
template <typename SampleType>
|
||||
SampleType processVuPPM (SampleType** input, int32 numChannels, int32 sampleFrames);
|
||||
|
||||
// our model values
|
||||
float fGain {1.f};
|
||||
float fGainReduction {0.f};
|
||||
float fVuPPMOld {0.f};
|
||||
|
||||
int32 currentProcessMode {-1}; // -1 means not initialized
|
||||
|
||||
bool bHalfGain {false};
|
||||
bool bBypass {false};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,32 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/againcids.h
|
||||
// Created by : Steinberg, 12/2007
|
||||
// Description : define the class IDs for AGain
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
// Here are defined the UIDs for the 2 processors (2 plug-ins) and 1 controller (shared by the 2 plug-ins)
|
||||
static const FUID AGainProcessorUID (0x84E8DE5F, 0x92554F53, 0x96FAE413, 0x3C935A18);
|
||||
static const FUID AGainWithSideChainProcessorUID (0x41347FD6, 0xFED64094, 0xAFBB12B7, 0xDBA1D441);
|
||||
|
||||
static const FUID AGainControllerUID (0xD39D5B65, 0xD7AF42FA, 0x843F4AC8, 0x41EB04F0);
|
||||
|
||||
#define AGainVST3Category "Fx"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,393 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/againcontroller.cpp
|
||||
// Created by : Steinberg, 04/2005
|
||||
// Description : AGain Controller Example for VST 3
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "againcontroller.h"
|
||||
#include "againparamids.h"
|
||||
#include "againuimessagecontroller.h"
|
||||
|
||||
#include "pluginterfaces/base/ibstream.h"
|
||||
#include "pluginterfaces/base/ustring.h"
|
||||
#include "pluginterfaces/vst/ivstmidicontrollers.h"
|
||||
|
||||
#include "base/source/fstreamer.h"
|
||||
#include "base/source/fstring.h"
|
||||
|
||||
#include "vstgui/uidescription/delegationcontroller.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace VSTGUI;
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// GainParameter Declaration
|
||||
// example of custom parameter (overwriting to and fromString)
|
||||
//------------------------------------------------------------------------
|
||||
class GainParameter : public Parameter
|
||||
{
|
||||
public:
|
||||
GainParameter (int32 flags, int32 id);
|
||||
|
||||
void toString (ParamValue normValue, String128 string) const SMTG_OVERRIDE;
|
||||
bool fromString (const TChar* string, ParamValue& normValue) const SMTG_OVERRIDE;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// GainParameter Implementation
|
||||
//------------------------------------------------------------------------
|
||||
GainParameter::GainParameter (int32 flags, int32 id)
|
||||
{
|
||||
Steinberg::UString (info.title, USTRINGSIZE (info.title)).assign (USTRING ("Gain"));
|
||||
Steinberg::UString (info.units, USTRINGSIZE (info.units)).assign (USTRING ("dB"));
|
||||
|
||||
info.flags = flags;
|
||||
info.id = id;
|
||||
info.stepCount = 0;
|
||||
info.defaultNormalizedValue = 0.5f;
|
||||
info.unitId = kRootUnitId;
|
||||
|
||||
setNormalized (1.f);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void GainParameter::toString (ParamValue normValue, String128 string) const
|
||||
{
|
||||
char text[32];
|
||||
if (normValue > 0.0001)
|
||||
{
|
||||
snprintf (text, 32, "%.2f", 20 * log10f ((float)normValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy (text, "-oo");
|
||||
}
|
||||
|
||||
Steinberg::UString (string, 128).fromAscii (text);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool GainParameter::fromString (const TChar* string, ParamValue& normValue) const
|
||||
{
|
||||
String wrapper ((TChar*)string); // don't know buffer size here!
|
||||
double tmp = 0.0;
|
||||
if (wrapper.scanFloat (tmp))
|
||||
{
|
||||
// allow only values between -oo and 0dB
|
||||
if (tmp > 0.0)
|
||||
{
|
||||
tmp = -tmp;
|
||||
}
|
||||
|
||||
normValue = expf (logf (10.f) * (float)tmp / 20.f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// AGainController Implementation
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainController::initialize (FUnknown* context)
|
||||
{
|
||||
tresult result = EditControllerEx1::initialize (context);
|
||||
if (result != kResultOk)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//--- Create Units-------------
|
||||
UnitInfo unitInfo {};
|
||||
Unit* unit;
|
||||
|
||||
// create root only if you want to use the programListId
|
||||
/* unitInfo.id = kRootUnitId; // always for Root Unit
|
||||
unitInfo.parentUnitId = kNoParentUnitId; // always for Root Unit
|
||||
Steinberg::UString (unitInfo.name, USTRINGSIZE (unitInfo.name)).assign (USTRING ("Root"));
|
||||
unitInfo.programListId = kNoProgramListId;
|
||||
|
||||
|
||||
unit = new Unit (unitInfo);
|
||||
addUnitInfo (unit);*/
|
||||
|
||||
// create a unit1 for the gain
|
||||
unitInfo.id = 1;
|
||||
unitInfo.parentUnitId = kRootUnitId; // attached to the root unit
|
||||
|
||||
Steinberg::UString (unitInfo.name, USTRINGSIZE (unitInfo.name)).assign (USTRING ("Unit1"));
|
||||
|
||||
unitInfo.programListId = kNoProgramListId;
|
||||
|
||||
unit = new Unit (unitInfo);
|
||||
addUnit (unit);
|
||||
|
||||
//---Create Parameters------------
|
||||
|
||||
//---Gain parameter--
|
||||
auto* gainParam = new GainParameter (ParameterInfo::kCanAutomate, kGainId);
|
||||
parameters.addParameter (gainParam);
|
||||
|
||||
gainParam->setUnitID (1);
|
||||
|
||||
//---VuMeter parameter---
|
||||
int32 stepCount = 0;
|
||||
ParamValue defaultVal = 0;
|
||||
int32 flags = ParameterInfo::kIsReadOnly;
|
||||
int32 tag = kVuPPMId;
|
||||
parameters.addParameter (STR16 ("VuPPM"), nullptr, stepCount, defaultVal, flags, tag);
|
||||
|
||||
//---Bypass parameter---
|
||||
stepCount = 1;
|
||||
defaultVal = 0;
|
||||
flags = ParameterInfo::kCanAutomate | ParameterInfo::kIsBypass;
|
||||
tag = kBypassId;
|
||||
parameters.addParameter (STR16 ("Bypass"), nullptr, stepCount, defaultVal, flags, tag);
|
||||
|
||||
//---Custom state init------------
|
||||
|
||||
String str ("Hello World!");
|
||||
str.copyTo16 (defaultMessageText, 0, 127);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainController::terminate ()
|
||||
{
|
||||
return EditControllerEx1::terminate ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainController::setComponentState (IBStream* state)
|
||||
{
|
||||
// we receive the current state of the component (processor part)
|
||||
// we read only the gain and bypass value...
|
||||
if (!state)
|
||||
return kResultFalse;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
float savedGain = 0.f;
|
||||
if (streamer.readFloat (savedGain) == false)
|
||||
return kResultFalse;
|
||||
setParamNormalized (kGainId, savedGain);
|
||||
|
||||
// jump the GainReduction
|
||||
streamer.seek (sizeof (float), kSeekCurrent);
|
||||
|
||||
int32 bypassState = 0;
|
||||
if (streamer.readInt32 (bypassState) == false)
|
||||
return kResultFalse;
|
||||
setParamNormalized (kBypassId, bypassState ? 1 : 0);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
IPlugView* PLUGIN_API AGainController::createView (const char* _name)
|
||||
{
|
||||
// someone wants my editor
|
||||
ConstString name (_name);
|
||||
if (name == ViewType::kEditor)
|
||||
{
|
||||
auto* view = new VST3Editor (this, "view", "again.uidesc");
|
||||
return view;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
IController* AGainController::createSubController (UTF8StringPtr name,
|
||||
const IUIDescription* /*description*/,
|
||||
VST3Editor* /*editor*/)
|
||||
{
|
||||
if (UTF8StringView (name) == "MessageController")
|
||||
{
|
||||
auto* controller = new UIMessageController (this);
|
||||
addUIMessageController (controller);
|
||||
return controller;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainController::setState (IBStream* state)
|
||||
{
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
int8 byteOrder;
|
||||
if (streamer.readInt8 (byteOrder) == false)
|
||||
return kResultFalse;
|
||||
if (streamer.readRaw (defaultMessageText, 128 * sizeof (TChar)) == false)
|
||||
return kResultFalse;
|
||||
|
||||
// if the byteorder doesn't match, byte swap the text array ...
|
||||
if (byteOrder != BYTEORDER)
|
||||
{
|
||||
for (int32 i = 0; i < 128; i++)
|
||||
{
|
||||
SWAP_16 (defaultMessageText[i])
|
||||
}
|
||||
}
|
||||
|
||||
// update our editors
|
||||
for (auto& uiMessageController : uiMessageControllers)
|
||||
uiMessageController->setMessageText (defaultMessageText);
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainController::getState (IBStream* state)
|
||||
{
|
||||
// here we can save UI settings for example
|
||||
|
||||
// as we save a Unicode string, we must know the byteorder when setState is called
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
int8 byteOrder = BYTEORDER;
|
||||
if (streamer.writeInt8 (byteOrder) == false)
|
||||
return kResultFalse;
|
||||
|
||||
if (streamer.writeRaw (defaultMessageText, 128 * sizeof (TChar)) == false)
|
||||
return kResultFalse;
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult AGainController::receiveText (const char* text)
|
||||
{
|
||||
// received from Component
|
||||
if (text)
|
||||
{
|
||||
fprintf (stderr, "[AGainController] received: ");
|
||||
fprintf (stderr, "%s", text);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainController::setParamNormalized (ParamID tag, ParamValue value)
|
||||
{
|
||||
// called from host to update our parameters state
|
||||
tresult result = EditControllerEx1::setParamNormalized (tag, value);
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainController::getParamStringByValue (ParamID tag, ParamValue valueNormalized,
|
||||
String128 string)
|
||||
{
|
||||
/* example, but better to use a custom Parameter as seen in GainParameter
|
||||
switch (tag)
|
||||
{
|
||||
case kGainId:
|
||||
{
|
||||
char text[32];
|
||||
if (valueNormalized > 0.0001)
|
||||
{
|
||||
sprintf (text, "%.2f", 20 * log10f ((float)valueNormalized));
|
||||
}
|
||||
else
|
||||
strcpy (text, "-oo");
|
||||
|
||||
Steinberg::UString (string, 128).fromAscii (text);
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
}*/
|
||||
return EditControllerEx1::getParamStringByValue (tag, valueNormalized, string);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainController::getParamValueByString (ParamID tag, TChar* string,
|
||||
ParamValue& valueNormalized)
|
||||
{
|
||||
/* example, but better to use a custom Parameter as seen in GainParameter
|
||||
switch (tag)
|
||||
{
|
||||
case kGainId:
|
||||
{
|
||||
Steinberg::UString wrapper ((TChar*)string, -1); // don't know buffer size here!
|
||||
double tmp = 0.0;
|
||||
if (wrapper.scanFloat (tmp))
|
||||
{
|
||||
valueNormalized = expf (logf (10.f) * (float)tmp / 20.f);
|
||||
return kResultTrue;
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
}*/
|
||||
return EditControllerEx1::getParamValueByString (tag, string, valueNormalized);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void AGainController::addUIMessageController (UIMessageController* controller)
|
||||
{
|
||||
uiMessageControllers.push_back (controller);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void AGainController::removeUIMessageController (UIMessageController* controller)
|
||||
{
|
||||
UIMessageControllerList::const_iterator it =
|
||||
std::find (uiMessageControllers.begin (), uiMessageControllers.end (), controller);
|
||||
if (it != uiMessageControllers.end ())
|
||||
uiMessageControllers.erase (it);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void AGainController::setDefaultMessageText (String128 text)
|
||||
{
|
||||
String tmp (text);
|
||||
tmp.copyTo16 (defaultMessageText, 0, 127);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
TChar* AGainController::getDefaultMessageText ()
|
||||
{
|
||||
return defaultMessageText;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainController::queryInterface (const char* iid, void** obj)
|
||||
{
|
||||
QUERY_INTERFACE (iid, obj, IMidiMapping::iid, IMidiMapping)
|
||||
return EditControllerEx1::queryInterface (iid, obj);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainController::getMidiControllerAssignment (int32 busIndex,
|
||||
int16 /*midiChannel*/,
|
||||
CtrlNumber midiControllerNumber,
|
||||
ParamID& tag)
|
||||
{
|
||||
// we support for the Gain parameter all MIDI Channel but only first bus (there is only one!)
|
||||
if (busIndex == 0 && midiControllerNumber == kCtrlVolume)
|
||||
{
|
||||
tag = kGainId;
|
||||
return kResultTrue;
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,98 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/againcontroller.h
|
||||
// Created by : Steinberg, 04/2005
|
||||
// Description : AGain Editor Example for VST 3
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vstgui/plugin-bindings/vst3editor.h"
|
||||
#include "public.sdk/source/vst/vsteditcontroller.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
template <typename T>
|
||||
class AGainUIMessageController;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// AGainController
|
||||
//------------------------------------------------------------------------
|
||||
class AGainController : public EditControllerEx1, public IMidiMapping, public VSTGUI::VST3EditorDelegate
|
||||
{
|
||||
public:
|
||||
using UIMessageController = AGainUIMessageController<AGainController>;
|
||||
using UTF8StringPtr = VSTGUI::UTF8StringPtr;
|
||||
using IUIDescription = VSTGUI::IUIDescription;
|
||||
using IController = VSTGUI::IController;
|
||||
using VST3Editor = VSTGUI::VST3Editor;
|
||||
|
||||
//--- ---------------------------------------------------------------------
|
||||
// create function required for plug-in factory,
|
||||
// it will be called to create new instances of this controller
|
||||
//--- ---------------------------------------------------------------------
|
||||
static FUnknown* createInstance (void* /*context*/)
|
||||
{
|
||||
return (IEditController*)new AGainController;
|
||||
}
|
||||
|
||||
//---from IPluginBase--------
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
|
||||
|
||||
//---from EditController-----
|
||||
tresult PLUGIN_API setComponentState (IBStream* state) SMTG_OVERRIDE;
|
||||
IPlugView* PLUGIN_API createView (const char* name) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setParamNormalized (ParamID tag, ParamValue value) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized,
|
||||
String128 string) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string,
|
||||
ParamValue& valueNormalized) SMTG_OVERRIDE;
|
||||
|
||||
//---from ComponentBase-----
|
||||
tresult receiveText (const char* text) SMTG_OVERRIDE;
|
||||
|
||||
//---from IMidiMapping-----------------
|
||||
tresult PLUGIN_API getMidiControllerAssignment (int32 busIndex, int16 channel,
|
||||
CtrlNumber midiControllerNumber,
|
||||
ParamID& tag) SMTG_OVERRIDE;
|
||||
|
||||
//---from VST3EditorDelegate-----------
|
||||
IController* createSubController (UTF8StringPtr name, const IUIDescription* description,
|
||||
VST3Editor* editor) SMTG_OVERRIDE;
|
||||
|
||||
DELEGATE_REFCOUNT (EditController)
|
||||
tresult PLUGIN_API queryInterface (const char* iid, void** obj) SMTG_OVERRIDE;
|
||||
|
||||
//---Internal functions-------
|
||||
void addUIMessageController (UIMessageController* controller);
|
||||
void removeUIMessageController (UIMessageController* controller);
|
||||
|
||||
void setDefaultMessageText (String128 text);
|
||||
TChar* getDefaultMessageText ();
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
using UIMessageControllerList = std::vector<UIMessageController*>;
|
||||
UIMessageControllerList uiMessageControllers;
|
||||
|
||||
String128 defaultMessageText {};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,80 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/againentry.cpp
|
||||
// Created by : Steinberg, 04/2005
|
||||
// Description : AGain Example for VST 3
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "again.h" // for AGain
|
||||
#include "againsidechain.h" // for AGain SideChain
|
||||
#include "againcontroller.h" // for AGainController
|
||||
#include "againcids.h" // for class ids and category
|
||||
#include "version.h" // for versioning
|
||||
|
||||
#include "public.sdk/source/main/pluginfactory.h"
|
||||
|
||||
#define stringPluginName "AGain VST3"
|
||||
#define stringPluginSideChainName "AGain SideChain VST3"
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#include "public.sdk/source/vst/vstguieditor.h"
|
||||
extern void* moduleHandle;
|
||||
#endif
|
||||
|
||||
using namespace Steinberg::Vst;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// VST Plug-in Entry
|
||||
//------------------------------------------------------------------------
|
||||
// Windows: do not forget to include a .def file in your project to export
|
||||
// GetPluginFactory function!
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
BEGIN_FACTORY_DEF (stringCompanyName, stringCompanyWeb, stringCompanyEmail)
|
||||
|
||||
//---First plug-in included in this factory-------
|
||||
// its kVstAudioEffectClass component
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID(AGainProcessorUID),
|
||||
PClassInfo::kManyInstances, // cardinality
|
||||
kVstAudioEffectClass, // the component category (do not change this)
|
||||
stringPluginName, // here the plug-in name (to be changed)
|
||||
Vst::kDistributable, // means that component and controller could be distributed on different computers
|
||||
AGainVST3Category, // Subcategory for this plug-in (to be changed)
|
||||
FULL_VERSION_STR, // Plug-in version (to be changed)
|
||||
kVstVersionString, // the VST 3 SDK version (do not change this, always use this define)
|
||||
Steinberg::Vst::AGain::createInstance) // function pointer called when this component should be instantiated
|
||||
|
||||
// its kVstComponentControllerClass component
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID (AGainControllerUID),
|
||||
PClassInfo::kManyInstances, // cardinality
|
||||
kVstComponentControllerClass,// the Controller category (do not change this)
|
||||
stringPluginName "Controller", // controller name (can be the same as the component name)
|
||||
0, // not used here
|
||||
"", // not used here
|
||||
FULL_VERSION_STR, // Plug-in version (to be changed)
|
||||
kVstVersionString, // the VST 3 SDK version (do not change this, always use this define)
|
||||
Steinberg::Vst::AGainController::createInstance)// function pointer called when this component should be instantiated
|
||||
|
||||
//---Second plug-in (AGain with sidechain (only component, use the same controller) included in this factory-------
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID(AGainWithSideChainProcessorUID),
|
||||
PClassInfo::kManyInstances, // cardinality
|
||||
kVstAudioEffectClass, // the component category (do not change this)
|
||||
stringPluginSideChainName, // here the plug-in name (to be changed)
|
||||
Vst::kDistributable, // means that component and controller could be distributed on different computers
|
||||
AGainVST3Category, // Subcategory for this plug-in (to be changed)
|
||||
FULL_VERSION_STR, // Plug-in version (to be changed)
|
||||
kVstVersionString, // the VST 3 SDK version (do not change this, always use this define)
|
||||
Steinberg::Vst::AGainWithSideChain::createInstance) // function pointer called when this component should be instantiated
|
||||
|
||||
//----for others plug-ins contained in this factory, put like for the first plug-in different DEF_CLASS2---
|
||||
|
||||
END_FACTORY
|
||||
@@ -0,0 +1,25 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/againparamids.h
|
||||
// Created by : Steinberg, 12/2007
|
||||
// Description : define the parameter IDs used by AGain
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
/** parameter ID */
|
||||
kGainId = 0, ///< for the gain value (is automatable)
|
||||
kVuPPMId, ///< for the Vu value return to host (ReadOnly parameter for our UI)
|
||||
kBypassId ///< Bypass value (we will handle the bypass process) (is automatable)
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/againprocess.h
|
||||
// Created by : Steinberg, 11/2016
|
||||
// Description : AGain Example for VST SDK 3.0
|
||||
// Simple gain plug-in with gain, bypass values and 1 midi input
|
||||
// and the same plug-in with sidechain
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <typename SampleType>
|
||||
SampleType AGain::processAudio (SampleType** in, SampleType** out, int32 numChannels,
|
||||
int32 sampleFrames, float gain)
|
||||
{
|
||||
SampleType vuPPM = 0;
|
||||
|
||||
// in real Plug-in it would be better to do dezippering to avoid jump (click) in gain value
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
int32 samples = sampleFrames;
|
||||
SampleType* ptrIn = (SampleType*)in[i];
|
||||
SampleType* ptrOut = (SampleType*)out[i];
|
||||
SampleType tmp;
|
||||
while (--samples >= 0)
|
||||
{
|
||||
// apply gain
|
||||
tmp = (*ptrIn++) * gain;
|
||||
(*ptrOut++) = tmp;
|
||||
|
||||
// check only positive values
|
||||
if (tmp > vuPPM)
|
||||
{
|
||||
vuPPM = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return vuPPM;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <typename SampleType>
|
||||
SampleType AGain::processVuPPM (SampleType** in, int32 numChannels, int32 sampleFrames)
|
||||
{
|
||||
SampleType vuPPM = 0;
|
||||
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
int32 samples = sampleFrames;
|
||||
SampleType* ptrIn = (SampleType*)in[i];
|
||||
SampleType tmp;
|
||||
while (--samples >= 0)
|
||||
{
|
||||
tmp = (*ptrIn++);
|
||||
|
||||
// check only positive values
|
||||
if (tmp > vuPPM)
|
||||
{
|
||||
vuPPM = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return vuPPM;
|
||||
}
|
||||
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
@@ -0,0 +1,365 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/againsidechain.cpp
|
||||
// Created by : Steinberg, 04/2005
|
||||
// Description : AGain Example for VST SDK 3
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "againsidechain.h"
|
||||
#include "againcids.h" // for class ids
|
||||
#include "againparamids.h"
|
||||
#include "againprocess.h"
|
||||
|
||||
#include "public.sdk/source/vst/vstaudioprocessoralgo.h"
|
||||
|
||||
#include "pluginterfaces/vst/ivstevents.h"
|
||||
#include "pluginterfaces/vst/ivstparameterchanges.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// AGainWithSideChain Implementation
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainWithSideChain::initialize (FUnknown* context)
|
||||
{
|
||||
//---always initialize the parent-------
|
||||
tresult result = AGain::initialize (context);
|
||||
// if everything Ok, continue
|
||||
if (result != kResultOk)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// create a Mono SideChain input bus (this will be the 2cd input)
|
||||
addAudioInput (STR16 ("Mono Aux In"), SpeakerArr::kMono, kAux, 0);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainWithSideChain::process (ProcessData& data)
|
||||
{
|
||||
// finally the process function
|
||||
// In this example there are 4 steps:
|
||||
// 1) Read inputs parameters coming from host (in order to adapt our model values)
|
||||
// 2) Read inputs events coming from host (we apply a gain reduction depending of the velocity
|
||||
// of pressed key) 3) Process the gain of the input buffer to the output buffer 4) Write the new
|
||||
// VUmeter value to the output Parameters queue
|
||||
|
||||
//---1) Read inputs parameter changes-----------
|
||||
if (IParameterChanges* paramChanges = data.inputParameterChanges)
|
||||
{
|
||||
int32 numParamsChanged = paramChanges->getParameterCount ();
|
||||
// for each parameter which are some changes in this audio block:
|
||||
for (int32 i = 0; i < numParamsChanged; i++)
|
||||
{
|
||||
if (IParamValueQueue* paramQueue = paramChanges->getParameterData (i))
|
||||
{
|
||||
int32 offsetSamples;
|
||||
double value;
|
||||
int32 numPoints = paramQueue->getPointCount ();
|
||||
switch (paramQueue->getParameterId ())
|
||||
{
|
||||
case kGainId:
|
||||
// we use in this example only the last point of the queue.
|
||||
// in some wanted case for specific kind of parameter it makes sense to
|
||||
// retrieve all points and process the whole audio block in small blocks.
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) ==
|
||||
kResultTrue)
|
||||
{
|
||||
fGain = (float)value;
|
||||
}
|
||||
break;
|
||||
|
||||
case kBypassId:
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) ==
|
||||
kResultTrue)
|
||||
{
|
||||
bBypass = (value > 0.5f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---2) Read input events-------------
|
||||
if (IEventList* eventList = data.inputEvents)
|
||||
{
|
||||
int32 numEvent = eventList->getEventCount ();
|
||||
for (int32 i = 0; i < numEvent; i++)
|
||||
{
|
||||
Event event {};
|
||||
if (eventList->getEvent (i, event) == kResultOk)
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
//--- -------------------
|
||||
case Event::kNoteOnEvent:
|
||||
// use the velocity as gain modifier
|
||||
fGainReduction = event.noteOn.velocity;
|
||||
break;
|
||||
|
||||
//--- -------------------
|
||||
case Event::kNoteOffEvent:
|
||||
// noteOff reset the reduction
|
||||
fGainReduction = 0.f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--- ----------------------------------
|
||||
//---3) Process Audio---------------------
|
||||
//--- ----------------------------------
|
||||
if (data.numInputs == 0 || data.numOutputs == 0)
|
||||
{
|
||||
// nothing to do
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
// (simplification) we suppose in this example that we have the same input channel count than
|
||||
// the output
|
||||
int32 numChannels = data.inputs[0].numChannels;
|
||||
|
||||
//---get audio buffers----------------
|
||||
uint32 sampleFramesSize = getSampleFramesSizeInBytes (processSetup, data.numSamples);
|
||||
void** in = getChannelBuffersPointer (processSetup, data.inputs[0]);
|
||||
void** out = getChannelBuffersPointer (processSetup, data.outputs[0]);
|
||||
void** auxIn = nullptr;
|
||||
|
||||
bool auxActive = false;
|
||||
// check if our sidechain input is active (here our sidechain is the 2cd input)
|
||||
if (getAudioInput (1)->isActive ())
|
||||
{
|
||||
auxIn = getChannelBuffersPointer (processSetup, data.inputs[1]);
|
||||
auxActive = true;
|
||||
}
|
||||
|
||||
float fVuPPM = 0.f;
|
||||
|
||||
//---check if silence---------------
|
||||
// check if all channel are silent then process silent
|
||||
if (data.inputs[0].silenceFlags == getChannelMask (data.inputs[0].numChannels))
|
||||
{
|
||||
// mark output silence too
|
||||
data.outputs[0].silenceFlags = data.inputs[0].silenceFlags;
|
||||
|
||||
// the plug-in has to be sure that if it sets the flags silence that the output buffer are
|
||||
// clear
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
// do not need to be cleared if the buffers are the same (in this case input buffer are
|
||||
// already cleared by the host)
|
||||
if (in[i] != out[i])
|
||||
{
|
||||
memset (out[i], 0, sampleFramesSize);
|
||||
}
|
||||
}
|
||||
fVuPPM = 0.f;
|
||||
}
|
||||
else // we have to process (no silence)
|
||||
{
|
||||
// mark our outputs has not silent
|
||||
data.outputs[0].silenceFlags = 0;
|
||||
|
||||
//---in bypass mode outputs should be like inputs-----
|
||||
if (bBypass)
|
||||
{
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
// do not need to be copied if the buffers are the same
|
||||
if (in[i] != out[i])
|
||||
{
|
||||
memcpy (out[i], in[i], sampleFramesSize);
|
||||
}
|
||||
}
|
||||
// in this example we do not update the VuMeter in Bypass
|
||||
}
|
||||
else
|
||||
{
|
||||
//---apply gain factor----------
|
||||
float gain = (fGain - fGainReduction);
|
||||
if (bHalfGain)
|
||||
{
|
||||
gain = gain * 0.5f;
|
||||
}
|
||||
|
||||
// if the applied gain is nearly zero, we could say that the outputs are zeroed and we set
|
||||
// the silence flags.
|
||||
if (gain < 0.0000001)
|
||||
{
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
memset (out[i], 0, sampleFramesSize);
|
||||
}
|
||||
// this will set to 1 all channels
|
||||
data.outputs[0].silenceFlags = getChannelMask (data.outputs[0].numChannels);
|
||||
fVuPPM = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auxActive)
|
||||
{
|
||||
if (data.symbolicSampleSize == kSample32)
|
||||
fVuPPM = processAudioWithSideChain<Sample32> (
|
||||
(Sample32**)in, (Sample32**)out, (Sample32**)auxIn, numChannels,
|
||||
data.numSamples, gain);
|
||||
else
|
||||
fVuPPM = static_cast<float> (processAudioWithSideChain<Sample64> (
|
||||
(Sample64**)in, (Sample64**)out, (Sample64**)auxIn, numChannels,
|
||||
data.numSamples, gain));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data.symbolicSampleSize == kSample32)
|
||||
fVuPPM = processAudio<Sample32> ((Sample32**)in, (Sample32**)out,
|
||||
numChannels, data.numSamples, gain);
|
||||
else
|
||||
fVuPPM = static_cast<float> (processAudio<Sample64> (
|
||||
(Sample64**)in, (Sample64**)out, numChannels, data.numSamples, gain));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//---3) Write <outputs parameter changes-----------
|
||||
IParameterChanges* outParamChanges = data.outputParameterChanges;
|
||||
// a new value of VuMeter will be send to the host
|
||||
// (the host will send it back in sync to our controller for updating our editor)
|
||||
if (outParamChanges && fVuPPMOld != fVuPPM)
|
||||
{
|
||||
int32 index = 0;
|
||||
IParamValueQueue* paramQueue = outParamChanges->addParameterData (kVuPPMId, index);
|
||||
if (paramQueue)
|
||||
{
|
||||
int32 index2 = 0;
|
||||
paramQueue->addPoint (0, fVuPPM, index2);
|
||||
}
|
||||
}
|
||||
fVuPPMOld = fVuPPM;
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <typename SampleType>
|
||||
SampleType AGainWithSideChain::processAudioWithSideChain (SampleType** in, SampleType** out,
|
||||
SampleType** aux, int32 numChannels,
|
||||
int32 sampleFrames, float gain)
|
||||
{
|
||||
SampleType vuPPM = 0;
|
||||
|
||||
// we add the sidechain to the input signal
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
int32 samples = sampleFrames;
|
||||
auto* ptrIn = (SampleType*)in[i];
|
||||
auto* ptrAuxIn = (SampleType*)aux[0];
|
||||
auto* ptrOut = (SampleType*)out[i];
|
||||
SampleType tmp;
|
||||
while (--samples >= 0)
|
||||
{
|
||||
// apply gain
|
||||
tmp = (*ptrIn++ + *ptrAuxIn++) * gain;
|
||||
(*ptrOut++) = tmp;
|
||||
|
||||
// check only positive values
|
||||
if (tmp > vuPPM)
|
||||
{
|
||||
vuPPM = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return vuPPM;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainWithSideChain::setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs,
|
||||
int32 numOuts)
|
||||
{
|
||||
// the first input is the Main Input and the second is the SideChain Input
|
||||
if (numIns == 2 && numOuts == 1)
|
||||
{
|
||||
// the host wants Mono => Mono (or 1 channel -> 1 channel)
|
||||
if (SpeakerArr::getChannelCount (inputs[0]) == 1 &&
|
||||
SpeakerArr::getChannelCount (outputs[0]) == 1)
|
||||
{
|
||||
auto* bus = FCast<AudioBus> (audioInputs.at (0));
|
||||
if (bus)
|
||||
{
|
||||
// check if we are Mono => Mono, if not we need to recreate the busses
|
||||
if (bus->getArrangement () != inputs[0])
|
||||
{
|
||||
getAudioInput (0)->setArrangement (inputs[0]);
|
||||
getAudioInput (0)->setName (STR16 ("Mono In"));
|
||||
getAudioOutput (0)->setArrangement (outputs[0]);
|
||||
getAudioOutput (0)->setName (STR16 ("Mono Out"));
|
||||
}
|
||||
// check if sidechain is mono
|
||||
if (SpeakerArr::getChannelCount (inputs[1]) != 1)
|
||||
return kResultFalse;
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
}
|
||||
// the host wants something else than Mono => Mono, in this case we are always Stereo =>
|
||||
// Stereo
|
||||
else
|
||||
{
|
||||
auto* bus = FCast<AudioBus> (audioInputs.at (0));
|
||||
if (bus)
|
||||
{
|
||||
tresult result = kResultFalse;
|
||||
|
||||
// the host wants 2->2 (could be LsRs -> LsRs)
|
||||
if (SpeakerArr::getChannelCount (inputs[0]) == 2 &&
|
||||
SpeakerArr::getChannelCount (outputs[0]) == 2)
|
||||
{
|
||||
getAudioInput (0)->setArrangement (inputs[0]);
|
||||
getAudioInput (0)->setName (STR16 ("Stereo In"));
|
||||
getAudioOutput (0)->setArrangement (outputs[0]);
|
||||
getAudioOutput (0)->setName (STR16 ("Stereo Out"));
|
||||
|
||||
// check if sidechain is mono
|
||||
if (SpeakerArr::getChannelCount (inputs[1]) != 1)
|
||||
result = kResultFalse;
|
||||
else
|
||||
result = kResultTrue;
|
||||
}
|
||||
// the host want something different than 1->1 or 2->2 : in this case we want stereo
|
||||
else if (bus->getArrangement () != SpeakerArr::kStereo)
|
||||
{
|
||||
getAudioInput (0)->setArrangement (SpeakerArr::kStereo);
|
||||
getAudioInput (0)->setName (STR16 ("Stereo In"));
|
||||
getAudioOutput (0)->setArrangement (SpeakerArr::kStereo);
|
||||
getAudioOutput (0)->setName (STR16 ("Stereo Out"));
|
||||
|
||||
result = kResultFalse;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,53 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/againsidechain.h
|
||||
// Created by : Steinberg, 04/2016
|
||||
// Description : AGain Example for VST SDK 3.0
|
||||
// Simple gain plug-in with gain, bypass values and 1 midi input
|
||||
// and a sidechain
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "again.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// AGainWithSideChain: directly derived from AGain
|
||||
//------------------------------------------------------------------------
|
||||
class AGainWithSideChain : public AGain
|
||||
{
|
||||
public:
|
||||
// just overwrite some functions
|
||||
static FUnknown* createInstance (void* /*context*/)
|
||||
{
|
||||
return (IAudioProcessor*)new AGainWithSideChain;
|
||||
}
|
||||
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API process (ProcessData& data) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs,
|
||||
int32 numOuts) SMTG_OVERRIDE;
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
template <typename SampleType>
|
||||
SampleType processAudioWithSideChain (SampleType** in, SampleType** out, SampleType** aux,
|
||||
int32 numChannels, int32 sampleFrames, float gain);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,702 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/againsimple.cpp
|
||||
// Created by : Steinberg, 04/2005
|
||||
// Description : AGain Example for VST SDK 3.0
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "againsimple.h"
|
||||
#include "againparamids.h"
|
||||
#include "againuimessagecontroller.h"
|
||||
#include "version.h" // for versioning
|
||||
|
||||
#include "public.sdk/source/main/pluginfactory.h"
|
||||
#include "public.sdk/source/vst/vstaudioprocessoralgo.h"
|
||||
|
||||
#include "pluginterfaces/base/funknownimpl.h"
|
||||
#include "pluginterfaces/base/ibstream.h"
|
||||
#include "pluginterfaces/base/ustring.h" // for UString128
|
||||
#include "pluginterfaces/vst/ivstevents.h"
|
||||
#include "pluginterfaces/vst/ivstmidicontrollers.h"
|
||||
#include "pluginterfaces/vst/ivstparameterchanges.h"
|
||||
#include "pluginterfaces/vst/vstpresetkeys.h" // for use of IStreamAttributes
|
||||
|
||||
#include "base/source/fstreamer.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
|
||||
// this allows to enable the communication example between again and its controller
|
||||
#define AGAIN_TEST 1
|
||||
|
||||
using namespace VSTGUI;
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// GainParameter Declaration
|
||||
// example of custom parameter (overwriting to and fromString)
|
||||
//------------------------------------------------------------------------
|
||||
class GainParameter : public Parameter
|
||||
{
|
||||
public:
|
||||
GainParameter (int32 flags, int32 id);
|
||||
|
||||
void toString (ParamValue normValue, String128 string) const SMTG_OVERRIDE;
|
||||
bool fromString (const TChar* string, ParamValue& normValue) const SMTG_OVERRIDE;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// GainParameter Implementation
|
||||
//------------------------------------------------------------------------
|
||||
GainParameter::GainParameter (int32 flags, int32 id)
|
||||
{
|
||||
Steinberg::UString (info.title, USTRINGSIZE (info.title)).assign (USTRING ("Gain"));
|
||||
Steinberg::UString (info.units, USTRINGSIZE (info.units)).assign (USTRING ("dB"));
|
||||
|
||||
info.flags = flags;
|
||||
info.id = id;
|
||||
info.stepCount = 0;
|
||||
info.defaultNormalizedValue = 0.5f;
|
||||
info.unitId = kRootUnitId;
|
||||
|
||||
setNormalized (1.f);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void GainParameter::toString (ParamValue normValue, String128 string) const
|
||||
{
|
||||
char text[32];
|
||||
if (normValue > 0.0001)
|
||||
snprintf (text, 32, "%.2f", 20 * log10f ((float)normValue));
|
||||
else
|
||||
strcpy (text, "-oo");
|
||||
|
||||
Steinberg::UString (string, 128).fromAscii (text);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool GainParameter::fromString (const TChar* string, ParamValue& normValue) const
|
||||
{
|
||||
Steinberg::UString wrapper ((TChar*)string, -1); // don't know buffer size here!
|
||||
double tmp = 0.0;
|
||||
if (wrapper.scanFloat (tmp))
|
||||
{
|
||||
// allow only values between -oo and 0dB
|
||||
if (tmp > 0.0)
|
||||
tmp = -tmp;
|
||||
|
||||
normValue = expf (logf (10.f) * (float)tmp / 20.f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// AGain Implementation
|
||||
//------------------------------------------------------------------------
|
||||
AGainSimple::AGainSimple ()
|
||||
: fGain (1.f)
|
||||
, fGainReduction (0.f)
|
||||
, fVuPPMOld (0.f)
|
||||
, currentProcessMode (-1) // -1 means not initialized
|
||||
, bHalfGain (false)
|
||||
, bBypass (false)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::initialize (FUnknown* context)
|
||||
{
|
||||
tresult result = SingleComponentEffect::initialize (context);
|
||||
if (result != kResultOk)
|
||||
return result;
|
||||
|
||||
//---create Audio In/Out busses------
|
||||
// we want a stereo Input and a Stereo Output
|
||||
addAudioInput (STR16 ("Stereo In"), SpeakerArr::kStereo);
|
||||
addAudioOutput (STR16 ("Stereo Out"), SpeakerArr::kStereo);
|
||||
|
||||
//---create Event In/Out busses (1 bus with only 1 channel)------
|
||||
addEventInput (STR16 ("Event In"), 1);
|
||||
|
||||
//---Create Parameters------------
|
||||
|
||||
//---Gain parameter--
|
||||
auto* gainParam = new GainParameter (ParameterInfo::kCanAutomate, kGainId);
|
||||
parameters.addParameter (gainParam);
|
||||
|
||||
//---VuMeter parameter---
|
||||
int32 stepCount = 0;
|
||||
ParamValue defaultVal = 0;
|
||||
int32 flags = ParameterInfo::kIsReadOnly;
|
||||
int32 tag = kVuPPMId;
|
||||
parameters.addParameter (USTRING ("VuPPM"), nullptr, stepCount, defaultVal, flags, tag);
|
||||
|
||||
//---Bypass parameter---
|
||||
stepCount = 1;
|
||||
defaultVal = 0;
|
||||
flags = ParameterInfo::kCanAutomate | ParameterInfo::kIsBypass;
|
||||
tag = kBypassId;
|
||||
parameters.addParameter (USTRING ("Bypass"), nullptr, stepCount, defaultVal, flags, tag);
|
||||
|
||||
//---Custom state init------------
|
||||
|
||||
UString str (defaultMessageText, 128);
|
||||
str.fromAscii ("Hello World!");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::terminate ()
|
||||
{
|
||||
return SingleComponentEffect::terminate ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::setActive (TBool state)
|
||||
{
|
||||
#if AGAIN_TEST
|
||||
if (state)
|
||||
fprintf (stderr, "[AGainSimple] Activated \n");
|
||||
else
|
||||
fprintf (stderr, "[AGainSimple] Deactivated \n");
|
||||
#endif
|
||||
|
||||
// reset the VuMeter value
|
||||
fVuPPMOld = 0.f;
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::process (ProcessData& data)
|
||||
{
|
||||
// finally the process function
|
||||
// In this example there are 4 steps:
|
||||
// 1) Read inputs parameters coming from host (in order to adapt our model values)
|
||||
// 2) Read inputs events coming from host (we apply a gain reduction depending of the velocity of pressed key)
|
||||
// 3) Process the gain of the input buffer to the output buffer
|
||||
// 4) Write the new VUmeter value to the output Parameters queue
|
||||
|
||||
|
||||
//---1) Read inputs parameter changes-----------
|
||||
if (IParameterChanges* paramChanges = data.inputParameterChanges)
|
||||
{
|
||||
int32 numParamsChanged = paramChanges->getParameterCount ();
|
||||
// for each parameter which are some changes in this audio block:
|
||||
for (int32 i = 0; i < numParamsChanged; i++)
|
||||
{
|
||||
if (IParamValueQueue* paramQueue = paramChanges->getParameterData (i))
|
||||
{
|
||||
ParamValue value;
|
||||
int32 sampleOffset;
|
||||
int32 numPoints = paramQueue->getPointCount ();
|
||||
switch (paramQueue->getParameterId ())
|
||||
{
|
||||
case kGainId:
|
||||
// we use in this example only the last point of the queue.
|
||||
// in some wanted case for specific kind of parameter it makes sense to retrieve all points
|
||||
// and process the whole audio block in small blocks.
|
||||
if (paramQueue->getPoint (numPoints - 1, sampleOffset, value) == kResultTrue)
|
||||
{
|
||||
fGain = (float)value;
|
||||
}
|
||||
break;
|
||||
|
||||
case kBypassId:
|
||||
if (paramQueue->getPoint (numPoints - 1, sampleOffset, value) == kResultTrue)
|
||||
{
|
||||
bBypass = (value > 0.5f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---2) Read input events-------------
|
||||
if (IEventList* eventList = data.inputEvents)
|
||||
{
|
||||
int32 numEvent = eventList->getEventCount ();
|
||||
for (int32 i = 0; i < numEvent; i++)
|
||||
{
|
||||
Event event {};
|
||||
if (eventList->getEvent (i, event) == kResultOk)
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
//--- -------------------
|
||||
case Event::kNoteOnEvent:
|
||||
// use the velocity as gain modifier
|
||||
fGainReduction = event.noteOn.velocity;
|
||||
break;
|
||||
|
||||
//--- -------------------
|
||||
case Event::kNoteOffEvent:
|
||||
// noteOff reset the reduction
|
||||
fGainReduction = 0.f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--- ----------------------------------
|
||||
//---3) Process Audio---------------------
|
||||
//--- ----------------------------------
|
||||
if (data.numInputs == 0 || data.numOutputs == 0)
|
||||
{
|
||||
// nothing to do
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
// (simplification) we suppose in this example that we have the same input channel count than
|
||||
// the output
|
||||
int32 numChannels = data.inputs[0].numChannels;
|
||||
|
||||
//---get audio buffers----------------
|
||||
uint32 sampleFramesSize = getSampleFramesSizeInBytes (processSetup, data.numSamples);
|
||||
void** in = getChannelBuffersPointer (processSetup, data.inputs[0]);
|
||||
void** out = getChannelBuffersPointer (processSetup, data.outputs[0]);
|
||||
float fVuPPM = 0.f;
|
||||
|
||||
//---check if silence---------------
|
||||
// check if all channel are silent then process silent
|
||||
if (data.inputs[0].silenceFlags == getChannelMask (data.inputs[0].numChannels))
|
||||
{
|
||||
// mark output silence too
|
||||
data.outputs[0].silenceFlags = data.inputs[0].silenceFlags;
|
||||
|
||||
// the plug-in has to be sure that if it sets the flags silence that the output buffer are
|
||||
// clear
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
// do not need to be cleared if the buffers are the same (in this case input buffer are
|
||||
// already cleared by the host)
|
||||
if (in[i] != out[i])
|
||||
{
|
||||
memset (out[i], 0, sampleFramesSize);
|
||||
}
|
||||
}
|
||||
fVuPPM = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// mark our outputs has not silent
|
||||
data.outputs[0].silenceFlags = 0;
|
||||
|
||||
//---in bypass mode outputs should be like inputs-----
|
||||
if (bBypass)
|
||||
{
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
// do not need to be copied if the buffers are the same
|
||||
if (in[i] != out[i])
|
||||
{
|
||||
memcpy (out[i], in[i], sampleFramesSize);
|
||||
}
|
||||
}
|
||||
// in this example we do not update the VuMeter in Bypass
|
||||
}
|
||||
else
|
||||
{
|
||||
//---apply gain factor----------
|
||||
float gain = (fGain - fGainReduction);
|
||||
if (bHalfGain)
|
||||
{
|
||||
gain = gain * 0.5f;
|
||||
}
|
||||
|
||||
// if the applied gain is nearly zero, we could say that the outputs are zeroed and we set
|
||||
// the silence flags.
|
||||
if (gain < 0.0000001)
|
||||
{
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
memset (out[i], 0, sampleFramesSize);
|
||||
}
|
||||
// this will set to 1 all channels
|
||||
data.outputs[0].silenceFlags = getChannelMask (data.outputs[0].numChannels);
|
||||
fVuPPM = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data.symbolicSampleSize == kSample32)
|
||||
fVuPPM = processAudio<Sample32> ((Sample32**)in, (Sample32**)out, numChannels,
|
||||
data.numSamples, gain);
|
||||
else
|
||||
fVuPPM = static_cast<float> (processAudio<Sample64> (
|
||||
(Sample64**)in, (Sample64**)out, numChannels, data.numSamples, gain));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---3) Write outputs parameter changes-----------
|
||||
IParameterChanges* outParamChanges = data.outputParameterChanges;
|
||||
// a new value of VuMeter will be send to the host
|
||||
// (the host will send it back in sync to our controller for updating our editor)
|
||||
if (outParamChanges && fVuPPMOld != fVuPPM)
|
||||
{
|
||||
int32 index = 0;
|
||||
IParamValueQueue* paramQueue = outParamChanges->addParameterData (kVuPPMId, index);
|
||||
if (paramQueue)
|
||||
{
|
||||
int32 index2 = 0;
|
||||
paramQueue->addPoint (0, fVuPPM, index2);
|
||||
}
|
||||
}
|
||||
fVuPPMOld = fVuPPM;
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::setState (IBStream* state)
|
||||
{
|
||||
// we receive the current (processor part)
|
||||
// called when we load a preset, the model has to be reloaded
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
float savedGain = 0.f;
|
||||
if (streamer.readFloat (savedGain) == false)
|
||||
return kResultFalse;
|
||||
|
||||
float savedGainReduction = 0.f;
|
||||
if (streamer.readFloat (savedGainReduction) == false)
|
||||
return kResultFalse;
|
||||
|
||||
int32 savedBypass = 0;
|
||||
if (streamer.readInt32 (savedBypass) == false)
|
||||
return kResultFalse;
|
||||
|
||||
fGain = savedGain;
|
||||
fGainReduction = savedGainReduction;
|
||||
bBypass = savedBypass > 0;
|
||||
|
||||
setParamNormalized (kGainId, savedGain);
|
||||
setParamNormalized (kBypassId, bBypass);
|
||||
|
||||
// Example of using the IStreamAttributes interface
|
||||
if (auto stream = U::cast<IStreamAttributes> (state))
|
||||
{
|
||||
if (IAttributeList* list = stream->getAttributes ())
|
||||
{
|
||||
// get the current type (project/Default..) of this state
|
||||
String128 string = {0};
|
||||
if (list->getString (PresetAttributes::kStateType, string, 128 * sizeof (TChar)) ==
|
||||
kResultTrue)
|
||||
{
|
||||
UString128 tmp (string);
|
||||
char ascii[128];
|
||||
tmp.toAscii (ascii, 128);
|
||||
if (strncmp (ascii, StateType::kProject, strlen (StateType::kProject)) == 0)
|
||||
{
|
||||
// we are in project loading context...
|
||||
}
|
||||
}
|
||||
|
||||
// get the full file path of this state
|
||||
TChar fullPath[1024];
|
||||
memset (fullPath, 0, 1024 * sizeof (TChar));
|
||||
if (list->getString (PresetAttributes::kFilePathStringType, fullPath,
|
||||
1024 * sizeof (TChar)) == kResultTrue)
|
||||
{
|
||||
// here we have the full path ...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::getState (IBStream* state)
|
||||
{
|
||||
// here we need to save the model
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
streamer.writeFloat (fGain);
|
||||
streamer.writeFloat (fGainReduction);
|
||||
streamer.writeInt32 (bBypass ? 1 : 0);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::setupProcessing (ProcessSetup& newSetup)
|
||||
{
|
||||
// called before the process call, always in a disable state (not active)
|
||||
|
||||
// here we keep a trace of the processing mode (offline,...) for example.
|
||||
currentProcessMode = newSetup.processMode;
|
||||
|
||||
return SingleComponentEffect::setupProcessing (newSetup);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs, int32 numOuts)
|
||||
{
|
||||
if (numIns == 1 && numOuts == 1)
|
||||
{
|
||||
// the host wants Mono => Mono (or 1 channel -> 1 channel)
|
||||
if (SpeakerArr::getChannelCount (inputs[0]) == 1 &&
|
||||
SpeakerArr::getChannelCount (outputs[0]) == 1)
|
||||
{
|
||||
auto* bus = FCast<AudioBus> (audioInputs.at (0));
|
||||
if (bus)
|
||||
{
|
||||
// check if we are Mono => Mono, if not we need to recreate the busses
|
||||
if (bus->getArrangement () != inputs[0])
|
||||
{
|
||||
bus->setArrangement (inputs[0]);
|
||||
bus->setName (STR16 ("Mono In"));
|
||||
if (auto* busOut = FCast<AudioBus> (audioOutputs.at (0)))
|
||||
{
|
||||
busOut->setArrangement (outputs[0]);
|
||||
busOut->setName (STR16 ("Mono Out"));
|
||||
}
|
||||
}
|
||||
return kResultOk;
|
||||
}
|
||||
}
|
||||
// the host wants something else than Mono => Mono, in this case we are always Stereo =>
|
||||
// Stereo
|
||||
else
|
||||
{
|
||||
auto* bus = FCast<AudioBus> (audioInputs.at (0));
|
||||
if (bus)
|
||||
{
|
||||
tresult result = kResultFalse;
|
||||
|
||||
// the host wants 2->2 (could be LsRs -> LsRs)
|
||||
if (SpeakerArr::getChannelCount (inputs[0]) == 2 &&
|
||||
SpeakerArr::getChannelCount (outputs[0]) == 2)
|
||||
{
|
||||
bus->setArrangement (inputs[0]);
|
||||
bus->setName (STR16 ("Stereo In"));
|
||||
if (auto* busOut = FCast<AudioBus> (audioOutputs.at (0)))
|
||||
{
|
||||
busOut->setArrangement (outputs[0]);
|
||||
busOut->setName (STR16 ("Stereo Out"));
|
||||
}
|
||||
result = kResultTrue;
|
||||
}
|
||||
// the host want something different than 1->1 or 2->2 : in this case we want stereo
|
||||
else if (bus->getArrangement () != SpeakerArr::kStereo)
|
||||
{
|
||||
bus->setArrangement (SpeakerArr::kStereo);
|
||||
bus->setName (STR16 ("Stereo In"));
|
||||
if (auto* busOut = FCast<AudioBus> (audioOutputs.at (0)))
|
||||
{
|
||||
busOut->setArrangement (SpeakerArr::kStereo);
|
||||
busOut->setName (STR16 ("Stereo Out"));
|
||||
}
|
||||
|
||||
result = kResultFalse;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::canProcessSampleSize (int32 symbolicSampleSize)
|
||||
{
|
||||
if (symbolicSampleSize == kSample32)
|
||||
return kResultTrue;
|
||||
|
||||
// we support double processing
|
||||
if (symbolicSampleSize == kSample64)
|
||||
return kResultTrue;
|
||||
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
IPlugView* PLUGIN_API AGainSimple::createView (const char* name)
|
||||
{
|
||||
// someone wants my editor
|
||||
if (name && FIDStringsEqual (name, ViewType::kEditor))
|
||||
{
|
||||
auto* view = new VST3Editor (this, "view", "again.uidesc");
|
||||
return view;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::getMidiControllerAssignment (int32 busIndex, int16 /*midiChannel*/,
|
||||
CtrlNumber midiControllerNumber,
|
||||
ParamID& tag)
|
||||
{
|
||||
// we support for the Gain parameter all MIDI Channel but only first bus (there is only one!)
|
||||
if (busIndex == 0 && midiControllerNumber == kCtrlVolume)
|
||||
{
|
||||
tag = kGainId;
|
||||
return kResultTrue;
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
IController* AGainSimple::createSubController (UTF8StringPtr name,
|
||||
const IUIDescription* /*description*/,
|
||||
VST3Editor* /*editor*/)
|
||||
{
|
||||
if (UTF8StringView (name) == "MessageController")
|
||||
{
|
||||
auto* controller = new UIMessageController (this);
|
||||
addUIMessageController (controller);
|
||||
return controller;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::setEditorState (IBStream* state)
|
||||
{
|
||||
tresult result = kResultFalse;
|
||||
|
||||
int8 byteOrder;
|
||||
if ((result = state->read (&byteOrder, sizeof (int8))) != kResultTrue)
|
||||
return result;
|
||||
if ((result = state->read (defaultMessageText, 128 * sizeof (TChar))) != kResultTrue)
|
||||
return result;
|
||||
|
||||
// if the byteorder doesn't match, byte swap the text array ...
|
||||
if (byteOrder != BYTEORDER)
|
||||
{
|
||||
for (int32 i = 0; i < 128; i++)
|
||||
SWAP_16 (defaultMessageText[i])
|
||||
}
|
||||
|
||||
for (auto& uiMessageController : uiMessageControllers)
|
||||
uiMessageController->setMessageText (defaultMessageText);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::getEditorState (IBStream* state)
|
||||
{
|
||||
// here we can save UI settings for example
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
// as we save a Unicode string, we must know the byteorder when setState is called
|
||||
int8 byteOrder = BYTEORDER;
|
||||
if (streamer.writeInt8 (byteOrder) == false)
|
||||
return kResultFalse;
|
||||
|
||||
if (streamer.writeRaw (defaultMessageText, 128 * sizeof (TChar)) == false)
|
||||
return kResultFalse;
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::setParamNormalized (ParamID tag, ParamValue value)
|
||||
{
|
||||
// called from host to update our parameters state
|
||||
tresult result = SingleComponentEffect::setParamNormalized (tag, value);
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::getParamStringByValue (ParamID tag, ParamValue valueNormalized,
|
||||
String128 string)
|
||||
{
|
||||
return SingleComponentEffect::getParamStringByValue (tag, valueNormalized, string);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::getParamValueByString (ParamID tag, TChar* string,
|
||||
ParamValue& valueNormalized)
|
||||
{
|
||||
return SingleComponentEffect::getParamValueByString (tag, string, valueNormalized);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void AGainSimple::addUIMessageController (UIMessageController* controller)
|
||||
{
|
||||
uiMessageControllers.push_back (controller);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void AGainSimple::removeUIMessageController (UIMessageController* controller)
|
||||
{
|
||||
UIMessageControllerList::const_iterator it =
|
||||
std::find (uiMessageControllers.begin (), uiMessageControllers.end (), controller);
|
||||
if (it != uiMessageControllers.end ())
|
||||
uiMessageControllers.erase (it);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void AGainSimple::setDefaultMessageText (String128 text)
|
||||
{
|
||||
UString str (defaultMessageText, 128);
|
||||
str.assign (text, -1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
TChar* AGainSimple::getDefaultMessageText ()
|
||||
{
|
||||
return defaultMessageText;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API AGainSimple::queryInterface (const TUID iid, void** obj)
|
||||
{
|
||||
DEF_INTERFACE (IMidiMapping)
|
||||
return SingleComponentEffect::queryInterface (iid, obj);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
// UI size
|
||||
kEditorWidth = 350,
|
||||
kEditorHeight = 120
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
BEGIN_FACTORY_DEF (stringCompanyName, stringCompanyWeb, stringCompanyEmail)
|
||||
|
||||
//---First plug-in included in this factory-------
|
||||
// its kVstAudioEffectClass component
|
||||
DEF_CLASS2 (INLINE_UID (0xB9F9ADE1, 0xCD9C4B6D, 0xA57E61E3, 0x123535FD),
|
||||
PClassInfo::kManyInstances, // cardinality
|
||||
kVstAudioEffectClass, // the component category (do not change this)
|
||||
"AGainSimple VST3", // here the plug-in name (to be changed)
|
||||
0, // single component effects cannot be distributed so this is zero
|
||||
"Fx", // Subcategory for this plug-in (to be changed)
|
||||
FULL_VERSION_STR, // Plug-in version (to be changed)
|
||||
kVstVersionString, // the VST 3 SDK version (do not change this, always use this define)
|
||||
Steinberg::Vst::AGainSimple::createInstance)// function pointer called when this component should be instantiated
|
||||
|
||||
END_FACTORY
|
||||
@@ -0,0 +1,148 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/againsimple.h
|
||||
// Created by : Steinberg, 04/2005
|
||||
// Description : AGain Example for VST SDK 3.0
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
// must always come first
|
||||
#include "public.sdk/source/vst/vstsinglecomponenteffect.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
#include "public.sdk/source/vst/vstguieditor.h"
|
||||
#include "pluginterfaces/vst/ivstcontextmenu.h"
|
||||
#include "pluginterfaces/vst/ivstplugview.h"
|
||||
|
||||
#include "vstgui/plugin-bindings/vst3editor.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
template <typename T>
|
||||
class AGainUIMessageController;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// AGain as combined processor and controller
|
||||
//------------------------------------------------------------------------
|
||||
class AGainSimple : public SingleComponentEffect,
|
||||
public VSTGUI::VST3EditorDelegate,
|
||||
public IMidiMapping
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
using UIMessageController = AGainUIMessageController<AGainSimple>;
|
||||
using UTF8StringPtr = VSTGUI::UTF8StringPtr;
|
||||
using IUIDescription = VSTGUI::IUIDescription;
|
||||
using IController = VSTGUI::IController;
|
||||
using VST3Editor = VSTGUI::VST3Editor;
|
||||
|
||||
AGainSimple ();
|
||||
|
||||
static FUnknown* createInstance (void* /*context*/) { return (IAudioProcessor*)new AGainSimple; }
|
||||
|
||||
//---from IComponent-----------------------
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setActive (TBool state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API process (ProcessData& data) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API canProcessSampleSize (int32 symbolicSampleSize) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setupProcessing (ProcessSetup& newSetup) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs,
|
||||
int32 numOuts) SMTG_OVERRIDE;
|
||||
|
||||
//---from IEditController-------
|
||||
IPlugView* PLUGIN_API createView (const char* name) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setEditorState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getEditorState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setParamNormalized (ParamID tag, ParamValue value) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized,
|
||||
String128 string) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string,
|
||||
ParamValue& valueNormalized) SMTG_OVERRIDE;
|
||||
|
||||
//---from IMidiMapping-----------------
|
||||
tresult PLUGIN_API getMidiControllerAssignment (int32 busIndex, int16 channel,
|
||||
CtrlNumber midiControllerNumber,
|
||||
ParamID& tag) SMTG_OVERRIDE;
|
||||
|
||||
//---from VST3EditorDelegate-----------
|
||||
IController* createSubController (UTF8StringPtr name, const IUIDescription* description,
|
||||
VST3Editor* editor) SMTG_OVERRIDE;
|
||||
|
||||
//---Interface---------
|
||||
OBJ_METHODS (AGainSimple, SingleComponentEffect)
|
||||
tresult PLUGIN_API queryInterface (const TUID iid, void** obj) SMTG_OVERRIDE;
|
||||
REFCOUNT_METHODS (SingleComponentEffect)
|
||||
|
||||
//---Internal functions-------
|
||||
void addUIMessageController (UIMessageController* controller);
|
||||
void removeUIMessageController (UIMessageController* controller);
|
||||
void setDefaultMessageText (String128 text);
|
||||
TChar* getDefaultMessageText ();
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <typename SampleType>
|
||||
SampleType processAudio (SampleType** in, SampleType** out, int32 numChannels,
|
||||
int32 sampleFrames, float gain)
|
||||
{
|
||||
SampleType vuPPM = 0;
|
||||
|
||||
// in real plug-in it would be better to do dezippering to avoid jump (click) in gain value
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
int32 samples = sampleFrames;
|
||||
auto* ptrIn = (SampleType*)in[i];
|
||||
auto* ptrOut = (SampleType*)out[i];
|
||||
SampleType tmp;
|
||||
while (--samples >= 0)
|
||||
{
|
||||
// apply gain
|
||||
tmp = (*ptrIn++) * gain;
|
||||
(*ptrOut++) = tmp;
|
||||
|
||||
// check only positive values
|
||||
if (tmp > vuPPM)
|
||||
{
|
||||
vuPPM = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return vuPPM;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
private:
|
||||
// our model values
|
||||
float fGain;
|
||||
float fGainReduction;
|
||||
float fVuPPMOld;
|
||||
|
||||
int32 currentProcessMode;
|
||||
|
||||
bool bHalfGain;
|
||||
bool bBypass;
|
||||
|
||||
using UIMessageControllerList = std::vector<UIMessageController*>;
|
||||
UIMessageControllerList uiMessageControllers;
|
||||
|
||||
String128 defaultMessageText;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,159 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/againuimessagecontroller.h
|
||||
// Created by : Steinberg, 04/2005
|
||||
// Description : AGain UI Message Controller
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2022, 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 "vstgui/lib/iviewlistener.h"
|
||||
#include "vstgui/uidescription/icontroller.h"
|
||||
#include "public.sdk/source/vst/utility/stringconvert.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// AGainUIMessageController
|
||||
//------------------------------------------------------------------------
|
||||
template <typename ControllerType>
|
||||
class AGainUIMessageController : public VSTGUI::IController, public VSTGUI::ViewListenerAdapter
|
||||
{
|
||||
public:
|
||||
enum Tags
|
||||
{
|
||||
kSendMessageTag = 1000
|
||||
};
|
||||
|
||||
AGainUIMessageController (ControllerType* againController) : againController (againController), textEdit (nullptr)
|
||||
{
|
||||
}
|
||||
~AGainUIMessageController () override
|
||||
{
|
||||
if (textEdit)
|
||||
viewWillDelete (textEdit);
|
||||
againController->removeUIMessageController (this);
|
||||
}
|
||||
|
||||
void setMessageText (String128 msgText)
|
||||
{
|
||||
if (!textEdit)
|
||||
return;
|
||||
textEdit->setText (StringConvert::convert (msgText));
|
||||
}
|
||||
|
||||
private:
|
||||
using CControl = VSTGUI::CControl;
|
||||
using CView = VSTGUI::CView;
|
||||
using CTextEdit = VSTGUI::CTextEdit;
|
||||
using UTF8String = VSTGUI::UTF8String;
|
||||
using UIAttributes = VSTGUI::UIAttributes;
|
||||
using IUIDescription = VSTGUI::IUIDescription;
|
||||
|
||||
//--- from IControlListener ----------------------
|
||||
void valueChanged (CControl* /*pControl*/) override {}
|
||||
void controlBeginEdit (CControl* /*pControl*/) override {}
|
||||
void controlEndEdit (CControl* pControl) override
|
||||
{
|
||||
if (pControl->getTag () == kSendMessageTag)
|
||||
{
|
||||
if (pControl->getValueNormalized () > 0.5f)
|
||||
{
|
||||
againController->sendTextMessage (textEdit->getText ().data ());
|
||||
pControl->setValue (0.f);
|
||||
pControl->invalid ();
|
||||
|
||||
//---send a binary message
|
||||
if (IPtr<IMessage> message = owned (againController->allocateMessage ()))
|
||||
{
|
||||
message->setMessageID ("BinaryMessage");
|
||||
uint32 size = 100;
|
||||
char8 data[100];
|
||||
memset (data, 0, size * sizeof (char));
|
||||
// fill my data with dummy stuff
|
||||
for (uint32 i = 0; i < size; i++)
|
||||
data[i] = i;
|
||||
message->getAttributes ()->setBinary ("MyData", data, size);
|
||||
againController->sendMessage (message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- from IControlListener ----------------------
|
||||
//--- is called when a view is created -----
|
||||
CView* verifyView (CView* view, const UIAttributes& /*attributes*/,
|
||||
const IUIDescription* /*description*/) override
|
||||
{
|
||||
if (CTextEdit* te = dynamic_cast<CTextEdit*> (view))
|
||||
{
|
||||
// this allows us to keep a pointer of the text edit view
|
||||
textEdit = te;
|
||||
|
||||
// add this as listener in order to get viewWillDelete and viewLostFocus calls
|
||||
textEdit->registerViewListener (this);
|
||||
|
||||
// initialize it content
|
||||
textEdit->setText (
|
||||
StringConvert::convert (againController->getDefaultMessageText ()));
|
||||
}
|
||||
return view;
|
||||
}
|
||||
//--- from IViewListenerAdapter ----------------------
|
||||
//--- is called when a view will be deleted: the editor is closed -----
|
||||
void viewWillDelete (CView* view) override
|
||||
{
|
||||
if (dynamic_cast<CTextEdit*> (view) == textEdit)
|
||||
{
|
||||
textEdit->unregisterViewListener (this);
|
||||
textEdit = nullptr;
|
||||
}
|
||||
}
|
||||
//--- is called when the view is loosing the focus -----------------
|
||||
void viewLostFocus (CView* view) override
|
||||
{
|
||||
if (dynamic_cast<CTextEdit*> (view) == textEdit)
|
||||
{
|
||||
// save the last content of the text edit view
|
||||
const auto& text = textEdit->getText ();
|
||||
auto utf16Text = StringConvert::convert (text.getString ());
|
||||
againController->setDefaultMessageText (utf16Text.data ());
|
||||
}
|
||||
}
|
||||
ControllerType* againController;
|
||||
CTextEdit* textEdit;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
@@ -0,0 +1,35 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again/source/version.h
|
||||
// Created by : Steinberg, 01/2008
|
||||
// Description : Example of handle the versioning and copyright info of again plug-in
|
||||
// used for the resources (RC file for example)
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/fplatform.h"
|
||||
|
||||
// Plain project version file generated by cmake
|
||||
#include "projectversion.h"
|
||||
|
||||
#define stringOriginalFilename "again.vst3"
|
||||
#if SMTG_PLATFORM_64
|
||||
#define stringFileDescription "AGain VST3-SDK (64Bit)"
|
||||
#else
|
||||
#define stringFileDescription "AGain VST3-SDK"
|
||||
#endif
|
||||
#define stringCompanyWeb "http://www.steinberg.net"
|
||||
#define stringCompanyEmail "mailto:info@steinberg.de"
|
||||
#define stringCompanyName "Steinberg Media Technologies"
|
||||
#define stringLegalCopyright "© 2025 Steinberg Media Technologies"
|
||||
#define stringLegalTrademarks "VST is a trademark of Steinberg Media Technologies GmbH"
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.25.0)
|
||||
|
||||
project(smtg-vst3-again
|
||||
VERSION ${vstsdk_VERSION}.0
|
||||
DESCRIPTION "Steinberg VST 3 AGain AAX example"
|
||||
)
|
||||
|
||||
if(NOT SMTG_AAX_SDK_PATH OR NOT SMTG_ENABLE_VSTGUI_SUPPORT)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(SMTG_AddAAXLibrary)
|
||||
|
||||
set(again_sources
|
||||
source/againaax.cpp
|
||||
../again/source/again.cpp
|
||||
../again/source/again.h
|
||||
../again/source/againcids.h
|
||||
../again/source/againcontroller.cpp
|
||||
../again/source/againcontroller.h
|
||||
../again/source/againentry.cpp
|
||||
../again/source/againparamids.h
|
||||
../again/source/againprocess.h
|
||||
../again/source/againsidechain.cpp
|
||||
../again/source/againsidechain.h
|
||||
../again/source/againuimessagecontroller.h
|
||||
../again/source/version.h
|
||||
../again/resource/again.uidesc
|
||||
)
|
||||
|
||||
set(target again-aax)
|
||||
smtg_add_aaxplugin(${target} ${again_sources})
|
||||
smtg_target_configure_version_file(${target})
|
||||
set_target_properties(${target}
|
||||
PROPERTIES
|
||||
${SDK_IDE_PLUGIN_EXAMPLES_FOLDER}
|
||||
)
|
||||
target_include_directories(${target}
|
||||
PUBLIC
|
||||
${SDK_ROOT}/public.sdk/samples/vst/again/source
|
||||
)
|
||||
|
||||
target_compile_features(${target}
|
||||
PUBLIC
|
||||
cxx_std_17
|
||||
)
|
||||
|
||||
target_link_libraries(${target}
|
||||
PRIVATE
|
||||
sdk
|
||||
vstgui_support
|
||||
aax_wrapper
|
||||
)
|
||||
smtg_target_add_plugin_resources(${target}
|
||||
RESOURCES
|
||||
../again/resource/again.uidesc
|
||||
../again/resource/background.png
|
||||
../again/resource/slider_background.png
|
||||
../again/resource/slider_handle.png
|
||||
../again/resource/slider_handle_2.0x.png
|
||||
../again/resource/vu_on.png
|
||||
../again/resource/vu_off.png
|
||||
)
|
||||
|
||||
if(SMTG_MAC)
|
||||
smtg_target_set_bundle(${target}
|
||||
BUNDLE_IDENTIFIER "com.steinberg.vst3.${target}"
|
||||
INFOPLIST "${CMAKE_CURRENT_LIST_DIR}/../again/mac/Info.plist" PREPROCESS
|
||||
)
|
||||
elseif(SMTG_WIN)
|
||||
target_sources(${target}
|
||||
PRIVATE
|
||||
../again/resource/again.rc
|
||||
)
|
||||
# remove warnings
|
||||
if(NOT MINGW)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
endif(NOT MINGW)
|
||||
endif(SMTG_MAC)
|
||||
@@ -0,0 +1,19 @@
|
||||
# AGain AAX
|
||||
|
||||
## Introduction
|
||||
|
||||
AGain AAX is the AAX version of the AGain plug-in by just adding a file (public.sdk/samples/vst/again_aax/source/againaax.cpp). It defines a mono and a stereo variant with a MIDI input.
|
||||
|
||||
|
||||
> See also: [VST 3 - AAX Wrapper]((https://steinbergmedia.github.io/vst3_dev_portal/pages/What+is+the+VST+3+SDK/Wrappers/AAX+Wrapper.html) and [Online Documentation](https://steinbergmedia.github.io/vst3_dev_portal/pages/What+is+the+VST+3+SDK/Plug-in+Examples.html#again).
|
||||
|
||||
## Getting Started
|
||||
|
||||
This plug-in is part of the VST 3 SDK package. It is created with the VST 3 SDK root project.
|
||||
|
||||
> See the top-level README of the VST 3 SDK: https://github.com/steinbergmedia/vst3sdk.git
|
||||
|
||||
## Getting Help
|
||||
|
||||
* Read through the SDK documentation on the **[VST 3 Developer Portal](https://steinbergmedia.github.io/vst3_dev_portal/pages/index.html)**
|
||||
* Ask some real people in the official **[VST 3 Developer Forum](https://forums.steinberg.net/c/developer/103)**
|
||||
@@ -0,0 +1,117 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again_aax/source/againaax.cpp
|
||||
// Created by : Steinberg, 03/2016
|
||||
// Description : AGain AAX Example for VST SDK 3
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "public.sdk/source/vst/aaxwrapper/aaxwrapper_description.h"
|
||||
|
||||
#include "againcids.h"
|
||||
#include "againparamids.h"
|
||||
#include "pluginterfaces/base/futils.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#if 0 // for additional outputs
|
||||
AAX_Aux_Desc effAux_stereo[] =
|
||||
{
|
||||
// name, channel count
|
||||
{ "AGain AUX2", 2 },
|
||||
{ nullptr }
|
||||
};
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#if 1 // MIDI inputs for instruments or Fx with MIDI input
|
||||
AAX_MIDI_Desc effMIDI[] =
|
||||
{
|
||||
// port name, channel mask
|
||||
{ "AGain", 0xffff },
|
||||
{ nullptr }
|
||||
};
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Input/Output meters
|
||||
AAX_Meter_Desc effMeters[] =
|
||||
{
|
||||
// not used { "Input", CCONST ('A', 'G', 'I', 'n'), 0 /*AAX_eMeterOrientation_Default*/, 0 /*AAX_eMeterType_Input*/ },
|
||||
{ "Output", kVuPPMId, 0 /*AAX_eMeterOrientation_Default*/, 1 /*AAX_eMeterType_Output*/ },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
AAX_Plugin_Desc effPlugins[] = {
|
||||
// effect-ID, name,
|
||||
// Native ID, AudioSuite ID,
|
||||
// InChannels, OutChannels, InSideChain channels,
|
||||
// MIDI, Aux,
|
||||
// Meters
|
||||
// Latency
|
||||
// note: IDs must be unique across plugins
|
||||
|
||||
// Mono variant
|
||||
{"com.steinberg.again.mono",
|
||||
"AGain",
|
||||
CCONST ('A', 'G', 'N', '1'),
|
||||
CCONST ('A', 'G', 'A', '1'),
|
||||
1, /*mInputChannels*/
|
||||
1, /*mOutputChannels*/
|
||||
0, /*mSideChainInputChannels*/
|
||||
effMIDI, /*effMIDI*/
|
||||
nullptr, /*effAux*/
|
||||
effMeters, /*effMeters*/
|
||||
0 /*Latency*/
|
||||
},
|
||||
|
||||
// Stereo variant
|
||||
{"com.steinberg.again.stereo",
|
||||
"AGain",
|
||||
CCONST ('A', 'G', 'N', '2'),
|
||||
CCONST ('A', 'G', 'A', '2'),
|
||||
2, /*mInputChannels*/
|
||||
2, /*mOutputChannels*/
|
||||
0, /*mSideChainInputChannels*/
|
||||
effMIDI, /*effMIDI*/
|
||||
nullptr, /*effAux*/
|
||||
effMeters, /*effMeters*/
|
||||
0 /*Latency*/
|
||||
},
|
||||
|
||||
{nullptr}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
AAX_Effect_Desc effDesc = {
|
||||
"Steinberg", // manufacturer
|
||||
"AGain", // product
|
||||
CCONST ('S', 'M', 'T', 'G'), // manufacturer ID
|
||||
CCONST ('A', 'G', 'S', 'B'), // product ID
|
||||
AGainVST3Category, // VST category (define againcids.h)
|
||||
{0}, // VST3 class ID (set later)
|
||||
1, // version
|
||||
nullptr, // no pagetable file "again.xml",
|
||||
effPlugins,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// this drag's in all the craft from the AAX library
|
||||
int* forceLinkAAXWrapper = &AAXWrapper_linkAnchor;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
AAX_Effect_Desc* AAXWrapper_GetDescription ()
|
||||
{
|
||||
// cannot initialize in global descriptor, and it might be link order dependent
|
||||
memcpy (effDesc.mVST3PluginID, (const char*)Steinberg::Vst::AGainProcessorUID,
|
||||
sizeof (effDesc.mVST3PluginID));
|
||||
return &effDesc;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
include(SMTG_AddVST3AuV3)
|
||||
|
||||
if(SMTG_MAC AND SMTG_ENABLE_VSTGUI_SUPPORT)
|
||||
if(XCODE)
|
||||
set(again_mac_app_sources
|
||||
"macOS/Sources/ViewController.m"
|
||||
"macOS/Sources/ViewController.h"
|
||||
"macOS/Sources/AppDelegate.m"
|
||||
"macOS/Sources/AppDelegate.h"
|
||||
"audiounitconfig.h"
|
||||
)
|
||||
|
||||
set(again_ios_app_sources
|
||||
"iOS/Sources/ViewController.m"
|
||||
"iOS/Sources/ViewController.h"
|
||||
"iOS/Sources/AppDelegate.m"
|
||||
"iOS/Sources/AppDelegate.h"
|
||||
"iOS/Sources/main.mm"
|
||||
"audiounitconfig.h"
|
||||
)
|
||||
|
||||
set(again_mac_app_ui_resources
|
||||
"macOS/Resources/Base.lproj/Main.storyboard"
|
||||
"macOS/Resources/again.icns"
|
||||
"Shared/drumLoop.wav"
|
||||
)
|
||||
|
||||
set(again_ios_app_ui_resources
|
||||
"iOS/Resources/Base.lproj/LaunchScreen.storyboard"
|
||||
"iOS/Resources/Base.lproj/Main.storyboard"
|
||||
"iOS/Resources/Assets.xcassets"
|
||||
"Shared/drumLoop.wav"
|
||||
)
|
||||
|
||||
# --------------------------------------------------------------------------------------------------------
|
||||
# macOS target
|
||||
# --------------------------------------------------------------------------------------------------------
|
||||
smtg_add_auv3_app(again_auv3_macos "macOS" "AGain AUV3 macOS" "com.steinberg.sdk.auv3.againmac" audiounitconfig.h "macOS/again.entitlements" "${again_mac_app_sources}" "${again_mac_app_ui_resources}" "macOS/Resources/Info.plist" "Shared/Info.plist" again)
|
||||
|
||||
# --------------------------------------------------------------------------------------------------------
|
||||
# iOS target
|
||||
# --------------------------------------------------------------------------------------------------------
|
||||
if(SMTG_ENABLE_IOS_TARGETS)
|
||||
smtg_add_auv3_app(again_auv3_ios "iOS" "AGain AUV3 iOS" "com.steinberg.sdk.auv3.againios" "audiounitconfig.h" "iOS/again.entitlements" "${again_ios_app_sources}" "${again_ios_app_ui_resources}" "iOS/Resources/Info.plist" "Shared/Info.plist" again_ios)
|
||||
endif(SMTG_ENABLE_IOS_TARGETS)
|
||||
endif(XCODE)
|
||||
endif(SMTG_MAC AND SMTG_ENABLE_VSTGUI_SUPPORT)
|
||||
@@ -0,0 +1,19 @@
|
||||
# AGain AUv3
|
||||
|
||||
## Introduction
|
||||
|
||||
AGain AUv3 is the AUv3 version of the AGain plug-in for macOS and iOS.
|
||||
|
||||
|
||||
> See also: [VST 3 - AudioUnit v3 Wrapper](https://steinbergmedia.github.io/vst3_dev_portal/pages/What+is+the+VST+3+SDK/Wrappers/AUv3+Wrapper.html) and [Online Documentation](https://steinbergmedia.github.io/vst3_dev_portal/pages/What+is+the+VST+3+SDK/Plug-in+Examples.html#again).
|
||||
|
||||
## Getting Started
|
||||
|
||||
This plug-in is part of the VST 3 SDK package. It is created with the VST 3 SDK root project.
|
||||
|
||||
> See the top-level README of the VST 3 SDK: https://github.com/steinbergmedia/vst3sdk.git
|
||||
|
||||
## Getting Help
|
||||
|
||||
* Read through the SDK documentation on the **[VST 3 Developer Portal](https://steinbergmedia.github.io/vst3_dev_portal/pages/index.html)**
|
||||
* Ask some real people in the official **[VST 3 Developer Forum](https://forums.steinberg.net/c/developer/103)**
|
||||
@@ -0,0 +1,61 @@
|
||||
<?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>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>AUv3WrapperExtension</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>NSExtensionServiceRoleType</key>
|
||||
<string>NSExtensionServiceRoleTypeEditor</string>
|
||||
<key>AudioComponents</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>description</key>
|
||||
<string>kAUcomponentDescription</string>
|
||||
<key>manufacturer</key>
|
||||
<string>kAUcomponentManufacturer1</string>
|
||||
<key>name</key>
|
||||
<string>kAUcomponentName</string>
|
||||
<key>sandboxSafe</key>
|
||||
<true/>
|
||||
<key>subtype</key>
|
||||
<string>kAUcomponentSubType1</string>
|
||||
<key>tags</key>
|
||||
<array>
|
||||
<string>kAUcomponentTag</string>
|
||||
</array>
|
||||
<key>type</key>
|
||||
<string>kAUcomponentType1</string>
|
||||
<key>version</key>
|
||||
<integer>kAUcomponentVersion</integer>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.AudioUnit-UI</string>
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>AUv3WrapperViewController</string>
|
||||
</dict>
|
||||
<key>SupportedNumChannels</key>
|
||||
<string>kSupportedNumChannels</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,74 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/samples/vst/again_auv3/audiounitconfig.h
|
||||
// Created by : Steinberg, 07/2017.
|
||||
// Description : VST 3 - AUv3Wrapper
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// AUWRAPPER_CHANGE: change all corresponding entries according to your plugin
|
||||
|
||||
// The specific variant of the Audio Unit app extension.
|
||||
// The four possible types and their values are:
|
||||
// Effect (aufx), Generator (augn), Instrument (aumu), and Music Effect (aufm)
|
||||
#define kAUcomponentType 'aufx'
|
||||
#define kAUcomponentType1 aufx
|
||||
|
||||
// A subtype code (unique ID) for the audio unit, such as gav3.
|
||||
// This value must be exactly 4 alphanumeric characters
|
||||
#define kAUcomponentSubType 'gav3'
|
||||
#define kAUcomponentSubType1 gav3
|
||||
|
||||
// A manufacturer code for the audio unit, such as Aaud.
|
||||
// This value must be exactly 4 alphanumeric characters
|
||||
#define kAUcomponentManufacturer 'Stgb'
|
||||
#define kAUcomponentManufacturer1 Stgb
|
||||
|
||||
// A product name for the audio unit
|
||||
#define kAUcomponentDescription AUv3WrapperExtension
|
||||
|
||||
// The full name of the audio unit.
|
||||
// This is derived from the manufacturer and description key values
|
||||
#define kAUcomponentName Steinberg: AGainv3
|
||||
|
||||
// Displayed Tags
|
||||
#define kAUcomponentTag Effects
|
||||
|
||||
// A version number for the Audio Unit app extension (decimal value of hexadecimal representation with zeros between subversions)
|
||||
// Hexadecimal indexes representing: [0] = main version, [1] = 0 = dot, [2] = sub version, [3] = 0 = dot, [4] = sub-sub version,
|
||||
// e.g. 1.0.0 == 0x10000 == 65536, 1.2.3 = 0x10203 = 66051
|
||||
#define kAUcomponentVersion 65536
|
||||
|
||||
// Supported number of channels of your audio unit.
|
||||
// Integer indexes representing: [0] = input count, [1] = output count, [2] = 2nd input count,
|
||||
// [3]=2nd output count, etc.
|
||||
// e.g. 1122 == config1: [mono input, mono output], config2: [stereo input, stereo output]
|
||||
// see channelCapabilities for discussion
|
||||
#define kSupportedNumChannels 1122
|
||||
|
||||
// The preview audio file name.
|
||||
// To add your own custom audio file (for standalone effects), add an audio file to the project (AUv3WrappermacOS and AUv3WrapperiOS targets) and
|
||||
// enter the file name here
|
||||
#define kAudioFileName "drumLoop"
|
||||
|
||||
// The preview audio file format.
|
||||
// To add your own custom audio file (for standalone effects), add an audio file to the project (AUv3WrappermacOS and AUv3WrapperiOS targets) and
|
||||
// enter the file format here
|
||||
#define kAudioFileFormat "wav"
|
||||
|
||||
// componentFlags (leave at 0)
|
||||
#define kAUcomponentFlags 0
|
||||
|
||||
// componentFlagsMask (leave at 0)
|
||||
#define kAUcomponentFlagsMask 0
|
||||
|
||||
// class name for the application delegate
|
||||
#define kAUapplicationDelegateClassName AppDelegate
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "83.5x83.5",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ios-marketing",
|
||||
"size" : "1024x1024",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="NO" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<development version="7000" identifier="xcode"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
|
||||
</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" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</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>
|
||||
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="NO" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<development version="7000" identifier="xcode"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" horizontalCompressionResistancePriority="751" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="awX-J2-WjW">
|
||||
<rect key="frame" x="154.5" y="28" width="66" height="33"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="66" id="mxM-10-2ZT"/>
|
||||
<constraint firstAttribute="height" constant="33" id="oes-CK-W5k"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="22"/>
|
||||
<state key="normal" title="Play"/>
|
||||
<connections>
|
||||
<action selector="togglePlay:" destination="BYZ-38-t0r" eventType="touchUpInside" id="L06-Zo-ks1"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view contentMode="scaleToFill" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="65L-bj-7ja">
|
||||
<rect key="frame" x="0.0" y="69" width="375" height="598"/>
|
||||
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
|
||||
</view>
|
||||
<button opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DO8-U6-Fin">
|
||||
<rect key="frame" x="16" y="20" width="59" height="30"/>
|
||||
<state key="normal" title="Load file"/>
|
||||
<connections>
|
||||
<action selector="loadFile:" destination="BYZ-38-t0r" eventType="touchUpInside" id="Mt3-w7-QRD"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="65L-bj-7ja" firstAttribute="top" secondItem="awX-J2-WjW" secondAttribute="bottom" constant="8" id="0pm-tA-HHv"/>
|
||||
<constraint firstItem="DO8-U6-Fin" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" id="4k9-78-uI8"/>
|
||||
<constraint firstItem="65L-bj-7ja" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="8DK-Kt-1aI"/>
|
||||
<constraint firstItem="DO8-U6-Fin" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="B7m-Ac-uWD"/>
|
||||
<constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="65L-bj-7ja" secondAttribute="bottom" id="MGd-GL-poe"/>
|
||||
<constraint firstItem="awX-J2-WjW" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="cDh-8H-Wf2"/>
|
||||
<constraint firstItem="awX-J2-WjW" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" constant="8" symbolic="YES" id="pzr-zC-F3E"/>
|
||||
<constraint firstAttribute="trailing" secondItem="65L-bj-7ja" secondAttribute="trailing" id="yaU-Up-alA"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="auContainerView" destination="65L-bj-7ja" id="wVS-br-3wc"/>
|
||||
<outlet property="playButton" destination="awX-J2-WjW" id="yBe-iR-A9Z"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="301.60000000000002" y="270.31484257871068"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?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>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>AGainv3</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>NSAppleMusicUsageDescription</key>
|
||||
<string>Import an audio file for preview</string>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>SupportedNumChannels</key>
|
||||
<string>kSupportedNumChannels</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,23 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/samples/vst/again_auv3/iOS/Sources/AppDelegate.h
|
||||
// Created by : Steinberg, 07/2017.
|
||||
// Description : VST 3 - AUv3Wrapper
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,44 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/samples/vst/again_auv3/iOS/Sources/AppDelegate.m
|
||||
// Created by : Steinberg, 07/2017.
|
||||
// Description : VST 3 - AUv3Wrapper
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
@interface AppDelegate ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application {
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application {
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application {
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,22 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/samples/vst/again_auv3/iOS/Sources/ViewController.h
|
||||
// Created by : Steinberg, 07/2017.
|
||||
// Description : VST 3 - AUv3Wrapper
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MediaPlayer/MediaPlayer.h>
|
||||
|
||||
@interface ViewController : UIViewController <MPMediaPickerControllerDelegate>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,142 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/samples/vst/again_auv3/iOS/Sources/ViewController.m
|
||||
// Created by : Steinberg, 07/2017.
|
||||
// Description : VST 3 - AUv3Wrapper
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#import "ViewController.h"
|
||||
#import <CoreAudioKit/AUViewController.h>
|
||||
#import "public.sdk/source/vst/auv3wrapper/Shared/AUv3AudioEngine.h"
|
||||
#import "public.sdk/source/vst/auv3wrapper/Shared/AUv3Wrapper.h"
|
||||
|
||||
@class AUv3WrapperViewController;
|
||||
|
||||
@interface ViewController () {
|
||||
// Button for playback
|
||||
IBOutlet UIButton *playButton;
|
||||
|
||||
// Container for our custom view.
|
||||
__weak IBOutlet UIView *auContainerView;
|
||||
|
||||
// Audio playback engine.
|
||||
AUv3AudioEngine *audioEngine;
|
||||
|
||||
// Container for the custom view.
|
||||
AUv3WrapperViewController *auV3ViewController;
|
||||
}
|
||||
|
||||
-(IBAction)togglePlay:(id)sender;
|
||||
-(IBAction)loadFile:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ViewController
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
[self embedPlugInView];
|
||||
|
||||
AudioComponentDescription desc;
|
||||
|
||||
desc.componentType = kAUcomponentType;
|
||||
desc.componentSubType = kAUcomponentSubType;
|
||||
desc.componentManufacturer = kAUcomponentManufacturer;
|
||||
desc.componentFlags = kAUcomponentFlags;
|
||||
desc.componentFlagsMask = kAUcomponentFlagsMask;
|
||||
|
||||
[AUAudioUnit registerSubclass: AUv3Wrapper.class asComponentDescription:desc name:@"Local AUv3" version: UINT32_MAX];
|
||||
|
||||
audioEngine = [[AUv3AudioEngine alloc] initWithComponentType:desc.componentType];
|
||||
|
||||
[audioEngine loadAudioUnitWithComponentDescription:desc completion:^{
|
||||
auV3ViewController.audioUnit = (AUv3Wrapper*)audioEngine.currentAudioUnit;
|
||||
|
||||
NSString* fileName = @kAudioFileName;
|
||||
NSString* fileFormat = @kAudioFileFormat;
|
||||
NSURL* fileURL = [[NSBundle mainBundle] URLForResource:fileName withExtension:fileFormat];
|
||||
NSError* error = [audioEngine loadAudioFile:fileURL];
|
||||
if (error)
|
||||
{
|
||||
NSLog (@"Error setting up audio or midi file: %@", [error description]);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (void)embedPlugInView {
|
||||
NSURL *builtInPlugInURL = [[NSBundle mainBundle] builtInPlugInsURL];
|
||||
NSURL *pluginURL = [builtInPlugInURL URLByAppendingPathComponent: @"AUv3WrapperiOSExtension.appex"];
|
||||
NSBundle *appExtensionBundle = [NSBundle bundleWithURL: pluginURL];
|
||||
|
||||
auV3ViewController = [[AUv3WrapperViewController alloc] initWithNibName: @"AUv3WrapperViewController" bundle: appExtensionBundle];
|
||||
|
||||
// Present the view controller's view.
|
||||
UIView *view = auV3ViewController.view;
|
||||
view.frame = auContainerView.bounds;
|
||||
|
||||
[auContainerView addSubview: view];
|
||||
|
||||
view.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat: @"H:|-[view]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)];
|
||||
[auContainerView addConstraints: constraints];
|
||||
|
||||
constraints = [NSLayoutConstraint constraintsWithVisualFormat: @"V:|-[view]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)];
|
||||
[auContainerView addConstraints: constraints];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
-(IBAction)loadFile:(id)sender {
|
||||
MPMediaPickerController *soundPicker=[[MPMediaPickerController alloc]
|
||||
initWithMediaTypes:MPMediaTypeAnyAudio];
|
||||
soundPicker.delegate=self;
|
||||
soundPicker.allowsPickingMultipleItems=NO; // You can set it to yes for multiple selection
|
||||
[self presentViewController:soundPicker animated:YES completion:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
-(void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:
|
||||
(MPMediaItemCollection *)mediaItemCollection
|
||||
{
|
||||
MPMediaItem *item = [[mediaItemCollection items] objectAtIndex:0]; // For multiple you can iterate iTems array
|
||||
NSURL *url = [item valueForProperty:MPMediaItemPropertyAssetURL];
|
||||
[mediaPicker dismissViewControllerAnimated:YES completion:nil];
|
||||
NSError* error = [audioEngine loadAudioFile:url];
|
||||
if (error != nil)
|
||||
{
|
||||
NSLog(@"something went wrong");
|
||||
}
|
||||
}
|
||||
|
||||
- (void) mediaPickerDidCancel: (MPMediaPickerController *) mediaPicker
|
||||
{
|
||||
[mediaPicker dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
-(IBAction)togglePlay:(id)sender {
|
||||
BOOL isPlaying = [audioEngine startStop];
|
||||
|
||||
[playButton setTitle: isPlaying ? @"Stop" : @"Play" forState: UIControlStateNormal];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,26 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/samples/vst/again_auv3/iOS/Sources/main.mm
|
||||
// Created by : Steinberg, 07/2017.
|
||||
// Description : VST 3 - AUv3Wrapper
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
return UIApplicationMain (argc, argv, nil, NSStringFromClass ([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?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>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Application-->
|
||||
<scene sceneID="JPo-4y-FX3">
|
||||
<objects>
|
||||
<application id="hnw-xV-0zn" sceneMemberID="viewController">
|
||||
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||
<items>
|
||||
<menuItem title="AUv3App" id="1Xt-HY-uBw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="AUv3App" systemMenu="apple" id="uQy-DD-JDr">
|
||||
<items>
|
||||
<menuItem title="About AUV3App" id="5kV-Vb-QxS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
|
||||
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
||||
<menuItem title="Services" id="NMo-om-nkz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
||||
<menuItem title="Hide AUV3App" keyEquivalent="h" id="Olw-nP-bQN">
|
||||
<connections>
|
||||
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="Kd2-mp-pUS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
||||
<menuItem title="Quit AUV3App" keyEquivalent="q" id="4sb-4s-VLi">
|
||||
<connections>
|
||||
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" tag="123" id="dMs-cI-mzQ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="File" id="bib-Uj-vzu">
|
||||
<items>
|
||||
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
|
||||
<connections>
|
||||
<action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="aUF-d1-5bR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="R4o-n2-Eq4">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
|
||||
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Help" id="wpr-3q-Mcd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
|
||||
<items>
|
||||
<menuItem title="AUv3LFO2 Help" keyEquivalent="?" id="FKE-Sm-Kum">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</application>
|
||||
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="75" y="0.0"/>
|
||||
</scene>
|
||||
<!--Window Controller-->
|
||||
<scene sceneID="R2V-B0-nI4">
|
||||
<objects>
|
||||
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
|
||||
<window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<rect key="contentRect" x="0.0" y="757" width="480" height="270"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="B8D-0N-5wS" id="j2h-An-kEE"/>
|
||||
</connections>
|
||||
</window>
|
||||
<connections>
|
||||
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
|
||||
</connections>
|
||||
</windowController>
|
||||
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="75" y="250"/>
|
||||
</scene>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="hIz-AP-VOD">
|
||||
<objects>
|
||||
<viewController id="XfG-lQ-9wD" customClass="ViewController" sceneMemberID="viewController">
|
||||
<view key="view" wantsLayer="YES" id="m2S-Jp-Qdl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="364"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kkG-5b-ojC">
|
||||
<rect key="frame" x="207" y="316" width="66" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Play" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="gCD-Et-Q6x">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="togglePlay:" target="XfG-lQ-9wD" id="oSe-db-zgP"/>
|
||||
</connections>
|
||||
</button>
|
||||
<customView wantsLayer="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6J0-ZM-W9c">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="323"/>
|
||||
</customView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="kkG-5b-ojC" firstAttribute="centerX" secondItem="m2S-Jp-Qdl" secondAttribute="centerX" id="5h0-Ry-y2J"/>
|
||||
<constraint firstItem="kkG-5b-ojC" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" constant="20" id="J8K-Ne-pVq"/>
|
||||
<constraint firstItem="6J0-ZM-W9c" firstAttribute="top" secondItem="kkG-5b-ojC" secondAttribute="bottom" id="RAO-aF-aJn"/>
|
||||
<constraint firstItem="6J0-ZM-W9c" firstAttribute="leading" secondItem="m2S-Jp-Qdl" secondAttribute="leading" id="bHR-tH-jff"/>
|
||||
<constraint firstAttribute="trailing" secondItem="6J0-ZM-W9c" secondAttribute="trailing" id="d6h-Oq-iH2"/>
|
||||
<constraint firstAttribute="bottom" secondItem="6J0-ZM-W9c" secondAttribute="bottom" id="jg2-r2-1A9"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="containerView" destination="6J0-ZM-W9c" id="j60-iC-0OX"/>
|
||||
<outlet property="playButton" destination="kkG-5b-ojC" id="lCN-dZ-Vtx"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="75" y="702"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>again</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2024 Steinberg Media Technologies. All rights reserved.</string>
|
||||
<key>NSMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>SupportedNumChannels</key>
|
||||
<string>kSupportedNumChannels</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,20 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/samples/vst/again_auv3/macOS/Sources/AppDelegate.h
|
||||
// Created by : Steinberg, 07/2017.
|
||||
// Description : VST 3 - AUv3Wrapper
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
@end
|
||||
@@ -0,0 +1,32 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/samples/vst/again_auv3/macOS/Sources/AppDelegate.m
|
||||
// Created by : Steinberg, 07/2017.
|
||||
// Description : VST 3 - AUv3Wrapper
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)aNotification {
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/samples/vst/again_auv3/macOS/Sources/ViewController.h
|
||||
// Created by : Steinberg, 07/2017.
|
||||
// Description : VST 3 - AUv3Wrapper
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface ViewController : NSViewController <NSWindowDelegate>
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/samples/vst/again_auv3/macOS/Sources/ViewController.m
|
||||
// Created by : Steinberg, 07/2017.
|
||||
// Description : VST 3 - AUv3Wrapper
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#import "ViewController.h"
|
||||
#import <CoreAudioKit/AUViewController.h>
|
||||
#import "public.sdk/source/vst/auv3wrapper/Shared/AUv3AudioEngine.h"
|
||||
#import "public.sdk/source/vst/auv3wrapper/Shared/AUv3Wrapper.h"
|
||||
|
||||
@class AUv3WrapperViewController;
|
||||
|
||||
@interface ViewController ()
|
||||
{
|
||||
// Button for playback
|
||||
IBOutlet NSButton* playButton;
|
||||
|
||||
AUv3AudioEngine* audioEngine;
|
||||
|
||||
// Container for the custom view.
|
||||
AUv3WrapperViewController* auV3ViewController;
|
||||
}
|
||||
|
||||
@property IBOutlet NSView *containerView;
|
||||
-(IBAction)togglePlay:(id)sender;
|
||||
-(void)handleMenuSelection:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ViewController
|
||||
//------------------------------------------------------------------------
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
[self embedPlugInView];
|
||||
|
||||
AudioComponentDescription desc;
|
||||
|
||||
desc.componentType = kAUcomponentType;
|
||||
desc.componentSubType = kAUcomponentSubType;
|
||||
desc.componentManufacturer = kAUcomponentManufacturer;
|
||||
desc.componentFlags = kAUcomponentFlags;
|
||||
desc.componentFlagsMask = kAUcomponentFlagsMask;
|
||||
|
||||
if (desc.componentType == 'aufx' || desc.componentType == 'aumf')
|
||||
[self addFileMenuEntry];
|
||||
|
||||
[AUAudioUnit registerSubclass: AUv3Wrapper.class asComponentDescription:desc name:@"Local AUv3" version: UINT32_MAX];
|
||||
|
||||
audioEngine = [[AUv3AudioEngine alloc] initWithComponentType:desc.componentType];
|
||||
|
||||
[audioEngine loadAudioUnitWithComponentDescription:desc completion:^{
|
||||
auV3ViewController.audioUnit = (AUv3Wrapper*)audioEngine.currentAudioUnit;
|
||||
|
||||
NSString* fileName = @kAudioFileName;
|
||||
NSString* fileFormat = @kAudioFileFormat;
|
||||
NSURL* fileURL = [[NSBundle mainBundle] URLForResource:fileName withExtension:fileFormat];
|
||||
NSError* error = [audioEngine loadAudioFile:fileURL];
|
||||
if (error)
|
||||
{
|
||||
NSLog (@"Error setting up audio or midi file: %@", [error description]);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
- (void)embedPlugInView
|
||||
{
|
||||
NSURL *builtInPlugInURL = [[NSBundle mainBundle] builtInPlugInsURL];
|
||||
NSURL *pluginURL = [builtInPlugInURL URLByAppendingPathComponent: @"vst3plugin.appex"];
|
||||
NSBundle *appExtensionBundle = [NSBundle bundleWithURL: pluginURL];
|
||||
|
||||
auV3ViewController = [[AUv3WrapperViewController alloc] initWithNibName: @"AUv3WrapperViewController" bundle: appExtensionBundle];
|
||||
|
||||
// Present the view controller's view.
|
||||
NSView *view = auV3ViewController.view;
|
||||
view.frame = _containerView.bounds;
|
||||
|
||||
[_containerView addSubview: view];
|
||||
|
||||
view.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat: @"H:|-[view]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)];
|
||||
[_containerView addConstraints: constraints];
|
||||
|
||||
constraints = [NSLayoutConstraint constraintsWithVisualFormat: @"V:|-[view]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)];
|
||||
[_containerView addConstraints: constraints];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
-(void)addFileMenuEntry
|
||||
{
|
||||
NSApplication *app = [NSApplication sharedApplication];
|
||||
NSMenu *fileMenu = [[app.mainMenu itemWithTag:123] submenu];
|
||||
|
||||
NSMenuItem *openFileItem = [[NSMenuItem alloc] initWithTitle:@"Load file..."
|
||||
action:@selector(handleMenuSelection:)
|
||||
keyEquivalent:@"O"];
|
||||
[fileMenu insertItem:openFileItem atIndex:0];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
-(void)handleMenuSelection:(NSMenuItem *)sender
|
||||
{
|
||||
// create the open dialog
|
||||
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
|
||||
openPanel.title = @"Choose an audio file";
|
||||
openPanel.showsResizeIndicator = YES;
|
||||
openPanel.canChooseFiles = YES;
|
||||
openPanel.allowsMultipleSelection = NO;
|
||||
openPanel.canChooseDirectories = NO;
|
||||
openPanel.canCreateDirectories = YES;
|
||||
openPanel.allowedFileTypes = @[@"aac", @"aif", @"aiff", @"caf", @"m4a", @"mp3", @"wav"];
|
||||
|
||||
if ( [openPanel runModal] == NSModalResponseOK )
|
||||
{
|
||||
NSArray* urls = [openPanel URLs];
|
||||
|
||||
// Loop through all the files and process them.
|
||||
for(int i = 0; i < [urls count]; i++ )
|
||||
{
|
||||
NSError* error = [audioEngine loadAudioFile:[urls objectAtIndex:i]];
|
||||
|
||||
if (error != nil)
|
||||
{
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setMessageText:@"Error loading file"];
|
||||
[alert setInformativeText:@"Something went wrong loading the audio file. Please make sure to select the correct format and try again."];
|
||||
[alert addButtonWithTitle:@"Ok"];
|
||||
[alert runModal];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
-(IBAction)togglePlay:(id)sender
|
||||
{
|
||||
BOOL isPlaying = [audioEngine startStop];
|
||||
|
||||
[playButton setTitle: isPlaying ? @"Stop" : @"Play"];
|
||||
}
|
||||
|
||||
#pragma mark <NSWindowDelegate>
|
||||
//------------------------------------------------------------------------
|
||||
- (void)windowWillClose:(NSNotification *)notification
|
||||
{
|
||||
// Main applicaiton window closing, we're done
|
||||
auV3ViewController = nil;
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,8 @@
|
||||
<?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>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.25.0)
|
||||
|
||||
project(smtg-vst3-again-sampleaccurate
|
||||
VERSION ${vstsdk_VERSION}.0
|
||||
DESCRIPTION "Steinberg VST 3 AGain example"
|
||||
)
|
||||
|
||||
smtg_add_vst3plugin(again-sample-accurate
|
||||
source/agsa_controller.cpp
|
||||
source/agsa_factory.cpp
|
||||
source/agsa_processor.cpp
|
||||
source/agsa.h
|
||||
source/tutorial.cpp
|
||||
source/tutorial.h
|
||||
source/version.h
|
||||
${SDK_ROOT}/public.sdk/source/vst/utility/test/sampleaccuratetest.cpp
|
||||
${SDK_ROOT}/public.sdk/source/vst/utility/test/rttransfertest.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(again-sample-accurate
|
||||
PRIVATE
|
||||
sdk_hosting
|
||||
)
|
||||
|
||||
smtg_target_setup_as_vst3_example(again-sample-accurate)
|
||||
@@ -0,0 +1,18 @@
|
||||
# AGain Sample Accurate
|
||||
|
||||
## Introduction
|
||||
|
||||
AGain Sample Accurate is the variant of the AGain FX plug-in showing how to achieve sample-accurate processing for the gain value.
|
||||
|
||||
> See also: [Online Documentation](https://steinbergmedia.github.io/vst3_dev_portal/pages/What+is+the+VST+3+SDK/Plug-in+Examples.html#again-sample-accurate).
|
||||
|
||||
## Getting Started
|
||||
|
||||
This plug-in is part of the VST 3 SDK package. It is created with the VST 3 SDK root project.
|
||||
|
||||
> See the top-level README of the VST 3 SDK: https://github.com/steinbergmedia/vst3sdk.git
|
||||
|
||||
## Getting Help
|
||||
|
||||
* Read through the SDK documentation on the **[VST 3 Developer Portal](https://steinbergmedia.github.io/vst3_dev_portal/pages/index.html)**
|
||||
* Ask some real people in the official **[VST 3 Developer Forum](https://forums.steinberg.net/c/developer/103)**
|
||||
@@ -0,0 +1,45 @@
|
||||
#include <windows.h>
|
||||
#include "../source/version.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Version
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION MAJOR_VERSION_INT,SUB_VERSION_INT,RELEASE_NUMBER_INT,BUILD_NUMBER_INT
|
||||
PRODUCTVERSION MAJOR_VERSION_INT,SUB_VERSION_INT,RELEASE_NUMBER_INT,BUILD_NUMBER_INT
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040004e4"
|
||||
BEGIN
|
||||
VALUE "FileVersion", FULL_VERSION_STR
|
||||
VALUE "ProductVersion", FULL_VERSION_STR
|
||||
VALUE "OriginalFilename", stringOriginalFilename
|
||||
VALUE "FileDescription", stringFileDescription
|
||||
VALUE "InternalName", stringFileDescription
|
||||
VALUE "ProductName", stringFileDescription
|
||||
VALUE "CompanyName", stringCompanyName
|
||||
VALUE "LegalCopyright", stringLegalCopyright
|
||||
VALUE "LegalTrademarks", stringLegalTrademarks
|
||||
//VALUE "PrivateBuild", " \0"
|
||||
//VALUE "SpecialBuild", " \0"
|
||||
//VALUE "Comments", " \0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x400, 1252
|
||||
END
|
||||
END
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again_sampleaccurate/source/agsa.h
|
||||
// Created by : Steinberg, 04/2021
|
||||
// Description : AGain with Sample Accurate Parameter Changes
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
namespace AgainSampleAccurate {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID ProcessorID (0xC18D3C1E, 0x719E4E29, 0x924D3ECA, 0xA5E4DA18);
|
||||
static const FUID ControllerID (0xC244B7E6, 0x24084E20, 0xA24A8C43, 0xF84C8BE8);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FUnknown* createProcessorInstance (void*);
|
||||
FUnknown* createControllerInstance (void*);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
enum ParameterID : ParamID
|
||||
{
|
||||
Bypass,
|
||||
Gain,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // AgainSampleAccurate
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
@@ -0,0 +1,92 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again_sampleaccurate/source/agsa_controller.cpp
|
||||
// Created by : Steinberg, 04/2021
|
||||
// Description : AGain with Sample Accurate Parameter Changes
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "agsa.h"
|
||||
#include "public.sdk/source/vst/vsteditcontroller.h"
|
||||
#include "base/source/fstreamer.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
namespace AgainSampleAccurate {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
class Controller : public EditController
|
||||
{
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setComponentState (IBStream* state) SMTG_OVERRIDE;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Controller::initialize (FUnknown* context)
|
||||
{
|
||||
tresult result = EditController::initialize (context);
|
||||
if (result != kResultOk)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
parameters.addParameter (STR ("Bypass"), nullptr, 1, 0.,
|
||||
ParameterInfo::kCanAutomate | ParameterInfo::kIsBypass,
|
||||
ParameterID::Bypass);
|
||||
parameters.addParameter (STR ("Gain"), STR ("%"), 0, 1., ParameterInfo::kCanAutomate,
|
||||
ParameterID::Gain);
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Controller::terminate ()
|
||||
{
|
||||
return EditController::terminate ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Controller::setComponentState (IBStream* state)
|
||||
{
|
||||
if (!state)
|
||||
return kInvalidArgument;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
uint32 numParams;
|
||||
if (streamer.readInt32u (numParams) == false)
|
||||
return kResultFalse;
|
||||
|
||||
ParamID pid;
|
||||
ParamValue value;
|
||||
for (uint32 i = 0u; i < numParams; ++i)
|
||||
{
|
||||
if (!streamer.readInt32u (pid))
|
||||
break;
|
||||
if (!streamer.readDouble (value))
|
||||
break;
|
||||
if (auto param = parameters.getParameter (pid))
|
||||
param->setNormalized (value);
|
||||
}
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FUnknown* createControllerInstance (void*)
|
||||
{
|
||||
return static_cast<IEditController*> (new Controller);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // AgainSampleAccurate
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
@@ -0,0 +1,60 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again_sampleaccurate/source/agsa_factory.cpp
|
||||
// Created by : Steinberg, 04/2021
|
||||
// Description : AGain with Sample Accurate Parameter Changes
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "agsa.h"
|
||||
#include "tutorial.h"
|
||||
#include "version.h"
|
||||
#include "public.sdk/source/main/pluginfactory.h"
|
||||
#include "public.sdk/source/vst/utility/testing.h"
|
||||
#include "pluginterfaces/vst/ivstaudioprocessor.h"
|
||||
#include "pluginterfaces/vst/ivsteditcontroller.h"
|
||||
|
||||
#define stringPluginName "AGain Sample Accurate"
|
||||
|
||||
using namespace Steinberg;
|
||||
using namespace Steinberg::Vst;
|
||||
using namespace Steinberg::Vst::AgainSampleAccurate;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// VST Plug-in Factory
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
BEGIN_FACTORY_DEF (stringCompanyName, stringCompanyWeb, stringCompanyEmail)
|
||||
|
||||
// AGain sample accurate
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID (ProcessorID), PClassInfo::kManyInstances, kVstAudioEffectClass,
|
||||
stringPluginName, Vst::kDistributable, "Fx", FULL_VERSION_STR, kVstVersionString,
|
||||
createProcessorInstance)
|
||||
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID (ControllerID), PClassInfo::kManyInstances,
|
||||
kVstComponentControllerClass, stringPluginName "Controller", 0, "", FULL_VERSION_STR,
|
||||
kVstVersionString, createControllerInstance)
|
||||
|
||||
// Test
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID (getTestFactoryUID ()), PClassInfo::kManyInstances, kTestClass,
|
||||
stringPluginName "Test Factory", 0, "", "", "", createTestFactoryInstance)
|
||||
|
||||
// Tutorial
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID (Tutorial::ProcessorID), PClassInfo::kManyInstances,
|
||||
kVstAudioEffectClass, "Advanced Tutorial", Vst::kDistributable, "Fx", FULL_VERSION_STR,
|
||||
kVstVersionString, Tutorial::createProcessorInstance)
|
||||
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID (Tutorial::ControllerID), PClassInfo::kManyInstances,
|
||||
kVstComponentControllerClass, "Advanced Tutorial Controller", 0, "", FULL_VERSION_STR,
|
||||
kVstVersionString, Tutorial::createControllerInstance)
|
||||
|
||||
END_FACTORY
|
||||
@@ -0,0 +1,264 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again_sampleaccurate/source/agsa_processor.cpp
|
||||
// Created by : Steinberg, 04/2021
|
||||
// Description : AGain with Sample Accurate Parameter Changes
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "agsa.h"
|
||||
#include "public.sdk/source/vst/utility/audiobuffers.h"
|
||||
#include "public.sdk/source/vst/utility/processdataslicer.h"
|
||||
#include "public.sdk/source/vst/utility/rttransfer.h"
|
||||
#include "public.sdk/source/vst/utility/sampleaccurate.h"
|
||||
#include "public.sdk/source/vst/vstaudioeffect.h"
|
||||
#include "base/source/fstreamer.h"
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
namespace AgainSampleAccurate {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct Processor : public AudioEffect
|
||||
{
|
||||
using ParameterVector = std::vector<std::pair<ParamID, ParamValue>>;
|
||||
using RTTransfer = RTTransferT<ParameterVector>;
|
||||
|
||||
Processor ();
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs,
|
||||
int32 numOuts) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API canProcessSampleSize (int32 symbolicSampleSize) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API process (ProcessData& data) SMTG_OVERRIDE;
|
||||
|
||||
void handleParameterChanges (IParameterChanges* changes);
|
||||
|
||||
template <SymbolicSampleSizes SampleSize>
|
||||
void process (ProcessData& data);
|
||||
|
||||
std::array<SampleAccurate::Parameter, 2> parameters;
|
||||
RTTransfer stateTransfer;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Processor::Processor ()
|
||||
{
|
||||
setControllerClass (ControllerID);
|
||||
parameters[0].setParamID (ParameterID::Bypass);
|
||||
parameters[1].setParamID (ParameterID::Gain);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Processor::initialize (FUnknown* context)
|
||||
{
|
||||
auto result = AudioEffect::initialize (context);
|
||||
if (result == kResultTrue)
|
||||
{
|
||||
addAudioInput (STR ("Input"), SpeakerArr::kStereo);
|
||||
addAudioOutput (STR ("Output"), SpeakerArr::kStereo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Processor::terminate ()
|
||||
{
|
||||
stateTransfer.clear_ui ();
|
||||
return AudioEffect::terminate ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Processor::setState (IBStream* state)
|
||||
{
|
||||
if (!state)
|
||||
return kInvalidArgument;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
uint32 numParams;
|
||||
if (streamer.readInt32u (numParams) == false)
|
||||
return kResultFalse;
|
||||
|
||||
auto paramChanges = std::make_unique<ParameterVector> ();
|
||||
ParamID pid;
|
||||
ParamValue value;
|
||||
for (uint32 i = 0u; i < numParams; ++i)
|
||||
{
|
||||
if (!streamer.readInt32u (pid))
|
||||
break;
|
||||
if (!streamer.readDouble (value))
|
||||
break;
|
||||
for (auto& param : parameters)
|
||||
{
|
||||
if (param.getParamID () == pid)
|
||||
{
|
||||
paramChanges->emplace_back (std::make_pair (pid, value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
stateTransfer.transferObject_ui (std::move (paramChanges));
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Processor::getState (IBStream* state)
|
||||
{
|
||||
if (!state)
|
||||
return kInvalidArgument;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
streamer.writeInt32u (static_cast<uint32> (parameters.size ()));
|
||||
for (auto& param : parameters)
|
||||
{
|
||||
streamer.writeInt32u (param.getParamID ());
|
||||
streamer.writeDouble (param.getValue ());
|
||||
}
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Processor::setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs, int32 numOuts)
|
||||
{
|
||||
if (numIns != 1 || numOuts != 1)
|
||||
return kResultFalse;
|
||||
if (SpeakerArr::getChannelCount (inputs[0]) == SpeakerArr::getChannelCount (outputs[0]))
|
||||
{
|
||||
getAudioInput (0)->setArrangement (inputs[0]);
|
||||
getAudioOutput (0)->setArrangement (outputs[0]);
|
||||
return kResultTrue;
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Processor::canProcessSampleSize (int32 symbolicSampleSize)
|
||||
{
|
||||
return (symbolicSampleSize == SymbolicSampleSizes::kSample32 ||
|
||||
symbolicSampleSize == SymbolicSampleSizes::kSample64) ?
|
||||
kResultTrue :
|
||||
kResultFalse;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <SymbolicSampleSizes SampleSize>
|
||||
void Processor::process (ProcessData& data)
|
||||
{
|
||||
using SampleT = typename std::conditional<SampleSize == SymbolicSampleSizes::kSample32, float,
|
||||
double>::type;
|
||||
|
||||
static constexpr auto SliceSize = 16u;
|
||||
|
||||
ProcessDataSlicer slicer (SliceSize);
|
||||
std::array<SampleT, SliceSize> againValueBuffer;
|
||||
|
||||
auto doProcessing = [this, &againValueBuffer] (ProcessData& data) {
|
||||
parameters[ParameterID::Bypass].advance (data.numSamples);
|
||||
|
||||
auto inputs = data.inputs;
|
||||
auto outputs = data.outputs;
|
||||
if (parameters[ParameterID::Bypass].getValue () > 0.5)
|
||||
{
|
||||
for (auto channelIndex = 0; channelIndex < inputs[0].numChannels; ++channelIndex)
|
||||
{
|
||||
auto inChannelBuffer = getChannelBuffers<SampleSize> (inputs[0])[channelIndex];
|
||||
auto outChannelBuffer = getChannelBuffers<SampleSize> (outputs[0])[channelIndex];
|
||||
for (auto sampleIndex = 0; sampleIndex < data.numSamples; ++sampleIndex)
|
||||
{
|
||||
outChannelBuffer[sampleIndex] = inChannelBuffer[sampleIndex];
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (auto i = 0; i < data.numSamples; ++i)
|
||||
againValueBuffer[i] = static_cast<SampleT> (parameters[ParameterID::Gain].advance (1));
|
||||
|
||||
for (auto channelIndex = 0; channelIndex < inputs[0].numChannels; ++channelIndex)
|
||||
{
|
||||
auto inChannelBuffer = getChannelBuffers<SampleSize> (inputs[0])[channelIndex];
|
||||
auto outChannelBuffer = getChannelBuffers<SampleSize> (outputs[0])[channelIndex];
|
||||
for (auto sampleIndex = 0; sampleIndex < data.numSamples; ++sampleIndex)
|
||||
{
|
||||
auto sample = inChannelBuffer[sampleIndex] * againValueBuffer[sampleIndex];
|
||||
outChannelBuffer[sampleIndex] = sample;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
slicer.process<SampleSize> (data, doProcessing);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void Processor::handleParameterChanges (IParameterChanges* changes)
|
||||
{
|
||||
if (changes)
|
||||
{
|
||||
auto changeCount = changes->getParameterCount ();
|
||||
for (auto i = 0; i < changeCount; ++i)
|
||||
{
|
||||
if (auto queue = changes->getParameterData (i))
|
||||
{
|
||||
auto paramID = queue->getParameterId ();
|
||||
if (paramID >= ParameterID::Bypass && paramID <= ParameterID::Gain)
|
||||
parameters[paramID].beginChanges (queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Processor::process (ProcessData& data)
|
||||
{
|
||||
stateTransfer.accessTransferObject_rt ([this] (const auto& stateChanges) {
|
||||
for (const auto& change : stateChanges)
|
||||
{
|
||||
if (change.first >= ParameterID::Bypass && change.first <= ParameterID::Gain)
|
||||
parameters[change.first].setValue (change.second);
|
||||
}
|
||||
});
|
||||
|
||||
handleParameterChanges (data.inputParameterChanges);
|
||||
|
||||
if (data.numSamples > 0)
|
||||
{
|
||||
if (processSetup.symbolicSampleSize == SymbolicSampleSizes::kSample32)
|
||||
process<SymbolicSampleSizes::kSample32> (data);
|
||||
else
|
||||
process<SymbolicSampleSizes::kSample64> (data);
|
||||
}
|
||||
|
||||
for (auto& param : parameters)
|
||||
param.endChanges ();
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FUnknown* createProcessorInstance (void*)
|
||||
{
|
||||
return static_cast<IAudioProcessor*> (new Processor);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // AgainSampleAccurate
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
@@ -0,0 +1,273 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again_sampleaccurate/source/tutorial.cpp
|
||||
// Created by : Steinberg, 04/2021
|
||||
// Description : Tutorial
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "tutorial.h"
|
||||
#include "public.sdk/source/vst/utility/audiobuffers.h"
|
||||
#include "public.sdk/source/vst/utility/processdataslicer.h"
|
||||
#include "public.sdk/source/vst/utility/rttransfer.h"
|
||||
#include "public.sdk/source/vst/utility/sampleaccurate.h"
|
||||
#include "public.sdk/source/vst/vstaudioeffect.h"
|
||||
#include "public.sdk/source/vst/vsteditcontroller.h"
|
||||
#include "base/source/fstreamer.h"
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
namespace Tutorial {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
enum ParameterID
|
||||
{
|
||||
Gain = 1,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct StateModel
|
||||
{
|
||||
double gain;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct MyEffect : public AudioEffect
|
||||
{
|
||||
using RTTransfer = RTTransferT<StateModel>;
|
||||
|
||||
MyEffect ();
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API terminate () SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs,
|
||||
int32 numOuts) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API canProcessSampleSize (int32 symbolicSampleSize) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API process (ProcessData& data) SMTG_OVERRIDE;
|
||||
|
||||
void handleParameterChanges (IParameterChanges* changes);
|
||||
|
||||
template <SymbolicSampleSizes SampleSize>
|
||||
void process (ProcessData& data);
|
||||
|
||||
SampleAccurate::Parameter gainParameter {ParameterID::Gain, 1.};
|
||||
RTTransfer stateTransfer;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
MyEffect::MyEffect ()
|
||||
{
|
||||
setControllerClass (ControllerID);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MyEffect::initialize (FUnknown* context)
|
||||
{
|
||||
auto result = AudioEffect::initialize (context);
|
||||
if (result == kResultTrue)
|
||||
{
|
||||
addAudioInput (STR ("Input"), SpeakerArr::kStereo);
|
||||
addAudioOutput (STR ("Output"), SpeakerArr::kStereo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MyEffect::terminate ()
|
||||
{
|
||||
stateTransfer.clear_ui ();
|
||||
return AudioEffect::terminate ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MyEffect::setState (IBStream* state)
|
||||
{
|
||||
if (!state)
|
||||
return kInvalidArgument;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
uint32 numParams;
|
||||
if (streamer.readInt32u (numParams) == false)
|
||||
return kResultFalse;
|
||||
|
||||
auto model = std::make_unique<StateModel> ();
|
||||
|
||||
ParamValue value;
|
||||
if (!streamer.readDouble (value))
|
||||
return kResultFalse;
|
||||
|
||||
model->gain = value;
|
||||
|
||||
stateTransfer.transferObject_ui (std::move (model));
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MyEffect::getState (IBStream* state)
|
||||
{
|
||||
if (!state)
|
||||
return kInvalidArgument;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
streamer.writeDouble (gainParameter.getValue ());
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MyEffect::setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs, int32 numOuts)
|
||||
{
|
||||
if (numIns != 1 || numOuts != 1)
|
||||
return kResultFalse;
|
||||
if (SpeakerArr::getChannelCount (inputs[0]) == SpeakerArr::getChannelCount (outputs[0]))
|
||||
{
|
||||
getAudioInput (0)->setArrangement (inputs[0]);
|
||||
getAudioOutput (0)->setArrangement (outputs[0]);
|
||||
return kResultTrue;
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MyEffect::canProcessSampleSize (int32 symbolicSampleSize)
|
||||
{
|
||||
return (symbolicSampleSize == SymbolicSampleSizes::kSample32 ||
|
||||
symbolicSampleSize == SymbolicSampleSizes::kSample64) ?
|
||||
kResultTrue :
|
||||
kResultFalse;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <SymbolicSampleSizes SampleSize>
|
||||
void MyEffect::process (ProcessData& data)
|
||||
{
|
||||
ProcessDataSlicer slicer (8);
|
||||
|
||||
auto doProcessing = [this] (ProcessData& data) {
|
||||
// get the gain value for this block
|
||||
ParamValue gain = gainParameter.advance (data.numSamples);
|
||||
|
||||
// process audio
|
||||
AudioBusBuffers* inputs = data.inputs;
|
||||
AudioBusBuffers* outputs = data.outputs;
|
||||
for (auto channelIndex = 0; channelIndex < inputs[0].numChannels; ++channelIndex)
|
||||
{
|
||||
auto inputBuffers = getChannelBuffers<SampleSize> (inputs[0])[channelIndex];
|
||||
auto outputBuffers = getChannelBuffers<SampleSize> (outputs[0])[channelIndex];
|
||||
for (auto sampleIndex = 0; sampleIndex < data.numSamples; ++sampleIndex)
|
||||
{
|
||||
auto sample = inputBuffers[sampleIndex];
|
||||
outputBuffers[sampleIndex] = sample * gain;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
slicer.process<SampleSize> (data, doProcessing);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void MyEffect::handleParameterChanges (IParameterChanges* changes)
|
||||
{
|
||||
if (!changes)
|
||||
return;
|
||||
int32 changeCount = changes->getParameterCount ();
|
||||
for (auto i = 0; i < changeCount; ++i)
|
||||
{
|
||||
if (auto queue = changes->getParameterData (i))
|
||||
{
|
||||
auto paramID = queue->getParameterId ();
|
||||
if (paramID == ParameterID::Gain)
|
||||
{
|
||||
gainParameter.beginChanges (queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MyEffect::process (ProcessData& data)
|
||||
{
|
||||
stateTransfer.accessTransferObject_rt (
|
||||
[this] (const auto& stateModel) { gainParameter.setValue (stateModel.gain); });
|
||||
|
||||
handleParameterChanges (data.inputParameterChanges);
|
||||
|
||||
if (processSetup.symbolicSampleSize == SymbolicSampleSizes::kSample32)
|
||||
process<SymbolicSampleSizes::kSample32> (data);
|
||||
else
|
||||
process<SymbolicSampleSizes::kSample64> (data);
|
||||
|
||||
gainParameter.endChanges ();
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FUnknown* createProcessorInstance (void*)
|
||||
{
|
||||
return static_cast<IAudioProcessor*> (new MyEffect);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
class Controller : public EditController
|
||||
{
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API setComponentState (IBStream* state) SMTG_OVERRIDE;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Controller::initialize (FUnknown* context)
|
||||
{
|
||||
tresult result = EditController::initialize (context);
|
||||
if (result != kResultOk)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
parameters.addParameter (STR ("Gain"), STR ("%"), 0, 1., ParameterInfo::kCanAutomate,
|
||||
ParameterID::Gain);
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Controller::setComponentState (IBStream* state)
|
||||
{
|
||||
if (!state)
|
||||
return kInvalidArgument;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
ParamValue value;
|
||||
if (!streamer.readDouble (value))
|
||||
return kResultFalse;
|
||||
|
||||
if (auto param = parameters.getParameter (ParameterID::Gain))
|
||||
param->setNormalized (value);
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FUnknown* createControllerInstance (void*)
|
||||
{
|
||||
return static_cast<IEditController*> (new Controller);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Tutorial
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
@@ -0,0 +1,39 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again_sampleaccurate/source/tutorial.h
|
||||
// Created by : Steinberg, 04/2021
|
||||
// Description : Tutorial
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
namespace Tutorial {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID ProcessorID (0xCC48BF25, 0x529043DA, 0x80223510, 0xFFE8BD02);
|
||||
static const FUID ControllerID (0x3A89B2B2, 0x4F474E02, 0x9C96EE27, 0x0AD2A15B);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FUnknown* createProcessorInstance (void*);
|
||||
FUnknown* createControllerInstance (void*);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // AgainSampleAccurate
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
@@ -0,0 +1,35 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/again_sampleaccurate/source/version.h
|
||||
// Created by : Steinberg, 04/2021
|
||||
// Description : Example of handle the versioning and copyright info of again sampleaccurate plug-in
|
||||
// used for the resources (RC file for example)
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/fplatform.h"
|
||||
|
||||
// Plain project version file generated by cmake
|
||||
#include "projectversion.h"
|
||||
|
||||
#define stringOriginalFilename "again_sampleaccurate.vst3"
|
||||
#if SMTG_PLATFORM_64
|
||||
#define stringFileDescription "AGain SampleAccurate VST3-SDK (64Bit)"
|
||||
#else
|
||||
#define stringFileDescription "AGain SampleAccurate VST3-SDK"
|
||||
#endif
|
||||
#define stringCompanyWeb "http://www.steinberg.net"
|
||||
#define stringCompanyEmail "mailto:info@steinberg.de"
|
||||
#define stringCompanyName "Steinberg Media Technologies"
|
||||
#define stringLegalCopyright "© 2025 Steinberg Media Technologies"
|
||||
#define stringLegalTrademarks "VST is a trademark of Steinberg Media Technologies GmbH"
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.25.0)
|
||||
|
||||
project(smtg-vst3-channelcontext
|
||||
VERSION ${vstsdk_VERSION}.0
|
||||
DESCRIPTION "Steinberg VST 3 Channel Context example"
|
||||
)
|
||||
|
||||
smtg_add_vst3plugin(channel-context
|
||||
source/plug.cpp
|
||||
source/plug.h
|
||||
source/plugcids.h
|
||||
source/plugcontroller.cpp
|
||||
source/plugcontroller.h
|
||||
source/plugentry.cpp
|
||||
source/plugparamids.h
|
||||
source/version.h
|
||||
)
|
||||
|
||||
smtg_target_setup_as_vst3_example(channel-context)
|
||||
@@ -0,0 +1,18 @@
|
||||
# Test Channel Context
|
||||
|
||||
## Introduction
|
||||
|
||||
**Test Channel Context** is simple FX plug-in showing how to use the [Steinberg::Vst::ChannelContext::IInfoListener](https://steinbergmedia.github.io/vst3_dev_portal/pages/Technical+Documentation/Change+History/3.6.5/IInfoListener.html) interface.
|
||||
|
||||
> See also: [Online Documentation](https://steinbergmedia.github.io/vst3_dev_portal/pages/What+is+the+VST+3+SDK/Plug-in+Examples.html#testchannelcontext).
|
||||
|
||||
## Getting Started
|
||||
|
||||
This plug-in is part of the VST 3 SDK package. It is created with the VST 3 SDK root project.
|
||||
|
||||
> See the top-level README of the VST 3 SDK: https://github.com/steinbergmedia/vst3sdk.git
|
||||
|
||||
## Getting Help
|
||||
|
||||
* Read through the SDK documentation on the **[VST 3 Developer Portal](https://steinbergmedia.github.io/vst3_dev_portal/pages/index.html)**
|
||||
* Ask some real people in the official **[VST 3 Developer Forum](https://forums.steinberg.net/c/developer/103)**
|
||||
@@ -0,0 +1,45 @@
|
||||
#include <windows.h>
|
||||
#include "../source/version.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Version
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION MAJOR_VERSION_INT,SUB_VERSION_INT,RELEASE_NUMBER_INT,BUILD_NUMBER_INT
|
||||
PRODUCTVERSION MAJOR_VERSION_INT,SUB_VERSION_INT,RELEASE_NUMBER_INT,BUILD_NUMBER_INT
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040004e4"
|
||||
BEGIN
|
||||
VALUE "FileVersion", FULL_VERSION_STR
|
||||
VALUE "ProductVersion", FULL_VERSION_STR
|
||||
VALUE "OriginalFilename", stringOriginalFilename
|
||||
VALUE "FileDescription", stringFileDescription
|
||||
VALUE "InternalName", stringFileDescription
|
||||
VALUE "ProductName", stringFileDescription
|
||||
VALUE "CompanyName", stringCompanyName
|
||||
VALUE "LegalCopyright", stringLegalCopyright
|
||||
VALUE "LegalTrademarks", stringLegalTrademarks
|
||||
//VALUE "PrivateBuild", " \0"
|
||||
//VALUE "SpecialBuild", " \0"
|
||||
//VALUE "Comments", " \0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x400, 1252
|
||||
END
|
||||
END
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/channelcontext/source/plug.cpp
|
||||
// Created by : Steinberg, 02/2014
|
||||
// Description : Plug Example for VST SDK 3.x
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "plug.h"
|
||||
#include "plugparamids.h"
|
||||
#include "plugcids.h" // for class ids
|
||||
|
||||
#include "public.sdk/source/vst/vstaudioprocessoralgo.h"
|
||||
|
||||
#include "pluginterfaces/base/futils.h"
|
||||
#include "pluginterfaces/base/ibstream.h"
|
||||
#include "pluginterfaces/vst/ivstevents.h"
|
||||
#include "pluginterfaces/vst/ivstparameterchanges.h"
|
||||
|
||||
#include "base/source/fstreamer.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Plug Implementation
|
||||
//------------------------------------------------------------------------
|
||||
Plug::Plug ()
|
||||
: bBypass (false)
|
||||
{
|
||||
// register its editor class (the same than used in plugentry.cpp)
|
||||
setControllerClass (PlugControllerUID);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Plug::initialize (FUnknown* context)
|
||||
{
|
||||
//---always initialize the parent-------
|
||||
tresult result = AudioEffect::initialize (context);
|
||||
// if everything Ok, continue
|
||||
if (result != kResultOk)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//---create Audio In/Out busses------
|
||||
// we want a stereo Input and a Stereo Output
|
||||
addAudioInput (STR16 ("Stereo In"), SpeakerArr::kStereo);
|
||||
addAudioOutput (STR16 ("Stereo Out"), SpeakerArr::kStereo);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Plug::process (ProcessData& data)
|
||||
{
|
||||
//---1) Read inputs parameter changes-----------
|
||||
if (IParameterChanges* paramChanges = data.inputParameterChanges)
|
||||
{
|
||||
int32 numParamsChanged = paramChanges->getParameterCount ();
|
||||
// for each parameter which are some changes in this audio block:
|
||||
for (int32 i = 0; i < numParamsChanged; i++)
|
||||
{
|
||||
if (IParamValueQueue* paramQueue = paramChanges->getParameterData (i))
|
||||
{
|
||||
int32 offsetSamples;
|
||||
double value;
|
||||
int32 numPoints = paramQueue->getPointCount ();
|
||||
switch (paramQueue->getParameterId ())
|
||||
{
|
||||
case kBypassId:
|
||||
if (paramQueue->getPoint (numPoints - 1, offsetSamples, value) == kResultTrue)
|
||||
{
|
||||
bBypass = (value > 0.5f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
//---3) Process Audio---------------------
|
||||
//-------------------------------------
|
||||
if (data.numInputs == 0 || data.numOutputs == 0)
|
||||
{
|
||||
// nothing to do
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
// (simplification) we suppose in this example that we have the same input channel count than
|
||||
// the output
|
||||
int32 numChannels = Min (data.inputs[0].numChannels, data.outputs[0].numChannels);
|
||||
|
||||
//---get audio buffers----------------
|
||||
float** in = data.inputs[0].channelBuffers32;
|
||||
float** out = data.outputs[0].channelBuffers32;
|
||||
|
||||
// check if all channel are silent then process silent
|
||||
if (data.inputs[0].silenceFlags == getChannelMask (data.inputs[0].numChannels))
|
||||
{
|
||||
// mark output silence too
|
||||
data.outputs[0].silenceFlags = data.inputs[0].silenceFlags;
|
||||
|
||||
int32 sampleFrames = data.numSamples;
|
||||
|
||||
// the plug-in has to be sure that if it sets the flags silence that the output buffer are
|
||||
// clear
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
// do not need to be cleared if the buffers are the same (in this case input buffer are
|
||||
// already cleared by the host)
|
||||
if (in[i] != out[i])
|
||||
{
|
||||
memset (out[i], 0, sampleFrames * sizeof (float));
|
||||
}
|
||||
}
|
||||
|
||||
// nothing to do at this point
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
// mark our outputs has not silent
|
||||
data.outputs[0].silenceFlags = 0;
|
||||
|
||||
//---in bypass mode outputs should be like inputs-----
|
||||
if (bBypass)
|
||||
{
|
||||
int32 sampleFrames = data.numSamples;
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
// do not need to be copied if the buffers are the same
|
||||
if (in[i] != out[i])
|
||||
{
|
||||
memcpy (out[i], in[i], sampleFrames * sizeof (float));
|
||||
}
|
||||
}
|
||||
for (int32 i = numChannels; i < data.outputs[0].numChannels; i++)
|
||||
{
|
||||
memset (out[i], 0, sizeof (float)* data.numSamples);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float gain = 0.5;
|
||||
|
||||
// in real plug-in it would be better to do dezippering to avoid jump (click) in gain value
|
||||
for (int32 i = 0; i < numChannels; i++)
|
||||
{
|
||||
int32 sampleFrames = data.numSamples;
|
||||
float* ptrIn = in[i];
|
||||
float* ptrOut = out[i];
|
||||
float tmp;
|
||||
while (--sampleFrames >= 0)
|
||||
{
|
||||
// apply gain
|
||||
tmp = (*ptrIn++) * gain;
|
||||
(*ptrOut++) = tmp;
|
||||
}
|
||||
}
|
||||
for (int32 i = numChannels; i < data.outputs[0].numChannels; i++)
|
||||
{
|
||||
memset (out[i], 0, sizeof (float)* data.numSamples);
|
||||
}
|
||||
}
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Plug::setState (IBStream* state)
|
||||
{
|
||||
// called when we load a preset, the model has to be reloaded
|
||||
|
||||
if (!state)
|
||||
return kResultFalse;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
// read the bypass
|
||||
int32 savedBypass = 0;
|
||||
if (streamer.readInt32 (savedBypass) == false)
|
||||
return kResultFalse;
|
||||
|
||||
bBypass = savedBypass > 0;
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API Plug::getState (IBStream* state)
|
||||
{
|
||||
// here we need to save the model
|
||||
|
||||
if (!state)
|
||||
return kResultFalse;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
streamer.writeInt32 (bBypass ? 1 : 0);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,58 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/channelcontext/source/plug.h
|
||||
// Created by : Steinberg, 02/2014
|
||||
// Description : Plug-in Example for VST SDK 3.x using ChannelContext::IInfoListener
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "public.sdk/source/vst/vstaudioeffect.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Plug: directly derived from the helper class AudioEffect
|
||||
//------------------------------------------------------------------------
|
||||
class Plug : public AudioEffect
|
||||
{
|
||||
public:
|
||||
Plug ();
|
||||
|
||||
//--- ---------------------------------------------------------------------
|
||||
// create function required for plug-in factory,
|
||||
// it will be called to create new instances of this plug-in
|
||||
//--- ---------------------------------------------------------------------
|
||||
static FUnknown* createInstance (void* /*context*/) { return (IAudioProcessor*)new Plug; }
|
||||
|
||||
//--- ---------------------------------------------------------------------
|
||||
// AudioEffect overrides:
|
||||
//--- ---------------------------------------------------------------------
|
||||
/** Called at first after constructor */
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
|
||||
/** Here we go...the process call */
|
||||
tresult PLUGIN_API process (ProcessData& data) SMTG_OVERRIDE;
|
||||
|
||||
/** For persistence */
|
||||
tresult PLUGIN_API setState (IBStream* state) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API getState (IBStream* state) SMTG_OVERRIDE;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
bool bBypass;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
@@ -0,0 +1,25 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/channelcontext/source/plugcids.h
|
||||
// Created by : Steinberg, 02/2014
|
||||
// Description : define the class IDs for channelcontext
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
// Plug A
|
||||
static const FUID PlugProcessorUID (0x01EDEBE8, 0x8CD14564, 0xAF34B1A2, 0xDDC13384);
|
||||
static const FUID PlugControllerUID(0xB4D97900, 0xAAC84AAE, 0xB9D1C427, 0xB77A698B);
|
||||
|
||||
}} // namespaces
|
||||
@@ -0,0 +1,293 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/channelcontext/source/PlugController.cpp
|
||||
// Created by : Steinberg, 02/2014
|
||||
// Description : Plug Controller Example for VST SDK 3.x
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "plugcontroller.h"
|
||||
#include "plugparamids.h"
|
||||
|
||||
#include "pluginterfaces/base/ibstream.h"
|
||||
#include "pluginterfaces/base/ustring.h"
|
||||
#include "base/source/fstreamer.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// PlugController Implementation
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API PlugController::initialize (FUnknown* context)
|
||||
{
|
||||
tresult result = EditControllerEx1::initialize (context);
|
||||
if (result != kResultOk)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//---Create Parameters------------
|
||||
|
||||
//---Bypass parameter---
|
||||
int32 stepCount = 1;
|
||||
ParamValue defaultVal = 0;
|
||||
int32 flags = ParameterInfo::kCanAutomate | ParameterInfo::kIsBypass;
|
||||
int32 tag = kBypassId;
|
||||
parameters.addParameter (STR16 ("Bypass"), nullptr, stepCount, defaultVal, flags, tag);
|
||||
|
||||
//---Read only parameters
|
||||
String128 undefinedStr;
|
||||
Steinberg::UString (undefinedStr, 128).fromAscii ("undefined");
|
||||
|
||||
flags = ParameterInfo::kIsReadOnly;
|
||||
auto* strParam = NEW StringListParameter (STR16 ("Ch Uid"), kChannelUIDId, nullptr, flags);
|
||||
strParam->appendString (undefinedStr);
|
||||
parameters.addParameter (strParam);
|
||||
|
||||
strParam = NEW StringListParameter (STR16 ("Ch Uid Len"), kChannelUIDLengthId, nullptr, flags);
|
||||
strParam->appendString (undefinedStr);
|
||||
parameters.addParameter (strParam);
|
||||
|
||||
strParam = NEW StringListParameter (STR16 ("Ch Name"), kChannelNameId, nullptr, flags);
|
||||
strParam->appendString (undefinedStr);
|
||||
parameters.addParameter (strParam);
|
||||
|
||||
strParam = NEW StringListParameter (STR16 ("Ch Name Len"), kChannelNameLengthId, nullptr, flags);
|
||||
strParam->appendString (undefinedStr);
|
||||
parameters.addParameter (strParam);
|
||||
|
||||
strParam = NEW StringListParameter (STR16 ("Ch Index"), kChannelIndexId, nullptr, flags);
|
||||
strParam->appendString (undefinedStr);
|
||||
parameters.addParameter (strParam);
|
||||
|
||||
strParam =
|
||||
NEW StringListParameter (STR16 ("Ch Index Namespace Order"), kChannelIndexNamespaceOrderId, nullptr, flags);
|
||||
strParam->appendString (undefinedStr);
|
||||
parameters.addParameter (strParam);
|
||||
|
||||
strParam =
|
||||
NEW StringListParameter (STR16 ("Ch Index Namespace"), kChannelIndexNamespaceId, nullptr, flags);
|
||||
strParam->appendString (undefinedStr);
|
||||
parameters.addParameter (strParam);
|
||||
|
||||
strParam = NEW StringListParameter (STR16 ("Ch Index Namespace Len"),
|
||||
kChannelIndexNamespaceLengthId, nullptr, flags);
|
||||
strParam->appendString (undefinedStr);
|
||||
parameters.addParameter (strParam);
|
||||
|
||||
strParam = NEW StringListParameter (STR16 ("Ch Color"), kChannelColorId, nullptr, flags);
|
||||
strParam->appendString (undefinedStr);
|
||||
parameters.addParameter (strParam);
|
||||
|
||||
strParam = NEW StringListParameter (STR16 ("Ch Plug Loc."), kChannelPluginLocationId, nullptr, flags);
|
||||
strParam->appendString (undefinedStr);
|
||||
parameters.addParameter (strParam);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API PlugController::setComponentState (IBStream* state)
|
||||
{
|
||||
// we receive the current state of the component (processor part)
|
||||
// we read only the gain and bypass value...
|
||||
|
||||
if (!state)
|
||||
return kResultFalse;
|
||||
|
||||
IBStreamer streamer (state, kLittleEndian);
|
||||
|
||||
// read the bypass
|
||||
int32 bypassState = 0;
|
||||
if (streamer.readInt32 (bypassState) == false)
|
||||
return kResultFalse;
|
||||
setParamNormalized (kBypassId, bypassState ? 1 : 0);
|
||||
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API PlugController::setChannelContextInfos (IAttributeList* list)
|
||||
{
|
||||
if (!list)
|
||||
return kResultFalse;
|
||||
|
||||
String128 undefinedStr;
|
||||
Steinberg::UString (undefinedStr, 128).fromAscii ("undefined");
|
||||
|
||||
// get the channel name length (optional) where we, as plugin, are instantiated
|
||||
auto* param =
|
||||
static_cast<StringListParameter*> (parameters.getParameter (kChannelNameLengthId));
|
||||
if (param)
|
||||
{
|
||||
int64 length;
|
||||
if (list->getInt (ChannelContext::kChannelNameLengthKey, length) == kResultTrue)
|
||||
{
|
||||
String128 string128;
|
||||
Steinberg::UString (string128, 128).printInt (length);
|
||||
param->replaceString (0, string128);
|
||||
}
|
||||
else
|
||||
param->replaceString (0, undefinedStr);
|
||||
}
|
||||
|
||||
// get the channel name where we, as plugin, are instantiated
|
||||
param = static_cast<StringListParameter*> (parameters.getParameter (kChannelNameId));
|
||||
if (param)
|
||||
{
|
||||
String128 name;
|
||||
if (list->getString (ChannelContext::kChannelNameKey, name, sizeof (name)) == kResultTrue)
|
||||
param->replaceString (0, name);
|
||||
else
|
||||
param->replaceString (0, undefinedStr);
|
||||
}
|
||||
|
||||
// get the channel UID Length
|
||||
param = static_cast<StringListParameter*> (parameters.getParameter (kChannelUIDLengthId));
|
||||
if (param)
|
||||
{
|
||||
int64 length;
|
||||
if (list->getInt (ChannelContext::kChannelUIDLengthKey, length) == kResultTrue)
|
||||
{
|
||||
String128 string128;
|
||||
Steinberg::UString (string128, 128).printInt (length);
|
||||
param->replaceString (0, string128);
|
||||
}
|
||||
else
|
||||
param->replaceString (0, undefinedStr);
|
||||
}
|
||||
|
||||
// get the channel UID
|
||||
param = static_cast<StringListParameter*> (parameters.getParameter (kChannelUIDId));
|
||||
if (param)
|
||||
{
|
||||
String128 name;
|
||||
if (list->getString (ChannelContext::kChannelUIDKey, name, sizeof (name)) == kResultTrue)
|
||||
param->replaceString (0, name);
|
||||
else
|
||||
param->replaceString (0, undefinedStr);
|
||||
}
|
||||
|
||||
// get Channel Index
|
||||
param = static_cast<StringListParameter*> (parameters.getParameter (kChannelIndexId));
|
||||
if (param)
|
||||
{
|
||||
int64 index;
|
||||
if (list->getInt (ChannelContext::kChannelIndexKey, index) == kResultTrue)
|
||||
{
|
||||
String128 string128;
|
||||
Steinberg::UString (string128, 128).printInt (index);
|
||||
param->replaceString (0, string128);
|
||||
}
|
||||
else
|
||||
param->replaceString (0, undefinedStr);
|
||||
}
|
||||
|
||||
// get Channel Index Namespace Order
|
||||
param = static_cast<StringListParameter*> (parameters.getParameter (kChannelIndexNamespaceOrderId));
|
||||
if (param)
|
||||
{
|
||||
int64 index;
|
||||
if (list->getInt (ChannelContext::kChannelIndexNamespaceOrderKey, index) == kResultTrue)
|
||||
{
|
||||
String128 string128;
|
||||
Steinberg::UString (string128, 128).printInt (index);
|
||||
param->replaceString (0, string128);
|
||||
}
|
||||
else
|
||||
param->replaceString (0, undefinedStr);
|
||||
}
|
||||
|
||||
// get the channel Index Namespace Length
|
||||
param = static_cast<StringListParameter*> (
|
||||
parameters.getParameter (kChannelIndexNamespaceLengthId));
|
||||
if (param)
|
||||
{
|
||||
int64 length;
|
||||
if (list->getInt (ChannelContext::kChannelIndexNamespaceLengthKey, length) == kResultTrue)
|
||||
{
|
||||
String128 string128;
|
||||
Steinberg::UString (string128, 128).printInt (length);
|
||||
param->replaceString (0, string128);
|
||||
}
|
||||
else
|
||||
param->replaceString (0, undefinedStr);
|
||||
}
|
||||
|
||||
// get the channel Index Namespace
|
||||
param = static_cast<StringListParameter*> (parameters.getParameter (kChannelIndexNamespaceId));
|
||||
if (param)
|
||||
{
|
||||
String128 name;
|
||||
if (list->getString (ChannelContext::kChannelIndexNamespaceKey, name, sizeof (name)) ==
|
||||
kResultTrue)
|
||||
param->replaceString (0, name);
|
||||
else
|
||||
param->replaceString (0, undefinedStr);
|
||||
}
|
||||
|
||||
// get plug-in Channel Location
|
||||
param = static_cast<StringListParameter*> (parameters.getParameter (kChannelPluginLocationId));
|
||||
if (param)
|
||||
{
|
||||
int64 location;
|
||||
if (list->getInt (ChannelContext::kChannelPluginLocationKey, location) == kResultTrue)
|
||||
{
|
||||
String128 string128;
|
||||
switch (location)
|
||||
{
|
||||
case ChannelContext::kPreVolumeFader:
|
||||
Steinberg::UString (string128, 128).fromAscii ("PreVolFader");
|
||||
break;
|
||||
case ChannelContext::kPostVolumeFader:
|
||||
Steinberg::UString (string128, 128).fromAscii ("PostVolFader");
|
||||
break;
|
||||
case ChannelContext::kUsedAsPanner:
|
||||
Steinberg::UString (string128, 128).fromAscii ("UsedAsPanner");
|
||||
break;
|
||||
default: Steinberg::UString (string128, 128).fromAscii ("unknown!"); break;
|
||||
}
|
||||
param->replaceString (0, string128);
|
||||
}
|
||||
else
|
||||
param->replaceString (0, undefinedStr);
|
||||
}
|
||||
|
||||
// get Channel Color
|
||||
param = static_cast<StringListParameter*> (parameters.getParameter (kChannelColorId));
|
||||
if (param)
|
||||
{
|
||||
int64 color;
|
||||
if (list->getInt (ChannelContext::kChannelColorKey, color) == kResultTrue)
|
||||
{
|
||||
uint32 channelColor = (uint32)color;
|
||||
char str[10];
|
||||
snprintf (str, 10, "%x%x%x%x", ChannelContext::GetAlpha (channelColor),
|
||||
ChannelContext::GetRed (channelColor),
|
||||
ChannelContext::GetGreen (channelColor),
|
||||
ChannelContext::GetBlue (channelColor));
|
||||
String128 string128;
|
||||
Steinberg::UString (string128, 128).fromAscii (str);
|
||||
param->replaceString (0, string128);
|
||||
}
|
||||
else
|
||||
param->replaceString (0, undefinedStr);
|
||||
}
|
||||
|
||||
// we have to inform the host that our strings have changed (values not)
|
||||
if (componentHandler)
|
||||
componentHandler->restartComponent (kParamValuesChanged);
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
}
|
||||
} // namespaces
|
||||
@@ -0,0 +1,58 @@
|
||||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Examples
|
||||
// Filename : public.sdk/samples/vst/channelcontext/source/plugcontroller.h
|
||||
// Created by : Steinberg, 02/2014
|
||||
// Description : channelcontext Controller Example for VST SDK 3.x
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// This file is part of a Steinberg SDK. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this distribution
|
||||
// and at www.steinberg.net/sdklicenses.
|
||||
// No part of the SDK, including this file, may be copied, modified, propagated,
|
||||
// or distributed except according to the terms contained in the LICENSE file.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "public.sdk/source/vst/vsteditcontroller.h"
|
||||
#include "pluginterfaces/vst/ivstchannelcontextinfo.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// PlugController
|
||||
//------------------------------------------------------------------------
|
||||
class PlugController : public EditControllerEx1, public ChannelContext::IInfoListener
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
// create function required for plug-in factory,
|
||||
// it will be called to create new instances of this controller
|
||||
//------------------------------------------------------------------------
|
||||
static FUnknown* createInstance (void* /*context*/) { return (IEditController*)new PlugController; }
|
||||
|
||||
//---from IPluginBase--------
|
||||
tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
|
||||
|
||||
//---from EditController-----
|
||||
tresult PLUGIN_API setComponentState (IBStream* state) SMTG_OVERRIDE;
|
||||
|
||||
//---from ChannelContext::IInfoListener-----
|
||||
tresult PLUGIN_API setChannelContextInfos (IAttributeList* list) SMTG_OVERRIDE;
|
||||
|
||||
//---Interface---------
|
||||
OBJ_METHODS (PlugController, EditControllerEx1)
|
||||
DEFINE_INTERFACES
|
||||
DEF_INTERFACE (ChannelContext::IInfoListener)
|
||||
END_DEFINE_INTERFACES (EditController)
|
||||
DELEGATE_REFCOUNT (EditControllerEx1)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
} // namespaces
|
||||