[Solved] Can't get edit controller to work

Edit: So, pongasoft happened to be browsing this forum right now. I happened to check out his excellent tutorial on br0kenb1ts (Br0kenB1ts | VST (3.6.9) Development Notes - Part 1). I happened to notice that I needed to call

setControllerClass(FirstSynthControllerUID)

in order to get it to work!
Now, the parameter does not work though, but that is for another day and another post perhaps. I’m done with this for today :slight_smile:

Thanks pongosoft!!

Original post →

Hi!
First post on forum, by a very novice VST3 developer. I am working through the SDK examples, and I have trouble getting an EditController to work.
When I look at the mda plugins, I can’t see anywhere where the GUI part would be defined, so I guess the host creates the basic GUI based on the parameters of the plug.

I have tried to do the same as the examples, and the processor works perfectly, but the EditController fails to work.

When I run my plugin through the validator, I get the following:

 Factory Info:
        vendor = Kilobytelogic
        url = http://www.kilobytelogic.com
        email = mailto:info@kilobytelogic.com

  Class Info 0:
        name = FirstSynth VST3
        category = Audio Module Class
        cid = 1FFEC88C727EE1BE7F8F3C28A23B23FF

  Class Info 1:
        name = FirstSynth VST3 Controller
        category = Component Controller Class
        cid = 6845E6BE64C711E8ADC0FA7AE01BBEBC

* Creating tests...

* Running tests...

-------------------------------------------------------------
TestSuite : FirstSynth VST3
-------------------------------------------------------------

-------------------------------------------------------------
TestSuite : General Tests
-------------------------------------------------------------

[Scan Editor Classes]
Info:  ===Scan Editor Classes ====================================
Info:  This component does not export an edit controller class ID!!!
[Succeeded]

My factory looks like this:

BEGIN_FACTORY_DEF("Kilobytelogic",
	"http://www.kilobytelogic.com",
	"mailto:info@kilobytelogic.com")

	DEF_CLASS2 (INLINE_UID_FROM_FUID(NSFirstSynth::FirstSynthProcessorUID),
		PClassInfo::kManyInstances,
		kVstAudioEffectClass,
		stringPluginName,
		Vst::kDistributable,
		Vst::PlugType::kInstrumentSynth,
		FULL_VERSION_STR,
		kVstVersionString,
		NSFirstSynth::FirstSynth::createInstance)

	DEF_CLASS2 (INLINE_UID_FROM_FUID(NSFirstSynth::FirstSynthControllerUID),
		PClassInfo::kManyInstances,
		kVstComponentControllerClass,
		stringControllerName,
		0,
		Vst::PlugType::kInstrumentSynth,
		FULL_VERSION_STR,
		kVstVersionString,
		NSFirstSynth::FirstSynthController::createInstance)


END_FACTORY

Note that the line 355 in validator.cpp prints out the cid alright.

For sake of completeness, here are my controller files:
FirstSynthController.h

#pragma once

#include "vstgui4/vstgui/plugin-bindings/vst3editor.h"
#include "public.sdk/source/vst/vsteditcontroller.h"
#include "pluginterfaces/base/ftypes.h"
#include "pluginterfaces/base/ustring.h"
#include "pluginterfaces/base/ibstream.h"
#include "StandardPatch.h"

using namespace Steinberg::Vst;
using namespace Steinberg;

namespace NSFirstSynth {

	static const FUID FirstSynthControllerUID(0x6845e6be, 0x64c711e8, 0xadc0fa7a, 0xe01bbebc);

	class FirstSynthController : public Steinberg::Vst::EditController
	{

	public:
		StandardPatch patch;
		int dummy;

		FirstSynthController();


		static FUnknown* createInstance(void* /*context*/)
		{
			return (IEditController*) new FirstSynthController;
		}

		//---from IPluginBase--------
		tresult PLUGIN_API initialize (FUnknown* context) SMTG_OVERRIDE;
		tresult PLUGIN_API terminate () SMTG_OVERRIDE;

