1 //------------------------------------------------------------------------
2 // Project     : VST SDK
3 //
4 // Category    : Helpers
5 // Filename    : public.sdk/source/vst/vst2wrapper/vst2wrapper.cpp
6 // Created by  : Steinberg, 01/2009
7 // Description : VST 3 -> VST 2 Wrapper
8 //
9 //-----------------------------------------------------------------------------
10 // LICENSE
11 // (c) 2020, Steinberg Media Technologies GmbH, All Rights Reserved
12 //-----------------------------------------------------------------------------
13 // Redistribution and use in source and binary forms, with or without modification,
14 // are permitted provided that the following conditions are met:
15 //
16 //   * Redistributions of source code must retain the above copyright notice,
17 //     this list of conditions and the following disclaimer.
18 //   * Redistributions in binary form must reproduce the above copyright notice,
19 //     this list of conditions and the following disclaimer in the documentation
20 //     and/or other materials provided with the distribution.
21 //   * Neither the name of the Steinberg Media Technologies nor the names of its
22 //     contributors may be used to endorse or promote products derived from this
23 //     software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
26 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33 // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
34 // OF THE POSSIBILITY OF SUCH DAMAGE.
35 //-----------------------------------------------------------------------------
36 
37 /// \cond ignore
38 
39 #include "public.sdk/source/vst/vst2wrapper/vst2wrapper.h"
40 
41 #include "public.sdk/source/vst/hosting/hostclasses.h"
42 #include "public.sdk/source/vst2.x/aeffeditor.h"
43 
44 #include "pluginterfaces/base/futils.h"
45 #include "pluginterfaces/base/keycodes.h"
46 #include "pluginterfaces/gui/iplugview.h"
47 #include "pluginterfaces/vst/ivstmessage.h"
48 #include "pluginterfaces/vst/ivstmidicontrollers.h"
49 #include "pluginterfaces/vst/vstpresetkeys.h"
50 
51 #include "base/source/fstreamer.h"
52 
53 #include <cstdio>
54 #include <cstdlib>
55 #include <limits>
56 
57 extern bool DeinitModule (); //! Called in Vst2Wrapper destructor
58 
59 //------------------------------------------------------------------------
60 // some Defines
61 //------------------------------------------------------------------------
62 // should be kVstMaxParamStrLen if we want to respect the VST 2 specification!!!
63 #define kVstExtMaxParamStrLen 32
64 
65 //------------------------------------------------------------------------
66 namespace Steinberg {
67 namespace Vst {
68 
69 //! The parameter's name contains the unit path (e.g. "Modulators.LFO 1.frequency")
70 bool vst2WrapperFullParameterPath = true;
71 
72 //------------------------------------------------------------------------
73 // Vst2EditorWrapper Declaration
74 //------------------------------------------------------------------------
75 class Vst2EditorWrapper : public BaseEditorWrapper, public AEffEditor
76 {
77 public:
78 //------------------------------------------------------------------------
79 	Vst2EditorWrapper (AudioEffect* effect, IEditController* controller);
80 
81 	//--- from BaseEditorWrapper ---------------------
82 	void _close () SMTG_OVERRIDE;
83 
84 	//--- from AEffEditor-------------------
85 	bool getRect (ERect** rect) SMTG_OVERRIDE;
86 	bool open (void* ptr) SMTG_OVERRIDE;
close()87 	void close () SMTG_OVERRIDE { _close (); }
setKnobMode(VstInt32 val)88 	bool setKnobMode (VstInt32 val) SMTG_OVERRIDE
89 	{
90 		return BaseEditorWrapper::_setKnobMode (static_cast<Vst::KnobMode> (val));
91 	}
92 
93 	///< Receives key down event. Return true only if key was really used!
94 	bool onKeyDown (VstKeyCode& keyCode) SMTG_OVERRIDE;
95 	///< Receives key up event. Return true only if key was really used!
96 	bool onKeyUp (VstKeyCode& keyCode) SMTG_OVERRIDE;
97 	///< Handles mouse wheel event, distance is positive or negative to indicate wheel direction.
98 	bool onWheel (float distance) SMTG_OVERRIDE;
99 
100 	//--- IPlugFrame ----------------------------
101 	tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* newSize) SMTG_OVERRIDE;
102 
103 //------------------------------------------------------------------------
104 protected:
105 	ERect mERect;
106 };
107 
108 //------------------------------------------------------------------------
areSizeEquals(const ViewRect & r1,const ViewRect & r2)109 bool areSizeEquals (const ViewRect &r1, const ViewRect& r2)
110 {
111 	if (r1.getHeight() != r2.getHeight ())
112 		return false;
113 	if (r1.getWidth() != r2.getWidth ())
114 		return false;
115 	return true;
116 }
117 
118 //------------------------------------------------------------------------
119 // Vst2EditorWrapper Implementation
120 //------------------------------------------------------------------------
Vst2EditorWrapper(AudioEffect * effect,IEditController * controller)121 Vst2EditorWrapper::Vst2EditorWrapper (AudioEffect* effect, IEditController* controller)
122 : BaseEditorWrapper (controller), AEffEditor (effect)
123 {
124 }
125 
126 //------------------------------------------------------------------------
resizeView(IPlugView * view,ViewRect * newSize)127 tresult PLUGIN_API Vst2EditorWrapper::resizeView (IPlugView* view, ViewRect* newSize)
128 {
129 	tresult result = kResultFalse;
130 	if (view && newSize && effect)
131 	{
132 		if (areSizeEquals (*newSize, mViewRect))
133 			return kResultTrue;
134 
135 		auto* effectx = dynamic_cast<AudioEffectX*> (effect);
136 		if (effectx && effectx->sizeWindow (newSize->getWidth (), newSize->getHeight ()))
137 		{
138 			result = view->onSize (newSize);
139 		}
140 	}
141 
142 	return result;
143 }
144 
145 //------------------------------------------------------------------------
getRect(ERect ** rect)146 bool Vst2EditorWrapper::getRect (ERect** rect)
147 {
148 	ViewRect size;
149 	if (BaseEditorWrapper::getRect (size))
150 	{
151 		mERect.left = (VstInt16)size.left;
152 		mERect.top = (VstInt16)size.top;
153 		mERect.right = (VstInt16)size.right;
154 		mERect.bottom = (VstInt16)size.bottom;
155 
156 		*rect = &mERect;
157 		return true;
158 	}
159 
160 	*rect = nullptr;
161 	return false;
162 }
163 
164 //------------------------------------------------------------------------
open(void * ptr)165 bool Vst2EditorWrapper::open (void* ptr)
166 {
167 	AEffEditor::open (ptr);
168 	return BaseEditorWrapper::_open (ptr);
169 }
170 
171 //------------------------------------------------------------------------
_close()172 void Vst2EditorWrapper::_close ()
173 {
174 	BaseEditorWrapper::_close ();
175 	AEffEditor::close ();
176 }
177 
178 //------------------------------------------------------------------------
onKeyDown(VstKeyCode & keyCode)179 bool Vst2EditorWrapper::onKeyDown (VstKeyCode& keyCode)
180 {
181 	if (!mView)
182 		return false;
183 
184 	return mView->onKeyDown (VirtualKeyCodeToChar (keyCode.virt), keyCode.virt, keyCode.modifier) ==
185 	       kResultTrue;
186 }
187 
188 //------------------------------------------------------------------------
onKeyUp(VstKeyCode & keyCode)189 bool Vst2EditorWrapper::onKeyUp (VstKeyCode& keyCode)
190 {
191 	if (!mView)
192 		return false;
193 
194 	return mView->onKeyUp (VirtualKeyCodeToChar (keyCode.virt), keyCode.virt, keyCode.modifier) ==
195 	       kResultTrue;
196 }
197 
198 //------------------------------------------------------------------------
onWheel(float distance)199 bool Vst2EditorWrapper::onWheel (float distance)
200 {
201 	if (!mView)
202 		return false;
203 
204 	return mView->onWheel (distance) == kResultTrue;
205 }
206 
207 //------------------------------------------------------------------------
208 // Vst2MidiEventQueue Declaration
209 //------------------------------------------------------------------------
210 class Vst2MidiEventQueue
211 {
212 public:
213 //------------------------------------------------------------------------
214 	Vst2MidiEventQueue (int32 maxEventCount);
215 	~Vst2MidiEventQueue ();
216 
isEmpty() const217 	bool isEmpty () const { return eventList->numEvents == 0; }
218 	bool add (const VstMidiEvent& e);
219 	bool add (const VstMidiSysexEvent& e);
220 	void flush ();
221 
operator VstEvents*()222 	operator VstEvents* () { return eventList; }
223 //------------------------------------------------------------------------
224 protected:
225 	VstEvents* eventList;
226 	int32 maxEventCount;
227 };
228 
229 //------------------------------------------------------------------------
230 // Vst2MidiEventQueue Implementation
231 //------------------------------------------------------------------------
Vst2MidiEventQueue(int32 _maxEventCount)232 Vst2MidiEventQueue::Vst2MidiEventQueue (int32 _maxEventCount) : maxEventCount (_maxEventCount)
233 {
234 	eventList = (VstEvents*)new char[sizeof (VstEvents) + (maxEventCount - 2) * sizeof (VstEvent*)];
235 	eventList->numEvents = 0;
236 	eventList->reserved = 0;
237 
238 	auto eventSize = sizeof (VstMidiSysexEvent) > sizeof (VstMidiEvent) ?
239 	                      sizeof (VstMidiSysexEvent) :
240 	                      sizeof (VstMidiEvent);
241 
242 	for (int32 i = 0; i < maxEventCount; i++)
243 	{
244 		char* eventBuffer = new char[eventSize];
245 		memset (eventBuffer, 0, eventSize);
246 		eventList->events[i] = (VstEvent*)eventBuffer;
247 	}
248 }
249 
250 //------------------------------------------------------------------------
~Vst2MidiEventQueue()251 Vst2MidiEventQueue::~Vst2MidiEventQueue ()
252 {
253 	for (int32 i = 0; i < maxEventCount; i++)
254 		delete[] (char*) eventList->events[i];
255 
256 	delete[] (char*) eventList;
257 }
258 
259 //------------------------------------------------------------------------
add(const VstMidiEvent & e)260 bool Vst2MidiEventQueue::add (const VstMidiEvent& e)
261 {
262 	if (eventList->numEvents >= maxEventCount)
263 		return false;
264 
265 	auto* dst = (VstMidiEvent*)eventList->events[eventList->numEvents++];
266 	memcpy (dst, &e, sizeof (VstMidiEvent));
267 	dst->type = kVstMidiType;
268 	dst->byteSize = sizeof (VstMidiEvent);
269 	return true;
270 }
271 
272 //------------------------------------------------------------------------
add(const VstMidiSysexEvent & e)273 bool Vst2MidiEventQueue::add (const VstMidiSysexEvent& e)
274 {
275 	if (eventList->numEvents >= maxEventCount)
276 		return false;
277 
278 	auto* dst = (VstMidiSysexEvent*)eventList->events[eventList->numEvents++];
279 	memcpy (dst, &e, sizeof (VstMidiSysexEvent));
280 	dst->type = kVstSysExType;
281 	dst->byteSize = sizeof (VstMidiSysexEvent);
282 	return true;
283 }
284 
285 //------------------------------------------------------------------------
flush()286 void Vst2MidiEventQueue::flush ()
287 {
288 	eventList->numEvents = 0;
289 }
290 
291 //------------------------------------------------------------------------
292 // Vst2Wrapper
293 //------------------------------------------------------------------------
Vst2Wrapper(BaseWrapper::SVST3Config & config,audioMasterCallback audioMaster,VstInt32 vst2ID)294 Vst2Wrapper::Vst2Wrapper (BaseWrapper::SVST3Config& config, audioMasterCallback audioMaster,
295                           VstInt32 vst2ID)
296 : BaseWrapper (config), AudioEffectX (audioMaster, 0, 0)
297 {
298 	mUseExportedBypass = false;
299 	mUseIncIndex = true;
300 
301 	setUniqueID (vst2ID);
302 	canProcessReplacing (true); // supports replacing output
303 	programsAreChunks (true);
304 }
305 
306 //------------------------------------------------------------------------
~Vst2Wrapper()307 Vst2Wrapper::~Vst2Wrapper ()
308 {
309 	//! editor needs to be destroyed BEFORE DeinitModule. Therefore destroy it here already
310 	//  instead of AudioEffect destructor
311 	if (mEditor)
312 	{
313 		setEditor (nullptr);
314 		mEditor = nullptr;
315 	}
316 
317 	if (mVst2InputArrangement)
318 		free (mVst2InputArrangement);
319 	if (mVst2OutputArrangement)
320 		free (mVst2OutputArrangement);
321 
322 	delete mVst2OutputEvents;
323 	mVst2OutputEvents = nullptr;
324 }
325 
326 //------------------------------------------------------------------------
init()327 bool Vst2Wrapper::init ()
328 {
329 	if (strstr (mSubCategories, "Instrument"))
330 		isSynth (true);
331 
332 	bool res = BaseWrapper::init ();
333 
334 	numPrograms = cEffect.numPrograms = mNumPrograms;
335 
336 	if (mController)
337 	{
338 		if (BaseEditorWrapper::hasEditor (mController))
339 		{
340 			auto* _editor = new Vst2EditorWrapper (this, mController);
341 			_setEditor (_editor);
342 			setEditor (_editor);
343 		}
344 	}
345 	return res;
346 }
347 
348 //------------------------------------------------------------------------
_canDoubleReplacing(bool val)349 void Vst2Wrapper::_canDoubleReplacing (bool val)
350 {
351 	canDoubleReplacing (val);
352 }
353 
354 //------------------------------------------------------------------------
_setInitialDelay(uint32 delay)355 void Vst2Wrapper::_setInitialDelay (uint32 delay)
356 {
357 	setInitialDelay (static_cast<VstInt32> (delay));
358 }
359 
360 //------------------------------------------------------------------------
_noTail(bool val)361 void Vst2Wrapper::_noTail (bool val)
362 {
363 	noTail (val);
364 }
365 
366 //------------------------------------------------------------------------
setupBuses()367 void Vst2Wrapper::setupBuses ()
368 {
369 	BaseWrapper::setupBuses ();
370 
371 	if (mHasEventOutputBuses)
372 	{
373 		if (mVst2OutputEvents == nullptr)
374 			mVst2OutputEvents = new Vst2MidiEventQueue (kMaxEvents);
375 	}
376 	else
377 	{
378 		if (mVst2OutputEvents)
379 		{
380 			delete mVst2OutputEvents;
381 			mVst2OutputEvents = nullptr;
382 		}
383 	}
384 }
385 //------------------------------------------------------------------------
setupProcessTimeInfo()386 void Vst2Wrapper::setupProcessTimeInfo ()
387 {
388 	VstTimeInfo* vst2timeInfo = AudioEffectX::getTimeInfo (0xffffffff);
389 	if (vst2timeInfo)
390 	{
391 		const uint32 portableFlags =
392 		    ProcessContext::kPlaying | ProcessContext::kCycleActive | ProcessContext::kRecording |
393 		    ProcessContext::kSystemTimeValid | ProcessContext::kProjectTimeMusicValid |
394 		    ProcessContext::kBarPositionValid | ProcessContext::kCycleValid |
395 		    ProcessContext::kTempoValid | ProcessContext::kTimeSigValid |
396 		    ProcessContext::kSmpteValid | ProcessContext::kClockValid;
397 
398 		mProcessContext.state = ((uint32)vst2timeInfo->flags) & portableFlags;
399 		mProcessContext.sampleRate = vst2timeInfo->sampleRate;
400 		mProcessContext.projectTimeSamples = (TSamples)vst2timeInfo->samplePos;
401 
402 		if (mProcessContext.state & ProcessContext::kSystemTimeValid)
403 			mProcessContext.systemTime = (TSamples)vst2timeInfo->nanoSeconds;
404 		else
405 			mProcessContext.systemTime = 0;
406 
407 		if (mProcessContext.state & ProcessContext::kProjectTimeMusicValid)
408 			mProcessContext.projectTimeMusic = vst2timeInfo->ppqPos;
409 		else
410 			mProcessContext.projectTimeMusic = 0;
411 
412 		if (mProcessContext.state & ProcessContext::kBarPositionValid)
413 			mProcessContext.barPositionMusic = vst2timeInfo->barStartPos;
414 		else
415 			mProcessContext.barPositionMusic = 0;
416 
417 		if (mProcessContext.state & ProcessContext::kCycleValid)
418 		{
419 			mProcessContext.cycleStartMusic = vst2timeInfo->cycleStartPos;
420 			mProcessContext.cycleEndMusic = vst2timeInfo->cycleEndPos;
421 		}
422 		else
423 			mProcessContext.cycleStartMusic = mProcessContext.cycleEndMusic = 0.0;
424 
425 		if (mProcessContext.state & ProcessContext::kTempoValid)
426 			mProcessContext.tempo = vst2timeInfo->tempo;
427 		else
428 			mProcessContext.tempo = 120.0;
429 
430 		if (mProcessContext.state & ProcessContext::kTimeSigValid)
431 		{
432 			mProcessContext.timeSigNumerator = vst2timeInfo->timeSigNumerator;
433 			mProcessContext.timeSigDenominator = vst2timeInfo->timeSigDenominator;
434 		}
435 		else
436 			mProcessContext.timeSigNumerator = mProcessContext.timeSigDenominator = 4;
437 
438 		mProcessContext.frameRate.flags = 0;
439 		if (mProcessContext.state & ProcessContext::kSmpteValid)
440 		{
441 			mProcessContext.smpteOffsetSubframes = vst2timeInfo->smpteOffset;
442 			switch (vst2timeInfo->smpteFrameRate)
443 			{
444 				case kVstSmpte24fps: ///< 24 fps
445 					mProcessContext.frameRate.framesPerSecond = 24;
446 					break;
447 				case kVstSmpte25fps: ///< 25 fps
448 					mProcessContext.frameRate.framesPerSecond = 25;
449 					break;
450 				case kVstSmpte2997fps: ///< 29.97 fps
451 					mProcessContext.frameRate.framesPerSecond = 30;
452 					mProcessContext.frameRate.flags = FrameRate::kPullDownRate;
453 					break;
454 				case kVstSmpte30fps: ///< 30 fps
455 					mProcessContext.frameRate.framesPerSecond = 30;
456 					break;
457 				case kVstSmpte2997dfps: ///< 29.97 drop
458 					mProcessContext.frameRate.framesPerSecond = 30;
459 					mProcessContext.frameRate.flags =
460 					    FrameRate::kPullDownRate | FrameRate::kDropRate;
461 					break;
462 				case kVstSmpte30dfps: ///< 30 drop
463 					mProcessContext.frameRate.framesPerSecond = 30;
464 					mProcessContext.frameRate.flags = FrameRate::kDropRate;
465 					break;
466 				case kVstSmpteFilm16mm: // not a smpte rate
467 				case kVstSmpteFilm35mm:
468 					mProcessContext.state &= ~ProcessContext::kSmpteValid;
469 					break;
470 				case kVstSmpte239fps: ///< 23.9 fps
471 					mProcessContext.frameRate.framesPerSecond = 24;
472 					mProcessContext.frameRate.flags = FrameRate::kPullDownRate;
473 					break;
474 				case kVstSmpte249fps: ///< 24.9 fps
475 					mProcessContext.frameRate.framesPerSecond = 25;
476 					mProcessContext.frameRate.flags = FrameRate::kPullDownRate;
477 					break;
478 				case kVstSmpte599fps: ///< 59.9 fps
479 					mProcessContext.frameRate.framesPerSecond = 60;
480 					mProcessContext.frameRate.flags = FrameRate::kPullDownRate;
481 					break;
482 				case kVstSmpte60fps: ///< 60 fps
483 					mProcessContext.frameRate.framesPerSecond = 60;
484 					break;
485 				default: mProcessContext.state &= ~ProcessContext::kSmpteValid; break;
486 			}
487 		}
488 		else
489 		{
490 			mProcessContext.smpteOffsetSubframes = 0;
491 			mProcessContext.frameRate.framesPerSecond = 0;
492 		}
493 
494 		///< MIDI Clock Resolution (24 Per Quarter Note), can be negative (nearest)
495 		if (mProcessContext.state & ProcessContext::kClockValid)
496 			mProcessContext.samplesToNextClock = vst2timeInfo->samplesToNextClock;
497 		else
498 			mProcessContext.samplesToNextClock = 0;
499 
500 		mProcessData.processContext = &mProcessContext;
501 	}
502 	else
503 		mProcessData.processContext = nullptr;
504 }
505 
506 //------------------------------------------------------------------------
suspend()507 void Vst2Wrapper::suspend ()
508 {
509 	BaseWrapper::_suspend ();
510 }
511 
512 //------------------------------------------------------------------------
resume()513 void Vst2Wrapper::resume ()
514 {
515 	AudioEffectX::resume ();
516 	BaseWrapper::_resume ();
517 
518 	mChunk.setSize (0);
519 }
520 
521 //------------------------------------------------------------------------
startProcess()522 VstInt32 Vst2Wrapper::startProcess ()
523 {
524 	BaseWrapper::_startProcess ();
525 	return 0;
526 }
527 
528 //------------------------------------------------------------------------
stopProcess()529 VstInt32 Vst2Wrapper::stopProcess ()
530 {
531 	BaseWrapper::_stopProcess ();
532 	return 0;
533 }
534 
535 //------------------------------------------------------------------------
setSampleRate(float newSamplerate)536 void Vst2Wrapper::setSampleRate (float newSamplerate)
537 {
538 	BaseWrapper::_setSampleRate (newSamplerate);
539 	AudioEffectX::setSampleRate (mSampleRate);
540 }
541 
542 //------------------------------------------------------------------------
setBlockSize(VstInt32 newBlockSize)543 void Vst2Wrapper::setBlockSize (VstInt32 newBlockSize)
544 {
545 	if (BaseWrapper::_setBlockSize (newBlockSize))
546 		AudioEffectX::setBlockSize (newBlockSize);
547 }
548 
549 //------------------------------------------------------------------------
getParameter(VstInt32 index)550 float Vst2Wrapper::getParameter (VstInt32 index)
551 {
552 	return BaseWrapper::_getParameter (index);
553 }
554 
555 //------------------------------------------------------------------------
setParameter(VstInt32 index,float value)556 void Vst2Wrapper::setParameter (VstInt32 index, float value)
557 {
558 	if (!mController)
559 		return;
560 
561 	if (index < (int32)mParameterMap.size ())
562 	{
563 		ParamID id = mParameterMap.at (index).vst3ID;
564 		addParameterChange (id, (ParamValue)value, 0);
565 	}
566 }
567 
568 //------------------------------------------------------------------------
setProgram(VstInt32 program)569 void Vst2Wrapper::setProgram (VstInt32 program)
570 {
571 	if (mProgramParameterID != kNoParamId && mController != nullptr && mProgramParameterIdx != -1)
572 	{
573 		AudioEffectX::setProgram (program);
574 
575 		ParameterInfo paramInfo = {0};
576 		if (mController->getParameterInfo (mProgramParameterIdx, paramInfo) == kResultTrue)
577 		{
578 			if (paramInfo.stepCount > 0 && program <= paramInfo.stepCount)
579 			{
580 				ParamValue normalized = (ParamValue)program / (ParamValue)paramInfo.stepCount;
581 				addParameterChange (mProgramParameterID, normalized, 0);
582 			}
583 		}
584 	}
585 }
586 
587 //------------------------------------------------------------------------
setProgramName(char *)588 void Vst2Wrapper::setProgramName (char* /*name*/)
589 {
590 	// not supported in VST 3
591 }
592 
593 //------------------------------------------------------------------------
getProgramName(char * name)594 void Vst2Wrapper::getProgramName (char* name)
595 {
596 	// name of the current program. Limited to #kVstMaxProgNameLen.
597 	*name = 0;
598 	if (mUnitInfo)
599 	{
600 		ProgramListInfo listInfo = {0};
601 		if (mUnitInfo->getProgramListInfo (0, listInfo) == kResultTrue)
602 		{
603 			String128 tmp = {0};
604 			if (mUnitInfo->getProgramName (listInfo.id, curProgram, tmp) == kResultTrue)
605 			{
606 				String str (tmp);
607 				str.copyTo8 (name, 0, kVstMaxProgNameLen);
608 			}
609 		}
610 	}
611 }
612 
613 //------------------------------------------------------------------------
getProgramNameIndexed(VstInt32,VstInt32 index,char * name)614 bool Vst2Wrapper::getProgramNameIndexed (VstInt32, VstInt32 index, char* name)
615 {
616 	*name = 0;
617 	if (mUnitInfo)
618 	{
619 		ProgramListInfo listInfo = {0};
620 		if (mUnitInfo->getProgramListInfo (0, listInfo) == kResultTrue)
621 		{
622 			String128 tmp = {0};
623 			if (mUnitInfo->getProgramName (listInfo.id, index, tmp) == kResultTrue)
624 			{
625 				String str (tmp);
626 				str.copyTo8 (name, 0, kVstMaxProgNameLen);
627 				return true;
628 			}
629 		}
630 	}
631 
632 	return false;
633 }
634 
635 //------------------------------------------------------------------------
getParameterLabel(VstInt32 index,char * label)636 void Vst2Wrapper::getParameterLabel (VstInt32 index, char* label)
637 {
638 	// units in which parameter \e index is displayed (i.e. "sec", "dB", "type", etc...). Limited to
639 	// #kVstMaxParamStrLen.
640 	*label = 0;
641 	if (mController)
642 	{
643 		int32 vst3Index = mParameterMap.at (index).vst3Index;
644 
645 		ParameterInfo paramInfo = {0};
646 		if (mController->getParameterInfo (vst3Index, paramInfo) == kResultTrue)
647 		{
648 			String str (paramInfo.units);
649 			str.copyTo8 (label, 0, kVstMaxParamStrLen);
650 		}
651 	}
652 }
653 
654 //------------------------------------------------------------------------
getParameterDisplay(VstInt32 index,char * text)655 void Vst2Wrapper::getParameterDisplay (VstInt32 index, char* text)
656 {
657 	// string representation ("0.5", "-3", "PLATE", etc...) of the value of parameter \e index.
658 	// Limited to #kVstMaxParamStrLen.
659 	*text = 0;
660 	if (mController)
661 	{
662 		int32 vst3Index = mParameterMap.at (index).vst3Index;
663 
664 		ParameterInfo paramInfo = {0};
665 		if (mController->getParameterInfo (vst3Index, paramInfo) == kResultTrue)
666 		{
667 			String128 tmp = {0};
668 			ParamValue value = 0;
669 			if (!getLastParamChange (paramInfo.id, value))
670 				value = mController->getParamNormalized (paramInfo.id);
671 
672 			if (mController->getParamStringByValue (paramInfo.id, value, tmp) == kResultTrue)
673 			{
674 				String str (tmp);
675 				str.copyTo8 (text, 0, kVstMaxParamStrLen);
676 			}
677 		}
678 	}
679 }
680 
681 //------------------------------------------------------------------------
getParameterName(VstInt32 index,char * text)682 void Vst2Wrapper::getParameterName (VstInt32 index, char* text)
683 {
684 	// name ("Time", "Gain", "RoomType", etc...) of parameter \e index. Limited to
685 	// #kVstExtMaxParamStrLen.
686 	*text = 0;
687 	if (mController && index < (int32)mParameterMap.size ())
688 	{
689 		int32 vst3Index = mParameterMap.at (index).vst3Index;
690 
691 		ParameterInfo paramInfo = {0};
692 		if (mController->getParameterInfo (vst3Index, paramInfo) == kResultTrue)
693 		{
694 			String str;
695 			if (vst2WrapperFullParameterPath)
696 			{
697 				//! The parameter's name contains the unit path (e.g. "LFO 1.freq") as well
698 				if (mUnitInfo)
699 				{
700 					getUnitPath (paramInfo.unitId, str);
701 				}
702 			}
703 			str.append (paramInfo.title);
704 
705 			if (str.length () > kVstExtMaxParamStrLen)
706 			{
707 				//! In case the string's length exceeds the limit, try parameter's title without
708 				// unit path.
709 				str = paramInfo.title;
710 			}
711 			if (str.length () > kVstExtMaxParamStrLen)
712 			{
713 				str = paramInfo.shortTitle;
714 			}
715 			str.copyTo8 (text, 0, kVstExtMaxParamStrLen);
716 		}
717 	}
718 }
719 
720 //------------------------------------------------------------------------
canParameterBeAutomated(VstInt32 index)721 bool Vst2Wrapper::canParameterBeAutomated (VstInt32 index)
722 {
723 	if (mController && index < (int32)mParameterMap.size ())
724 	{
725 		int32 vst3Index = mParameterMap.at (index).vst3Index;
726 
727 		ParameterInfo paramInfo = {0};
728 		if (mController->getParameterInfo (vst3Index, paramInfo) == kResultTrue)
729 			return (paramInfo.flags & ParameterInfo::kCanAutomate) != 0;
730 	}
731 	return false;
732 }
733 
734 //------------------------------------------------------------------------
string2parameter(VstInt32 index,char * text)735 bool Vst2Wrapper::string2parameter (VstInt32 index, char* text)
736 {
737 	if (mController && index < (int32)mParameterMap.size ())
738 	{
739 		int32 vst3Index = mParameterMap.at (index).vst3Index;
740 
741 		ParameterInfo paramInfo = {0};
742 		if (mController->getParameterInfo (vst3Index, paramInfo) == kResultTrue)
743 		{
744 			TChar tString[1024] = {0};
745 			String tmp (text);
746 			tmp.copyTo16 (tString, 0, 1023);
747 
748 			ParamValue valueNormalized = 0.0;
749 
750 			if (mController->getParamValueByString (paramInfo.id, tString, valueNormalized))
751 			{
752 				setParameterAutomated (index, (float)valueNormalized);
753 				// TODO: check if setParameterAutomated is correct
754 			}
755 		}
756 	}
757 	return false;
758 }
759 
760 //------------------------------------------------------------------------
getParameterProperties(VstInt32 index,VstParameterProperties * p)761 bool Vst2Wrapper::getParameterProperties (VstInt32 index, VstParameterProperties* p)
762 {
763 	if (mController && index < (int32)mParameterMap.size ())
764 	{
765 		p->label[0] = 0;
766 		p->shortLabel[0] = 0;
767 
768 		int32 vst3Index = mParameterMap.at (index).vst3Index;
769 
770 		ParameterInfo paramInfo = {0};
771 		if (mController->getParameterInfo (vst3Index, paramInfo) == kResultTrue)
772 		{
773 			String str (paramInfo.title);
774 			str.copyTo8 (p->label, 0, kVstMaxLabelLen);
775 
776 			String str2 (paramInfo.shortTitle);
777 			str.copyTo8 (p->shortLabel, 0, kVstMaxShortLabelLen);
778 
779 			if (paramInfo.stepCount == 0) // continuous
780 			{
781 				p->flags |= kVstParameterCanRamp;
782 			}
783 			else if (paramInfo.stepCount == 1) // on / off
784 			{
785 				p->flags |= kVstParameterIsSwitch;
786 			}
787 			else
788 			{
789 				p->minInteger = 0;
790 				p->maxInteger = paramInfo.stepCount;
791 				p->flags |= kVstParameterUsesIntegerMinMax;
792 			}
793 
794 			return true;
795 		}
796 	}
797 	return false;
798 }
799 
800 //------------------------------------------------------------------------
getChunk(void ** data,bool isPreset)801 VstInt32 Vst2Wrapper::getChunk (void** data, bool isPreset)
802 {
803 	return BaseWrapper::_getChunk (data, isPreset);
804 }
805 
806 //------------------------------------------------------------------------
setChunk(void * data,VstInt32 byteSize,bool isPreset)807 VstInt32 Vst2Wrapper::setChunk (void* data, VstInt32 byteSize, bool isPreset)
808 {
809 	return BaseWrapper::_setChunk (data, byteSize, isPreset);
810 }
811 
812 //------------------------------------------------------------------------
vst3ToVst2SpeakerArr(SpeakerArrangement vst3Arr)813 VstInt32 Vst2Wrapper::vst3ToVst2SpeakerArr (SpeakerArrangement vst3Arr)
814 {
815 	switch (vst3Arr)
816 	{
817 		case SpeakerArr::kMono: return kSpeakerArrMono;
818 		case SpeakerArr::kStereo: return kSpeakerArrStereo;
819 		case SpeakerArr::kStereoSurround: return kSpeakerArrStereoSurround;
820 		case SpeakerArr::kStereoCenter: return kSpeakerArrStereoCenter;
821 		case SpeakerArr::kStereoSide: return kSpeakerArrStereoSide;
822 		case SpeakerArr::kStereoCLfe: return kSpeakerArrStereoCLfe;
823 		case SpeakerArr::k30Cine: return kSpeakerArr30Cine;
824 		case SpeakerArr::k30Music: return kSpeakerArr30Music;
825 		case SpeakerArr::k31Cine: return kSpeakerArr31Cine;
826 		case SpeakerArr::k31Music: return kSpeakerArr31Music;
827 		case SpeakerArr::k40Cine: return kSpeakerArr40Cine;
828 		case SpeakerArr::k40Music: return kSpeakerArr40Music;
829 		case SpeakerArr::k41Cine: return kSpeakerArr41Cine;
830 		case SpeakerArr::k41Music: return kSpeakerArr41Music;
831 		case SpeakerArr::k50: return kSpeakerArr50;
832 		case SpeakerArr::k51: return kSpeakerArr51;
833 		case SpeakerArr::k60Cine: return kSpeakerArr60Cine;
834 		case SpeakerArr::k60Music: return kSpeakerArr60Music;
835 		case SpeakerArr::k61Cine: return kSpeakerArr61Cine;
836 		case SpeakerArr::k61Music: return kSpeakerArr61Music;
837 		case SpeakerArr::k70Cine: return kSpeakerArr70Cine;
838 		case SpeakerArr::k70Music: return kSpeakerArr70Music;
839 		case SpeakerArr::k71Cine: return kSpeakerArr71Cine;
840 		case SpeakerArr::k71Music: return kSpeakerArr71Music;
841 		case SpeakerArr::k80Cine: return kSpeakerArr80Cine;
842 		case SpeakerArr::k80Music: return kSpeakerArr80Music;
843 		case SpeakerArr::k81Cine: return kSpeakerArr81Cine;
844 		case SpeakerArr::k81Music: return kSpeakerArr81Music;
845 		case SpeakerArr::k102: return kSpeakerArr102;
846 	}
847 
848 	return kSpeakerArrUserDefined;
849 }
850 
851 //------------------------------------------------------------------------
vst2ToVst3SpeakerArr(VstInt32 vst2Arr)852 SpeakerArrangement Vst2Wrapper::vst2ToVst3SpeakerArr (VstInt32 vst2Arr)
853 {
854 	switch (vst2Arr)
855 	{
856 		case kSpeakerArrMono: return SpeakerArr::kMono;
857 		case kSpeakerArrStereo: return SpeakerArr::kStereo;
858 		case kSpeakerArrStereoSurround: return SpeakerArr::kStereoSurround;
859 		case kSpeakerArrStereoCenter: return SpeakerArr::kStereoCenter;
860 		case kSpeakerArrStereoSide: return SpeakerArr::kStereoSide;
861 		case kSpeakerArrStereoCLfe: return SpeakerArr::kStereoCLfe;
862 		case kSpeakerArr30Cine: return SpeakerArr::k30Cine;
863 		case kSpeakerArr30Music: return SpeakerArr::k30Music;
864 		case kSpeakerArr31Cine: return SpeakerArr::k31Cine;
865 		case kSpeakerArr31Music: return SpeakerArr::k31Music;
866 		case kSpeakerArr40Cine: return SpeakerArr::k40Cine;
867 		case kSpeakerArr40Music: return SpeakerArr::k40Music;
868 		case kSpeakerArr41Cine: return SpeakerArr::k41Cine;
869 		case kSpeakerArr41Music: return SpeakerArr::k41Music;
870 		case kSpeakerArr50: return SpeakerArr::k50;
871 		case kSpeakerArr51: return SpeakerArr::k51;
872 		case kSpeakerArr60Cine: return SpeakerArr::k60Cine;
873 		case kSpeakerArr60Music: return SpeakerArr::k60Music;
874 		case kSpeakerArr61Cine: return SpeakerArr::k61Cine;
875 		case kSpeakerArr61Music: return SpeakerArr::k61Music;
876 		case kSpeakerArr70Cine: return SpeakerArr::k70Cine;
877 		case kSpeakerArr70Music: return SpeakerArr::k70Music;
878 		case kSpeakerArr71Cine: return SpeakerArr::k71Cine;
879 		case kSpeakerArr71Music: return SpeakerArr::k71Music;
880 		case kSpeakerArr80Cine: return SpeakerArr::k80Cine;
881 		case kSpeakerArr80Music: return SpeakerArr::k80Music;
882 		case kSpeakerArr81Cine: return SpeakerArr::k81Cine;
883 		case kSpeakerArr81Music: return SpeakerArr::k81Music;
884 		case kSpeakerArr102: return SpeakerArr::k102;
885 	}
886 
887 	return 0;
888 }
889 
890 //------------------------------------------------------------------------
vst3ToVst2Speaker(Vst::Speaker vst3Speaker)891 VstInt32 Vst2Wrapper::vst3ToVst2Speaker (Vst::Speaker vst3Speaker)
892 {
893 	switch (vst3Speaker)
894 	{
895 		case Vst::kSpeakerM: return ::kSpeakerM;
896 		case Vst::kSpeakerL: return ::kSpeakerL;
897 		case Vst::kSpeakerR: return ::kSpeakerR;
898 		case Vst::kSpeakerC: return ::kSpeakerC;
899 		case Vst::kSpeakerLfe: return ::kSpeakerLfe;
900 		case Vst::kSpeakerLs: return ::kSpeakerLs;
901 		case Vst::kSpeakerRs: return ::kSpeakerRs;
902 		case Vst::kSpeakerLc: return ::kSpeakerLc;
903 		case Vst::kSpeakerRc: return ::kSpeakerRc;
904 		case Vst::kSpeakerS: return ::kSpeakerS;
905 		case Vst::kSpeakerSl: return ::kSpeakerSl;
906 		case Vst::kSpeakerSr: return ::kSpeakerSr;
907 		case Vst::kSpeakerTc: return ::kSpeakerTm;
908 		case Vst::kSpeakerTfl: return ::kSpeakerTfl;
909 		case Vst::kSpeakerTfc: return ::kSpeakerTfc;
910 		case Vst::kSpeakerTfr: return ::kSpeakerTfr;
911 		case Vst::kSpeakerTrl: return ::kSpeakerTrl;
912 		case Vst::kSpeakerTrc: return ::kSpeakerTrc;
913 		case Vst::kSpeakerTrr: return ::kSpeakerTrr;
914 		case Vst::kSpeakerLfe2: return ::kSpeakerLfe2;
915 	}
916 	return ::kSpeakerUndefined;
917 }
918 
919 //------------------------------------------------------------------------
920 static const char* gSpeakerNames[] = {
921     "M", ///< Mono (M)
922     "L", ///< Left (L)
923     "R", ///< Right (R)
924     "C", ///< Center (C)
925     "Lfe", ///< Subbass (Lfe)
926     "Ls", ///< Left Surround (Ls)
927     "Rs", ///< Right Surround (Rs)
928     "Lc", ///< Left of Center (Lc)
929     "Rc", ///< Right of Center (Rc)
930     "Cs", ///< Center of Surround (Cs) = Surround (S)
931     "Sl", ///< Side Left (Sl)
932     "Sr", ///< Side Right (Sr)
933     "Tm", ///< Top Middle (Tm)
934     "Tfl", ///< Top Front Left (Tfl)
935     "Tfc", ///< Top Front Center (Tfc)
936     "Tfr", ///< Top Front Right (Tfr)
937     "Trl", ///< Top Rear Left (Trl)
938     "Trc", ///< Top Rear Center (Trc)
939     "Trr", ///< Top Rear Right (Trr)
940     "Lfe2" ///< Subbass 2 (Lfe2)
941 };
942 static const int32 kNumSpeakerNames = sizeof (gSpeakerNames) / sizeof (char*);
943 
944 //------------------------------------------------------------------------
pinIndexToBusChannel(BusDirection dir,VstInt32 pinIndex,int32 & busIndex,int32 & busChannel)945 bool Vst2Wrapper::pinIndexToBusChannel (BusDirection dir, VstInt32 pinIndex, int32& busIndex,
946                                         int32& busChannel)
947 {
948 	AudioBusBuffers* busBuffers = dir == kInput ? mProcessData.inputs : mProcessData.outputs;
949 	int32 busCount = dir == kInput ? mProcessData.numInputs : mProcessData.numOutputs;
950 	uint64 mainBusFlags = dir == kInput ? mMainAudioInputBuses : mMainAudioOutputBuses;
951 
952 	int32 sourceIndex = 0;
953 	for (busIndex = 0; busIndex < busCount; busIndex++)
954 	{
955 		AudioBusBuffers& buffers = busBuffers[busIndex];
956 		if (mainBusFlags & (uint64 (1) << busIndex))
957 		{
958 			for (busChannel = 0; busChannel < buffers.numChannels; busChannel++)
959 			{
960 				if (pinIndex == sourceIndex)
961 				{
962 					return true;
963 				}
964 				sourceIndex++;
965 			}
966 		}
967 	}
968 	return false;
969 }
970 
971 //------------------------------------------------------------------------
getPinProperties(BusDirection dir,VstInt32 pinIndex,VstPinProperties * properties)972 bool Vst2Wrapper::getPinProperties (BusDirection dir, VstInt32 pinIndex,
973                                     VstPinProperties* properties)
974 {
975 	int32 busIndex = -1;
976 	int32 busChannelIndex = -1;
977 
978 	if (pinIndexToBusChannel (dir, pinIndex, busIndex, busChannelIndex))
979 	{
980 		BusInfo busInfo = {0};
981 		if (mComponent && mComponent->getBusInfo (kAudio, dir, busIndex, busInfo) == kResultTrue)
982 		{
983 			properties->flags = kVstPinIsActive; // ????
984 
985 			String name (busInfo.name);
986 			name.copyTo8 (properties->label, 0, kVstMaxLabelLen);
987 
988 			if (busInfo.channelCount == 1)
989 			{
990 				properties->flags |= kVstPinUseSpeaker;
991 				properties->arrangementType = kSpeakerArrMono;
992 			}
993 			if (busInfo.channelCount == 2)
994 			{
995 				properties->flags |= kVstPinUseSpeaker;
996 				properties->flags |= kVstPinIsStereo;
997 				properties->arrangementType = kSpeakerArrStereo;
998 			}
999 			else if (busInfo.channelCount > 2)
1000 			{
1001 				Vst::SpeakerArrangement arr = 0;
1002 				if (mProcessor && mProcessor->getBusArrangement (dir, busIndex, arr) == kResultTrue)
1003 				{
1004 					properties->flags |= kVstPinUseSpeaker;
1005 					properties->arrangementType = vst3ToVst2SpeakerArr (arr);
1006 				}
1007 				else
1008 				{
1009 					return false;
1010 				}
1011 			}
1012 
1013 			return true;
1014 		}
1015 	}
1016 
1017 	return false;
1018 }
1019 
1020 //------------------------------------------------------------------------
getInputProperties(VstInt32 index,VstPinProperties * properties)1021 bool Vst2Wrapper::getInputProperties (VstInt32 index, VstPinProperties* properties)
1022 {
1023 	return getPinProperties (kInput, index, properties);
1024 }
1025 
1026 //------------------------------------------------------------------------
getOutputProperties(VstInt32 index,VstPinProperties * properties)1027 bool Vst2Wrapper::getOutputProperties (VstInt32 index, VstPinProperties* properties)
1028 {
1029 	return getPinProperties (kOutput, index, properties);
1030 }
1031 
1032 //------------------------------------------------------------------------
setSpeakerArrangement(VstSpeakerArrangement * pluginInput,VstSpeakerArrangement * pluginOutput)1033 bool Vst2Wrapper::setSpeakerArrangement (VstSpeakerArrangement* pluginInput,
1034                                          VstSpeakerArrangement* pluginOutput)
1035 {
1036 	if (!mProcessor || !mComponent)
1037 		return false;
1038 
1039 	Vst::SpeakerArrangement newInputArr = 0;
1040 	Vst::SpeakerArrangement newOutputArr = 0;
1041 	Vst::SpeakerArrangement outputArr = 0;
1042 	Vst::SpeakerArrangement inputArr = 0;
1043 
1044 	int32 inputBusCount = mComponent->getBusCount (kAudio, kInput);
1045 	int32 outputBusCount = mComponent->getBusCount (kAudio, kOutput);
1046 
1047 	if (inputBusCount > 0)
1048 		if (mProcessor->getBusArrangement (kInput, 0, inputArr) != kResultTrue)
1049 			return false;
1050 	if (outputBusCount > 0)
1051 		if (mProcessor->getBusArrangement (kOutput, 0, outputArr) != kResultTrue)
1052 			return false;
1053 
1054 	if (pluginInput)
1055 	{
1056 		newInputArr = vst2ToVst3SpeakerArr (pluginInput->type);
1057 		if (newInputArr == 0)
1058 			return false;
1059 	}
1060 	if (pluginOutput)
1061 	{
1062 		newOutputArr = vst2ToVst3SpeakerArr (pluginOutput->type);
1063 		if (newOutputArr == 0)
1064 			return false;
1065 	}
1066 
1067 	if (newInputArr == 0)
1068 		newInputArr = inputArr;
1069 	if (newOutputArr == 0)
1070 		newOutputArr = outputArr;
1071 
1072 	if (newInputArr != inputArr || newOutputArr != outputArr)
1073 	{
1074 		if (mProcessor->setBusArrangements (
1075 		        &newInputArr, (newInputArr > 0 && inputBusCount > 0) ? 1 : 0, &newOutputArr,
1076 		        (newOutputArr > 0 && outputBusCount > 0) ? 1 : 0) != kResultTrue)
1077 			return false;
1078 
1079 		restartComponent (kIoChanged);
1080 	}
1081 
1082 	return true;
1083 }
1084 
1085 //------------------------------------------------------------------------
setupVst2Arrangement(VstSpeakerArrangement * & vst2arr,Vst::SpeakerArrangement vst3Arrangement)1086 void Vst2Wrapper::setupVst2Arrangement (VstSpeakerArrangement*& vst2arr,
1087                                         Vst::SpeakerArrangement vst3Arrangement)
1088 {
1089 	int32 numChannels = Vst::SpeakerArr::getChannelCount (vst3Arrangement);
1090 
1091 	if (vst2arr && (numChannels == 0 || (numChannels > vst2arr->numChannels && numChannels > 8)))
1092 	{
1093 		free (vst2arr);
1094 		vst2arr = nullptr;
1095 		if (numChannels == 0)
1096 			return;
1097 	}
1098 
1099 	if (vst2arr == nullptr)
1100 	{
1101 		int32 channelOverhead = numChannels > 8 ? numChannels - 8 : 0;
1102 		uint32 structSize =
1103 		    sizeof (VstSpeakerArrangement) + channelOverhead * sizeof (VstSpeakerProperties);
1104 		vst2arr = (VstSpeakerArrangement*)malloc (structSize);
1105 		memset (vst2arr, 0, structSize);
1106 	}
1107 
1108 	if (vst2arr)
1109 	{
1110 		vst2arr->type = vst3ToVst2SpeakerArr (vst3Arrangement);
1111 		vst2arr->numChannels = numChannels;
1112 
1113 		Speaker vst3TestSpeaker = 1;
1114 
1115 		for (int32 i = 0; i < numChannels; i++)
1116 		{
1117 			VstSpeakerProperties& props = vst2arr->speakers[i];
1118 
1119 			// find nextSpeaker in vst3 arrangement
1120 			Speaker vst3Speaker = 0;
1121 			while (vst3Speaker == 0 && vst3TestSpeaker != 0)
1122 			{
1123 				if (vst3Arrangement & vst3TestSpeaker)
1124 					vst3Speaker = vst3TestSpeaker;
1125 
1126 				vst3TestSpeaker <<= 1;
1127 			}
1128 
1129 			if (vst3Speaker)
1130 			{
1131 				props.type = vst3ToVst2Speaker (vst3Speaker);
1132 				if (props.type >= 0 && props.type < kNumSpeakerNames)
1133 					strncpy (props.name, gSpeakerNames[props.type], kVstMaxNameLen);
1134 				else
1135 					sprintf (props.name, "%ld", i + 1);
1136 			}
1137 		}
1138 	}
1139 }
1140 
1141 //------------------------------------------------------------------------
getSpeakerArrangement(VstSpeakerArrangement ** pluginInput,VstSpeakerArrangement ** pluginOutput)1142 bool Vst2Wrapper::getSpeakerArrangement (VstSpeakerArrangement** pluginInput,
1143                                          VstSpeakerArrangement** pluginOutput)
1144 {
1145 	if (!mProcessor)
1146 		return false;
1147 
1148 	Vst::SpeakerArrangement inputArr = 0;
1149 	Vst::SpeakerArrangement outputArr = 0;
1150 
1151 	if (mProcessor->getBusArrangement (kInput, 0, inputArr) != kResultTrue)
1152 		inputArr = 0;
1153 
1154 	if (mProcessor->getBusArrangement (kOutput, 0, outputArr) != kResultTrue)
1155 		outputArr = 0;
1156 
1157 	setupVst2Arrangement (mVst2InputArrangement, inputArr);
1158 	setupVst2Arrangement (mVst2OutputArrangement, outputArr);
1159 
1160 	*pluginInput = mVst2InputArrangement;
1161 	*pluginOutput = mVst2OutputArrangement;
1162 
1163 	return mVst2InputArrangement != nullptr && mVst2OutputArrangement != nullptr;
1164 }
1165 
1166 //------------------------------------------------------------------------
setBypass(bool onOff)1167 bool Vst2Wrapper::setBypass (bool onOff)
1168 {
1169 	return BaseWrapper::_setBypass (onOff);
1170 }
1171 
1172 //-----------------------------------------------------------------------------
setProcessPrecision(VstInt32 precision)1173 bool Vst2Wrapper::setProcessPrecision (VstInt32 precision)
1174 {
1175 	int32 newVst3SampleSize = -1;
1176 
1177 	if (precision == kVstProcessPrecision32)
1178 		newVst3SampleSize = kSample32;
1179 	else if (precision == kVstProcessPrecision64)
1180 		newVst3SampleSize = kSample64;
1181 
1182 	if (newVst3SampleSize != mVst3SampleSize)
1183 	{
1184 		if (mProcessor && mProcessor->canProcessSampleSize (newVst3SampleSize) == kResultTrue)
1185 		{
1186 			mVst3SampleSize = newVst3SampleSize;
1187 			setupProcessing ();
1188 
1189 			setupBuses ();
1190 
1191 			return true;
1192 		}
1193 		return false;
1194 	}
1195 	return true;
1196 }
1197 
1198 //-----------------------------------------------------------------------------
getNumMidiInputChannels()1199 VstInt32 Vst2Wrapper::getNumMidiInputChannels ()
1200 {
1201 	if (!mComponent)
1202 		return 0;
1203 
1204 	int32 busCount = mComponent->getBusCount (kEvent, kInput);
1205 	if (busCount > 0)
1206 	{
1207 		BusInfo busInfo = {0};
1208 		if (mComponent->getBusInfo (kEvent, kInput, 0, busInfo) == kResultTrue)
1209 		{
1210 			return busInfo.channelCount;
1211 		}
1212 	}
1213 	return 0;
1214 }
1215 
1216 //-----------------------------------------------------------------------------
getNumMidiOutputChannels()1217 VstInt32 Vst2Wrapper::getNumMidiOutputChannels ()
1218 {
1219 	if (!mComponent)
1220 		return 0;
1221 
1222 	int32 busCount = mComponent->getBusCount (kEvent, kOutput);
1223 	if (busCount > 0)
1224 	{
1225 		BusInfo busInfo = {0};
1226 		if (mComponent->getBusInfo (kEvent, kOutput, 0, busInfo) == kResultTrue)
1227 		{
1228 			return busInfo.channelCount;
1229 		}
1230 	}
1231 	return 0;
1232 }
1233 
1234 //-----------------------------------------------------------------------------
getGetTailSize()1235 VstInt32 Vst2Wrapper::getGetTailSize ()
1236 {
1237 	if (mProcessor)
1238 		return static_cast<VstInt32> (mProcessor->getTailSamples ());
1239 
1240 	return 0;
1241 }
1242 
1243 //-----------------------------------------------------------------------------
getEffectName(char * effectName)1244 bool Vst2Wrapper::getEffectName (char* effectName)
1245 {
1246 	if (mName[0])
1247 	{
1248 		strncpy (effectName, mName, kVstMaxEffectNameLen);
1249 		return true;
1250 	}
1251 	return false;
1252 }
1253 
1254 //-----------------------------------------------------------------------------
getVendorString(char * text)1255 bool Vst2Wrapper::getVendorString (char* text)
1256 {
1257 	if (mVendor[0])
1258 	{
1259 		strncpy (text, mVendor, kVstMaxVendorStrLen);
1260 		return true;
1261 	}
1262 	return false;
1263 }
1264 
1265 //-----------------------------------------------------------------------------
getVendorVersion()1266 VstInt32 Vst2Wrapper::getVendorVersion ()
1267 {
1268 	return mVersion;
1269 }
1270 
1271 //-----------------------------------------------------------------------------
vendorSpecific(VstInt32 lArg,VstIntPtr lArg2,void * ptrArg,float floatArg)1272 VstIntPtr Vst2Wrapper::vendorSpecific (VstInt32 lArg, VstIntPtr lArg2, void* ptrArg, float floatArg)
1273 {
1274 	switch (lArg)
1275 	{
1276 		case 'stCA':
1277 		case 'stCa':
1278 			switch (lArg2)
1279 			{
1280 				//--- -------
1281 				case 'FUID':
1282 					if (ptrArg && mVst3EffectClassID.isValid ())
1283 					{
1284 						memcpy ((char*)ptrArg, mVst3EffectClassID, 16);
1285 						return 1;
1286 					}
1287 					break;
1288 				//--- -------
1289 				case 'Whee':
1290 					if (editor)
1291 						editor->onWheel (floatArg);
1292 					return 1;
1293 					break;
1294 			}
1295 	}
1296 
1297 	return AudioEffectX::vendorSpecific (lArg, lArg2, ptrArg, floatArg);
1298 }
1299 
1300 //-----------------------------------------------------------------------------
getPlugCategory()1301 VstPlugCategory Vst2Wrapper::getPlugCategory ()
1302 {
1303 	if (mSubCategories[0])
1304 	{
1305 		if (strstr (mSubCategories, "Analyzer"))
1306 			return kPlugCategAnalysis;
1307 
1308 		else if (strstr (mSubCategories, "Delay") || strstr (mSubCategories, "Reverb"))
1309 			return kPlugCategRoomFx;
1310 
1311 		else if (strstr (mSubCategories, "Dynamics") || strstr (mSubCategories, "Mastering"))
1312 			return kPlugCategMastering;
1313 
1314 		else if (strstr (mSubCategories, "Restoration"))
1315 			return kPlugCategRestoration;
1316 
1317 		else if (strstr (mSubCategories, "Generator"))
1318 			return kPlugCategGenerator;
1319 
1320 		else if (strstr (mSubCategories, "Spatial"))
1321 			return kPlugCategSpacializer;
1322 
1323 		else if (strstr (mSubCategories, "Fx"))
1324 			return kPlugCategEffect;
1325 
1326 		else if (strstr (mSubCategories, "Instrument"))
1327 			return kPlugCategSynth;
1328 	}
1329 	return kPlugCategUnknown;
1330 }
1331 
1332 //-----------------------------------------------------------------------------
canDo(char * text)1333 VstInt32 Vst2Wrapper::canDo (char* text)
1334 {
1335 	if (stricmp (text, "sendVstEvents") == 0)
1336 	{
1337 		return -1;
1338 	}
1339 	else if (stricmp (text, "sendVstMidiEvent") == 0)
1340 	{
1341 		return mHasEventOutputBuses ? 1 : -1;
1342 	}
1343 	else if (stricmp (text, "receiveVstEvents") == 0)
1344 	{
1345 		return -1;
1346 	}
1347 	else if (stricmp (text, "receiveVstMidiEvent") == 0)
1348 	{
1349 		return mHasEventInputBuses ? 1 : -1;
1350 	}
1351 	else if (stricmp (text, "receiveVstTimeInfo") == 0)
1352 	{
1353 		return 1;
1354 	}
1355 	else if (stricmp (text, "offline") == 0)
1356 	{
1357 		if (mProcessing)
1358 			return 0;
1359 		if (mVst3processMode == kOffline)
1360 			return 1;
1361 
1362 		bool canOffline = setupProcessing (kOffline);
1363 		setupProcessing ();
1364 		return canOffline ? 1 : -1;
1365 	}
1366 	else if (stricmp (text, "midiProgramNames") == 0)
1367 	{
1368 		if (mUnitInfo)
1369 		{
1370 			UnitID unitId = -1;
1371 			if (mUnitInfo->getUnitByBus (kEvent, kInput, 0, 0, unitId) == kResultTrue &&
1372 			    unitId >= 0)
1373 				return 1;
1374 		}
1375 		return -1;
1376 	}
1377 	else if (stricmp (text, "bypass") == 0)
1378 	{
1379 		return mBypassParameterID != kNoParamId ? 1 : -1;
1380 	}
1381 	return 0; // do not know
1382 }
1383 
1384 //-----------------------------------------------------------------------------
getMidiProgramName(VstInt32 channel,MidiProgramName * midiProgramName)1385 VstInt32 Vst2Wrapper::getMidiProgramName (VstInt32 channel, MidiProgramName* midiProgramName)
1386 {
1387 	UnitID unitId;
1388 	ProgramListID programListId;
1389 	if (mUnitInfo && getProgramListAndUnit (channel, unitId, programListId))
1390 	{
1391 		if (midiProgramName)
1392 			setupMidiProgram (channel, programListId, *midiProgramName);
1393 
1394 		ProgramListInfo programListInfo;
1395 		if (getProgramListInfoByProgramListID (programListId, programListInfo))
1396 			return programListInfo.programCount;
1397 	}
1398 	return 0;
1399 }
1400 
1401 //-----------------------------------------------------------------------------
getCurrentMidiProgram(VstInt32 channel,MidiProgramName * currentProgram)1402 VstInt32 Vst2Wrapper::getCurrentMidiProgram (VstInt32 channel, MidiProgramName* currentProgram)
1403 {
1404 	if (mUnitInfo && mController)
1405 	{
1406 		UnitID unitId;
1407 		ProgramListID programListId;
1408 		if (getProgramListAndUnit (channel, unitId, programListId))
1409 		{
1410 			// find program selector parameter
1411 			int32 parameterCount = mController->getParameterCount ();
1412 			for (int32 i = 0; i < parameterCount; i++)
1413 			{
1414 				ParameterInfo parameterInfo = {0};
1415 				if (mController->getParameterInfo (i, parameterInfo) == kResultTrue)
1416 				{
1417 					if ((parameterInfo.flags & ParameterInfo::kIsProgramChange) != 0 &&
1418 					    parameterInfo.unitId == unitId)
1419 					{
1420 						ParamValue normalized = mController->getParamNormalized (parameterInfo.id);
1421 						int32 discreteValue =
1422 						    Min<int32> ((int32) (normalized * (parameterInfo.stepCount + 1)),
1423 						                parameterInfo.stepCount);
1424 
1425 						if (currentProgram)
1426 						{
1427 							currentProgram->thisProgramIndex = discreteValue;
1428 							setupMidiProgram (channel, programListId, *currentProgram);
1429 						}
1430 
1431 						return discreteValue;
1432 					}
1433 				}
1434 			}
1435 		}
1436 	}
1437 
1438 	return 0;
1439 }
1440 
1441 //-----------------------------------------------------------------------------
setupMidiProgram(int32 midiChannel,ProgramListID programListId,MidiProgramName & midiProgramName)1442 bool Vst2Wrapper::setupMidiProgram (int32 midiChannel, ProgramListID programListId,
1443                                     MidiProgramName& midiProgramName)
1444 {
1445 	if (mUnitInfo)
1446 	{
1447 		String128 string128 = {0};
1448 
1449 		if (mUnitInfo->getProgramName (programListId, midiProgramName.thisProgramIndex,
1450 		                               string128) == kResultTrue)
1451 		{
1452 			String str (string128);
1453 			str.copyTo8 (midiProgramName.name, 0, 64);
1454 
1455 			midiProgramName.midiProgram = static_cast<char8> (midiProgramName.thisProgramIndex);
1456 			midiProgramName.midiBankMsb = -1;
1457 			midiProgramName.midiBankLsb = -1;
1458 			midiProgramName.parentCategoryIndex = -1;
1459 			midiProgramName.flags = 0;
1460 
1461 			if (mUnitInfo->getProgramInfo (programListId, midiProgramName.thisProgramIndex,
1462 			                               PresetAttributes::kInstrument, string128) == kResultTrue)
1463 			{
1464 				midiProgramName.parentCategoryIndex =
1465 				    lookupProgramCategory (midiChannel, string128);
1466 			}
1467 			return true;
1468 		}
1469 	}
1470 	return false;
1471 }
1472 
1473 //-----------------------------------------------------------------------------
lookupProgramCategory(int32 midiChannel,String128 instrumentAttribute)1474 int32 Vst2Wrapper::lookupProgramCategory (int32 midiChannel, String128 instrumentAttribute)
1475 {
1476 	std::vector<ProgramCategory>& channelCategories = mProgramCategories[midiChannel];
1477 
1478 	for (uint32 categoryIndex = 0; categoryIndex < channelCategories.size (); categoryIndex++)
1479 	{
1480 		ProgramCategory& cat = channelCategories[categoryIndex];
1481 		if (memcmp (instrumentAttribute, cat.vst3InstrumentAttribute, sizeof (String128)) == 0)
1482 			return static_cast<int32> (categoryIndex);
1483 	}
1484 
1485 	return -1;
1486 }
1487 
1488 //-----------------------------------------------------------------------------
makeCategoriesRecursive(std::vector<ProgramCategory> & channelCategories,String128 vst3Category)1489 uint32 Vst2Wrapper::makeCategoriesRecursive (std::vector<ProgramCategory>& channelCategories,
1490                                              String128 vst3Category)
1491 {
1492 	for (uint32 categoryIndex = 0; categoryIndex < channelCategories.size (); categoryIndex++)
1493 	{
1494 		ProgramCategory& cat = channelCategories[categoryIndex];
1495 		if (memcmp (vst3Category, cat.vst3InstrumentAttribute, sizeof (String128)) == 0)
1496 		{
1497 			return categoryIndex;
1498 		}
1499 	}
1500 
1501 	int32 parentCategorIndex = -1;
1502 
1503 	String128 str;
1504 	String strAcc (str);
1505 	strAcc.copyTo16 (vst3Category, 0, 127);
1506 	int32 len = strAcc.length ();
1507 	String singleName;
1508 
1509 	char16 divider = '|';
1510 	for (int32 strIndex = len - 1; strIndex >= 0; strIndex--)
1511 	{
1512 		bool isDivider = str[strIndex] == divider;
1513 		str[strIndex] = 0; // zero out rest
1514 		if (isDivider)
1515 		{
1516 			singleName.assign (vst3Category + strIndex + 1);
1517 			parentCategorIndex = static_cast<int32> (makeCategoriesRecursive (channelCategories, str));
1518 			break;
1519 		}
1520 	}
1521 
1522 	// make new
1523 	ProgramCategory cat = {};
1524 	memcpy (cat.vst3InstrumentAttribute, vst3Category, sizeof (String128));
1525 	singleName.copyTo8 (cat.vst2Category.name, 0, kVstMaxNameLen);
1526 	cat.vst2Category.parentCategoryIndex = parentCategorIndex;
1527 	cat.vst2Category.thisCategoryIndex = (int32)channelCategories.size ();
1528 
1529 	channelCategories.push_back (cat);
1530 
1531 	return cat.vst2Category.thisCategoryIndex;
1532 }
1533 
1534 //-----------------------------------------------------------------------------
setupProgramCategories()1535 void Vst2Wrapper::setupProgramCategories ()
1536 {
1537 	mProgramCategories.clear ();
1538 	if (mUnitInfo && mComponent)
1539 	{
1540 		if (mComponent->getBusCount (kEvent, kInput) > 0)
1541 		{
1542 			for (int32 channel = 0; channel < 16; channel++) // the 16 channels
1543 			{
1544 				// make vector for channel
1545 				mProgramCategories.push_back (std::vector<ProgramCategory> ());
1546 				std::vector<ProgramCategory>& channelCategories = mProgramCategories[channel];
1547 
1548 				// scan program list of channel and find categories
1549 				UnitID unitId;
1550 				ProgramListID programListId;
1551 				if (getProgramListAndUnit (channel, unitId, programListId))
1552 				{
1553 					ProgramListInfo programListInfo;
1554 					if (getProgramListInfoByProgramListID (programListId, programListInfo))
1555 					{
1556 						for (int32 programIndex = 0; programIndex < programListInfo.programCount;
1557 						     programIndex++)
1558 						{
1559 							String128 string128 = {0};
1560 							if (mUnitInfo->getProgramInfo (programListId, programIndex,
1561 							                               PresetAttributes::kInstrument,
1562 							                               string128) == kResultTrue)
1563 							{
1564 								makeCategoriesRecursive (channelCategories, string128);
1565 							}
1566 						}
1567 					}
1568 				}
1569 			}
1570 		}
1571 	}
1572 }
1573 
1574 //-----------------------------------------------------------------------------
getMidiProgramCategory(VstInt32 channel,MidiProgramCategory * category)1575 VstInt32 Vst2Wrapper::getMidiProgramCategory (VstInt32 channel, MidiProgramCategory* category)
1576 {
1577 	// try to rebuild it each time
1578 	setupProgramCategories ();
1579 
1580 	if (channel >= (VstInt32)mProgramCategories.size ())
1581 		return 0;
1582 
1583 	std::vector<ProgramCategory>& channelCategories = mProgramCategories[channel];
1584 	if (category && category->thisCategoryIndex < (VstInt32)channelCategories.size ())
1585 	{
1586 		ProgramCategory& cat = channelCategories[category->thisCategoryIndex];
1587 		if (cat.vst2Category.thisCategoryIndex == category->thisCategoryIndex)
1588 			memcpy (category, &cat.vst2Category, sizeof (MidiProgramCategory));
1589 	}
1590 	return (VstInt32)channelCategories.size ();
1591 }
1592 
1593 //-----------------------------------------------------------------------------
hasMidiProgramsChanged(VstInt32)1594 bool Vst2Wrapper::hasMidiProgramsChanged (VstInt32 /*channel*/)
1595 {
1596 	// names of programs or program categories have changed
1597 	return false;
1598 }
1599 
1600 //-----------------------------------------------------------------------------
getMidiKeyName(VstInt32 channel,MidiKeyName * keyName)1601 bool Vst2Wrapper::getMidiKeyName (VstInt32 channel, MidiKeyName* keyName)
1602 {
1603 	UnitID unitId;
1604 	ProgramListID programListId;
1605 	if (mUnitInfo && getProgramListAndUnit (channel, unitId, programListId))
1606 	{
1607 		String128 string128 = {0};
1608 		if (mUnitInfo->getProgramPitchName (programListId, keyName->thisProgramIndex,
1609 		                                    keyName->thisKeyNumber, string128))
1610 		{
1611 			String str (string128);
1612 			str.copyTo8 (keyName->keyName, 0, kVstMaxNameLen);
1613 			return true;
1614 		}
1615 	}
1616 	return false;
1617 }
1618 
1619 //-----------------------------------------------------------------------------
setupParameters()1620 void Vst2Wrapper::setupParameters ()
1621 {
1622 	BaseWrapper::setupParameters ();
1623 	cEffect.numParams = mNumParams;
1624 }
1625 
1626 //-----------------------------------------------------------------------------
processEvents(VstEvents * events)1627 VstInt32 Vst2Wrapper::processEvents (VstEvents* events)
1628 {
1629 	if (mInputEvents == nullptr)
1630 		return 0;
1631 	mInputEvents->clear ();
1632 
1633 	for (int32 i = 0; i < events->numEvents; i++)
1634 	{
1635 		VstEvent* e = events->events[i];
1636 		if (e->type == kVstMidiType)
1637 		{
1638 			auto* midiEvent = (VstMidiEvent*)e;
1639 			Event toAdd = {0, midiEvent->deltaFrames, 0};
1640 			processMidiEvent (toAdd, &midiEvent->midiData[0],
1641 			                  midiEvent->flags & kVstMidiEventIsRealtime, midiEvent->noteLength,
1642 			                  midiEvent->noteOffVelocity * kMidiScaler, midiEvent->detune);
1643 		}
1644 		//--- -----------------------------
1645 		else if (e->type == kVstSysExType)
1646 		{
1647 			Event toAdd = {0, e->deltaFrames};
1648 			VstMidiSysexEvent& src = *(VstMidiSysexEvent*)e;
1649 			toAdd.type = Event::kDataEvent;
1650 			toAdd.data.type = DataEvent::kMidiSysEx;
1651 			toAdd.data.size = src.dumpBytes;
1652 			toAdd.data.bytes = (uint8*)src.sysexDump;
1653 			mInputEvents->addEvent (toAdd);
1654 		}
1655 	}
1656 
1657 	return 0;
1658 }
1659 
1660 //-----------------------------------------------------------------------------
processOutputEvents()1661 inline void Vst2Wrapper::processOutputEvents ()
1662 {
1663 	if (mVst2OutputEvents && mOutputEvents && mOutputEvents->getEventCount () > 0)
1664 	{
1665 		mVst2OutputEvents->flush ();
1666 
1667 		Event e = {0};
1668 		for (int32 i = 0, total = mOutputEvents->getEventCount (); i < total; i++)
1669 		{
1670 			if (mOutputEvents->getEvent (i, e) != kResultOk)
1671 				break;
1672 
1673 			//---SysExclusif----------------
1674 			if (e.type == Event::kDataEvent && e.data.type == DataEvent::kMidiSysEx)
1675 			{
1676 				VstMidiSysexEvent sysexEvent = {0};
1677 				sysexEvent.deltaFrames = e.sampleOffset;
1678 				sysexEvent.dumpBytes = e.data.size;
1679 				sysexEvent.sysexDump = (char*)e.data.bytes;
1680 
1681 				if (!mVst2OutputEvents->add (sysexEvent))
1682 					break;
1683 			}
1684 			else
1685 			{
1686 				VstMidiEvent midiEvent = {0};
1687 				midiEvent.deltaFrames = e.sampleOffset;
1688 				if (e.flags & Event::kIsLive)
1689 					midiEvent.flags = kVstMidiEventIsRealtime;
1690 				char* midiData = midiEvent.midiData;
1691 
1692 				switch (e.type)
1693 				{
1694 					//--- ---------------------
1695 					case Event::kNoteOnEvent:
1696 						midiData[0] = (char)(kNoteOn | (e.noteOn.channel & kChannelMask));
1697 						midiData[1] = (char)(e.noteOn.pitch & kDataMask);
1698 						midiData[2] =
1699 						    (char)((int32) (e.noteOn.velocity * 127.f + 0.4999999f) & kDataMask);
1700 						if (midiData[2] == 0) // zero velocity => note off
1701 							midiData[0] = (char)(kNoteOff | (e.noteOn.channel & kChannelMask));
1702 						midiEvent.detune = (char)e.noteOn.tuning;
1703 						midiEvent.noteLength = e.noteOn.length;
1704 						break;
1705 
1706 					//--- ---------------------
1707 					case Event::kNoteOffEvent:
1708 						midiData[0] = (char)(kNoteOff | (e.noteOff.channel & kChannelMask));
1709 						midiData[1] = (char)(e.noteOff.pitch & kDataMask);
1710 						midiData[2] = midiEvent.noteOffVelocity =
1711 						    (char)((int32) (e.noteOff.velocity * 127.f + 0.4999999f) & kDataMask);
1712 						break;
1713 
1714 						break;
1715 				}
1716 
1717 				if (!mVst2OutputEvents->add (midiEvent))
1718 					break;
1719 			}
1720 		}
1721 
1722 		mOutputEvents->clear ();
1723 
1724 		sendVstEventsToHost (*mVst2OutputEvents);
1725 	}
1726 }
1727 
1728 //-----------------------------------------------------------------------------
updateProcessLevel()1729 void Vst2Wrapper::updateProcessLevel ()
1730 {
1731 	auto currentLevel = getCurrentProcessLevel ();
1732 	if (mCurrentProcessLevel != currentLevel)
1733 	{
1734 		mCurrentProcessLevel = currentLevel;
1735 		if (mCurrentProcessLevel == kVstProcessLevelOffline)
1736 			mVst3processMode = kOffline;
1737 		else
1738 			mVst3processMode = kRealtime;
1739 
1740 		bool callStartStop = mProcessing;
1741 
1742 		if (callStartStop)
1743 			stopProcess ();
1744 
1745 		setupProcessing ();
1746 
1747 		if (callStartStop)
1748 			startProcess ();
1749 	}
1750 }
1751 
1752 //-----------------------------------------------------------------------------
processReplacing(float ** inputs,float ** outputs,VstInt32 sampleFrames)1753 void Vst2Wrapper::processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames)
1754 {
1755 	updateProcessLevel ();
1756 
1757 	_processReplacing (inputs, outputs, sampleFrames);
1758 }
1759 
1760 //-----------------------------------------------------------------------------
processDoubleReplacing(double ** inputs,double ** outputs,VstInt32 sampleFrames)1761 void Vst2Wrapper::processDoubleReplacing (double** inputs, double** outputs, VstInt32 sampleFrames)
1762 {
1763 	updateProcessLevel ();
1764 
1765 	_processDoubleReplacing (inputs, outputs, sampleFrames);
1766 }
1767 
1768 //-----------------------------------------------------------------------------
1769 // static
1770 //-----------------------------------------------------------------------------
create(IPluginFactory * factory,const TUID vst3ComponentID,VstInt32 vst2ID,audioMasterCallback audioMaster)1771 AudioEffect* Vst2Wrapper::create (IPluginFactory* factory, const TUID vst3ComponentID,
1772                                   VstInt32 vst2ID, audioMasterCallback audioMaster)
1773 {
1774 	if (!factory)
1775 		return nullptr;
1776 
1777 	BaseWrapper::SVST3Config config;
1778 	config.factory = factory;
1779 	config.processor = nullptr;
1780 
1781 	FReleaser factoryReleaser (factory);
1782 
1783 	factory->createInstance (vst3ComponentID, IAudioProcessor::iid, (void**)&config.processor);
1784 	if (config.processor)
1785 	{
1786 		config.controller = nullptr;
1787 		if (config.processor->queryInterface (IEditController::iid, (void**)&config.controller) !=
1788 		    kResultTrue)
1789 		{
1790 			FUnknownPtr<IComponent> component (config.processor);
1791 			if (component)
1792 			{
1793 				TUID editorCID;
1794 				if (component->getControllerClassId (editorCID) == kResultTrue)
1795 				{
1796 					factory->createInstance (editorCID, IEditController::iid,
1797 					                         (void**)&config.controller);
1798 				}
1799 			}
1800 		}
1801 
1802 		config.vst3ComponentID = FUID::fromTUID (vst3ComponentID);
1803 
1804 		auto* wrapper = new Vst2Wrapper (config, audioMaster, vst2ID);
1805 		FUnknownPtr<IPluginFactory2> factory2 (factory);
1806 		if (factory2)
1807 		{
1808 			PFactoryInfo factoryInfo;
1809 			if (factory2->getFactoryInfo (&factoryInfo) == kResultTrue)
1810 				wrapper->setVendorName (factoryInfo.vendor);
1811 
1812 			for (int32 i = 0; i < factory2->countClasses (); i++)
1813 			{
1814 				Steinberg::PClassInfo2 classInfo2;
1815 				if (factory2->getClassInfo2 (i, &classInfo2) == Steinberg::kResultTrue)
1816 				{
1817 					if (memcmp (classInfo2.cid, vst3ComponentID, sizeof (TUID)) == 0)
1818 					{
1819 						wrapper->setSubCategories (classInfo2.subCategories);
1820 						wrapper->setEffectName (classInfo2.name);
1821 						wrapper->setEffectVersion (classInfo2.version);
1822 
1823 						if (classInfo2.vendor[0] != 0)
1824 							wrapper->setVendorName (classInfo2.vendor);
1825 
1826 						break;
1827 					}
1828 				}
1829 			}
1830 		}
1831 
1832 		if (wrapper->init () == false)
1833 		{
1834 			wrapper->release ();
1835 			return nullptr;
1836 		}
1837 
1838 		return wrapper;
1839 	}
1840 
1841 	return nullptr;
1842 }
1843 
1844 //-----------------------------------------------------------------------------
getName(String128 name)1845 tresult PLUGIN_API Vst2Wrapper::getName (String128 name)
1846 {
1847 	char8 productString[128];
1848 	if (getHostProductString (productString))
1849 	{
1850 		String str (productString);
1851 		str.copyTo16 (name, 0, 127);
1852 
1853 		return kResultTrue;
1854 	}
1855 	return kResultFalse;
1856 }
1857 
1858 //-----------------------------------------------------------------------------
1859 // IComponentHandler
1860 //-----------------------------------------------------------------------------
beginEdit(ParamID tag)1861 tresult PLUGIN_API Vst2Wrapper::beginEdit (ParamID tag)
1862 {
1863 	std::map<ParamID, int32>::const_iterator iter = mParamIndexMap.find (tag);
1864 	if (iter != mParamIndexMap.end ())
1865 		AudioEffectX::beginEdit ((*iter).second);
1866 	return kResultTrue;
1867 }
1868 
1869 //-----------------------------------------------------------------------------
performEdit(ParamID tag,ParamValue valueNormalized)1870 tresult PLUGIN_API Vst2Wrapper::performEdit (ParamID tag, ParamValue valueNormalized)
1871 {
1872 	std::map<ParamID, int32>::const_iterator iter = mParamIndexMap.find (tag);
1873 	if (iter != mParamIndexMap.end () && audioMaster)
1874 		audioMaster (&cEffect, audioMasterAutomate, (*iter).second, 0, nullptr,
1875 		             (float)valueNormalized); // value is in opt
1876 
1877 	mInputTransfer.addChange (tag, valueNormalized, 0);
1878 
1879 	return kResultTrue;
1880 }
1881 
1882 //-----------------------------------------------------------------------------
endEdit(ParamID tag)1883 tresult PLUGIN_API Vst2Wrapper::endEdit (ParamID tag)
1884 {
1885 	std::map<ParamID, int32>::const_iterator iter = mParamIndexMap.find (tag);
1886 	if (iter != mParamIndexMap.end ())
1887 		AudioEffectX::endEdit ((*iter).second);
1888 	return kResultTrue;
1889 }
1890 
1891 //-----------------------------------------------------------------------------
_ioChanged()1892 void Vst2Wrapper::_ioChanged ()
1893 {
1894 	BaseWrapper::_ioChanged ();
1895 	ioChanged ();
1896 }
1897 
1898 //-----------------------------------------------------------------------------
_updateDisplay()1899 void Vst2Wrapper::_updateDisplay ()
1900 {
1901 	BaseWrapper::_updateDisplay ();
1902 	updateDisplay ();
1903 }
1904 
1905 //-----------------------------------------------------------------------------
_setNumInputs(uint32 inputs)1906 void Vst2Wrapper::_setNumInputs (uint32 inputs)
1907 {
1908 	BaseWrapper::_setNumInputs (inputs);
1909 	setNumInputs (static_cast<VstInt32> (inputs));
1910 }
1911 
1912 //-----------------------------------------------------------------------------
_setNumOutputs(uint32 outputs)1913 void Vst2Wrapper::_setNumOutputs (uint32 outputs)
1914 {
1915 	BaseWrapper::_setNumOutputs (outputs);
1916 	setNumOutputs (static_cast<VstInt32> (outputs));
1917 }
1918 
1919 //-----------------------------------------------------------------------------
_sizeWindow(int32 width,int32 height)1920 bool Vst2Wrapper::_sizeWindow (int32 width, int32 height)
1921 {
1922 	return sizeWindow (width, height);
1923 }
1924 
1925 //-----------------------------------------------------------------------------
1926 } // namespace Vst
1927 } // namespace Steinberg
1928 
1929 extern bool InitModule ();
1930 
1931 //-----------------------------------------------------------------------------
1932 extern "C" {
1933 
1934 //-----------------------------------------------------------------------------
1935 /** Prototype of the export function main */
1936 //-----------------------------------------------------------------------------
VSTPluginMain(audioMasterCallback audioMaster)1937 SMTG_EXPORT_SYMBOL AEffect* VSTPluginMain (audioMasterCallback audioMaster)
1938 {
1939 	// Get VST Version of the host
1940 	if (!audioMaster (nullptr, audioMasterVersion, 0, 0, nullptr, 0))
1941 		return nullptr; // old version
1942 
1943 	if (InitModule () == false)
1944 		return nullptr;
1945 
1946 	// Create the AudioEffect
1947 	AudioEffect* effect = createEffectInstance (audioMaster);
1948 	if (!effect)
1949 		return nullptr;
1950 
1951 	// Return the VST AEffect structure
1952 	return effect->getAeffect ();
1953 }
1954 
1955 //-----------------------------------------------------------------------------
1956 // support for old hosts not looking for VSTPluginMain
1957 #if (TARGET_API_MAC_CARBON && __ppc__)
main_macho(audioMasterCallback audioMaster)1958 SMTG_EXPORT_SYMBOL AEffect* main_macho (audioMasterCallback audioMaster)
1959 {
1960 	return VSTPluginMain (audioMaster);
1961 }
1962 #elif WIN32
MAIN(audioMasterCallback audioMaster)1963 SMTG_EXPORT_SYMBOL AEffect* MAIN (audioMasterCallback audioMaster)
1964 {
1965 	return VSTPluginMain (audioMaster);
1966 }
1967 #elif BEOS
main_plugin(audioMasterCallback audioMaster)1968 SMTG_EXPORT_SYMBOL AEffect* main_plugin (audioMasterCallback audioMaster)
1969 {
1970 	return VSTPluginMain (audioMaster);
1971 }
1972 #endif
1973 
1974 } // extern "C"
1975 //-----------------------------------------------------------------------------
1976 
1977 /// \endcond
1978