1 //-----------------------------------------------------------------------------
2 // Flags       : clang-format auto
3 // Project     : VST SDK
4 //
5 // Category    : AudioHost
6 // Filename    : public.sdk/samples/vst-hosting/audiohost/source/audiohost.cpp
7 // Created by  : Steinberg 09.2016
8 // Description : Audio Host Example for VST 3
9 //
10 //-----------------------------------------------------------------------------
11 // LICENSE
12 // (c) 2018, Steinberg Media Technologies GmbH, All Rights Reserved
13 //-----------------------------------------------------------------------------
14 // Redistribution and use in source and binary forms, with or without modification,
15 // are permitted provided that the following conditions are met:
16 //
17 //   * Redistributions of source code must retain the above copyright notice,
18 //     this list of conditions and the following disclaimer.
19 //   * Redistributions in binary form must reproduce the above copyright notice,
20 //     this list of conditions and the following disclaimer in the documentation
21 //     and/or other materials provided with the distribution.
22 //   * Neither the name of the Steinberg Media Technologies nor the names of its
23 //     contributors may be used to endorse or promote products derived from this
24 //     software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
34 // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
35 // OF THE POSSIBILITY OF SUCH DAMAGE.
anchor()36 //-----------------------------------------------------------------------------
37 
38 #include "public.sdk/samples/vst-hosting/audiohost/source/audiohost.h"
39 #include "public.sdk/samples/vst-hosting/audiohost/source/platform/appinit.h"
40 #include "public.sdk/source/vst/hosting/hostclasses.h"
41 #include "public.sdk/source/vst/hosting/stringconvert.h"
42 #include "base/source/fcommandline.h"
43 #include "pluginterfaces/base/funknown.h"
44 #include "pluginterfaces/gui/iplugview.h"
45 #include "pluginterfaces/gui/iplugviewcontentscalesupport.h"
46 #include "pluginterfaces/vst/ivstaudioprocessor.h"
47 #include "pluginterfaces/vst/ivsteditcontroller.h"
48 #include "pluginterfaces/vst/vsttypes.h"
49 #include <cstdio>
50 #include <iostream>
51 
52 #if WIN32
53 #include "windows.h"
54 #include <wtypes.h>
55 #endif
56 
57 //------------------------------------------------------------------------
58 namespace Steinberg {
59 FUnknown* gStandardPluginContext = new Vst::HostApplication ();
60 
61 namespace Vst {
62 namespace AudioHost {
63 static AudioHost::AppInit gInit (std::make_unique<App> ());
64 
65 //------------------------------------------------------------------------
66 App::~App () noexcept
67 {
68 }
69 
70 //------------------------------------------------------------------------
71 void App::startAudioClient (const std::string& path, VST3::Optional<VST3::UID> effectID,
72                             uint32 flags)
73 {
74 	std::string error;
75 	module = VST3::Hosting::Module::create (path, error);
76 	if (!module)
77 	{
78 		std::string reason = "Could not create Module for file:";
79 		reason += path;
80 		reason += "\nError: ";
81 		reason += error;
82 		// EditorHost::IPlatform::instance ().kill (-1, reason);
83 	}
84 	auto factory = module->getFactory ();
85 	for (auto& classInfo : factory.classInfos ())
86 	{
87 		if (classInfo.category () == kVstAudioEffectClass)
88 		{
89 			if (effectID)
90 			{
91 				if (*effectID != classInfo.ID ())
92 					continue;
93 			}
94 			plugProvider = owned (new PlugProvider (factory, classInfo, true));
95 			break;
96 		}
97 	}
98 	if (!plugProvider)
99 	{
100 		std::string error;
101 		if (effectID)
102 			error =
103 			    "No VST3 Audio Module Class with UID " + effectID->toString () + " found in file ";
104 		else
105 			error = "No VST3 Audio Module Class found in file ";
106 		error += path;
107 		// EditorHost::IPlatform::instance ().kill (-1, error);
108 	}
109 
110 	OPtr<IComponent> component = plugProvider->getComponent ();
111 	OPtr<IEditController> controller = plugProvider->getController ();
112 	FUnknownPtr<IMidiMapping> midiMapping (controller);
113 
114 	//! TODO: Query the plugProvider for a proper name which gets displayed in JACK.
115 	vst3Processor = AudioClient::create ("VST 3 SDK", component, midiMapping);
116 }
117 
118 //------------------------------------------------------------------------
119 void App::init (const std::vector<std::string>& cmdArgs)
120 {
121 	if (cmdArgs.empty ())
122 	{
123 		/*auto helpText = R"(
124 		usage: AudioHost pluginPath
125 		)";
126 		*/
127 		return;
128 	}
129 
130 	VST3::Optional<VST3::UID> uid;
131 	uint32 flags {};
132 
133 	startAudioClient (cmdArgs.back (), std::move (uid), flags);
134 }
135 
136 //------------------------------------------------------------------------
137 } // EditorHost
138 } // Vst
139 } // Steinberg
140 
141 //------------------------------------------------------------------------
142 #if WIN32
143 int wmain (int argc, wchar_t* argv[])
144 {
145 	std::vector<std::string> cmdArgs;
146 	for (int i = 1; i < argc; ++i)
147 		cmdArgs.push_back (VST3::StringConvert::convert (argv[i]));
148 
149 	Steinberg::Vst::AudioHost::gInit.app->init (cmdArgs);
150 
151 	std::cout << "Press <enter> to continue . . .";
152 	std::getchar ();
153 
154 	return 0;
155 }
156 #else
157 int main (int argc, char* argv[])
158 
159 {
160 	std::vector<std::string> cmdArgs;
161 	for (int i = 1; i < argc; ++i)
162 		cmdArgs.push_back (argv[i]);
getRegionValueSymbol(const TypedValueRegion * R)163 
164 	Steinberg::Vst::AudioHost::gInit.app->init (cmdArgs);
165 
166 	std::cout << "Press <enter> to continue . . .";
167 	std::getchar ();
168 
169 	return 0;
170 }
171 #endif
172