FYI, every fader control has quite a few things going on inside it. The components that influence how the encoder changes its value and subsequently how the value is displayed graphically are:
- a fully-customizable lookup table which maps encoder phase to an actual value.
- should the lookup table be interpolated or not?
- phase increments for SUPER FINE, FINE, COARSE, and SUPER COARSE.
- a scaling rule that maps fader value to the actual graphical position (i.e. usually linear vs octaves).
- a unit of measurement (dB, Hz, sec, cents, etc.) for the numeric readouts.
For your enjoyment here is how the frequency faders for oscillators are defined. First, the function that is used to define the entries in the fader’s lookup table.
local function octaveMapWithZero(from,to,F0,step)
local map = app.DialMap()
local n = 0
for x=from,to,step do n = n + 1 end
map:clear(n+1)
map:add(0)
for x=from,to,step do
map:add((2^x)*F0)
end
map:setZero(0,false)
return map
end
dialMaps["oscFreq"] = octaveMapWithZero(-10,10,27.5,1.0/12)
In English,
Create an entry, every semitone, 10 octaves above and 10 octaves below 27.5Hz. Finally, add zero to the beginning.
Here is the definition for the f0 control for a Sine Oscillator unit that uses the above lookup table for its fader control:
controls.freq = GainBias {
button = "f0",
description = "Fundamental",
branch = self:getBranch("Fundamental"),
gainbias = objects.f0,
range = objects.f0Range,
biasMap = Encoder.getMap("oscFreq"),
biasUnits = app.unitHertz,
initialBias = 27.5,
gainMap = Encoder.getMap("freqGain"),
scaling = app.octaveScaling
}
Notice that the biasMap
specifies the encoder lookup table, biasUnits
specifies the unit of measurement and scaling
changes the graphical scaling from linear (default) to octaves.
The freq fader of a filter is essentially the same except a zero is not added to the lookup table. The zero is added in the case of oscillators so that you can “freeze” the oscillator.