Is there a way to assign a parameter to the active zone as opposed to globally (type:zone) or singly (Zone XX)?

To provide some background my project has dozens of samples all layered on the same key and triggered individually by velocity which is then assigned to a knob. All velocity inputs are converted to a single number as demonstrated here, triggering sound 22:

function RandomizerDefine()
low_vel = Velocity
high_vel = Velocity
this.parent:getMidiModule("MIDI Randomizer"):setParameter("OutputLowVel", low_vel)
this.parent:getMidiModule("MIDI Randomizer"):setParameter("OutputHighVel", high_vel)
end
defineParameter("Velocity", 0, 127, 1, 50, RandomizerDefine)
The user then selects the required sound via the Timbre knob. So far, so good.

I would however like the waveform to display the currently playing sound. At the moment it’s either connected per zone (using Zone 01) or globally (type.Zone), however none are appropriate. The first option obviously only shows one fixed zone and the second option stacks them all so it’s misleading and a mess.

Is there a way to change the type:Zone command to something like type:ZoneActive so that the display changes when the Timbre knob selects a different sample?
Failing that, how could I create a script to only pick up the active zone? I will then link the waveform parameters to that.
Are you using the midi randomizer to play notes at fixed velocity? There is a more simple way to do this.
defineParameter("Velocity", nil, 100, 0, 127, 1)
function onNote(e)
playNote(e.note, Velocity)
end
For the sample display check any of the Skylab instruments. You probably want something similar but based on velocity instead of midi note. Or maybe even tied to your Velocity parameter.
Check the zoneScope parameter and updateSampleDisplay function right at the beginning of the script. This zoneScope parameter is connected to ui script.The updateSampleDisplay function is called from onNote function (end of the script) and also when loading new layer preset.
1 Like
Yes I was using the MIDI randomizer for that. I have now deleted that MIDI module and script and instead replaced with your recommendation. Much cleaner now, thanks.
30GB of downloads later and I’m able to look at the Skylab script 
I’ve isolated the sections relevant to the waveform display and I believe it’s just the following (as you mentioned):
-- set the zone for sample display
defineParameter("zoneScope", nil, "")
function updateSampleDisplay(note)
local zones = this.parent:getLayer():findZones()
for i, zone in pairs(zones) do
if note >= zone.keyLow and note <= zone.keyHigh then
zoneScope = "@layer:0/@0:"..zone.name.."/"
break
end
end
end
function onNote(ev)
updateSampleDisplay(ev.note)
postEvent(ev)
end
which I have modified to (ref bold for changes):
-- set the zone for sample display
defineParameter("zoneScope", nil, "")
function updateSampleDisplay(note)
local zones = **this.parent:findZones()**
for i, zone in pairs(zones) do
if note >= **zone.LowVel and note <= zone.HighVel then**
zoneScope = "@layer:0/@0:"..zone.name.."/"
break
end
end
end
function onNote(ev)
updateSampleDisplay(ev.note)
postEvent(ev)
end
However, I encounter the following error which is I assume relates to the “zone.LowVel” and “zone.HighVel” components. I’m not sure how these are specifically defined to had to guess.

The first step is to correct these and then check what additional errors exist.
Update:
I followed the same logic and changed to zone.velLow/High and there is no longer an error. However, no luck with the waveform display so I must be missing something else.
-- set the zone for sample display
defineParameter("zoneScope", nil, "")
function updateSampleDisplay(note)
local zones = this.parent:findZones()
for i, zone in pairs(zones) do
if note >= zone.velLow and note <= zone.velHigh then
zoneScope = "@layer:0/@0:"..zone.name.."/"
break
end
end
end
function onNote(ev)
updateSampleDisplay(ev.note)
postEvent(ev)
end
Yes, you fixed the error. That’s good. You may also check the scope.
zoneScope = "@layer:0/@0:"..zone.name.."/"
Connect temporarily one of the zones and check the scope. Are your zones inside the layer? The zone.name in the code will be replaced by the zone name. So the output will be something like:
@layer:0/@0:Zone 1/
Check if the scope looks correct in your instrument and adjust if needed. Try with and without the forward slash at the end.
You also need the zoneScope parameter in ui script. You can’t connect it directly from the program tree script.
1 Like
Actually because you want this to act on velocity you also need to adjust the onNote function and pass the velocity as argument.
function onNote(ev)
updateSampleDisplay(ev.velocity)
postEvent(ev)
end
1 Like
Yes that was an error also. I needed to remove layer so I now have:
zoneScope = "@0:"..zone.name..""
which corresponds to:

Done.
How it looks currently:
-- set the zone for sample display
defineParameter("zoneScope", nil, "")
function updateSampleDisplay(note)
local zones = this.parent:findZones()
for i, zone in pairs(zones) do
if note >= zone.velLow and note <= zone.velHigh then
zoneScope = "@0:"..zone.name..""
break
end
end
end
function onNote(ev)
updateSampleDisplay(ev.velocity)
postEvent(ev)
end
This I don’t follow though. How do I connect it?
I take it you mean not by this zoneScope in the script:

You need to create ui script and a zoneScope parameter (same like the one you already have in your program tree script). Then connect those 2 script parameters. Connect the sample display scope to this ui script parameter.
Check the Skylab macro page to see how it’s all connected together.
1 Like
Here is a simple example:
Sample Display.vstpreset (12.8 KB)
You can add ui script here:
1 Like
Amazing, working perfectly here now.
I managed to add the script to the UI yesterday and connect the two scripts however I hadn’t created the Waveform @zoneScope group.

Now that I’ve done this is working exactly as intended.
Thanks!