####################################################################### # Live coding for beginners - making music with FoxDot ####################################################################### # Written by Ryan Kirkbride & adapted for this workshop by Lucy Cheesman ####################################################################### # Basics ######################################################################bytearray # Before you can get started in FoxDot, you need to launch SuperCollider, and type in the following line of code: FoxDot.start # Then run that code in SuperCollider by pressing Ctrl+Enter on Windows or Cmd+Enter on Mac # To "run" code in FoxDot, put your text cursor on the line of code and press Ctrl+Enter on Windows or Cmd+Enter on Mac. # Let's start by making a drum beat! # d1 is the name we give to the player, and "play" tells FoxDot we want to use some samples d1 >> play("x-o-") # Anything you type between the speech marks will play a different sound d1 >> play("Site Gallery") # Try changing what it says! What does your name sound like? # You can stop it using 'stop' d1.stop() # Let's try adding some synth sounds too # To add a new player we just have to call it something different p1 >> pads() # p1 is the new name we've chosen, and 'pads' is the name of the synth in FoxDot. # There's a lot of synths to choose from - if you run the code below you'll see a list (watch out though, loop, play1 and play2 are something different!) print(SynthDefs) p1 >> varsaw() # Try changing the name of the synth and see if you can find one you like # ok let's stop those - Clock.clear() stops everything Clock.clear() # Let's add some notes to our player p1 >> pads([0,2,4]) # If we use round brackets instead of square, it plays the notes together p1 >> pads((0,2,4)) # Or we can use a combination: p1 >> pads([0,1,2,(3,5,7)]) # Putting a list inside of another list alternates which value is used p1 >> pads([0,2,[4,7]]) # Try adding your own numbers and experiment with the brackets to see how it sounds! # Press Ctrl+. to quickly stop everything ####################################################################### # Keywords ####################################################################### # After we set the pitch, we use "keywords" to assign other instructions - like durations p1 >> pads([0,1,2,3], dur=1) p1 >> pads([0,1,2,3], dur=1/2) p1.stop() # What happens when we use lists for pitch and durations that are not equal size? p1 >> pads([0,1,2,3], dur=[1,1/2,1/2]) # Useful keywords are "amp", "dur", "sus", "pan", "oct" p1 >> pads([0,1,2,3], dur=[1,1/2,1/2], amp=[1.5,0.5], sus=2, pan=[-1,1], oct=[5,5,5,(4,6)]) # Try changing some of the numbers or adding your own - can you figure out what's going on? # Ok - lets stop that. p1.stop() ####################################################################### # Rhythms ####################################################################### # We can make our drum pattern more complex by using brackets # The square bracket plays multiple samples in the space of one step: d1 >> play("x-o[--]") d1 >> play("x-o[---]") d1 >> play("x-o[-------]") d1.stop() # The round brackets alternates the sound used: d1 >> play("x-o(-o)") d1 >> play("x-o(-[-o])") d1 >> play("x-o(-[-(-o)])") d1.stop() # And the curly braces selects a sample at random for more variety d1 >> play("x-o{-o}") d1 >> play("x-o{-[--]o}") # You can stop it using stop! d1.stop() # Just like before we can use keyword arguments: d1 >> play("x-(-[-o])", dur=[3/4,3/4,1/2], pan=[-1,1]) # You can also change the rate the audio is played d1 >> play("x-(-[-o])", dur=[3/4,3/4,1/2], pan=[-1,1], rate=1) d1 >> play("x-(-[-o])", dur=[3/4,3/4,1/2], pan=[-1,1], rate=2) d1 >> play("x-(-[-o])", dur=[3/4,3/4,1/2], pan=[-1,1], rate=0.5) d1 >> play("x-(-[-o])", dur=[3/4,3/4,1/2], pan=[-1,1], rate=-1) d1 >> play("x-(-[-o])", dur=[3/4,3/4,1/2], pan=[-1,1], rate=[1,2,0.5,-1]) d1.stop() # We can use cut to slice our samples down (this can be useful if we're using long samples and we don't want them to overlap): d1 >> play("1V2V") d1 >> play("1V2V", cut=0.5) print(Effects) # To play things at the same time, just use multiple Players. p1 >> pads([0,2,4,9,7], dur=1/4) d1 >> play("x-x-") d2 >> play(" * ") # To stop everything, press "Cmd+." or run the line of code below. Clock.clear() ####################################################################### # Adding and sequencing effects ####################################################################### # We can also add effects to the players l1 >> blip(dur=4) l1 >> blip(dur=4, echo=0.5) l1.stop() # Could you hear the difference? Below are some other effects to try out. # High Pass Filter - only lets frequencies *above* this value into the signal d1 >> play("x-o-") d1 >> play("x-o-", hpf=500) d1 >> play("x-o-", hpf=5000) d1 >> play("x-o-", hpf=[0,100,250,500,1000,2000,4000,8000]) d1.stop() # Low pass filter - only lets frequences *below* this value into the signal d1 >> play("x-o-") d1 >> play("x-o-", lpf=5000) d1 >> play("x-o-", lpf=500) d1 >> play("x-o-", lpf=[50,100,200,400,800,1600,3200,6400]) d1.stop() # Chop - chops the signal into "n" parts p1 >> pluck([0,4], dur=4, chop=4) p1 >> pluck([0,4], dur=4, chop=8) p1 >> pluck([0,4], dur=4, chop=320) p1.stop() We can also chop a sample: d1 >> play("1 2 ") d1 >> play("1 2 ", chop=8) d1.stop() # -- Sustain is how long a note is held for # -- What happens when you use a different sustain than duration? p1 >> pluck([0,4], dur=[3/4,3/4,1/2], chop=4) p1 >> pluck([0,4], dur=[3/4,3/4,1/2], chop=4, sus=2) p1.stop() # Shape - wave shape distortion b1 >> bass(dur=4, shape=0) b1 >> bass(dur=4, shape=0.5) b1 >> bass(dur=4, shape=[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]) # -- Try combining different effects in the same player (room and mix and reverb): b1 >> bass(dur=4, shape=[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0], chop=16, room=0.5, mix=0.2) # Try changing the values and adding your own effects # Remember you can stop a player by using the name of the player and .stop() b1.stop() # Or you can stop everything using Ctrl+. or Clock.clear() Clock.clear() ####################################################################### # Let's make a tune! ####################################################################### # All of the timing is handled by "Clock" and we can change the tempo if we want Clock.bpm = 144 # Let's make a basic tune # 1. We can start with a simple drum beat d1 >> play("x ") # 2. Add a bassline b1 >> sawbass([0,-1,3], dur=[4,4,8]) # 3. Let's add some chords - we can make sure they fit with the bass by setting the pitch relative # to the pitch of the bass, b1, using the + sign). p1 >> star(b1.pitch) p1 >> star(b1.pitch + (0,2,4)) p1 >> star(b1.pitch + (0,2,4), dur=[3/4, 3/4, 1/2]) # 4. Create you own melody to go with it - pitch a SynthDef print(SynthDefs) # e.g. blip # e.g. p2 >> blip([0,7,6,4,2], dur=1/2, sus=1) p2 >> blip([0,7,6,4,2], dur=1/2, sus=1) # 5. Let's add to our drums. Try making this more complex by using the different brackets d1 >> play("x-") d2 >> play(" * ") # What happens to our chords if we change the bass? b1 >> sawbass([2,3,4,6], dur=4) # Challenge time! Use "room", "chop", "hpf", "lpf", and "shape" in the tune we # worked on to customise your sound and add your own bit of flair. # Feel free to copy and paste from the examples if you're not sure of the syntax # You can always change some parameters # Or if you're feeling brave just go for it! # Press Cmd+. to stop playing or Clock.clear()