VST3 Host initialization sequence

I’m hoping someone can help me figure this out. I no longer have any hair.

I’ve created a VST Host DLL for our audio application, but I’m not sure I have the initialization sequence correct. Some plugins don’t load correctly, and other will crash.

The following is the diagnostic output from my load routine for 2 differnt plugins. The first seems to load correctly, but the second crashes:

20-11-25 13:49:21.94 Calling Module::create for bx_console SSL 4000 E
20-11-25 13:49:21.94 Module create success
20-11-25 13:49:21.94 Calling factory.createInstance to create component
20-11-25 13:49:21.94 Component creation success
20-11-25 13:49:21.94 calling component->initialize
20-11-25 13:49:22.02 component->initialize → 0
20-11-25 13:49:22.02 creating IAudioProcessor from component
20-11-25 13:49:22.02 processor creation success
20-11-25 13:49:22.02 creating controller from component
20-11-25 13:49:22.02 controller->setComponentHandler → 0
20-11-25 13:49:22.02 isSingleComponent == true. controller ↔ component connection not required
20-11-25 13:49:22.02 Creating editor view
20-11-25 13:49:22.02 editor view creation success
20-11-25 13:49:22.02 Setting bus arrangements.
20-11-25 13:49:22.02 processor->setBusArrangements failed → 1.
20-11-25 13:49:22.02 processor->setupProcessing → 0
20-11-25 13:49:22.02 activateBus input → 0
20-11-25 13:49:22.02 activateBus output → 0
20-11-25 13:49:22.02 component->setActive → 0.
20-11-25 13:49:22.02 processor->setProcessing → 0.
20-11-25 13:49:22.02 BusCount in=2 out=1
20-11-25 13:49:22.02 Loading saved Plugin settings
20-11-25 13:49:22.02 Plugin latency is 0 samples

20-11-25 13:59:21.94 Calling Module::create for Ozone 11 Equalizer
20-11-25 13:59:21.94 Module create success
20-11-25 13:59:21.94 Calling factory.createInstance to create component
20-11-25 13:59:21.94 Component creation success
20-11-25 13:59:21.94 calling component->initialize
20-11-25 13:59:22.02 component->initialize → 0
20-11-25 13:59:22.02 creating IAudioProcessor from component
20-11-25 13:59:22.02 processor creation success
20-11-25 13:59:22.02 creating controller from component
20-11-25 13:59:22.02 controller->setComponentHandler → 0
20-11-25 13:49:22.02 Connecting controller ↔ component
20-11-25 13:49:22:02 Exception thrown in Ozone 11 Equalizer. Access violation reading location 0x0000000000000000.

Any help is greatly appreciated.

are you calling controller->initialize ?

Yvan,
When the controller is created from the factory using classID, it crashes when connecting component <-> controller below.
When the controller is created from the component, it always returns 1 (fail).

Here's the code:

	// --- Create controller
	TRACE(_T("Getting controller from classID\n"));
	TUID ctrlTuid = { 0 };
	if (component->getControllerClassId(ctrlTuid) == kResultOk)
	{
		TRACE(_T("calling factory.createInstance to create controller\n"));
		controller = factory.createInstance<IEditController>(ctrlTuid);
	}

	if (!controller)
	{
		TRACE(_T("creating controller from component\n"));
		controller = FUnknownPtr<IEditController>(component);
		isSingleComponent = true;
	}

	if (controller)
	{
		TRACE("Calling controller->initialize\n");
		status = controller->initialize(hostCtx);
		TRACE(_T("controller->initialize -> %d\n"), status);

		TRACE(_T("Setting controller Component Handler\n"));
		status = controller->setComponentHandler(&componentHandler);
		TRACE(_T("controller->setComponentHandler -> %d\n"), status);
	}

	try
	{
		// --- Connect controller <-> component
		if (!isSingleComponent)
		{
			TRACE(_T("Connecting controller <-> component\n"));
			compCP = FUnknownPtr<Steinberg::Vst::IConnectionPoint>(component);
			ctrlCP = FUnknownPtr<Steinberg::Vst::IConnectionPoint>(controller);
			if (compCP && ctrlCP)
			{
====>			status = compCP->connect(ctrlCP);
				TRACE(_T("compCP->connect -> %d\n"), status);
				status = ctrlCP->connect(compCP);
				TRACE(_T("ctrlCP->connect -> %d\n"), status);
			}
		}
	}
	catch (...)
	{
		TRACE("Connect controller <-> component");
	}

Did you try the audiohost example provided by the SDK?

check public.sdk/source/vst/hosting/plugprovider.cpp for setupPlugin where a plugin in initialized…

check type for component and controller, order of calling….

Yvan, Thanks for the info. I made the changes you suggested and I’m still crashing inside connectionproxy.cpp here: tresult res = srcConnection→connect(this);

New source code below.

Thanks for your help, Russ…

  // create component (IComponent)
  TRACE("Calling factory.createInstance to create component\n");
  component = factory.createInstance<IComponent>(procInfo->ID());
  if (!component)
  {
     TRACE("Failed to create component instance -> %d\n", status);
     return false;
  }

  TRACE("Component creation success\n");

  // Initialize the component with your host context
  TRACE(_T("calling component->initialize\n"));
  hostCtx = new MyHostApp();

  if (auto plugBase = U::cast<IPluginBase>(component))
  {
     status = plugBase->initialize(hostCtx);
     if (status != kResultOk)
     {
        TRACE(_T("Failed to initialize component\n"));
        return false;
     }
  }
  else
  {
     TRACE(_T("Failed to get IPluginBase from component\n"));
     return false;
  }

  TRACE("Getting controller from classID\n");
  TUID ctrlTuid = { 0 };
  // try to create the controller part from the component
  // (for Plug-ins which did not succeed to separate component from controller)
  if (component->queryInterface(IEditController::iid, (void**)&controller) == kResultTrue)
  {
     isSingleComponent = true;
  }
  else
  {
     // ask for the associated controller class ID
     if (component->getControllerClassId(ctrlTuid) == kResultTrue)
     {
        // create its controller part created from the factory
        controller = factory.createInstance<IEditController>(VST3::UID(ctrlTuid));
        if (controller)
        {
           // initialize the component with our context
           if (auto plugCtrlBase = U::cast<IPluginBase>(controller))
           {
              status = plugCtrlBase->initialize(hostCtx);
              if (status != kResultOk)
              {
                 TRACE(_T("Failed to initialize controller!\n"));
              }
           }
           else
           {
              TRACE(_T("Failed to get IPluginBase from controller\n"));
              return false;
           }
        }
     }
     else
     {
        TRACE(_T("Component does not provide a required controller class ID\n"));
     }
  }

  if (status != kResultOk)
  {
     component.reset();
     controller.reset();
  } 
  else
  {
     // --- Connect controller <-> component
     if (!isSingleComponent)
     {
        if (component && controller)
        {
           TRACE("Connecting controller <-> component\n");
           //auto compICP = U::cast<IConnectionPoint>(component);
           //auto contrICP = U::cast<IConnectionPoint>(controller);
           FUnknownPtr<Steinberg::Vst::IConnectionPoint> compICP{ nullptr };
           FUnknownPtr<Steinberg::Vst::IConnectionPoint> contrICP{ nullptr };
           compICP = FUnknownPtr<Steinberg::Vst::IConnectionPoint>(component);
           contrICP = FUnknownPtr<Steinberg::Vst::IConnectionPoint>(controller);
           if (!compICP || !contrICP)
              return false;

           componentCP = owned(new ConnectionProxy(compICP));
           controllerCP = owned(new ConnectionProxy(contrICP));

           status = componentCP->connect(contrICP);
           if (status != kResultTrue)
           {
              TRACE("componentCP->connect -> %d\n", status);
              return false;
           }
           status = controllerCP->connect(compICP);
           if (status != kResultTrue)
           {
              TRACE("controllerCP->connect -> %d\n", status);
              return false;
           }
        }
     }
  }

Did you try the audiohost example provided by the SDK?

Does it generate the crash?

Yes I did. It crashes as well. That’s why I abandoned the PlugProvider and used the code above.

Any chance I can get source code for the VST3 Plugin Test Host app to compare ?

1 Like