Hello,
I’m working on an Instrument and I like to define the Envelope Parameter in the same way as it is in the Anima Instrument. I have an existing Script for the Mod Matrix. So I copied the area with the Env from Anima to my Script and link the Parameter from the Script to the Gui. That works, the Values will be set. But when I change the Value using the Sliders, there is an Script Error for the Parameter change callback and the Settings will not work.
I don’t know where the Problem is becaus I don’t know much about scripting. Maybe both Scripts will not work together or I don’t copy all. Maybe there is an easier way.
I also like to use the Env in all Zones, that works fine without the Script.
Is it also possible to set the Parameter for Attack, Decay and Release to “ms” and not to “%” ?
I know this are a lot of questions, maybe someone can help.
Many thanks.
The Functions for the Env are on the Top.
-- keep track of last applied parameter values
last = {}
-- parameter change callbacks for filter envelope offsets
function onFilterEnvAttackChanged()
last.FilterEnvAttack = FilterEnvAttack
this.parent:getZone():setParameter("DCFAttOffset", FilterEnvAttack)
end
function onFilterEnvSustainChanged()
last.FilterEnvSustain = FilterEnvSustain
this.parent:getZone():setParameter("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
this.parent:getZone():setParameter("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
this.parent:getZone():setParameter("DCAAttOffset", AmpEnvAttack)
end
function onAmpEnvSustainChanged()
last.AmpEnvSustain = AmpEnvSustain
this.parent:getZone():setParameter("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
this.parent:getZone():setParameter("User Env.VelocityToLevel", UserEnvVelocity)
end
function onUserEnvAttackChanged()
last.UserEnvAttack = UserEnvAttack
this.parent:getZone():setParameter("UserAttOffset", UserEnvAttack)
end
function onUserEnvLevel0Changed()
last.UserEnvLevel0 = UserEnvLevel0
this.parent:getZone():setParameter("UserL0Offset", UserEnvLevel0 * 0.5)
end
function onUserEnvLevel1Changed()
last.UserEnvLevel1 = UserEnvLevel1
this.parent:getZone():setParameter("UserL1Offset", UserEnvLevel1 * 0.5)
end
function onUserEnvSustainChanged()
last.UserEnvSustain = UserEnvSustain
this.parent:getZone():setParameter("UserSusOffset", UserEnvSustain * 0.5)
end
function onUserEnvLevelRChanged()
last.UserEnvLevelR = UserEnvLevelR
this.parent:getZone():setParameter("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)
-- 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 assignLFO3(row, source, polarity, smoothing)
local LFO1 = this.parent:getMidiModule("LFO 3") -- needs to match midi module name
if LFO3 then
setSource(row, source, polarity, smoothing, ModulationSource.modulationModule, LFO3)
else
setSource(row, source, polarity, smoothing, ModulationSource.unassigned)
end
end
function assignLFO4(row, source, polarity, smoothing)
local LFO4 = this.parent:getMidiModule("LFO 4")
if LFO4 then
setSource(row, source, polarity, smoothing, ModulationSource.modulationModule, LFO4)
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/LFO 1", assignFunc = assignStandardSource, index = ModulationSource.lfo1, bipolar = 0, smoothing = -1 },
{ name = "/LFO/LFO 2", assignFunc = assignStandardSource, index = ModulationSource.lfo2, bipolar = 0, smoothing = -1 },
{ name = "/ENV/Amp Envelope", assignFunc = assignStandardSource, index = ModulationSource.ampEnv, bipolar = 0, smoothing = -1 },
{ name = "/ENV/Filter Envelope", assignFunc = assignStandardSource, index = ModulationSource.filterEnv, bipolar = 0, smoothing = -1 },
{ name = "/ENV/Envelope 3", assignFunc = assignStandardSource, index = ModulationSource.userEnv, bipolar = 0, smoothing = -1 },
{ name = "/Wheel/Modulation Wheel", assignFunc = assignStandardSource, index = ModulationSource.modWheel, bipolar = 0, smoothing = -1 },
{ name = "/Wheel/Pitch Bend", assignFunc = assignStandardSource, index = ModulationSource.pitchBend, bipolar = 1, smoothing = -1 },
{ name = "/Wheel/Aftertouch", assignFunc = assignStandardSource, index = ModulationSource.aftertouch, bipolar = 1, smoothing = -1 },
{ name = "/Bus/Bus 1", assignFunc = assignStandardSource, index = ModulationSource.bus1, bipolar = 1, smoothing = -1 },
{ name = "/Quick Control/Quick Control 1", assignFunc = assignQC, index = 1, bipolar = 1, smoothing = -1 },
{ name = "/Quick Control/Quick Control 2", assignFunc = assignQC, index = 2, bipolar = 1, smoothing = -1 },
{ name = "/Quick Control/Quick Control 3", assignFunc = assignQC, index = 3, bipolar = 1, smoothing = -1 },
{ name = "/Quick Control/Quick Control 4", assignFunc = assignQC, index = 4, bipolar = 1, smoothing = -1 },
{ name = "/Quick Control/Quick Control 5", assignFunc = assignQC, index = 5, bipolar = 1, smoothing = -1 },
{ name = "/Quick Control/Quick Control 6", assignFunc = assignQC, index = 6, bipolar = 1, smoothing = -1 },
{ name = "/Quick Control/Quick Control 7", assignFunc = assignQC, index = 7, bipolar = 1, smoothing = -1 },
{ name = "/Quick Control/Quick Control 8", assignFunc = assignQC, index = 8, bipolar = 1, smoothing = -1 },
}
-- create table with mod source names
function getModSrcNames()
modSrcNames = {}
modSrcNamesText = {}
for i=1, #modSources do
modSrcNames[i] = modSources[i].name
modSrcNamesText[i] = string.match(modSources[i].name, "[^/]+$")
end
end
getModSrcNames()
-- parameter change callback to set the modulation source
function onModSourceChanged(row, source, modSourceParam)
if source == 1 then
_G["ModSourceText"..row] = modSourceParam
else
_G["ModModifierText"..row] = modSourceParam
end
local modSource = modSources[modSourceParam]
local zones = this.parent:findZones(true)
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
mmParameterInfo.strings = modSrcNamesText
for i = 1, 16 do
mmParameterInfo.name = "ModSourceText"..i
defineParameter(mmParameterInfo)
mmParameterInfo.name = "ModModifierText"..i
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 1", index = ModulationDestination.volume1 },
{ name = "/Volume 2", index = ModulationDestination.volume2 },
{ name = "/Pan", index = ModulationDestination.pan },
{ name = "/Bus/Bus 1", index = ModulationDestination.bus1},
{ name = "/Amp Env/Amp Env Attack", index = ModulationDestination.ampEnvAttack },
{ name = "/Amp Env/Amp Env Decay", index = ModulationDestination.ampEnvDecay },
{ name = "/Amp Env/Amp Env Sustain", index = ModulationDestination.ampEnvSustain },
{ name = "/Amp Env/Amp Env Release", index = ModulationDestination.ampEnvRelease },
{ name = "/Filter Env/Filter Env Attack", index = ModulationDestination.filterEnvAttack },
{ name = "/Filter Env/Filter Env Decay", index = ModulationDestination.filterEnvDecay },
{ name = "/Filter Env/Filter Env Sustain", index = ModulationDestination.filterEnvSustain },
{ name = "/Filter Env/Filter Env Release", index = ModulationDestination.filterEnvRelease },
{ name = "/Env 3/Env 3 Start Level", index = ModulationDestination.userEnvStartLev },
{ name = "/Env 3/Env 3 Attack", index = ModulationDestination.userEnvAttack },
{ name = "/Env 3/Env 3 Attack Level", index = ModulationDestination.userEnvAttLev },
{ name = "/Env 3/Env 3 Decay", index = ModulationDestination.userEnvDecay },
{ name = "/Env 3/Env 3 Sustain", index = ModulationDestination.userEnvSustain },
{ name = "/Env 3/Env 3 Release", index = ModulationDestination.userEnvRelease },
{ name = "/Env 3/Env 3 Release Level", index = ModulationDestination.userEnvRelLev },
{ name = "/Osc 1/Osc 1 Pitch", index = ModulationDestination.osc1Pitch },
{ name = "/Osc 1/Osc 1 Level", index = ModulationDestination.osc1Level },
{ name = "/Osc 1/Osc 1 Waveform", index = ModulationDestination.osc1Waveform },
{ name = "/Osc 1/Osc 1 Multi Detune", index = ModulationDestination.osc1MultiDetune },
{ name = "/Osc 1/Osc 1 Multi Pan", index = ModulationDestination.osc1MultiPan },
{ name = "/Osc 1/Osc 1 Multi Voices", index = ModulationDestination.osc1MultiVoices },
{ name = "/Osc 2/Osc 2 Pitch", index = ModulationDestination.osc2Pitch },
{ name = "/Osc 2/Osc 2 Level", index = ModulationDestination.osc2Level },
{ name = "/Osc 2/Osc 2 Waveform", index = ModulationDestination.osc2Waveform },
{ name = "/Osc 2/Osc 2 Multi Detune", index = ModulationDestination.osc2MultiDetune },
{ name = "/Osc 2/Osc 2 Multi Pan", index = ModulationDestination.osc2MultiPan },
{ name = "/Osc 2/Osc 2 Multi Voices", index = ModulationDestination.osc2MultiVoices },
{ name = "/Osc 3/Osc 3 Pitch", index = ModulationDestination.osc3Pitch },
{ name = "/Osc 3/Osc 3 Level", index = ModulationDestination.osc3Level },
{ name = "/Osc 3/Osc 3 Waveform", index = ModulationDestination.osc3Waveform },
{ name = "/Osc 3/Osc 3 Multi Detune", index = ModulationDestination.osc3MultiDetune },
{ name = "/Osc 3/Osc 3 Multi Pan", index = ModulationDestination.osc3MultiPan },
{ name = "/Osc 3/Osc 3 Multi Voices", index = ModulationDestination.osc3MultiVoices },
{ name = "/Sample/Sample Start", index = ModulationDestination.sampleStart },
{ name = "/Sample/Speed Factor", index = ModulationDestination.speedFactor },
{ name = "/Sample/Formant Shift", index = ModulationDestination.formantShift },
{ name = "Noise Level", index = ModulationDestination.noiseLevel },
{ name = "Sub Osc Level", index = ModulationDestination.subOscLevel },
{ name = "Ring Modulator Level", index = ModulationDestination.ringModLevel },
{ name = "/LFO 1/LFO 1 Frequency", index = ModulationDestination.lfo1Freq },
{ name = "/LFO 1/LFO 1 Shape", index = ModulationDestination.lfo1Shape },
{ name = "/LFO 2/LFO 2 Frequency", index = ModulationDestination.lfo2Freq },
{ name = "/LFO 2/LFO 2 Shape", index = ModulationDestination.lfo2Shape },
}
-- create table with the names of the modulation destinations
function getModDestNames()
modDestNames = {}
modDestNamesText = {}
for i=1, #modDestinations do
modDestNames[i] = modDestinations[i].name
modDestNamesText[i] = string.match(modDestinations[i].name, "[^/]+$")
end
end
getModDestNames()
-- parameter change callback to set the modulation destination
function onModDestChanged(row, modDestinationParam)
_G["ModDestinationText"..row] = modDestinationParam
local modDestination = modDestinations[modDestinationParam]
local zones = this.parent:findZones(true)
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
mmParameterInfo.strings = modDestNamesText
for i = 1, 16 do
mmParameterInfo.name = "ModDestinationText"..i
defineParameter(mmParameterInfo)
end
-- keep track of last applied parameter values
last = {}