I think I know what the problem is …
The rest of the script’s functions conflict with my macro page, if I remove my macro page and leave only the sampler selector template, everything seems fine.
I need to leave the script only with the functions necessary for the “selectedPatch” and “selectedPreset” parameters to work and remove everything else.
could someone tell me how it should be the script?
I’m trying but it always throws errors
I paste the complete script
-- copy relevant zone parameters
defineSlotLocal("copiedParameters")
copiedParameters =
{
{"Filter.Type", nil}, -- second value will be set to the parameter of the previous zones
{"Filter.VelocityToCutoff", nil},
{"DCFAttOffset", nil},
{"DCFSusOffset", nil},
{"DCAAttOffset", nil},
{"DCASusOffset", nil},
{"Amp Env.VelocityToLevel", nil},
{"UserAttOffset", nil},
{"Pitch.Coarse", nil},
{"Pitch.Fine", nil},
{"Pitch.Random", nil},
{"VoiceControl.UseStartRange", nil},
{"Amp.Pan", nil},
{"Filter.Cutoff", nil},
{"Filter.Resonance", nil},
{"Filter.Distortion", nil},
{"Filter.EnvAmount", nil},
{"Filter.Keytrack", nil},
{"Filter.Bypass", nil},
{"Filter.ShapeA", nil},
{"DCFRelOffset", nil},
{"DCFDecOffset", nil},
{"DCARelOffset", nil},
{"DCADecOffset", nil},
{"Amp.Level", nil},
{"User Env.VelocityToLevel", nil},
{"UserDecOffset", nil},
{"UserSusOffset", nil},
{"UserRelOffset", nil},
{"VoiceControl.GlideOn", nil},
{"VoiceControl.Fingered", nil},
{"VoiceControl.Glide", nil},
{"Pitch.PitchBendUp", nil},
{"Pitch.PitchBendDn", nil},
{"UserL0Offset", nil},
{"UserL1Offset", nil},
{"UserLROffset", nil},
}
defineSlotLocal("copiedModulationMatrixParameters")
copiedModulationMatrixParameters = {}
for i = 1, 19, 1 do
copiedModulationMatrixParameters[i] =
{
{"Source1.Polarity", nil},
{"Source2.Polarity", nil},
{"Source1.Smoothing", nil},
{"Source2.Smoothing", nil},
{"Destination.Depth", nil},
{"Destination.Bypass", nil}
}
end
-- keep track of last applied parameter values
last = {}
-- load handling
-- selectedPath and selectedPreset should not appear in the undo history,
-- so we make them non-persistent, but save and restore them explicitly with
-- onSave and onLoad
defineParameter{name = "selectedPath", default = "", onChanged = function() onSelectPath() end, persistent = false, automatable = false}
defineParameter{name = "selectedPreset", default = "", persistent = false, automatable = false}
function onSave()
return { selectedPath = selectedPath, selectedPreset = selectedPreset }
end
function onLoad(data)
if type(data) == "table" then
-- beware of old tables still filled with other entries
if data.selectedPath then
selectedPath = data.selectedPath
end
if data.selectedPreset then
selectedPreset = data.selectedPreset
end
end
end
function onUndo()
-- print("onUndo: updatePreset = ", undoInfo.updatePreset)
if undoInfo.updatePreset then
local layer = this.parent:getLayer()
if layer then
selectedPreset = layer.name
end
end
end
-- pseudo parameter to add a callback into the undo group for replacing the sample layer
defineParameter{name = "undoInfo", default = {}, onChanged = onUndo, automatable = false}
-- all parameters but the modulation sources can be restored
-- before insertion into the parent layer
function restoreZoneParameters(layer)
local zones = layer:findZones()
for i, zone in pairs(zones) do
for j, parameter in pairs(copiedParameters) do
zone:setParameter(parameter[1], parameter[2])
end
for j = 1, 16, 1 do
local modDestination = modDestinations[_G["ModDestination"..j]]
zone:getModulationMatrixRow(j):setParameter("Destination.Destination", modDestination.index)
end
for j = 1, 3, 1 do
local modDestination = modDestinations[_G["CtrlLane"..j.."Dest"]]
zone:getModulationMatrixRow(j + 16):setParameter("Destination.Destination", modDestination.index)
end
for j, parametersOfRow in pairs(copiedModulationMatrixParameters) do
local row = zone:getModulationMatrixRow(j)
for k, parameter in pairs(parametersOfRow) do
row:setParameter(parameter[1], parameter[2])
end
end
end
end
-- modulation sources must be restored after insertion into the parent layer
-- because QC and MidiModule references do not exist before
function restoreMatrixSources(layer)
local zones = layer:findZones()
for i, zone in pairs(zones) do
for j = 1, 16, 1 do
local row = zone:getModulationMatrixRow(j)
local polarity1 = row:getParameter("Source1.Polarity")
local polarity2 = row:getParameter("Source2.Polarity")
local modSource = modSources[_G["ModSource"..j]]
modSource.assignFunc(row, 1, modSource.bipolar, modSource.smoothing, modSource.index)
local modModifier = modSources[_G["ModModifier"..j]]
modModifier.assignFunc(row, 2, modModifier.bipolar, modModifier.smoothing, modModifier.index)
row:setParameter("Source1.Polarity", polarity1)
row:setParameter("Source2.Polarity", polarity2)
end
end
end
function saveZoneParameters(layer)
local sourceZone = layer:getZone()
if not sourceZone then
return false
end
for i, parameter in pairs(copiedParameters) do
parameter[2] = sourceZone:getParameter(parameter[1])
end
for i, parametersOfRow in pairs(copiedModulationMatrixParameters) do
local row = sourceZone:getModulationMatrixRow(i)
for j, parameter in pairs(parametersOfRow) do
parameter[2] = row:getParameter(parameter[1])
end
end
return true
end
function forwardSphere(layer)
local sphereH = layer:getParameterDefinition("QuickControl.QC9").id
local sphereV = layer:getParameterDefinition("QuickControl.QC10").id
this.parent:addQCAssignment(9, layer, sphereH, layer)
this.parent:addQCAssignment(10, layer, sphereV, layer)
end
function loadFinished(currentProgressInfo)
if currentProgressInfo.root then
startUndoBlock("Load Layer " .. currentProgressInfo.root.name)
undoInfo = { updatePreset = true }
this:setParameter("undoInfo", { updatePreset = false }, true)
local saved = false
local layer = this.parent:getLayer()
if layer then
saved = saveZoneParameters(layer)
if saved then
restoreZoneParameters(currentProgressInfo.root)
end
end
this.parent:appendLayer(currentProgressInfo.root)
if layer then
this.parent:removeLayer(layer)
if saved then
restoreMatrixSources(currentProgressInfo.root)
end
end
forwardSphere(currentProgressInfo.root)
undoInfo = { updatePreset = false }
this:setParameter("undoInfo", { updatePreset = true }, true)
endUndoBlock()
end
end
function onSelectPath()
loadPresetAsync(selectedPath, loadFinished)
end
-- set parameter of all zones
function setParameterOfZones(parameterName, value)
local zones = this.parent:getLayer():findZones()
for i, zone in pairs(zones) do
zone:setParameter(parameterName, value)
end
end
-- parameter change callback for pitch random
function onPitchRandomChanged()
last.PitchRandom = PitchRandom
setParameterOfZones("Pitch.Random", PitchRandom)
end
defineParameter("PitchRandom", "Pitch Random", 0, 0, 1, onPitchRandomChanged)
-- define the filter types
defineSlotLocal("filterTypes")
filterTypes = {
{ name = "Tube", index = 2 },
{ name = "Hard Clip", index = 3 },
{ name = "Bit Reduction", index = 4 },
{ name = "Rate Reduction", index = 5 },
{ name = "Rate Reduction Key Follow", index = 6 },
}
-- create table with the names of the filter types
function getFilterTypeNames()
filterTypeNames = {}
for i=1, #filterTypes do
filterTypeNames[i] = filterTypes[i].name
end
end
getFilterTypeNames()
-- parameter change callbacks for the filter parameters
function onFilterTypeChanged()
setParameterOfZones("Filter.Type", filterTypes[FilterType].index)
end
function onFilterVelChanged()
last.FilterVelocity = FilterVelocity
setParameterOfZones("Filter.VelocityToCutoff", FilterVelocity)
end
-- define parameters for the filter section
defineParameter("FilterType", "Filter Type", 1, filterTypeNames, onFilterTypeChanged)
defineParameter("FilterVelocity", "Filter Velocity", 0, 0, 200, onFilterVelChanged)
-- parameter change callbacks for filter envelope offsets
function onFilterEnvAttackChanged()
last.FilterEnvAttack = FilterEnvAttack
setParameterOfZones("DCFAttOffset", FilterEnvAttack)
end
function onFilterEnvSustainChanged()
last.FilterEnvSustain = FilterEnvSustain
setParameterOfZones("DCFSusOffset", FilterEnvSustain)
end
-- define parameters for filter envelope offsets
defineParameter("FilterEnvAttack", "Filter Envelope Attack", 0, 0, 100, 0.1, onFilterEnvAttackChanged)
defineParameter("FilterEnvSustain", "Filter Envelope Sustain", 0, 0, 100, 0.1, onFilterEnvSustainChanged)
-- parameter change callbacks for the amplifier parameters
function onAmpVelChanged()
last.AmpVelocity = AmpVelocity
setParameterOfZones("Amp Env.VelocityToLevel", AmpVelocity)
end
-- define parameters for the amplifier section
defineParameter("AmpVelocity", "Amp Velocity", 100, 0, 100, onAmpVelChanged)
-- parameter change callbacks for amplifier envelope offsets
function onAmpEnvAttackChanged()
last.AmpEnvAttack = AmpEnvAttack
setParameterOfZones("DCAAttOffset", AmpEnvAttack)
end
function onAmpEnvSustainChanged()
last.AmpEnvSustain = AmpEnvSustain
setParameterOfZones("DCASusOffset", AmpEnvSustain)
end
-- define parameters for amplifier envelope offsets
defineParameter("AmpEnvAttack", "Amp Envelope Attack", 0, 0, 100, 0.1, onAmpEnvAttackChanged)
defineParameter("AmpEnvSustain", "Amp Envelope Sustain", 100, 0, 100, 0.1, onAmpEnvSustainChanged)
-- parameter change callbacks for the user envelope parameters
function onUserEnvVelChanged()
last.UserEnvVelocity = UserEnvVelocity
setParameterOfZones("User Env.VelocityToLevel", UserEnvVelocity)
end
function onUserEnvAttackChanged()
last.UserEnvAttack = UserEnvAttack
setParameterOfZones("UserAttOffset", UserEnvAttack)
end
function onUserEnvLevel0Changed()
last.UserEnvLevel0 = UserEnvLevel0
setParameterOfZones("UserL0Offset", UserEnvLevel0 * 0.5)
end
function onUserEnvLevel1Changed()
last.UserEnvLevel1 = UserEnvLevel1
setParameterOfZones("UserL1Offset", UserEnvLevel1 * 0.5)
end
function onUserEnvSustainChanged()
last.UserEnvSustain = UserEnvSustain
setParameterOfZones("UserSusOffset", UserEnvSustain * 0.5)
end
function onUserEnvLevelRChanged()
last.UserEnvLevelR = UserEnvLevelR
setParameterOfZones("UserLROffset", UserEnvLevelR * 0.5)
end
-- define parameters for the user envelope
defineParameter("UserEnvVelocity", "User Envelope Velocity", 0, 0, 100, 0.1, onUserEnvVelChanged)
defineParameter("UserEnvAttack", "User Envelope Attack", 0, 0, 100, 0.1, onUserEnvAttackChanged)
defineParameter("UserEnvLevel0", "User Envelope Start Level", 0, -100, 100, 0.1, onUserEnvLevel0Changed)
defineParameter("UserEnvLevel1", "User Envelope Attack Level", 0, -100, 100, 0.1, onUserEnvLevel1Changed)
defineParameter("UserEnvSustain", "User Envelope Sustain Level", 0, -100, 100, 0.1, onUserEnvSustainChanged)
defineParameter("UserEnvLevelR", "User Envelope Release Level", 0, -100, 100, 0.1, onUserEnvLevelRChanged)
-- function for setting the LFO sync mode
function setLfoSyncMode(lfo, LfoSync, LfoSyncMode)
if LfoSync then
if LfoSyncMode == 1 then
lfo:setParameter("Trigger", 0)
lfo:setParameter("Sync", 2)
elseif LfoSyncMode == 2 then
lfo:setParameter("Trigger", 1)
lfo:setParameter("Sync", 1)
else
lfo:setParameter("Trigger", 2)
lfo:setParameter("Sync", 1)
end
else
lfo:setParameter("Trigger", 0)
lfo:setParameter("Sync", 0)
end
end
-- parameter change callbacks for LFO A and B
function onLfoASyncModeChanged()
local lfo = this.parent:getChild("LFO A")
if lfo then
setLfoSyncMode(lfo, LfoASync, LfoASyncMode)
end
end
function onLfoBSyncModeChanged()
local lfo = this.parent:getChild("LFO B")
if lfo then
setLfoSyncMode(lfo, LfoBSync, LfoBSyncMode)
end
end
-- names of the LFO sync modes
defineSlotLocal("syncModeNames")
syncModeNames = { "Beat", "First", "Each" }
-- define parameters for the LFO section
defineParameter("LfoASync", "LFO A Sync", false, onLfoASyncModeChanged)
defineParameter("LfoASyncMode", "LFO A Sync Mode", 1, syncModeNames, onLfoASyncModeChanged)
defineParameter("LfoBSync", "LFO B Sync", false, onLfoBSyncModeChanged)
defineParameter("LfoBSyncMode", "LFO B Sync Mode", 1, syncModeNames, onLfoBSyncModeChanged)
-- functions for assigning the modulation sources
function setSource(row, source, polarity, smoothing, sourceIndex, sourceExtra1, sourceExtra2)
if source == 1 then
row:setSource1(sourceIndex, sourceExtra1, sourceExtra2)
row:setParameter("Source1.Polarity", polarity)
row:setParameter("Source1.Smoothing", smoothing)
else
row:setSource2(sourceIndex, sourceExtra1, sourceExtra2)
row:setParameter("Source2.Polarity", polarity)
row:setParameter("Source2.Smoothing", smoothing)
end
end
function assignStandardSource(row, source, polarity, smoothing, sourceIndex)
setSource(row, source, polarity, smoothing, sourceIndex)
end
function assignLfoA(row, source, polarity, smoothing)
local lfoA = this.parent:getMidiModule("LFO A")
if lfoA then
setSource(row, source, polarity, smoothing, ModulationSource.modulationModule, lfoA)
else
setSource(row, source, polarity, smoothing, ModulationSource.unassigned)
end
end
function assignLfoB(row, source, polarity, smoothing)
local lfoB = this.parent:getMidiModule("LFO B")
if lfoB then
setSource(row, source, polarity, smoothing, ModulationSource.modulationModule, lfoB)
else
setSource(row, source, polarity, smoothing, ModulationSource.unassigned)
end
end
function assignQC(row, source, polarity, smoothing, qcIndex)
setSource(row, source, polarity, smoothing, ModulationSource.quickControl, this.parent, qcIndex)
end
function assignMidiCtrl(row, source, polarity, smoothing, sourceIndex)
setSource(row, source, polarity, smoothing, ModulationSource.midiControl, sourceIndex)
end
-- define modulation sources
defineSlotLocal("modSources")
modSources = {
{ name = "-", assignFunc = assignStandardSource, index = ModulationSource.unassigned, bipolar = 0, smoothing = -1 },
{ name = "LFO A", assignFunc = assignLfoA, bipolar = 1, smoothing = -1 },
{ name = "LFO B", assignFunc = assignLfoB, bipolar = 1, smoothing = -1 },
{ name = "Amp Envelope", assignFunc = assignStandardSource, index = ModulationSource.ampEnv, bipolar = 0, smoothing = -1 },
{ name = "Filter Envelope", assignFunc = assignStandardSource, index = ModulationSource.filterEnv, bipolar = 0, smoothing = -1 },
{ name = "Env3", assignFunc = assignStandardSource, index = ModulationSource.userEnv, bipolar = 1, smoothing = -1 },
{ name = "Key Follow", assignFunc = assignStandardSource, index = ModulationSource.keyFollow, bipolar = 1, smoothing = -1 },
{ name = "Note-on Velocity", assignFunc = assignStandardSource, index = ModulationSource.noteOnVelocity, bipolar = 0, smoothing = -1 },
{ name = "Note-on Vel Squared", assignFunc = assignStandardSource, index = ModulationSource.noteOnVelocitySquared, bipolar = 0, smoothing = -1 },
{ name = "Pitch Bend", assignFunc = assignStandardSource, index = ModulationSource.pitchBend, bipolar = 1, smoothing = -1 },
{ name = "Modulation Wheel", assignFunc = assignStandardSource, index = ModulationSource.modWheel, bipolar = 0, smoothing = -1 },
{ name = "Aftertouch", assignFunc = assignStandardSource, index = ModulationSource.aftertouch, bipolar = 0, smoothing = -1 },
{ name = "Arp Controller 1", assignFunc = assignMidiCtrl, index = 110, bipolar = 0, smoothing = 0 },
{ name = "Arp Controller 2", assignFunc = assignMidiCtrl, index = 111, bipolar = 0, smoothing = 0 },
{ name = "Arp Controller 3", assignFunc = assignMidiCtrl, index = 112, bipolar = 0, smoothing = 0 },
{ name = "Bus 1", assignFunc = assignStandardSource, index = ModulationSource.bus1, bipolar = 1, smoothing = -1 },
{ name = "Bus 2", assignFunc = assignStandardSource, index = ModulationSource.bus2, bipolar = 1, smoothing = -1 },
{ name = "Bus 3", assignFunc = assignStandardSource, index = ModulationSource.bus3, bipolar = 1, smoothing = -1 },
{ name = "Bus 4", assignFunc = assignStandardSource, index = ModulationSource.bus4, bipolar = 1, smoothing = -1 },
{ name = "Bus 5", assignFunc = assignStandardSource, index = ModulationSource.bus5, bipolar = 1, smoothing = -1 },
{ name = "Bus 6", assignFunc = assignStandardSource, index = ModulationSource.bus6, bipolar = 1, smoothing = -1 },
{ name = "Bus 7", assignFunc = assignStandardSource, index = ModulationSource.bus7, bipolar = 1, smoothing = -1 },
{ name = "Bus 8", assignFunc = assignStandardSource, index = ModulationSource.bus8, bipolar = 1, smoothing = -1 },
{ name = "Quick Control 1", assignFunc = assignQC, index = 1, bipolar = 1, smoothing = -1 },
{ name = "Quick Control 2", assignFunc = assignQC, index = 2, bipolar = 1, smoothing = -1 },
{ name = "Quick Control 3", assignFunc = assignQC, index = 3, bipolar = 1, smoothing = -1 },
{ name = "Quick Control 4", assignFunc = assignQC, index = 4, bipolar = 1, smoothing = -1 },
{ name = "Quick Control 5", assignFunc = assignQC, index = 5, bipolar = 1, smoothing = -1 },
{ name = "Quick Control 6", assignFunc = assignQC, index = 6, bipolar = 1, smoothing = -1 },
{ name = "Quick Control 7", assignFunc = assignQC, index = 7, bipolar = 1, smoothing = -1 },
{ name = "Quick Control 8", assignFunc = assignQC, index = 8, bipolar = 1, smoothing = -1 }
}
-- create table with mod source names
function getModSrcNames()
modSrcNames = {}
for i=1, #modSources do
modSrcNames[i] = modSources[i].name
end
end
getModSrcNames()
-- parameter change callback to set the modulation source
function onModSourceChanged(row, source, modSourceParam)
local modSource = modSources[modSourceParam]
local zones = this.parent:getLayer():findZones()
for i, zone in pairs(zones) do
modSource.assignFunc(zone:getModulationMatrixRow(row), source, modSource.bipolar, modSource.smoothing, modSource.index)
end
end
defineSlotLocal("mmParameterInfo")
mmParameterInfo =
{
default = 1,
automatable = false,
strings = modSrcNames
}
-- define parameters for modulation matrix rows
for i = 1, 16 do
mmParameterInfo.name = "ModSource"..i
mmParameterInfo.longName = "Modulation Source "..i
mmParameterInfo.onChanged = function() onModSourceChanged(i, 1, _G["ModSource"..i]) end
defineParameter(mmParameterInfo)
mmParameterInfo.name = "ModModifier"..i
mmParameterInfo.longName = "Modulation Modifier "..i
mmParameterInfo.onChanged = function() onModSourceChanged(i, 2, _G["ModModifier"..i]) end
defineParameter(mmParameterInfo)
end
-- define modulation destinations
defineSlotLocal("modDestinations")
modDestinations = {
{ name = "-", index = ModulationDestination.unassigned },
{ name = "Pitch", index = ModulationDestination.pitch },
{ name = "Cutoff", index = ModulationDestination.cutoff },
{ name = "Resonance", index = ModulationDestination.resonance },
{ name = "Distortion", index = ModulationDestination.distortion },
{ name = "Level", index = ModulationDestination.level },
{ name = "Volume", index = ModulationDestination.volume1 },
{ name = "Pan", index = ModulationDestination.pan },
{ name = "Amp Env Attack", index = ModulationDestination.ampEnvAttack },
{ name = "Amp Env Decay", index = ModulationDestination.ampEnvDecay },
{ name = "Amp Env Sustain", index = ModulationDestination.ampEnvSustain },
{ name = "Amp Env Release", index = ModulationDestination.ampEnvRelease },
{ name = "Filter Env Attack", index = ModulationDestination.filterEnvAttack },
{ name = "Filter Env Decay", index = ModulationDestination.filterEnvDecay },
{ name = "Filter Env Sustain", index = ModulationDestination.filterEnvSustain },
{ name = "Filter Env Release", index = ModulationDestination.filterEnvRelease },
{ name = "Env3 Start Level", index = ModulationDestination.userEnvStartLev },
{ name = "Env3 Attack", index = ModulationDestination.userEnvAttack },
{ name = "Env3 Attack Level", index = ModulationDestination.userEnvAttLev },
{ name = "Env3 Decay", index = ModulationDestination.userEnvDecay },
{ name = "Env3 Sustain", index = ModulationDestination.userEnvSustain },
{ name = "Env3 Release", index = ModulationDestination.userEnvRelease },
{ name = "Env3 Release Level", index = ModulationDestination.userEnvRelLev },
{ name = "Bus 1", index = ModulationDestination.bus1 },
{ name = "Bus 2", index = ModulationDestination.bus2 },
{ name = "Bus 3", index = ModulationDestination.bus3 },
{ name = "Bus 4", index = ModulationDestination.bus4 },
{ name = "Bus 5", index = ModulationDestination.bus5 },
{ name = "Bus 6", index = ModulationDestination.bus6 },
{ name = "Bus 7", index = ModulationDestination.bus7 },
{ name = "Bus 8", index = ModulationDestination.bus8 }
}
-- create table with the names of the modulation destinations
function getModDestNames()
modDestNames = {}
for i=1, #modDestinations do
modDestNames[i] = modDestinations[i].name
end
end
getModDestNames()
-- parameter change callback to set the modulation destination
function onModDestChanged(row, modDestinationParam)
local modDestination = modDestinations[modDestinationParam]
local zones = this.parent:getLayer():findZones()
for i, zone in pairs(zones) do
zone:getModulationMatrixRow(row):setParameter("Destination.Destination", modDestination.index)
end
end
mmParameterInfo.strings = modDestNames
-- define parameters for modulation matrix rows
for i = 1, 16 do
mmParameterInfo.name = "ModDestination"..i
mmParameterInfo.longName = "Modulation Destination "..i
mmParameterInfo.onChanged = function() onModDestChanged(i, _G["ModDestination"..i]) end
defineParameter(mmParameterInfo)
end
-- define parameters for arpeggiator controller lane destinations
for i = 1, 3 do
mmParameterInfo.name = "CtrlLane"..i.."Dest"
mmParameterInfo.longName = "Ctrl Lane "..i.." Destination"
mmParameterInfo.onChanged = function() onModDestChanged(16 + i, _G["CtrlLane"..i.."Dest"]) end
defineParameter(mmParameterInfo)
end
--[[
verify some parameters for being updated by automation/QC
(QC relative changes don't produce a change notification because the document isn't changed)
Relying on the document update has idle timing for absolute changes, so might not be fast enough
--]]
function verifyParam(name, callback)
if last[name] ~= _G[name] then
callback()
end
end
function onNote(ev)
verifyParam("PitchRandom", onPitchRandomChanged)
verifyParam("FilterVelocity", onFilterVelChanged)
verifyParam("FilterEnvAttack", onFilterEnvAttackChanged)
verifyParam("FilterEnvSustain", onFilterEnvSustainChanged)
verifyParam("AmpVelocity", onAmpVelChanged)
verifyParam("AmpEnvAttack", onAmpEnvAttackChanged)
verifyParam("AmpEnvSustain", onAmpEnvSustainChanged)
verifyParam("UserEnvVelocity", onUserEnvVelChanged)
verifyParam("UserEnvAttack", onUserEnvAttackChanged)
verifyParam("UserEnvLevel0", onUserEnvLevel0Changed)
verifyParam("UserEnvLevel1", onUserEnvLevel1Changed)
verifyParam("UserEnvSustain", onUserEnvSustainChanged)
verifyParam("UserEnvLevelR", onUserEnvLevelRChanged)
postEvent(ev)
end