Closed x42 closed 1 year ago
Thanks
I get your patch but then I also need to change my scene out Logic above to not write to a null bus in the case we have b only or an only momentarily so will need to look at that too!
Appreciate the report
The other problem with your proposed patch is it would allow c1==0 and c2==1 through
I think we really want (c1 = 0 || 2) && (c2 == 0||2)
Yes, please ignore my suggested patch. You are in a much better position to solve this properly.
I have never used JUCE and am also not very familiar with surge's codebase, but since I can easily reproduce this issue, I can provide additional information if needed.
Cool.
The real problem is that juce doesn’t recover from a transiently invalid layout right? Nothing special about surge here. a juce sampler would have the same problem if it supported 1 or 8 outs and the host tried to configure it with 5.
Actually hmm I’m not sure what juce correct behavior is - you do ask for an invalid bus config
does activate bus return tresult ok in the xx call above in your real code?
Yes, kResultTrue
is returned in all cases.
The last call to disable bus2 even returns early.
in modules/juce_audio_processors/processors/juce_AudioProcessor.cpp:1045 AudioProcessor::Bus::enable
the condition if (isEnabled() == shouldEnable)
is already true, since the earlier call to disable bus 1 disabled all busses.
Right so it definitely seems like an error that the xxx activste returns true
reaper and bitwig and logic are able to probe for the valid configs (logic with the au of course) and not offer invalid ones. Any idea how that works? I’ve never written a host.
It’s possible to fix surge of course (although I really do want either 1 or 3 stereo out and not 2) but this problem will also break shortcircuit later this year and that is not fixable in the same way which is why I’d like to figure out the actual core problem
AudioProcessor::applyBusLayouts only returns false if the number of busses mismatch. There does indeed seem no way for it to return false. Which makes some sense. Enabling or disabling a bus should always work.
To not allow mono operation, or to enforce a given channel layout Vst::SpeakerArrangement is used.
Anyway the callgraph is something like this (top to bottom)
AudioProcessor::Bus::enable
AudioProcessor::Bus::setCurrentLayout
AudioProcessor::setChannelLayoutOfBus
-> AudioProcessor::Bus::getBusesLayoutForLayoutChangeOfBus
-> isLayoutSupported()
here the layout is changed to mute all busses via calls to
-> getNextBestLayout()
AudioProcessor::applyBusLayouts
here the *best* layout is applied to *all* busses, not just the one that is being en/disabled.
The problem may be the relation between AudioProcessor::getNextBestLayout
in juce_AudioProcessor.cpp and your implementation of checkBusesLayoutSupported
Does juce surge return a proper speaker arrangement? Or does it return a speaker arrangement which would allow on off on right now.
And thanks for the check / get hint, that’s useful
setBusArrangements
returns kResultFalse
when trying to configure any given Bus as Mono, but otherwise succeeds.
Regardless if the bus is active or not, getBusArrangement
always reports SpeakerArrangement::kStereo for each bus.
Can you check if Reaper or Bitwig ever configures the synth as stereo, or are all busses always active?
Sure will do!
when you draf into reaper it prompts for 2 out or 6 out. When you pull into bitwig the device has an option to add the extra pair of tracks. And when you create in logic it shows you 1x or 3x stereo. But I’ve never actually checked if the other buses are activated anyway when you choose the smaller config! Lol. Will look tomorrow and update here
have some travel over the long weekend which will have me not in dev mode but will try and answer that before I split!
What happens if you change it after the fact in Reaper? Start with 6 out and the change it to Stereo.
It would work when the busses are deactivated in reverse order, but otherwise it would also result in silence.
OK just did a quick check in latest reaper
If you choose to add as stereo, the sceneA and sceneB bus have isEnabled false, and have channel count 0.
If you add as 3x stereo they are true and count 2.
When I add surge it asks me this
but before it does that it calls isBusLayoutSupported what looks like about 15 times. When I add
std::cout << "isBusLayoutSuported " << outputValid << " " << inputValid << " " << sceneOut << " " << c1 << " " << c2 << std::endl;
I see
isBusLayoutSuported 0 0 0 1 1
isBusLayoutSuported 0 1 0 1 1
isBusLayoutSuported 1 1 1 2 2
isBusLayoutSuported 1 1 1 2 2
isBusLayoutSuported 1 1 1 2 2
isBusLayoutSuported 0 1 0 1 1
isBusLayoutSuported 1 1 1 2 2
isBusLayoutSuported 1 1 1 2 2
isBusLayoutSuported 1 1 1 2 2
isBusLayoutSuported 1 1 1 0 0
isBusLayoutSuported 1 1 1 0 0
isBusLayoutSuported 0 1 0 1 1
isBusLayoutSuported 1 1 1 2 2
isBusLayoutSuported 1 1 1 2 2
isBusLayoutSuported 1 1 1 2 2
isBusLayoutSuported 0 1 0 1 1
isBusLayoutSuported 1 1 1 2 2
isBusLayoutSuported 1 1 1 2 2
isBusLayoutSuported 1 1 1 2 2
isBusLayoutSuported 1 1 1 0 0
isBusLayoutSuported 1 1 1 0 0
isBusLayoutSuported 1 1 1 0 0
isBusLayoutSuported 1 1 1 0 0
isBusLayoutSuported 1 1 1 0 0
isBusLayoutSuported 1 1 1 0 0
When I look at the stack for those I see things like
-------- Stack Trace (14 frames of 29 depth showing) --------
[ 1]: 1 Surge XT 0x000000028fe2d234 _ZNK19SurgeSynthProcessor22isBusesLayoutSupportedERKN4juce14AudioProcessor11BusesLayoutE + 40
[ 2]: 2 Surge XT 0x000000029094dac0 _ZNK4juce14AudioProcessor25checkBusesLayoutSupportedERKNS0_11BusesLayoutE + 140
[ 3]: 3 Surge XT 0x000000029094d838 _ZN4juce14AudioProcessor29setBusesLayoutWithoutEnablingERKNS0_11BusesLayoutE + 544
[ 4]: 4 Surge XT 0x000000028fdb4b5c _ZN4juce17JuceVST3Component18setBusArrangementsEPyiS1_i + 400
[ 5]: 5 REAPER 0x000000010521360c _ZN8VST3Data13RecalcBusInfoEi + 780
which looks like it is calling setBusArrangements with all the permutations of the 6 channels and seeing if it gets a true or false before it tries and offers the choice to the user. Note that setBusArrangements is non destructive and also is transactional (that is you don't set them one by one).
So it looks like reaper does a probe across the channels to figure out the correct configurations.
Helpful?
What happens if you change it after the fact in Reaper? Start with 6 out and the change it to Stereo.
It would work when the busses are deactivated in reverse order, but otherwise it would also result in silence.
I don't know how to do that in reaper. Do you?
in bitwig if I add missing chains (to get the 3x output) then delete the scene A output, the synth still makes noise when i press the virtual keyboard, if that helps? I didn't check if that actually deactivates the bus and gotta run now.
OK here's the deal
1: Bitwig always has the channels at 1x3 no matter what I add or delete. I instrumented the call stack a bit more cleanly and here's how it starts up
JUCE v6.1.6
SurgeXT VST3
- Version : 1.1.main.aa66b292 with JUCE 60106
- Build Info : 2023-02-16 21:14:43 using AppleClang-14.0.0.14000029
- Data : "/Library/Application Support/Surge XT"
- User Data : "/Users/paul/Documents/Surge XT"
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=0 index=0 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=1 dir=0 index=0 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=1 index=2 state=TRUE
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=0 out2Chan=0 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=0 out2Chan=2 inputValid=1 outputValid=1 res=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=0 out2Chan=2 inputValid=1 outputValid=1 res=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=1 index=1 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=1 index=0 state=TRUE
Applying plugin IO state
Applying plugin instance state
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:291 (processBlock) aEnabled=1 aChan=2 bEnabled=1 bChan=2
Reaper is more chatty. When I create a plugin here's what it does up to and then after me selecting 2
JUCE v6.1.6
SurgeXT VST3
- Version : 1.1.main.aa66b292 with JUCE 60106
- Build Info : 2023-02-16 21:14:43 using AppleClang-14.0.0.14000029
- Data : "/Library/Application Support/Surge XT"
- User Data : "/Users/paul/Documents/Surge XT"
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=1 out2Chan=1 inputValid=0 outputValid=0 res=0
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=1 out2Chan=1 inputValid=1 outputValid=1 res=0
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=1 out2Chan=1 inputValid=1 outputValid=1 res=0
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=1 dir=0 index=0 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=0 index=0 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=0 index=0 state=FALSE
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=0 out2Chan=0 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=1 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=0 out2Chan=0 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=1 out2Chan=1 inputValid=1 outputValid=1 res=0
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=1 out2Chan=1 inputValid=1 outputValid=1 res=0
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=1 dir=0 index=0 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=0 index=0 state=TRUE
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=1 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=0 out2Chan=0 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=0 out2Chan=0 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=1 index=0 state=TRUE
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:291 (processBlock) aEnabled=0 aChan=0 bEnabled=0 bChan=0
If I then go and add the scene A output it does this
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=1 index=1 state=TRUE
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=0 out2Chan=0 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=0 inputValid=1 outputValid=1 res=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=0 inputValid=1 outputValid=1 res=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:291 (processBlock) aEnabled=1 aChan=2 bEnabled=1 bChan=2
If I remove that mapping it stays at 3x output. I can't see a way to make reaper destroy the channel even if you unmapped the output.
The Juce AudioPlugin Host seems to take the same tack as bitwig. It just activates everything independent of whether you have it bound or not
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=1 dir=0 index=0 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=0 index=0 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=1 index=0 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=1 index=1 state=TRUE
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=0 out2Chan=0 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=0 inputValid=1 outputValid=1 res=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=0 inputValid=1 outputValid=1 res=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=1 index=2 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2984 (setBusArrangements) numIns=1 numOuts=3
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:207 (isBusesLayoutSupported) inputDisabled=0 outputDisabled=0
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:227 (isBusesLayoutSupported) out1Chan=2 out2Chan=2 inputValid=1 outputValid=1 res=1
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=0 index=0 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=1 index=0 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=1 index=1 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=0 dir=1 index=2 state=TRUE
/Users/paul/dev/music/surge/libs/JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:2907 (activateBus) type=1 dir=0 index=0 state=TRUE
/Users/paul/dev/music/surge/src/surge-xt/SurgeSynthProcessor.cpp:291 (processBlock) aEnabled=1 aChan=2 bEnabled=1 bChan=2
It might be the case, by the way, that you could get around the problem by calling "setBusArrangements" with 1 in and 1 out before you deactivate the higher buses?
Thanks for the rigorous investigation!
It just activates everything independent of whether you have it bound or not
Wow. What a mess. So Reaper is the only host that even tries to deactivate a bus at one point, only to undo it later.
By default Surge's optional output busses are disabled (BusInfo::kDefaultActive is only set for the first).
I will have to verify this myself, one of our testers reported that deactivating optional outputs apparently reduces DSP load for Kontakt and Addictive Drums. I hazard a guess that this might be true for Surge as well.
I have only checked various audio plugins which reconfigure themselves depending on Input and Sidechain busses (Fabfilter, waves) and that works correctly by first en/disabling a bus and then calling setBusArrangements
.
I will try your suggestion and call it first and see if that helps.
Calling setBusArrangements
before activateBus
makes no difference.
In your Reaper trace above, after "If I then go and add the scene A output it does this"
only the first two busses are active, and the "B" scene bus is disabled. Does Surge produce sound on both the main bus and scene A?
Wow. What a mess.
Welcome to VST3...
Actually hmm I’m not sure what juce correct behavior is - you do ask for an invalid bus config
The problem is that this breaks later valid configs.
Reaper expands but never contracts is the thing @x42
I dint have a host which goes for full back to default in my test set. So no one does what you do.
@mkruselj you must know does kontact have fixed 1,4,8) or any 1-8 output settings?
@x42 as mentioned I’m not going to be able to look again until in depth afret the us long weekend.
Ardour is a big enough host for us thst we can patch surge and do something (more painfully) different in sc if we need to although I may host condition it. I would just like to make sure we have to before we do that.
No rush, there won't be another Ardour release for at least 6 weeks.
Like other hosts, Ardour could never disable a previously enabled bus. Likely this will also have to be saved with the session-state, and things get ugly quickly. I'll see if I can get my hands on Reaper and compare and also ask around if other plugins are affected.
I'm also prepared to argue that it is a bug in JUCE. When choosing an invalid config it would make a lot more sense to retain the last known working bus configuration rather than disable all busses internally, and doing that without any feedback to the host.
It is not currently possible to detect for the host that enabling only Surge's bus 0 and 1 is invalid.
Yes
we were chatting in our discord and studio 1 has a ui which lets you do your “xxx” line and it also silences surge sigh
I agree this is a bug like behavior which lives somewhere in the ether between the vst3 “spec”, the juce choice, the surge strictness, and the ambiguity they present. But the fact that surge is doing something valid which breaks it doesn’t mean there’s no break
Do you have pianoteq? It is also a juce plugin with lots of output configs. Wonder what happens there
but my guess is we need to change surge to work around this indeed and I need to make sure it doesn’t make the plugin create ui in logic a mess and so on. Let me tag this into our 12 milestone
OK I pushed a version to baconpaul/busses-6847
which is valid for 2/0/2 and 2/2/0 as well as 2/0/0 and 2/2/2
i tested in reaper and logic and no problem at track creation time
no rush @mkruselj since I'm away anyway but if you get a chance to build that and test it in S1 that would be great, and same @x42 for ardour?
Wow you're fast, and on a long weekend no less.
I can confirm that baconpaul/busses-6847
fixes the issue here with Ardour.
Great so let’s check in s1 and then I can merge this and design sc with a similar thing in place
Appreciate the back and forth
Works as expected in S1 as well!
Awesome I need to clean up the debug prints but can do that and merge next week
@baconpaul If you want me to, I can go ahead and push your fix minus the debug prints.
Yes that would be great thank you!
Bug Description:
Surge VST3 becomes silent when first using it in 6 channel mode, and then changing it back to stereo:
At
XXX
abovehttps://github.com/surge-synthesizer/surge/blob/aa66b292bdb21c229820ff93fd936fda0cf976ae/src/surge-xt/SurgeSynthProcessor.cpp#L212
c1 == 0
(first output bus was just disabled) butc2 ==2
(second bus is still active):isBusesLayoutSupported
returns false;JUCE's
AudioProcessor::getNextBestLayout
ends up with an empty layout, andAudioProcessor::applyBusLayouts
disables all outputs incl. the default stereo output.newNumberOfOuts == 0
.Even if the final configuration step succeeds, the first bus remains disabled, and then
SurgeSynthProcessor::processBlock
just returns without producing sound.This does not happen with JUCE's default implementation of
AudioPluginAudioProcessor::isBusesLayoutSupported
in which the connection order is not significant.Proposed solution, allow any stereo bus configuration:
It seems overly restrictive, to only allow both scenes or none of them. That being said, JUCE's logic in
Bus::isLayoutSupported
->AudioProcessor::getNextBestLayout
is also questionable.Surge XT Version release_xt_1.1.2-101-gaa66b292
Reproduction Steps: Load the Plugin in Ardour 7.3.0
With a debug version of Ardour you can use
Ardour7 -DVST3Config
to print calls toactivateBus
as they' are made. Then play with plugin pin connections. Initially Ardour enables all outputs and then the plugin is reconfigured as stereo: