; Splat.csd
; Written by Iain McCurdy, 2014.
;
; Left click somewhere within the swarm to splat the flies.
; Left click again somewhere within the field of splatted flies to unsplat them and bring them back to life.
;
; Population - the number of flies in the swarm
; Liveliness - the speed with which flies will move about within the swarm
; Excursion - how far flies will move away from the centre of the swarm, therefore this also defines the area covered by the swarm.
; Fly Size - doesn't affect the physical size of flies but instead affects the central frequency of the buzzing tone they produce.
; Swarm Speed - the speed with which the swarm moves around the panel. The swarm can exit the panel completely.
;
; If the swarm area (excursion) is very small it can become difficult to splat (and unsplat) it.
; If this becomes a problem, simply raise the value for excursion, even while the swarm is splatted.
form caption("Splat!"), size(1000,530), colour(230,230,230),guirefresh(64), pluginid("Splt")
image bounds(0, 0, 0, 0), colour(white), shape(ellipse), widgetarray("fly",500)
numberbox bounds( 5,495,60,34), channel("Population"), range(1,100, 10,1,1), textcolour(black), fontcolour(black), text("Population"), colour(white)
numberbox bounds( 70,495,60,34), channel("Liveliness"), range(0.1,10.00, 4,1,0.1), textcolour(black), fontcolour(black), text("Liveliness"), colour(white)
numberbox bounds(135,495,60,34), channel("Excursion"), range(2,300, 50,1,1), textcolour(black), fontcolour(black), text("Excursion"), colour(white)
numberbox bounds(200,495,60,34), channel("FlySize"), range(2,12, 5,1,0.001), textcolour(black), fontcolour(black), text("Fly Size"), colour(white)
numberbox bounds(265,495,80,34), channel("SwarmSpeed"), range(0.1,10, 0.3,1,0.001), textcolour(black), fontcolour(black), text("Swarm Speed"),colour(white)
label bounds( 0, 0, 0, 0), text("Click swarm to splat. Click again to unsplat."), align(centre), fontcolour(white), identchannel("instructions1") ; Instructions
label bounds(350,519,100, 10), text("Iain McCurdy 2014"), align(left), fontcolour(0,0,0,150)
-n -dm0
sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1
seed 0
giPanelWidth = 1000
giPanelHeight = 530
gisine ftgen 0,0,131072,10,1
giMaxFlies = 500
; UDO that provide different portamento times whether a value is rising or falling
opcode SwitchPort, k, kkk
kin,kUpPort,kDnPort xin
kold init 0
kporttime = (kin=(kOffX-kExcursion) && kMOUSE_X<=(kOffX+kExcursion) && kMOUSE_Y>=(kOffY-kExcursion) && kMOUSE_Y<=(kOffY+kExcursion) then
kSplat = (kSplat==1?0:1)
endif
; Call UDO for moving fly and creating buzzing sound
if changed:k(gkPopulation)==1 then
reinit ChangedPopulation
endif
ChangedPopulation:
aMixL,aMixR Fly kSplat,kExcursion,kLiveliness,koct,kFlySize,kOffX,kOffY,i(gkPopulation)
rireturn
kenv linseg 0,4,1 ; initial rise in amplitude
aMixL *= SwitchPort((1-kSplat),0.5,0.001)*kenv ; turn audio on an off according to splat status. When splatted audio is interrupted suddenly, when unsplatted audio rises more slowly.
aMixR *= SwitchPort((1-kSplat),0.5,0.001)*kenv ;
outs aMixL,aMixR ; send audio to outputs
clear aMixL,aMixR ; clear audio mix variables
endin
instr 10 ; hide all flies
iCount = 1
while iCount<=giMaxFlies do
Sid sprintf "fly_ident%d",iCount
chnset "bounds(-100,-100,0,0), colour(0,0,0,0)",Sid
iCount += 1
od
endin
instr 20 ; graphically splat flies
event_i "i",21,0,0.1 ; call instrument that produces the sound effect
iCount = 1
while iCount<=giMaxFlies do
isize random 4,20 ; splat size randomised
ialpha random 80,180 ; alpha (transparency) randomised
ired random 30,150 ; add in a random amount of red to give it a bit of gore
Smess sprintf "size(%d,%d), colour(%d,0,0,%d)",isize,isize,ired,ialpha ; create message for graphical splat
Sid sprintf "fly_ident%d",iCount
chnset Smess,Sid ; send message to the fly widget
iCount += 1
od
endin
instr 21 ; splat sound effect
idur scale_i rnd(1)^2,0.15,0.08 ; random duration
p3 = idur ; assign to p3
imin random 8,10 ; minimum frequency for splat filter (in oct)
anoise dust2 10,100*gkPopulation ; some crackly noise, the density of which is dependent upon the fly population
kcf random cpsoct(imin),cpsoct(imin+3) ; cutoff frequency is a random function moving to a new value every k-cycle
anoise moogladder anoise,kcf,0.7 ; filter the crackly noise using moogladder to give it a bit of squelch
anoise buthp anoise,200 ; highpass filter to remove some of the lower frequencies
aenv expon 1,p3,0.1 ; amplitude envelope which will give the splat sound a percussive shape
anoise *= aenv ; apply envelope
outch 1,anoise ; send this signal to the left channel
anoise dust2 10,1000 ; repeat for the left channel. Doing both channels completely seperately create a nice stereo effect
kcf random cpsoct(imin),cpsoct(imin+3)
anoise moogladder anoise,kcf,0.7
anoise buthp anoise,200
aenv expon 1,p3,0.1
anoise *= aenv
outch 2,anoise
endin
instr 1001 ; Print and then hide instructions
kMOUSE_DOWN_LEFT chnget "MOUSE_DOWN_LEFT" ; sense left click
kEscapeTrig trigger kMOUSE_DOWN_LEFT,0.5,0 ; trigger of left click is pressed
krel release ; release flag - normally 0, 1 at note release
kalpha transeg 0,0.2,4,255,p3-0.4,0,255,0.2,-4,-1 ; colour alpha channel: fades in, holds, fades out
if metro(ksmps)==1||krel==1 then ; peg updates or interrupt if mouse has been clicked
Smess1 sprintfk "bounds(%d,%d,400,17), fontcolour(0,0,0,%d)", (giPanelWidth*0.5) - 200, (giPanelHeight*0.5)-10, kalpha*(1-krel)
chnset Smess1,"instructions1"
endif
ktime times ; note elapsed time in seconds
if trigger(ktime,p3-0.2,0)==1||kEscapeTrig==1 then ; if time is up mouse has been clicked...
event "i",1,0,3600*24*7 ; start swarm
turnoff
endif
endin
i 1001 0 3 ; Instructions fade up then down (currently not working)