--[[ Paste the code below into the formula modulator. Set it to modulate the pitch by some amount, such as 1 semitone or 1 key, then edit the controls below. As of now, a tuning file or MTS-ESP is still required because the Surge XT formula modulator has no access to individual midi notes. Similarly, there is no GUI, which makes the code even smaller compared to the Kontakt version. The modulation precision should be a C++ double, but even a float with a 24-bit mantissa has enough precision to cover all usable octaves at millicent precision. Channels are 0-indexed here but arrays are 1-indexed in Lua, which is dumb and weird. It would be possible to assume that modAmount is 1 key to avoid having to ever specify ed, but then the equave offsets wouldn't work. Right click modulator -> Copy modulator with targets Default configurations: subunitFactor = 2 equaveOffsets = {0, 1, 2, 3, -4,-3,-2,-1, 0, 1, 2, 3, -4,-3,-2,-1} subunitOffsets = {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0} subunitFactor = 3 equaveOffsets = {0, 1, 2, -2,-1, 0, 1, 2, -2,-1, 0, 1, 2, -3,-2,-1} subunitOffsets = {0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0, 0} subunitFactor = 4 equaveOffsets = {0, 1, -2,-1, 0, 1, -2,-1, 0, 1, -2,-1, 0, 1, -2,-1} subunitOffsets = {0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 0, 0} ]] function process(state) -- TuneLoon S0.1 for Surge by ground -- CONTROLS ed = 24 subunitFactor = 3 modAmount = 1/ed equaveOffsets = {0, 1, 2, -2,-1, 0, 1, 2, -2,-1, 0, 1, 2, -3,-2,-1} subunitOffsets = {0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0, 0} --[[ eq: Equal divisions of the equave specified in the tuning file. subunitFactor: Multiple of the existing equal temperament, for higher resolution using MIDI channels. modAmount: Amount that the formula modulator is set to alter the pitch parameter, as a fraction of the equave. - "Apply tuning at midi input": unit is semitones, so set to (N/12) / (math.log(equaveRatio)/math.log(2)) for N semitones. - "Apply tuning after modulation": unit is keys, so set to N/ed for N keys. equaveOffsets and subunitOffsets: Offset values per MIDI channel. ]] state.clamp_output = false state.output = (equaveOffsets[state.channel+1] / modAmount) + (subunitOffsets[state.channel+1] / (ed*subunitFactor*modAmount)) return state end