Flexible load of layers

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