		//---from EditController-----
		tresult PLUGIN_API setComponentState (IBStream* state) SMTG_OVERRIDE;
		tresult PLUGIN_API notify(IMessage* message) SMTG_OVERRIDE;

		//IPlugView* PLUGIN_API createView(const char* name);
		
		tresult PLUGIN_API setState (IBStream* state) SMTG_OVERRIDE;
		tresult PLUGIN_API getState (IBStream* state) SMTG_OVERRIDE;

		tresult PLUGIN_API setParamNormalized (ParamID tag, ParamValue value) SMTG_OVERRIDE;
		tresult PLUGIN_API getParamStringByValue (ParamID tag, ParamValue valueNormalized,
	                                          String128 string) SMTG_OVERRIDE;
		tresult PLUGIN_API getParamValueByString (ParamID tag, TChar* string,
	                                          ParamValue& valueNormalized) SMTG_OVERRIDE;

		//---from ComponentBase-----
		tresult receiveText(const char* text) SMTG_OVERRIDE;

		//-----------------------------
		DELEGATE_REFCOUNT (EditController)
		tresult PLUGIN_API queryInterface (const char* iid, void** obj) SMTG_OVERRIDE;
		//-----------------------------
	};
}

FirstSynthController.cpp:

#include "FirstSynthController.h"

namespace NSFirstSynth {


	//-------------------------------------------------------------------
	// FirstSynthController implementation
	//-------------------------------------------------------------------
	FirstSynthController::FirstSynthController()
	{
		dummy = 47;
	}

	tresult PLUGIN_API FirstSynthController::initialize(FUnknown* context)
	{
		tresult result = EditController::initialize(context);
		if (result != kResultOk)
			return result;

		patch.setParams(parameters);
		
		return result;
	}

	tresult PLUGIN_API FirstSynthController::terminate()
	{
		return EditController::terminate();
	}

	tresult PLUGIN_API FirstSynthController::setComponentState(IBStream* state)
	{
		return patch.readParams(parameters, state);
	}

	tresult PLUGIN_API FirstSynthController::notify(IMessage* message)
	{
		return EditController::notify (message);
	}

	tresult PLUGIN_API FirstSynthController::queryInterface (const char* iid, void** obj)
	{
		//QUERY_INTERFACE (iid, obj, IMidiMapping::iid, IMidiMapping)
		return EditController::queryInterface (iid, obj);
	}

	tresult FirstSynthController::receiveText (const char* text)
	{
		// received from Component
		if (text)
		{
			fprintf (stderr, "[FirstSynthController] received: ");
			fprintf (stderr, "%s", text);
			fprintf (stderr, "\n");
		}
		return kResultOk;
	}



	tresult PLUGIN_API FirstSynthController::setState(IBStream* state)
	{
		//return EditController::setState(state);
		return kResultOk;
	}

	tresult PLUGIN_API FirstSynthController::getState(IBStream* state)
	{
		//return EditController::getState(state);
		return kResultOk;
	}

	tresult PLUGIN_API FirstSynthController::setParamNormalized(ParamID tag, ParamValue value)
	{
		return EditController::setParamNormalized(tag, value);
	}

	tresult PLUGIN_API FirstSynthController::getParamStringByValue(ParamID tag, ParamValue valueNormalized, String128 string)
	{
		return EditController::getParamStringByValue(tag, valueNormalized, string);
	}

	tresult PLUGIN_API FirstSynthController::getParamValueByString(ParamID tag, TChar* string, ParamValue& valueNormalized)
	{
		return EditController::getParamValueByString (tag, string, valueNormalized);
	}

	//IPlugView* PLUGIN_API FirstSynthController::createView(const char* name)
	//{
	//	if(name && strcmp(name, "editor") == 0)
	//		return new VSTGUI::VST3Editor(this, "view", "ui.uidesc");
	//	return nullptr;
	//}

}

The constructor never seems to be invoked… I don’t understand where I go wrong. Any helpful pointers?

Go to a bookshop and say “Can I please buy Will Pirkle’s Synth book
?”