Closed Spacechild1 closed 2 years ago
that sounds like a cool project.
Anyway That happens if process is never called or if process is called with an invalid bus configuration. Specifically if you can process and don’t have at least one stereo output main bus the Audio will be disabled. If you build a debug version of scxt you can see in src surge-xt surge synth processor where we set audio active to true and you will either not call process or punch out in one of the conditions.
Let me know if you need help.
Specifically a breakpoint here and ahead of it
That toggle to true sets the processing available flag which controls both the sound coming out and the ui display
Thanks for your reply!
I've just found the actual issue: When I call IAudioProcessor::setBusArrangements
with an empty input bus (SpeakerArr::kEmpty
), the plugin happily accepts this arrangement (verified by calling IAudioProcessor::getBusArrangements
), but afterwards it displays the "Audio Output Unavailable" message and refuses to play. This is even more confusing because it really is about the input bus.
Note that when I pass a stereo input bus instead of an empty bus, it works as expected.
I never had this problem with any other VSTi... Maybe it's a JUCE problem. The other JUCE based VST3 plugins I have, like Dexed or Helm, don't have an input bus, so I can't really compare...
Here's the relevant code: https://git.iem.at/pd/vstplugin/-/blob/master/vst/VST3Plugin.cpp#L1341
(Tell me if I should move this to a new proper bug report.)
Surge has a very weird topology that it is an instrument (no main input) with a side chain (aux main input). I’ll take a peek at your code and my code but the confusion is there somewhere I’m sure. I might be mis-rejecting a main input
Hmm looking at my code I should reject that topology. I am assuming it isn’t super easy to run this yeah? Oh and we can keep using this issue I’ll just change the title.
Can you do fx as well as instruments? I’m curious if the surge fx bank works since it also has a sidechain
Thanks for the quick reply!
Hmm looking at my code I should reject that topology
Since the input bus is an aux bus, it would make sense to accept an empty bus. The plugin should still work without the side chain input.
I am assuming it isn’t super easy to run this yeah?
What do you mean by that?
I’m curious if the surge fx bank works since it also has a sidechain
Surge generally doesn't produce any output when passing an empty input bus.
When trying to pass an empty input bus + a stereo output bus (+ 2 empty output busses) to Surge XT I get the following result (this is the verbose output of my plugin host):
requested bus arrangement:
input bus 0: 0ch
output bus 0: 2ch
output bus 1: 0ch
output bus 2: 0ch
actual bus arrangement:
input bus 0: 0ch
output bus 0: 2ch
output bus 1: 2ch
output bus 2: 2ch
You can see that it accepts the empty (aux) input bus, but rejects the empty (main) output busses. This actually looks fine. The only surprising part is that Surge stays silent and says "Audio Output Unavailable" :-)
For comparison, here's the output of Surge XT Effects:
requested bus arrangement:
input bus 0: 0ch
input bus 1: 0ch
output bus 0: 2ch
actual bus arrangement:
input bus 0: 2ch
input bus 1: 0ch
output bus 0: 2ch
The empty main input bus is rejected, the empty aux input is accepted. This looks fine as well.
I just tried to pass a stereo main input bus + an empty aux input bus to Surge XT Effects and it shows a similar problem: the plugin doesn't process the input, but rather passes it through unchanged. Only when I provide a non-empty aux input bus, the effects actually work.
Generally, I think it's fine that both plugins accept empty aux inputs (that's expected behavior), but they should also produce sound :-)
What I meant with the “super easy to run” is “how do I run my plugin in your host”. I’m on mac with at best a casual understanding of sc but have built lots of software
i agree the plugins should work in these configurations. To figure out why they don’t one of us needs to be in the process loop of our plugin with your host stopped on a debugger breakpoint. If it’s me I need to know how to run your stuff. If it’s you we happily take prs. :)
What I meant with the “super easy to run” is “how do I run my plugin in your host”. I’m on mac with at best a casual understanding of sc but have built lots of software
I see! Here's how you do it:
VSTPlugin
release: https://git.iem.at/pd/vstplugin/-/releasesC:/Users/<you>/AppData/Local/SuperCollider/Extensions
macOS: ~/Library/Application Support/SuperCollider/Extensions
Linux: ~/.local/share/SuperCollider/Extensions
VSTPlugin 0.5.4
in the console.scsynth.exe
process in your debugger.Shift+Enter
; code blocks in parantheses are executed with Cmd+Enter
.
// 1. create VSTi synthdef (no input, stereo output)
(
SynthDef.new(\vsti, { arg out = 0;
Out.ar(out, VSTPlugin.ar(nil, 2));
}).add;
)
// 2. create Synth ~vsti = VSTPluginController(Synth(\vsti));
// 3. open Surge debug version
~vsti.open("
// 4. open the editor ~vsti.editor;
Let me know if you have problems!
Awesome. I will look this week.
Oh and excellent directions. I followed them, xattrd the scx, and am good. Now I just to set up my CLion to do debug x86 builds on this m1 and I should in theory be able to stop in the debugger!
So when i run it, i never even get into surge processBlock (like - i put a print in there and it never gets called). That explains why the message is on.
something well north of that is not happening.
Let me see if I can reject the active but empty input structure.
I found the problem!
When the user requests 0 channels for an aux bus, I don't verify the channel count but instead just deactivate the bus. I quickly changed the code to always verify the channel count and now I see that Surge really wants stereo input for the aux input bus.
Because I deactivated the aux input bus, I pass an empty buffer in the processing function, as advertized by the VST3 docs. Surge, however, expects the bus to be stereo, that's probably why it bails.
So I think the problem really is that Surge ignores the fact that I have deactivated the bus. Can you verify this?
Apart from that, what I could do is to only deactivate an aux bus if the plugin accepts the 0 channel count.
OK I stepped through it in the code and found out where JUCE is kicking you out
juce wraps the process in this
if (totalInputChans == pluginInstance->getTotalNumInputChannels()
&& totalOutputChans == pluginInstance->getTotalNumOutputChannels())
and you fail that test because your totalInputChans == 0
I think this might be because you are conflating bus configuration with input shape. But this always confuses me too. It looks like surge (via juce) is expecting a mono or stereo or disabled input bus - we can cope with any of those and so we advertise that. But the plugin requires two channel topology even if you don't use them. Basically "Bus layout" and "pointers" are different.
You can see this if you look inside the juce VST3 host in fact. It has code which looks like this:
for (int i = getTotalNumInputChannels(); i < buffer.getNumChannels(); ++i)
buffer.clear (i, 0, numSamples);
that is, it clears the input buffers it hasn't mapped.
So your 'empty' statement is a correct indication that logically we can handle you not populating the inputs. But that layout is different than the bus which is 2-in-6-out-no-matter-what-you -use
If you don't want 6 out you can only listen to 1 or 2 out. But you have to pass us the 6. Similarly if you don't want 2 in you can disable or pass us 1 or 2 in but we need the 2 pointers.
Or put another way: what we tell you with getBusCount is kinda what you have to do. How you wire that is up to you. But the slots have to be there. That seems to be how it is working in the JUCE code and the VST3 api.
I haven't dug much deeper but the 0-vs-2 is clearly why we are stopping and also clearly not what the JUCE VST3 host (or reaper, logic, cubase, bespoke, live etc...) do. It is invariably more subtle than this too.
I found the problem!
When the user requests 0 channels for an aux bus, I don't verify the channel count but instead just deactivate the bus. I quickly changed the code to always verify the channel count and now I see that Surge really wants stereo input for the aux input bus.
Because I deactivated the aux input bus, I pass an empty buffer in the processing function, as advertized by the VST3 docs. Surge, however, expects the bus to be stereo, that's probably why it bails.
So I think the problem really is that Surge ignores the fact that I have deactivated the bus. Can you verify this?
Apart from that, what I could do is to only deactivate an aux bus if the plugin accepts the 0 channel count.
ha we drew the same conclusion
Surge is absolutely fine with a deactivated bus, a mono bus, or a stereo bus, but transports that on a stereo buffer.
So I need 2 channels of which you can use 0, 1, or 2.
Ok, looks like I've slightly misread the VST3 docs:
The size of the channel buffer array must always match the number of channels. So the host must always supply an array for the channel buffers, regardless if the bus is active or not. However, if an audio bus is currently inactive, the actual sample buffer addresses are safe to be null.
So yeah, I really have to always check the channel count. I can't just deactivate the bus for 0 channels because the plugin might not actually accept that arrangement.
On the other hand, I think Surge really should accept 0 channels for all aux busses.
it does. it handles those nulls with no problem.
I also notice you only call setBusArrangements once and you all it with an input. Perhaps after you re-confiugre you need to call that again? I am almost 100% sure that if you do call setBusArrangements with 0 inputs, surge will work, but I never see that call. So as a result, I expect the inputs. And then I don't get them.
What happens is that I request 0 input channels, but Surge rejects that arrangement and tells me it needs 2 channels. This is the output of my modified host:
requested bus arrangement:
input bus 0: 0ch
output bus 0: 2ch
output bus 1: 0ch
output bus 2: 0ch
actual bus arrangement:
input bus 0: 2ch
output bus 0: 2ch
output bus 1: 2ch
output bus 2: 2ch
What I should do is deactivate the aux input bus and provide 2 channels nevertheless (the actual channel buffers can be null). But I'm wondering why Surge rejects the 0 channels for the aux input bus?
oh right well that's a separate issue. I would have to dig more into juce code and my bus answers to figure that out.
But it seems like surge is giving valid answers and you can fix your bridge right? That is, it is telling you "no" and if you listen to the "no" then everything works? The fact that maybe it should say "yes" is separate?
But it seems like surge is giving valid answers and you can fix your bridge right? That is, it is telling you "no" and if you listen to the "no" then everything works?
Exactly!
The fact that maybe it should say "yes" is separate?
I agree.
Thanks a lot for your help!
if that's correct then perhaps the thing to do is make it so you still ask, and then make it so i can run the code that asks, and then we can step through that once you have it working with the respect of the no answer and appropriate physical topology based on that?
(and this stuff is really hard; i helped figure it out for bespoke and am still working on it for CLAP. Total pain in the neck).
Cool well lets keep this issue open but I will knock it ouf of our milestone. If you have a release I can run in SC where you try and ask for 0 I can trap that in debugger and see why we don't say yes (or if we could).
Glad we got it working!
If you have a release I can run in SC where you try and ask for 0 I can trap that in debugger and see why we don't say yes (or if we could).
Actually, the example code above should do exactly that!
It asks yes, and I respond that any disabled bus is ok. I out prints in there even. And so you call set bus arrangements with 1 1 then probe the busses and I say disabled to stereo is ok and then you don’t call setbusarragements again!
if you build surge yourself you can see the calls
But anyway why not merge your fix and let’s make it work then I can build that and probe - sound good?
But anyway why not merge your fix and let’s make it work then I can build that and probe - sound good?
Ok!
Here's a branch with the fix: https://git.iem.at/pd/vstplugin/-/tree/vst3-bus-fix
Here are binaries: https://git.iem.at/pd/vstplugin/-/jobs/35892/artifacts/download?file_type=archive
Generally, I'm happy now. The original issue is resolved and it was really a bug in my host implementation.
The only "issue" remaining is that Surge XT doesn't accept an empty aux input bus with setBusArrangements
and insists on stereo input. However, I just tried a few plugins that have side-chain inputs and they show a similar behavior. Don't bother!
I'll just go ahead and close this issue. Thanks a lot for your help!
BTW, Surge is awesome! Controlling it algorithmically from SC or Pd is big fun!
Awesome! And yes I was rather excited for it to work. I’ll try and make some music with it :) and glad you enjoy surge!
Hi, I have developed a VST plugin host for Pure Data and SuperCollider (https://git.iem.at/pd/vstplugin/).
I can successfully play the Surge VSTi in Pure Data, but in SuperCollider the "Output" meter says "Audio Output Unavailable" and the output stays silent. What does this message mean and under which circumstances does it appear?
There is probably a subtle bug in my SuperCollider implementation and maybe you can point me in the right direction.
Thanks a lot in advance!