; Calculated_F_Tables.csd
; Written by Iain McCurdy, 2015
; GEN tables are calculated point-by-point within i-time loops based on a number of simple formulae relating y and x.
; The y-axis location is only a graphical indication of what x values were used in calculating y values. It does not
; imply a shift in table index values (which are always positive).
; n.b. tan function output exceeds the range of the gentable viewer
; Some of these functions might be useful for control mapping or waveshaping.
form size(500,570), text("Calculated F-Table"), guirefresh(32), colour(80,80,80), pluginid("CaFT")
gentable bounds( 0, 0,500,500), tablenumber(1), tablecolour("Orange"), identchannel("table"), amprange(-1,1,-1), zoom(-1), fill(0)
image bounds( 0,250,500, 1), shape("sharp"), colour("white")
image bounds(500, 0, 1,300), shape("sharp"), colour("white"), identchannel("y_axis")
combobox bounds( 5,505,120, 20), channel("formula"), text("y = x","y = -x","y = x / a","y = x * a","y = x ^ a","y = - [x ^ a]","y = x ^ [1/a]","y = - x ^ [1/a] + 1","y = sin[x * pi]","y = cos[x * pi]","y = tan[x * pi]","y = log[x]","y = log2[x]","y = log10[x]","y = sinh[x * a]","y = cosh[x * a]","y = tanh[x * pi * a]","y = sininv[x]","y = cosinv[x]","y = taninv[x * a]","y = a ^ x","y = [a ^ x] - 1","y = [a ^ -x] - 1")
image bounds( 5,525, 66, 40) plant("a") identchannel("aID") colour(0,0,0,0)
{
numberbox bounds( 0, 0, 40, 30), text("a ="), channel("a"), range(1,100,2,1,1) textcolour("white")
button bounds(41, 8, 20, 14), text("^","^") channel("aIncr") latched(0)
button bounds(41, 8, 20, 14), text("^","^") channel("aDecr") latched(0), rotate(3.147,10,15)
}
label bounds(130,513,100, 14), text("normalised"), visible(0), identchannel("normalised")
label bounds(220,513,100, 14), text("x = 0 to 10"), visible(0), identchannel("x = 0 to 10")
numberbox bounds(340,505,60,30), text("x value"), channel("xval"), range(-10, 10,0,1,0.00001)
numberbox bounds(405,505,60,30), text("y value"), channel("yval"), range(-100,100,0,1,0.00001)
-n -dm0
sr = 44100
ksmps = 16
nchnls = 1
0dbfs = 1
gi1 ftgen 1,0,2048,10,1 ; table for storage of functions
giprenorm ftgen 2,0,2048,10,1 ; table for storage of functions (pre-normalisation)
opcode TabNormalise,0,i ; UDO for normalising a table
itabnum xin
inumitems = ftlen(itabnum) ; derive number of items in table
imax table 0,itabnum ; maximum value starts as first table items
icount init 1 ; counter starts at 1 (we've already read item 0)
loop: ; loop 1 beginning
ival table icount,itabnum ; read value from table
if abs(ival)>=imax then ; if absolute value read from table is higher than (or equal to) current maximum...
imax = abs(ival) ; ...value becomes new maximum
indx = icount ; index of maximum becomes the index of this value
endif ; end of conditional branch
loop_lt icount,1,inumitems,loop ; conditionally loop back
icount = 0
loop2:
ival table icount,gi1
tableiw ival/imax, icount,itabnum
loop_lt icount,1,ftlen(itabnum),loop2
endop
instr 1
iftlen = ftlen(gi1) ; length of the function table
kformula chnget "formula" ; formula choice
kformula init 1
ka chnget "a"
if trigger:k(chnget:k("aIncr"),0.5,0)==1 then
chnset limit:k(ka+1,1,100),"a"
elseif trigger:k(chnget:k("aDecr"),0.5,0)==1 then
chnset limit:k(ka-1,1,100),"a"
endif
if changed(kformula)==1 then ; if formula choice changes...
reinit UPDATE ; start a reinitilisation
endif
UPDATE:
iformula = i(kformula) ; i-time state of kformula
icount = 0 ; reset counter. (Moves for each index of the function table)
chnset "bounds(250, 0,1,500)","y_axis" ; default set position of y-axis
chnset "visible(0)","normalised" ; default hide 'normalised' label
chnset "visible(0)","x = 0 to 10" ; default hide label
if iformula==1 then ; y = x
while icountimax then ; if current y value is a new (absolute) maximum
imax = iy ; overwrite maximum
endif
tableiw iy,icount,gi1 ; write y value to table
icount += 1 ; increment counter
od ; end of while loop
tableicopy giprenorm, gi1
TabNormalise gi1
chnset "visible(1)","normalised" ; show 'normalised' label
kNorm init 1
kXScale init 0
chnset "visible(1)","aID" ; show/hide a widgets
elseif iformula==22 then ; y = (a ^ x) -1
if changed:k(ka)==1 then
reinit RestartForm22
endif
RestartForm22:
icount = 0
imax init 0 ; initialise maximum y value
while icountimax then ; if current y value is a new (absolute) maximum
imax = iy ; overwrite maximum
endif
tableiw iy,icount,gi1 ; write y value to table
icount += 1 ; increment counter
od ; end of while loop
tableicopy giprenorm, gi1
TabNormalise gi1
chnset "visible(1)","normalised" ; show 'normalised' label
kNorm init 1
kXScale init 0
chnset "visible(1)","aID" ; show/hide a widgets
elseif iformula==23 then ; y = (a ^ -x) - 1
if changed:k(ka)==1 then
reinit RestartForm23
endif
RestartForm23:
icount = 0
imax init 0 ; initialise maximum y value
while icountimax then ; if current y value is a new (absolute) maximum
imax = iy ; overwrite maximum
endif
tableiw iy,icount,gi1 ; write y value to table
icount += 1 ; increment counter
od ; end of while loop
tableicopy giprenorm, gi1
TabNormalise gi1
chnset "visible(1)","normalised" ; show 'normalised' label
kNorm init 1
kXScale init 0
chnset "visible(1)","aID" ; show/hide a widgets
endif
chnset "tablenumber(1)","table" ; update table
; read y values and print to numberbox
kMOUSE_X chnget "MOUSE_X" ; read mouse x position. range: 0 - panel_width(in pixels)
kndx = (kMOUSE_X/500) ; range: 0 - 1
if metro(8)==1 then ; restrict maximum rate of updates
if changed(kndx)==1 then ; if index has change. i.e. if mouse has moved horizontally...
if kNorm = 1 then ; normalised to fit values vertically, therefore read actual value from an unnormalised version
kyval table kndx,giprenorm,1 ; read value from prenormalised table
else
kyval table kndx,gi1,1 ; otherwise just read from the viewed table
endif
if kXScale==1 then ; range 0 to 1
kxval = kndx
elseif kXScale==10 then ; range 0 to 10
kxval = kndx*10
elseif kXScale==0 then ; range -1 to 1
kxval = kndx*2 - 1
endif
chnset kxval, "xval" ; write value to number box
chnset kyval, "yval" ; write value to number box
endif
endif
endin
i 1 0 3600