# Designing Instruments with SuperCollider > KnowVember Day 3 - An exploration of techniques for crafting drums and synths **Published by:** [mxjxn musings](https://paragraph.com/@mxjxn/) **Published on:** 2023-11-04 **URL:** https://paragraph.com/@mxjxn/knowvember-3 ## Content In last nights post I demonstrated how you can use external data (the blockchain) to control the events of a supercollider musical routine. But what that article had in technical insights, it lacked in musicality. So in this article we will remedy that by designing some instruments and testing them out with some musical patterns.Designing instruments with codeAny band worth listening to has a variety of instruments that play different roles and occupy different sonic ranges. The drums and bass guitar provide the backbone of the music by setting the tempo and energy levels, and giving a foundation for the melodic instruments to build on top of. The guitar and keys are both percussive instruments that occupy a more mid- to high-frequency sonic range. However this isnt a band. This is all going to be synthesized. Its electronic music, so we can get more creative with our instrumentation. Heres a short list of Percussion instruments I'd like to define with code for later use:Soft and Hard Kick, Snare, High hat, Toms, ClapAnd for melodic parts, we'll need a few more Synthdefs from which we can make different instruments:Frequency Modulation (FM) SynthKarplus-Strong (Plucked string) SynthGranular synth (for textures)Subtractive synth (like your usual classic synthesizer)Additive synth (like an organ with different harmonic tones added together)Drone synth with feedbackThat is more than enough to start with. Realistically we dont need all of these - a well designed FM synthdef could alone possibly emulate the entire band. So for today, I'll focus on making a versatile FM synthesizer.Starting with some drumsKick DrumSynthDef(\mx_kick, { arg out = 0, freq = 60, dur=0.3, pitchDur = 0.03, pitchDepth = 0.9, gate = 1, amp=0.6 , noiseAmp=0.03, drive=1; var ampenv, pitchenv, sig; ampenv = EnvGen.kr(Env.perc(0.01, dur, amp, -4), gate, doneAction: 2); // main kick tone, with a pitch envelope sig = LFPar.ar( freq + Line.kr(pitchDepth * freq, 0, pitchDur), 0, ampenv); // Adding a little click to the kick sig = sig + ( WhiteNoise.ar(ampenv * noiseAmp) * EnvGen.kr(Env.perc(0.005,0.01)) ); sig = sig * drive; sig = sig.tanh; Out.ar(out, sig ! 2); }).add;A good kick drum synth has a few elements to it. A basic tone is the foundation. Rather than a clean sine-wave, I prefer a low-frequency LFPar to a SinOsc because it has more harmonic structure and can be filtered and overdriven with better results. A kick drum sound will also have that kick at the beginning, so we will need a pitch envelope and an amplitude envelope. In addition, lets add a little click for extra percussion, and handle overdriven sounds at the end with tanh. Then we can use this single kick drum SynthDef to make several different types of kicks: clicky clean short kick: Synth(\mx_kick, [\dur,0.23, \pitchDepth, 4, \pitchDur, 0.02, \noiseAmp, 0.1]) Shallow pitched long kick: Synth(\mx_kick, [\dur,1, \pitchDepth, 0.2, \pitchDur, 0.2]) Hardcore kick: Synth(\mx_kick, [\dur,1, \pitchDepth, 0.2, \pitchDur, 0.4, \drive, 30])Snare DrumSynthDef(\snare, { |out=0, toneFreq=180, noiseMix=0.5, decayTime=0.2| var env, tone, noise, sig; env = Env.perc(0.005, decayTime, 1, -4).kr(2); tone = SinOsc.ar(toneFreq, 0, env); noise = WhiteNoise.ar(env); sig = Mix([tone, noise * noiseMix]); Out.ar(out, sig ! 2); }).add;This snare is a simple mix of a sine tone and noise, with a controllable tone freq, mix, and decay time. You can test out different snare sounds with Synth like we did with the kick drums.Hi-hatSynthDef(\hihat, { |out=0, freq=7500, rq=0.2, decayTime=0.1| var env, noise, sig; env = Env.perc(0.001, decayTime, 1, -4).kr(2); noise = WhiteNoise.ar(env); sig = BPF.ar(noise, freq, rq); Out.ar(out, sig ! 2); }).add;Tom (or a simpler kick)SynthDef(\tom, { |out=0, freq=70, decayTime=0.6, depth=0.2, pitchDur=0.2| var env, sig; env = Env.perc(0.01, decayTime, 1, -4).kr(2); sig = LFCub.ar( freq + Line.kr(depth * freq, 0, pitchDur), 0, env); Out.ar(out, sig ! 2); }).add;ClapSynthDef(\clap, { |out=0, decayTime=0.1| var env, noise, sig; env = Env.perc(0.001, decayTime, 1, -4).kr(2); noise = WhiteNoise.ar(env); sig = CombN.ar(noise, 0.2, [0.093, 0.04]); Out.ar(out, sig ! 2); }).add;The CombN is a delay line which simulates the clap by repeating the percussive noise sound. This is a very simple and not especially great clap sound to be honest, but its something to work with for now.The FM SynthSynthDef(\simpleFM, { |out = 0, gate = 1, freq = 440, carAmp = 0.5, modFreqRatio=2, modAmp = 0.3, attackCar = 0.01, decayCar = 1, sustainCar = 0.3, releaseCar = 0.5, attackMod = 0.01, decayMod = 1, sustainMod = 0.3, releaseMod = 0.5| var modulator, carrier, modEnv, carEnv, sig; // Envelopes for modulator and carrier modEnv = EnvGen.kr(Env.adsr(attackMod, decayMod, sustainMod, releaseMod), gate, doneAction: 2); carEnv = EnvGen.kr(Env.adsr(attackCar, decayCar, sustainCar, releaseCar), gate, doneAction: 2); // Modulator oscillator modulator = SinOsc.ar(freq*modFreqRatio, 0, modEnv * modAmp* modFreqRatio); // Frequency is set to twice the base frequency for a harmonically related modulation // Carrier oscillator // The modulator is used to modulate the frequency of the carrier carrier = SinOsc.ar(freq + modulator, 0, carEnv * carAmp); // Combine signals sig = carrier; // Output Out.ar(out, sig ! 2); // Stereo Output }).add;This synth is a simple two oscillator FM synth with a carrier and a modulator. There are a lot of controls to it, but it boils down to controls for the amplitude envelopes for both oscillators, a frequency, and a ratio for the modulator (so if freq is 440 and ratio is 2, the modulator is 880). Rather than percussive envelopes like we used in the drums, this SynthDef uses Env.adsr which sustains until the gate ≤ 0. Gate is sort of a special control name that allows a node to use the release method. Heres an example of it in action:( // run this block to hear the FM synth x = Synth(\simpleFM, [ \freq, 140, \modIndex, 2, \carAmp, 0.6, \modAmp, 1008, \attackCar, 0.01, \decayCar, 0.5, \sustainCar, 0.7, \releaseCar, 1, \attackMod, 0.02, \decayMod, 0.4, \sustainMod, 0.5, \releaseMod, 1 ]); ) // run the following line to release it x.release;Testing all the sounds togetherUsing Pattern classes, we can sequence several patterns in parallel that use our new instruments.// Ensure all SynthDefs are loaded before running this. ( Ppar([ // Kick pattern: plays 4 dotted quarter notes and then 4 quarter notes Pbind( \instrument, \mx_kick, \dur, Pseq([0.25],inf), \amp, 0.28, \freq, Pseq(([60, \r, \r, 60, \r, \r, 60, \r, \r, 60, \r, \r, 50, \r, 50, \r]).flatten, inf), \pitchDepth, 0.2, \pitchDur, 0.4, \drive, 30 ), // Snare pattern: plays on the 2nd and 4th beat of every measure Pbind( \instrument, \snare, \dur, 1, \amp, 0.5, \toneFreq, 180, \noiseMix, 0.5, \decayTime, 0.2, \freq, Pseq([\r, 180, \r, 180], inf) ), // Hi-hat pattern: plays on every offbeat Pbind( \instrument, \hihat, \dur, 0.5, \amp, 0.3, \freq, 7500, \rq, 0.2, \decayTime, 0.1 ), // Tom pattern: plays on the second beat of every measure Pbind( \instrument, \tom, \dur, 0.5, \amp, Pseq([\r, 1, \r, \r],inf), \freq, 70, \decayTime, 0.16, \depth, 0.2, \pitchDur, 0.2 ), // Clap pattern: plays on the 3rd beat of every measure Pbind( \instrument, \clap, \dur, 0.5, \amp, 0.5, \decayTime, 0.051, \freq, Pseq([\r, \r, 1, \r], inf) ), // melody pattern plays a series of rising chords. // the +.t adverb operator is some syntax sugar to get an array of arrays. Pbind( \instrument, \simpleFM, \note, Pseq([0,2,4,5,8]+.t [0,4,7], inf), \modRatio, 2, \dur, 0.75, \carAmp, 0.3, \modAmp, 508, \attackCar, 0.01, \decayCar, 0.5, \sustainCar, 0.7, \releaseCar, 1, \attackMod, 0.02, \decayMod, 0.4, \sustainMod, 0.1, \releaseMod, 1 ) ]).play; ) // run this to speed it up a little bit. TempoClock.default.tempo = 1.5ConclusionWe have used SynthDefs to prepare some instruments ahead of time for using in future compositions and experiments. Making a good synthdef can be time consuming, and its always good to have a few at the ready ahead of attempting any musical livecoding routines. To learn more about this topic, take a look at the following help files:SynthDefUnit Generators and SynthsA Practical Guide to Patterns, Events, and Streams See you tomorrow for the continued experiment in livecoding music! ## Publication Information - [mxjxn musings](https://paragraph.com/@mxjxn/): Publication homepage - [All Posts](https://paragraph.com/@mxjxn/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@mxjxn): Subscribe to updates - [Twitter](https://twitter.com/mxjxn): Follow on Twitter ## Optional - [Collect as NFT](https://paragraph.com/@mxjxn/knowvember-3): Support the author by collecting this post - [View Collectors](https://paragraph.com/@mxjxn/knowvember-3/collectors): See who has collected this post