Skip to content

Instantly share code, notes, and snippets.

@jmsole
Created October 10, 2021 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmsole/e3150840e4704afa796ddd12a30e1354 to your computer and use it in GitHub Desktop.
Save jmsole/e3150840e4704afa796ddd12a30e1354 to your computer and use it in GitHub Desktop.
rotating grid 32-0.1 -- based on the grid script by @Grey, inspired by grids by @pichenettes.
-- rotating grid 32-0.1
-- based on the grid script by @grey, inspired by grids by @pichenettes.
-- patterns are based on those found in grids, but adapted to 16 values per step
-- and converted to hex numbers to make the script more compact.
patterns={
{{'1000007000003000b0d050009000b000'},
{'d09000f0100000b0005000d030007000'},
{'609010c0607040c0609020e0609040b0'}},
{{'20e0a0e040e0b0f010f0d0e050e07080'},
{'e040c0c020e070e0e060e0e01090b0b0'},
{'606010c0606040e0608010e0608020a0'}},
{{'1000800000a0002000504000b0d070e0'},
{'008000001040e0c000a000002000e060'},
{'10b070b080b090c030604060b0d020e0'}},
{{'1030c0009070b08040e02000e06000d0'},
{'00007090104000c000b0c0e020e060c0'},
{'1020103070a090a050b0d0d060e030d0'}},
{{'10e0c0c080a040c020e060c0e0c0a0e0'},
{'f000a0c010008000f00060c0102040e0'},
{'b0e0108070d040a0b0d0208070d050a0'}},
{{'10d0e0b00000a00040200050007080f0'},
{'508070401000e0b0a0d0000020e0e040'},
{'50a010b080b020b070a010e080d040d0'}},
{{'10002000e0f08000a0006000a0c04000'},
{'d04000a01080f050e02000b04070d0e0'},
{'1020101040e070c060c0b0e060e090c0'}},
{{'2000c000a00020e01000600080e040e0'},
{'00009000300050b0f0d070d010f050b0'},
{'10b030d03000700010d050d050009000'}},
{{'10003000d000300050901000000070b0'},
{'6000e08010e000a0f00040e010e020c0'},
{'10e0c0e0a0e0c08060e0c0e020204040'}},
{{'20e0e070f0f010f090e040b0c04060e0'},
{'f0a0f0f010c0e020f0e040f010808060'},
{'90d0105070e0309020b01060709020a0'}},
{{'7000009000001090b0300000d0005000'},
{'00806080604020c010a0e0a0e0f0c0f0'},
{'10007000509090903000b00050b050d0'}},
{{'1000000000000000100030bd00500079'},
{'008000d0300300300000d0001000668b'},
{'709939b070b03090509010b059d91990'}},
{{'100010400000a0c0e000202000f06080'},
{'00b0c0e010e000200060c09040009070'},
{'10d020c030b0409040e060f060807070'}},
{{'100000c040a0e02010c0a0c060000080'},
{'b000000010000000b0b0d0f030507090'},
{'106020602090307050a050d060b060e0'}},
{{'1000d0000000a000400070000000d000'},
{'0000f0d0100050f00000b09070001030'},
{'30f060008000b0f010f060008000d0f0'}},
{{'10000000d000500030000000b0007090'},
{'d0d000001000500000000009300070bb'},
{'10e020c0400000ee600070009000bbbb'}},
{{'100000a00080000020a0c0e040006000'},
{'00e0100000a0200000c0400000006080'},
{'70e0e0e090f0f0f01000200040c060b0'}},
{{'1000f0005000b0003000d00070009000'},
{'00debee070008a504000001000a020b0'},
{'900070b000006000ce10000040002000'}},
{{'10f0e0e040c0c0b010b0909020706070'},
{'000000001000800000000000c0004000'},
{'1000108000b000300030d06000800000'}},
{{'100000305000007070d000909000b0d0'},
{'000090f0b0001050000070f0d0f03050'},
{'10000020b0007000000060c0400090e0'}},
{{'1000900040c0b0e01000200060007000'},
{'0000000010709030d050b0b010000090'},
{'d0d07000b0b05000b0b0300090901000'}},
{{'100030007000d0003000d00050b00090'},
{'0000f00010b030d00000f000b06080d0'},
{'90901000b0b0300070501000d0d030f0'}},
{{'1000d0003000f0306000b00030f080f0'},
{'10b0000020b000400070c00060e00090'},
{'90c01000b0c0200000600070e0e040e0'}},
{{'10002000404000b05070d0505080adde'},
{'0000000e0000100e00f000468aa020c0'},
{'1010444400dddd00404077777000aaaa'}},
{{'6000010040000e0070000200c0090b00'},
{'10000900b0000200700f06cc400c07e0'},
{'1000040060000200a0000c0080000e00'}}
}
knobMap={[1]="kickMask",[2]="snareMask",[3]="hatMask",[4]="pattern",[5]="kickRot",[6]="snareRot",[7]="hatRot"}
knobs={kickMask=7;snareMask=2;hatMask=4;pattern=1;kickRot=1,snareRot=1,hatRot=1}
-- Main clock counter
clock=1
-- The rotated clocks for each track
rotatedbd=1
rotatedsd=1
rotatedhh=1
function init()
input[1]{ mode='change',direction='rising'}
input[2]{ mode='change',direction='rising'}
for n=1,4 do
output[n].slew=0.0015
end
metro[1].event=function(c)
for i=1,7 do ii.faders.get(i) end
end
metro[1].time=0.05
metro[1]:start()
ii.faders.event=function( e,value )
if e.name>=1 and e.name<=8 then
if value>9.98 then value=9.98 end
if (e.name==4) then
knobs[knobMap[e.name]]=(quantizeToStepsDetent(value,#patterns,1))+1
-- I am quantizing faders 5 to 7 to 33 values
elseif (e.name>=5) and (e.name<=7)then
knobs[knobMap[e.name]]=(quantizeToSteps(value,33,1.1))
-- While faders 1 to 3 are constrained to 17 values so they match the range
-- of values per step in the pattern
else
knobs[knobMap[e.name]]=(quantizeToSteps(value,17,1.1))
end
end
end
end
input[1].change=function()
-- Loop to read faders 5 to 7 and get a rotation value
for j=5,7 do
if (j==5) then
rotatedbd = rotate(5)
elseif (j==6) then
rotatedsd = rotate(6)
else
rotatedhh = rotate(7)
end
end
-- Loop to read faders 1 to 3 plus the rotation value and determine if a note
-- should be played
for n=1,3 do
if (n==1) then
playdrum(1,rotatedbd)
elseif (n==2) then
playdrum(2,rotatedsd)
else
playdrum(3,rotatedhh)
end
end
if ((math.random(2)==1) and ((clock%2)==1)) then output[4](pulse()) end
-- This resets the clock once it reaches 32
if clock==32 then
clock=0
end
-- This advances the clock by 1
clock=clock+1
end
-- Removed Boost and meassure from this version but will add it again soon
input[2].change=function(s)
clock=1
end
-- Next four functions are helper functions
function quantizeToStepsDetent(value,steps,centerWidth)
local centerBottom=5-(centerWidth/2)
local centerTop=5+(centerWidth/2)
if (value < centerBottom) then
return math.floor(range(0,centerBottom,0,math.floor(steps/2),value))
elseif (value > centerTop) then
return math.floor(range(centerTop,10,math.ceil(steps/2),steps,value))
else
return math.floor(steps/2)
end
end
function quantizeToSteps(value,steps)
return math.floor(range(0,10,0,steps,value))
end
function range(min,max,newMin,newMax,value)
return newMin+(value-min)*(newMax-newMin)/(max-min)
end
function wrap(x_max, x_min, x)
return (((x - x_min) % (x_max - x_min)) + (x_max - x_min)) % (x_max - x_min) + x_min
end
-- Called to read the knob value and pick the right pattern and play or not
-- play a note
function playdrum(n,rotateddrum)
if (((patternhex(knobs.pattern,n,rotateddrum)<=(knobs[knobMap[n]]))
and (patternhex(knobs.pattern,n,rotateddrum)>0))
or (knobs[knobMap[n]]==16))
then output[n](pulse())
end
end
-- Function used to rotate wwhile constraining
function rotate(m)
knobvalue = knobs[knobMap[m]]
if (knobvalue>=0) and (knobvalue<=33) then
-- Change /2 and *2 for 4 to get eigths and 8 for quarter notes divisions
rotatedm=clock+(math.floor(knobvalue/2+0.5)*2)
-- Since we are adding to the based clock, we need to wrap the values
-- around for the pattern
rotatedm=wrap(33,1,rotatedm)
return rotatedm
end
end
-- This decodes the hex numbers in the patterns so they can be used in the
-- script as it was written by @grey
function patternhex (knobs,n,clk)
str = tostring(patterns[knobs][n][1])
fields = { str:match( (str:gsub(".", "(.)")) ) }
return(tonumber(fields[clk],16))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment