Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3106 lines
89KB

  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) 2017, 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. /// \cond ignore
  37. #include "public.sdk/source/vst/vst2wrapper/vst2wrapper.h"
  38. #include "public.sdk/source/vst/hosting/hostclasses.h"
  39. #include "public.sdk/source/vst2.x/aeffeditor.h"
  40. #include "pluginterfaces/gui/iplugview.h"
  41. #include "pluginterfaces/vst/ivstmidicontrollers.h"
  42. #include "pluginterfaces/vst/ivstmessage.h"
  43. #include "pluginterfaces/vst/vstpresetkeys.h"
  44. #include "pluginterfaces/base/futils.h"
  45. #include "pluginterfaces/base/keycodes.h"
  46. #include "base/source/fstreamer.h"
  47. #include <cstdlib>
  48. #include <cstdio>
  49. #include <limits>
  50. extern bool DeinitModule (); //! Called in Vst2Wrapper destructor
  51. //------------------------------------------------------------------------
  52. // some Defines
  53. //------------------------------------------------------------------------
  54. // should be kVstMaxParamStrLen if we want to respect the VST 2 specification!!!
  55. #define kVstExtMaxParamStrLen 32
  56. //------------------------------------------------------------------------
  57. namespace Steinberg {
  58. namespace Vst {
  59. //! The parameter's name contains the unit path (e.g. "Modulators.LFO 1.frequency")
  60. bool vst2WrapperFullParameterPath = true;
  61. //------------------------------------------------------------------------
  62. // some Globals
  63. //------------------------------------------------------------------------
  64. // In order to speed up hasEditor function gPluginHasEditor can be set in EditController::initialize
  65. enum
  66. {
  67. kDontKnow = -1,
  68. kNoEditor = 0,
  69. kEditor,
  70. };
  71. // default: kDontKnow which uses createView to find out
  72. typedef int32 EditorAvailability;
  73. EditorAvailability gPluginHasEditor = kDontKnow;
  74. // Set to 'true' in EditController::initialize
  75. // default: VST 3 kIsProgramChange parameter will not be exported in VST 2
  76. bool gExportProgramChangeParameters = false;
  77. //------------------------------------------------------------------------
  78. // Vst2EditorWrapper Declaration
  79. //------------------------------------------------------------------------
  80. class Vst2EditorWrapper : public AEffEditor, public IPlugFrame
  81. {
  82. public:
  83. //------------------------------------------------------------------------
  84. Vst2EditorWrapper (AudioEffect* effect, IEditController* controller);
  85. ~Vst2EditorWrapper ();
  86. static bool hasEditor (IEditController* controller);
  87. virtual bool getRect (ERect** rect);
  88. virtual bool open (void* ptr);
  89. virtual void close ();
  90. virtual bool setKnobMode (VstInt32 val);
  91. ///< Receives key down event. Return true only if key was really used!
  92. virtual bool onKeyDown (VstKeyCode& keyCode);
  93. ///< Receives key up event. Return true only if key was really used!
  94. virtual bool onKeyUp (VstKeyCode& keyCode);
  95. ///< Handles mouse wheel event, distance is positive or negative to indicate wheel direction.
  96. virtual bool onWheel (float distance);
  97. // IPlugFrame
  98. virtual tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* newSize);
  99. virtual tresult PLUGIN_API queryInterface (const char* _iid, void** obj);
  100. virtual uint32 PLUGIN_API addRef () { return 1; }
  101. virtual uint32 PLUGIN_API release () { return 1; }
  102. //------------------------------------------------------------------------
  103. protected:
  104. void createView ();
  105. IEditController* mController;
  106. IPlugView* mView;
  107. ERect mERect;
  108. };
  109. //------------------------------------------------------------------------
  110. // Vst2EditorWrapper Implementation
  111. //------------------------------------------------------------------------
  112. Vst2EditorWrapper::Vst2EditorWrapper (AudioEffect* effect, IEditController* controller)
  113. : AEffEditor (effect), mController (controller), mView (0)
  114. {
  115. if (mController)
  116. mController->addRef ();
  117. }
  118. //------------------------------------------------------------------------
  119. Vst2EditorWrapper::~Vst2EditorWrapper ()
  120. {
  121. if (mView)
  122. close ();
  123. if (mController)
  124. mController->release ();
  125. }
  126. //------------------------------------------------------------------------
  127. tresult PLUGIN_API Vst2EditorWrapper::queryInterface (const char* _iid, void** obj)
  128. {
  129. QUERY_INTERFACE (_iid, obj, FUnknown::iid, FUnknown)
  130. QUERY_INTERFACE (_iid, obj, IPlugFrame::iid, IPlugFrame)
  131. *obj = 0;
  132. return kNoInterface;
  133. }
  134. //------------------------------------------------------------------------
  135. tresult PLUGIN_API Vst2EditorWrapper::resizeView (IPlugView* view, ViewRect* newSize)
  136. {
  137. tresult result = kResultFalse;
  138. if (view && newSize)
  139. {
  140. if (effect)
  141. {
  142. AudioEffectX* effectx = dynamic_cast<AudioEffectX*> (effect);
  143. if (effectx && effectx->sizeWindow (newSize->getWidth (), newSize->getHeight ()))
  144. {
  145. #if MAC
  146. ViewRect nSize (0, 0, newSize->right - newSize->left, newSize->bottom - newSize->top);
  147. result = view->onSize (&nSize);
  148. #else
  149. result = view->onSize (newSize);
  150. #endif
  151. }
  152. }
  153. }
  154. return result;
  155. }
  156. //------------------------------------------------------------------------
  157. bool Vst2EditorWrapper::hasEditor (IEditController* controller)
  158. {
  159. /* Some Plug-ins might have large GUIs. In order to speed up hasEditor function while
  160. * initializing the Plug-in gPluginHasEditor can be set in EditController::initialize
  161. * beforehand. */
  162. bool result = false;
  163. if (gPluginHasEditor == kEditor)
  164. {
  165. result = true;
  166. }
  167. else if (gPluginHasEditor == kNoEditor)
  168. {
  169. result = false;
  170. }
  171. else
  172. {
  173. IPlugView* view = controller ? controller->createView (ViewType::kEditor) : 0;
  174. FReleaser viewRel (view);
  175. result = (view != 0);
  176. }
  177. return result;
  178. }
  179. //------------------------------------------------------------------------
  180. void Vst2EditorWrapper::createView ()
  181. {
  182. if (mView == 0 && mController != 0)
  183. {
  184. mView = mController->createView (ViewType::kEditor);
  185. mView->setFrame (this);
  186. #if MAC
  187. #if PLATFORM_64
  188. if (mView && mView->isPlatformTypeSupported (kPlatformTypeNSView) != kResultTrue)
  189. #else
  190. if (mView && mView->isPlatformTypeSupported (kPlatformTypeHIView) != kResultTrue)
  191. #endif
  192. {
  193. mView->release ();
  194. mView = nullptr;
  195. mController->release (); // do not try again
  196. mController = nullptr;
  197. }
  198. #endif
  199. }
  200. }
  201. //------------------------------------------------------------------------
  202. bool Vst2EditorWrapper::getRect (ERect** rect)
  203. {
  204. createView ();
  205. if (mView)
  206. {
  207. ViewRect size;
  208. if (mView->getSize (&size) == kResultTrue)
  209. {
  210. mERect.left = (VstInt16)size.left;
  211. mERect.top = (VstInt16)size.top;
  212. mERect.right = (VstInt16)size.right;
  213. mERect.bottom = (VstInt16)size.bottom;
  214. if ((mERect.bottom - mERect.top) > 0 && (mERect.right - mERect.left) > 0)
  215. {
  216. *rect = &mERect;
  217. return true;
  218. }
  219. }
  220. }
  221. *rect = 0;
  222. return false;
  223. }
  224. //------------------------------------------------------------------------
  225. bool Vst2EditorWrapper::open (void* ptr)
  226. {
  227. AEffEditor::open (ptr);
  228. createView ();
  229. if (mView)
  230. {
  231. #if WINDOWS
  232. FIDString type = kPlatformTypeHWND;
  233. #elif MAC && PLATFORM_64
  234. FIDString type = kPlatformTypeNSView;
  235. #elif MAC
  236. FIDString type = kPlatformTypeHIView;
  237. #endif
  238. return mView->attached (ptr, type) == kResultTrue;
  239. }
  240. return false;
  241. }
  242. //------------------------------------------------------------------------
  243. void Vst2EditorWrapper::close ()
  244. {
  245. if (mView)
  246. {
  247. mView->setFrame (0);
  248. mView->removed ();
  249. mView->release ();
  250. mView = nullptr;
  251. }
  252. AEffEditor::close ();
  253. }
  254. //------------------------------------------------------------------------
  255. bool Vst2EditorWrapper::setKnobMode (VstInt32 val)
  256. {
  257. bool result = false;
  258. IEditController2* editController2;
  259. if (mController &&
  260. mController->queryInterface (IEditController2::iid, (void**)&editController2) ==
  261. kResultTrue)
  262. {
  263. switch (val)
  264. {
  265. // Circular
  266. case 0:
  267. result = editController2->setKnobMode (Vst::kCircularMode) == kResultTrue;
  268. break;
  269. // Relative Circular
  270. case 1:
  271. result = editController2->setKnobMode (kRelativCircularMode) == kResultTrue;
  272. break;
  273. // Linear
  274. case 2: result = editController2->setKnobMode (kLinearMode) == kResultTrue; break;
  275. }
  276. editController2->release ();
  277. }
  278. return result;
  279. }
  280. //------------------------------------------------------------------------
  281. bool Vst2EditorWrapper::onKeyDown (VstKeyCode& keyCode)
  282. {
  283. if (mView)
  284. return mView->onKeyDown (VirtualKeyCodeToChar (keyCode.virt), keyCode.virt,
  285. keyCode.modifier) == kResultTrue;
  286. return false;
  287. }
  288. //------------------------------------------------------------------------
  289. bool Vst2EditorWrapper::onKeyUp (VstKeyCode& keyCode)
  290. {
  291. if (mView)
  292. return mView->onKeyUp (VirtualKeyCodeToChar (keyCode.virt), keyCode.virt,
  293. keyCode.modifier) == kResultTrue;
  294. return false;
  295. }
  296. //------------------------------------------------------------------------
  297. bool Vst2EditorWrapper::onWheel (float distance)
  298. {
  299. if (mView)
  300. return mView->onWheel (distance) == kResultTrue;
  301. return false;
  302. }
  303. //------------------------------------------------------------------------
  304. // Vst2MidiEventQueue Declaration
  305. //------------------------------------------------------------------------
  306. class Vst2MidiEventQueue
  307. {
  308. public:
  309. //------------------------------------------------------------------------
  310. Vst2MidiEventQueue (int32 maxEventCount);
  311. ~Vst2MidiEventQueue ();
  312. bool isEmpty () const { return eventList->numEvents == 0; }
  313. bool add (const VstMidiEvent& e);
  314. bool add (const VstMidiSysexEvent& e);
  315. void flush ();
  316. operator VstEvents* () { return eventList; }
  317. //------------------------------------------------------------------------
  318. protected:
  319. VstEvents* eventList;
  320. int32 maxEventCount;
  321. };
  322. //------------------------------------------------------------------------
  323. // Vst2MidiEventQueue Implementation
  324. //------------------------------------------------------------------------
  325. Vst2MidiEventQueue::Vst2MidiEventQueue (int32 maxEventCount) : maxEventCount (maxEventCount)
  326. {
  327. eventList = (VstEvents*)new char[sizeof (VstEvents) + (maxEventCount - 2) * sizeof (VstEvent*)];
  328. eventList->numEvents = 0;
  329. eventList->reserved = 0;
  330. int32 eventSize = sizeof (VstMidiSysexEvent) > sizeof (VstMidiEvent) ?
  331. sizeof (VstMidiSysexEvent) :
  332. sizeof (VstMidiEvent);
  333. for (int32 i = 0; i < maxEventCount; i++)
  334. {
  335. char* eventBuffer = new char[eventSize];
  336. memset (eventBuffer, 0, eventSize);
  337. eventList->events[i] = (VstEvent*)eventBuffer;
  338. }
  339. }
  340. //------------------------------------------------------------------------
  341. Vst2MidiEventQueue::~Vst2MidiEventQueue ()
  342. {
  343. for (int32 i = 0; i < maxEventCount; i++)
  344. delete[] (char*) eventList->events[i];
  345. delete[] (char*) eventList;
  346. }
  347. //------------------------------------------------------------------------
  348. bool Vst2MidiEventQueue::add (const VstMidiEvent& e)
  349. {
  350. if (eventList->numEvents >= maxEventCount)
  351. return false;
  352. VstMidiEvent* dst = (VstMidiEvent*)eventList->events[eventList->numEvents++];
  353. memcpy (dst, &e, sizeof (VstMidiEvent));
  354. dst->type = kVstMidiType;
  355. dst->byteSize = sizeof (VstMidiEvent);
  356. return true;
  357. }
  358. //------------------------------------------------------------------------
  359. bool Vst2MidiEventQueue::add (const VstMidiSysexEvent& e)
  360. {
  361. if (eventList->numEvents >= maxEventCount)
  362. return false;
  363. VstMidiSysexEvent* dst = (VstMidiSysexEvent*)eventList->events[eventList->numEvents++];
  364. memcpy (dst, &e, sizeof (VstMidiSysexEvent));
  365. dst->type = kVstSysExType;
  366. dst->byteSize = sizeof (VstMidiSysexEvent);
  367. return true;
  368. }
  369. //------------------------------------------------------------------------
  370. void Vst2MidiEventQueue::flush ()
  371. {
  372. eventList->numEvents = 0;
  373. }
  374. //------------------------------------------------------------------------
  375. // MemoryStream with attributes to add information "preset or project"
  376. //------------------------------------------------------------------------
  377. class VstPresetStream : public MemoryStream, Vst::IStreamAttributes
  378. {
  379. public:
  380. VstPresetStream () {}
  381. VstPresetStream (void* memory, TSize memorySize) : MemoryStream (memory, memorySize) {}
  382. //---from Vst::IStreamAttributes-----
  383. virtual tresult PLUGIN_API getFileName (String128 name) SMTG_OVERRIDE { return kNotImplemented; }
  384. virtual IAttributeList* PLUGIN_API getAttributes () SMTG_OVERRIDE { return &attrList; }
  385. //------------------------------------------------------------------------
  386. DELEGATE_REFCOUNT (MemoryStream)
  387. virtual tresult PLUGIN_API queryInterface (const TUID iid, void** obj) SMTG_OVERRIDE
  388. {
  389. QUERY_INTERFACE (iid, obj, IStreamAttributes::iid, IStreamAttributes)
  390. return MemoryStream::queryInterface (iid, obj);
  391. }
  392. protected:
  393. HostAttributeList attrList;
  394. };
  395. //------------------------------------------------------------------------
  396. // Define the numeric max as "No ParamID"
  397. const ParamID kNoParamId = std::numeric_limits<ParamID>::max ();
  398. const int32 kMaxEvents = 2048;
  399. //------------------------------------------------------------------------
  400. // Vst2Wrapper
  401. //------------------------------------------------------------------------
  402. Vst2Wrapper::Vst2Wrapper (IAudioProcessor* processor, IEditController* controller,
  403. audioMasterCallback audioMaster, const TUID vst3ComponentID,
  404. VstInt32 vst2ID, IPluginFactory* factory)
  405. : AudioEffectX (audioMaster, 0, 0)
  406. , mVst2InputArrangement (nullptr)
  407. , mVst2OutputArrangement (nullptr)
  408. , mProcessor (processor)
  409. , mComponent (nullptr)
  410. , mController (controller)
  411. , mUnitInfo (nullptr)
  412. , mMidiMapping (nullptr)
  413. , componentInitialized (false)
  414. , controllerInitialized (false)
  415. , componentsConnected (false)
  416. , processing (false)
  417. , hasEventInputBuses (false)
  418. , hasEventOutputBuses (false)
  419. , mVst3SampleSize (kSample32)
  420. , mVst3processMode (kRealtime)
  421. , mBypassParameterID (kNoParamId)
  422. , mProgramParameterID (kNoParamId)
  423. , mProgramParameterIdx (-1)
  424. , mInputEvents (nullptr)
  425. , mOutputEvents (nullptr)
  426. , mVst2OutputEvents (nullptr)
  427. , mMainAudioInputBuses (0)
  428. , mMainAudioOutputBuses (0)
  429. , mTimer (nullptr)
  430. , mFactory (factory)
  431. {
  432. memset (mName, 0, sizeof (mName));
  433. memset (mVendor, 0, sizeof (mVendor));
  434. memset (mSubCategories, 0, sizeof (mSubCategories));
  435. memset (&mProcessContext, 0, sizeof (ProcessContext));
  436. mVersion = 0;
  437. for (int32 b = 0; b < kMaxMidiMappingBusses; b++)
  438. for (int32 i = 0; i < 16; i++)
  439. mMidiCCMapping[b][i] = 0;
  440. // VST 2 stuff -----------------------------------------------
  441. setUniqueID (vst2ID); // identify
  442. mVst3EffectClassID = vst3ComponentID;
  443. canProcessReplacing (true); // supports replacing output
  444. programsAreChunks (true);
  445. for (int32 i = 0; i < kMaxProgramChangeParameters; i++)
  446. {
  447. mProgramChangeParameterIDs[i] = kNoParamId;
  448. mProgramChangeParameterIdxs[i] = -1;
  449. }
  450. if (factory)
  451. factory->addRef ();
  452. }
  453. //------------------------------------------------------------------------
  454. bool Vst2Wrapper::init ()
  455. {
  456. // VST 3 stuff -----------------------------------------------
  457. if (mProcessor)
  458. mProcessor->queryInterface (IComponent::iid, (void**)&mComponent);
  459. if (mController)
  460. {
  461. mController->queryInterface (IUnitInfo::iid, (void**)&mUnitInfo);
  462. mController->queryInterface (IMidiMapping::iid, (void**)&mMidiMapping);
  463. }
  464. //---init the processor component
  465. componentInitialized = true;
  466. if (mComponent->initialize ((IHostApplication*)this) != kResultTrue)
  467. return false;
  468. //---init the controller component
  469. if (mController)
  470. {
  471. // do not initialize 2 times the component if it is singleComponent
  472. if (FUnknownPtr<IEditController> (mComponent).getInterface () != mController)
  473. {
  474. controllerInitialized = true;
  475. if (mController->initialize ((IHostApplication*)this) != kResultTrue)
  476. return false;
  477. }
  478. //---set this class as Component Handler
  479. mController->setComponentHandler (this);
  480. //---connect the 2 components
  481. FUnknownPtr<IConnectionPoint> cp1 (mProcessor);
  482. FUnknownPtr<IConnectionPoint> cp2 (mController);
  483. if (cp1 && cp2)
  484. {
  485. cp1->connect (cp2);
  486. cp2->connect (cp1);
  487. componentsConnected = true;
  488. }
  489. //---inform the component "controller" with the component "processor" state
  490. MemoryStream stream;
  491. if (mComponent->getState (&stream) == kResultTrue)
  492. {
  493. stream.seek (0, IBStream::kIBSeekSet, 0);
  494. mController->setComponentState (&stream);
  495. }
  496. }
  497. // VST 2 stuff -----------------------------------------------
  498. if (mProcessor)
  499. {
  500. if (mProcessor->canProcessSampleSize (kSample64) == kResultTrue)
  501. {
  502. canDoubleReplacing (); // supports double precision processing
  503. // we use the 64 as default only if 32 bit not supported
  504. if (mProcessor->canProcessSampleSize (kSample32) != kResultTrue)
  505. mVst3SampleSize = kSample64;
  506. else
  507. mVst3SampleSize = kSample32;
  508. }
  509. // latency -------------------------------
  510. setInitialDelay (mProcessor->getLatencySamples ());
  511. if (mProcessor->getTailSamples () == kNoTail)
  512. noTail (true);
  513. setupProcessing (); // initialize vst3 component processing parameters
  514. }
  515. // parameters
  516. setupParameters ();
  517. // setup inputs and outputs
  518. setupBuses ();
  519. if (mController)
  520. {
  521. if (Vst2EditorWrapper::hasEditor (mController))
  522. setEditor (new Vst2EditorWrapper (this, mController));
  523. }
  524. // find out programs of root unit --------------------------
  525. numPrograms = cEffect.numPrograms = 0;
  526. if (mUnitInfo)
  527. {
  528. int32 programListCount = mUnitInfo->getProgramListCount ();
  529. if (programListCount > 0)
  530. {
  531. ProgramListID rootUnitProgramListId = kNoProgramListId;
  532. for (int32 i = 0; i < mUnitInfo->getUnitCount (); i++)
  533. {
  534. UnitInfo unit = {0};
  535. if (mUnitInfo->getUnitInfo (i, unit) == kResultTrue)
  536. {
  537. if (unit.id == kRootUnitId)
  538. {
  539. rootUnitProgramListId = unit.programListId;
  540. break;
  541. }
  542. }
  543. }
  544. if (rootUnitProgramListId != kNoProgramListId)
  545. {
  546. for (int32 i = 0; i < programListCount; i++)
  547. {
  548. ProgramListInfo progList = {0};
  549. if (mUnitInfo->getProgramListInfo (i, progList) == kResultTrue)
  550. {
  551. if (progList.id == rootUnitProgramListId)
  552. {
  553. numPrograms = cEffect.numPrograms = progList.programCount;
  554. break;
  555. }
  556. }
  557. }
  558. }
  559. }
  560. }
  561. if (mTimer == 0)
  562. {
  563. mTimer = Timer::create (this, 50);
  564. }
  565. initMidiCtrlerAssignment ();
  566. return true;
  567. }
  568. //------------------------------------------------------------------------
  569. Vst2Wrapper::~Vst2Wrapper ()
  570. {
  571. if (mTimer)
  572. {
  573. mTimer->release ();
  574. mTimer = nullptr;
  575. }
  576. mProcessData.unprepare ();
  577. if (mVst2InputArrangement)
  578. free (mVst2InputArrangement);
  579. if (mVst2OutputArrangement)
  580. free (mVst2OutputArrangement);
  581. //---Disconnect components
  582. if (componentsConnected)
  583. {
  584. FUnknownPtr<IConnectionPoint> cp1 (mProcessor);
  585. FUnknownPtr<IConnectionPoint> cp2 (mController);
  586. if (cp1 && cp2)
  587. {
  588. cp1->disconnect (cp2);
  589. cp2->disconnect (cp1);
  590. }
  591. }
  592. //---Terminate Controller Component
  593. if (mController)
  594. {
  595. mController->setComponentHandler (0);
  596. if (controllerInitialized)
  597. mController->terminate ();
  598. controllerInitialized = false;
  599. }
  600. //---Terminate Processor Component
  601. if (mComponent && componentInitialized)
  602. {
  603. mComponent->terminate ();
  604. componentInitialized = false;
  605. }
  606. if (mUnitInfo)
  607. mUnitInfo->release ();
  608. if (mMidiMapping)
  609. mMidiMapping->release ();
  610. if (mMidiCCMapping[0])
  611. for (int32 b = 0; b < kMaxMidiMappingBusses; b++)
  612. for (int32 i = 0; i < 16; i++)
  613. delete mMidiCCMapping[b][i];
  614. if (mController)
  615. mController->release ();
  616. //! editor needs to be destroyed BEFORE DeinitModule. Therefore destroy it here already
  617. // instead of AudioEffect destructor
  618. delete editor;
  619. editor = nullptr;
  620. if (mComponent)
  621. mComponent->release ();
  622. if (mProcessor)
  623. mProcessor->release ();
  624. delete mInputEvents;
  625. delete mOutputEvents;
  626. delete mVst2OutputEvents;
  627. if (mFactory)
  628. mFactory->release ();
  629. DeinitModule ();
  630. }
  631. // VST 2
  632. //------------------------------------------------------------------------
  633. void Vst2Wrapper::suspend ()
  634. {
  635. stopProcess ();
  636. if (mComponent)
  637. mComponent->setActive (false);
  638. }
  639. //------------------------------------------------------------------------
  640. void Vst2Wrapper::resume ()
  641. {
  642. AudioEffectX::resume ();
  643. mChunk.setSize (0);
  644. if (mComponent)
  645. mComponent->setActive (true);
  646. }
  647. //------------------------------------------------------------------------
  648. VstInt32 Vst2Wrapper::startProcess ()
  649. {
  650. if (mProcessor && processing == false)
  651. {
  652. processing = true;
  653. mProcessor->setProcessing (true);
  654. }
  655. return 0;
  656. }
  657. //------------------------------------------------------------------------
  658. VstInt32 Vst2Wrapper::stopProcess ()
  659. {
  660. if (mProcessor && processing)
  661. {
  662. mProcessor->setProcessing (false);
  663. processing = false;
  664. }
  665. return 0;
  666. }
  667. //------------------------------------------------------------------------
  668. bool Vst2Wrapper::setupProcessing (int32 processModeOverwrite)
  669. {
  670. if (!mProcessor)
  671. return false;
  672. ProcessSetup setup;
  673. if (processModeOverwrite >= 0)
  674. setup.processMode = processModeOverwrite;
  675. else
  676. setup.processMode = mVst3processMode;
  677. setup.maxSamplesPerBlock = blockSize;
  678. setup.sampleRate = sampleRate;
  679. setup.symbolicSampleSize = mVst3SampleSize;
  680. return mProcessor->setupProcessing (setup) == kResultTrue;
  681. }
  682. //------------------------------------------------------------------------
  683. void Vst2Wrapper::setSampleRate (float newSamplerate)
  684. {
  685. if (processing)
  686. return;
  687. if (newSamplerate != sampleRate)
  688. {
  689. AudioEffectX::setSampleRate (newSamplerate);
  690. setupProcessing ();
  691. }
  692. }
  693. //------------------------------------------------------------------------
  694. void Vst2Wrapper::setBlockSize (VstInt32 newBlockSize)
  695. {
  696. if (processing)
  697. return;
  698. if (blockSize != newBlockSize)
  699. {
  700. AudioEffectX::setBlockSize (newBlockSize);
  701. setupProcessing ();
  702. }
  703. }
  704. //------------------------------------------------------------------------
  705. float Vst2Wrapper::getParameter (VstInt32 index)
  706. {
  707. if (!mController)
  708. return 0.f;
  709. if (index < (int32)mParameterMap.size ())
  710. {
  711. ParamID id = mParameterMap.at (index).vst3ID;
  712. return (float)mController->getParamNormalized (id);
  713. }
  714. return 0.f;
  715. }
  716. //------------------------------------------------------------------------
  717. void Vst2Wrapper::setParameter (VstInt32 index, float value)
  718. {
  719. if (!mController)
  720. return;
  721. if (index < (int32)mParameterMap.size ())
  722. {
  723. ParamID id = mParameterMap.at (index).vst3ID;
  724. addParameterChange (id, (ParamValue)value, 0);
  725. }
  726. }
  727. //------------------------------------------------------------------------
  728. void Vst2Wrapper::addParameterChange (ParamID id, ParamValue value, int32 sampleOffset)
  729. {
  730. mGuiTransfer.addChange (id, value, sampleOffset);
  731. mInputTransfer.addChange (id, value, sampleOffset);
  732. }
  733. //------------------------------------------------------------------------
  734. void Vst2Wrapper::setProgram (VstInt32 program)
  735. {
  736. if (mProgramParameterID != kNoParamId && mController != 0 && mProgramParameterIdx != -1)
  737. {
  738. AudioEffectX::setProgram (program);
  739. ParameterInfo paramInfo = {0};
  740. if (mController->getParameterInfo (mProgramParameterIdx, paramInfo) == kResultTrue)
  741. {
  742. if (paramInfo.stepCount > 0 && program <= paramInfo.stepCount)
  743. {
  744. ParamValue normalized = (ParamValue)program / (ParamValue)paramInfo.stepCount;
  745. addParameterChange (mProgramParameterID, normalized, 0);
  746. }
  747. }
  748. }
  749. }
  750. //------------------------------------------------------------------------
  751. void Vst2Wrapper::setProgramName (char* name)
  752. {
  753. // not supported in VST 3
  754. }
  755. //------------------------------------------------------------------------
  756. void Vst2Wrapper::getProgramName (char* name)
  757. {
  758. // name of the current program. Limited to #kVstMaxProgNameLen.
  759. *name = 0;
  760. if (mUnitInfo)
  761. {
  762. ProgramListInfo listInfo = {0};
  763. if (mUnitInfo->getProgramListInfo (0, listInfo) == kResultTrue)
  764. {
  765. String128 tmp = {0};
  766. if (mUnitInfo->getProgramName (listInfo.id, curProgram, tmp) == kResultTrue)
  767. {
  768. String str (tmp);
  769. str.copyTo8 (name, 0, kVstMaxProgNameLen);
  770. }
  771. }
  772. }
  773. }
  774. //------------------------------------------------------------------------
  775. bool Vst2Wrapper::getProgramNameIndexed (VstInt32, VstInt32 index, char* name)
  776. {
  777. *name = 0;
  778. if (mUnitInfo)
  779. {
  780. ProgramListInfo listInfo = {0};
  781. if (mUnitInfo->getProgramListInfo (0, listInfo) == kResultTrue)
  782. {
  783. String128 tmp = {0};
  784. if (mUnitInfo->getProgramName (listInfo.id, index, tmp) == kResultTrue)
  785. {
  786. String str (tmp);
  787. str.copyTo8 (name, 0, kVstMaxProgNameLen);
  788. return true;
  789. }
  790. }
  791. }
  792. return false;
  793. }
  794. //------------------------------------------------------------------------
  795. void Vst2Wrapper::getParameterLabel (VstInt32 index, char* label)
  796. {
  797. // units in which parameter \e index is displayed (i.e. "sec", "dB", "type", etc...). Limited to
  798. // #kVstMaxParamStrLen.
  799. *label = 0;
  800. if (mController)
  801. {
  802. int32 vst3Index = mParameterMap.at (index).vst3Index;
  803. ParameterInfo paramInfo = {0};
  804. if (mController->getParameterInfo (vst3Index, paramInfo) == kResultTrue)
  805. {
  806. String str (paramInfo.units);
  807. str.copyTo8 (label, 0, kVstMaxParamStrLen);
  808. }
  809. }
  810. }
  811. //------------------------------------------------------------------------
  812. /*! Usually VST 2 hosts call setParameter (...) and getParameterDisplay (...) synchronously.
  813. In setParameter (...) param changes get queued (guiTransfer) and transfered in idle (::onTimer).
  814. The ::onTimer call almost always comes AFTER getParameterDisplay (...) and therefore returns an
  815. old
  816. value. To avoid sending back old values, getLastParamChange (...) returns the latest value
  817. from the guiTransfer queue. */
  818. //------------------------------------------------------------------------
  819. bool Vst2Wrapper::getLastParamChange (ParamID id, ParamValue& value)
  820. {
  821. ParameterChanges changes;
  822. mGuiTransfer.transferChangesTo (changes);
  823. for (int32 i = 0; i < changes.getParameterCount (); ++i)
  824. {
  825. IParamValueQueue* queue = changes.getParameterData (i);
  826. if (queue)
  827. {
  828. if (queue->getParameterId () == id)
  829. {
  830. int32 points = queue->getPointCount ();
  831. if (points > 0)
  832. {
  833. mGuiTransfer.transferChangesFrom (changes);
  834. int32 sampleOffset = 0;
  835. return queue->getPoint (points - 1, sampleOffset, value) == kResultTrue;
  836. }
  837. }
  838. }
  839. }
  840. mGuiTransfer.transferChangesFrom (changes);
  841. return false;
  842. }
  843. //------------------------------------------------------------------------
  844. void Vst2Wrapper::getParameterDisplay (VstInt32 index, char* text)
  845. {
  846. // string representation ("0.5", "-3", "PLATE", etc...) of the value of parameter \e index.
  847. // Limited to #kVstMaxParamStrLen.
  848. *text = 0;
  849. if (mController)
  850. {
  851. int32 vst3Index = mParameterMap.at (index).vst3Index;
  852. ParameterInfo paramInfo = {0};
  853. if (mController->getParameterInfo (vst3Index, paramInfo) == kResultTrue)
  854. {
  855. String128 tmp = {0};
  856. ParamValue value = 0;
  857. if (!getLastParamChange (paramInfo.id, value))
  858. value = mController->getParamNormalized (paramInfo.id);
  859. if (mController->getParamStringByValue (paramInfo.id, value, tmp) == kResultTrue)
  860. {
  861. String str (tmp);
  862. str.copyTo8 (text, 0, kVstMaxParamStrLen);
  863. }
  864. }
  865. }
  866. }
  867. //------------------------------------------------------------------------
  868. void Vst2Wrapper::getUnitPath (UnitID unitID, String& path)
  869. {
  870. //! Build the unit path up to the root unit (e.g. "Modulators.LFO 1.". Separator is a ".")
  871. for (int32 unitIndex = 0; unitIndex < mUnitInfo->getUnitCount (); ++unitIndex)
  872. {
  873. UnitInfo info = {0};
  874. mUnitInfo->getUnitInfo (unitIndex, info);
  875. if (info.id == unitID)
  876. {
  877. String unitName (info.name);
  878. unitName.append (".");
  879. path.insertAt (0, unitName);
  880. if (info.parentUnitId != kRootUnitId)
  881. getUnitPath (info.parentUnitId, path);
  882. break;
  883. }
  884. }
  885. }
  886. //------------------------------------------------------------------------
  887. void Vst2Wrapper::getParameterName (VstInt32 index, char* text)
  888. {
  889. // name ("Time", "Gain", "RoomType", etc...) of parameter \e index. Limited to
  890. // #kVstExtMaxParamStrLen.
  891. *text = 0;
  892. if (mController && index < (int32)mParameterMap.size ())
  893. {
  894. int32 vst3Index = mParameterMap.at (index).vst3Index;
  895. ParameterInfo paramInfo = {0};
  896. if (mController->getParameterInfo (vst3Index, paramInfo) == kResultTrue)
  897. {
  898. String str;
  899. if (vst2WrapperFullParameterPath)
  900. {
  901. //! The parameter's name contains the unit path (e.g. "LFO 1.freq") as well
  902. if (mUnitInfo)
  903. {
  904. getUnitPath (paramInfo.unitId, str);
  905. }
  906. }
  907. str.append (paramInfo.title);
  908. if (str.length () > kVstExtMaxParamStrLen)
  909. {
  910. //! In case the string's length exceeds the limit, try parameter's title without
  911. // unit path.
  912. str = paramInfo.title;
  913. }
  914. if (str.length () > kVstExtMaxParamStrLen)
  915. {
  916. str = paramInfo.shortTitle;
  917. }
  918. str.copyTo8 (text, 0, kVstExtMaxParamStrLen);
  919. }
  920. }
  921. }
  922. //------------------------------------------------------------------------
  923. bool Vst2Wrapper::canParameterBeAutomated (VstInt32 index)
  924. {
  925. if (mController && index < (int32)mParameterMap.size ())
  926. {
  927. int32 vst3Index = mParameterMap.at (index).vst3Index;
  928. ParameterInfo paramInfo = {0};
  929. if (mController->getParameterInfo (vst3Index, paramInfo) == kResultTrue)
  930. return (paramInfo.flags & ParameterInfo::kCanAutomate) != 0;
  931. }
  932. return false;
  933. }
  934. //------------------------------------------------------------------------
  935. bool Vst2Wrapper::string2parameter (VstInt32 index, char* text)
  936. {
  937. if (mController && index < (int32)mParameterMap.size ())
  938. {
  939. int32 vst3Index = mParameterMap.at (index).vst3Index;
  940. ParameterInfo paramInfo = {0};
  941. if (mController->getParameterInfo (vst3Index, paramInfo) == kResultTrue)
  942. {
  943. TChar tString[1024] = {0};
  944. String tmp (text);
  945. tmp.copyTo16 (tString, 0, 1023);
  946. ParamValue valueNormalized = 0.0;
  947. if (mController->getParamValueByString (paramInfo.id, tString, valueNormalized))
  948. {
  949. setParameterAutomated (index, (float)valueNormalized);
  950. // TODO: check if setParameterAutomated is correct
  951. }
  952. }
  953. }
  954. return false;
  955. }
  956. //------------------------------------------------------------------------
  957. bool Vst2Wrapper::getParameterProperties (VstInt32 index, VstParameterProperties* p)
  958. {
  959. if (mController && index < (int32)mParameterMap.size ())
  960. {
  961. p->label[0] = 0;
  962. p->shortLabel[0] = 0;
  963. int32 vst3Index = mParameterMap.at (index).vst3Index;
  964. ParameterInfo paramInfo = {0};
  965. if (mController->getParameterInfo (vst3Index, paramInfo) == kResultTrue)
  966. {
  967. String str (paramInfo.title);
  968. str.copyTo8 (p->label, 0, kVstMaxLabelLen);
  969. String str2 (paramInfo.shortTitle);
  970. str.copyTo8 (p->shortLabel, 0, kVstMaxShortLabelLen);
  971. if (paramInfo.stepCount == 0) // continuous
  972. {
  973. p->flags |= kVstParameterCanRamp;
  974. }
  975. else if (paramInfo.stepCount == 1) // on / off
  976. {
  977. p->flags |= kVstParameterIsSwitch;
  978. }
  979. else
  980. {
  981. p->minInteger = 0;
  982. p->maxInteger = paramInfo.stepCount;
  983. p->flags |= kVstParameterUsesIntegerMinMax;
  984. }
  985. return true;
  986. }
  987. }
  988. return false;
  989. }
  990. //------------------------------------------------------------------------
  991. VstInt32 Vst2Wrapper::getChunk (void** data, bool isPreset)
  992. {
  993. // Host stores Plug-in state. Returns the size in bytes of the chunk (Plug-in allocates the data
  994. // array)
  995. MemoryStream componentStream;
  996. if (mComponent && mComponent->getState (&componentStream) != kResultTrue)
  997. componentStream.setSize (0);
  998. MemoryStream controllerStream;
  999. if (mController && mController->getState (&controllerStream) != kResultTrue)
  1000. controllerStream.setSize (0);
  1001. if (componentStream.getSize () + controllerStream.getSize () == 0)
  1002. return 0;
  1003. mChunk.setSize (0);
  1004. IBStreamer acc (&mChunk, kLittleEndian);
  1005. acc.writeInt64 (componentStream.getSize ());
  1006. acc.writeInt64 (controllerStream.getSize ());
  1007. acc.writeRaw (componentStream.getData (), (int32)componentStream.getSize ());
  1008. acc.writeRaw (controllerStream.getData (), (int32)controllerStream.getSize ());
  1009. int32 chunkSize = (int32)mChunk.getSize ();
  1010. *data = mChunk.getData ();
  1011. return chunkSize;
  1012. }
  1013. //------------------------------------------------------------------------
  1014. VstInt32 Vst2Wrapper::setChunk (void* data, VstInt32 byteSize, bool isPreset)
  1015. {
  1016. if (!mComponent)
  1017. return 0;
  1018. // throw away all previously queued parameter changes, they are obsolete
  1019. mGuiTransfer.removeChanges ();
  1020. mInputTransfer.removeChanges ();
  1021. MemoryStream chunk (data, byteSize);
  1022. IBStreamer acc (&chunk, kLittleEndian);
  1023. int64 componentDataSize = 0;
  1024. int64 controllerDataSize = 0;
  1025. acc.readInt64 (componentDataSize);
  1026. acc.readInt64 (controllerDataSize);
  1027. VstPresetStream componentStream (((char*)data) + acc.tell (), componentDataSize);
  1028. VstPresetStream controllerStream (((char*)data) + acc.tell () + componentDataSize,
  1029. controllerDataSize);
  1030. mComponent->setState (&componentStream);
  1031. componentStream.seek (0, IBStream::kIBSeekSet, 0);
  1032. if (mController)
  1033. {
  1034. if (!isPreset)
  1035. {
  1036. if (Vst::IAttributeList* attr = componentStream.getAttributes ())
  1037. attr->setString (Vst::PresetAttributes::kStateType,
  1038. String (Vst::StateType::kProject));
  1039. if (Vst::IAttributeList* attr = controllerStream.getAttributes ())
  1040. attr->setString (Vst::PresetAttributes::kStateType,
  1041. String (Vst::StateType::kProject));
  1042. }
  1043. mController->setComponentState (&componentStream);
  1044. mController->setState (&controllerStream);
  1045. }
  1046. return 0;
  1047. }
  1048. //------------------------------------------------------------------------
  1049. VstInt32 Vst2Wrapper::vst3ToVst2SpeakerArr (SpeakerArrangement vst3Arr)
  1050. {
  1051. switch (vst3Arr)
  1052. {
  1053. case SpeakerArr::kMono: return kSpeakerArrMono;
  1054. case SpeakerArr::kStereo: return kSpeakerArrStereo;
  1055. case SpeakerArr::kStereoSurround: return kSpeakerArrStereoSurround;
  1056. case SpeakerArr::kStereoCenter: return kSpeakerArrStereoCenter;
  1057. case SpeakerArr::kStereoSide: return kSpeakerArrStereoSide;
  1058. case SpeakerArr::kStereoCLfe: return kSpeakerArrStereoCLfe;
  1059. case SpeakerArr::k30Cine: return kSpeakerArr30Cine;
  1060. case SpeakerArr::k30Music: return kSpeakerArr30Music;
  1061. case SpeakerArr::k31Cine: return kSpeakerArr31Cine;
  1062. case SpeakerArr::k31Music: return kSpeakerArr31Music;
  1063. case SpeakerArr::k40Cine: return kSpeakerArr40Cine;
  1064. case SpeakerArr::k40Music: return kSpeakerArr40Music;
  1065. case SpeakerArr::k41Cine: return kSpeakerArr41Cine;
  1066. case SpeakerArr::k41Music: return kSpeakerArr41Music;
  1067. case SpeakerArr::k50: return kSpeakerArr50;
  1068. case SpeakerArr::k51: return kSpeakerArr51;
  1069. case SpeakerArr::k60Cine: return kSpeakerArr60Cine;
  1070. case SpeakerArr::k60Music: return kSpeakerArr60Music;
  1071. case SpeakerArr::k61Cine: return kSpeakerArr61Cine;
  1072. case SpeakerArr::k61Music: return kSpeakerArr61Music;
  1073. case SpeakerArr::k70Cine: return kSpeakerArr70Cine;
  1074. case SpeakerArr::k70Music: return kSpeakerArr70Music;
  1075. case SpeakerArr::k71Cine: return kSpeakerArr71Cine;
  1076. case SpeakerArr::k71Music: return kSpeakerArr71Music;
  1077. case SpeakerArr::k80Cine: return kSpeakerArr80Cine;
  1078. case SpeakerArr::k80Music: return kSpeakerArr80Music;
  1079. case SpeakerArr::k81Cine: return kSpeakerArr81Cine;
  1080. case SpeakerArr::k81Music: return kSpeakerArr81Music;
  1081. case SpeakerArr::k102: return kSpeakerArr102;
  1082. }
  1083. return kSpeakerArrUserDefined;
  1084. }
  1085. //------------------------------------------------------------------------
  1086. SpeakerArrangement Vst2Wrapper::vst2ToVst3SpeakerArr (VstInt32 vst2Arr)
  1087. {
  1088. switch (vst2Arr)
  1089. {
  1090. case kSpeakerArrMono: return SpeakerArr::kMono;
  1091. case kSpeakerArrStereo: return SpeakerArr::kStereo;
  1092. case kSpeakerArrStereoSurround: return SpeakerArr::kStereoSurround;
  1093. case kSpeakerArrStereoCenter: return SpeakerArr::kStereoCenter;
  1094. case kSpeakerArrStereoSide: return SpeakerArr::kStereoSide;
  1095. case kSpeakerArrStereoCLfe: return SpeakerArr::kStereoCLfe;
  1096. case kSpeakerArr30Cine: return SpeakerArr::k30Cine;
  1097. case kSpeakerArr30Music: return SpeakerArr::k30Music;
  1098. case kSpeakerArr31Cine: return SpeakerArr::k31Cine;
  1099. case kSpeakerArr31Music: return SpeakerArr::k31Music;
  1100. case kSpeakerArr40Cine: return SpeakerArr::k40Cine;
  1101. case kSpeakerArr40Music: return SpeakerArr::k40Music;
  1102. case kSpeakerArr41Cine: return SpeakerArr::k41Cine;
  1103. case kSpeakerArr41Music: return SpeakerArr::k41Music;
  1104. case kSpeakerArr50: return SpeakerArr::k50;
  1105. case kSpeakerArr51: return SpeakerArr::k51;
  1106. case kSpeakerArr60Cine: return SpeakerArr::k60Cine;
  1107. case kSpeakerArr60Music: return SpeakerArr::k60Music;
  1108. case kSpeakerArr61Cine: return SpeakerArr::k61Cine;
  1109. case kSpeakerArr61Music: return SpeakerArr::k61Music;
  1110. case kSpeakerArr70Cine: return SpeakerArr::k70Cine;
  1111. case kSpeakerArr70Music: return SpeakerArr::k70Music;
  1112. case kSpeakerArr71Cine: return SpeakerArr::k71Cine;
  1113. case kSpeakerArr71Music: return SpeakerArr::k71Music;
  1114. case kSpeakerArr80Cine: return SpeakerArr::k80Cine;
  1115. case kSpeakerArr80Music: return SpeakerArr::k80Music;
  1116. case kSpeakerArr81Cine: return SpeakerArr::k81Cine;
  1117. case kSpeakerArr81Music: return SpeakerArr::k81Music;
  1118. case kSpeakerArr102: return SpeakerArr::k102;
  1119. }
  1120. return 0;
  1121. }
  1122. //------------------------------------------------------------------------
  1123. VstInt32 Vst2Wrapper::vst3ToVst2Speaker (Vst::Speaker vst3Speaker)
  1124. {
  1125. switch (vst3Speaker)
  1126. {
  1127. case Vst::kSpeakerM: return ::kSpeakerM;
  1128. case Vst::kSpeakerL: return ::kSpeakerL;
  1129. case Vst::kSpeakerR: return ::kSpeakerR;
  1130. case Vst::kSpeakerC: return ::kSpeakerC;
  1131. case Vst::kSpeakerLfe: return ::kSpeakerLfe;
  1132. case Vst::kSpeakerLs: return ::kSpeakerLs;
  1133. case Vst::kSpeakerRs: return ::kSpeakerRs;
  1134. case Vst::kSpeakerLc: return ::kSpeakerLc;
  1135. case Vst::kSpeakerRc: return ::kSpeakerRc;
  1136. case Vst::kSpeakerS: return ::kSpeakerS;
  1137. case Vst::kSpeakerSl: return ::kSpeakerSl;
  1138. case Vst::kSpeakerSr: return ::kSpeakerSr;
  1139. case Vst::kSpeakerTc: return ::kSpeakerTm;
  1140. case Vst::kSpeakerTfl: return ::kSpeakerTfl;
  1141. case Vst::kSpeakerTfc: return ::kSpeakerTfc;
  1142. case Vst::kSpeakerTfr: return ::kSpeakerTfr;
  1143. case Vst::kSpeakerTrl: return ::kSpeakerTrl;
  1144. case Vst::kSpeakerTrc: return ::kSpeakerTrc;
  1145. case Vst::kSpeakerTrr: return ::kSpeakerTrr;
  1146. case Vst::kSpeakerLfe2: return ::kSpeakerLfe2;
  1147. }
  1148. return ::kSpeakerUndefined;
  1149. }
  1150. //------------------------------------------------------------------------
  1151. static const char* gSpeakerNames[] = {
  1152. "M", ///< Mono (M)
  1153. "L", ///< Left (L)
  1154. "R", ///< Right (R)
  1155. "C", ///< Center (C)
  1156. "Lfe", ///< Subbass (Lfe)
  1157. "Ls", ///< Left Surround (Ls)
  1158. "Rs", ///< Right Surround (Rs)
  1159. "Lc", ///< Left of Center (Lc)
  1160. "Rc", ///< Right of Center (Rc)
  1161. "Cs", ///< Center of Surround (Cs) = Surround (S)
  1162. "Sl", ///< Side Left (Sl)
  1163. "Sr", ///< Side Right (Sr)
  1164. "Tm", ///< Top Middle (Tm)
  1165. "Tfl", ///< Top Front Left (Tfl)
  1166. "Tfc", ///< Top Front Center (Tfc)
  1167. "Tfr", ///< Top Front Right (Tfr)
  1168. "Trl", ///< Top Rear Left (Trl)
  1169. "Trc", ///< Top Rear Center (Trc)
  1170. "Trr", ///< Top Rear Right (Trr)
  1171. "Lfe2" ///< Subbass 2 (Lfe2)
  1172. };
  1173. static const int32 kNumSpeakerNames = sizeof (gSpeakerNames) / sizeof (char*);
  1174. //------------------------------------------------------------------------
  1175. bool Vst2Wrapper::pinIndexToBusChannel (BusDirection dir, VstInt32 pinIndex, int32& busIndex,
  1176. int32& busChannel)
  1177. {
  1178. AudioBusBuffers* busBuffers = dir == kInput ? mProcessData.inputs : mProcessData.outputs;
  1179. int32 busCount = dir == kInput ? mProcessData.numInputs : mProcessData.numOutputs;
  1180. uint64 mainBusFlags = dir == kInput ? mMainAudioInputBuses : mMainAudioOutputBuses;
  1181. int32 sourceIndex = 0;
  1182. for (busIndex = 0; busIndex < busCount; busIndex++)
  1183. {
  1184. AudioBusBuffers& buffers = busBuffers[busIndex];
  1185. if (mainBusFlags & (uint64 (1) << busIndex))
  1186. {
  1187. for (busChannel = 0; busChannel < buffers.numChannels; busChannel++)
  1188. {
  1189. if (pinIndex == sourceIndex)
  1190. {
  1191. return true;
  1192. }
  1193. sourceIndex++;
  1194. }
  1195. }
  1196. }
  1197. return false;
  1198. }
  1199. //------------------------------------------------------------------------
  1200. bool Vst2Wrapper::getPinProperties (BusDirection dir, VstInt32 pinIndex,
  1201. VstPinProperties* properties)
  1202. {
  1203. int32 busIndex = -1;
  1204. int32 busChannelIndex = -1;
  1205. if (pinIndexToBusChannel (dir, pinIndex, busIndex, busChannelIndex))
  1206. {
  1207. BusInfo busInfo = {0};
  1208. if (mComponent && mComponent->getBusInfo (kAudio, dir, busIndex, busInfo) == kResultTrue)
  1209. {
  1210. properties->flags = kVstPinIsActive; // ????
  1211. String name (busInfo.name);
  1212. name.copyTo8 (properties->label, 0, kVstMaxLabelLen);
  1213. if (busInfo.channelCount == 1)
  1214. {
  1215. properties->flags |= kVstPinUseSpeaker;
  1216. properties->arrangementType = kSpeakerArrMono;
  1217. }
  1218. if (busInfo.channelCount == 2)
  1219. {
  1220. properties->flags |= kVstPinUseSpeaker;
  1221. properties->flags |= kVstPinIsStereo;
  1222. properties->arrangementType = kSpeakerArrStereo;
  1223. }
  1224. else if (busInfo.channelCount > 2)
  1225. {
  1226. Vst::SpeakerArrangement arr = 0;
  1227. if (mProcessor && mProcessor->getBusArrangement (dir, busIndex, arr) == kResultTrue)
  1228. {
  1229. properties->flags |= kVstPinUseSpeaker;
  1230. properties->arrangementType = vst3ToVst2SpeakerArr (arr);
  1231. }
  1232. else
  1233. {
  1234. return false;
  1235. }
  1236. }
  1237. return true;
  1238. }
  1239. }
  1240. return false;
  1241. }
  1242. //------------------------------------------------------------------------
  1243. bool Vst2Wrapper::getInputProperties (VstInt32 index, VstPinProperties* properties)
  1244. {
  1245. return getPinProperties (kInput, index, properties);
  1246. }
  1247. //------------------------------------------------------------------------
  1248. bool Vst2Wrapper::getOutputProperties (VstInt32 index, VstPinProperties* properties)
  1249. {
  1250. return getPinProperties (kOutput, index, properties);
  1251. }
  1252. //------------------------------------------------------------------------
  1253. bool Vst2Wrapper::setSpeakerArrangement (VstSpeakerArrangement* pluginInput,
  1254. VstSpeakerArrangement* pluginOutput)
  1255. {
  1256. if (!mProcessor || !mComponent)
  1257. return false;
  1258. Vst::SpeakerArrangement newInputArr = 0;
  1259. Vst::SpeakerArrangement newOutputArr = 0;
  1260. Vst::SpeakerArrangement outputArr = 0;
  1261. Vst::SpeakerArrangement inputArr = 0;
  1262. int32 inputBusCount = mComponent->getBusCount (kAudio, kInput);
  1263. int32 outputBusCount = mComponent->getBusCount (kAudio, kOutput);
  1264. if (inputBusCount > 0)
  1265. if (mProcessor->getBusArrangement (kInput, 0, inputArr) != kResultTrue)
  1266. return false;
  1267. if (outputBusCount > 0)
  1268. if (mProcessor->getBusArrangement (kOutput, 0, outputArr) != kResultTrue)
  1269. return false;
  1270. if (pluginInput)
  1271. {
  1272. newInputArr = vst2ToVst3SpeakerArr (pluginInput->type);
  1273. if (newInputArr == 0)
  1274. return false;
  1275. }
  1276. if (pluginOutput)
  1277. {
  1278. newOutputArr = vst2ToVst3SpeakerArr (pluginOutput->type);
  1279. if (newOutputArr == 0)
  1280. return false;
  1281. }
  1282. if (newInputArr == 0)
  1283. newInputArr = inputArr;
  1284. if (newOutputArr == 0)
  1285. newOutputArr = outputArr;
  1286. if (newInputArr != inputArr || newOutputArr != outputArr)
  1287. {
  1288. if (mProcessor->setBusArrangements (
  1289. &newInputArr, (newInputArr > 0 && inputBusCount > 0) ? 1 : 0, &newOutputArr,
  1290. (newOutputArr > 0 && outputBusCount > 0) ? 1 : 0) != kResultTrue)
  1291. return false;
  1292. restartComponent (kIoChanged);
  1293. }
  1294. return true;
  1295. }
  1296. //------------------------------------------------------------------------
  1297. void Vst2Wrapper::setupVst2Arrangement (VstSpeakerArrangement*& vst2arr,
  1298. Vst::SpeakerArrangement vst3Arrangement)
  1299. {
  1300. int32 numChannels = Vst::SpeakerArr::getChannelCount (vst3Arrangement);
  1301. if (vst2arr && (numChannels == 0 || (numChannels > vst2arr->numChannels && numChannels > 8)))
  1302. {
  1303. free (vst2arr);
  1304. vst2arr = 0;
  1305. if (numChannels == 0)
  1306. return;
  1307. }
  1308. if (vst2arr == 0)
  1309. {
  1310. int32 channelOverhead = numChannels > 8 ? numChannels - 8 : 0;
  1311. uint32 structSize =
  1312. sizeof (VstSpeakerArrangement) + channelOverhead * sizeof (VstSpeakerProperties);
  1313. vst2arr = (VstSpeakerArrangement*)malloc (structSize);
  1314. memset (vst2arr, 0, structSize);
  1315. }
  1316. if (vst2arr)
  1317. {
  1318. vst2arr->type = vst3ToVst2SpeakerArr (vst3Arrangement);
  1319. vst2arr->numChannels = numChannels;
  1320. Speaker vst3TestSpeaker = 1;
  1321. for (int32 i = 0; i < numChannels; i++)
  1322. {
  1323. VstSpeakerProperties& props = vst2arr->speakers[i];
  1324. // find nextSpeaker in vst3 arrangement
  1325. Speaker vst3Speaker = 0;
  1326. while (vst3Speaker == 0 && vst3TestSpeaker != 0)
  1327. {
  1328. if (vst3Arrangement & vst3TestSpeaker)
  1329. vst3Speaker = vst3TestSpeaker;
  1330. vst3TestSpeaker <<= 1;
  1331. }
  1332. if (vst3Speaker)
  1333. {
  1334. props.type = vst3ToVst2Speaker (vst3Speaker);
  1335. if (props.type >= 0 && props.type < kNumSpeakerNames)
  1336. strncpy (props.name, gSpeakerNames[props.type], kVstMaxNameLen);
  1337. else
  1338. sprintf (props.name, "%d", i + 1);
  1339. }
  1340. }
  1341. }
  1342. }
  1343. //------------------------------------------------------------------------
  1344. bool Vst2Wrapper::getSpeakerArrangement (VstSpeakerArrangement** pluginInput,
  1345. VstSpeakerArrangement** pluginOutput)
  1346. {
  1347. if (!mProcessor)
  1348. return false;
  1349. Vst::SpeakerArrangement inputArr = 0;
  1350. Vst::SpeakerArrangement outputArr = 0;
  1351. if (mProcessor->getBusArrangement (kInput, 0, inputArr) != kResultTrue)
  1352. inputArr = 0;
  1353. if (mProcessor->getBusArrangement (kOutput, 0, outputArr) != kResultTrue)
  1354. outputArr = 0;
  1355. setupVst2Arrangement (mVst2InputArrangement, inputArr);
  1356. setupVst2Arrangement (mVst2OutputArrangement, outputArr);
  1357. *pluginInput = mVst2InputArrangement;
  1358. *pluginOutput = mVst2OutputArrangement;
  1359. return mVst2InputArrangement != 0 && mVst2OutputArrangement != 0;
  1360. }
  1361. //------------------------------------------------------------------------
  1362. bool Vst2Wrapper::setBypass (bool onOff)
  1363. {
  1364. if (mBypassParameterID != kNoParamId)
  1365. {
  1366. addParameterChange (mBypassParameterID, onOff ? 1.0 : 0.0, 0);
  1367. return true;
  1368. }
  1369. return false;
  1370. }
  1371. //-----------------------------------------------------------------------------
  1372. bool Vst2Wrapper::setProcessPrecision (VstInt32 precision)
  1373. {
  1374. int32 newVst3SampleSize = -1;
  1375. if (precision == kVstProcessPrecision32)
  1376. newVst3SampleSize = kSample32;
  1377. else if (precision == kVstProcessPrecision64)
  1378. newVst3SampleSize = kSample64;
  1379. if (newVst3SampleSize != mVst3SampleSize)
  1380. {
  1381. if (mProcessor && mProcessor->canProcessSampleSize (newVst3SampleSize) == kResultTrue)
  1382. {
  1383. mVst3SampleSize = newVst3SampleSize;
  1384. setupProcessing ();
  1385. setupBuses ();
  1386. return true;
  1387. }
  1388. return false;
  1389. }
  1390. return true;
  1391. }
  1392. //-----------------------------------------------------------------------------
  1393. VstInt32 Vst2Wrapper::getNumMidiInputChannels ()
  1394. {
  1395. if (!mComponent)
  1396. return 0;
  1397. int32 busCount = mComponent->getBusCount (kEvent, kInput);
  1398. if (busCount > 0)
  1399. {
  1400. BusInfo busInfo = {0};
  1401. if (mComponent->getBusInfo (kEvent, kInput, 0, busInfo) == kResultTrue)
  1402. {
  1403. return busInfo.channelCount;
  1404. }
  1405. }
  1406. return 0;
  1407. }
  1408. //-----------------------------------------------------------------------------
  1409. VstInt32 Vst2Wrapper::getNumMidiOutputChannels ()
  1410. {
  1411. if (!mComponent)
  1412. return 0;
  1413. int32 busCount = mComponent->getBusCount (kEvent, kOutput);
  1414. if (busCount > 0)
  1415. {
  1416. BusInfo busInfo = {0};
  1417. if (mComponent->getBusInfo (kEvent, kOutput, 0, busInfo) == kResultTrue)
  1418. {
  1419. return busInfo.channelCount;
  1420. }
  1421. }
  1422. return 0;
  1423. }
  1424. //-----------------------------------------------------------------------------
  1425. VstInt32 Vst2Wrapper::getGetTailSize ()
  1426. {
  1427. if (mProcessor)
  1428. return mProcessor->getTailSamples ();
  1429. return 0;
  1430. }
  1431. //-----------------------------------------------------------------------------
  1432. bool Vst2Wrapper::getEffectName (char* effectName)
  1433. {
  1434. if (mName[0])
  1435. {
  1436. strncpy (effectName, mName, kVstMaxEffectNameLen);
  1437. return true;
  1438. }
  1439. return false;
  1440. }
  1441. //-----------------------------------------------------------------------------
  1442. bool Vst2Wrapper::getVendorString (char* text)
  1443. {
  1444. if (mVendor[0])
  1445. {
  1446. strncpy (text, mVendor, kVstMaxVendorStrLen);
  1447. return true;
  1448. }
  1449. return false;
  1450. }
  1451. //-----------------------------------------------------------------------------
  1452. VstInt32 Vst2Wrapper::getVendorVersion ()
  1453. {
  1454. return mVersion;
  1455. }
  1456. //-----------------------------------------------------------------------------
  1457. VstIntPtr Vst2Wrapper::vendorSpecific (VstInt32 lArg, VstIntPtr lArg2, void* ptrArg, float floatArg)
  1458. {
  1459. switch (lArg)
  1460. {
  1461. case 'stCA':
  1462. case 'stCa':
  1463. switch (lArg2)
  1464. {
  1465. //--- -------
  1466. case 'FUID':
  1467. if (ptrArg && mVst3EffectClassID.isValid ())
  1468. {
  1469. memcpy ((char*)ptrArg, mVst3EffectClassID, 16);
  1470. return 1;
  1471. }
  1472. break;
  1473. //--- -------
  1474. case 'Whee':
  1475. if (editor)
  1476. editor->onWheel (floatArg);
  1477. return 1;
  1478. break;
  1479. }
  1480. }
  1481. return AudioEffectX::vendorSpecific (lArg, lArg2, ptrArg, floatArg);
  1482. }
  1483. //-----------------------------------------------------------------------------
  1484. VstPlugCategory Vst2Wrapper::getPlugCategory ()
  1485. {
  1486. if (mSubCategories[0])
  1487. {
  1488. if (strstr (mSubCategories, "Analyzer"))
  1489. return kPlugCategAnalysis;
  1490. else if (strstr (mSubCategories, "Delay") || strstr (mSubCategories, "Reverb"))
  1491. return kPlugCategRoomFx;
  1492. else if (strstr (mSubCategories, "Dynamics") || strstr (mSubCategories, "Mastering"))
  1493. return kPlugCategMastering;
  1494. else if (strstr (mSubCategories, "Restoration"))
  1495. return kPlugCategRestoration;
  1496. else if (strstr (mSubCategories, "Generator"))
  1497. return kPlugCategGenerator;
  1498. else if (strstr (mSubCategories, "Spatial"))
  1499. return kPlugCategSpacializer;
  1500. else if (strstr (mSubCategories, "Fx"))
  1501. return kPlugCategEffect;
  1502. else if (strstr (mSubCategories, "Instrument"))
  1503. return kPlugCategSynth;
  1504. }
  1505. return kPlugCategUnknown;
  1506. }
  1507. //-----------------------------------------------------------------------------
  1508. VstInt32 Vst2Wrapper::canDo (char* text)
  1509. {
  1510. if (stricmp (text, "sendVstEvents") == 0)
  1511. {
  1512. return -1;
  1513. }
  1514. else if (stricmp (text, "sendVstMidiEvent") == 0)
  1515. {
  1516. return hasEventOutputBuses ? 1 : -1;
  1517. }
  1518. else if (stricmp (text, "receiveVstEvents") == 0)
  1519. {
  1520. return -1;
  1521. }
  1522. else if (stricmp (text, "receiveVstMidiEvent") == 0)
  1523. {
  1524. return hasEventInputBuses ? 1 : -1;
  1525. }
  1526. else if (stricmp (text, "receiveVstTimeInfo") == 0)
  1527. {
  1528. return 1;
  1529. }
  1530. else if (stricmp (text, "offline") == 0)
  1531. {
  1532. if (processing)
  1533. return 0;
  1534. if (mVst3processMode == kOffline)
  1535. return 1;
  1536. bool canOffline = setupProcessing (kOffline);
  1537. setupProcessing ();
  1538. return canOffline ? 1 : -1;
  1539. }
  1540. else if (stricmp (text, "midiProgramNames") == 0)
  1541. {
  1542. if (mUnitInfo)
  1543. {
  1544. UnitID unitId = -1;
  1545. if (mUnitInfo->getUnitByBus (kEvent, kInput, 0, 0, unitId) == kResultTrue && unitId >= 0)
  1546. return 1;
  1547. }
  1548. return -1;
  1549. }
  1550. else if (stricmp (text, "bypass") == 0)
  1551. {
  1552. return mBypassParameterID != kNoParamId ? 1 : -1;
  1553. }
  1554. return 0; // do not know
  1555. }
  1556. //-----------------------------------------------------------------------------
  1557. bool Vst2Wrapper::setupMidiProgram (int32 midiChannel, ProgramListID programListId,
  1558. MidiProgramName& midiProgramName)
  1559. {
  1560. if (mUnitInfo)
  1561. {
  1562. String128 string128 = {0};
  1563. if (mUnitInfo->getProgramName (programListId, midiProgramName.thisProgramIndex, string128) ==
  1564. kResultTrue)
  1565. {
  1566. String str (string128);
  1567. str.copyTo8 (midiProgramName.name, 0, kVstMaxNameLen);
  1568. midiProgramName.midiProgram = midiProgramName.thisProgramIndex;
  1569. midiProgramName.midiBankMsb = -1;
  1570. midiProgramName.midiBankLsb = -1;
  1571. midiProgramName.parentCategoryIndex = -1;
  1572. midiProgramName.flags = 0;
  1573. if (mUnitInfo->getProgramInfo (programListId, midiProgramName.thisProgramIndex,
  1574. PresetAttributes::kInstrument, string128) == kResultTrue)
  1575. {
  1576. midiProgramName.parentCategoryIndex =
  1577. lookupProgramCategory (midiChannel, string128);
  1578. }
  1579. return true;
  1580. }
  1581. }
  1582. return false;
  1583. }
  1584. //-----------------------------------------------------------------------------
  1585. VstInt32 Vst2Wrapper::getMidiProgramName (VstInt32 channel, MidiProgramName* midiProgramName)
  1586. {
  1587. UnitID unitId;
  1588. ProgramListID programListId;
  1589. if (mUnitInfo && getProgramListAndUnit (channel, unitId, programListId))
  1590. {
  1591. if (midiProgramName)
  1592. setupMidiProgram (channel, programListId, *midiProgramName);
  1593. ProgramListInfo programListInfo;
  1594. if (getProgramListInfoByProgramListID (programListId, programListInfo))
  1595. return programListInfo.programCount;
  1596. }
  1597. return 0;
  1598. }
  1599. //-----------------------------------------------------------------------------
  1600. VstInt32 Vst2Wrapper::getCurrentMidiProgram (VstInt32 channel, MidiProgramName* currentProgram)
  1601. {
  1602. if (mUnitInfo && mController)
  1603. {
  1604. UnitID unitId;
  1605. ProgramListID programListId;
  1606. if (getProgramListAndUnit (channel, unitId, programListId))
  1607. {
  1608. // find program selector parameter
  1609. int32 parameterCount = mController->getParameterCount ();
  1610. for (int32 i = 0; i < parameterCount; i++)
  1611. {
  1612. ParameterInfo parameterInfo = {0};
  1613. if (mController->getParameterInfo (i, parameterInfo) == kResultTrue)
  1614. {
  1615. if ((parameterInfo.flags & ParameterInfo::kIsProgramChange) != 0 &&
  1616. parameterInfo.unitId == unitId)
  1617. {
  1618. ParamValue normalized = mController->getParamNormalized (parameterInfo.id);
  1619. int32 discreteValue =
  1620. Min<int32> ((int32) (normalized * (parameterInfo.stepCount + 1)),
  1621. parameterInfo.stepCount);
  1622. if (currentProgram)
  1623. {
  1624. currentProgram->thisProgramIndex = discreteValue;
  1625. setupMidiProgram (channel, programListId, *currentProgram);
  1626. }
  1627. return discreteValue;
  1628. }
  1629. }
  1630. }
  1631. }
  1632. }
  1633. return 0;
  1634. }
  1635. //-----------------------------------------------------------------------------
  1636. VstInt32 Vst2Wrapper::getMidiProgramCategory (VstInt32 channel, MidiProgramCategory* category)
  1637. {
  1638. // try to rebuild it each time
  1639. setupProgramCategories ();
  1640. if (channel >= (VstInt32)mProgramCategories.size ())
  1641. return 0;
  1642. std::vector<ProgramCategory>& channelCategories = mProgramCategories[channel];
  1643. if (category && category->thisCategoryIndex < (VstInt32)channelCategories.size ())
  1644. {
  1645. ProgramCategory& cat = channelCategories[category->thisCategoryIndex];
  1646. if (cat.vst2Category.thisCategoryIndex == category->thisCategoryIndex)
  1647. memcpy (category, &cat.vst2Category, sizeof (MidiProgramCategory));
  1648. }
  1649. return (VstInt32)channelCategories.size ();
  1650. }
  1651. //-----------------------------------------------------------------------------
  1652. bool Vst2Wrapper::hasMidiProgramsChanged (VstInt32 channel)
  1653. {
  1654. // names of programs or program categories have changed
  1655. return false;
  1656. }
  1657. //-----------------------------------------------------------------------------
  1658. bool Vst2Wrapper::getMidiKeyName (VstInt32 channel, MidiKeyName* keyName)
  1659. {
  1660. UnitID unitId;
  1661. ProgramListID programListId;
  1662. if (mUnitInfo && getProgramListAndUnit (channel, unitId, programListId))
  1663. {
  1664. String128 string128 = {0};
  1665. if (mUnitInfo->getProgramPitchName (programListId, keyName->thisProgramIndex,
  1666. keyName->thisKeyNumber, string128))
  1667. {
  1668. String str (string128);
  1669. str.copyTo8 (keyName->keyName, 0, kVstMaxNameLen);
  1670. return true;
  1671. }
  1672. }
  1673. return false;
  1674. }
  1675. //-----------------------------------------------------------------------------
  1676. bool Vst2Wrapper::getProgramListAndUnit (int32 midiChannel, UnitID& unitId,
  1677. ProgramListID& programListId)
  1678. {
  1679. programListId = kNoProgramListId;
  1680. unitId = -1;
  1681. // use the first input event bus (VST2 has only 1 bus for event)
  1682. if (mUnitInfo && mUnitInfo->getUnitByBus (kEvent, kInput, 0, midiChannel, unitId) == kResultTrue)
  1683. {
  1684. for (int32 i = 0, unitCount = mUnitInfo->getUnitCount (); i < unitCount; i++)
  1685. {
  1686. UnitInfo unitInfoStruct = {0};
  1687. if (mUnitInfo->getUnitInfo (i, unitInfoStruct) == kResultTrue)
  1688. {
  1689. if (unitId == unitInfoStruct.id)
  1690. {
  1691. programListId = unitInfoStruct.programListId;
  1692. return programListId != kNoProgramListId;
  1693. }
  1694. }
  1695. }
  1696. }
  1697. return false;
  1698. }
  1699. //-----------------------------------------------------------------------------
  1700. bool Vst2Wrapper::getProgramListInfoByProgramListID (ProgramListID programListId,
  1701. ProgramListInfo& info)
  1702. {
  1703. if (mUnitInfo)
  1704. {
  1705. int32 programListCount = mUnitInfo->getProgramListCount ();
  1706. for (int32 i = 0; i < programListCount; i++)
  1707. {
  1708. memset (&info, 0, sizeof (ProgramListInfo));
  1709. if (mUnitInfo->getProgramListInfo (i, info) == kResultTrue)
  1710. {
  1711. if (info.id == programListId)
  1712. {
  1713. return true;
  1714. }
  1715. }
  1716. }
  1717. }
  1718. return false;
  1719. }
  1720. //-----------------------------------------------------------------------------
  1721. int32 Vst2Wrapper::lookupProgramCategory (int32 midiChannel, String128 instrumentAttribute)
  1722. {
  1723. std::vector<ProgramCategory>& channelCategories = mProgramCategories[midiChannel];
  1724. for (uint32 categoryIndex = 0; categoryIndex < channelCategories.size (); categoryIndex++)
  1725. {
  1726. ProgramCategory& cat = channelCategories[categoryIndex];
  1727. if (memcmp (instrumentAttribute, cat.vst3InstrumentAttribute, sizeof (String128)) == 0)
  1728. return categoryIndex;
  1729. }
  1730. return -1;
  1731. }
  1732. //-----------------------------------------------------------------------------
  1733. uint32 Vst2Wrapper::makeCategoriesRecursive (std::vector<ProgramCategory>& channelCategories,
  1734. String128 vst3Category)
  1735. {
  1736. for (uint32 categoryIndex = 0; categoryIndex < channelCategories.size (); categoryIndex++)
  1737. {
  1738. ProgramCategory& cat = channelCategories[categoryIndex];
  1739. if (memcmp (vst3Category, cat.vst3InstrumentAttribute, sizeof (String128)) == 0)
  1740. {
  1741. return categoryIndex;
  1742. }
  1743. }
  1744. int32 parentCategorIndex = -1;
  1745. String128 str;
  1746. String strAcc (str);
  1747. strAcc.copyTo16 (vst3Category, 0, 127);
  1748. int32 len = strAcc.length ();
  1749. String singleName;
  1750. char16 divider = '|';
  1751. for (int32 strIndex = len - 1; strIndex >= 0; strIndex--)
  1752. {
  1753. bool isDivider = str[strIndex] == divider;
  1754. str[strIndex] = 0; // zero out rest
  1755. if (isDivider)
  1756. {
  1757. singleName.assign (vst3Category + strIndex + 1);
  1758. parentCategorIndex = makeCategoriesRecursive (channelCategories, str);
  1759. break;
  1760. }
  1761. }
  1762. // make new
  1763. ProgramCategory cat = {0};
  1764. memcpy (cat.vst3InstrumentAttribute, vst3Category, sizeof (String128));
  1765. singleName.copyTo8 (cat.vst2Category.name, 0, kVstMaxNameLen);
  1766. cat.vst2Category.parentCategoryIndex = parentCategorIndex;
  1767. cat.vst2Category.thisCategoryIndex = (int32)channelCategories.size ();
  1768. channelCategories.push_back (cat);
  1769. return cat.vst2Category.thisCategoryIndex;
  1770. }
  1771. //-----------------------------------------------------------------------------
  1772. void Vst2Wrapper::setupProgramCategories ()
  1773. {
  1774. mProgramCategories.clear ();
  1775. if (mUnitInfo && mComponent)
  1776. {
  1777. if (mComponent->getBusCount (kEvent, kInput) > 0)
  1778. {
  1779. for (int32 channel = 0; channel < 16; channel++) // the 16 channels
  1780. {
  1781. // make vector for channel
  1782. mProgramCategories.push_back (std::vector<ProgramCategory> ());
  1783. std::vector<ProgramCategory>& channelCategories = mProgramCategories[channel];
  1784. // scan program list of channel and find categories
  1785. UnitID unitId;
  1786. ProgramListID programListId;
  1787. if (getProgramListAndUnit (channel, unitId, programListId))
  1788. {
  1789. ProgramListInfo programListInfo;
  1790. if (getProgramListInfoByProgramListID (programListId, programListInfo))
  1791. {
  1792. for (int32 programIndex = 0; programIndex < programListInfo.programCount;
  1793. programIndex++)
  1794. {
  1795. String128 string128 = {0};
  1796. if (mUnitInfo->getProgramInfo (programListId, programIndex,
  1797. PresetAttributes::kInstrument,
  1798. string128) == kResultTrue)
  1799. {
  1800. makeCategoriesRecursive (channelCategories, string128);
  1801. }
  1802. }
  1803. }
  1804. }
  1805. }
  1806. }
  1807. }
  1808. }
  1809. //-----------------------------------------------------------------------------
  1810. void Vst2Wrapper::setVendorName (char* name)
  1811. {
  1812. memcpy (mVendor, name, sizeof (mVendor));
  1813. }
  1814. //-----------------------------------------------------------------------------
  1815. void Vst2Wrapper::setEffectName (char* effectName)
  1816. {
  1817. memcpy (mName, effectName, sizeof (mName));
  1818. }
  1819. //-----------------------------------------------------------------------------
  1820. void Vst2Wrapper::setEffectVersion (char* version)
  1821. {
  1822. if (!version)
  1823. mVersion = 0;
  1824. else
  1825. {
  1826. int32 major = 1;
  1827. int32 minor = 0;
  1828. int32 subminor = 0;
  1829. int32 subsubminor = 0;
  1830. int32 ret = sscanf (version, "%d.%d.%d.%d", &major, &minor, &subminor, &subsubminor);
  1831. mVersion = (major & 0xff) << 24;
  1832. if (ret > 3)
  1833. mVersion += (subsubminor & 0xff);
  1834. if (ret > 2)
  1835. mVersion += (subminor & 0xff) << 8;
  1836. if (ret > 1)
  1837. mVersion += (minor & 0xff) << 16;
  1838. }
  1839. }
  1840. //-----------------------------------------------------------------------------
  1841. void Vst2Wrapper::setSubCategories (char* string)
  1842. {
  1843. memcpy (mSubCategories, string, sizeof (mSubCategories));
  1844. if (strstr (mSubCategories, "Instrument"))
  1845. isSynth (true);
  1846. }
  1847. //-----------------------------------------------------------------------------
  1848. void Vst2Wrapper::setupBuses ()
  1849. {
  1850. if (!mComponent)
  1851. return;
  1852. mProcessData.prepare (*mComponent, 0, mVst3SampleSize);
  1853. setNumInputs (countMainBusChannels (kInput, mMainAudioInputBuses));
  1854. setNumOutputs (countMainBusChannels (kOutput, mMainAudioOutputBuses));
  1855. hasEventInputBuses = mComponent->getBusCount (kEvent, kInput) > 0;
  1856. hasEventOutputBuses = mComponent->getBusCount (kEvent, kOutput) > 0;
  1857. if (hasEventInputBuses)
  1858. {
  1859. if (mInputEvents == 0)
  1860. mInputEvents = new EventList (kMaxEvents);
  1861. }
  1862. else
  1863. {
  1864. if (mInputEvents)
  1865. {
  1866. delete mInputEvents;
  1867. mInputEvents = nullptr;
  1868. }
  1869. }
  1870. if (hasEventOutputBuses)
  1871. {
  1872. if (mOutputEvents == 0)
  1873. mOutputEvents = new EventList (kMaxEvents);
  1874. if (mVst2OutputEvents == 0)
  1875. mVst2OutputEvents = new Vst2MidiEventQueue (kMaxEvents);
  1876. }
  1877. else
  1878. {
  1879. if (mOutputEvents)
  1880. {
  1881. delete mOutputEvents;
  1882. mOutputEvents = nullptr;
  1883. }
  1884. if (mVst2OutputEvents)
  1885. {
  1886. delete mVst2OutputEvents;
  1887. mVst2OutputEvents = nullptr;
  1888. }
  1889. }
  1890. }
  1891. //-----------------------------------------------------------------------------
  1892. void Vst2Wrapper::setupParameters ()
  1893. {
  1894. mParameterMap.clear ();
  1895. mParamIndexMap.clear ();
  1896. mBypassParameterID = mProgramParameterID = kNoParamId;
  1897. mProgramParameterIdx = -1;
  1898. std::vector<ParameterInfo> programParameterInfos;
  1899. std::vector<int32> programParameterIdxs;
  1900. int32 paramCount = mController ? mController->getParameterCount () : 0;
  1901. int32 vst2ParamID = 0;
  1902. for (int32 i = 0; i < paramCount; i++)
  1903. {
  1904. ParameterInfo paramInfo = {0};
  1905. if (mController->getParameterInfo (i, paramInfo) == kResultTrue)
  1906. {
  1907. //--- ------------------------------------------
  1908. if ((paramInfo.flags & ParameterInfo::kIsBypass) != 0)
  1909. {
  1910. if (mBypassParameterID == kNoParamId)
  1911. mBypassParameterID = paramInfo.id;
  1912. }
  1913. //--- ------------------------------------------
  1914. else if ((paramInfo.flags & ParameterInfo::kIsProgramChange) != 0)
  1915. {
  1916. programParameterInfos.push_back (paramInfo);
  1917. programParameterIdxs.push_back (i);
  1918. if (paramInfo.unitId == kRootUnitId)
  1919. {
  1920. if (mProgramParameterID == kNoParamId)
  1921. {
  1922. mProgramParameterID = paramInfo.id;
  1923. mProgramParameterIdx = i;
  1924. }
  1925. }
  1926. if (gExportProgramChangeParameters == true)
  1927. {
  1928. ParamMapEntry entry = {paramInfo.id, i};
  1929. mParameterMap.push_back (entry);
  1930. mParamIndexMap[paramInfo.id] = vst2ParamID;
  1931. vst2ParamID++;
  1932. }
  1933. }
  1934. //--- ------------------------------------------
  1935. // do not export read only parameters to VST2
  1936. else if ((paramInfo.flags & ParameterInfo::kIsReadOnly) == 0)
  1937. {
  1938. ParamMapEntry entry = {paramInfo.id, i};
  1939. mParameterMap.push_back (entry);
  1940. mParamIndexMap[paramInfo.id] = vst2ParamID;
  1941. vst2ParamID++;
  1942. }
  1943. }
  1944. }
  1945. numParams = cEffect.numParams = (int32)mParameterMap.size ();
  1946. mInputTransfer.setMaxParameters (paramCount);
  1947. mOutputTransfer.setMaxParameters (paramCount);
  1948. mGuiTransfer.setMaxParameters (paramCount);
  1949. mInputChanges.setMaxParameters (paramCount);
  1950. mOutputChanges.setMaxParameters (paramCount);
  1951. for (int32 midiChannel = 0; midiChannel < kMaxProgramChangeParameters; midiChannel++)
  1952. {
  1953. mProgramChangeParameterIDs[midiChannel] = kNoParamId;
  1954. mProgramChangeParameterIdxs[midiChannel] = -1;
  1955. UnitID unitId;
  1956. ProgramListID programListId;
  1957. if (getProgramListAndUnit (midiChannel, unitId, programListId))
  1958. {
  1959. for (int32 i = 0; i < (int32)programParameterInfos.size (); i++)
  1960. {
  1961. const ParameterInfo& paramInfo = programParameterInfos.at (i);
  1962. if (paramInfo.unitId == unitId)
  1963. {
  1964. mProgramChangeParameterIDs[midiChannel] = paramInfo.id;
  1965. mProgramChangeParameterIdxs[midiChannel] = programParameterIdxs.at (i);
  1966. break;
  1967. }
  1968. }
  1969. }
  1970. }
  1971. }
  1972. //-----------------------------------------------------------------------------
  1973. void Vst2Wrapper::initMidiCtrlerAssignment ()
  1974. {
  1975. if (!mMidiMapping || !mComponent)
  1976. return;
  1977. int32 busses = Min<int32> (mComponent->getBusCount (kEvent, kInput), kMaxMidiMappingBusses);
  1978. if (!mMidiCCMapping[0][0])
  1979. {
  1980. for (int32 b = 0; b < busses; b++)
  1981. for (int32 i = 0; i < 16; i++)
  1982. mMidiCCMapping[b][i] = NEW int32[Vst::kCountCtrlNumber];
  1983. }
  1984. ParamID paramID;
  1985. for (int32 b = 0; b < busses; b++)
  1986. {
  1987. for (int16 ch = 0; ch < 16; ch++)
  1988. {
  1989. for (int32 i = 0; i < Vst::kCountCtrlNumber; i++)
  1990. {
  1991. paramID = kNoParamId;
  1992. if (mMidiMapping->getMidiControllerAssignment (b, ch, (CtrlNumber)i, paramID) ==
  1993. kResultTrue)
  1994. {
  1995. // TODO check if tag is associated to a parameter
  1996. mMidiCCMapping[b][ch][i] = paramID;
  1997. }
  1998. else
  1999. mMidiCCMapping[b][ch][i] = kNoParamId;
  2000. }
  2001. }
  2002. }
  2003. }
  2004. //-----------------------------------------------------------------------------
  2005. int32 Vst2Wrapper::countMainBusChannels (BusDirection dir, uint64& mainBusBitset)
  2006. {
  2007. int32 result = 0;
  2008. mainBusBitset = 0;
  2009. int32 busCount = mComponent->getBusCount (kAudio, dir);
  2010. for (int32 i = 0; i < busCount; i++)
  2011. {
  2012. BusInfo busInfo = {0};
  2013. if (mComponent->getBusInfo (kAudio, dir, i, busInfo) == kResultTrue)
  2014. {
  2015. if (busInfo.busType == kMain)
  2016. {
  2017. result += busInfo.channelCount;
  2018. mainBusBitset |= (uint64 (1) << i);
  2019. mComponent->activateBus (kAudio, dir, i, true);
  2020. }
  2021. else if (busInfo.flags & BusInfo::kDefaultActive)
  2022. {
  2023. mComponent->activateBus (kAudio, dir, i, false);
  2024. }
  2025. }
  2026. }
  2027. return result;
  2028. }
  2029. //------------------------------------------------------------------------
  2030. const uint8 kNoteOff = 0x80; ///< note, off velocity
  2031. const uint8 kNoteOn = 0x90; ///< note, on velocity
  2032. const uint8 kPolyPressure = 0xA0; ///< note, pressure
  2033. const uint8 kController = 0xB0; ///< controller, value
  2034. const uint8 kProgramChangeStatus = 0xC0; ///< program change
  2035. const uint8 kAfterTouchStatus = 0xD0; ///< channel pressure
  2036. const uint8 kPitchBendStatus = 0xE0; ///< lsb, msb
  2037. const float kMidiScaler = 1.f / 127.f;
  2038. static const uint8 kChannelMask = 0x0F;
  2039. static const uint8 kStatusMask = 0xF0;
  2040. static const uint32 kDataMask = 0x7F;
  2041. //-----------------------------------------------------------------------------
  2042. void Vst2Wrapper::processMidiEvent (VstMidiEvent* midiEvent, int32 bus)
  2043. {
  2044. Event toAdd = {bus, 0};
  2045. uint8 status = midiEvent->midiData[0] & kStatusMask;
  2046. uint8 channel = midiEvent->midiData[0] & kChannelMask;
  2047. if (channel < 16)
  2048. {
  2049. //--- -----------------------------
  2050. if (status == kNoteOn || status == kNoteOff)
  2051. {
  2052. toAdd.sampleOffset = midiEvent->deltaFrames;
  2053. if (midiEvent->flags & kVstMidiEventIsRealtime)
  2054. toAdd.flags |= Event::kIsLive;
  2055. toAdd.ppqPosition = 0;
  2056. if (status == kNoteOff) // note off
  2057. {
  2058. toAdd.type = Event::kNoteOffEvent;
  2059. toAdd.noteOff.channel = channel;
  2060. toAdd.noteOff.pitch = midiEvent->midiData[1];
  2061. toAdd.noteOff.velocity = (float)midiEvent->noteOffVelocity * kMidiScaler;
  2062. toAdd.noteOff.noteId = -1; // TODO ?
  2063. }
  2064. else if (status == kNoteOn) // note on
  2065. {
  2066. toAdd.type = Event::kNoteOnEvent;
  2067. toAdd.noteOn.channel = channel;
  2068. toAdd.noteOn.pitch = midiEvent->midiData[1];
  2069. toAdd.noteOn.tuning = midiEvent->detune;
  2070. toAdd.noteOn.velocity = (float)midiEvent->midiData[2] * kMidiScaler;
  2071. toAdd.noteOn.length = midiEvent->noteLength;
  2072. toAdd.noteOn.noteId = -1; // TODO ?
  2073. }
  2074. mInputEvents->addEvent (toAdd);
  2075. }
  2076. //--- -----------------------------
  2077. else if (status == kPolyPressure)
  2078. {
  2079. toAdd.type = Vst::Event::kPolyPressureEvent;
  2080. toAdd.sampleOffset = midiEvent->deltaFrames;
  2081. if (midiEvent->flags & kVstMidiEventIsRealtime)
  2082. toAdd.flags |= Event::kIsLive;
  2083. toAdd.ppqPosition = 0;
  2084. toAdd.polyPressure.channel = channel;
  2085. toAdd.polyPressure.pitch = midiEvent->midiData[1] & kDataMask;
  2086. toAdd.polyPressure.pressure = (midiEvent->midiData[2] & kDataMask) * kMidiScaler;
  2087. toAdd.polyPressure.noteId = -1; // TODO ?
  2088. mInputEvents->addEvent (toAdd);
  2089. }
  2090. //--- -----------------------------
  2091. else if (status == kController) // controller
  2092. {
  2093. if (bus < kMaxMidiMappingBusses && mMidiCCMapping[bus][channel])
  2094. {
  2095. ParamID paramID = mMidiCCMapping[bus][channel][midiEvent->midiData[1]];
  2096. if (paramID != kNoParamId)
  2097. {
  2098. ParamValue value = (double)midiEvent->midiData[2] * kMidiScaler;
  2099. int32 index = 0;
  2100. IParamValueQueue* queue = mInputChanges.addParameterData (paramID, index);
  2101. if (queue)
  2102. {
  2103. queue->addPoint (midiEvent->deltaFrames, value, index);
  2104. }
  2105. mGuiTransfer.addChange (paramID, value, midiEvent->deltaFrames);
  2106. }
  2107. }
  2108. }
  2109. //--- -----------------------------
  2110. else if (status == kPitchBendStatus)
  2111. {
  2112. if (bus < kMaxMidiMappingBusses && mMidiCCMapping[bus][channel])
  2113. {
  2114. ParamID paramID = mMidiCCMapping[bus][channel][Vst::kPitchBend];
  2115. if (paramID != kNoParamId)
  2116. {
  2117. const double kPitchWheelScaler = 1. / (double)0x3FFF;
  2118. const int32 ctrl = (midiEvent->midiData[1] & kDataMask) |
  2119. (midiEvent->midiData[2] & kDataMask) << 7;
  2120. ParamValue value = kPitchWheelScaler * (double)ctrl;
  2121. int32 index = 0;
  2122. IParamValueQueue* queue = mInputChanges.addParameterData (paramID, index);
  2123. if (queue)
  2124. {
  2125. queue->addPoint (midiEvent->deltaFrames, value, index);
  2126. }
  2127. mGuiTransfer.addChange (paramID, value, midiEvent->deltaFrames);
  2128. }
  2129. }
  2130. }
  2131. //--- -----------------------------
  2132. else if (status == kAfterTouchStatus)
  2133. {
  2134. if (bus < kMaxMidiMappingBusses && mMidiCCMapping[bus][channel])
  2135. {
  2136. ParamID paramID = mMidiCCMapping[bus][channel][Vst::kAfterTouch];
  2137. if (paramID != kNoParamId)
  2138. {
  2139. ParamValue value =
  2140. (ParamValue) (midiEvent->midiData[1] & kDataMask) * kMidiScaler;
  2141. int32 index = 0;
  2142. IParamValueQueue* queue = mInputChanges.addParameterData (paramID, index);
  2143. if (queue)
  2144. {
  2145. queue->addPoint (midiEvent->deltaFrames, value, index);
  2146. }
  2147. mGuiTransfer.addChange (paramID, value, midiEvent->deltaFrames);
  2148. }
  2149. }
  2150. }
  2151. //--- -----------------------------
  2152. else if (status == kProgramChangeStatus)
  2153. {
  2154. if (mProgramChangeParameterIDs[channel] != kNoParamId &&
  2155. mProgramChangeParameterIdxs[channel] != -1)
  2156. {
  2157. ParameterInfo paramInfo = {0};
  2158. if (mController->getParameterInfo (mProgramChangeParameterIdxs[channel],
  2159. paramInfo) == kResultTrue)
  2160. {
  2161. int32 program = midiEvent->midiData[1];
  2162. if (paramInfo.stepCount > 0 && program <= paramInfo.stepCount)
  2163. {
  2164. ParamValue normalized =
  2165. (ParamValue)program / (ParamValue)paramInfo.stepCount;
  2166. addParameterChange (mProgramChangeParameterIDs[channel], normalized,
  2167. midiEvent->deltaFrames);
  2168. }
  2169. }
  2170. }
  2171. }
  2172. }
  2173. }
  2174. //-----------------------------------------------------------------------------
  2175. VstInt32 Vst2Wrapper::processEvents (VstEvents* events)
  2176. {
  2177. if (mInputEvents == 0)
  2178. return 0;
  2179. mInputEvents->clear ();
  2180. for (int32 i = 0; i < events->numEvents; i++)
  2181. {
  2182. VstEvent* e = events->events[i];
  2183. if (e->type == kVstMidiType)
  2184. {
  2185. VstMidiEvent* midiEvent = (VstMidiEvent*)e;
  2186. processMidiEvent (midiEvent, 0);
  2187. }
  2188. //--- -----------------------------
  2189. else if (e->type == kVstSysExType)
  2190. {
  2191. Event toAdd = {0};
  2192. VstMidiSysexEvent& src = *(VstMidiSysexEvent*)e;
  2193. toAdd.type = Event::kDataEvent;
  2194. toAdd.sampleOffset = e->deltaFrames;
  2195. toAdd.data.type = DataEvent::kMidiSysEx;
  2196. toAdd.data.size = src.dumpBytes;
  2197. toAdd.data.bytes = (uint8*)src.sysexDump;
  2198. mInputEvents->addEvent (toAdd);
  2199. }
  2200. }
  2201. return 0;
  2202. }
  2203. //-----------------------------------------------------------------------------
  2204. inline void Vst2Wrapper::processOutputEvents ()
  2205. {
  2206. if (mVst2OutputEvents && mOutputEvents && mOutputEvents->getEventCount () > 0)
  2207. {
  2208. mVst2OutputEvents->flush ();
  2209. Event e = {0};
  2210. for (int32 i = 0, total = mOutputEvents->getEventCount (); i < total; i++)
  2211. {
  2212. if (mOutputEvents->getEvent (i, e) != kResultOk)
  2213. break;
  2214. //---SysExclusif----------------
  2215. if (e.type == Event::kDataEvent && e.data.type == DataEvent::kMidiSysEx)
  2216. {
  2217. VstMidiSysexEvent sysexEvent = {0};
  2218. sysexEvent.deltaFrames = e.sampleOffset;
  2219. sysexEvent.dumpBytes = e.data.size;
  2220. sysexEvent.sysexDump = (char*)e.data.bytes;
  2221. if (!mVst2OutputEvents->add (sysexEvent))
  2222. break;
  2223. }
  2224. else
  2225. {
  2226. VstMidiEvent midiEvent = {0};
  2227. midiEvent.deltaFrames = e.sampleOffset;
  2228. if (e.flags & Event::kIsLive)
  2229. midiEvent.flags = kVstMidiEventIsRealtime;
  2230. char* midiData = midiEvent.midiData;
  2231. switch (e.type)
  2232. {
  2233. //--- ---------------------
  2234. case Event::kNoteOnEvent:
  2235. midiData[0] = (char)(kNoteOn | (e.noteOn.channel & kChannelMask));
  2236. midiData[1] = (char)(e.noteOn.pitch & kDataMask);
  2237. midiData[2] =
  2238. (char)((int32) (e.noteOn.velocity * 127.f + 0.4999999f) & kDataMask);
  2239. if (midiData[2] == 0) // zero velocity => note off
  2240. midiData[0] = (char)(kNoteOff | (e.noteOn.channel & kChannelMask));
  2241. midiEvent.detune = (char)e.noteOn.tuning;
  2242. midiEvent.noteLength = e.noteOn.length;
  2243. break;
  2244. //--- ---------------------
  2245. case Event::kNoteOffEvent:
  2246. midiData[0] = (char)(kNoteOff | (e.noteOff.channel & kChannelMask));
  2247. midiData[1] = (char)(e.noteOff.pitch & kDataMask);
  2248. midiData[2] = midiEvent.noteOffVelocity =
  2249. (char)((int32) (e.noteOff.velocity * 127.f + 0.4999999f) & kDataMask);
  2250. break;
  2251. break;
  2252. }
  2253. if (!mVst2OutputEvents->add (midiEvent))
  2254. break;
  2255. }
  2256. }
  2257. mOutputEvents->clear ();
  2258. sendVstEventsToHost (*mVst2OutputEvents);
  2259. }
  2260. }
  2261. //-----------------------------------------------------------------------------
  2262. inline void Vst2Wrapper::setupProcessTimeInfo ()
  2263. {
  2264. VstTimeInfo* vst2timeInfo = getTimeInfo (0xffffffff);
  2265. if (vst2timeInfo)
  2266. {
  2267. const uint32 portableFlags =
  2268. ProcessContext::kPlaying | ProcessContext::kCycleActive | ProcessContext::kRecording |
  2269. ProcessContext::kSystemTimeValid | ProcessContext::kProjectTimeMusicValid |
  2270. ProcessContext::kBarPositionValid | ProcessContext::kCycleValid |
  2271. ProcessContext::kTempoValid | ProcessContext::kTimeSigValid |
  2272. ProcessContext::kSmpteValid | ProcessContext::kClockValid;
  2273. mProcessContext.state = ((uint32)vst2timeInfo->flags) & portableFlags;
  2274. mProcessContext.sampleRate = vst2timeInfo->sampleRate;
  2275. mProcessContext.projectTimeSamples = (TSamples)vst2timeInfo->samplePos;
  2276. if (mProcessContext.state & ProcessContext::kSystemTimeValid)
  2277. mProcessContext.systemTime = (TSamples)vst2timeInfo->nanoSeconds;
  2278. else
  2279. mProcessContext.systemTime = 0;
  2280. if (mProcessContext.state & ProcessContext::kProjectTimeMusicValid)
  2281. mProcessContext.projectTimeMusic = vst2timeInfo->ppqPos;
  2282. else
  2283. mProcessContext.projectTimeMusic = 0;
  2284. if (mProcessContext.state & ProcessContext::kBarPositionValid)
  2285. mProcessContext.barPositionMusic = vst2timeInfo->barStartPos;
  2286. else
  2287. mProcessContext.barPositionMusic = 0;
  2288. if (mProcessContext.state & ProcessContext::kCycleValid)
  2289. {
  2290. mProcessContext.cycleStartMusic = vst2timeInfo->cycleStartPos;
  2291. mProcessContext.cycleEndMusic = vst2timeInfo->cycleEndPos;
  2292. }
  2293. else
  2294. mProcessContext.cycleStartMusic = mProcessContext.cycleEndMusic = 0.0;
  2295. if (mProcessContext.state & ProcessContext::kTempoValid)
  2296. mProcessContext.tempo = vst2timeInfo->tempo;
  2297. else
  2298. mProcessContext.tempo = 120.0;
  2299. if (mProcessContext.state & ProcessContext::kTimeSigValid)
  2300. {
  2301. mProcessContext.timeSigNumerator = vst2timeInfo->timeSigNumerator;
  2302. mProcessContext.timeSigDenominator = vst2timeInfo->timeSigDenominator;
  2303. }
  2304. else
  2305. mProcessContext.timeSigNumerator = mProcessContext.timeSigDenominator = 4;
  2306. mProcessContext.frameRate.flags = 0;
  2307. if (mProcessContext.state & ProcessContext::kSmpteValid)
  2308. {
  2309. mProcessContext.smpteOffsetSubframes = vst2timeInfo->smpteOffset;
  2310. switch (vst2timeInfo->smpteFrameRate)
  2311. {
  2312. case kVstSmpte24fps: ///< 24 fps
  2313. mProcessContext.frameRate.framesPerSecond = 24;
  2314. break;
  2315. case kVstSmpte25fps: ///< 25 fps
  2316. mProcessContext.frameRate.framesPerSecond = 25;
  2317. break;
  2318. case kVstSmpte2997fps: ///< 29.97 fps
  2319. mProcessContext.frameRate.framesPerSecond = 30;
  2320. mProcessContext.frameRate.flags = FrameRate::kPullDownRate;
  2321. break;
  2322. case kVstSmpte30fps: ///< 30 fps
  2323. mProcessContext.frameRate.framesPerSecond = 30;
  2324. break;
  2325. case kVstSmpte2997dfps: ///< 29.97 drop
  2326. mProcessContext.frameRate.framesPerSecond = 30;
  2327. mProcessContext.frameRate.flags =
  2328. FrameRate::kPullDownRate | FrameRate::kDropRate;
  2329. break;
  2330. case kVstSmpte30dfps: ///< 30 drop
  2331. mProcessContext.frameRate.framesPerSecond = 30;
  2332. mProcessContext.frameRate.flags = FrameRate::kDropRate;
  2333. break;
  2334. case kVstSmpteFilm16mm: // not a smpte rate
  2335. case kVstSmpteFilm35mm:
  2336. mProcessContext.state &= ~ProcessContext::kSmpteValid;
  2337. break;
  2338. case kVstSmpte239fps: ///< 23.9 fps
  2339. mProcessContext.frameRate.framesPerSecond = 24;
  2340. mProcessContext.frameRate.flags = FrameRate::kPullDownRate;
  2341. break;
  2342. case kVstSmpte249fps: ///< 24.9 fps
  2343. mProcessContext.frameRate.framesPerSecond = 25;
  2344. mProcessContext.frameRate.flags = FrameRate::kPullDownRate;
  2345. break;
  2346. case kVstSmpte599fps: ///< 59.9 fps
  2347. mProcessContext.frameRate.framesPerSecond = 60;
  2348. mProcessContext.frameRate.flags = FrameRate::kPullDownRate;
  2349. break;
  2350. case kVstSmpte60fps: ///< 60 fps
  2351. mProcessContext.frameRate.framesPerSecond = 60;
  2352. break;
  2353. default: mProcessContext.state &= ~ProcessContext::kSmpteValid; break;
  2354. }
  2355. }
  2356. else
  2357. {
  2358. mProcessContext.smpteOffsetSubframes = 0;
  2359. mProcessContext.frameRate.framesPerSecond = 0;
  2360. }
  2361. ///< MIDI Clock Resolution (24 Per Quarter Note), can be negative (nearest)
  2362. if (mProcessContext.state & ProcessContext::kClockValid)
  2363. mProcessContext.samplesToNextClock = vst2timeInfo->samplesToNextClock;
  2364. else
  2365. mProcessContext.samplesToNextClock = 0;
  2366. mProcessData.processContext = &mProcessContext;
  2367. }
  2368. else
  2369. mProcessData.processContext = nullptr;
  2370. }
  2371. //-----------------------------------------------------------------------------
  2372. template <class T>
  2373. inline void Vst2Wrapper::setProcessingBuffers (T** inputs, T** outputs)
  2374. {
  2375. // set processing buffers
  2376. int32 sourceIndex = 0;
  2377. for (int32 i = 0; i < mProcessData.numInputs; i++)
  2378. {
  2379. AudioBusBuffers& buffers = mProcessData.inputs[i];
  2380. if (mMainAudioInputBuses & (uint64 (1) << i))
  2381. {
  2382. for (int32 j = 0; j < buffers.numChannels; j++)
  2383. {
  2384. buffers.channelBuffers32[j] = (Sample32*)inputs[sourceIndex++];
  2385. }
  2386. }
  2387. else
  2388. buffers.silenceFlags = HostProcessData::kAllChannelsSilent;
  2389. }
  2390. sourceIndex = 0;
  2391. for (int32 i = 0; i < mProcessData.numOutputs; i++)
  2392. {
  2393. AudioBusBuffers& buffers = mProcessData.outputs[i];
  2394. buffers.silenceFlags = 0;
  2395. if (mMainAudioOutputBuses & (uint64 (1) << i))
  2396. {
  2397. for (int32 j = 0; j < buffers.numChannels; j++)
  2398. {
  2399. buffers.channelBuffers32[j] = (Sample32*)outputs[sourceIndex++];
  2400. }
  2401. }
  2402. }
  2403. }
  2404. //-----------------------------------------------------------------------------
  2405. inline void Vst2Wrapper::setEventPPQPositions ()
  2406. {
  2407. if (!mInputEvents)
  2408. return;
  2409. int32 eventCount = mInputEvents->getEventCount ();
  2410. if (eventCount > 0 && (mProcessContext.state & ProcessContext::kTempoValid) &&
  2411. (mProcessContext.state & ProcessContext::kProjectTimeMusicValid))
  2412. {
  2413. TQuarterNotes projectTimeMusic = mProcessContext.projectTimeMusic;
  2414. double secondsToQuarterNoteScaler = mProcessContext.tempo / 60.0;
  2415. double multiplicator = secondsToQuarterNoteScaler / this->sampleRate;
  2416. for (int32 i = 0; i < eventCount; i++)
  2417. {
  2418. Event* e = mInputEvents->getEventByIndex (i);
  2419. if (e)
  2420. {
  2421. TQuarterNotes localTimeMusic = e->sampleOffset * multiplicator;
  2422. e->ppqPosition = projectTimeMusic + localTimeMusic;
  2423. }
  2424. }
  2425. }
  2426. }
  2427. //-----------------------------------------------------------------------------
  2428. inline void Vst2Wrapper::doProcess (VstInt32 sampleFrames)
  2429. {
  2430. if (!mProcessor)
  2431. return;
  2432. mProcessData.numSamples = sampleFrames;
  2433. if (processing == false)
  2434. startProcess ();
  2435. mProcessData.inputEvents = mInputEvents;
  2436. mProcessData.outputEvents = mOutputEvents;
  2437. setupProcessTimeInfo ();
  2438. setEventPPQPositions ();
  2439. mInputTransfer.transferChangesTo (mInputChanges);
  2440. mProcessData.inputParameterChanges = &mInputChanges;
  2441. mProcessData.outputParameterChanges = &mOutputChanges;
  2442. mOutputChanges.clearQueue ();
  2443. // VST 3 process call
  2444. mProcessor->process (mProcessData);
  2445. mOutputTransfer.transferChangesFrom (mOutputChanges);
  2446. processOutputEvents ();
  2447. // clear input parameters and events
  2448. mInputChanges.clearQueue ();
  2449. if (mInputEvents)
  2450. mInputEvents->clear ();
  2451. }
  2452. //-----------------------------------------------------------------------------
  2453. void Vst2Wrapper::processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames)
  2454. {
  2455. if (mProcessData.symbolicSampleSize != kSample32)
  2456. return;
  2457. setProcessingBuffers<float> (inputs, outputs);
  2458. doProcess (sampleFrames);
  2459. }
  2460. //-----------------------------------------------------------------------------
  2461. void Vst2Wrapper::processDoubleReplacing (double** inputs, double** outputs, VstInt32 sampleFrames)
  2462. {
  2463. if (mProcessData.symbolicSampleSize != kSample64)
  2464. return;
  2465. setProcessingBuffers<double> (inputs, outputs);
  2466. doProcess (sampleFrames);
  2467. }
  2468. //-----------------------------------------------------------------------------
  2469. void Vst2Wrapper::onTimer (Timer*)
  2470. {
  2471. if (!mController)
  2472. return;
  2473. ParamID id;
  2474. ParamValue value;
  2475. int32 sampleOffset;
  2476. while (mOutputTransfer.getNextChange (id, value, sampleOffset))
  2477. {
  2478. mController->setParamNormalized (id, value);
  2479. }
  2480. while (mGuiTransfer.getNextChange (id, value, sampleOffset))
  2481. {
  2482. mController->setParamNormalized (id, value);
  2483. }
  2484. }
  2485. //-----------------------------------------------------------------------------
  2486. // static
  2487. //-----------------------------------------------------------------------------
  2488. AudioEffect* Vst2Wrapper::create (IPluginFactory* factory, const TUID vst3ComponentID,
  2489. VstInt32 vst2ID, audioMasterCallback audioMaster)
  2490. {
  2491. if (!factory)
  2492. return 0;
  2493. IAudioProcessor* processor = nullptr;
  2494. FReleaser factoryReleaser (factory);
  2495. factory->createInstance (vst3ComponentID, IAudioProcessor::iid, (void**)&processor);
  2496. if (processor)
  2497. {
  2498. IEditController* controller = nullptr;
  2499. if (processor->queryInterface (IEditController::iid, (void**)&controller) != kResultTrue)
  2500. {
  2501. FUnknownPtr<IComponent> component (processor);
  2502. if (component)
  2503. {
  2504. FUID editorCID;
  2505. if (component->getControllerClassId (editorCID) == kResultTrue)
  2506. {
  2507. factory->createInstance (editorCID, IEditController::iid, (void**)&controller);
  2508. }
  2509. }
  2510. }
  2511. Vst2Wrapper* wrapper =
  2512. new Vst2Wrapper (processor, controller, audioMaster, vst3ComponentID, vst2ID, factory);
  2513. if (wrapper->init () == false)
  2514. {
  2515. delete wrapper;
  2516. return 0;
  2517. }
  2518. FUnknownPtr<IPluginFactory2> factory2 (factory);
  2519. if (factory2)
  2520. {
  2521. PFactoryInfo factoryInfo;
  2522. if (factory2->getFactoryInfo (&factoryInfo) == kResultTrue)
  2523. wrapper->setVendorName (factoryInfo.vendor);
  2524. for (int32 i = 0; i < factory2->countClasses (); i++)
  2525. {
  2526. Steinberg::PClassInfo2 classInfo2;
  2527. if (factory2->getClassInfo2 (i, &classInfo2) == Steinberg::kResultTrue)
  2528. {
  2529. if (memcmp (classInfo2.cid, vst3ComponentID, sizeof (TUID)) == 0)
  2530. {
  2531. wrapper->setSubCategories (classInfo2.subCategories);
  2532. wrapper->setEffectName (classInfo2.name);
  2533. wrapper->setEffectVersion (classInfo2.version);
  2534. if (classInfo2.vendor[0] != 0)
  2535. wrapper->setVendorName (classInfo2.vendor);
  2536. break;
  2537. }
  2538. }
  2539. }
  2540. }
  2541. return wrapper;
  2542. }
  2543. return 0;
  2544. }
  2545. // FUnknown
  2546. //-----------------------------------------------------------------------------
  2547. tresult PLUGIN_API Vst2Wrapper::queryInterface (const char* iid, void** obj)
  2548. {
  2549. QUERY_INTERFACE (iid, obj, FUnknown::iid, Vst::IHostApplication)
  2550. QUERY_INTERFACE (iid, obj, Vst::IHostApplication::iid, Vst::IHostApplication)
  2551. QUERY_INTERFACE (iid, obj, Vst::IComponentHandler::iid, Vst::IComponentHandler)
  2552. QUERY_INTERFACE (iid, obj, Vst::IUnitHandler::iid, Vst::IUnitHandler)
  2553. // we are a VST 3 to VST 2 Wrapper
  2554. QUERY_INTERFACE (iid, obj, Vst::IVst3ToVst2Wrapper::iid, Vst::IVst3ToVst2Wrapper)
  2555. *obj = 0;
  2556. return kNoInterface;
  2557. }
  2558. //-----------------------------------------------------------------------------
  2559. // IHostApplication
  2560. //-----------------------------------------------------------------------------
  2561. tresult PLUGIN_API Vst2Wrapper::createInstance (TUID cid, TUID iid, void** obj)
  2562. {
  2563. FUID classID (cid);
  2564. FUID interfaceID (iid);
  2565. if (classID == IMessage::iid && interfaceID == IMessage::iid)
  2566. {
  2567. *obj = new HostMessage;
  2568. return kResultTrue;
  2569. }
  2570. else if (classID == IAttributeList::iid && interfaceID == IAttributeList::iid)
  2571. {
  2572. *obj = new HostAttributeList;
  2573. return kResultTrue;
  2574. }
  2575. *obj = 0;
  2576. return kResultFalse;
  2577. }
  2578. //-----------------------------------------------------------------------------
  2579. tresult PLUGIN_API Vst2Wrapper::getName (String128 name)
  2580. {
  2581. char8 productString[128];
  2582. if (getHostProductString (productString))
  2583. {
  2584. String str (productString);
  2585. str.copyTo16 (name, 0, 127);
  2586. return kResultTrue;
  2587. }
  2588. return kResultFalse;
  2589. }
  2590. //-----------------------------------------------------------------------------
  2591. // IComponentHandler
  2592. //-----------------------------------------------------------------------------
  2593. tresult PLUGIN_API Vst2Wrapper::beginEdit (ParamID tag)
  2594. {
  2595. std::map<ParamID, int32>::const_iterator iter = mParamIndexMap.find (tag);
  2596. if (iter != mParamIndexMap.end ())
  2597. AudioEffectX::beginEdit ((*iter).second);
  2598. return kResultTrue;
  2599. }
  2600. //-----------------------------------------------------------------------------
  2601. tresult PLUGIN_API Vst2Wrapper::performEdit (ParamID tag, ParamValue valueNormalized)
  2602. {
  2603. std::map<ParamID, int32>::const_iterator iter = mParamIndexMap.find (tag);
  2604. if (iter != mParamIndexMap.end () && audioMaster)
  2605. audioMaster (&cEffect, audioMasterAutomate, (*iter).second, 0, 0,
  2606. (float)valueNormalized); // value is in opt
  2607. mInputTransfer.addChange (tag, valueNormalized, 0);
  2608. return kResultTrue;
  2609. }
  2610. //-----------------------------------------------------------------------------
  2611. tresult PLUGIN_API Vst2Wrapper::endEdit (ParamID tag)
  2612. {
  2613. std::map<ParamID, int32>::const_iterator iter = mParamIndexMap.find (tag);
  2614. if (iter != mParamIndexMap.end ())
  2615. AudioEffectX::endEdit ((*iter).second);
  2616. return kResultTrue;
  2617. }
  2618. //-----------------------------------------------------------------------------
  2619. tresult PLUGIN_API Vst2Wrapper::restartComponent (int32 flags)
  2620. {
  2621. tresult result = kResultFalse;
  2622. //--- ----------------------
  2623. if (flags & kIoChanged)
  2624. {
  2625. setupBuses ();
  2626. ioChanged ();
  2627. result = kResultTrue;
  2628. }
  2629. //--- ----------------------
  2630. if ((flags & kParamValuesChanged) || (flags & kParamTitlesChanged))
  2631. {
  2632. updateDisplay ();
  2633. result = kResultTrue;
  2634. }
  2635. //--- ----------------------
  2636. if (flags & kLatencyChanged)
  2637. {
  2638. if (mProcessor)
  2639. setInitialDelay (mProcessor->getLatencySamples ());
  2640. ioChanged ();
  2641. result = kResultTrue;
  2642. }
  2643. //--- ----------------------
  2644. if (flags & kMidiCCAssignmentChanged)
  2645. {
  2646. initMidiCtrlerAssignment ();
  2647. result = kResultTrue;
  2648. }
  2649. // kReloadComponent is Not supported in VST 2
  2650. return result;
  2651. }
  2652. //-----------------------------------------------------------------------------
  2653. // IUnitHandler
  2654. //-----------------------------------------------------------------------------
  2655. tresult PLUGIN_API Vst2Wrapper::notifyUnitSelection (UnitID unitId)
  2656. {
  2657. return kResultTrue;
  2658. }
  2659. //-----------------------------------------------------------------------------
  2660. tresult PLUGIN_API Vst2Wrapper::notifyProgramListChange (ProgramListID listId, int32 programIndex)
  2661. {
  2662. // TODO -> redirect to hasMidiProgramsChanged somehow...
  2663. return kResultTrue;
  2664. }
  2665. //-----------------------------------------------------------------------------
  2666. } // namespace Vst
  2667. } // namespace Steinberg
  2668. extern bool InitModule ();
  2669. //-----------------------------------------------------------------------------
  2670. extern "C" {
  2671. #if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
  2672. #define VST_EXPORT __attribute__ ((visibility ("default")))
  2673. #elif WINDOWS
  2674. #define VST_EXPORT __declspec( dllexport )
  2675. #else
  2676. #define VST_EXPORT
  2677. #endif
  2678. //-----------------------------------------------------------------------------
  2679. /** Prototype of the export function main */
  2680. //-----------------------------------------------------------------------------
  2681. VST_EXPORT AEffect* VSTPluginMain (audioMasterCallback audioMaster)
  2682. {
  2683. // Get VST Version of the Host
  2684. if (!audioMaster (0, audioMasterVersion, 0, 0, 0, 0))
  2685. return 0; // old version
  2686. if (InitModule () == false)
  2687. return 0;
  2688. // Create the AudioEffect
  2689. AudioEffect* effect = createEffectInstance (audioMaster);
  2690. if (!effect)
  2691. return 0;
  2692. // Return the VST AEffect structure
  2693. return effect->getAeffect ();
  2694. }
  2695. //-----------------------------------------------------------------------------
  2696. // support for old hosts not looking for VSTPluginMain
  2697. #if (TARGET_API_MAC_CARBON && __ppc__)
  2698. VST_EXPORT AEffect* main_macho (audioMasterCallback audioMaster)
  2699. {
  2700. return VSTPluginMain (audioMaster);
  2701. }
  2702. #elif WIN32
  2703. VST_EXPORT AEffect* MAIN (audioMasterCallback audioMaster)
  2704. {
  2705. return VSTPluginMain (audioMaster);
  2706. }
  2707. #elif BEOS
  2708. VST_EXPORT AEffect* main_plugin (audioMasterCallback audioMaster)
  2709. {
  2710. return VSTPluginMain (audioMaster);
  2711. }
  2712. #endif
  2713. } // extern "C"
  2714. //-----------------------------------------------------------------------------
  2715. /// \endcond