Unable to access ProcessData.processContext (validator fails at "setlocal...")

I am new to plugin development (and C++), but I have some various experience with programming and audio. So this is my first VST plugin: cyclical amplitude modulation. It started as a square wave tremolo, I added some parameters (rate, smoothness, intensity), and that went well enough (yay, results!).

Now I’m trying to extend a tempo sync feature, so I implemented getProcessContextRequirements, added some “kNeeds[…]” flags, and started trying to use the processContext member of ProcessData, but it seems I can’t even reference that member without triggering this failure.

The validator fails at “Check Audio Bus Arrangement”, with the cryptic “setlocal…” error. I pared it down to just a null check for processContext (in my process function):

  if (!data.processContext) {
  	throw std::invalid_argument("missing processContext");
  }

At this point, I had hit a sort of wall; that seems like the simplest reasonable troubleshooting I can perform within my code.

I’ve solved other problems, that caused similar validator failures, by modifying/recompiling the validator to add debug output. So I added some output and it looks like it fails, just after this line (asynchronously BTW; subsequent debug output gets cut off while printing):

public.sdk\source\vst\testsuite\bus\checkaudiobusarrangement.cpp:60:

int32 numInputs = vstPlug->getBusCount (kAudio, kInput);

Does anyone know why the validator would balk at a mere reference to processContext in my process method? The plugin seems to work fine without that null check…

For reference, here’s the output from validator:


1>[Check Audio Bus Arrangement]
1>Info: ===Check Audio Bus Arrangement ====================================
1>Info: got num inp
1>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(157,5): error MSB3073: The command "setlocal

UPDATE:
I tried bypassing that test:

addMessage(testResult, printf(“skipping bus arrangement test”));
return true;

This still fails, so I’m pretty sure it’s not anything specifically about the call to getBusCount. Based on the asynchronous-seeming nature of the failure, I guess I’ll try to back up and understand the flow of control in the validator. An opportunity to learn more about C++? Sure… but I am “dead in the water”, as far as the tempo sync feature.

Here’s the output of the stubbed version of the bus arrangement test (notice the message cuts off):

1>[Check Audio Bus Arrangement]
1>Info: ===Check Audio Bus Arrangement ====================================
1>Info: skipping bu

UPDATE 2:
Reading through the source code of the validator and commenting stuff out until it works, I found the issue is somewhere in the "{Single,Double} Precision ({32,64} bit) Tests" TestSuites. If those aren’t added to the TestSuite, the plugin seems to build and function properly.

UPDATE 3:
I’ve narrowed it down to these lines in the Silence Flags test. The build seems to work fine with those lines commented out, but the nature of the failure precludes any sort of output from the test that’s actually failing.

I confirmed, it’s trying to send each combination of silence flags, for two channels, to one input. I don’t see any reason why that should fail, certainly not in this apparently catastrophic manner. My plugin handles silence flags exactly as the “AGain” example… I guess my princess is in another castle.

I’m sure the ultimate cause is something I did wrong (e.g. not implementing something that’s required, or implementing it incorrectly), but still, the mode of failure and opacity of error reporting is making it really hard to figure out what I need to change.

UPDATE 4:
OK, I’m officially ridiculous. This “cryptic/catastrophic failure” is caused by my process function explicitly throwing an exception when processContext is missing. If so, then error handling in the Silence Flags test could be improved, and none of the other tests (nor hosts) fails to provide processContext… I’ll keep looking to confirm, because it seems a little suspect that this one test would be unique in that way.

UPDATE 5 (resolved, I guess):
If I invert the null check (i.e. throw exception when processContext is not null), then all the tests pass and the build succeeds. Of course the plugin fails in an actual host that provides processContext. So, I guess I’ll just have to account for the possibility it won’t be provided, because apparently it’s not, at least in the Silence Flags validator test…

E.g. workaround, for sampleRate:

  double sampleRate = data.processContext
  	? data.processContext->sampleRate
  	: 44100;

CONCLUSION (TL/DR):

  • One cannot assume ProcessData will always provide processContext. In my experience, it is null when called from the “Silence Flags” test.
  • Throwing exceptions in the process function is not a particularly useful way to get error output. In my experience, they will be swallowed up somewhere along the line and I’m not sure how/whether they are recorded/reported.

Hi and welcome.
As you found out yourself, the processContext member of the ProcessData structure is optional and you have to test for it before you can use it.