General Purpose Microphone Mixer
-
Here I have a microphone mixer module with volume, delay, width, pan, mute, solo, and purge controls. Every control is part of a sliderPack so that it can easily expand to accommodate any number of mic positions. The GUI is intended only for behind the scenes and your front panel GUI should connect to it - if you want to use the sliderPack GUI in production though you can of course do so.
You should route your samplers so that each microphone channel goes to a separate "Simple Gain" effect in the master container and you should ensure that each of these Simple Gain effects contain "mic" within their ID/name as this will be picked up by the script so it knows which simple gain effects to use - in case you have others that aren't for mic mixing purposes.
Let me know if you find any bugs, keeping track of the mute/solo state and channel volume is always a bit fiddly with these sorts of things so a bug might have got in there that I missed.
After careful consideration I am open to the possibility of dual licensing my GPL snippets for use in proprietary projects, pm/email me to discuss this further if you're interested.
/** * Title Microphone Mixer v1.0.0 * Author: David Healey * Date: 01/07/2017 * Modified: 02/07/2017 * License: GPLv3 - https://www.gnu.org/licenses/gpl-3.0.en.html */ //INIT Content.setHeight(250); //Retrieve simple gain FX with "mic" in their ID and store in gainFX array const var simpleGainIds = Synth.getIdList("Simple Gain"); //Get IDs of simple gain FX - 1 per mic const var gainFx = []; for (g in simpleGainIds) { if (!Engine.matchesRegex(g, "mic")) continue; //Skip if it doesn't contain "mic" in its ID gainFx.push(Synth.getEffect(g)); } //Retrieve samplers and store in samplers array const var samplerIds = Synth.getIdList("Sampler"); //Get IDs of samplers const var samplers = []; for (s in samplerIds) { samplers.push(Synth.getSampler(s)); } //GUI const var vol = sliderPackFactory(4, 0, "vol", {sliderAmount:simpleGainIds.length, min:-100, max:36, stepSize:0.01}); const var delay = sliderPackFactory(209, 0, "delay", {sliderAmount:simpleGainIds.length, min:0, max:500, stepSize:0.01}); const var width = sliderPackFactory(414, 0, "width", {sliderAmount:simpleGainIds.length, min:0, max:200, stepSize:0.01}); const var pan = sliderPackFactory(619, 0, "pan", {sliderAmount:simpleGainIds.length, min:-100, max:100, stepSize:0.01}); const var mute = sliderPackFactory(4, 125, "mute", {sliderAmount:simpleGainIds.length, stepSize:1}); const var solo = sliderPackFactory(209, 125, "solo", {sliderAmount:simpleGainIds.length, stepSize:1}); const var purge = sliderPackFactory(414, 125, "purge", {sliderAmount:simpleGainIds.length, stepSize:1}); const var labels = []; labels.push(Content.addLabel("Volume", 0, 100)); labels.push(Content.addLabel("Delay", 205, 100)); labels.push(Content.addLabel("Width", 410, 100)); labels.push(Content.addLabel("Pan", 615, 100)); labels.push(Content.addLabel("Mute", 0, 225)); labels.push(Content.addLabel("Solo", 205, 225)); labels.push(Content.addLabel("Purge", 410, 225)); //FUNCTIONS inline function sliderPackFactory(x, y, name, obj) { var control = Content.addSliderPack(name, x, y); //Set control properties for (k in obj) //Each key in object { control.set(k, obj[k]); } control.set("flashActive", false); return control; }; inline function muteSolo() { reg soloOn = false; //Flag to indicate if at least one channel is soloed //Determine if any channels are soloed in order to set soloOn flag for (i = 0; i < gainFx.length; i++) //Each solo slider { if (solo.getSliderValueAt(i) == 1) { soloOn = true; //Flag that at least one channel is soloed mute.setSliderAtIndex(i, 0); //Toggle mute state } } for (i = 0; i < gainFx.length; i++) { //If a channel is soloed set volume of all non-soloed channels to 0, if no channel is soloed restore volume of non-muted channels if (mute.getSliderValueAt(i) == 1) continue; //Ignore muted channels if (solo.getSliderValueAt(i) == 1) //Channel is soloed { gainFx[i].setAttribute(0, vol.getSliderValueAt(i)); mute.setSliderAtIndex(i, 0); //Toggle mute state } else //Channel is not soloed { if (soloOn == true) //If at least one channel is soloed { gainFx[i].setAttribute(0, -100); //Mute the channel } else //No channels soloed { gainFx[i].setAttribute(0, vol.getSliderValueAt(i)); //Restore channel's volume } } } } function onNoteOn() { } function onNoteOff() { } function onController() { } function onTimer() { } function onControl(number, value) { switch(number) { case vol: if (mute.getSliderValueAt(value) == 0) //Channel isn't muted { gainFx[value].setAttribute(0, vol.getSliderValueAt(value)); } break; case delay: gainFx[value].setAttribute(1, delay.getSliderValueAt(value)); break; case width: gainFx[value].setAttribute(2, width.getSliderValueAt(value)); break; case pan: gainFx[value].setAttribute(3, pan.getSliderValueAt(value)); break; case mute: if (mute.getSliderValueAt(value) == 1) //Mute is active for channel { gainFx[value].setAttribute(0, -100); //Silence channel solo.setSliderAtIndex(value, 0); //Toggle solo state } muteSolo(); break; case solo: muteSolo(); break; case purge: for (s in samplers) //Each sampler { s.purgeMicPosition(s.getMicPositionName(value), purge.getSliderValueAt(value)); } break; } }