ok.. success! (partially)

i have a simple setup now with three plugins, and i can successfully bypass the middle one and route around it. this is also working with the version 6a9eb9aa0eab4ed4b5bd7c2e203c3cd3f11272c4, so sorry i was indeed using the ports wrongly, my bad. so maybe 279b1bd9d489291c99fff6ac528a7d264e9f3496 can be undone again.

actually it is much more simple if only audio-ports are counted, you don't have to dig in the ports-list of each plugin to find the right ports.

the routing of "adc" and "dac" does not work on the 6a9eb9aa0eab4ed4b5bd7c2e203c3cd3f11272c4, if i set slot to -1 or endslot + 1 for inslot or outslot the program builds but immediately segfaults with error 139

sure: (i used calfs exclusively, so you should be able to run it as well)

#include <Bela.h>
#include <vector>
#include "Lv2Host.h"
#include <libraries/OnePole/OnePole.h>
#include <libraries/Scope/Scope.h>

Lv2Host gLv2Host;

//Scope scope;



int gAudioFramesPerAnalogFrame;
int gLedPin = 0;


float gUpdateInterval = 0.05;



void Bela_userSettings(BelaInitSettings *settings)
{
	settings->uniformSampleRate = 1;
	settings->interleave = 0;
	settings->analogOutputsPersist = 0;
}

bool setup(BelaContext* context, void* userData)
{
	
	// these should be initialized by Bela_userSettings above
	if((context->flags & BELA_FLAG_INTERLEAVED) || context->audioSampleRate != context->analogSampleRate)
	{
		fprintf(stderr, "Using Lv2Host requires non-interleaved buffers and uniform sample rate\n");
		return false;
	}
	if(!gLv2Host.setup(context->audioSampleRate, context->audioFrames,
				context->audioInChannels, context->audioOutChannels))
	{
		fprintf(stderr, "Unable to create Lv2 host\n");
		return false;
	}
		
	std::vector<std::string> lv2Chain;
	lv2Chain.emplace_back("http://calf.sourceforge.net/plugins/MonoCompressor");
	lv2Chain.emplace_back("http://calf.sourceforge.net/plugins/VintageDelay");
	lv2Chain.emplace_back("http://calf.sourceforge.net/plugins/Reverb");
	for(auto &name : lv2Chain)
	{
		gLv2Host.add(name);
	}
	if(0 == gLv2Host.count())
	{
		fprintf(stderr, "No plugins were successfully instantiated\n");
		return false;	
	}

	if(context->analogFrames)
		gAudioFramesPerAnalogFrame = context->audioFrames / context->analogFrames;


	gLv2Host.setPort(1, 4, 40); //delay time
	gLv2Host.setPort(1,9,0.9); //delay feedback
//comment the next 5 lines to have the normal chain working	
	
//disconnect from reverb
	gLv2Host.disconnect(2,0);
    gLv2Host.disconnect(2,1);
    gLv2Host.bypass(1,1);
    // connect compressor to reverb (or try to set to -1 or 3 to bypass whole chain)
    gLv2Host.connect(0,0,2,0);
    gLv2Host.connect(0,1,2,1);
	


	return true;
}

void render(BelaContext* context, void* userData)
{




	// set inputs and outputs
	const float* inputs[context->audioInChannels];
	float* outputs[context->audioOutChannels];
	for(unsigned int ch = 0; ch < context->audioInChannels; ++ch)
		inputs[ch] = (float*)&context->audioIn[context->audioFrames * ch];
	for(unsigned int ch = 0; ch < context->audioOutChannels; ++ch)
		outputs[ch] = &context->audioOut[context->audioFrames * ch];

	// do the actual processing on the buffers specified above
	gLv2Host.render(context->audioFrames, inputs, outputs);



	// Log input, output, compressor's threshold and compressor's gain reduction into scope
}

void cleanup(BelaContext* context, void* userData) {

}

I think I addressed most of the issues. Now it won't crash, and you can actually set individual channels as pass through by connecting source -1 to destination slots.size(), which was not actually possible earlier. Can you test?

getting this on the latest git:


/root/Bela/projects/lv2hostpass/Lv2Host.cpp:200:5: error: use of undeclared identifier 'memcpy'; did you mean 'wmemcpy'?
    memcpy(outputs[n], inputs[port],
    ^~~~~~
    wmemcpy
/usr/include/wchar.h:332:17: note: 'wmemcpy' declared here
extern wchar_t *wmemcpy (wchar_t *__restrict __s1,
                ^
/root/Bela/projects/lv2hostpass/Lv2Host.cpp:200:12: error: cannot initialize a parameter of type 'wchar_t *' with an lvalue of type 'float *'
    memcpy(outputs[n], inputs[port],
           ^~~~~~~~~~
/usr/include/wchar.h:332:46: note: passing argument to parameter '__s1' here
extern wchar_t *wmemcpy (wchar_t *__restrict __s1,
                                             ^
2 errors generated.
make: *** [/root/Bela/projects/lv2hostpass/build/Lv2Host.o] Error 1
In file Lv2Host.cpp: use of undeclared identifier 'memcpy'; did you mean 'wmemcpy'? column: 5, line: 200
In file Lv2Host.cpp: cannot initialize a parameter of type 'wchar_t *' with an lvalue of type 'float *' column: 12, line: 200

that tells you how well I tested it ... not even built it . Fixed now.

ok, builds and runs now. but... no sound output at all if i either set input to -1 or try to connect a plugin to output (nr. of last slot + 1) and if i try to do both at once (setting input to -1 and output to last slot + 1 it still segfaults with error 139

ok tomorrow I should be able to connect a sound source so I can test on my side, too. Can you send the actual lines that make it fail?

this fails:

//disconnect from reverb
	gLv2Host.disconnect(2,0);
    gLv2Host.disconnect(2,1);
    gLv2Host.bypass(1,1);
    // connect compressor to reverb (or try to set to -1 or 3 to bypass whole chain) following two lines make it fail
    gLv2Host.connect(-1,0,3,0);
    gLv2Host.connect(-1,0,3,1);

this does not output any sound

//disconnect from reverb
	gLv2Host.disconnect(2,0);
    gLv2Host.disconnect(2,1);
    gLv2Host.bypass(1,1);
    // connect compressor to reverb (or try to set to -1 or 3 to bypass whole chain) 
    gLv2Host.connect(-1,0,2,0);
    gLv2Host.connect(-1,0,2,1);

ok done quite some testing, I think most things should work now.

yes! it works... great work! i tested on the patch i sent you and also on a more complex patch where i have more routing going on. next test will be to bypass and change out plugins while running (not in setup)

It should be fairly cheap to do the bypassing and rerouting in render(). The only possible negative consequence is that you'll find more of my bugs 🙂.

    giuliomoro what is the default behaviour of mono plugins regarding stereo input in LV2Host? does it connect both outputs (from another plugin or adc) to the mono input? my tests seem to indicate that.

    no, inputs are never summed at the moment, but a given input can be duplicated to several outputs.

    If I understand correctly the code at these lines does, the current behaviour is as follows, I think:

    • if you have more inputs than outputs, the last few inputs will be filled with copies of the last output.
      e.g.:
      MONOout -> LRin
      
      the LRin plug in will have duplicated copies of the MONOout signal into its L and R inputs.
      - If you have more outputs than inputs, the last input will be filled with the last output .
      e.g.:
      LRout -> MONOin
      
      the MONOin plugin will have its input connected to the R output of the LRout plugin
      The latter behaviour doesn't seem particularly clever to me. It should take the L value instead.

      Can you verify practically if the above is true?

      giuliomoro no, inputs are never summed at the moment, but a given input can be duplicated to several outputs.

      ah my bad, you wrote that before...

      my findings with a mono plugin as the only plugin in a chain are:

      • only the left channel of the stereo input is going through the plugin
        -i only get output from bela only on the left channel

      i am fairly certain my test procedure is right, i am sending two hard panned and totally different audio signals from my DAW.

      this seems fairly logical to me like that. have to run, will test further later on

        lokki this seems fairly logical to me like that. have to run, will test further later on

        to me too, and it is my recollection of how I programmed it. However, reading my code suggested me otherwise. One of the two versions of me (the one who wrote it and the one who read it) must be smarter than the other, or maybe just luckier 🙂

        ok, some more testing done...it all works when switching out plugins in the chain from render.cpp which is great!

        to bypass a plugin at slot 1 and enable slot 2 (and vice versa) and connect to the rest of the chain i have to do something like this:

        if (!vocoder) {
        	gLv2Host.disconnect(3,0);
        	gLv2Host.bypass(1,0);
        	
        	gLv2Host.bypass(2,1);
        	gLv2Host.connect(1,0,3,0);
        	} else {
        	gLv2Host.disconnect(3,0);	
        	gLv2Host.bypass(1,1);
        	
        	gLv2Host.bypass(2,0);
        	gLv2Host.connect(-1,1,2,1);
        	gLv2Host.connect(0,0,2,0);
        	gLv2Host.connect(2,0,3,0);
        	}

        note that in the vocoder case i also have to send the direct adc signal to the second input, to get carrier and modulator :-)

        ideally, since you said an input can only have one port connected the disconnects should not be needed if i run another connect, right? so whenever the connect function is run it should run the respective disconnect function first.
        in the state it is now if i don't do the disconnects like so:

        if (!vocoder) {
        	gLv2Host.bypass(1,0);
        	
        	gLv2Host.bypass(2,1);
        	gLv2Host.connect(1,0,3,0);
        	} else {
        	gLv2Host.bypass(1,1);
        	
        	gLv2Host.bypass(2,0);
        	gLv2Host.connect(-1,1,2,1);
        	gLv2Host.connect(0,0,2,0);
        	gLv2Host.connect(2,0,3,0);
        	}

        the vocoder does not work (i just get a frozen sound, like a repeated buffer or similar) once i switch back to non vocoder (autotune plugin) it works again.

        full code, or at least the name and order of the plugins? disconnect() assigns an empty buffer to the disconnected inputs, but that should be overridden by the next call to connect(). This may not be true for the input (-1) and output (numSlots).

        here is the code:

        #include <Bela.h>
        #include <vector>
        #include "Lv2Host.h"
        #include <libraries/Midi/Midi.h>
        #include <libraries/Gui/Gui.h>
        
        Lv2Host gLv2Host;
        
        int gAudioFramesPerAnalogFrame;
        int gLedPin = 0;
        
        
        float gUpdateInterval = 0.05;
        
        
        void Bela_userSettings(BelaInitSettings *settings)
        {
        	settings->uniformSampleRate = 1;
        	settings->interleave = 0;
        	settings->analogOutputsPersist = 0;
        }
        //scales to choose
        bool chromatic[12] {1,1,1,1,1,1,1,1,1,1,1,1,};
        bool major[12] {1,0,1,0,1,1,0,1,0,1,0,1,};
        bool minor[12] {1,0,1,1,0,1,0,1,1,0,0,1,};
        bool penta[12] {1,0,1,0,1,0,0,1,0,1,0,0,};
        bool whole[12] {1,0,1,0,1,0,1,0,1,0,1,0,};
        bool dim[12]   {1,0,0,1,0,0,1,0,0,1,0,0,};
        bool octave = 0;
        bool powercut = 0;
        bool echo = 0;
        //pointer to choosen scale
        bool *scale = chromatic;
        bool gIsNoteOn = 0;
        int tap_count = 0;
        int frame_count = 0;
        int gVelocity = 0;
        int gNote = 0;
        int gControl = 0;
        int gCCVal = 0;
        bool vocoder = 1;
        void midiMessageCallback(MidiChannelMessage message, void* arg){
        /*	if(arg != NULL){
        		rt_printf("Message from midi port %s ", (const char*) arg);
        	} */
        //	message.prettyPrint();
        	if(message.getType() == kmmNoteOn){
        	gNote =	message.getDataByte(0);
        	gVelocity = message.getDataByte(1);
        		gIsNoteOn = gVelocity > 0;
        	}
        		if(message.getType() == kmmControlChange){
        			gControl = message.getDataByte(0);
        			gCCVal = message.getDataByte(1);
        			
        		}
        }
        
        Midi midi;
        
        const char* gMidiPort0 = "hw:1,0,0";
        
        
        bool setup(BelaContext* context, void* userData)
        {
        	midi.readFrom(gMidiPort0);
        	midi.writeTo(gMidiPort0);
        	midi.enableParser(true);
        	midi.setParserCallback(midiMessageCallback, (void*) gMidiPort0);
        	// these should be initialized by Bela_userSettings above
        	if((context->flags & BELA_FLAG_INTERLEAVED) || context->audioSampleRate != context->analogSampleRate)
        	{
        		fprintf(stderr, "Using Lv2Host requires non-interleaved buffers and uniform sample rate\n");
        		return false;
        	}
        	if(!gLv2Host.setup(context->audioSampleRate, context->audioFrames,
        				context->audioInChannels, context->audioOutChannels))
        	{
        		fprintf(stderr, "Unable to create Lv2 host\n");
        		return false;
        	}
        		
        	std::vector<std::string> lv2Chain;
        	lv2Chain.emplace_back("http://moddevices.com/plugins/caps/Noisegate");
        //	lv2Chain.emplace_back("http://moddevices.com/plugins/caps/Compress");
        	lv2Chain.emplace_back("http://gareus.org/oss/lv2/fat1");
        	lv2Chain.emplace_back("http://drobilla.net/plugins/mda/TalkBox");
        	lv2Chain.emplace_back("http://guitarix.sourceforge.net/plugins/gx_oc_2_#_oc_2_");
        	lv2Chain.emplace_back("http://drobilla.net/plugins/mda/SubSynth");
        	lv2Chain.emplace_back("http://drobilla.net/plugins/mda/Detune");
        	lv2Chain.emplace_back("http://drobilla.net/plugins/mda/Stereo");
        	lv2Chain.emplace_back("http://calf.sourceforge.net/plugins/VintageDelay");
        	lv2Chain.emplace_back("http://guitarix.sourceforge.net/plugins/gx_reverb_stereo#_reverb_stereo");
        	for(auto &name : lv2Chain)
        	{
        		gLv2Host.add(name);
        	}
        	if(0 == gLv2Host.count())
        	{
        		fprintf(stderr, "No plugins were successfully instantiated\n");
        		return false;	
        	}
        
        	if(context->analogFrames)
        		gAudioFramesPerAnalogFrame = context->audioFrames / context->analogFrames;
        //noisegate
        gLv2Host.setPort(0, 0, -20);
        	gLv2Host.setPort(0, 2, -30);
        	//autotune
        	
        	gLv2Host.setPort(1, 6, 0.5);
        	gLv2Host.setPort(1, 7, 0.02);
        //	gLv2Host.setPort(2, 9, 24);
        	gLv2Host.setPort(1, 11, 1); //fastmode
        	gLv2Host.setPort(1, 12, 1); //c
        	gLv2Host.setPort(1, 13, 0);
        	gLv2Host.setPort(1, 14, 0);
        	gLv2Host.setPort(1, 15, 1);
        	gLv2Host.setPort(1, 16, 0);
        	gLv2Host.setPort(1, 17, 1);
        	gLv2Host.setPort(1, 18, 0);
        	gLv2Host.setPort(1, 19, 1);
        	gLv2Host.setPort(1, 20, 0);
        	gLv2Host.setPort(1, 21, 0);
        	gLv2Host.setPort(1, 22, 1);
        	gLv2Host.setPort(1, 23, 0);
        //vocoder (talkbox)
        gLv2Host.setPort(2, 0, 1); //wet signal
        gLv2Host.setPort(2, 2, 0); //choose carrier channel
        gLv2Host.setPort(2, 3, 1); //quality
        
        	// octaver off by default
                    	gLv2Host.setPort(3, 3, 0);
        				gLv2Host.setPort(3, 4, 0);
        				gLv2Host.setPort(3, 2, 0.3);
        				
        					//mda subsynth
        				//	gLv2Host.setPort(4,1, 0);
        	gLv2Host.setPort(4, 3, 1);
        	gLv2Host.setPort(4, 4, 0);
        	
        	//mda detune
        	gLv2Host.setPort(5, 0,0.1 );
        	gLv2Host.setPort(5, 1,0.5 );
        gLv2Host.setPort(5, 3,0.3 );
        	gLv2Host.setPort(5, 2, 0.3);
        //mda stereo
        	gLv2Host.setPort(6, 0, 0.5);
        	gLv2Host.setPort(6, 1, 0.3);
        	
        
        				
        	//echo
        	
        	
        	gLv2Host.setPort(7, 11, 0);
        	gLv2Host.setPort(7, 10, 0);
        	gLv2Host.setPort(7, 4, 100);
        //	gLv2Host.setPort(7, 15, 1);
        	//_reverb
        	
        	gLv2Host.setPort(8, 0, 40);
        	gLv2Host.setPort(8, 3, 0.1);
        	//connect carrier to vocoder directly (without mono fx, gate and compressor)
        //	gLv2Host.connect(-1,1,2,1);
        
        //	scope.setup(4, context->audioSampleRate);
        	
        	// Turn LED on
        	pinMode(context, 0, gLedPin, OUTPUT); // Set pin as output
        	digitalWrite(context, 0, gLedPin, 1); //Turn LED on
        	return true;
        }
        
        void render(BelaContext* context, void* userData)
        {
        	if (!vocoder) {
        	gLv2Host.disconnect(3,0);
        	gLv2Host.bypass(1,0);
        	
        	gLv2Host.bypass(2,1);
        	gLv2Host.connect(1,0,3,0);
        	} else {
        	gLv2Host.disconnect(3,0);	
        	gLv2Host.bypass(1,1);
        	
        	gLv2Host.bypass(2,0);
        	gLv2Host.connect(-1,1,2,1);
        	gLv2Host.connect(0,0,2,0);
        	gLv2Host.connect(2,0,3,0);
        	}
        frame_count++;
        if (frame_count > (1000*tap_count)) {
        	tap_count = 0;
        }
        //	static bool pluginsOn[3] = {true, true, true};
        	
        	// set inputs and outputs
        	const float* inputs[context->audioInChannels];
        	float* outputs[context->audioOutChannels];
        	for(unsigned int ch = 0; ch < context->audioInChannels; ++ch)
        		inputs[ch] = (float*)&context->audioIn[context->audioFrames * ch];
        	for(unsigned int ch = 0; ch < context->audioOutChannels; ++ch)
        		outputs[ch] = &context->audioOut[context->audioFrames * ch];
        			// do the actual processing on the buffers specified above
        	gLv2Host.render(context->audioFrames, inputs, outputs);
        
        	
        			switch (gControl) {
        				case 7: {
        						gLv2Host.setPort(2, 3, float(gCCVal/127));
        					break;
        				}	
        				case 8: {
        						gLv2Host.setPort(4, 0, float(gCCVal>>5)/4.0);
        					break;
        				}	
        				case 9: {
        						gLv2Host.setPort(7, 6, (gCCVal/8) + 1);
        					//	gLv2Host.setPort(7, 1, float(gCCVal/ 127.0));
        					break;
        				}	
        				case 10: {
        					gLv2Host.setPort(8, 2, float(gCCVal/ 127.0));
        					break;
        				}
        			}
        		if(gIsNoteOn == 1){
        			//logic to switch between non "tonal" and "semitonal" scales 
        			if ((scale == whole) | (scale == dim)) scale = chromatic;
        		switch (gNote) {
        			case 20: {
        			if (!echo) {
        				gLv2Host.setPort(7, 10, 0.3);
        			
        				echo = 1;
        			} else {
        			gLv2Host.setPort(7, 10, 0);
        			
        				
        				echo = 0;
        			}
        				break;
        			}
        			case 21: {
        			/*	if (tap_count == 4) {
        				float bpm =	float(60.0/float(frame_count * 8 / 11025.0));
        			//	gLv2Host.setPort(7, 4, bpm);
        			gLv2Host.setPort(7, 4, bpm);
        				rt_printf("bpm: %f\n",bpm);
        					tap_count = 0;
        				}
        				
        				if (!tap_count) frame_count = 0;
        				if (tap_count < 4) tap_count++;
        				
        				*/
        				vocoder = !vocoder;
        				
        				break;
        			}
        			case 22: {
        			if (!octave) {
        				gLv2Host.setPort(3, 3, 0.5);
        				gLv2Host.setPort(3, 4, 0.5);
        				octave = 1;
        			} else {
        			gLv2Host.setPort(3, 3, 0);
        				gLv2Host.setPort(3, 4, 0);
        				octave = 0;
        			}
        				break;
        			}
        			case 23: {
        				// subsynth
        				if (!powercut) {
        					gLv2Host.setPort(4, 2, 1);
        					powercut = 1;
        				} else {
        				gLv2Host.setPort(4, 2, 0);
        				powercut = 0;
        				}
        				break;
        			}
        			
        			case 36: {
        					//set scale, in key of c, no offset
        	for(unsigned int n = 0; n < 12; n++){
        	
        	gLv2Host.setPort(2, n + 12, scale[n]);
          // 	rt_printf("value%d: %d\n", n, scale[n]);
        	}
        	
        			break;
        			}
        		case 37: {
        			//set scale, in key of c# offset of 1 halftone
        			if (scale == chromatic) scale = whole;
        	for(unsigned int n = 0; n < 12; n++){			
        	gLv2Host.setPort(1, ((n+1)%12 + 12), scale[(n)]);
        //	rt_printf("value%d: %d\n", (n+1)%12, scale[n]);
        	}
        			break;
        			}
        	case 38: {
        	//set scale, in key of d offset of 2 halftones	
        		if (scale == chromatic) scale = whole;
        	for(unsigned int n = 0; n < 12; n++){			
        	gLv2Host.setPort(1, ((n+2)%12 + 12), scale[(n)]);
        	}
        			break;
        			}
            case 39: {
        				scale = chromatic;
        				break;
        			}
        	case 40: {
        	//set scale, in key of d# offset of 3 halftones	
        	if (scale == chromatic) scale = dim;
        	for(unsigned int n = 0; n < 12; n++){			
        	gLv2Host.setPort(1, ((n+3)%12 + 12), scale[(n)]);
        	}
        	break;
        	}
        	case 41: {
        	//set scale, in key of e offset of 4 halftones	
        	if (scale == chromatic) scale = dim;
        	for(unsigned int n = 0; n < 12; n++){			
        	gLv2Host.setPort(1, ((n+4)%12 + 12), scale[(n)]);
        	}
        	break;
        	}
        	case 42: {
        	//set scale, in key of f offset of 5 halftones	
        	if (scale == chromatic) scale = dim;
        	for(unsigned int n = 0; n < 12; n++){		
        	gLv2Host.setPort(1, ((n+5)%12 + 12), scale[(n)]);
        	}
        	break;
        	}
        	case 43: {
        		scale = major;
        		break;
        			}
        	case 44: {
        	//set scale, in key of f# offset of 6 halftones	
        	for(unsigned int n = 0; n < 12; n++){			
        	gLv2Host.setPort(1, ((n+6)%12 + 12), scale[(n)]);
        	}
        	break;
        	}	
        	case 45: {
        	//set scale, in key of g offset of 7 halftones	
        	for(unsigned int n = 0; n < 12; n++){			
        	gLv2Host.setPort(1, ((n+7)%12 + 12), scale[(n)]);
        	}
        	break;
        	}	
        	case 46: {
        	//set scale, in key of g# offset of 8 halftones	
        	for(unsigned int n = 0; n < 12; n++){			
        	gLv2Host.setPort(1, ((n+8)%12 + 12), scale[(n)]);
        	}
        	break;
        	}	
        			case 47: {
        				scale = minor;
        				break;
        	
        			}
        				case 48: {
        	//set scale, in key of a offset of 9 halftones	
        	for(unsigned int n = 0; n < 12; n++){			
        	gLv2Host.setPort(1, ((n+9)%12 + 12), scale[(n)]);
        	}
        	break;
        	}	
        	case 49: {
        	//set scale, in key of a# offset of 10 halftones	
        	for(unsigned int n = 0; n < 12; n++){			
        	gLv2Host.setPort(1, ((n+10)%12 + 12), scale[(n)]);
        	}
        	break;
        	}	
        	case 50: {
        	//set scale, in key of b offset of 11 halftones	
        	for(unsigned int n = 0; n < 12; n++){			
        	gLv2Host.setPort(1, ((n+11)%12 + 12), scale[(n)]);
        	}
        	break;
        	}
        			case 51: {
        				scale = penta;
        				break;
        			}
        			
        		}
        		gIsNoteOn = 0;
        		}
        
        
        }
        
        void cleanup(BelaContext* context, void* userData) {
        
        }

        this code works as intended. to reproduce the "error"/bug you have to remove the two disconnects at start of render() i.e.

        if (!vocoder) {
        	// gLv2Host.disconnect(3,0);
        	gLv2Host.bypass(1,0);
        	
        	gLv2Host.bypass(2,1);
        	gLv2Host.connect(1,0,3,0);
        	} else {
        	// gLv2Host.disconnect(3,0);	
        	gLv2Host.bypass(1,1);
        	
        	gLv2Host.bypass(2,0);
        	gLv2Host.connect(-1,1,2,1);
        	gLv2Host.connect(0,0,2,0);
        	gLv2Host.connect(2,0,3,0);
        	}

        to reproduce you will have to switch the plugins live (currently by sending a note on 21), simply setting bool vocoder does not show the bug. so to make it clear again, leaving the disconnects out produces a frozen sound when i switch to the vocoder part, having the disconnects in there solves it.