LNX studio poll results

lnx studio from github works on linux if you use the xplat branch. this comes with the caveat that it provides everything, but you have to manually set a couple of things up, which means mostly to edit some paths. together with pipewire this is fantastic. I also added this line to the executable to scale the ui:
QT_SCALE_FACTOR=1 QT_AUTO_SCREEN_SCALE_FACTOR=0 QT_SCREEN_SCALE_FACTORS=2 QT_QPA_PLATFORM=xcb

if you have VSTPlugin installed, save this as LNX_VSTi.sc in lnx studios own
‘SCClassLibrary/LNX_Studio Library/2. Instruments’ to get started.
Also edit sclang_conf_lnx.yaml to include the VSTPlugin extension.
It works on my machine :slight_smile:

LNX_VSTi : LNX_InstrumentTemplate {
	var <vsti, <proxy;

	*new { arg server=Server.default,studio,instNo,bounds,open=true,id,loadList;
		^super.new(server,studio,instNo,bounds,open,id,loadList)
	}

	*studioName {^"VSTi"}
	*thisWidth  {^200} // the default width of this instrument
	*thisHeight {^100} // the default height of this instrument
	*sortOrder{^10}
	*isVisible{^true}

	isInstrument{^true}
	canBeSequenced{^true}
	isMixerInstrument{^true}

	mixerColor{^Color(1,1,1,0.4)} // colour in mixer

	canTurnOnOff{^true}
	hasMIDIClock{^false}
	clockPriority{^5} // order for clock beats. sequenced controllers 1st. instruments last.
	// the lower the number the higher the priority

	// this line is important for mixer instruments!
	hasLevelsOut{^true}

	interface{^nil} // supply an immutable list of methods to make available to the network

	header { // define your document header details
		instrumentHeaderType="SC Template Doc";
		version="v1.1";
	}

	initModel {
		#models,defaults=[
			// 0.solo
			[0, \switch, (\strings_:"S"), midiControl, 0, "Solo",
				{|me,val,latency,send,toggle| this.solo(val,latency,send,toggle) },
				\action2_ -> {|me| this.soloAlt(me.value) }],

			// 1.onOff
			[1, \switch, (\strings_:((this.instNo+1).asString)), midiControl, 1, "On/Off",
				{|me,val,latency,send,toggle| this.onOff(val,latency,send,toggle) },
				\action2_ -> {|me| this.onOffAlt(me.value) }],

			// 2.amp
			[ \db6, midiControl, 2, "Amp",
				(mouseDownAction_:{hack[\fadeTask].stop}),
				{|me,val,latency,send|
					this.setPVP(2,val,latency,send);
					this.setMixerSynth(\amp,val.dbamp,latency); // set mixer synth
			}],

			// 3. master pan
			[\bipolar, midiControl, 3, "Pan", (\label_:"Pan", zeroValue_:0),
				{|me,val,latency,send|
					this.setPVPModel(3,val,0,send);      // set p & network model via VP
					this.setMixerSynth(\pan,val,latency); // set mixer synth
			}],

			// 4. peak level
			[0.7, \unipolar,  midiControl, 4, "Peak Level",
				{|me,val,latency,send| this.setPVP(4,val,latency,send) }],

			// 5. out channels
			[0,\audioOut, midiControl, 5, "Output channels",
				(\items_:LNX_AudioDevices.outputAndFXMenuList),
				{|me,val,latency,send|
					var channel = LNX_AudioDevices.getOutChannelIndex(val);
					this.setPVPModel(5,val,0,send);     // set p & network model via VP
					this.setMixerSynth(\outChannel,channel,latency); // set mixer synth
				}],

			// 6. main send channel
			[-1, \audioOut,  midiControl, 6, "Main Send Channel",
				(\items_:LNX_AudioDevices.outputAndFXMenuList),
				{|me,val,latency,send|
					var channel = LNX_AudioDevices.getOutChannelIndex(val);
					this.setPVPModel(6,val,0,send);             // set p & network model via VP
					this.setMixerSynth(\sendChannel,channel,latency); // set mixer synth
			}],

			// 7. main send amp
			[-inf, \db2,  midiControl, 7, "Main Send Amp", (label_:"Send"),
				{|me,val,latency,send|
					this.setPVPModel(7,val,0,send);             // set p & network model via VP
					this.setMixerSynth(\sendAmp,val.dbamp,latency); // set mixer synth
			}],

			// 8. syncDelay
			[\sync, {|me,val,latency,send|
				this.setPVPModel(8,val,latency,send);
				this.syncDelay_(val);
			}]
		].generateAllModels;

		presetExclusion=[0,1];
		randomExclusion=[0,1];
		autoExclusion=[];
	}

	// return your output model, for fadeIn, fadeOut, and Mixer
	peakModel    {^models[4]}
	volumeModel  {^models[2]}
	outChModel   {^models[5]}
	soloModel    {^models[0]}
	onOffModel   {^models[1]}
	panModel     {^models[3]}
	sendChModel  {^models[6]}
	sendAmpModel {^models[7]}
	syncModel {^models[8]}

	//// GUI ///////////////////////////////////////////

	createWindow{|bounds|
		this.createTemplateWindow(bounds,Color(0.1,0.1,0.1,1));
	}

	createWidgets{
		gui[\topLevel]=MVC_RoundedCompositeView(window, window.bounds);

		MVC_FlatButton2(window, Rect(10, 10, 85, 30))
		.strings_(["gui"])
		.action_({ vsti.gui });
		MVC_FlatButton2(window, Rect(105, 10, 85, 30))
		.strings_(["editor"])
		.action_({ vsti.editor });

		// MIDI Settings
		MVC_FlatButton(window,Rect(10, 50, 85, 30),"MIDI")
		.rounded_(true)
		.canFocus_(false)
		.shadow_(true)
		.color_(\up,Color(10665/19997,223/375,2/3) )
		.color_(\down,Color(10665/19997,223/375,2/3) )
		.color_(\string,Color.white)
		.resize_(9)
		.action_{ this.createMIDIInOutModelWindow(window, //,low:11,high:12,
			colors:(border1:Color(0,1/103,9/77,65/77) , border2:Color(59/108,65/103,505/692))
		) };

		// MIDI Control
		MVC_FlatButton(window,Rect(105, 50, 85, 30),"Cntrl")
		.rounded_(true)
		.canFocus_(false)
		.shadow_(true)
		.color_(\up,Color(10665/19997,223/375,2/3) )
		.color_(\down,Color(10665/19997,223/375,2/3))
		.color_(\string,Color.white)
		.resize_(9)
		.action_{  LNX_MIDIControl.editControls(this); LNX_MIDIControl.window.front  };
	} // put your GUI code in here

	//// uGens & midi players //////////////////////////

	// this will be called by the studio after booting
	*initUGens{|server|

		SynthDef(\vsti, { arg out = 0;
			// VST instruments usually don't have inputs
			Out.ar(out, VSTPlugin.ar(nil, 2))
		}).add.send(server);
	}

	// startDSP  : this is called once to start ugens at instrument creation
	// stopDSP   : and once to stop ugen when the instrument is deleted
	//             used to start & stop fx's or mono synths
	// updateDSP : and also update synth parameters in a load
	startDSP  {
		synth = Synth.new(\vsti, [\out, this.instGroupChannel], instGroupID);
		vsti = VSTPluginController(synth);
		proxy = vsti.midi;
		vsti.browse;
	}
	stopDSP   { synth.free; vsti = proxy = nil; }

	updateDSP{|oldP,latency|
		synth.set(\out, this.instGroupChannel);
		this.setMixerSynth(\sendChannel,LNX_AudioDevices.getOutChannelIndex(p[6]),latency); // set mixer synth
		this.setMixerSynth(\outChannel, LNX_AudioDevices.getOutChannelIndex(p[5]),latency); // set mixer synth
	}
	replaceDSP{} // to be used by synth's or fx's that need to replace the current
	// synth with a new one in order to update values

	// midi In methods, latency is supplied
	noteOn	{|note, vel, latency| proxy.noteOn(0, note, vel)}		// noteOn
	noteOff	{|note, vel, latency| proxy.noteOff(0, note, vel)}		// noteOff
	control	{|num,  val, latency| proxy.control(0, num, val)}		// control
	bend 	{|bend     , latency| proxy.bend(0, bend)}		// bend
	touch	{|pressure , latency|}		// pressure
	program	{|program  , latency|}      // and program (the selectProgram method is called 1st
	sysex	{|data     , latency|}
	midiInternal{|command,arg1,arg2| }   // internal comms via midi (not used yet)

	// a quick way to get working, to be used by all midi in future
	pipeIn{|pipe|
		switch (pipe.kind)
		{\noteOn} { // noteOn
			this.noteOn(pipe.note, pipe.velocity, pipe.latency)
		}
		{\noteOff} { // noteOff
			this.noteOff(pipe.note, pipe.velocity, pipe.latency)
		}
		{\control} { // control
			this.control(pipe.num, pipe.val, pipe.latency)
		}
		{\bend} { // bend
			this.bend(pipe.val, pipe.latency)
		}
		{\touch} { // touch
			this.touch(pipe.pressure, pipe.latency)
		}
		{\program} {
			// to do and confirm
		}
	}
} // end ////////////////////////////////////
1 Like