You are on page 1of 320

Computer Music

With Examples In
SuperCollider (3.6.5) and Logic Pro (9)



David Michael Cottle



Thursday, July 11, 2013


2
Table of Contents
Table of Contents 2
SuperCollider Examples 8
Table of Figures 10
1. The Introduction 11
OS X (10.8) 11
Logic Studio 11
SuperCollider 11
Max/MSP 11
Amadeus Pro 11
Target audience 12
Logic Pro Certification 12
Terms of Use 12
Content, Format, Conventions 12
Legal Stuff 13
2. OS 10.x 14
The Finder 14
A Finder Window 14
Power 15
System Preferences 16
Documents, Folders, and Info 16
Storage Devices 17
Server Space 17
Sessions and Assets 18
OS X Survival 18
Exercises 20
3. Logic Pro Quickstart 21
New Project 21
Video Overdub 22
I/O Buffer Size 22
Comping 23
Apple Loops 24
Looping 25
Mix 25
Automation 25
Audio, Instrument, and MIDI 26
Inserts 26
Bounce 27
Exercises 27
4. The Nature of Sound 28
Vibration 28
Patterns, Periods, and Noise 28
Frequency, Duration, and Tempo 29
Amplitude 31
Shape 31
EQ 32
Phase 33
Velocity and Wave Length 33
Expression 33


3
Exercises 35
5. Music Languages 37
Binary, Hex, Decimal 37
Frequency 38
Cents 39
MIDI 39
XML 40
Pitch Class, Intervals, Notation 40
PDF and Screen Shots 41
AIFF, Wave, MP3, AAC 41
Sample Rate and Bit Depth 42
File Size 43
Exercises 45
6. Mics, Cables, Placement 47
Connectors and Cables 47
Microphone Types 48
Microphone, Cable Care 48
Mic Placement 49
Proximity 50
Phase 51
Axis 51
Exercises 52
7. Recording Techniques 53
Stereo/Mono 53
Overdubbing 53
Big Mono 53
Patterns, Stereo Pairs 54
Sample Rate 55
Noise 56
Balanced Cables 57
Distortion 58
Optimum Levels 58
Aliasing 59
Edits 60
Optimum Engineering 61
Exercises 63
8. The Way Music Works 65
Meter 65
Harmony and Melody 67
Music is Math 69
Quality of Music 70
Set Theory 71
Consonance and Dissonance 72
Tuning 74
Pythagorean Comma 74
Tuning by Ear 75
Music is 76
Exercises 77
9. Mix: Style, Dimension 79
Music, and Machines 79
Mix Styles 79
Mix Dimensions and Elements 80


4
EQ and Filtering (Height) 81
Boost, Sweep, Cut 84
Noise Reduction Algorithms 84
Panning (width) 84
Compression 85
Reverbs and Delays 87
Doubling Delay 88
Synced Delays 88
Asynchronous Delays 89
Chorus 89
Serial Routing 89
Exercises 90
10. Auxiliaries 91
Signal Chain 91
Groups 91
Busses and Auxiliary Routing 92
Sub-masters 92
Parallel Effects 94
Freezing and Distributed Processing 96
Auxiliaries for Monitors 96
Exercises 98
11. Adding Sound Effects 100
London Effects 100
Media/Library, Shortcuts, User Settings 100
Delay Designer 100
Evoc 20 Filterbank 101
Evoc 20 TrackOscillator 101
Spectral Gate 101
Flanger, Modulation Delay, Phaser 101
Ring Shifter 101
Side Chains 101
EVOC 20 PolySynth 102
Spatialization 102
Automation 103
Latch 104
Exercises 105
12. Review, Examples 106
Review Session 106
Electro-acoustic mix 109
Examples and Analyses 109
Exercises 112
13. SC 3 Quick Start 113
SC Intro 113
Hello World 114
Error messages 116
Elements of Code 116
Enclosures (parentheses, braces, brackets) 117
Arguments 119
Object.Message 119
Exercises 121
14. Concrte Procedures 123
Concrte 123


5
Looping 124
Pitch and Time Shift 125
Reversal 125
Abrupt Edits 125
EXS24 125
UltraBeat 126
Concrte using SC 127
Envelopes 129
Variables, Frequency and Duration 129
User Defined Arguments 131
Multi-Channel Expansion 132
Experiment 133
Exercises 134
15. SC to Logic 135
KeyState.kr 135
Recording to Disk 136
SC to Logic using Soundflower 137
Real-Time Analysis 139
Come Out 139
Granular Synthesis 142
Sequenced Granular Synthesis 143
Exercises 144
16. Wave Generators 145
Frequency, Amplitude, Timbre 145
Voltage Control 145
Scale and Offset 146
Precedence 148
Keyword Assignment 149
Vibrato 150
Unipolar/Bipolar 152
Audio UGen, Control UGen (Carrier, Modulator) 153
Theremin 154
Exercises 155
17. Sources of Control 156
Periodic Waves 156
VCA 157
Aperiodic Triggers, Complex Envelopes 158
Dseq 160
Array.fill 161
Function Arguments 162
VCO, VCF, VCA in Logic Instruments 163
Control Sources in logic 164
Synchronized Controls 165
Exercises 169
18. SynthDef and GUIs 170
SynthDef 170
SynthDef arguments 171
GUI slider 173
Iteration 178
Synth Browser 180
Startup File 183
Exercises 184


6
19. Filtering, SoundIn 185
RLPF 185
Logic ES1, ES2 186
Complex Resonance 186
Klank 187
Bells 188
Debugging 190
Monitoring Data 192
Exercises 194
20. Phase Modulation 195
Frequency Modulation 195
Phase Modulation 198
EFM1 201
Logic Pro Modulators, Ringshifter 201
Latch (Sample and Hold) 201
Control Source Review 207
Exercises 211
21. Physical Models 212
Chaos 212
Karplus-Strong Pluck Instrument 214
Pluck 215
Physical Model Interface 216
Physical Model Results 216
Sculpture (Modeling Synth) 217
Jitter 219
MIDI Input 220
MIDI In 224
Exercises 225
22. Additive Synthes.. 226
Harmonic Series 226
Additive Synthesis 226
Syntax Shortcuts 231
Inharmonic Spectra 232
Noise 235
White and Pink Noise 236
Additive Examples 237
Synthesis Review 241
Exercises 242
23. K and A Busses 243
Audio and Control Busses 243
Auxiliary Sends. 244
Control Busses 247
Exercises 250
24. On Random Numbers 251
Computers Cannot be Random 251
Random Number Generator 252
Random Seed 253
Random Bias 258
Aleatory and Generative Composition 259
MIDI Out 260
Random Walk 261
Total Randomization 263


7
Conditional Control 265
Structural Control 267
Exercises 269
25. Computer Music 270
Speed 270
Accuracy 271
Methodical 274
Obedient and Obtuse 276
Escaping Human Bias 276
Autonomy 278
Absolute or Proportional 279
Pitch 279
Duration and Next Event 280
Next Event 281
Non-Sequential Events 281
Rhythmic Inversion 281
Pbind 282
Legato 284
Prand, Pseries, Pseq 285
Exercises 290
26. Working With Data 291
ASCII 291
12-Tone Matrix 292
Kinderstuck Variations 296
Working With Files 297
Path Names 297
Set Theory 299
Cyphers 301
Exercises 305
27. Maps, Masks, and Markovs 306
Music from Non-Musical Ideas 306
Mapping 306
Markov Process 312
Control Source Review 318
Music of the Spheres 318
Exercises 320


8
SuperCollider Examples
1.1:: Code Headings __________________ 13
7.1:: Balanced Lines ________________ 57
7.2:: Balanced Lines With Noise ________ 58
7.3:: Balanced Lines Re-Inverted _______ 58
13.1:: Hello World __________________ 114
13.2:: Hello Hal ____________________ 114
13.3:: Music Math __________________ 114
13.4:: First Patch __________________ 115
13.5:: Second Patch ________________ 115
13.6:: Balanced Formatting ___________ 118
13.7:: Arguments __________________ 119
13.8:: SinOsc defaults _______________ 120
13.9:: Experimenting with a patch ______ 121
13.10:: Rising Sines __________________ 122
14.1:: Loading an Audio Buffer _________ 127
14.2:: Pitch and Direction ____________ 128
14.3:: Loop, Playback Position, Triggers ___ 128
14.4:: Envelopes ___________________ 129
14.5:: Variables ___________________ 130
14.6:: Arguments __________________ 131
14.7:: 60 Second Phase ______________ 132
14.8:: Generative Choices ____________ 133
15.1:: Keyboard Triggers _____________ 135
15.2:: Options for Record ____________ 137
15.3:: SC to Soundflower to Logic ______ 138
15.4:: Come Out Variations ___________ 139
15.5:: Granular Synthesis ____________ 142
15.6:: Grains with Pan and Speed _______ 143
16.1:: VCO SinOsc __________________ 146
16.2:: VCO, VCF, VCA using Blip ________ 146
16.3:: Scale and Offset Examples _______ 147
16.4:: Scale and Offset Patch _________ 148
16.5:: Keywords ___________________ 149
16.6:: First Patch using Keywords _______ 149
16.7:: SinOsc poll __________________ 150
16.8:: VCO Vibrato _________________ 151
16.9:: Rate, Scale, and Offset Sliders ____ 151
16.10:: Vibrato Envelope ______________ 152
16.11:: Theremin ___________________ 154
17.1:: Wave Shapes _________________ 156
17.2:: VCA _______________________ 157
17.3:: VCA With LFNoise and Line ______ 157
17.4:: VCO, VCA With LFNoise And Line __ 157
17.5:: Aperiodic Triggers _____________ 158
17.6:: VCA and VCF Envelope __________ 159
17.7:: Dseq _______________________ 160
17.8:: Filling Arrays ________________ 161
17.9:: Array.fill counter _____________ 162
17.10:: Complex Demand Sequence _______ 163
17.11:: Synched LFO ________________ 165
17.12:: Mix.fill _____________________ 166
18.1:: SynthDef ___________________ 170
18.2:: SynthDef arguments ___________ 171
18.1:: Ad Hoc Arguments _____________ 172
18.2:: Single Slider _________________ 173
18.3:: GUI Button, Parent Window ______ 173
18.4:: Sines and Theremin with Interface _ 174
18.5:: Synth with GUI: 2666 __________ 176
18.6:: No GUI: 138 Characters _________ 178
18.7:: Array, Do, Counters ____________ 179
18.8:: Array Iteration _______________ 179
18.9:: Sliders Using Do() _____________ 180
18.10:: SynthDef.load.play ____________ 180
18.11:: Add Control Specs _____________ 182
18.12:: Modify Control Spec ___________ 183
18.13:: Startup.rtf __________________ 183
19.1:: SoundIn, RLPF ________________ 185
19.2:: RLPF With Dust ______________ 186
19.3:: Klank ______________________ 187
19.4:: Chimes _____________________ 189
19.5:: Isolate, Evaluate ______________ 190
19.6:: Safe Alternatives _____________ 191
19.7:: Post And Poll ________________ 192
19.8:: Nested Postln ________________ 192
19.9:: Formatting Posted Information ____ 193
20.1:: From LFO to FM ______________ 195
20.2:: AM Synthesis ________________ 196
20.3:: AM, FM, Bird Song _____________ 196
20.4:: FM Synthesis ________________ 197
20.5:: Complex Sets of Sidebands ______ 197
20.6:: Phase Modulator Efficiency ______ 198
20.7:: Phase Modulation _____________ 198
20.8:: PM Ratio ___________________ 199
20.9:: Voltage Controlled PM Ratio _____ 200
20.10:: PMOsc and Demand Sequence _____ 201
20.11:: Sample and Hold Patterns _______ 202
20.12:: Sample and Hold Improvisation ____ 203
20.13:: Complex Wave as Source ________ 206
20.14:: Sample and Hold, PM ___________ 207
21.1:: Sample vs. Modeled Bell _________ 213
21.2:: Karplus-Strong with CombL ______ 215
21.3:: Pluck ______________________ 215
21.4:: SynthDef and Triggers __________ 221
21.5:: Pluck and Task _______________ 222
21.6:: Logic to IAC to SC to Pluck ______ 224
21.7:: Logic to IAC to SC to Logic ______ 224


9
22.1:: Additive Saw, Square __________ 227
22.2:: Additive Graph ______________ 229
22.3:: Additive Saw Modulation _______ 230
22.4:: Syntax Shortcuts _____________ 231
22.5:: Additive Inharmonic Spectrum ___ 232
22.6:: Additive Noise _______________ 235
22.7:: Linear/White, Exponential/Pink __ 237
22.8:: Additive Synthesis Examples _____ 237
23.1:: Busses as Sub Masters _________ 244
23.2:: Three Simple Independent Synths _ 245
23.3:: Auxiliary Send Using Out and In __ 246
23.4:: Control Busses _______________ 248
24.1:: Random Seed ________________ 254
24.2:: Client/Server Seed ___________ 255
24.3:: Pick a Card, but Show Me ______ 257
24.4:: Random Bias ________________ 258
24.5:: MIDI Init __________________ 260
24.6:: Constant Monkeys _____________ 261
24.7:: Random Walk _______________ 262
24.8:: Random Walk _______________ 263
24.9:: Control Using If _____________ 265
24.10:: Range Control with If _________ 266
24.11:: More If ___________________ 267
24.12:: Structural Control ____________ 267
25.1:: Fast ______________________ 270
25.2:: Mixed Tuplets, Atonal Just Tuning 272
25.3:: I Don't Dig You Work __________ 274
25.4:: As Fast As Reasonable _________ 275
25.5:: Proportional MIDI inversion _____ 280
25.6:: Rhythmic Inversion ___________ 282
25.7:: Environment Variables and Defaults 283
25.8:: Read global library ___________ 283
25.9:: Pbind with frequency function ___ 283
25.10:: Pbind, Previous Instrument Def ___ 284
25.11:: Pitch Model for Mutation _______ 285
25.12:: Patterns ___________________ 286
25.13:: Parallel Pbinds ______________ 286
25.14:: Serialism ___________________ 288
26.1:: String as Array ______________ 292
26.2:: 12 Tone Math _______________ 293
26.3:: T and E ____________________ 294
26.4:: Kinderstuck Segment __________ 295
26.5:: Reading a File _______________ 297
26.6:: Interpret __________________ 298
26.7:: Open File __________________ 299
26.8:: Set Versions ________________ 300
26.9:: Locate Pitch Class Set _________ 300
26.10:: Cypher ____________________ 302
26.11:: To Be _____________________ 303
26.12:: Vigenere Cipher ______________ 303
26.13:: Extracting Code ______________ 304
27.1:: Pitch Map __________________ 307
27.2:: Mapping Array _______________ 307
27.3:: Extra-Musical Criteria, Pitch Only _ 307
27.4:: Text Map, Intervals ___________ 309
27.5:: Transition Table ______________ 314
27.6:: Probability chart _____________ 315
27.7:: Foster Markov _______________ 316
27.8:: Solar System ________________ 319



10
Table of Figures
Fig. 1-1 Figures Look Like This ___________ 13
Fig. 2-1 Modifier Keys for Shortcuts _______ 15
Fig. 2-2 Logic Session Folder vs. File _______ 18
Fig. 3-1 Logic's Unmodified Shortcuts ______ 21
Fig. 3-2 Comp Tracks ________________ 23
Fig. 4-1 Waves of Alternating Density ____ 28
Fig. 4-2 Periodic, Complex, Aperiodic _____ 29
Fig. 4-3 Amplitude ___________________ 31
Fig. 4-4 Wave Shape and Timbre ________ 32
Fig. 4-5 Sonogram Showing Harmonics _____ 32
Fig. 4-6 EQ Parameters _______________ 32
Fig. 4-7 Phases _____________________ 33
Fig. 4-8 Four Score __________________ 34
Fig. 5-1 Nyquist Theorem ______________ 42
Fig. 5-2 Sampled Triangle Wave _________ 42
Fig. 5-3 Low Bit Depth Terracing ________ 43
Fig. 5-4 Relative File Sizes ____________ 44
Fig. 5-5 Bulgarian Download Speeds ______ 44
Fig. 6-1 Connectors __________________ 47
Fig. 6-2 Waves Out of Phase ____________ 51
Fig. 7-1 ORTF ______________________ 55
Fig. 7-2 Bit Depth Noise ______________ 56
Fig. 7-3 Balanced Lines _______________ 57
Fig. 7-4 Saturation, Clipping ___________ 58
Fig. 7-5 Aliasing ____________________ 59
Fig. 7-6 Non-Zero Crossing Edits ________ 60
Fig. 7-7 Descending, Zero-Crossing _______ 60
Fig. 8-1 Repeated Noise = Piano _________ 66
Fig. 8-2 Phase and Constructive Interference 67
Fig. 8-3 1:1 Ratio ___________________ 67
Fig. 8-4 2:1 Ratio ___________________ 68
Fig. 8-5 3:2, 4:3 Ratios _______________ 68
Fig. 8-6 Constructive, Destructive Waves __ 69
Fig. 8-7 Interval Ratios _______________ 69
Fig. 8-8 Comparative Dissonance ________ 72
Fig. 8-9 Patterns of White Key Intervals __ 73
Fig. 8-10 Movable Frets _______________ 75
Fig. 9-1 Channel EQ ___________________ 81
Fig. 9-2 Clean Sine Wave From Low Roll Off 82
Fig. 9-3 Sonogram Of R, K _____________ 83
Fig. 9-4 Pan, Balance, Directional Mixer ___ 85
Fig. 9-5 Gain Control, Mono ____________ 85
Fig. 9-6 Compression and makeup gain ____ 86
Fig. 9-7 NY, LA, Classical Styles ________ 87
Fig. 9-8 Reverb ____________________ 88
Fig. 9-9 Slap Echo, Doubling ___________ 88
Fig. 9-10 Channel Strip, Serial Signal Flow _ 89
Fig. 9-11 Signal Flow _________________ 90
Fig. 10-1 Sub-Masters ________________ 93
Fig. 10-2 Reverb Mix vs Dry Mix _________ 94
Fig. 10-3 Auxiliary Sends vs. Sub-masters __ 95
Fig. 10-4 Routing for Headphone Sends ____ 97
Fig. 11-1 Loop Browser _______________ 100
Fig. 11-2 Channel Strip Focus __________ 100
Fig. 11-3 Binaural Panner _____________ 103
Fig. 11-4 Automation Menu ____________ 103
Fig. 11-5 Multiple Timelines ____________ 104
Fig. 13-1 SuperCollider IDE Shortcuts _____ 113
Fig. 13-2 Error Message _______________ 116
Fig. 13-3 Matched Enclosures ___________ 117
Fig. 14-1 UltraBeat _________________ 127
Fig. 15-1 Keycode map _______________ 136
Fig. 15-2 Server GUI ________________ 137
Fig. 16-1 Scale and Offset ____________ 148
Fig. 16-2 Unipolar Output _____________ 153
Fig. 16-3 Unipolar Scaled by 5 _________ 153
Fig. 16-4 Unipolar Offset by 100, Scaled by 5153
Fig. 17-1 Wave shapes _______________ 156
Fig. 17-2 AR, ASR, ADSR, Aussie Opera ___ 158
Fig. 17-3 Logic Voltage Control Instruments 163
Fig. 17-4 Synchronous LFOs ___________ 166
Fig. 18-1 Synth Browser Windows ________ 181
Fig. 19-1 ES1, Filter _________________ 186
Fig. 19-2 Single Pole Filter Sweep _______ 186
Fig. 19-3 Complex Resonance __________ 187
Fig. 19-4 Noise Burst ________________ 188
Fig. 20-1 LFO to FM _________________ 195
Fig. 20-2 Sample and Hold (Latch) Patterns 203
Fig. 21-1 Chaotic vs. Static Excitation ____ 213
Fig. 21-2 Chaotic Pluck Waveforms ______ 215
Fig. 21-3 FM vs. Physical Model ________ 216
Fig. 21-4 EVD3, EVD6, EXS24 Waves _____ 217
Fig. 21-5 Sculpture Interface __________ 218
Fig. 21-6 Sculpture Controls ___________ 219
Fig. 21-7 Jitter ____________________ 219
Fig. 21-8 CPU Overload ______________ 223
Fig. 22-1 Harmonic Series _____________ 226
Fig. 22-2 Additive Saw Sonogram _______ 228
Fig. 22-3 Additive Sine Scope __________ 228
Fig. 22-4 Additive Sine, Random Phase ___ 228
Fig. 22-5 Additive Saw Modulation ______ 230
Fig. 22-6 1000 Sines vs. 100 PM Osc's ____ 236
Fig. 24-1 A Million Random Digits (Excerpt) 251
Fig. 24-2 When Repeated, Not Random ___ 252
Fig. 26-1 Set Theory Clock ____________ 300





11
1. The Introduction
Which starts from the beginning. First year tech students.
This text begins with OS X, the nature of audio, different qualities of audio and best
practices for recording, mix elements, styles and techniques. It then applies those techniques in
Concrte and electro-acoustic projects, and synthesis techniques with examples in Logic Studio,
Amadeus Pro, and SuperCollider.
OS X (10.8)
is invariably the choice of professional musicians. The reasons are sometimes personal
and subjective, such as pride, erudition and loyalty, but many are practical; compatibility,
stability, interface, hardware consistency, security, and software. Resistance is futile. Logic
Studio is only available on OS X, but knowledge and techniques are transferable. Amadeus Pro
and SC (as insiders call it) works on a number of platforms, but I won't address the differences.
Logic Studio
has come to dominate new composition at academic institutions. I believe it's the
future. Other developers now follow their lead (with no external hardware requirement, comping
features, on board instruments and plug-ins), or certainly will (physically modeled instruments
and reverbs).
SuperCollider
is open source, with a dedicated cult of contributing international geniuses. It is
powerful and deep, with a solid academic pedigree; the logical progeny of Music N languages,
including Csound. You can do things right away, but will spend years, maybe even a lifetime
mining the possibilities.
But ultimately, it's the sounds. Twenty years ago I launched SC 1 and hit command-r and
was immediately hooked by the rich textures. You can do everything, including that new,
previously unknown method of synthesis you are going to invent.
Max/MSP
is the other (and probably more common) choice for electro-acoustic composition.
The key difference between the two is code (lines you write and execute), vs GUI (icons you
drag around and connect with lines). They both have a steep learning curve, but SC, once
mastered, is more flexible and versatile. As with any user interface, including Logic Pro, you
will always be limited to the choices on the GUI. I've composed with and taught these courses
using all three, and SC is now my first choice for teaching and exploring new ideas.
Amadeus Pro
is an inexpensive, full-featured, two track digital editor. Many of the examples and
figures in this text were generated in Amadeus, and we will use it in the early chapters for audio
experiments.



12
Target audience
is second year music tech and composition students with no previous experience with
synthesis or code. Knowing music or programming might be handy, but not necessary. The
topics assume some individual research and reading. Each of these programs has an online
manual and help files that you will need to dig into. My goal is not to teach the applications
themselves, but rather synthesis, quality audio, and computer assisted composition with step-by-
step examples using one or more of these tools. The same is true for music theory topics. For
example, 12-tone theory receives only a brief description, then we dive into examples using SC.
Most of the SC examples, while interesting, are not performable works. I offer them as
starting points, illustrations, ideas that can be expanded into full-fledged performances. While I
try to represent a broad spectrum of techniques and styles, they do lean toward generative,
minimalist, aleatory, algorithmic, and abstract methods.
Logic Pro Certification
is not a priority. Though I am T3 certified (certified to train trainers), preparing you
for certification is not the goal of this text. The certification people are very picky about terms,
and the exam is hard, really hard, I-failed-by-0.3%-during-my-second-certification hard. To
certify you need to study the official certification text, page by page. You can assume there is a
very specific question taken from every page of the text. For example, the white line with the
green triangle at the top: Is that a playback bar, a scroll bar, a playhead, a scroll position, a
playback cursor, an edit cursor, a select tool, a position locator, or a reflex phase induction
modulator unit? You have to know. And rightly so. If you're certified you should be able to offer
user support over the phone away from a computer. That means knowing where everything is
and the correct terms for everything on the screen.
Terms of Use
reflect these goals: First and foremost I want this text to be used by as many people as
possible, so as to generate feedback to improve it for my own use. I prefer it remain digital but
also am opposed to DRM. You can share it with colleagues as you might lend a hard cover text.
But if you use it regularly, purchase the original. I'll try to keep the cost within a graduate
student's lunch budget. Benefits of buying (aside from encouraging me to continue) include
being on the mailing list for notifications of updates, and TBD extras such as the answers to
assignments, access to code files, corrections, more detailed break downs of patches, and links to
podcasts of lectures and assignments.
Examples in these chapters are designed to push the envelope. Turn down monitors
before trying something unusual. I take no responsibility for damaged gear, locked up machines,
corrupted systems, missed meals, incensed co-habitants or startled pets.
Content, Format, Conventions
The text is divided into two sections. Chapters 112 focus on Logic Pro, the goal being
a multi-track mix in a popular style. Chapters 1329 build on this foundation with electro-
acoustic composition topics. The first half teaches how to capture, compile, organize, and
compose elements of composition. The second digs into the sounds themselves, creating the raw
materials from scratch. We split these two sections into a year course, a semester each.




13
Section Headings are in Bold
and part of the next or previous sentence, for really no good reason. Text that you
should read quietly to yourself is in the Times font with no other formatting.
Bold text indicates items on the computer screen; Save As under the File menu,
Freeze in the contextual menu, or the Sample Editor button.
Keys that you need to find and press on the keyboard are bracketed (to imitate a square
key): [A], [ [ ] [return], [I]. They are spelled and capitalized as they appear on the key.
Keyboard shortcuts are identified by the preceding modifier; !R. Modifier keys are: !
(command) " (shift) # (option) $ (control).
Italics are used to offset code in the paragraphs you read quietlybizarre looking words
or phrases such as SinOsc.ar, LFNoise0.kr(1, 0, 100)but also normal looking words
that have a particular meaning, different from their normal meaning, such as the variable
myString, the argument offset, the if, play, or do message. Numbers taken from code
examples are not italicized (because they have an intrinsic meaning), unless they are
parameters inside a section of code. Italics are also used for emphasis or introduction of a
new term: The frequency of a wave is different from its output. Changing the range of
output is called scaling.
Some common SC terms, that stand on their own, are not italicized, but often capitalized
such as UGen, Synth Server.
Fig. 1-1 Figures Look Like This
Figure numbers are tiered with the chapters (see Figure 1.1)
and will float close to the text where they are
explained.
Images that illustrate a set of instructions (like
the image on the right) are not useful out of this
context, and are not labeled as figures.
! Paragraphs with information that may appear on an exam are
check marked.
1.1:: Code Headings
"Code intended to be run in SC appears in Chalkboard Font.".post;
"Code that is broken in the current version of SC will be crossed out.".speak;
["I", "leave", "it", "in", "presuming", "an", "eventual", "fix"].plot;

::
1:1 Exercises are tiered with chapters.
Legal Stuff
Apple screen shots reprinted with permission from Apple Inc.
Amadeus Pro screen shots reprinted with permission from HairerSoft Inc.



14
2. OS 10.x
It's Unix under the hood. Named after big cats.
The Finder
is an application like MS Word, Internet Explorer, or iPhoto. It launches automatically
when the computer boots and it remains open and running at all times. You use it to navigate the
contents of the hard drive as well as connect to and copy between other storage devices. It also
has menus and tools that change superficial preferences such as appearance, keyboard function,
screen backgrounds, but also essential preferences such as the input and output device for
recording.
A Finder Window
can be opened by pressing !N. (You can also double click on the hard drive icon or
click on the icon in the Dock.) Several finder windows can be open at once, and often need to be,
for example to drag files from one to the other. The default layout of a window has a
customizable sidebar (drag items to or off of it) with frequently visited folders and locations, a
customizable menu bar at the top, and a list of items in that folder.
You can change how the items are listed using the View menu, or
by clicking on one of the view buttons in the menu bar. I find icon view
(far left) the least useful, although with preview icons, it seems better.
Columns view shows the hierarchy of folders, but you can also turn on View/Show Path Bar
and the path will be displayed at the bottom. I prefer list view or cover flow because they show
information such as creation date and size as well as a preview. You can also have them ordered
by name, date, and size by clicking on the appropriate label at the top of each column. I keep my
folders ordered by date. This brings things Im working on to the top of the list. I switch to size if
Im cleaning up my drive.
Quick Look (space bar) is useful for auditioning audio files or peeking into documents.
Spotlight is a powerful search engine that not only looks for file names, but also inside files. In
some cases it's a little too powerfuluseless, for example, if I type in "cottle." Pretty much every
email I send has "cottle" in it, so I gravitate toward the find by name when looking for files, then
the search options in a particular application for content. That said, Ive found documents several
years old, buried deep in an archive folder by just typing a few key words of a Webern Quote:
"The further one presses." Once in spotlight, the down arrow will reveal quick looks at
documents. !-return will open the enclosing folder rather than the file itself.
If you open a search window (File/Find, or !F) you have many more options. You can
find by content or name, but also modification, type, and so on. Clicking the "+" button allows
multiple criteria. Holding down the option key (# ) while clicking the button allows combined
criteria such as "music" and "created today." You can also use keywords in both the spotlight and
find fields. For example "name:cottle kind:folder " will bring up all folders with cottle in the
name. (This looks like it needs a comma between cottle and kind, but you have to type it exactly
as it is. The name includes cottle, the kind is folder.)




15
Another great search resource is the Help menu (available in each application). It even
shows menu items. Try searching for shortcuts, covered next.
Power
users have become a Hollywood action movie clich: The (mandatory) geek character
sits at a computer and uses his special knowledge to execute a key plot point. A detail youll
notice from now on is that they never use a mouse. Before the development of graphic user
interfaces (GUI), computer commands were text based, and had to be typed out on a command
line. Once learned, they are very efficient, but at the expense of intimidating language such as ls,
grep, or -mtime +3 \\! -name '.*' -exec mv -n {} " & file_path & "/Archive/.
Command lines are faster. GUI's are accessible. Even two year olds understand an
elephant icon. The fact is you can have both. Learning shortcuts doesn't mean you have to give
up the user interface. You can have both power and accessibility, relying on the GUI when
navigating unfamiliar waters.
Fig. 2-1 Modifier Keys for Shortcuts
The fastest way to learn is to notice them next to each
menu item. Figure 2.1 shows the View/Arrange by sub-
menu. Each menu item has a shortcut. To view by icon pres
command-1. The Arrange By list of shortcuts is a nice
summary of the symbols used for three modifier keys;
control, option, and command, in that order. Other key icons
are shift ("), caps lock (%), delete, return (&), escape, and
arrows. As a matter of fact, I will often pull down the menu
just to learn or remind myself what the shortcut is, close the
menu, then use the shortcut.
! Below are the shortcuts I use most often. I suggest you try each as you read, then note the
ones you like, then review and practice them so that they become second nature.
- Type to find: In most dialogs and windows you can type a name to select an item. Also,
tab or arrows will scroll through a list of items. When I tell people this they reflexively
click in the find field. Resist the temptation, just start typing.
- Single click (select the item), double click (open the item), $ -click (contextual menu)
- !N: new finder window
- "!N: new folder in a given window
- & (return): rename a selected item
- "!A (D, O, U, or H): go to Applications, Desktop, Documents, Utilities, and Home
- !K: connect to remote device
- !O, W, Q: open, close windows, quit applications
- !', (: move into a folder, or back up a folder level
- ! delete: move to trash
- Fn delete: forward delete



16
- !space: spotlight, then !& to show item in the Finder (rather than open the item)
- ! tab and !`: rotate through applications or windows
- !1, 2, 3, 4: change view to icons, list, columns, cover flow
- !"4: snapshot of screen. Add the control key to copy the snapshot to a clipboard,
press the space bar after you get the cross hairs to isolate a window.
- Not really a shortcut, but related to screen shots, you can create a PDF of any file from
the print dialog by choosing PDF.
- Esc (cancel out of any dialog)
- Finally, though these are usually disabled, I often use the "move focus to" menu and
dock as well as full keyboard access (all controls). Look at System
Preferences/Keyboard for a more complete list or to create your own.
There are many more. The few seconds it takes to commit a command to memory pays
off quickly in terms of workflow, but also slack jawed onlookers.
System Preferences
allow customization of the computer's look and default settings. Ive discovered some
clever settings just poking around in my spare time. For example, users usually overlook
universal access. I keep sticky keys on all the time. It doesnt change the way I normally type,
and is handy for those occasional situations where youre typing with one hand. (It also displays
modifier keys on the screen during a lectures and podcasts.) Zoom is indispensable in lectures.
The preference you will interact with most often is Sound for setting the input and
playback device. I cant tell you the correct device to choose because it will change depending
on your project. In our studio we regularly switch between the internal speakers, the Mackie or
Presonus firewire return, SoundFlower, or a variety of inputs. The recording software you use
will also have a preference file that allows you to choose an input. Sometimes the software
inherits the system settings, sometimes not. Here is a real life example of not using this dialog
correctly: after spending hours setting up mics and interfaces, you check the levels and hit
record. Everything looks great. But then it sounds awful: in mono, noisy, distant. The error could
be that the input is set to the internal mic on the computer rather than the firewire mixer input.
Documents, Folders, and Info
are hierarchical; folders in folders. There are usually several ways to get to important
locations. The Desktop, for example, though immediately available by clicking on the
background, is in fact buried in the hard drive. Its in your account folder, which is in the Users
folder, which is on the Hard Disk. Folders can go pretty deep. A song in your iTunes collection
will probably have a path that is eight folders deep:
Hard Disk/Users/YourAccount/Music/iTunes/iTunes Music/Tom Waits/Greatest Hits/They are all great/But How About Swordfishtrombone
Files are documents containing data. These can be opened by double clicking, pressing
!O, $-clicking and choosing open or open with, or using File/Open from inside an application.
There are usually two or three, sometimes dozens of applications that can open and edit a
single file or file type. If you double click, the OS will use the default application. You can use




17
File/Open with, or Always Open With (using the # key) to force it to open in something other
than the default.
To move or copy a file, you can drag it to a new location (after opening both locations
and arranging the windows so that you see both). If you drag the item to a location on the same
physical device (e.g., hard disk, flash drive, server location), it moves. If another device, it
copies. Use #-drag to make a copy on the same physical device.
A faster method for copying is to select one or several items (in list view click and drag
to the right ofnot ona list of names, or use "-click to select everything between a selected
item and the one you click on, or !-click to add non-contiguous items) then press !C to copy,
navigate to the new location, then !V to paste.
It is often useful to inspect the attributes of a file (or folder) using File/Get info for a
single item, or even more useful, File/Show Inspector (hold down the # key). This window
stays open as you change your selection or add to a group of items. You can then see the size of
all items, or change attributes such as the default application, the label, or permissions.
Permissions are a part of the security of an operating system; who can read and write to
the file, who can just read, or no access at all. Most of this takes place behind the scenes, but
what is intended as a feature often interferes with the function of a multi-user lab. For example,
when a student hands in a project, or if copying an item from a shared folder, the permissions
may not transfer correctly.
Storage Devices
contain data. These include USB jump drives, CDs, internal hard drives, external hard
drives, or servers.
Unmount discs before you remove or disconnect them. You may damage the disc and in
the case of firewire drives you could damage the internal firewire card. Unmount a disk with the
eject button or by selecting it and choosing File/Eject, or by dragging it to the trash.
If you are working on one machine with one hard drive, such as your laptop, these issues
are moot. But in a multi-user lab, four out of ten students (uh, that's two fifths I guess) struggle
with storage issues all semester. If you're one of those (you know who you are), read this next
section carefully. If confident with storage management, skip to the next section.
Server Space
is a remote machine where you can store and access items from on or off campus. This
is handy when moving between machines or between labs. But don't rely on it as your master
copy. The copy you own is the one you can carry out of the classroom.
Servers are for storage, not work. You shouldn't open the file directly from the server,
particularly in the realm of audio, because the connection between the two machines is too slow
and/or the permissions may be wrong. Working from the server will result in oblique errors. By
this I mean the error dialog will not read "hey, stop working from the server." It will complain
about something seemingly unrelated, such as slow disk speed or permissions.



18
Sessions and Assets
are contained in a single session folder. Logic (as with many other programs) uses
possibly hundreds of components or assets; audio files, of course, but also instrument samples,
reverb impulses, backups, movie clips, instrument and plug-in presets, and so on. All of these are
individual files in different locations. (The advantage to this scheme is that one file can be shared
by unlimited sessions.) If you are working with only one machine in a studio, these assets can be
spread around the machine, nearly anywhere. But if you are moving from one machine to
another, as in a lab, it is important to keep all of these items together. For that reason you should
think of a Logic session not as a file, but an entire folder, with sub-folders filled with assets.
Figure 2.2 shows a Logic session folder. The session file (what you open to start
working) is named Spaceman.logic. This project has 81 tracks, many of them stereo, instrument
samples and a video. But note the size: 6.1M. That's hardly enough to hold a few Mp3 files. It's
small because the session file itself contains no audio. The audio is in the Audio Files folder.
Fig. 2-2 Logic Session Folder vs. File
This bundled approach is used for most applications
(Mail, iPhoto, Calendar, TextEdit), but the structure is buried
deep inside the application itself, chiefly to keep you from
fiddling with them. You can reveal these assets using $-click,
Show Package Contents. Even system applications are folders
with assets that you should routinely peruse and modify.
Kidding! Do not under any circumstances navigate to Hard Disk/System/Library/Core
Services/CoreTypes.bundle, and open package contents. Are you nuts? Instead, make a copy of
TextEdit on the Desktop, $-click to open its contents. Continue to dig down into
Contents/Resources to open the English.lproj/InfoPlist.strings. Open this file in any text editor
(e.g., ironically, TextEdit) and change the wording in dialogs. The brave and/or reckless
CoreServices people could check out some of the .icns files used by the OS. Use quick look to
scroll through them. These are handy when writing texts on operating systems. They could be
modified or changed, but I wash my hands of any fallout.
Logic Pro session folders have a similar structure, but it's visible, and much easier to
screw up. Just wait and see.
If you use your own personal external firewire drive you can open the sessions directly.
The connection is fast enough for audio.
! To review: Work locally (on the internal hard drive), but save remotely (to the server).
When creating Logic sessions choose Include Assets and check all assets in the save dialog.
OS X Survival
The good news is OS X is very stable. Even if the Finder locks up you can continue to
operate other programs. Beneath the interface of icons and menus is the Unix operating system,
which has been used in government and university systems, where security and stability matter,
for over 35 years. (For old school command line control launch the Terminal application. Unix is
more cryptic, but once mastered, more efficient.)
! Even with this stability, if you get past chapter 14, you will run into problems. Here is a
survival guide.




19
- Save often. Save every 15 seconds. Each day use Save As to save versions (with a
different name) so that a previous version is preserved. Saving is a knee jerk strategy
whenever I'm trying something new. Saving costs you nothing. Not saving could cost
you hours of work, maybe hundreds of dollars. The machine could die at any moment:
power failure, power manager failure, hard drive failure, motherboard failure, heck, the
instructor unplugging the wrong power chord or bumping the power strip (true story).
- Backup often. My rule of thumb is four copies, four physical locations, daily; my
laptop, a hard drive at home, a cloud, and the university's backup system. Paranoid?
Sure. I like SafeCopy and SyncSyncSync.
- Learn how to locate and read online help and manuals.
- Learn effective Googling. For example, take a
snapshot of an error dialog and use the exact wording
(especially numbers, or cryptic messages) in a search.
Thousands of people around the country have no doubt
seen that dialog, tried to trouble shoot it, and may have
posted a solution. Also search user's groups.
- Maintain a "Tech Solutions" file where you document your own solutions.
- After trying to solve the problem on your own don't hesitate to lean over and ask a
classmate or the instructor, or even fire off an email or text. I realize this feels like an
admission of incompetence, but you have to be fearless, in two ways: Dont be afraid of
looking like a novice (as I do, Im sure, on many discussion groups), or be intimidated
by the machine. It was, after all, put together by nerds. The majority of solutions I
eventually pass on to other users aren't things I knew at the time the question was asked.
They are things I learned after being asked.
- If the operating system or an application is acting strangely, you should first try saving
everything then re-launching the application or the entire system.
- Install a system monitor similar to Menu Meters or iStat Menus. Many problems first
appear as absurdly high CPU, disk, or network activity.
- Try discarding the preferences. The preferences for each application are in the folder
[yourusername]/Library/Preferences, and/or [HardDriveName]/Library/Preferences.
- If the system or an application does not respond to any commands, follow these steps:
1) Try typing !-period. This is a standard key combination for "stop." (It never
works, but I always try it.)
2) Wish you had saved more often.
3) Give the computer a time out, take a coffee break, go get lunch (don't laugh,
this works about 80% of the time). Maybe the solution is you being patient.
4) For example, networking confusion can cause both slow performance or the
spinning beach ball of death. Try turning off wireless and disconnecting
Ethernet. Networking can hypnotize applications into flakey behavior and lock
the entire system up for many, many minutes, which seems like hours.
Removing the connection often snaps them back to reality.



20
5) Force quit the application (!#-esc, click-hold on the Dock icon). This brings
up a dialog that allows you to force any application to quit.
6) Check connections. We laugh afterward, but often an unresponsive machine is
just an unplugged keyboard.
7) A moment of silence to remember the work you lost because you didn't save.
8) If it turns into a zombie, cut off its head. This is different for each design and
model, but for most machines hold the start button down for 15 seconds. If
nothing else, unplug it.
Exercises
2:1 Find and launch TextEdit, Quicktime, Amadeus Pro, Safari or Firefox, and
PhotoBooth using as many different methods as you can. Generate content in each
(i.e., record a movie, audio, take pictures, write something, connect to a site). Take
snapshots of the web page and paste it into TextEdit. Switch between the two using
!-Tab. Create a PDF of the web page. Save all to the Desktop. Force-quit TextEdit.
Select all the files and use Get Info or Inspector to examine their sizes. Use Get Info
to change the permissions and the default application for the video.
2:2 Without using the mouse: Switch to Finder, open a new Finder window, navigate to
the Desktop, create a new folder, and name it. Copy all the files you created and
paste them into the new folder. Move back to the Desktop, rename the folder, copy
it and paste it to another external device, or a server.
2:3 Open system preferences and change the desktop image, the alert sound effect, time
until the system sleeps, and input device. Also find and turn on sticky keys and one
finger tap and drag (if using a track pad). Find keyboard shortcuts and create a new
shortcut for Show Clipboard in the Finder.




21
3. Logic Pro Quickstart
Nice project for beginners: a movie soundtrack.
New Project
The first dialog after launch shows a set of templates. Be sure to explore these, but we
will start from scratch with an Empty Project. The next dialog asks for the number and type of
tracks. For now we will use 4 mono audio tracks. More can be added later. Also, the options for
each track can be changed later. If your project is a large session with a 16-channel interface,
check Ascending next to the Input menu. This will assign each track to successive inputs of the
interface.
The next thing you see is the Arrange Window. Most projects can be done with this
window. Click on Mixer (lower left) to open the mixer area. If you don't see the Media area to
the right, select the Media icon in the upper right corner.
There are five sections to the arrange window. The inspector on the left, the arrange area
with tracks and timelines, the mixer with volume sliders, the media area to the right, showing the
Library, Loops, Bin, and Browser, and the transport at the bottom.
Key presses and shortcuts such as the space bar or arrows have different meanings
depending on which area has focus. The focused area is highlighted and can be changed with the
tab key. Press the tab key a few times to see how to change focus.
You can toggle the Inspector with the icon in the upper left corner or by pressing the [I]
key with no modifier. In most text editors shortcuts include modifier keys because the
unmodified keys are require to enter text. Since most Logic operations never involve unmodified
keys (aside from changing names or numbers in text and number boxes) they are free to be used
as shortcuts. This sometimes gets you into trouble. If you start typing text, thinking you're in a
text box or the caps lock keyboard, but are in fact focused on one of the arrange areas, you will
inadvertently turn things on and off with each key press. In particular [S] and [M] will solo or
mute tracks if pressed accidentally. Figure 3.1 shows a list of unmodified shortcuts. Those I use
often are in bold.
Fig. 3-1 Logic's Unmodified Shortcuts
[1-9] screen recall
[A] automation
[B] bounce
[C] metronome
[D] delete duplicates
[E] Event List
[F] Finder (Browse)
[G] global tracks
[H] hide view (mode)
[I] inspector
[J] swap left, right locator
[K] create marker
[L] loop folders
[M] mute
[N] score editor
[O] loop browser
[P] piano roll
[Q] quantize
[R] library
[S] solo
[T] tempo list
[U] time signature
[V] plug-in windows
[W] sample editor
[X] mixer
[Y] hyper editor
[Z] track zoom
[/] cycle mode
[< >] rewind, forward

The arrange area shows a timeline with regions for each track. The mixer shows all
channel strips. The inspector shows information about items that are selected, but also two
channel strips; the one that is selected, and the next strip in the chain (chosen by contextit's



22
pretty smart). The Media, Lists, and Notes area on the upper right show the location and
disposition of assets. The bottom, of course, is the transport.
In addition to the mixer, the lower section can display the Sample Editor, Piano Roll,
Score, and Hyper Editor. Most of the areas can be opened in a separate window, if you prefer,
using the Window menu. A session can quickly become cluttered with information. Press keys 1
through 9 to recall a new screenset. Each screenset can be arranged with a particular task or
workflow in mind. Once a screenset is arranged it will retain that layout when recalled.
One of my favorite projects for illustrating the features of Logic is a
Video Overdub
with music and sound effects. Find a short segment of an action filled movie (may I
suggest a Roadrunner cartoon?) and drag it from to the arrange window. Be sure the yellow
insert region shows 1 1 1 1. Logic will ask if you want to import the
movie and extract the audio. Do both. The movie should appear in a
floating window and the audio should appear in a new track. You can
resize the video window or close it, which then moves it to the upper left
corner of the arrange window.
Save the session (maybe to the desktop). Be sure to check include assets and check all
assets.
Turn on cycle mode by pressing the cycle icon to the right of the
transport. A green bar will appear at the top of the timeline window, set to the
size of the audio region that was imported from the movie. Adjust the length of
the cycle region by dragging the end of the green bar. Mute the original audio by pressing [M]
when that track is selected. Press the play bar to start playback.
We are going to record a vocal overdub (serious or tongue-in-cheek), where you add an
action commentary or dialog for the actors. For this example use the internal microphone as an
input source. To check these settings, choose Logic Pro/Preferences/Audio and set the input
to internal microphone (or your interface).
I/O Buffer Size
! the number of sample that are sent
to the hard drive in one chunk. A larger size is
more efficient, but adds latency, or a delay. A
small size is more work for the CPU, which
can result in dropped samples (pops or clicks
in the recording) but less delay. A large buffer
adds delay, but is more reliable DA conversion. (Imagine delivering
telegrams to your boss. Doing them one at a time allows him to read each
one the minute it arrives, but more work for you. Collecting 50 of them in a
box is less work for you, but your boss reads them late.) If using the internal
mic you should mute the speakers or use headphones to avoid a feedback
loop.
At the bottom of the inspector are two channel strips. The first is the
track that is currently selected (Warp Engi) in the arrange window. The




23
second track shows the next track in the signal chain, in this image, the master output. Double
the name of the track at the bottom to change it.
! Just above the name are the stereo (two circles) and mono (once circle). Click to toggle.
M is mute, S solo and I switches the monitor to input (rather than automatically switching from
input to playback according to context), and R enables that track for recording. Above that are
the meters and the volume adjustment slider. Next the pan knob, automation (off in this
example), grouping (covered later) and finally input source and output (I/O) for that track.
On one of the empty tracks click on the R button. This arms only that track for recording.
The input in this example shows 3-4 because it was taken from a stereo mic setup (covered later).
Since we are using the internal microphone we only have access to one input. If not already
selected, change the input to input 1.
We won't use the metronome, which is on by default. To turn it off, open File/Project
Settings/Metronome and uncheck Click While Recording.
! Logic has two sets of preferences: Project Settings under the File menu and Preferences
under the Logic Pro menu. Preferences are globally applied to all projects. Project settings apply
to the current project only. This may seem redundant, but is actually a smart design.
Take a deep breath; you're about to enter the world of digital audio recording. Press the
record button and start recording. Don't worry if you make a mistake. Just continue to lay down
multiple tracks of dialog. With cycle mode on, the armed tracks will continue to record multiple
takes, layering them in a comp folder. You will see each new comp added to the track as the
cycle returns to the beginning. If you don't like any of the takes and want to start over, press !-
period. This stops playback and discards those audio files.
Comping
When finished, use the zoom controls in the lower right corner of the
arrange window to zoom your takes.
You can choose complete takes by clicking on the
reveal triangle in the upper right corner of the new comp
tracks. But you aren't stuck with one complete take. The real power of
this feature is in Quick Swipe Comping. This allows you to click and
drag anywhere in any take to select just that section of that take. The
program will automatically switch between takes during playback,
allowing precise control of edits. You can select a single word from one
track then switch back to another. Spoken dialog is sometimes difficult to comp, if takes are very
different, but if you were doing a musical track, especially if using a metronome, it is easy to
isolate a single correct note from 10 or so takes. Figure 3.2 shows a comped track.
Fig. 3-2 Comp Tracks
There is certainly a lot more to know about recording
(low latency mode, auto punch, replace, MIDI recording),
but this is a start. Feel free to explore on your own. (I just
figured out what the audio wave image next to the zoom
buttons does.) Once you've settled on an overdub, click the
reveal triangle to close all the comped tracks into a single



24
track. (You can also choose "flatten" to reduce it to a single audio file.) Review the previous
section describing the Logic Pro session folder/assets, then switch to the finder, locate your
folder and open it. Confirm that in addition to the logic file a folder for your movie and newly
created audio files has been created. All these combine make up your session.
Apple Loops
are a sizeable collection of high quality, creative, varied, interesting, and well
performed musical components that can be snapped together quickly and efficiently. They are
invaluable when putting together quick overdubs for video or voice over. The sound effects
section alone (about 5% of all loops) would be worth thousands of dollars in the analog days.
The right to use any of these effects and musical loops comes with the Logic license.
To access loops, click on the Media icon in the upper right
corner and choose the Loops tab. Select FX, located in the top right
of the loops tab. The buttons below are filters. You can click on
several to narrow down your search. For example, clicking both Sci-
Fi and Processed will give you a collection of processed sci-fi
effects. In the list below, click once to hear the effect, space bar to
replay it, and use the up or down arrows to scroll through each
effect. Note that when the Media area is in focus, space bar plays
back the selected effect. If you tab to the mixer or arrange window, space bar will start playback.
Once you have found an interesting effect, drag it and hover over and empty track to
place it on that track or over the blank area of the arrange window (not over an existing track).
This will create and place the sound effect in a new track. You can certainly collect groups of
effects on a single track, but if you decided to add reverb, pan position, or volume automation it
will apply to everything on that track, so it is better to group sound effects logically. As you
hover over the arrange window you will notice that the movie updates to show the frame at the
drop location. It will also try to pop to a grid. Drop it on the grid closest to where you want the
sound. Once placed, you can zoom in further and select the newly created region for a more fine-
tuned location. All the while the video will show the exact frame corresponding to the left side of
the dragged region. Continue to add sound effects.
In the loop browser, switch from sound effects to music. This section contains two or
four measure excerpts of drums, piano, guitar, bass, and synth music. Likewise, you can narrow
down the search using the filters. I usually start with Beats. Note the green and blue icons to the
left of each loop. The blue icons represent audio loopsrecordings
of real sound. The green are MIDI loops that use Logic's integrated
synthesizers.
! You can drag MIDI loops into an audio track and it will
convert it to audio. You cannot place an audio loop in a MIDI track.
It won't play back.
For now, drag all loops to an empty space in the arrange area. This will create a new track
with all the plug-ins and settings for that loop. Find both blue and green loops to use.
Each loop includes columns showing the original tempo and key (where applicable),
number of beats, match, and a favorite button. This allows you to choose loops that match the
tempo of the original session, but also reveals how flexible this system is. If the original tempo




25
or pitch does not match the one you are currently using, it will adjust the loop to match, not only
while browsing, but also after you have dragged it into the session. With MIDI tracks this is a
simple adjustment to the timing. With actual audio it is done through sophisticated algorithms
developed in the past decade. Previously it was possible to change the pitch and the speed, but
not just one without changing the other. As amazing as this is (and yes, it's amazing) it's not
infallible. If you try to match something that differs too far, artifacts will appear in the playback.
Loops, of course, are designed for
Looping
To extend a loop, hover the mouse over the upper right-hand side of the region. The
cursor will change into a loop icon. Click on the edge of the region and drag as far as you need
the loop to play. If you know exactly how far, press !R and type in the number of repetitions
needed. Finally, in the inspector you can click the loop button, or press [L]. This will loop it
indefinitely, or until it encounters another region.
Next, you can browse for a guitar, piano, or bass loop to match the drum selection. Once
located, drag it to a new track and loop it appropriately. Do the same with another backup
instrument, but this time start playback (with cycle turned on) before clicking on the loop in the
browser. This will playback the auditioning loop along with what you've gathered together
already. Remember that space bar applies to the focused window. If the loop window is focused,
it will start and stop the loop only.
Continue this process until you've cobbled together an interesting background track to the
action in the movie.
In a later chapter we'll cover the elements and styles of creating a popular
Mix
This section will serve as a quick overview. There are a number of approaches to the
layout of a mix. If you have a lot of tracks, you may want to close the mix section of the arrange
window (press [X] to toggle on and off). You can still adjust mix components on the currently
selected track using the inspector. Alternately, you can open a second window showing just the
mixer (!-2). Finally, you can use screen sets to switch between a mix screen and an arrange
screen.
Play your project and explore the following components: Move the volume sliders up and
down to adjust the relative volume of each track. Adjust the master volume if the overall sound is
too low or too high. It's ok if you peak (the top of the level meter will show red) once in a while,
but it should not be in the red the majority of the time. Use the pan knob to move the sound to
the left or right of the virtual space. Use mute and/or solo to isolate a single track or tracks. Solo
or mute to group similar items, to adjust them in isolation. For example, you might want to
balance the drums, bass, and piano (volume and pan position) then add the guitar and adjust it.
Automation
allows you to adjust each of these (and pretty much any adjustable parameter of any
instrument or plug-in) automatically, as if you had a handful of assistant engineers, each one
managing a single track (which is how we used to do it). Press [A] to switch the arrange window
to automation. Each track will show a timeline that can be used to change the displayed



26
parameter automatically. The track defaults to volume. Click on the volume pull down menu to
select another item to automate.
! To add a new breakpoint, click on the timeline. Note
that you can create and locate a breakpoint by clicking
above or below the existing timeline. Use shift drag to
select a portion of the timeline, then click and drag the line up or down. This will place two
breakpoints at each end of the selection, allowing you to adjust the entire segment. You can also
copy and paste or drag automation along the timeline once selected. After adding automation,
select playback and the volume and pan knobs will move on their own. Select a track that has
automation and note the green Read button. This means that the track has automation and it is
engaged. Change this button to Latch, start playback, and adjust any item in real time. This will
record your movements precisely.
There are three types of tracks in a session
Audio, Instrument, and MIDI
! Audio regions are colored blue, and contain real audio recorded in the real world. The
next are instrument tracks. These contain MIDI data (essentially just note on and off commands)
that are then realized as sound by one of Logic's built in synthesizers. The last are also MIDI, but
intended to be played on external gear.
Select an instrument track (any of the green regions). Click on the Piano Roll button at
the bottom of the arrange window. This shows the MIDI events in a piano roll layout. You can
click on an event (for example, a sound effect) and move it up or down, left or right (with the
video frames reflecting the position for fine adjustment) or crop the beginning or end.
Locate the I/O section of a track. In audio tracks the first button is used to select an input
source from the interface. On instrument tracks it allows you to select a software instrument
(which is a type of input). The current instrument is indicated in blue. This is the synthesizer that
is used to create the sounds from the MIDI data. To change it, click and hold on the input. To
open the synthesizer window, double click.
Instruments are a type of plug-in; a separate module that can be added to the Logic
interface. In addition to instruments, which generate sounds, there are processing plug-ins, or
Inserts
When you pick a loop, it not only loads the MIDI information that triggers
events, but also the instrument and plug-ins required to reproduce that particular
character of sound. Plug-ins are placed in inserts at the top of the channel. Signal
flows from the top insert to the bottom. The top menu (above the EQ graph) selects a
channel insert, which is a group of preset plug-ins (2-Step in this example). The next
window shows a miniature diagram of the channel EQ. This example has a
compressor, a high-pass filter, distortion (disabled), and a channel EQ. Disable a
plug-in with #-click. Move them with !-drag, duplicate to another channel with
#-! drag. Double click to open the preset editor. We will spend much more time on
plugins in later chapters, but don't hesitate to explore now.




27
Bounce
(under the File menu) commits the entire arrangement to a two channel (mono, or 5.1)
file. To export the movie with the new audio, choose File/Export Audio to Movie. PCM will
save to an aiff audio file (16 bit, 44.1k sampling rate is standard for CDs), Mp3 or M4A for
compressed audio, and CD to burn a CD.
Exercises
3:1 Continue with the project from this chapter and control click
on any track and check Freeze. Click on of the newly
created freeze buttons and press play. On an instrument
track, click the I/O input and choose the EXS24. Use the
Media/Library to locate HeadBanger Kit and record some
drums. Press the CapsLock to open the caps lock keyboard
and record some drums. With each of these steps examine
the session folder where all assets of this session reside. The
point of this exercise is not the content of the session (or
indeed understanding how a session works), but rather the
assets in a session folder. Note what new folders and files
are created and how they change the size of the folder. Save
the entire session folder to your documents folder on the
server. Open the folder from the server and click each reveal
triangle to show all assets; the tracks, the folders, the session
files, and their contents. Open and run the session file from
the server (as I've said not to) to see if you can produce the
"disk too slow error." Delete all the assets from the session
folder on the Desktop and empty the trash. Launch the
session to produce the assets missing error.
3:2 Create a list of 20 sounds that you have never heard in real
life, in person, only in recordings or movies. Place an asterisk by those you suspect
are different in real life. For example, I've never heard whales sing or a fog horn
except in movies and recordings.
3:3 Use Quicktime to create a short segment, with no dialog, of a favorite movie. Import
it into Logic, and remove the audio track. Listen to the original sound track, taking
note of music and sound effects. Create your own audio track trying to imitate the
original mood of the film. With the same excerpt, create an audio track that changes
the mood drastically: if intense, try comical, if moody try cheerful.
3:4 Open Logic Pro/Preferences/Key Commands and explore each section. Choose
Options/Copy Key Commands to Clipboard and paste into a text document.
Delete those you don't think you would use.
3:5 Open one of the demo sessions that came with the Logic Pro installation. Engage
cycle mode, hit playback, and spend 20 minutes exploring: double click on plug-ins,
fiddle with the knobs and explore the presets.




28
4. The Nature of Sound
Of any material: Change in density.
Vibration
of any material is the alternating compression and decompression of atoms; like ripples
on a pond, but spherical, in all directions. In digital audio editors this motion is represented as a
graph with peaks and valleys. The peaks represent greater density, the valleys lesser density.
When the graph of a sound is realized (for example by playing through a speaker) the forward
motion of the speaker creates the peaks and the backward motion creates valleys. The first image
in Figure 4.1 illustrates smooth changes in air density, dark being more dense, light less. Below it
is an audio graph of that wave would be drawn in a digital editor.
Fig. 4-1 Waves of Alternating Density

Patterns, Periods, and Noise
make up the character of the sounds we hear. The example above shows a sine wave.
It is periodic because the pattern repeats, or goes through cycles. Nature is filled with examples
of periodicity; tides, moon phases, days and nights music of the spheres, so to speak.
Aperiodic waves have no apparent patternrandom motion. Few natural sounds are either
perfectly periodic, or absolutely random. Rather, there is a continuum of varying degrees of
periodicity. Figure 4.2 shows audio graphs of three sound waves with different degrees of
periodicity. The first example is clearly periodic, but has some variation. The second looks fairly
random, but if you focus on the peaks you see a pattern. There are four peaks that make about
three and a half periods. The last has no pattern, and would sound like noise, or static.
Our world is filled with patterns. The lines and shapes we see out any window are
interpreted as objects such as trees, grass, and people. We decipher sounds in much the same
way; searching for patterns. We match the pattern in the waves with real phenomena such as a
violin, airplane, rushing water, or a particular breed of bird. If our eyes were as experienced with
wave forms as our ears are with sound, we would recognize the first image in 4.2 as an electric
piano. Periodic waves have pitch concomitant to the clarity of the pattern. The clearer the
pattern, the clearer the character of the pitch. The absence of pattern, to the same degree,
approaches noise. I say approach because pure noise, like infinity, is a theoretical abstract,
subject to our limits of perception. More on that later.




29
Fig. 4-2 Periodic, Complex, Aperiodic



Each wave can be described and measured using four criteria. These are all important for
understanding synthesis and audio engineering. The first is
Frequency, Duration, and Tempo
The musical equivalent to frequency is pitch and tempo. A real life example of frequency
would be the number of times the reed on a saxophone flaps up and down, or the number of
times the string on a guitar sways back and forth when plucked. Slow frequencies are rhythms or
tempos.
! We measure frequency in both absolute and relative terms. The absolute scale is Hertz
(Hz), or cycles per second and bpm (beats per minute) for tempi. The lowest C on the piano is
32.7 Hz, which is close to a frog croak. The next C above that is 65.4 Hzwhich is the range of a
tuba blat. The next C is 130.8 Hzthat guy who sings bass on Lawrence Welk (Google it). 261.6
Hz (also known as middle C), is the normal speaking range for men. Did you notice that I'm
doubling the frequency each time? No? Well go back and check. 523.25 Hz, the next C, is the
edge of a good tenor (great title for a short story), but also the normal speaking and singing range
for women and the late great Michael Jackson. 1046.5 Hz is the range at which Viking women
(or sopranos singing Viking operas) can, using only their voices, sterilize the croaking frogs.
There are two Cs above that, covering the highest keys on the piano (2093 Hz to 4186 Hz). This
is the range regularly occupied by piccolos and toy pianos.
Humans can hear frequencies two Cs higher than that; up to 22,000 Hz. We don't think of
this range as pitch, but rather the "brightness" or the edge in sound, such as fingernails on a
blackboard or little sister.



30
! The low range of hearing capacity requires a qualification. We can hear sharp edged
waves at frequencies as low as one pulse every minute, even one every hour or one a year. We
can also feel smoother waves at frequencies as low as 1 per minute. But the point where the
pulses begin to blend into a single homogenous pitch is what most texts consider the low range
of hearing. So while there is theoretically no lower limit to audible frequency, pitch begins at
about 20 Hz.
! Periodic pulses lower than 25 Hz are heard as rhythm or tempo. Musicians measure
tempo in absolute beats per minute or use tempo markings: Presto very fast (170 bpm),
Allegro fast and bright or "march tempo" (120 bpm), Moderato moderately (100 bpm),
Adagio slow and stately (literally, "at ease") (66 bpm), Lento very slow (40 bpm), etc.
By absolute we mean that C will always be 261.6 Hz. Absolute measures of frequency
are useful when using a metronome, EQ or filtering. Music (as in melodies and harmonies) is not
absolute, but relative. It is defined and described by the relationship between two frequencies.
(As an example, a foot, an inch, one mile are all absolute distances. They will always be the
same. Relative distances are twice as far, half as long, 1.5 times as tall.) The units for the
relationship between pitches are called intervals; a fifth, an octave, a second, a third. We
interpret two frequencies (either sounding sequentially or at the same time) as music if they are
related mathematically.
Since these measures are relative, it is impossible to say how many Hertz there are, for
example, in an octave, no more than you could ask how many feet there are in 'half as tall.' The
distance in Hertz will change depending on your starting point. An interval, therefore, is not a
specific difference in frequency, but rather calculated in relation to a given frequency; 2x higher,
1.5x higher. An octave (2:1 ratio) above 440 is 880 (2 x 440); a difference of 440 Hz. But an
octave above 1200 Hz is 2400 Hz, a difference of 1200 Hz. More on ratios later.
! Each period of a pitch and each pulse of a tempo has a duration. For example, a single
period of a 100 Hz sine wave is .01 seconds (100 periods in a second, each 1/100th of a second).
Each beat of a tempo at 120 bpm will be .5 seconds (120 in 60 seconds, each is 1/2 second). In
electronic music you need to be able to convert back and forth between the two. To calculate the
duration of a single cycle or beat, express it as a fraction then use the reciprocal: 120 beats in 60
seconds is 120/60. Each beat then is the reciprocal60/120, or 1/2. To calculate 100 bpm
(100/60) use 60/100, or 3/5ths of a second. Frequency is even easier because we use a single
second rather than 60; 440 Hz is 440 in one second (440/1), so each cycle of a wave is 1/440th of
a second.
! If you like formulas, given duration, frequency, and tempo: duration = 1/frequency,
frequency = 1/duration, tempo = 60/duration, duration = 60/tempo.
Two examples of how we might use these calculations: Delays (Chapter 9) or echoes
work well when they match a tempo, however, delays are usually expressed in milliseconds,
while tempo is beats per minute. To enter the correct value, you need to know, given a tempo,
the duration of each beat. Similarly, we may create sounds using a very fast delay. The delay is
expressed in milliseconds, but the result will be a pitch. To do the correct pitch, you need to
know which millisecond delay will result in which pitch. (A delay time of 0.0022727 will create
a pitch at 440 Hz.)




31
Amplitude
is the height of the peaks and depth of the valleys in a wave. The musical equivalent to
amplitude, is volume. A physical example of amplitude is the distance a speaker cone travels
forward and back. We increase amplitude by driving the vibrating body harder with more energy.
Example 4.3 shows a triangle wave at three different amplitudes.
Fig. 4-3 Amplitude
! We measure sound in dB, or decibels.
Most people speak of volume in absolute terms,
as in "a jet engine produces sound levels up to
110 dB." This is incorrect. Like intervals,
decibels measure relative amplitude, not
absolute; nothing is 100 dB. It is however
correct to say a jet engine is 110 dB louder than rustling leaves. But you could also say that late
night commercials are 110 dB louder than a jet engine. A sound can be 10 dB
louder than what it was before, or you can decrease amplitude by -10 dB.
This is why mixer controls often have 0 about two-thirds near the top;
because 0 means no change. Increasing or decreasing the volume is + or
dB.
! This misunderstanding comes from the practice of setting 0 at the threshold of hearing to
compare relative volumes. In this case, 0 might be a light snowfall deep in the forest, without
you in it. You arrive on skinny skis, stop and hold your breath to take in 0 dB, but your heartbeat
invades at 1 dB. You exhale at 10 dB, whisper to yourself "my skinny skis must think it queer" at
20 dB. Your buddy arrives and you whisper a little louder "listen how quiet" at 30 dB. After a
minute of blissful silence you shush off down the trail at 50 dB, saying over your shoulder "miles
to go before we sleep" at 60 dB. Your friend shouts "look out" at 75 dB because he sees the Yeti
who shrieks at 90 dB (How do I know? Jonny Quest, episode 122 "Expedition to Khumbu").
You shoot your rifle (in the air, just to scare him) at 100 dB. An F-15 clips the treetops from out
of the blue at only 10 dB. Yup, you read correctly; 10 dBlouder than the rifle shot.
! In general terms, the difference between the quietest sound and the loudest sound you
would want to hear is about 120 dB. In musical terms, one level of dynamic (e.g. mezzo forte to
forte) is about 7 dB. So in practical terms "A little louder" is 5 to 7 dB. When I'm making
adjustments for a client with a sensitive ear, I go 3 dB at a time.
Shape
is the fourth dimension of sound. The musical equivalent to shape is tone or timbre. A
real-life example of timbre change is simply playing a different instrument, or modifying the
instrument for a different quality: a muted trumpet or guitar, the angle of a violin bow, artificial
harmonics on string instruments, playing on different parts of a cymbal, and changing the shape
of your mouth during speech.
! In general, a bright sound will have sharp edges to the peaks and valleys. A dull sound
will have a smoother shape.
There is no standard measure for timbre, except if you measure the frequency and
amplitude of each harmonic.



32
Fig. 4-4 Wave Shape and Timbre

Figure 4.4 shows three sounds that are the same height, same number of cycles, but
different shapes. They would be heard as the same pitch, same volume, but one is distinctly a
guitar, then a saxophone, the last an electric piano.
Fig. 4-5 Sonogram Showing Harmonics
In addition to shape, timbre can be analyzed and
displayed on a spectrograph or sonogram. Wave shape is
a product of the presence and strength of harmonics,
which we will cover in later chapters. Harmonics are
pure sine waves at different frequencies (usually
multiples) that, when added together, meld into one
pitch. Figure 4.5 shows a spectrograph of the three
waves above. Each horizontal line represents a single
sine wave or pure tone. Higher lines are higher frequencies, 10k near the top, 100 near the
bottom. The darker lines are higher amplitudes.
Manipulating these harmonics constitutes a large percentage of electro-acoustic
composition. There are many sophisticated methods for this, which we will discuss later. The
most common tool for adjusting timbre is
EQ
There are essentially three types of EQs; low shelf, high shelf, and peak, or band pass.
You can combine them, as shown in the top image of Figure 4.6. This shows a low shelf at about
100 Hz, a high shelf at about 5k, and a peak boost at around 700 Hz.
Fig. 4-6 EQ Parameters
! There are three parameters for adjusting EQ; frequency
cut off is the point where increase or reduction begins (174, 500
and 2600 in the second example in Figure 4.6), dB gain or cut is
the amount you increase or reduce a given set of frequencies
(+14, 0, and 12.5), and Q, which is the width of the frequencies
filtered (4.8, 0.71, and 0.23). The last image shows the resulting
shape of the parameters above; a narrow band EQ (the sharp
peak) and a broad band (the hill). A higher Q has a narrower
band. The sharp peak has a 4.8 Q, the hill is 0.23. We see
nothing representing the 500 Hz because it's gain is 0.
Band or bandwidth describes a frequency range. Octave
band refers to the frequencies within an octave. For example,
113 to 226, 1284 to 2568 are octave bands. It's important to
note that octave bands grow exponentially. That means the
distance between each octave is twice as large as the previous. This is sometimes confusing
because the keys on a piano show octaves of equal distance.





33
Phase
Fig. 4-7 Phases
is the next property of sound. Periodic waves go
through a 360 cycle; like the phases of the moon. A wave
begins at 0 degrees. One quarter through the cycle is 90. Half
way through the cycle is 180 and 360 is one complete cycle.
We dont hear changes in the phase of a single sine wave, but
phase does change how two waves interact, and the overall
sound when frequencies blend.
Velocity and Wave Length
are dependent on temperature, altitude, and air density, but for this class you can use
1000 feet per second, 100 feet in .1 seconds, 10 feet in .01 seconds.
! The length of a wave is calculated by dividing velocity or speed by frequency (v/f). Using
1000 feet per second, a wave with a frequency of 100 Hz (about a G3, where a male voice
comfortably sings) is about 10 feet (1000/100). A 1000 Hz wave (about a C6, the upper range of
a soprano, and many instruments) is about 1 foot (1000/1000). The pitch A 440 is about 2.2 feet
(1000/440). Wavelength and speed are important for understanding echo and reverb, phase
cancellation, stereo imaging, as well as proper microphone and speaker placement.
What does all this science have to do with music? Most instruments provide the musician
with control over these three dimensions. Changing them is what gives an instrument
Expression
The more control and potential change over amplitude, frequency, and timbre, the greater
the expressive quality of the instrument. For example, the piano was a major advance over
keyboard instruments of the period because it allowed the performer to control and change
amplitude, and therefore increase its expressive quality. Keyboard synthesizers made a similar
leap in musicality when they included weighted and velocity sensitive keys. Less expressive
instrumentstriangle, snare, woodblockare missing control over one or more of these
elements.
An engineer likewise can control the expressive nature of a mix, and electro-acoustic
composers draw their expression through control and manipulation of these elements.
The human voice has precise control over amplitude and pitch, but it has greater control
over timbre than any other instrument. It is so precise and varied that it can communicate not
only musical ideas (notes, chords, melodies), but also complex and precise philosophical,
religious, emotional, and patriotic ideas. This is because speech is the change in timbre from
shaping upper harmonics with your mouth, tongue, and nasal passages. The character of a
person's voice (e.g. your mom vs. Mr. Rodgersa pretty even celebrity death match) is also
defined by the presence and strength of upper harmonics. Interesting note: inhaling helium does
not raise the pitch of a person's voice, as most people believe, rather, it sharpens the timbre, of
the voice. We are very adept at interpreting harmonic structure. That's why (before caller ID) we
could answer the phone and immediately say "hi mom, you sound like you have a cold. Are you
watching Mr. Rodgers reruns?"



34
Figure 4.8 shows a frequency spectrum graph of a friend saying, "four score and seven
years ago." If I played it for you, you would recognize it as Emily, who works in the library. The
x axis is time, the y axis is frequency. The "s" sounds are in the 6400 to 12,800 range. The C's
and K's are 800 to 1600. The vowel sounds are the fat ribs between 200 and 1600. Note that a
vowel is made of a band of related frequencies. The "e" in seven and years has higher bands.
Note the changes in upper harmonics when Emily closes her mouth for the "r" sound. Note the
slight Boston accent.
Fig. 4-8 Four Score
Adding, removing, or changing the amplitude of
upper harmonics will change the shape of the wave and
therefore the timbre. More harmonics will make a wave
sharper, and will result in a brighter sound.




35
Exercises
4:1 Of the wave examples on the right (each is exactly 1/100th of a second), which is
the loudest? softest? highest pitch? clearest pitch? brightest sound? is aperiodic? is
periodic? What is the length of each of these waves: 10
Hz, 250 Hz, 440 Hz, 1000 Hz? What is the lowest pitch
humans can hear? What
is the highest? What is
the lowest frequency
humans can hear? Story
question! If you clap
your hand at one end of
a 200' deep
performance hall, how
long will it take the
sound to reflect off of
the far wall and back?
4:2 Open Amadeus Pro. Choose Oscilloscope from the Analyze menu. Record your
own voice changing amplitude but not wave shape or frequency, then, as you sing,
change frequency, but not the shape or amplitude, then shape, but not frequency or
amplitude.
4:3 Record ambient background sounds from some random source. Select
Effects/Normalize. Select about 1 second and play it back. Can you hear a pattern?
Check the loop button in the lower left hand corner and listen again. See if you can
identify the meter. Change the length of the selection. What is the largest amount
you can copy and still feel a rhythmic pattern? Stop playback and make the selection
much smaller.01 seconds. Turn loop off and playback that segment. Do you hear
a pitch? Turn loop on and try again. Change the selection size. What is the pitch of
each selection? Choose a loud section and reduce the amplitude by 7 dB. Repeat this
process !-T, reducing by 7 dB each time. How many dB until you can barely hear
it? How would you characterize 7 dB?
4:4 In Logic, create an instrument track and assign the EXS24 by clicking on the
instrument slot below the I/O icon. Click on the instrument pop up menu and select
a kit patch. Add an EQ and engage the Analyze feature. Explore and locate
instruments from the kit that "fit" into each octave band. Record each in sequence,
bounce the recording, open in Amadeus, and generate a sonogram.
4:5 In Logic, import a song or several loops on different tracks with broad frequency
spectra (for example, a drum loop, guitar, piano, etc.). Also import a tune that has
full frequency representation. Add an EQ to the first track by double clicking the
EQ box. Change the gain of the first band from 1 to 14 (you can click and drag the
number or the peak in the graphic EQ, or double click the number and type).
Change the frequency to 100. Press the solo button on one track, start playback and
change the frequency. Note the effect on that instrument. Solo a different track and
repeat. Next, click on the automation pull down menu and choose Latch. This will
record your changes to the EQ in real time. Press play and double click the



36
frequency during playback and change it about every measure to the next octave;
100, 200, 400, 800, 1600, 3200, 6400, 12800. Leave playback running. When it
repeats it will reproduce your changes. As it repeats, make changes to the EQ and
note the effect. Use solo to select each track and listen to the results of the change in
EQ. Choose two of the instruments and generate a chart showing a short
characterization of each band (as shown below).

100 200 400 800 1600
Piano boomy presence narrow boxy crisp
Guitar thump body funky thin bright
4:6 In a Logic session, find a drum loop with a broad frequency spectrum
and no effects. (Drag green loops to instrument tracks and blue loops
to audio tracks.) Click on an open inserts slot and add a filter plug-in.
Select Logic Pro/Preferences/Key Commands and search for
Next Plug-in. Use the shortcut to explore the presets. Add three or
four more plug-ins or multiple instances of the same plug-in. Option click on all
insert slots to turn them all off ("bypass"). They will turn from blue to grey. (The
image to the right shows three plug-ins, two of which are bypassed.) Set
Automation to latch and press play. Switch each on and off using option-click. Mix
and match. (Optional: modify other settings too). Bounce and open in Amadeus,
then generate a sonogram.




37
5. Music Languages
I use MIDI every day. Less so, binary.
One of my first professors point out that 95% of programming is user interface; writing
code that connects the ideas of humans with the capacity of computers. Getting a computer to
generate a complex sound is a cinch: its just a stream of 0s and 1s. Nothing could be simpler.
The problem is, we dont speak 0s and 1s. What follows is a discussion of languages computer
musicians use to pass ideas to and from computers and other musicians, beginning with
Binary, Hex, Decimal
Humans use base ten because we have ten fingers. When weve reached the end of our
fingers, the person next to us holds up one finger to indicate one group of ten so we can start
over with out fingers. With each total of ten, our neighbor puts up another finger. When he gets
to the end of his fingers, the next guy holds up one finger. So four people holding up a 3, 4, then
5 and 2 means we counted three groups of a thousand, plus four groups of a hundred, five groups
of ten, and two ones. In the absence of buddies we use an odometer. Each wheel shows the total
number for that multiple.
Binary works the same way, except bits have only one hand with one finger. (They are
cartoon characters.) The first bit holds up one finger for the first item counted. When you add
another item the next bit holds up one while the first shows no fingers. The second bits single
finger means they've counted one group of twos. Appropriately, their odometers have two
characters; 0 and 1. Hexadecimal also works this way, but since computers themselves have
essentially 16 fingers, they use odometers with 16 symbols: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, then A, B,
C, D, E, F. When this odometer reaches 9, it doesnt return to 0, but continues on to A, then B,
and so on. After F, it returns to 0.
In computer music, you may never have to speak or write in binary or hex, but you may
very well encounter them. Here is a comparison chart. Think of each one as an odometer. Each
column is a wheel with numbers. The first has 0-9, the Hex is 0-9 then A-F, the binary only has
two items: 0 and 1.
Total number of items counted: Decimal Hex Binary
000 000 00000
001 001 00001
002 002 00010
003 003 00011
004 004 00100
etc. etc. etc. etc.
009 009 01001
010 00A 01010
011 00B 01011
etc. etc. etc. etc.
015 00F 01111
016 010 10000
017 011 10001
Here is how they are totaled. Each number represents a total of that position's value.



38
Decimal odometer 3 4 1 300 + 40 + 1 = 341
Totals for each: 100s 10s 1s
Binary odometer 1 0 1 1 0 16 + 4 + 2 = 22 (decimal)
Totals for each: 16s 8s 4s 2s 1s
Hex odometer F 1 A 5 61440+256+160+5 = 61861
Totals for each: 4096s 256s 16s 1s
In decimal, the first column from the right represents 1s, the second 10s, 100s, etc. In
binary, the first column indicates how many 1s there are. The second shows the number of 2s,
then 4s, 8s, 16s, etc. In hex, the columns are 1s, 16s, 256s, then 4096s. To parse a value you
multiply the number in the column by the value it represents. In binary, 10110 is (starting from
the right) zero 1s, one group of 2, one of 4, zero 8s, and one group of 16 = 22. Hex is a little
harder. F1A5 is 5 1s, 1 'A' 16s (10 16s), 1 256, 'F' 4096s (15 4096s) = 68161.
Why use binary? Because that's how bits work. They can only be on or off. Why hex?
Because it is a more efficient way to represent high numbers, and bits are combined in such a
way that counting in groups of 16 uses all the available bits.
Computers speak low level languages such as binary, Hex and MIDI. Humans speak
high-level languages such as pitch class, interval, chords, clefs, and staves. When you have a
musical idea, you need to interface with machines, networks, and people to get that idea across.
The language, or format you choose will make a difference in how easily your target will
understand. The more languages you know, the more choices you have. Imagine weve been
asked to write a catchy leitmotif for a cop show in Bulgaria. How do we communicate that to the
producer? If I use my laptop to write it, buried beneath the slick icon interface is this:
0011110000111110001111110011110001000010
Catchy, dont you think? The problem is, while this is the easiest language for my
computer, the producer is old school and can't sight sing binary. So lets bring it up a level.
0000003C, 0000003E, 0000003F, 0000003C, 00000042
Id say a handful of you could now hum this familiar theme. But, still not the producer.
Up one more level would be
Frequency
Here it is: 261.62, 293.66, 311.13, 261.62, 370. Its unlikely even another degreed
musician would understand frequency, but in electronic/computer composition and audio
engineering we deal with music on these terms all the time (e.g., EQ, filtering, as in the last
chapter or arrays of inharmonic additive sine waves in future chapters).
Frequency is not very useful when discussing melodies due to the exponential nature of
intervals. The distance between each interval is relative; different depending on where you start.
The first three notes of my theme make up a musical scale. The first two are a whole step: 261.62
then 293.66a difference of roughly 32 Hz. But the next two are a difference of 17.47. That's
not 32, but it's also not half of 32. Is it a half step or a whole step? Wouldn't a half step be 16?
Thats what I thought until half way through my doctorate, if you can believe that. In fact if my
musical theme were two whole steps the next frequency above 293.66 would be 36.7 Hz higher,
and thats if Im talking to a violinist. If a pianist, it would be, no kidding, 35.9. If I started my
melody on an A (440), the distance would be 59.8. Though the distance between these




39
frequencies all differ we hear them as the same distance, the same interval, the same melody. So
in this context at least, frequency isn't very useful.
To get around the math required to calculate intervals and talk about the mind-boggling
phenomena of tuning, we use
Cents
Its simple: 100 cents per half-step (i.e. one piano key). If my TV exec speaks "cents," I
could write this: 6000, 6200, 6400, 6000, 6600. Dont laugh. Take a closer look. Id wager most
of you could sing the tune. An understanding of both frequency and cents is essential for wading
through later chapters.

Note C3 C4 C5 C6
Distance in Hz ------65.4---------------------130.8--------------------261.6-------------------523.3
Distance in cents -----1200--------------------1200---------------------1200--------------------1200
While hex and binary are rare, and frequency is only useful in broad terms, the digital
musician regularly uses
MIDI
! Each key on the piano is a MIDI number. The lowest note musicians use is C-1, which
has the MIDI number 0. The number 12 = C0, 24 = C1, 36 = C2, 48 = C3, 60 = C4 (which is
middle C on the piano, remember this one and you can quickly calculate the others), and so on.
Music theorists use C4 for middle C. Unfortunately, this is not standard among synthesizers:
some MIDI equipment uses C5 for MIDI pitch 60, which makes MIDI 0 a C0, and Logic uses C3
for middle C. Sorry.
Each piano key is 1 number. C#4 would be 61. The pitch A-440 is above middle C so it is
69. Here is our theme in MIDI: 60, 62, 63, 60, 66. You can use decimal precision with MIDI, so
60.00, 62.00, etc. would work. It should look familiar. MIDI and cents are the same.
MIDI intervals are just as easy. One piano key (a half step) is one number. A unison is a
0, 2 a whole step, 4 a major third, 7 a fifth, etc. Written in MIDI intervals, our theme would be 0,
2, 1, -3, 6. If you have no musical training this system is actually easier than the major, minor,
augmented, diminished intervals we use in theory classes. In fact, theorists rely exclusively on
numbers to describe the complex, rich, and abstract harmonic and melodic content of 20th
Century styles.
! MIDI data files have been a standard for several decades. The main advantages of
working with MIDI are file size (they are tiny by any standard), and universal compatibility with
all computers and synthesizers since the early 1980s. Other features: Midi files are easily edited,
not only the notes, but also instrumentation. Because it is not actual sound, but instructions for
creating sound, a single note's length, attack time, release, or pitch can be changed.
A common scenario might be: you hire a pianist to record a jazz standard. He makes one
pass on a MIDI enabled grand piano. You record the MIDI, not the audio. He makes a few
mistakes, but plays a stellar solo. No matter, send him home. Open the MIDI data, correct the
mistakes, move the solo to another track and set it to a vibe instrument. Extract the bass line and



40
put that on a sampled upright bass. Then you send everything else back to the live grand piano
and record the actual audio.
Another feature of MIDI deserves a separate paragraph; online MIDI collections have
exploded. I rely on them more than our music library. Example: I want to show a class the final
measures of Bachs WTK book I Prelude in C as a classic example of a pedal tone. A quick
Google search, 5 second download and I have books I and II, which I can easily peruse (listen to,
but not see) using quick look. These can then be imported into my favorite copy program or
Logic. I have literally done this in front of a class for both classical and jazz standards. From
there I can improve the orchestration or arrangement, experiment with other voicings or chord
progressions, hearing the results immediately, and add note colors or analysis. The quality and
arrangements are uneven, you're a little at the mercy of the creator, but I have found several
trusted sources.
! There are disadvantages to MIDI: 1) MIDI is not sound. The sound is generated by local
equipment. What that means is the clever orchestration that sounds great on your equipment will
sound cheesy on a cheapskate Bulgarian TV execs setup. You have no control over exact
instrument choice once youve attached it to email. 2) MIDI files contain no information about
notation. There are no key signatures, time signatures, measure divisions, or staves. For example,
piano music often isnt written the way its played. Bachs WTK book I prelude is an excellent
example. It is written as eighth notes, but played as tied eighth notes. This often complicates my
Bach/MIDI trick. 3) MIDI files are written in a very low level, cryptic language. You can't just
open a file in any text program and make sense of the data. Writing and reading MIDI files is a
task for experienced programmers only. 4) It will soon be replaced.
Frequency, cents, and MIDI may seem like ancient Sanskrit, but in computer composition
you will often use all three, possibly in the same file, so fluency is a must.
XML
is a Music Extensible Markup Language, similar to HTML. It is the second attempt,
after NIFF, to standardize a music notation format, and has received wider support.
! It has similar disadvantages to MIDI; it contains no sound, it contains no playback
instructions, but it does contain information about key, clef, time signature, measures, etc.
Another advantage over MIDI is that it is text based. This means that you can open an XML file
using any text editor and with some practice make sense of, edit, or even write XML code.
Pitch Class, Intervals, Notation
could be used to describe the melody in an email. A pitch class is the single letter that
represents a note and all its octave transpositions. A4 is the frequency 440. But 'A' refers to all
pitches at multiples of 440: 220, 110, 55, 880, and so on. If I said my melody is C, D, E, C, F,
most of you would get the idea.
Intervals describe the distance between two notes. For this text, a short list of the
intervals in the key of C will do. "M" stands for major, "m" for minor, "P" is perfect, "A" is
augmented, "U" unison or 1. A "Step" is two piano keys.
Below is a chart showing all the different ways we describe musical intervals.




41
Letter C D D E E F F G A A B B
Interval U m2 M2 m3 M3 P4 A4 P5 m6 M6 m7 M7
Steps 0 ! 1 1 ! 2 2 ! 3 3 ! 4 4 ! 5 5 !
Piano keys 0 1 2 3 4 5 6 7 8 9 10 11
MIDI number 0 1 2 3 4 5 6 7 8 9 10 11
Cents 0 100 200 300 400 500 600 700 800 900 1000 1100
In the language of intervals, the theme would be U, up M2, up m2, down m3, up A4.
Pitch class, intervals, and music notation are handy, if my TV exec reads music. If he does, I can
send him
PDF and Screen Shots
There are two slick methods for getting notation into an email. The first is a screen shot.
Select "!4, or "!$4, which places an image of the screen onto the clipboard. I use screen
shots to create examples for tests, document unusual errors or dialogs, grab small sections of a
web page, but also to send one or two measures of a students assignment with my notes and
corrections.
If you want a nice layout and maybe multiple pages, PDF (portable document format) is
the next choice. A PDF can be read on any computer, any operating system. Creating a PDF is
simple in OS X. In any application, open the print dialog and choose PDF at the bottom. You can
choose Save as PDF, or Mail PDF, and it will not only create the PDF,
but also attach it to the bottom of an email message. Here then is a screen
shot of the theme, in a higher-level language of pitch class, which I hope
you recognize by now.
Believe it or not, there are still people who would not recognize any of these digital
renditions. My last choice? Call him up and sing it.
AIFF, Wave, MP3, AAC
are digital audio formats. Audio is such a universal language that any human, heck,
even other species, will get that youre making music. Though universal, sound has some
disadvantages. Audio recordings have no information about note values, durations, chords,
theory, notation, or instrument assignment. This means you cant change the orchestration, you
cant edit single notes from a chord, extract a bass line, or change keys as you can with MIDI.
Digital audio, in terms of format, is surprisingly simple to get into and out of a computer.
It's just a stream of numbers. There is very little detail (compared to a text or notation document).
A wave file (.wav) is an IBM standard. Most Macintosh programs can handle wave files. SDII
stands for Sound Designer II, which is the pioneer digital audio editor developed by DigiDesign,
the authors of ProTools products. The most reliable and interchangeable standard for digital
audio is AIFF, or Audio Interchange File Format.
AIFF (Mac) or WAV (Mac or Windows) are the standards for audio CDs. MP3 and AAC
are the two most common compression formats. While compression is good, they can degrade
each time you open, edit, and save. (This is because compression is a process that interpolates
samples. A little graininess in one copy will be interpolated again and again with each
compression.) Engineers still do all of their important masters in AIFF or WAV. The quality of
these files also depends on



42
Sample Rate and Bit Depth
Most digital editors offer sample rates from 5k to 128k and bit depths of 8, 16, 24, or 32.
Logic Pro will record in 16 or 24 depth, but will not read 32. Drag and drop a 32 bit segment and
it is converted to noise. Sample rate is analogous to frame rate in video: the number of snapshots
taken of a sound as it is digitized. More on this later, but 44.1k is the standard for CDs, 48k for
digital video. The reason for this discrepancy is complex and absurd, but we live with it. The
story goes something like this: 44.1 allowed 74 minutes, which was enough to accommodate
most classical works, in particular Beethoven's 9
th
. It's less and less of an issue, and CDs are on
the way out, so recording in 48k makes the most sense.
! We use 48k because you need at least two samples to document, even roughly, a wave:
one for its positive value, one for the negative. (See Figure 5.1.) We hear up to 24k, so you
double that. This is called the Nyquist Theorem. Granted, you end up with a square wave even if
the original was a sine, but at least you capture it. Oversampling is discussed further down.
Fig. 5-1 Nyquist Theorem
Lower frequencies have a clearer contour because
there are more samples to represent the wave. Figure 5.2
shows a triangle wave at 1000 Hz, which would be sampled
40 times at 48k. Thats a pretty good representation of a
triangle. A lower sample rate, say 10k, would have about 9
samples per wave (three of which are 0, so they dont show up
as a bar) as shown in the next image.
You could extrapolate a triangle wave, but thats
because, for illustration, these samples fall at tidy intervals.
This could have been a more complex wave with many
contour changes between the samples. Though more
complex, the wave just happen to fall at the shape of a
triangle, but the finer details would not be registered at this
sample rate. The other problem is, when the sound is played
back, each value is essentially the length of the time between
samples, so the shape of the triangle wave will not look like a
triangle, but will be distorted and terraced.

Fig. 5-2 Sampled Triangle Wave







43


Bit depth is the resolution or size of the numbers used for sampling. CDs use 16 bits.
These numbers are used to document the amplitude or size of the wave. Though not technically
correct, it is analogous to decimal precision. This means, in practical terms, that numbers are
rounded to the nearest precision. Even with a high sampling rate, a low bit depth creates
terracing.
The first image in Figure 5.3 shows a ramp wave where the sample rate and bit depth are
high enough to give a decent contour of the descending wave. There are twenty different bars;
each at a different height, so you could say it has a depth of at least 20. In the second, while the
sample rate is the same, the bit depth is lower. There are only 5 values, and samples are rounded
down to the nearest precision. This is no longer an accurate representation of the wave.
Fig. 5-3 Low Bit Depth Terracing
! Think of sample rate as the X axis resolution, bit depth is
Y axis resolution. Sample rate represents frequency, bit depth
amplitude. We will discuss what this means in terms of quality in
the next chapter. In general, higher numbers are higher quality
audio.
All this information has bearing on our goal;
communicating with others. That is because sample rate and bit
depth affect
File Size
My Dragnet theme is about a minute long. I could send a 128k 32 bit audio file of me
singing the theme. It would weigh in at 60M; enough to choke most service providers. Or I could
send a 4k MIDI file (that's 1/15000 the size). These days 60M isn't much, but what if it is with a
slow connection? And while it's next to nothing on a hard drive, multiply that by two for stereo,
then 32 tracks for a large project, then by 360 for an hour of recordingtypical for a single cut
on a CD. Now were talking about 80 gig. Thats for one CD track. A whole CD would be 800,
2.4 terabytes if youre working on several CDs. It adds up quickly. But storage space is not the
only consideration. File size comes into play each time you copy, backup, or open a project.
Consider a music school that has five performance and rehearsal spaces. You want to
implement automated recordings. The system will turn on and off when the ambient sound




44
crosses a given threshold. On average there are 10 hours of activity in each space every day.
That's 50 hours a day, a little less on weekends, so about 300 hours a week. Just to be safe, make
it redundant, so 600 hours a week. Archive up to six months in case a performing group forgets
to request recordings of their entire season (of course, I'm describing our system, and I have
indeed pulled 6 month old recordings). That's 18000 hours. This system, if recorded at 128k, 32
bit, would require 67 terabytes. The more rational 44.1k, 16 bit is a manageable 11 terabytes.
That's still pretty daunting on a tight budget.
Figure 5.4 shows two charts. The first is the smaller formats only, since they aren't even
visible on the second chart, which includes audio formats. Imagine each is a progress bar as you
open a file and wait for it to load, or copy to a server from home.
Fig. 5-4 Relative File Sizes

Now consider the workflow: faculty, clients, and students want to edit and publish their
own material. They will often download the files from home with slow connections. The files are
usually an hour long, often several files. I just did an (admittedly unscientific) trial, with a
mediocre connection to emulate my Bulgarian producer's internet connection, and I'm getting
about 10M a minute. The download times are shown in Figure 5.5. MIDI is 5 seconds. High
quality audio is 6 hours. Which should I use? Do I really want this producer to sit for six hours,
thinking about other engineers/composers who can get the same idea to him in 5 seconds?
Fig. 5-5 Bulgarian Download Speeds
Even if downloads were not an
issue, do you really want to have to
explain, over and over, why students can't
burn a CD directly from your recordings
because they are the incorrect, higher
quality format? Now consider how the
recordings are used. In the rehearsal spaces
faculty typically only need to review the
recording once, and the quality is not
critical. The performance spaces will likely
be edited and published, but to CDs at 16
bit 44.1k. You will lose any quality gained
from a higher sampling rate.




45
So we've settled on 44.1k 16 bit for performances and AAC for everything else. That
gives us a year of acceptable quality archives on 8T. That master class you did at the beginning
of the year, for which you didn't request a recording, but now you need for an audition CD? Sure,
I'll have it to you in 5 minutes at a reasonable quality. A purist, who insists on recording
everything at 128k won't.
Exercises
5:1 Complete the following charts. The first documents the sizes of digital audio that 5
CD projects might require. In the first, record 1 minute of sound at 48k 16 bit,
mono. Use Sound/Characteristics (or just calculate) to change the sample rate and
bit depth for other values in the chart. The first column is 1 minute of audio.
Multiply it by 60 for an hour in the next column, then 10 for a multi-track session,
then 2 for stereo tracks all around, then 5 for all the projects you're working on. In
the second chart, check all true answers for each file type

1 min * 60 * 10 * 2 *5
48k 16 bit
96k 16 bit
96k 24 bit
96k 32 bit
128k 32 bit

MIDI AIFF XML PDF
Small file size
Large file size
Accessible to non-musicians
to luddite musicians
to computer savvy musicians
to computer programmers
to computers
Contains clefs, keys, tempos
Contains actual audio
Orchestration can be changed
Notes are easily edited/changed
5:2 Give the decimal equivalent to these binary numbers: 00101010, 00000110,
10000001, 10010001, and these hexadecimal numbers: 000000EA, 0000001F,
000000F0, 00000099. What is the next number above each of these binary and hex
numbers: 00111011, 00011110, 00111111, 00000099, 0000FFFF, 0000A4CF. Give
the letter names, interval name and distance in cents for these MIDI numbers; 60 to
66, 60 to 69, D to E, G to B, D to B. How many octaves between 100 and 6400?

5:3 Search online for and download a MIDI version of a jazz tune. (Try something
obscure.) Use Open with to open it in Logic Pro. Select Screen Set/Rename and
type "Instruments." Press 2 to open another screen set. Press !-2 to open the mixer
in this screen set. (Optional; close the arrange window in screen set 2.) Rename this
screen set "Mix." Solo (in the Mix window) each track to familiarize yourself with



46
the material. Switch back to screen set 1 (press 1) to
delete any tracks that don't seem to add to the
arrangement or have incorrect notes. In screen set 1
open the Media area then click on Library. Click the
channel strip button (Silk Clav in the image) and use
the library to browse different channel strips.
(Optional, click on plug-ins and browse them.)
Choose pleasing instruments for each track. Switch to
the Mix screen and double click on any plug-in or
instrument to open them in a new window. Explore
plug-ins and adjust settings. Open screen set 3 and
click on the Lists icon then Events. Also select
Piano Roll. Name this set "MIDI." Continue to create
a pleasant mix using screen 1 to select channel strips
(and plug-ins). Use set 2 to adjust the level and pan
position of each track, and also to open plug-in
windows to make adjustments. Use 3 to edit MIDI
data. For example, delete Control or Program data
at the top of the track. It will interfere with your own
settings and automation. Click on the filter categories
(Notes, Progr. Change) to filter data. Click-drag to
select a group of items in the status column. Also in
window 3 use the piano roll to select different tools
(eraser, pencil, velocity) to edit or adjust velocity of
individual or groups of notes. Create a good
arrangement. Press 4 to open screen set 4. Name it
"Score" and select the Score window. In the local
menu (the menu inside the Score window) choose View, Page View. In a single
folder save your arrangement as a MIDI file, bounce it as an AIF (PCM, 44.1k, 16
bit), mp3, print the score as a PDF, and take a screen shot of the MIDI screen set.
Use the get info dialog to set open with to QuickTime for the MIDI file, AIF, and
mp3, set the other two to open in Preview.









47
6. Mics, Cables, Placement
Essential for musicians; not just those who sing.
In a few chapters well have a foundation on which we can build techniques of electro-
acoustic and computer composition. The first topic is one of the earliest styles of electronic
music: Musique Concrte. While one might argue that any recording, even acoustic orchestras
filled with luddites, is set in "concrete" and will never change, Musique Concrte is generally
accepted as not just recorded material, but recordings of real sounds that are manipulated in
unusual, interesting ways. Before you can manipulate sounds, you have to collect them, which
requires mics, cables, and interfaces.
Connectors and Cables
can be balanced or unbalanced (the details of which Ill explain in the noise section),
stereo or mono. For now you just need to know how they relate to the various connectors.
Unbalanced lines require only one wire for signal, balanced requires two. In addition, each cable
needs a ground wire, so a mono unbalanced line requires two wires. One for the signal, and one
for the ground. An unbalanced stereo cable has three wires. One for the left signal, one for the
right, and one for the ground, which is shared. A balanced mono cable also uses three wires, two
for the balanced signal, and one ground. A balanced stereo cable (less common), uses five wires;
two for the balanced left signal, two for the balanced right, and one ground. Common connectors
are: RCA, TS (tip, sleeve) TRS (tip, ring, sleeve), and XLR, as shown in Fig 6.1.
Fig. 6-1 Connectors

RCA connectors are unbalanced mono, but usually come in a stereo pair. XLR cables
could be stereo, but are invariably balanced mono. A TS can only be unbalanced mono. TRS is
the only cable that is regularly used three different ways: as unbalanced stereo, balanced mono,
or as an insert. This connector is what you see at the end of headphones, in this case stereo
unbalanced.
To be used as an insert, the other end is split into two TS connections. This single patch
point saves space on a board because it is both a send and a return. The tip is the send. The ring
is the return. At the other end one connector is plugged into the input of the device, the other into
the output.



48
The cables I always carry: firewire cable, 400 to 800 converter, a mini to mini TRS, a
stereo mini to RCA adapter, an RCA to RCA, and (2) RCA to quarter adapters, a quarter to mini
TRS, and a mini to quarter TRS. This collection gets me through most ad hoc recording or
playback situations.
The two most common
Microphone Types
are condenser and dynamic. Both have a diaphragm (like a small drum head) that
moves back and forth in response to sound. The diaphragm of a condenser is made of two thin
metal plates. An electrical charge is placed on each disk, one positive, the other negative. The
change in electrical voltage between the two is measured when the sound pressure moves one.
That voltage is transmitted to the recording device. The diaphragm of a dynamic microphone is
connected to magnets inside a coil of wires. The sound waves move the diaphragm and magnets
between the wires that pick up the electrical field. Most speakers have the same components as a
dynamic mic. You can even use headphones as a low quality microphone in a pinch.
Condensers require power either from a battery inside the mic (quieter, but cost a little
and if they aren't rechargeable, less green), or from phantom power sent down the cable from a
mixer or the recording interface. Phantom is less hassle, more environmentally friendly, less
expensive, and wont damage dynamic mics. (This is important to know because dynamic mics
dont require phantom powerbut are often used together with condensers on a mixer with just
one phantom power switch for all channels.)
! Im generalizing, but condensers are common in the studio, usually in an isolation booth
since they are more sensitive, and will pick up other sounds in the room. The other common
application is as a pair to record a large group of instruments, even an entire orchestra. They can
be used in live sound reinforcement (PAs), but are more prone to feedback.
! Dynamic mics, in general, are good for isolating several instruments in the same room.
Because they isolate, are cheap and rugged, they are the standard choice for live sound. The
following is a very general comparison of the two.
Condenser Dynamic
Expensive Cheap
Delicate Rugged
Requires phantom or battery power No power required (passive)
Wide range, depending on pattern Effective range of 6 inches
Typically used as studio spot mic or stereo pairs Used as spot mic, live sound
Microphone, Cable Care
- Keep microphone clips paired and attached to their microphones. They are less likely to
break or get lost.
- Store mics in a box, closed closet, or bag. This will protect them from dust, which can
reduce sensitivity.
- Twist the mic stand or boom onto the mic holder (after loosening the anchor thingys)
rather than twist the mic to attach it to the stand; less chance of dropping.




49
- To reduce possible damage to the mic and speakers, turn phantom power off before
connecting or disconnecting a mic. You should also power down speakers and amps to
avoid the mostly annoying, and possibly damaging pop. The rule of thumb for speakers
is: last on, first off.
- For nearly ten years I coiled cables using the standard alternating
backward loop (also used by rock climbers and competitive calf
ropers), and that's how most studios will expect you to do them, but
now I just "gather" them in arm length sections. They end up in a
loose figure eight, which, in my experience, believe it or not, looks
messy but is less likely to tangle than the alternating loop method.
- Do not roll cables around your arm. Ridicule anyone who does.
- I never tape cables, either to label or for security. I prefer to plan the
routing more carefully, block off those areas, use rug runners and
maybe tape the edges of the rug. Tape is evil.
Were getting closer to your first Concrte composition. Youve
picked out a mic, cable, plugged it into a phantom powered interface
(firewire mixer, Mbox, 002, the line input of your Mac), and are ready to
record backward satanic messages. Finally, the question youve been
anticipating.
Mic Placement
When recording voice, piano, guitar, didgeridoo where do you place the mic? The
frustrating but true answer: anywhere you like. I cant tell you exactly where to put the mic
because I dont know what you like, or what your performer likes, or even where the sweet spot
on that particular guitar is, so I cant tell you where it sounds best. You have to use your ears,
and these techniques.
- There are plenty of opinions online, so start there, but dont let that replace your ears.
- Ask the performer. They know their instrument and if they've done some recording will
tell you. They might like something different from you.
- Listen for a good spot. Its probably different on every instrument, even of the same
type. The spot that works great for one cello may be right over the wolf tone of another.
- Experimenttake the time to find the sound you want for this project. As I've watched
visiting engineers work, the one thing they do different from amateurs (like me) is take
the time, sometimes hours, to try things and get it right. Remember the experiment with
the phase cancellation. Sometimes inches make a big difference.
- Get it right before it hits the mic. That is, use the mic to document the sound you want.
Dont rely on post-production to repair mistakes made up front. If you're ever lucky
enough to stumble an original 16 or 24 track sessions of a great classic, you'll hear that
the raw tracks are very close to the final version.
- Dont let poor equipment/halls/circumstances get in the way of the music. Of course use
the best you have access to, but do the best with what you have. Contrary to the
previous paragraph, the engineering for many of the iconic hits from the 60s and 70s is



50
awful. Some even in mono. (Stereo didn't exist.) They sound great because its good
music. The poor quality recording just adds character.
- Remember there are no definitive methods. I've caught a lot of flack for this opinion,
but take distortion as an illustration. We go on and on about the nuanced variations of
guitar distortion, which, fifty years ago, in any form was wrong. The earliest examples
of distortion came from damaged equipment. You cant be more wrong than that. The
strings in Eleanor Rigby (Beatles) were mic'd so close as to make the musicians uneasy,
scooting back between takes. This was contrary to the accepted wisdom of the time and
contrary to the express rules of EMI. Paul wanted it to be edgy. It worked, and is now a
standard for that kind of intimate, full, studio sound.
While there are many opinions and styles, and I encourage you to develop your own
opinions on positions and sounds, there are a handful of techniques you should know.
Proximity
is the distance from the mic to the source.
! A close position will result in a fuller sound, better isolation, hence less feedback when
working with a PA. But the closer you are, the more pronounced the change (in dB) if the
performer moves. A closer mic will also pick up more mechanical noise; keys clicking, smacking
lips and tongue, ps and bs from the vocalist, dampers lifting, fingers on strings. Finally,
pointing the mic to one part of the instrument will isolate just a narrow part of its overall sound.
If you do mic close, it is important to realize (in the case of PA reinforcement) that the
performer has as much as 50 dB change at their disposal through proximity. If you want
complete control, encourage them not to move, or even touch the mic to the corner of their
mouth. Then again, I've always admired groups who use proximity to their advantage. They mix
themselves by stepping into a mic for a solo, using the mic and the PA as part of their
instrument. Many folk groups have returned to a single condenser instead of spot dynamics on
every instrument. This takes the engineer out of the picture, which is often a good thing.
If isolation is not an issue, I mic much further back than many engineers. This records
less mechanical noise, has a more uniform and natural dynamic change, and allows the
instrument to do it's job of blending the overtones into a true piano, guitar, trumpet, etc. On the
other hand, a close microphone has allowed musicians, especially vocals, to explore a wider
range of expression. The intimacy of Nora Jones, the strength of the strings in Eleanor Rigby, the
breadth of Bobby McFerrin, would not be possible without a close mic position.
The last consideration regarding proximity is room mix. If you want to capture the
natural reverb of a performance hall, the mix (wet vs. dry) can be controlled by proximity. Some
engineers capture the hall with another stereo pair near the back, often even facing the back walls
to pick up the reverb, which is then mixed later. I try not to fiddle with nature. If it sounds great
with me standing 10' away thats what I record. If the room doesn't provide the reflections you
want, then mic close and put reverb in during post-production.
In addition to proximity from the source, you have to consider the distance between
multiple mics. Two mics at different distances from the source can set two signals out of




51
Phase
Figure 6.2 shows one of my first two track recordings: a violin and piano. One mic was
placed near the piano, the other on the violin. They were about six feet apart. You see signal in
both tracks even though only the piano is playing. The top track is the mic on the piano; the
bottom is the mic for the violin. Since sound travels through the air, it reaches the violin mic a
split second after the piano mic. The difference is only milliseconds, so is nearly imperceptible
(as a delay, at least). In effect this virtually duplicates and displaces the piano six feet. It is mixed
with itself, but out of phase.
Fig. 6-2 Waves Out of Phase
! To illustrate, imagine recording a pure sine wave at 100 Hz (the
range where you get that solid thump of a kick drum) with two mics 5
feet apart. A 100 Hz wave has a length of 10 feet. Five feet is half the
distance of the waves length. The second image in figure 6.2 shows
what I would see in a digital editor. Both mics pick up exactly the
same wave, but the second mic, because of the time it takes for the
wave to reach it, will pick up the beginning of the wave when the first
mic has already recorded half of it. When mixed down the two cancel
each other out. Thats right; no sound. Their energies are mirror
images, one telling the speaker to push, the other to pull. So the
speaker does nothing. This is called deconstructive interference or
phase cancellation. Of course it would be hard to reproduce this precisely because the wave
bounces around the room, but it is a theoretical possibility. It can be reproduced using precise
(incorrect) editing techniques.
! Phasing errors come from poor mic placement, poor speaker placement, poor editing
techniques (e.g., deleting a millisecond too much from one track), or incorrectly wired speakers.
The solution is to isolate better (which hinders performance), or use a single stereo pair.
! You can also rely on the 3:1 rule. The distance between two mics should be three times
the distance of the first mic and the source. If mic A is 5 feet away from the piano, then mic B
should be 15 feet from mic A.
All this said, you should trust your ears. Inches matter. To illustrate, play a sine tone
through stereo speakers (but from a mono file, so it's the same in both speakers) and move
around the room with one ear plugged. You can find spots where the sine wave more or less
disappears. It's an astonishing experiment. Two inches from that spot it will reappear. The moral:
you can very easily improve the sound of a mic by moving it an inch.
Axis
is the angle of the diaphragm (not just the mic, but the diaphragm inside) in relation to
the source. For proper placement you have to know the orientation of the diaphragm. Most
dynamic mics have the diaphragm on the end, perpendicular to the barrel, so for on-axis
positioning you point it at the source the way you would a flashlight or shotgun. This is also true
with small diaphragm (and hence, small barrel) condensers.
Most mono, large-diaphragm mics have horizontal diaphragms, so the performer would
face them as if using a hand-held mirror. In these mics there is a front and a back. Manufacturers



52
usually put their name on the front of a mic. This is also true for many stereo condensers. The
diaphragms are horizontal with the barrel, so you would stand them up like a lighthouse.
Mono mics should always be placed on axis. This is the single most common error in PA
use. Inexperienced performers hold a microphone so that the diaphragm is pointing toward the
ceiling. This places it 90 off axis from their voice. The signal will be weaker and thinner.
Proximity and axis account for the startling change in volume with multiple announcers: one
person can barely be heard, the other is obnoxiously loud. People blame the engineer, but it's the
announcer's fault. Don't hesitate to offer suggestions to performers or announcers, and instruct
them about proximity and axis. Simply turning it up, which the announcer and everyone in the
audience expects, is not the answer.
Axis can be used as a strategy for isolation, to control feedback and to achieve stereo
patterns (described below).
Exercises
6:1 Play a pure mono sine tone through speakers in a room. Walk around the room with
one ear plugged looking for "dead" spots. Create two tracks (L/R) with identical
sine waves, one inverted. Play them through headphones, but hold them on one side
of your head at about six inches apart. Move them so that your one ear is close to
one, then the other, then exactly in the middle. The sine should disappear. Repeat
this experiment after selecting just one channel and inverting the wave. In the same
room, clap and listen to the sound of the room. Move around and see if you can find
a standing wave (where the reflections bounce back and forth and add onto each
other). You will hear a rapid, odd sounding echo, like flipping a spring doorstop.
6:2 In a Logic session import the same audio file (mono or stereo) into two tracks.
Zoom in to the sample level. Select just one of the regions in one track and start
playback. Use nudge to move the region to the left just slightly. Note the phasing (it
will sound more hollow). Repeat this several times so that the sound is increasingly
hollow. Notice the frequencies dropping out. Bounce the file, open in Amadeus,
generate a sonogram and hand in the sonogram showing the bands of missing
frequencies. Do the same with a noise source.
6:3 Record your voice or an instrument using a number of varied mic placements; close,
far, on axis, off, different positions around the instrument. Compare the results.
Place two microphones 10 and 15 feet from a source. Play a single note and
examine the resulting stereo file, confirming that they are out of sync.
6:4 Find a rich source (e.g., play pink noise through quality speakers) and record using
two condenser microphones. Begin with them exactly on the same plane and
distance, then slowly move one further away. Mix them to a mono file (either in
Logic or Amadeus.) Listen to the phasing that results.





53
7. Recording Techniques
Ways to improve audio. You'll thank me later.
Stereo/Mono
Your final electro-acoustic composition should be stereo. While I have no scientific
backing, I think our brains can interpret elements of a stereo mix more efficiently. The guitar in
the left ear is being processed by our right brain, and the flute in the right ear, by the left side of
the brain. Logic Pro and SC can produce very interesting results in 5.1 ("quad"what we called
it back then), but don't let that take over the project. Mediocre music is rarely improved with
more channels. On the other hand, SC has extremely powerful spatialization tools, and should be
exploited.
When laying down tracks in a multi-track session, each track can be mono or stereo.
Mono tracks are then placed in a virtual stereo field by adjusting the pan position. If the subject
youre recording includes important stereo placement (such as an entire drum set, street noises, a
quartet or entire orchestra), use two mics and a stereo track. But since this takes twice the space,
it might not be the best choice with individual instruments. A piano is rich enough and wide
enough to make a stereo recording worthwhile, but maybe not a guitar or voice. Some engineers
place two mics on a single instrument, and while the sound is not true stereo, the two tracks are
different, and when panned left and right thicken the sound.
Overdubbing
is ubiquitous in popular music. Rather than place two mics on a single instrument,
record an instrument twice, then mix both left and right. This technique is most commonly
applied to guitars or vocal tracks. One reason is that overdubbing masks imperfection. Two out
of tune lead vocals, when meshed together, magically sound more in tune. In fact, most
synthesizers and guitar effects achieve a similar result with a mono signal that is split, then one
or the other is detuned for a gentle phase shift.
Examples of overdubbing include the guitar riff in La Grange (ZZ Top, studio version),
Cocaine (Eric Clapton, vocal, both panned center), Martha My Dear, Beatles, Little Bitty Pretty
One, Slippery Saint Paul, China Grove, Black Water, Eyes of Silver, and Long Train Running
(Doobie Brothers, guitars, panned left and right).
You can go overboard with stereo mics, resulting in a minor engineering error. As an
example, consider a session with a stereo pair on the piano, the drums, a stereo feed from the
electric guitar, dubbed vocals, and finally stereo mics on a three piece horn section. Since all of
these are stereo, you would pan them all center to get the full effect of the two channels, correct?
Wrong. This is called
Big Mono
and it compromises the overall image, placing every instrument (or stereo set of
instruments) essentially in the center. Even if something was recorded in stereo, consider moving
the image to the left or right, giving a place for each instrument or group.



54
Important note: For true stereo panning in Logic you have to use the
Imaging/Directional Mixer plug-in. More about this in Chapter 9.
Each mono microphone may offer a variety of
Patterns, Stereo Pairs
Unidirectional patterns will pick up just one direction; in front. There are also cardioid
(shaped like a heart), omni (all directions equally), and figure 8 (front and back) patterns.
Two microphones, usually condensers, are often combined in a stereo pair. Stereo mics
have two capsules integrated into a single body, but you can also place two mono mics on two
stands or a stereo bar in any of these patterns.
One popular configuration is an x/y figure 8. The microphone capsules are placed directly
over one another, each facing 45 off axis to the left and right of the source (90 from each
other), both in a figure 8 pattern. The figure 8 preserves the stereo image in front and adds a nice
hall mix, also in stereo from the back part of the figure 8. The two capsules are placed
meticulously over one another to eliminate any distance between the two capsules, which would
invite time delays and phase cancellation.
A mid-side pattern is very clever, and slightly mysterious. Two capsules are again right
on top of one another, but one is on axis with the source, the other faces the sides (90 off axis)
in a figure 8 pattern. To create an image, the center mic is mixed to the center and the sides are
mixed to both the left and right channels, but with one channel's phase inverted. This produces a
less convincing stereo image, but the advantage is a clear mono reduction. Since the left and
right channels are mirror images, when mixed to mono they will cancel each other out and you
are left with the center capsule only. This pattern is used extensively in television programs,
where mono and stereo playback are (were, does anyone own a mono TV?) practically equal
possibilities. In Logic Pro, the directional mixer has a mid-side option, applying all the wizardry
on a single stereo pair.
But phase cancelation isn't wrong per se. Its only wrong when it compromises the sound.
The truth is, we encountered phasing in every aspect of music. It is, as we will see, what makes
music work; waves interacting in both constructive and destructive interference. It is used to
great effect for EQ, phase shifters, flanging, and enhanced stereo. In my first digital recording
the sound reached the second mic later, causing delays and phasing. In that case, something I
wanted to avoid. But notice our ears are not on the same plane. Sounds on the left will reach the
right ear both delayed and phased. That is in fact one of the cues we use to interpret the stereo
world around us; a vestige of hunting or being hunted, where audio location was critical to
survival.
For that reason, my favorite pattern, not only for the results, but because it makes so
much sense, is an ORTF (developed by l'Office de Radiodiffusion Tlvision Franaise). There
are many variations (Figure 7.1 is a little narrower than 110), but the original uses two
microphones 17 centimeters apart at a 110 angle from each other (each 55 off axis from the
source), cardioid or figure 8 pattern. In addition to accurately capturing the relative amplitude
between left and right sources, it reproduces time delays, phasing, and filtering of frequencies
that would occur naturally with our ears, which are also about 17 centimeters apart and at a 55
angle from a source. Though I understand that was not the original inspiration for the pattern, it
is a good way to remember it; the distance of your ears, and at the same angle as your ears. I love




55
the reaction I get when clients first hear this pattern. It's usually along the lines of "it's so clear"
or "how can it sound so good so fast."
Fig. 7-1 ORTF

A variation of this type of spacing is a baffled stereo pair. This method places two
capsules at roughly an ORTF configuration, but with some type of sound absorbing material in
the middle. The Crown SASS is one of my favorite baffled pairs. They are relatively inexpensive
(for a pair), but limited to stereo recordings, and a bit bulky, so we use them as hanging mics.
Sample Rate
is the number of samples per second used to record a sound. There are four criteria to
consider when deciding on a sampling rate: Frequency range, aliasing, concrte, and file size.
Recording at lower sample rates will reduce the upper range of frequencies being recorded,
essentially filtering higher pitches and harmonics. CDs use 44.1k and video uses 48k. These rates
were chosen because they are double the highest frequency we hear. Dog whistles, insects, and
most instruments produce frequencies beyond our hearing range. Do we need to worry about
frequencies we can't hear? Yes, for four reasons.
The first reason is to avoid aliasing. Frequencies that are normally beyond our hearing
range can interact with the sampling rate to produce unwanted aliases (described in the section
on noise) that are in our hearing range. Recording at a higher sampling rate reduces the risk of
aliasing.
The second argument for a higher sampling rate is the theory that frequencies beyond
human perception interact to produce important artifacts in lower frequencies, the range that we
do hear. (In other words, natural aliasing.) In a concert hall those frequencies have a chance to
interact and combine. But in a session where the instruments are isolated, they cannot. In this
case the instruments can only blend digitally inside the computer during mix down. The theory is
that masters should be recorded at 96k or higher to include frequencies in the 30k and above
range, which can then blend during the mix. I've seen no solid proof of this theory. On the other
hand, while you can always down sample, you can never up sample. Something that was
originally recorded in 96 can be reduced to 11 to save space. But if you record in 11k you can
never retrieve the information that would have been recorded at 96k.
The next reason for higher rates involves sound effects and concrte work. Remember
that when you change the speed (and pitch) you essentially change the sample rate. If you want
to explore sounds beyond our hearing range by transposing them down, you need to record
sounds beyond our hearing.
The last reason is metaphysical, philosophical, anthropological and probably flippant.
Future technology may reveal some information in those upper frequencies that are not available
to our current technology. Record at higher rates so that future generations can extrapolate from



56
those archival documents the existence of beings, possibly from other dimensions, who sing
along with our performances, but in frequencies that are beyond our current comprehension.
! In review: up sampling avoids unwanted aliasing, captures frequencies that may generate
natural aliasing, captures frequencies beyond our hearing for experiments in pitch change, and to
capture information we don't yet know how to process.
Noise
is any unwanted sound. Noise can be in the room (air conditioning fans, computer
fans, resonance that turns into feedback, buzzing lights, cell phonesthey are noise booby
traps), in the equipment (mixers, fx units or amplifiers), in the digitization or encoding process
(low bit depth or aliasing), in adjacent rooms (a candy machine, drum set in the isolation booth,
NIN practicing down the hall) and even out there in the ether (radio interference, SETI signals
from Elvis). Some of these may have merit on their own, but if they don't add to the sound you
want, they are noise.
As John Cage discovered in the anechoic chamber (the inspiration for 433"), you will
never eliminate noise, so the next best thing is to increase the divide between signal (what you
want to hear) and noise (what you don't want to hear). The term for this division is signal to
noise ratio. For example, an amplifier may list a signal to noise ratio of 80 dB. There are many
ways to improve signal to noise ratio. It is, in fact, what an engineer does.
! Turn things off, move to another room, isolate the source with partitions, absorb
unwanted sounds with insulation. You can also improve signal with proximity: place the mic
closer or move yourself closer, being aware of the issues described above (increased mechanical
noise, unnatural sound).
! To reduce system noise use quality equipment. Some engineers seem obsessed with
preamps (the circuitry that brings the low level mic signal up to a useful range), and with good
reason. Also, see the section on distortion below.
How much should you pay for high end equipment? As a general rule, you get what you
pay for, but with a steep diminishing return. That is, there is a difference between a $100
(approximate per channel for a consumer level mixer) preamp and a $1000 per channel preamp,
but few people would notice the difference. This is also true for mics. The trick is to find the
optimum between your budget and your (client's) ears. When I took a job for the local symphony
I envisioned gold plated cables and Genelec speakers in every room. The truth is, they were on a
very tight budget, and renewed my contract precisely because I got the most out of what they
could afford, which wasn't much.
Fig. 7-2 Bit Depth Noise

One source of noise is the digital conversion itself. The example on the right, believe it or
not, is a sine wave that was either recorded at a very low depth, or recorded at a high bit depth,
but at a very low amplitude, then amplified to normal levels. The terraces you see are the results





57
of rounding to the nearest bit. When you subtract the sine wave (by adding an inversion of the
original wave), you can see (Figure 7.2) the edges are themselves a periodic wave, but in this
case unwanted noise.
The last resort, for me at least, is digital noise reduction. Signal processors make up for
poor engineering and poor quality equipment. It is sometimes difficult to resist fiddling with all
the knobs, flashing lights and technical graphs and readouts, but a skilled engineer will never
reach that point. Processing always compromises the signal.
Balanced Cables
are used to eliminate noise from the ether (RF signals). A balanced cable is a self-
contained noise reduction system. Balanced refers to two mirrored signals. A single signal is
duplicated and one is intentionally inverted just before it starts its journey down the cable. If, at
the other end, these mirrored signals were just mixed together they would cancel each other out,
being exact opposites. To prevent this, they are re-inverted before being mixed together.
Fig. 7-3 Balanced Lines

The clever part of balancing a line is this; rather than blocking out the noise, it assumes
there will be noise acquired, but that it will be present, and exactly the same, in both lines. The
first example in Figure 7.3 shows two balanced square waves. The bottom is an exact mirror of
the top. The next is not a mirror. It is a noise source captured along the path after the signal was
inverted. A short burst of this noise was added to the first wave, and it will be present and
exactly the same in both signals (third image). If you mixed the two lines at this point the
original square wave, which we want, would vanish, because its a mirror image, but the noise
would be added together and twice as loud. But if we re-invert the second channel at the
receiving component (third image) and mix them down the square wave will add together, but
the noise, which is now a mirror image, will vanish.
If you prefer grasping this with math, think of the original signal as: [0.5, -0.5, 0.5, -0.5,
0.5, -0.5, 0.5, -0.5]. The inversion would be: [-0.5, 0.5, -0.5, 0.5, -0.5, 0.5, -0.5, 0.5].
Adding these two together would result in: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
We can run the math and get a sneak peak at SuperCollider. Chapter 13 provides a more
in depth quick start for SC, and it is used in the chapters after that. For now, type this line in SC,
select it, and choose Lang/Evaluate Selection.
7.1:: Balanced Lines
[0.5, -0.5, 0.5, -0.5, 0.5, -0.5, 0.5, -0.5] + [-0.5, 0.5, -0.5, 0.5, -0.5, 0.5, -0.5, 0.5]
::

Now add random numbers as noise: [0.14, 0.36, -0.11, 0.102, -0.4, -0. 1, 0.319, 0.1]. We
will add it to both the original and the inverted signal. Run each line separately.






58
7.2:: Balanced Lines With Noise
[0.5, -0.5, 0.5, -0.5, 0.5, -0.5, 0.5, -0.5] + [0.14, 0.36, -0.11, 0.102, -0.4, -0.1, 0.319, 0.1]
[-0.5, 0.5, -0.5, 0.5, -0.5, 0.5, -0.5, 0.5] + [0.14, 0.36, -0.11, 0.102, -0.4, -0.1, 0.319, 0.1]
::
The resulting arrays seem just as random, but watch what happens when we invert them
and add them together. The .neg inverts the second array, the /2 reduces it by ! since we are
adding the original signals together.
7.3:: Balanced Lines Re-Inverted
([0.64,-0.14,0.39,-0.398,0.1,-0.6,0.819,-0.4 ] + [-0.36,0.86,-0.61,0.602,-0.9,0.4,-0.181,0.6].neg)/2
::

Distortion
is any misrepresentation or deformation of a wave. The jagged edges created by low
sample rate or bit depth are an example of distortion. Distortion is often used creatively, to
transform the source into something new (e.g., Jimis screaming guitar). But if your goal is
accurate representation then it should be avoided.
Fig. 7-4 Saturation, Clipping
The most common source of distortion
comes from pushing an audio device beyond its
physical or virtual capacity to respond. The
medium is then saturated, or overdriven.
Anythingmics, preamps, mixers, sub-masters,
fx units, instruments, speakers, magnetic tape, digital bit depth, even your earscan be saturated.
The energy that goes beyond that physical barrier is not reproduced and therefore lost, or
clipped. The result is a fuzzy or gravely sound (as well as some frequency loss). Figure 7.4
shows two channels of a sine wave increasing in volume. Ive imposed an artificial limit on the
lower channel. When it reaches this limit the shape changes, because the wave is still moving
beyond the limit. The wave is clipped, changing the shape and therefore the sound. A mixer
channel will usually have an LED meter, showing input level, or a red and/or green single LED
to indicate if there is a signal present and if the signal is over the units capacity. Logic Pro
channel strips will show red when clipped.
These two noise sources, system noise and wave distortion, are on opposite ends of the
level spectrum. If your recording levels are too low, you are near the inherent noise in the
system. If you record too high, then the signal is distorted. The trick is to record at
Optimum Levels
That is, as high above the noise floor as possible
without clipping: not too loud, or too soft. Levels are set
while the performer plays a loud passage, or even the
loudest that the instrument can play. It is good to adjust levels during a rehearsal, playing the
actual music to be recorded, if in a session with other tracks playing along. I find that a real




59
performance is more aggressive, and a better representation than a sound check. Keep in mind
that any component in the path can be overdriven and should be monitored. You can use a single
test tone to set all levels on all equipment to unity. This way a single meter can serve to monitor
all levels.
Analog tape was much noisier than digital and had a softer distortion; a more forgiving
sound. Levels were often pushed daringly hot. Digital distortion is harsh, and the bed of noise is
much lower. So if I'm not sure about a signal I err on the low side. It can be optimized later
without adding as much noise.
Aliasing
is the final source of noise. To illustrate aliasing, imagine filming the second hand of
an analog clock at a very low frame rate, say 4 times per second. Though the motion would be
jerky, it would still accurately capture the movement of the second hand. Even a snapshot every
15 seconds would give you a pretty good idea. But with a frame rate of one every 60 seconds all
the images would be the same; showing the second hand at the same position every 60 seconds.
According to these samples the second hand is not moving
As the rate of motion approaches the rate of sample, you get something worse than jerky
motion. You get incorrect motion. A sample rate of one in 55 seconds would show the second
hand moving backward.
Fig. 7-5 Aliasing
! It's like the wagon wheel effect in movies, where a
wheel appears to slow down or go backward. Its actually
moving faster, but the frame rate, combined with the
frequency of the wheel, gives the illusion of backward or
slower motion; an alias. The alias is the difference between
the sample rate and the rate of the sampled item.
This is easy to see with a square wave. Figure 7.5
shows a 1/1000
th
of a second segment of a recorded square
wave. There are 12 cycles in the upper track; 12000 Hz. The
lines represent a very low sample rate; 8000 Hz. There are
not enough samples to show an accurate picture of the wave,
but it does indeed return a positive and negative value at each
sample. Using only the information returned by the samples,
the resulting wave is 4000 Hz, a much lower frequency. The
next example shows a triangle wave with samples that are
close to the cycle itself, but fall a little further along the wave
in the next cycle. According to the samples only, they slowly ascend then descend, documenting
a non-existent, and much lower triangle wave in the second track. The final image is the same
example zoomed out, showing the original wave, and the alias. (See chapter 20 for a composition
technique using aliasing; sample and hold.)
! When a frequency is close to a sample rate the alias will be the difference between the
two; a sine wave at 44200 Hz, and a sample rate of 44100 Hz will result in an alias at 100 Hz.
Even though 44,200 Hz is not within our hearing range, the alias is. For this reason, many
engineers record at 96 or 128k.




60
Edits
are the final component to skilled engineering. Years ago we edited reel to reel
magnetic tape with razor blades, splicing tape, a splicing block and lots of time and practice. The
next generation of recording media (DATs and CDs) could not be edited. For that reason I never
owned a DAT or ADAT. I knew that direct to disk was coming, so I skipped a wave of
technology. Random access digital audio is revolutionary in its flexibility, ease, and accessible
editing tools. It is so easy to piece together complete works with sections of several takes, even
with complex audio (e.g., full orchestra), that many students and faculty do it on their own. The
graphic display makes it easy to see where to do the edits and can show waves with a resolution
down to the sample level. It is easy to be precise and accurate, so it is unforgivable to make this
one error: non-zero crossing edits.
Fig. 7-6 Non-Zero Crossing Edits
A non-zero edit is when you select, copy, or
paste at a point where the wave is not at 0, or the center
of the graph. Such cuts result in a sharp change from
positive to negative energy in only one sample. Figure
7.6 shows a non-zero cut. (This example is very short.
The edits you actually do may be several minutes, but
the principle is the same.) The first image shows the
selection from an audio file at non-zero points of the
wave. The next has the selection deleted, leaving a
sharp edge.
The result is a click or pop. The error is so
common that most editors provide some simple solution such as a cross-fade, interpolation of the
wave, snap to zero, or even an automatic "repair clicks." But a skilled engineer should avoid
them in the first place. This is accomplished by either carefully choosing edit points at silence
(and planning sessions to accommodate such edits) or by zooming into each selection before
copying or pasting and choosing non-zero edit points. This goal is often complicated by a stereo
file, where the left channel may be zero, but the right is in a positive position. In this case cross
fades, or rapid fading in and/or out (e.g. a tenth of a second), or interpolating the wave can be
used to correct the edit point.
These sharp edged waves can also be caused by a slow disk or a low buffer size. If the
system can't keep up with the DA conversion, it simply drops samples out.
Fig. 7-7 Descending, Zero-Crossing
Zero-crossing edits are considered good form, but a real
pro goes one step further and chooses zero-crossing descending
edit points. A descending edit point is where the wave is moving
from positive energy to negative energy. If you choose the
beginning of an edit at a zero crossing, descending, but at the end
select a zero crossing ascending, then the edit will indeed be at a
zero point, but will have a quick change of direction. This first
example shows a pair of non-zero edits, but one is descending
and the other ascending (bad). The next shows a more correct
pair where both are descending, non-zero edits.




61
Digital audio workstations use cross fades: millisecond ramping between two audio files,
or two sections of audio files. But most of the work I do (concert recordings with stereo pairs) is
with two track editors. Choosing edit points carefully is faster, and easier. If the edits are within
the worka measure here and thereI use crossfades.
Amadeus Pro uses a system called smart edit. When on, crossfades are automatically
applied at every edit. You can set the number of milliseconds in the preferences. For some work
(stock concert editing), I find them useful. For other projects (precise experimentation), I turn it
off.
Optimum Engineering
You can skip this section if you'd like. It's just my opinion; a bit of a rant.
After all this discussion, what sampling rate, bit depth, pre-amps, mics, placement, reverb
or compression (see chapter 9), should you use?
One of the best suggestions I can offer is to hone your aural skills and deconstruct the
artists you like. When you're invited to work on a project it's unlikely they will hand you written
music or an existing session as an example. They will give you a CD. You have to be able to
reproduce what you hear, and just about anything you hear.
Here is an example of the recording skills used to produce one of my favorite recordings:
Find a house close to a road so you can hear the odd bus passing by. Use the cheapest mic you
can, preferably used, from a pawnshop. Place it in the middle of a room routed to cheap preamps.
Don't spend any time positioning the artists in the room. Let them sit wherever they want. Have
the lead vocal sing through a can. Make sure the room has no sound proofing so we can hear the
reflections off of flat, boxy walls. Have one of the musicians sit in a creaky rocking chair. Open
the windows so we can hear the dog or random rooster crowing outside on the front porch. Set
the mic next to an AC unit to get a nice rumbly dark pink noise. Don't do any post-production
no reverb, delays, panning, EQ, or compression.
This sounds facetious, but I'm serious. I love this recording, and the ghetto engineering
perfectly captures the intention of the artist. He is the only person, and I include the huge
collection of classical composers, to whom I can and often will listen all day long: Tom Waits.
His work defies and defines both musical and recording conventions as a matter of style. For
example, in fact, example one, Chocolate Jesus is genius. The lyrics, the subtext, the gravely
voice are all tied together with the recording techniques he used, or should I say, didn't use. I've
read on the ever-reliable Internet that the rooster is real, and just happened to crow at the right
timea live chicken for god's sake. Similar ghetto recordings: Jesus Gonna Be Here, In The
Colosseum (how does one mic a trash can?) Murder in the Red Barn, Lowside Of The Road, and
Johnsburg Illinois, which just wouldn't sound right on a properly tuned piano.
Second example: Poorly tuned guitars, everyone playing all the time without any
consideration for height, elements of mix or texturejust one big jam, no pop filter on the vocal
(where it was clearly needed), no headphones or a click track lest anyone accidentally play on
the same beat. These recording techniques gave us the profound, inspiring, so emotionally
draining that it's not even on my playlist, Like A Rolling Stone (Dylan).



62
Admittedly, these are cult artists, a bit left of main stream. So I offer this more familiar
example: encase a microphone in a condom and immerse it in a bottle of water. Oh, make sure
it's a powered condenser to increase the probability of electrocution.
The engineer who should and might have been fired if John Lennon hadn't hidden the
bottle/water/condom/mic technique behind his back? Geoff Emerickthree Grammies. The
effect they wanted didn't work, but they tried, and they continued to experiment, adding to an
impressive list of firsts, which we now take for granted: compression, close mics on drums, close
mics on strings (Eleanor Rigby), looping, Concrte, sampling synthesis (the Mellotron that opens
Strawberry Fields), music videos, reversal (Revolver), generative orchestration (A Day in the
Life), dubbing to mask weak vocals, controlled feedback (years before Hendrix), moving the tape
machines to the control room, phased vocals for richness (Tomorrow Never Knows), and
synchronizing two tape decks with a pulse tone.
I have a folder dedicated to flawed recording techniques. Taken out of the context of each
artist's standing in the music world they would disgust any engineer with any training. That is, an
engineer who is more afraid of liking what is bad than embracing what is good. I suspect that
strongly and narrowly opinioned engineers are clinging to something they've read or heard rather
than forming their own opinions with their own ears; knee jerk reactions (as with political
demagogues) in lieu of rational thought. I know Waits didn't use a $2000 mic and I love his
recordings. Most of the Rolling Stones' recordings are noisyboth hiss and hum. Hendrix
wouldn't be Hendrix without a healthy 60 cycle buzz.
This is even more apt for electro-acoustic music. I discovered early on that the spaces
between the samples, the mistakes, the noise from handling the mic, often contain the most
interesting material.
A good engineer is one who has lots of equipment and knows lots of techniques, but
doesn't feel obligated to use all of it/them all the time. A good engineer does what works
best with the limited time, storage space, budget, and a wide variety of patrons that
keep calling because he does what works. Deciding on a mic, preamp, and sample rate is similar
to setting levels on a mixer. You dont want to saturate resources, but you want to stay above the
bed of noise.
I can make a similar observation about live PA. For several years I played with a full
sized jazz band that never used any kind of reinforcement. You heard correctly, we never used a
PA, even on tour. At competitions we insisted they take it off the stage. Oh, sure, we were loud,
and we played some big halls, but we were soft too. We knew how to play our instruments and
we knew how to listen to one another. Ive adopted this director's philosophy.
I've also received plenty of calls from panicked stage managers because, for whatever
reason, the single announcer's mic isn't working. Sure, I try to trouble shoot, but sometimes I
offer this miraculous solution: "could you try just talking louder?" or "could you have people
stop talking and listen carefully." Turns out that works really well.
We listened to, and even danced to, acoustic music for thousands of years. Audio
reinforcement has become a crutch, and all audio equipment compromises and colors the sound.
Of course Bobby McFerrin's mic is not about reinforcement. He plays it like an
instrument. Also, early blues singers discovered that a mic allowed a greater level of intimacy,
which is standard procedure on female vocals such as Nora Jones or Tracy Chapman.




63
I live about 20 miles from the greatest snow on earth. I'm up there often, and it's not
always perfect; too wet, too crusty, or too old. On days like that I try to remember; there is no
such thing as bad snow, just bad skiers. Many platinum selling classics were recorded on
(especially by our standards) horrible equipment. It doesn't get in the way of the music. In
summary; use your skills as best you can with the equipment you can afford and focus on the art.
If someone criticizes your technique, suggest they bring a chicken to their next session. Waits
can have any mic he wants. He records with chickens.
Exercises
7:1 Experiment with noise cancelation headphones.
7:2 Record an ensemble or other stereo rich source using ORTF, x/y, Mid-side, and
mono. Compare the results.
7:3 Balanced Lines: In Amadeus, generate a sine wave at 40% amplitude in a stereo file.
Split the tracks. The playback (upper right corner of the track) will show front right
and front left. Change them both to front. On the second track, invert the phase and
playback. There should be no sound, as the two cancel each other out. In a separate
file, generate pink noise in mono. Select a section, switch to the sine wave drop a
marker anywhere. (This will ensure a precise paste position in both channels.) Use
option-arrow to position the cursor on the marker and choose Edit/Paste over.
Repeat for the other track. This will reproduce the effect of a balanced line; the sine
waves are inverted, and the exact noise has been introduced to both channels. Now
re-invert the second track. Note the missing noise, and the return of the sine wave.
Repeat this exercise using noise as the audio source and a sine as "noise." (Make
sure it's the same in both tracks; generate it as mono or choose Tracks/Convert
Track to Stereo.)
7:4 Noise Floor: In Amadeus, generate a sine wave at optimum levels in two tracks (or
files); same amplitude and frequency. Invert one and mix them to confirm that they
cancel each other out, and are therefore precise inversions. Reduce one by 60 dB
then increase it by 60 dB to its original volume. (This reproduces the effect of
recording one of them at a low bit depth, or at a high bit depth with too low levels.)
Listen to the effect. Finally, mix the inversion of the original wave, leaving only the
bit depth noise.
7:5 Signal to Noise: Realize Alvin Lucier's I Am Sitting in a Room.
7:6 Aliasing: be sure the sample rate is set to 44100. Generate a wave at 44000 Hz to
create aliasing. What pitch do you actually hear? Repeat at different sample rates
and frequencies.
7:7 Start with a high quality (44.1k, 16 bit, stereo). Generate separate files in the
qualities listed below. Use these files to copy and paste non-contiguous sections (so
that the edits are obvious), of musically accurate measures (i.e. maintaining the flow
of each measure) into one file with musically accurate, cleanly spliced edits. The
result should be a rhythmically accurate, but abruptly shifted collection of gradually
degraded qualities, illustrating the difference of each rate, depth, etc. Here are the
resulting qualities:
44k, 16 bit, stereo



64
44k, 16 bit, mono
44k, 8 bit, stereo
22k, 16 bit, stereo
11k, 16 bit, stereo
5k, 16 bit, stereo
5k, 8 bit, mono
7:8 Import into a logic session a stereo song that has very clear separation between left
and right channels (e.g., early Beatles). Move the default pan dial left and right to
confirm that you lose signal on the right and left. Insert a directional mixer control
by clicking on an open insert and confirm that adjusting it moves both signals left or
right.
7:9 Run these examples in SuperCollider. (Maybe wait until you have a few SC
chapters under your belt.) Boot the server (Language/Boot Server), then run each
set of lines inside the parentheses to see how bit depth and sample rate change a sine
wave, white noise, and an audio example you can choose. (Open an example that
has plenty of highs, like crisp and sizzly cymbals.) Move the mouse to change the
quality. The left top of the screen is the highest quality. Move right to reduce the
sample rate, down to reduce bit depth. Note the aliasing when the sample rate is
near the sine wave. Note that with the audio example, even with a terribly low
quality, you still recognize the example. I find this slightly amazing. You can resize
the scope for a better view of the wave.


(
{Latch.ar(SinOsc.ar([400, 600]),
Impulse.ar(MouseX.kr(22000, 5000))).trunc(MouseY.kr(0.001, 1.0))}.play
)

(
{Latch.ar(WhiteNoise.ar,
Impulse.ar(MouseX.kr(22000, 5000))).trunc(MouseY.kr(0.001, 1.0))}.play
)

(
({
b = Buffer.loadDialog;
a = PlayBuf.ar(1, b.bufnum, BufRateScale.kr(1));

Latch.ar(a, Impulse.ar(MouseX.kr(22000, 5000))).trunc(MouseY.kr(0.01, 1.0, 1))

}).play;
)





65
8. The Way Music Works
When does sound become music? When it's repeated.
My definition includes the silence of Cage, the imaginary music of Johnston, conceptual
music of Ives, bio-music of crickets, and metaphysical music of Oliveros, but for this text, well
narrow it down to my neighbors. If I hear a thump from the apartment upstairs I grab my first aid
kit, worried that someone has fainted. If I hear a second thump, I grab my WWE costume. If
there are three thumps, all evenly spaced, I grab my guitar; its a jam session.
One thump; someone fainting. Two thumps; pretend wrestling. Three or more thumps;
Meter
Music is repeated sound. Varied repetition is interesting music. Varying the volume or
accents of a pulse creates rhythms, which can be parsed into two musical ideas: groups and
divisions. All metered music boils down to groups and divisions of threes and twos. For
example, 3/4 time is a group of 3, division of 2; while 4/4 is a group of 4 (but essentially two
groups of 2), division of 2; and 9/8 is a group of three, but a division of 3. Additionally, 6/8 is
grouped in 2, divided by 3. Even more complex meters, like 7/8 or 5/4, are conceived and
performed in groups of 3 and 2, where 7/8 can be 2 + 2 + 3, and 5/4 is usually 3 + 3 + 2 + 2.
We count 1, 2, 3 to identify groups, and for the division insert "and" or "and a." (There
are many variations to counting divisions.) Below is an example meter with HH playing the sub-
division, the kick on the beat, and the guitar syncopated on the sub-division.
Meter 1 & 2 & 1 & 2 & 1 & 2 & 1 & 2 & 1
HH | | | | | | | | | | | | | | | | |
Kick | | | | | | | | |
Guitar | | | | | | | |
The simplicity or complexity of any style comes from how and where the beats sync up.
In this example, every other high hat matches the downbeat of the kick, but the other high hat
beats are in sync with the guitar. The complexity is often layered: lower instruments playing very
basic beats, middle ground instruments (such as rhythm guitar) playing interesting, but repetitive
beats, and the lead instruments as abstract or complex as the style merits. But it is important to
understand that (in metered music) the beats eventually come together in one way or another.
These relationships can be expressed as ratios. The high hat and kick are in a 2:1 ratio.
The guitar is a 1:1 ratio with the kick, but out of phase.
You can pair up more complicated divisions such as 3:2 or 4:3. Even though the beats
don't line up as often, it's still music because the important beats match. The 2:1 rhythms are the
bread and butter of the music industry, while 3:1 are less common. A 4:3 ratio is pretty rare, but
3:2 can be heard in many popular songs including This Will Be by Natalie Cole, Minute By
Minute by the Doobie Brothers, and Kashmir by Led Zeppelin, to mention just a few. Below are
illustrations of a simple 3/2 then 4/3. The next example illustrates how the beats of a popular
song might fall together. The lower instruments lay a foundation. The vocal part can be very
complex, sometimes in sync, sometimes free of the underlying meter.



66
1 2 3 1 2 3 1
HH | | | | | | | | | | | | | 3 against
Kick | | | | | | | | | 2
1 2 1 2 1
1 2 3 4 1 2 3 4 1
HH | | | | | | | | | 4/
Kick | | | | | | | 3
1 2 3 1 2 3 1
Vocal (complex variations)
1 2 3 4 5 6 7 8 9 A B C 1 2 3 4 5 6 7 8 9 A B C 1
HH | | | | | | | | | | | | | | | | | | | | | | | | | 12:4 (3:1)
1 2 3 1 2 3 1 2 3 1 2 3 1
P/G | | | | | | | | | | | | | 3:2 (with pulse)

1 2 1 2 1
K/S | | | | | 2:4 (1:2)
1 1
Snare | | 1:4
1 1 1
Kick | | | 1:4
1 2 3 4 1 2 3 4 1
Cymbal | | | | | | | | | 1:1

Everyone knows about groupings of 9/8 and 6/8, but here is something you might not
know. It turns out that pitch works the same way. Pitch is just very fast rhythm. Earlier we saw
that non-periodic (noise) waves could produce pitch if a small section of this noise source, any
section, was repeated. Even though the wave is very complex, the fact that it is repeated as few
as three times creates pitch. The duration of the section that is copied will determine the pitch. If
the selection is 1/100th of a second, 100 of them will fit into one second, which becomes 100 Hz.
The pitch is the reciprocal of the duration of the loop. Figure 8.1 is an illustration. First, a
millisecond of noise, then the noise repeated four times, and finally, a complex wave of an actual
sound (piano?) for comparison.
Fig. 8-1 Repeated Noise = Piano

Rhythms are in sync when the beats match. Likewise, pitches are in tune when their
frequencies match cycle for cycle. If one guitar string is vibrating at 440, the other at 441, they
sound (slightly) out of tune. To understand why, consider rhythms that dont quite match, for
example two cars at a stop light with their turn signals going. They may begin in sync, but since
one is usually slightly faster it creeps ahead of the other. Eventually they will be completely out
of sync, like the kick and snare. Eventually the faster light will catch up and again they will be
back in sync. Frequencies that differ slightly are the same. They may begin together, but slowly
(actually, quickly) they move completely out of phase, then back into phase. Below is a graph of




67
two frequencies moving in and out of phase. Ive increased the difference (200 and 210) so that
you can see the phasing in a few hundredths of a second.
Fig. 8-2 Phase and Constructive Interference


At the beginning of the example the two waves are added together (shown in the bottom
track). This is called constructive interference. At about 0.05" they are out of phase and cancel
each other out; destructive interference. This alternation between constructive and destructive
interference, in and out of phase, creates changes in amplitude. The change in amplitude produce
pulses, which are understood by performers as out of tune.
An interesting note: you can use these pulses for incredibly precise tuning. The number
of pulses per second is equal to the difference in Hz. If two pitches produce 3 beats per a second,
they differ by 3 Hz. If one is 500 Hz, then the other has to be 503. This is because they go in and
out of phase 3 times in a second.
! Since detuning a little seems to improve and thicken a sound, two questions emerge: what
is the threshold? When does in tune but phased become out of tune? And what is the threshold
between the same pitch, but out of tune, and two different pitches altogether? Our (unscientific)
experiments show that 1% is still in tune. 1% to 10% is the same pitch but out of tune. At 10%
and greater you hear two different notes.
Different can be used to create
Harmony and Melody
When any sound, even noise, is repeated it becomes music. When several frequencies are
played at the same time (harmony) or linked together in a series (melody) they become musical
ideas; melody or chord progressions.
If you're keeping score at home: thump = faint, two thumps = wrestling, three thumps =
rhythm, fast thumps = pitch, two pitches within 1% of each other = same note, two pitches
greater than 10% = harmony and melody.
Fig. 8-3 1:1 Ratio
If two frequencies match exactly, we hear them as the
same pitch. Using the same system of tics (conveniently set up
by the author during the discussion on rhythm) to mark the peak
of each wave, we see the two frequencies in Figure 8.3 match in
a 1:1 relationship. We hear this as the same note:



68

1: | | | |
1 | | | |

Rhythms that are different but connected by matching beats are considered music. The
same is true for melodic and harmonic intervals. Take for example 440 and 880, a 2:1 ratio.
Again, the tics mark the peaks of the waves.
2: | | | | | | | |
1 | | | |

Fig. 8-4 2:1 Ratio
! A 1:1 ratio is the same pitch and a 2:1 ratio is heard as,
drum roll, the same pitch! Any musician, even those with
abbreviations in front of their names, would say without
hesitation that these two frequencies are the same pitch. This is
called octave equivalence. That is: two frequencies that differ by
any multiple of two are considered equivalent. 261.6 is a C, but
so is 523.2, as well as 1046.4. They all belong to the pitch class
C. In music discussions it is often irrelevant which C I'm referring to. For example, C, E, G is a
chord that could be played anywhere on the piano and we would still call it a C chord.
To identify a specific pitch of any class, add a number to indicate the octave, C4 being
middle C. All notes between that C and the next C are in the fourth octave: D4, F4, etc. So C4 is
a pitch with a specific frequency: 261.6, and C is a pitch class that includes all multiples of
261.6.
Fig. 8-5 3:2, 4:3 Ratios
While 2:1 and 1:2 result in the same pitch, different octave,
other rhythmic ratios become different pitches, for example, 3:2
and 4:3. Two frequencies that are related by these ratios make up
the intervals of a fifth and fourth, respectively.

150 Hz 3: | | | | | | |
100 Hz 2 | | | | |

133.3 Hz 4: | | | | | | | | |
100 Hz 3 | | | | | | |

When they are mixed together, and this happens either on
the instrument or in the air, their constructive and destructive
interference creates another overlaying pattern, the cycle of which is the point where they come
back into sync. Figure 8.6 shows the two ratios again. The first two tracks are the individual
frequencies; the last channel shows how they add together to create a larger pattern of their
combined interference patterns. The first





69
Fig. 8-6 Constructive, Destructive Waves


Our music experience is made up of the patterns that result from the interference of
waves. We recognize them as intervals, chords and melodies, use them to tune instruments and
as clues for space and environment (reverb and echo).
In casual conversation I'm often asked about the nature of music; why do we use the
major and minor scales, why are there 12 notes in a scale, how do we account for the black and
white key arrangement? Do we accept the system used in Western music because that's what
we're used to (nurture), or is there a fundamental principle at work (nature)? What is the
universal field theory of music?
Music is Math
! All the intervals in Western music can be expressed as ratios. Figure 8.7 shows the white
keys of the piano. Intervals down are the reciprocal: An octave up is 2:1, an octave down is 1:2.
A fifth up is 3:2, down is 2:3. (And the math pans out. A fifth down, 2:3, then octave up 2:1 is
3/2 times 2/1, or 4/3.) The chart below describes the white keys on the piano beginning with the
traditional theory terminology of intervals and steps, then the MIDI interval (one piano key per
number), a pitch class example, then the ratio.
Fig. 8-7 Interval Ratios
Interval Steps MIDI Example up Ratio Example down Ratio
P1 unison 0 C to C 1:1 C to C 1:1
M2 1 step 2 C to D 9:8 C to Bb 8:9
M3 2 steps 4 C to E 5:4 C to Ab 4:5
P4 2 ! steps 5 C to F 4:3 C to G 3:4
+4 3 6 C to F# 45:32 C to Gb 32:45
P5 3 ! steps 7 C to G 3:2 C to F 2:3
M6 4 ! steps 9 C to A 5:3 C to Eb 3:5
M7 5 ! steps 11 C to B 15:8 C to Db 8:15
P8 6 steps 12 C to C 2:1 C to C 1:2
! And finally, an easy way to remember 8ve, 5th, 4th, M3rd, m3rd is that the numbers are
super particular (first number is one higher than second): 2:1, 3:2, 4:3, 5:4, 6:5. Just remember
the jump in the series for a 9:8 major second (what happened to 7:6, and 8:7?). These are the
ones I remember. You can easily calculate the other intervals using combinations or inversions.
For example, a m6th is M3rd down, then moved up one octave (4:5 * 2:1 = 8:5). A tritone is a
M3rd + M2nd.
It is more useful, and more logical to order them from lowest ratios to highest ratios:



70
P1 unison 0 C to C 1:1
P8 6 steps 12 C to C 2:1
P5 3 ! steps 7 C to G 3:2
P4 2 ! steps 5 C to F 4:3
M6 4 ! steps 9 C to A 5:3
M3 2 steps 4 C to E 5:4
m3 1 ! steps 3 C to Eb 6:5
m6 4 steps 8 C to Ab 8:5
M2 1 step 2 C to D 9:8
m7 5 steps 10 C to Bb 9:5
M7 5 ! steps 11 C to B 15:8
m2 ! step 1 C to Db 16:15
+4 3 steps 6 C to F# 45:32
And finally, theorists, especially 20th C theorists, simplify this system by grouping
intervals into classes. That is, a major third up (C up to E) has the same character as major third
down (C down to A), but also the same as a minor sixth up or down. This is not the case in tonal
music, since the third up implies the key of C, down it implies A-flat or E-flat. Since most 20
th
C
(art) music is post-tonal, key does not come into play, and only the fundamental character of the
interval matters. Also, the major, minor, perfect nomenclature has no bearing, so simple numbers
are used (which you already know; they are MIDI intervals). The theory is they all have the same
character. Just as all Cs are the same pitch class, all 7s and 5s, up or down, belong to the same
interval class.
The equivalency intervals up and down obviates values above a tritone. Intervals larger
can be identified by the inversion, since they are equivalent: 7 is a 5, 8 is a 4, 9 is 3, 10 is 2, and
11 is 1. Interval classes may seem like a complicated convolution, but they explain more than
just the scientific foundation of melodies, chords and intervals. They define the very nature,
character, and
Quality of Music
The second party question that inevitably follows a discussion of white keys on the piano
is this: Why does some music sound happy, bright, cheerful, and others somber, sad, confusing,
abstract, dark, even frightening. The answer is the same. (Spoiler alert.) Hard math is frightening,
easy math is cheery.
Seems too simple, but it's true. The character of a melody and the accompanying chords
come from the type of scale used. The clearest examples are major and minor. Music in the
minor mode sounds somber, serious, intense (Beethovens Fifth Symphony), while major modes
sound bright, hopeful, and cheery (ShBoom by the Light Brigade).
But there are many more modes than just major and minor. Consider these (simplified)
examples, which in my opinion, show a clear progression from bright and cheery to dark and
menacing, and finally abstract and confusing.
In this table I use the 20
th
C system, or MIDI values. The white keys on the piano are: 0,
2, 4, 5, 7, 9, and 11. Black keys are bold.





71
Scale Example Steps
Pentatonic Eastern music styles 0 2 4 7 9
Major ShBoom 0 2 4 5 7 9 E
Myxolydian/Blues Theme from Shaft 0 2 4 5 7 9 T
Dorian Are you Going to Scarborough Fair 0 2 3 5 7 9 T
Minor Beethovens Fifth 0 2 3 5 6 8 T (E)
Phrygian What to Do Before Im Dead (Kidney Thieves) 0 1 3 5 7 8 T
Diminished? The New S**t (Manson) 0 2 3 5 6 8 9 E
Chromatic Webern 0 1 2 3 4 5 6 7 8 9 T E
You will notice that the progression to darker modes includes more black keys (1, 3, 6, 8,
and T). In very general terms, more black keys = more dissonant music. Why? Because black
keys are harder math. Major and minor thirds are the best example. Minor scales sound darker,
more somber, because these two intervals have higher ratios, which mean fewer waves match,
which means more destructive interference. The reason This is the New S**t seems menacing
right out of the box is the first three notes use ratios of 8:1, then 45:32 and 6:5; a very dissonant,
unstable diminished chord.
Compare the ratios for the first three chords (from tonic) in Bachs WTK Book I
preludea very simple, accessible workwith the opening intervals (the first two are E and 6,
the two most dissonant intervals) of Webern's Op 27, interval to interval, since it's not tonal.
Bach: 1:1, 5:4, 3:2, 2:1, 5:2; 1:1, 9:8, 6:5, 8:4, 4:3; 8:15, 9:8, 3:2, 9:8, 4:3
Webern: 15:8, 45:32, 4:3, 16:15, 45:32, 3:5, 32:15, 4:3, 6:5, 9:8
With major through Phrygian the number of whole and half steps are the same. The
character relies on establishing tonic through repetition, phrase structure and cadence. With more
exotic collections, found in the music of Bartok, Crumb, Webern, or Babbitt, one can precisely
identify the character of any collection of pitches using
Set Theory
Take, for example, C, E, and G (0, 4, and 7). These three pitches make up three intervals:
0 to 4, 0 to 7, and 4 to 7. Each of these intervals has a character, and adds to the character of the
whole. To quantify that character, theorists tabulate all intervals into a vector showing 1 to 6.
The example above has an interval of 4, and an interval of 7 (but we use its inversion: 5), and an
interval of 3 (4 to 7).
Interval class: 1s 2s 3s 4s 5s 6s
Total: 0 0 1 1 1 0
Except for the 6, these are conveniently ordered by dissonance. An interval 1 is the most
dissonant and 5 the most consonant. I think the 6 is more dissonant than the 1, but many students
disagree. It is certainly more dissonant than a second. So if you place the 6 between a 1 and 2,
they are in order of dissonance. This chord, with the 6 moved to position 2, is 000111. One might
say it has a dissonance of 111 units. Compare this to a diminished chord: C, E, G, or 0, 3, 6,
where 0 to 3 is a 3, 0 to 6 is a 6, 3 to 6 is a 3. Tallied up, with the 6 to the left, this equals
010200. (One 6 and two 3s.) One might say this has a dissonance level of 10,200 units. More
dissonant than the major triad.
One of the most dissonant chords in tonal music is a French Augmented sixth chord: C, D
F and A, or 0, 2, 6, 8. The intervals from 0 are 2, 6, 8 (becomes 4). From the 2 they are 4 and
6, then from 6 another 2; 2, 6, 4, 2, 4, 6, or 022020.



72
This system can precisely compare the relative dissonance and consonance of any style of
music, but in particular, non-tonal styles. What is the most dissonant collection (on a piano)? The
chromatic cluster; CCCCCC (in hexsee, I told you we'd use it). The notes are 0 1 2 3 4 5 6 7 8
9 T E. Intervals from 0 are 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1. From 1 they are 1, 2, 3, 4, 5, 6, 5, 4, 3, 2.
From 2 - 1, 2, 3, 4, 5, 6, 5, 4, 3. From 3 - 1, 2, 3, 4, 5, 6, 5, 4. From 4 - 1, 2, 3, 4, 5, 6, 5. From 5 -
1, 2, 3, 4, 5, 6. From 6 - 1, 2, 3, 4, 5. From 7 - 1, 2, 3, 4. From 8 - 1, 2, 3. From 9 - 1, 2. And from
T - 1. Twelve 1s, 2s, 3s, 4s, etc. We have to use hexadecimal notation to indicate 12 in each
column.
Figure 8.8 shows a chart with works from three periods. Bach, where dissonance is (to
our ears) mild, Chopin's more chromatic worksrich, but still normal to most concert patron's
earsthen Webern, who most describe as a cat walking on a piano. These are just the opening
chords or in the case of Webern, note groups.
Fig. 8-8 Comparative Dissonance
Bach, WTK I, prelude in C Chopin, Op. 28, no 4 Webern, Op. 25, Pierrot Lunair
C
0
, E
4
, G
7
000111 E
4
, G
7
, B
E
000111 F
6
, F
5
, D
2
, G
7
, E
3
302111
D
2
, F
5
, A
9
, C
0
001131 E
4
, G
7
, B
E
, C
0
100122 A
9
, G
8
, C
1
, C
0
200111
G
7
, B
E
, D
2
000111 F
6
, A
9
, B
E
, E
4
002103 B
E
, B
T
, G
7
100110
A
8
, C
0
, E
4
000111 F
6
, A
9
, B
E
, E
3
011211 G
7
, E
4
, E
3
, F
6
, C
1
212345
D
2
, F
6
, A
9
, C
0
011211 F
6
, A
9
, C
0
, E
3
020400 F
5
, D
2
, B
E
, B
T
, E
3
, F
6
321333
G
7
, B
E
, D
2
000111 F
5
, A
9
, B
E
, E
3
022020 C
0
, A
9
, G
8
, C
1
, F
6
, F
5
113433
C
0
, E
4
, G
7
, B
E
100122 F
5
, A
9
, B
E
, D
2
011211 E
3
, D
2
, F
5
, E
4
302100
Totals: 112908 167178 571543
And it makes sense. We are just counting up all the intervals. (I'm sure my example is
riddled with errors.) Webern uses 1s and 6s more often than Bach or Chopin. Chopin uses more
dissonant intervals than Bach. It's just that simple: music is math, hard math is unsettling.
Consonance and Dissonance
are subjective and relative. Many books define consonance as pitches that sound
"good" together and dissonance as pitches that don't sound good together. This is wrong for two
reasons. First, it implies intervals must fall into one or the other category. They don't. Secondly,
it implies that you should avoid bad sounding dissonance. You shouldn't and we don't.
Rather, all intervals fall somewhere along a continuing scale of relative consonance and
dissonance, and musicians use intervals all along this continuum to achieve a particular mood.
Music students spend four full semesters learning to understand and carefully control the balance
of consonance and dissonance in common practice styles. At the end of the first year, a final
exam can drop an entire grade if they don't approach and resolve an augmented 4
th
correctly. A
more appropriate definition is suggested by the Latin root consonare: sounding together.
Intervals with low ratios have more constructive interference, and the waves coincide more
often; theylike rhythms of 1:1 or 2:1sound together. The waves of dissonant intervals
coincide less often, and thus have more waves that sound apart.




73
Fig. 8-9 Patterns of White Key Intervals

Using our ticks once again you can see the patterns (Figure 8.9) for each of these ratios.
Note that higher numbered ratios have a longer combined cycle, therefore more time between
coincident beats, which is harder to see on the page, and more difficult to hear. Higher ratios are
more dissonant and lower ratios are more consonant. The goal of the 12-tone school was
precisely to avoid simple relationships, thereby avoiding tonality. It is abstract and complex for a
reason; its harder math.
If the collection of ratios strike a balance that keeps our interest or matches our mood at
the time (which changes depending on the context; church, movie theatre, concert hall), the
music is effective. If a composers goal is to sooth he will choose simple relationships. If she
wants to unnerve us, or engage our intellect, then she may try more complex relationships. Even
if a composition is not what we expect, it can still be effective, if it achieves the composer's goals
through the use of relative dissonance and consonance. The same is true for rhythm; complex
rhythms either intrigue or confuse, depending on our ability to focus and the context of the work.
Simple rhythms are more visceral. They work well for, say, The Andy Griffith Show theme song;
bright, happy, comfortable. Complex or abstract rhythms and intervals are and were used for
more intellectual, mysterious moods, such as the Twilight Zone incidental music.
When offered a collection of ratios we intuitively look for the simplest combinations, the
1:1s the 2:1s, and 3:2s. Western tonal music works with motion away from stable, or consonant
structures, to dissonant structures and back to consonant again. That motion, and the relative
consonance/dissonance in infinite variation, mixed with a similar balance in rhythmic simplicity
or complexity, is what we find satisfying in the works of Bach, Wagner, Schoenberg, Chick
Corea, and Alison Kraus. All styles can be boiled down to motion to and from low ratios and
high ratios, consonance and dissonance, structure and prolongation, stability and instability, low
on the harmonic scale to high on the harmonic scale. Or as Schenker might put it; tonic (1:1),
departure to dominant (3:2) return to tonic (1:1).
Complicated? Note compared to



74
Tuning
My party guests are reassured to know that the intervals found on our modern piano are
based on such rational scientific principles. So I usually follow up with this unsettling truth; for
the majority of musicians it's a lie. I lied in Figure 8.7. We don't use those ratios for the keys on
the piano. In Figure 8.9 the white key intervals do not line up so tidily.
I recently visited the studios of a world-renowned luthier. He was an eccentric artisan,
filled with surprising insights. When we got to the fretted instruments, he made an off-hand
comment about how terrible modern guitars are. "What do you mean?" I asked. "Well," he said
dismissively, as though the whole world knew why, "you cant tune them."
I already knew this about pianos, but guitar was my instrument. How could I have gotten
to a college music program still ignorant of such a fundamental flaw? Turns out all keyed and
fretted instruments by their naturethe way they are designedcannot be tuned correctly, that
is, to the ratios we just described. There are not enough keys or frets to represent all the pitches
we use today. In addition, while non-fretted or keyed instruments such as the voice or violin can
tune to pure ratios they often don't, either because they need to match a keyed or fretted
instrument in the ensemble or because over years of acclimation (nurture) they have come to
accept the piano as "in tune," which it's not. The best example of this contradiction is choir
singing to piano accompaniment. The singers, if correctly trained, tune their notes to the piano,
which is incorrect. When singing A Capella, if correctly trained, they will sing slightly different
intervals.
! I can see you shaking your heads, so let's do the math. We'll start with the frequencies for
the black key 8 (used for both an A-flat or G-sharp) using the lowest possible ratios (most
consonant or in tune). Starting from C4 (about 261.6) we would go up a minor sixth (8:5) to A.
The result is 418.56. A G on the other hand is two major thirds above C (261.6 * 5/4 * 5/4),
which comes out to 408.75; not even close to the A. As a matter of fact, these two "enharmonic"
pitches, A and G, are nearly a quarter step (41 cents) from each other! Students are always a
little suspicious of these results (or they suggest some kind of rounding error), so I'll wait while
you dig through the kitchen drawer for a slide rule. Try major seconds down, then an octave up;
261.6 * 8/9 * 8/9, then * 2/1 = 413.4 Hmm thats right in the middle. How about a minor third
and a fourth: 418.56. How about just whole tones up: 419.03. Yikes! What about half-steps?
(438.43) Half steps down? (404.19) Which do we use for the black key 8; 418.56, 408.75, 413.4,
419.03, 438.43, or 404.19?
This curious, almost unbelievable warp in music, where logically equivalent but
mathematically different intervals will result in different frequencies is called the
Pythagorean Comma
Your stunned look is justifiable. I freely admit to relishing the labored emails I exchange
with engineers who dabble in music, or musicians who dabble in science, as they struggle with
the math. But the explanation is simple; it is because while we use one black key for both A and
G, they are different pitches. A cellist or violinist will play them differently. In a recent
recording session an internationally renowned producer stopped a well degreed performer and
said (paraphrased). "I believe your C was high." The performer wasnt offended, but he didnt
believe he was wrong. He matter-of-factly said "you are hearing it as a pianist, Im playing it as a




75
violinist," and then played three slow long notes asking "which C do you want me to play?"
That was followed by 15 minutes of very professional, reasonable, polite disagreement. It wasnt
an easy answer. Most violinists spend half their lives getting just one C to sound right. He could
do three. But despite experimental pianos with typewriter style keyboards ("Janko"just Google
microtonal keyboard) or split black keys to accommodate each pitch, our modern piano only has
one key for both. What do you do? Tune to one or the other? If you tune to the A, then the key
of C minor, which uses A, will be in tune. But the key of E major, which uses a G, will be out
of tune. Fretted instruments have a similar flaw. The precise position of each note changes
depending on the context. Our luthier guide explained that early guitars had movable frets to
accommodate such adjustments, but were difficult to manage. Fixed frets began to be used,
which raises a similar dilemma. Which note do you set the fret or tune the guitar to? If you tune
it to one, the other may sound off. This explains why you can tune your guitar to sound great on
a G chord, but an E sounds wrong; it is wrong.
Fig. 8-10 Movable Frets
Three centuries ago the music community picked one.
The practical result was you could only play in certain keys;
those that included the pitch you tuned to (e.g. A, not G). In
this system the farther you stray from those easy keys the more
out of tune it sounded. Many musicians, notably the renegade
progressive Bach, werent satisfied with such a restriction. The
compromise they proposed evolved into our modern equal
tempered tuning, where the strings are adjusted (the fifths are flat,
thirds are high) to be out of tune enough to represent all
enharmonic pitches on the keyboard, but in tune enough to sound
ok. It took nearly 100 years to be accepted, and the debate
continues, but in rarified circles. Bach's masterwork The Well-
Tempered Clavier includes fugues in all 12 major and minor keys
to prove the value and to encourage the migration to this tuning.
The accordion was most instrumental (pun intended) in world-
wide acceptance, because it was cheap and couldn't be tuned.
Another practical conclusion is that you cannot trust your
ear when tuning a guitar. The frets are set for equal temperament, so that's what you have to use.
The fifths have to be slightly flatter than what your ears tell you is correct. How can you make
such fine adjustments if
Tuning by Ear
For nearly twenty years I included this discussion in my theory and technology classes
before a smarty pants student raised this intriguing question: Tuners use stroboscopes to adjust
pianos to precise "wrong" frequencies. Modern guitarists use tuners. "What," a student asked,
"did they use in Bachs time, hundreds of years before electricity?" "That's 100 years," I
corrected before admitting I had no clue. I should have read the first part of this chapter, where I
point out that the difference between 440 Hz and 441 Hz is easily detected by counting the beats
as they move in and out of phase. Early tuners calculated the correct number of beats per second
for each fine adjustment and tuned so that the beats matched a metronome.



76
So the next time you are at a friend's house, play a few keys on their grand piano and tell
them its out of tune. When they counter that they just paid someone to tune it you can respond:
"I know, and its out of tune. The G is way off."
But there is a payoff: The acceptance of equal tempered tuning and the simplicity of the
keyboard "interface" made chromatic harmonies and enharmonic interpretations more appealing.
This allowed Beethoven a greater freedom in harmonic choices, which was expanded by Chopin,
taken to tonal extremes by Wagner and Brahms, laying ground for the inevitable leap of logic by
the second Viennese school to non-tonal systems. One could argue, therefore, that Bach, the
pinnacle of tonal thought, helped plant the seeds of atonality. (Furtive chords.)
Should our compositions reflect a distinction between A and G? Are there renegade,
progressive composers who are not satisfied by the constraints of 12 notes per octave? Will it
take us 100 years to give in? Is the next step in synthesis a piano that can play both?
Yes, yes, probably, and yes: Hermode tuning, which is available in Logic Pro.
Computer music is a phenomenal break through in the field of tuning. We can try ideas
that we only talked about twenty years ago. The piano, a machine, taught us to play and sing to
the equal tempered scale. Theres no telling what these computerized machines can teach us, and
where they can take us, as we'll see in future chapters.
Music is
the mathematical relationships of constructive and destructive interference resulting
from the ratios of sound waves. Intervals, chords, melodies, and even large-scale formal
structures, are mathematically related. The musical experience boils down to our search for
related patterns in sound, in time. We compare and match the patterns we hear with those in our
memory; from the micro level of 1000th of a second ago to the macro level of days and years.
When we hear two or three frequencies in a row we not only recognize each cycle of a wave as a
periodic pattern, and together their relationship with each other as a pattern (a set of ratios that
become a melody), but we match that sequence of patterns with memories of sets of frequencies
(melodies) from as far back as our childhood.




77
Exercises
8:1 Calculate the dissonance vectors for these segments of Wagner's Tristan und Isolde,
Steely Dan's Josie and Marius Constant's Twilight Zone. The notes are:
[F, B, D, G], [F, B, D, A], [E, G, D, A], [E, G, D, B] for Tristan
[F, E, G, C, E], [F, C, A, E, A], [B, D, A, D, F], [G, C, F, G]Josie
[F, G, C], [D, G, C], [A, C, G], [G, A, B, E]Twilight Zone

8:2 Using Amadeus, generate sine tones (in left and right channels) at the ratios for an
octave, 5
th
, 4
th
, and third. Convert the two tracks to mono to see the resulting
interference waves.
8:3 Using Amadeus, generate sine tones in left and right channels at the consecutive
intervals: an equal tempered fifth, then just fifth, equal tempered major third, then
just major third. Can you hear the difference?
8:4 Open a MIDI version of a fugue from the Well Tempered Clavier in Logic Pro.
Choose a "dark" major key, one with lots of accidentals. Open Project
Settings/Tuning. Explore different tunings. Find a tuning that was used in 1722.
Switch between it and equal temperament. Which do you prefer? Try Hermode
tuning. Can you hear a difference? Split them into separate tracks, each with a tuner
plug-in. Note the differences.
8:5 With the same fugue, open the piano roll window and select the first four bars.
Choose Functions/ Transform/ Random Pitch. (We will use this as a template, but
be sure to try the random pitch algorithm too.) Uncheck Hide Unused Parameters.
Select All under Pitch then select the seventh step of the scale for each octave in
use, (if the work is in B major, choose A3, A4, A5), and select fix to change
them to flatted sevenths. Repeat for each four bars, changing each step of the scale
so that the original major mode transforms into five or six of the other modes.
Bounce the results.
8:6 Bounce the exercise above in two of the tunings. Open them both in Amadeus and
copy/paste over so that you hear both tunings together.
8:7 Beginning at A 440, calculate each pitch
in Webern's Op. 25, no. 1 using pure
ratios. For chords, start with the bottom
pitch and move up the chord. Compare
the results with equal tempered pitches.
Here are the pitches:
F, F, D, G, E, D, G, C, C, B, B





78
8:8 Run the following example in SuperCollider, which realizes a free-just Frere
Jacques. Replace the array r with the ratios for the Webern above.
(
f = 440; r = [1, 9/8, 9/8, 4/5];
Task({50.do({arg i; i.round(0.1).postln; f = f * r.wrapAt(i);
f.round(0.1).postln; (freq: f, tempo: 2, legato: 0.3).play; 1.wait;}) });
)





79
9. Mix: Style, Dimension
The elements of a mix. Popular styles first.
Programs such as Logic Pro and Garage Band have made digital recording more
accessible than ever. Some argue that while earlier recording artists passed through a natural
filter of inaccessibility, the best rising to the top, today's crop of musicians can merely noodle
around on an electronic keyboard, bounce the file and print the manuscript then post it online.
Removing the struggle, the argument goes, has to lower the quality of music produced.
Music, and Machines
But remember the piano is a machine. It made music more accessible by simplifying the
representation (such as a single key for A and G) and the tuning (which is such a struggle for
string players). It is such a successful interface that any self respecting 3 year old can hammer
out Mozart. (Even other speciesyou've seen the videoscan plunk at the keys.) I believe it's
true that this simplification has produced billions of mediocre musicians, but it has also produced
millions of excellent pianists, thousands of superb pianists, and certainly more true masters than
in any other period of history. Furthermore, this machine has inspired composers to take music to
new horizons. Subject and Reflection, by Bartok, was written expressly for the piano keyboard
interface. In fact, the 12-tone school grew out of the enharmonic tuning, which inspired
composers to think outside the box of one key and closely related modulations.
Logic Pro, Max/MSP, SuperCollider, Cubase and Reson are rife with interesting sounds
and clever loops. It's easier than ever to sound good quickly. This rise of common experience
and mediocrity makes it all the more important to distinguish yourself. Noodling is not enough.
When performers of traditional instruments audition for a position you can assume they will play
correct notes. That's not enough either, and its not what committees look for. Performers
distinguish themselves and make their music memorable through technique, treatment, and
interpretation. The same is true for electronic and popular styles.
For example, the engineering on Bone Machine (Waits) is very distinct. It sounds like it
was recorded with a single cheap microphone set in the middle of a living room using
instruments from a junk yard or pawn shop. But so is the engineering on Steely Dan's Aja;
layered with carefully crafted reverbs, delays, panning, and EQs. Norah Jones (anything) is
natural, transparent, simply beautiful. The engineering on Marc Broussard's work is tight, even,
punchy, perfect for cutting through a noisy bar or the chaos of a road trip.
Though very different, I love all of these styles, because they capture the artists so well.
Like a skilled photographer, these engineers frame, filter, mat, light, focus, and compose their
subjects with a wide range of techniques. Electronic composition benefits from the same
attention to detail, beginning with
Mix Styles
! There are four styles, each named for the region where they evolved; LA (natural,
transparent), New York (aggressive, tight, even), London (layered with fx and digital sophistry),
and finally Garage Band (raw). You can certainly do an LA style in London or Garage style in
downtown NY or any of them in your basement.



80
Examples of New York style include ZZ Top, Dixie Chicks, (as well as most modern
rock/country), Kidney Thieves, Daft Punk, Reel Big Fish (and most Ska), and The Pretenders.
LA Style artists include Doobie Brothers, Norah Jones, Steely Dan, Willey Nelson, Eagles,
Ricky Lee Jones, and pretty much everything I do (in particular, classical recordings). London
includes, of course, most of the post Revolver Beatles, many of Kidney Thieves tracks (which is
a blend of NY and London), Hendrix (Experienced), Kidjo (Voodoo Child Return), and many
cuts from Zeppelin. Garage style: Waits, Dylan, and a lot of the Stones.
! We will narrow in on each style while discussing the techniques below, but one of the
best ways to distinguish each style is by examining the role of the engineer. In LA style the
engineer is transparent. In New York style he is a craftsman. For London style the engineer is a
collaborative artist, working along with the musicians. (The first, and quintessential example of
London style is George Emerick, who engineered Sgt. Pepper.) In Garage, the engineer is absent.
Mix Dimensions and Elements
describe the position and role each of the instruments has in the whole. Dimensions of
a mix are height, width, and depth. These describe the virtual space created with frequency's
ranges (height), pan position (width), and reverb and delay (depth). Absence of one or more of
these three is the single most common error in a student's portfolio submission.
The elements of a mix have a parallel in orchestration, where we talk about background,
middle ground, and foreground. There are similar components to a good mix. The background or
foundation is made up of instruments in the lower register, but more precisely repetitive simple
components: the drums, bass, possibly guitar or piano. They lay a foundation on which other
musicians build. The goal of a foundation is not to draw attention, but to provide a solid bed of
simple, clear rhythms out of which the more interesting elements can grow.
In the middle ground there are two elements with diametrically opposed characters. The
first is a rhythm. This is typically a keyboard or guitar playing an interesting, but repetitive idea.
It is interesting enough to draw your attention, but repetitive enough not to demand complete
focus. It is often the first catchy hook with which the song is identified. The guitar parts in The
Doobie Brother's Listen to the Music, China Grove, Long Train Running, and Dependin on You,
as well as ZZ Top's Tush, Eric Clapton's Cocaine, and Atlanta Rhythm Section's Spooky, She
Knows All My Tricks, and Voodoo are all good examples of a rhythm. It doesn't have to be the
guitar. In Stevie Wonder's work it is, of course, the keyboards, the tambourine in the Beatle's We
Can Work it Out. Sometimes it's a subtle offbeat snap of a guitar chord, as in Patsy Cline's Crazy,
or Elvin Bishop's Fooled Around and Fell in Love, or the guitar harmonics and the riff in Buffalo
Springfield's For What it's Worth. To summarize, a rhythm is interesting but repetitious.
The other middle-ground element is the pad; a cohesive, smooth sustained pitch, chord,
or series of chords that hold together and blend other components. The most obvious example,
almost clich in blues, is an organ (vocals or strings) playing quiet sustained chords. The organ
in Norah Jones Turn Me On, second verse, Bob Marleys I Shot the Sheriff, second verse, Tracy
Chapman's Give Me One Reason, and Willie Nelsons Stardust, are good examples.
The foreground elements are the lead (usually pretty obvious), and the fill. These are both
interesting, melodic, varied (not repetitive), and share the center of focus. The fill is as
interesting as the lead, but fills the gaps where the lead is not active.




81
! To summarize: Lead and Fill are interesting, melodic, inventive, and share the
foreground. Rhythm and Pad share the middle ground. Rhythm is interesting, but repetitive. Pad
is sustained and cohesive. Everything else is background and foundation.
Students seem to struggle most with the rhythm. I offer these suggestions: first, not all
examples are so cut and dried. An instrument may be a blend of several elements, or switch roles
in the middle of the tune, beginning as a rhythm, then evolving into a fill. Second, the key is
repetition and interest. No matter how interesting, if it repeats, it is a rhythm. We can relegate it
to our sub-conscious and focus on the lead and fills. Life in the Fast Lane, Eagles; Don't Stop to
Watch the Wheels, Doobies; Walk This Way, Aerosmith; Nearly Everything, Police; all contain
intricate guitar lines, but because of the repetition, they are rhythms.
Likewise, elements of a mix, though taught in the context of pop engineering, are often
what distinguish quality electro-acoustic compositions. Young composers tend to err to one
extreme or the other; either all middle-ground, repetitive elements with no clearly focused lead,
or all foreground material, fighting with each other for focus.
You dont have to have all five elements. Elements can also shift between one role to
another. To better familiarize yourself with these components, listen to your favorite music; try
to place each instrument in one of the categories. You will soon be surprised how easy they are
to identify, how effective they are in their roles, and how common they are.
Less with elements, but often with style, there are gradients. Students always disagree,
for example, about Kidney Thieves, Blood Sweat, and Tears, and Steely Dan. They have strong
elements of at least two styles. Bob Marley is a convincing mix of all three.
We can further characterize these styles by how they use each of the following.
EQ and Filtering (Height)
Fig. 9-1 Channel EQ
is built into every channel strip because it is
assumed that every channel will require EQ. The EQ window,
when double clicked, will add an EQ plug-in. You can add
more, or different EQs by clicking on an empty insert slot.
! The three parameters of an EQ are frequency cutoff,
gain, and Q. Cutoff is where in the range of frequencies the
EQ is applied. With roll offs and shelves, all frequencies
above or below that cutoff are reduced or increased. With
notch or peak filters, frequencies above and below the cutoff
are filtered. Gain is how much the frequency is increased or
decreased. Q is the width of the band of frequencies filtered. (Other apps such as Logic Pro
instruments or SC patches use the terms rq and resonance.) We will use these terms in later
chapters on synthesis.
The Q is a little counterintuitive in that a higher number is a narrow band of frequencies,
a lower number results in a wider band. The EQ in Figure 9.1 shows a low roll off at 57 Hz, a
broad-band (0.37 Q) boost at 186 Hz, a narrow band (2.10 Q) notch cut at 2000Hz, and a high
shelf boost. The EQ interface is intuitive. Click inside the shaded area of a band and drag left or
right, up or down to change frequency and gain. To adjust the Q, click on the small circle that



82
appears when the mouse hovers over the cutoff frequency. You can also click on the numbers
below the graph and drag them, or double-click to type in a precise value. I typically use the gain
to boost the band, which makes it easier to grab in the graphic interface.
! Some general suggestions about EQ:
Bypass the EQ often to remind yourself what you started with.
Remember that when you are boosting frequencies you are increasing the gain, the
same as you would with the volume slider. Adjust the levels to avoid saturation.
Start with the presets. Many engineers dismiss presets, arguing that every instrument is
different, and any preset will miss nuance. But the presets aren't random. Each is a
private EQ workshop with a professional. They are certainly worth trying, and a good
starting point.
Compare with recordings you know and try to match the sound.
Listening fatigue can skew your judgment. Take breaks. Trust your first impression
after a break or the next day.
Make small adjustments to improve the quality of a sound (e.g., for an LA style). Large
adjustments for effect (a London style). Cut deep and narrow bands to eliminate noise.
Always be aware that when you are removing unwanted sounds (hiss or hum), you are
also removing sounds you probably want (depth, crispness). EQ should be a last resort
for fixing signal to noise. Get it right in the first place.
When adjusting the EQ of two instruments with similar ranges (two guitars), consider
complimentary adjustment; boost in one the frequencies you cut in the other, and visa
versa, so they can occupy different ranges of the spectrum.
! Here are descriptions, reasons to boost, and reasons to cut each octave band.
0 to 25 Hz: "Rumble" frequencies provide special effects such as thunder, helicopter
thrash, explosions, and flutter. In music mixes there's not much reason to boost them. Rather,
they are a potential surreptitious source of noise. Most monitoring systems won't reproduce these
frequencies, but many home systems do, so you should mix with that in mind. There could be a 5
Hz rumble from an equipment room or AC that you'll never hear in a pair of headphones, but
your client with a 5.1 system will. Cut or "roll off" the final mix at about 20 Hz as a standard
mastering procedure.
Fig. 9-2 Clean Sine Wave From Low Roll Off
25 to 50 Hz: "Chest thump" frequencies are what you feel
in your body with a solid NY style rock mix. Boost them only in
your bottom instruments; kick, toms, and other drums. Cut them
in low melodic instruments (such as a bass) to bring out the
higher overtones for better recognition. Bleed from other tracks
(through an isolation booth wall or in the same room) will
interfere with the tracks you do want down there. For that reason, roll off all tracks that you don't
want in this range, even if they are incapable of producing frequencies this low.




83
A solid low end can be seen in the waveform in the audio graph. Figure 9.2 shows a pop
tune zoomed in far enough to see individual waves. The low frequency sine wave is very clear;
evidence that there are no phasing issues.
50 to 100: "Foundation" frequencies come from the drum set, bass guitar and piano.
Boost to fatten or warm up the sound. Cut if it sounds boomy, or to remove ground hum (60 Hz).
This will increase the clarity, even for instruments that can play below that.
100 to 200: "Warmth" frequencies come from the lower end of rhythm instruments such
as the guitar and piano, but also toms and snares. Boost to add fullness to guitars but also vocals.
Cut to reduce muddiness and bring out the lead instruments.
200 to 400: "Rhythm" frequencies make up the natural range of most rhythm instruments.
I try to keep this octave as flat as possible. Boost for a punchier bass or lower drums. Cut to
eliminate overbearing frequencies or feedback issues in live PA using the boost/sweep/cut
procedure covered below.
400 to 800: "Lead" frequencies make up the natural range of most melodic instruments.
Boost to bring out the lead but also to sharpen the attack of lower instruments. Cut to eliminate
overbearing frequencies or feedback issues.
800 to 1600: "Harmonic" frequencies are above most melodic lines, but provide the
harmonics of those instruments. They are what define the timbre of the lead. Vowels and
diphthongs are shaped in this range. Manipulate this octave to change the character of an
instrument, either adjust for a more natural sound, or increase for a (London style) megaphone or
cheap radio effect. Sweep through with a narrow Q for a wa-wa effect. Boost for unusual effects.
Cut if an instrument sounds cheap or boxy.
Fig. 9-3 Sonogram Of R, K

1.6k to 3.2k: "Consonant" frequencies are the k's, t's, ch's in speech, but also the attack of
most instruments. Boost for clearer lyrics and crisper guitar strumming. Cut to reduce sharpness
or edge and listener fatigue. This is also a common range for feedback.
3.2k to 6.4k: "Edge" frequencies provide s and sh sounds as well as cymbals and shakers.
Boost for clarity and brilliance. Cut also to reduce listener fatigue or to soften a mix. This is the
range of hiss from older tape machines, but cutting it will also take the edge off the mix.
6.4k to 12.8k: "Sizzle" is air and light cymbals, but also can be piercing and painful.
Boost for metallic sounds but also to liven up a dull vocal. Increasing slightly will lighten the
strum of a guitar. It will also liven up a reverb. Cut to reduce noise (hiss), but only in spoken
recordings, or to take off the edge and avoid listener fatigue.
! To review:
25 50 100 200 400 800 1.6k 3.2k 6.4k
Thump Foundation Warmth Rhythm Lead Harmonics Consonants Edge Sizzle
A common application of EQ is to reduce feedback problems in live PA. There is a law in
California requiring feedback on every PA. I know this because whenever a Hollywood hero



84
steps up to a mic to make an embarrassing, but pivotal speech, the PA squeals. Directors can't
seem to resist this clich to make the moment more uncomfortable. These movie engineers are
timid, afraid of feedback, and simply hope it won't happen. But problem frequencies need to be
confrontedflushed out and eradicated long before the eventusing
Boost, Sweep, Cut
Boost the gain of a single mic until it is on the verge of feedback. When the resonance
begins pull it back just a little. Next, use a narrow band EQ and sweep it slowly through the
general range of the offensive tone. When you hit it, it will pop out like bad tooth being tapped
by a dentist. Cut by dragging the band down. Rinse and repeat until you've found all the resonant
frequencies in the hall. Not only will this reduce the chance of feedback, but also you've
compensated for the harmonic character of the hall, resulting in a more even frequency response.
If you don't have a nice graphic interface (for example the selectable EQ on a mixer), and if you
have a musical instrument handy, you can use it to fish around for the pitch that emerges from
the sweep, then (assuming you've read Chapter 5 and can calculate frequency from pitch class)
reduce that frequency. We work with a few pianist who, at the first hint of a feedback ring, will
quickly find it on the piano and yell back the pitch so we can calculate the frequency.
Use the same technique to find annoying frequencies in a mix; a boomy guitar, nasally
vocal, honky saxophone.
Noise Reduction Algorithms
are the holy grail of plug-ins; something that will remove the hum and hiss of a low
quality recording. These work by first reading a sample of what you consider noise, analyzing
the frequencies and amplitudes, then applying gates on selective bands. They do well with
speech, but I've never had success with music. They create too many artifacts. I remain hopeful,
but dubious.
Panning (width)
can be adjusted with the knob just above the volume slider. It's namePan/Balance
Controlreveals a flaw. Pan and balance are different, and it is confusing to use both terms for
one knob.
This is because on a mono track pan and balance are essentially the same. But with a
stereo track they are very different. When a mono signal is routed to a stereo output, it is split
equally in both channels. (You can replicate the effect manually by duplicating a mono track
and sending one to output 1, the other to output 2.) This effectively places it in the center of the
field because we hear it at the same level in both ears. Turning the balance knob to the left turns
down the volume in the right channel. The aural effect however is a pan; moving the instrument
to the left or right in the stereo field.
! But on a stereo track the information in the left and right channels may be and probably is
different. In the case of a stereo drum set, the toms to the left and the hi-hat to the right. The
balance control in this situation will turn down the right or left channel. The effect is not a pan,
but a balance. Moving the knob all the way to the right will turn the left channel off. You will
lose the toms.





85

Fig. 9-4 Pan, Balance, Directional Mixer
For true panning on a stereo track or sub-master you have to add a
directional mixer as an insert. Turning the knob to the left will not simply
reduce the amplitude of the hi-hat (for example) in the right; it will increase it
in the left, effectively moving it in the stereo image.
! To summarize: the default knob effectively functions as a pan on a
mono track, but as a balance mixer on a stereo track. A directional mixer must
be inserted on a stereo track for true stereo panning.
Most of the engineering I do is live classical performances. The stereo image is a
reproduction of the actual positions of the performers. Pan never comes into play. Even so, I've
gathered some guidelines about generating an image through panning in multi-track recordings.
Again, I encourage you to listen and analyze your own examples.
Extreme image placement and real-time change of placement is common in London
style mixes. For both New York and California the panning should be more evenly distributed
and never change. Spatial effects, especially dynamic effects, should always be a part of
electronic composition. It will set your work apart.
Your individual tracks may be either mono or stereo, depending on the source. Even if
stereo, consider panning (with a directional mixer) to one side or the other to avoid big mono.
In California style you would place the instruments where you might expect them on
stage. For a jazz group the piano on the right, the bass on the left, the drums a little off center,
horns behind the piano, and so on. For a New York mix, consider panning based on the roll
they play in the mix. Place the lead and fill a little off center opposite each other. Place the
guitar and piano opposite, as well as the bass guitar and bass drum. For a horn section, (though
back and to the right in an LA mix), you might pyramid with the lead in the center, horn II and
III slightly left and right, IV and V harder left and right, as they often provide support.
Fig. 9-5 Gain Control, Mono
Pan position changes the blend of a channel and therefore can
improve or worsen phasing. Phasing issues are more evident in mono. For
that reason, consider fine-tuning the pan position in mono. Yes, you read
correctly; pan in mono. Place a gain control on the master track, select
mono, then make small adjustments to improve the balance, listening to see
if something drops out or pops out.
Pan overdubs either both center (vocal), or both hard left and right (rhythms).
Compression
controls volume. The goal of most compression is uniformity. Two typical
applications are vocal and bass tracks. Basses, especially upright, are notoriously inconsistent in
attack and level. Even the best performers struggle with dynamic control because of the resonant
nature of the body of the instrument. This is also the case with inexperienced vocals.
Compression can be used to correct both.



86
It was first used in radio to protect equipment and avoid distortion by reducing
amplitudes that would exceed the available threshold. Artists heard their music over AM radios,
post compression, and liked the sound. The uniform amplitude cut through the small speakers
and noisy environments.
Geoff Emerick was the first engineer to intentionally apply compression to drums to alter
the character of the set (A Day in the Life). It is now standard.
Fig. 9-6 Compression and makeup gain

! The four main parameters are threshold (the level, in dB, where compression is applied),
ratio (the amount the amplitude is reduced), attack (how quickly compression is engaged) and
release (the time it takes to return to normal). Figure 9.6 shows three audio waves. The first track
has three soft notes, one loud note, then three medium range notes. The first three pitches are at
about -9 dB. The fourth note is -3; a difference of 6 dB. The goal is to first bring the louder
amplitudes down to the same level as the lower volumes, then raise all levels. To accomplish this
you would set the compression threshold at -9 dB, so as not to change the first three notes and
only one or two of the last four in this example. The second image shows the results of a -12 dB
threshold with a light compression ratio (3:1). Notice the first three notes have not changed, but
the loudest note has been reduced. The last four have been modified slightly. With the additional
headroom you can raise the level of the entire track, shown in the third example. Most
compressors also have a control for make up gain.
Compression is used extensively in New York and creatively in London style, sparingly
in LA style. It is common to compress every channel, maybe slightly, and often the sub-masters,
and masters in a NY mix. A snare drum, for example, through a handful of sub-mixes, may have
compression applied eight times before it reaches your ears.
Heavily compressed styles are great for the car, dance venues, and sports events, because
the amplitude needs to be consistent to better cut through competing noise. But dynamic change
is an important expressive tool in LA style, and even more important in classical programs.
Rampant, knee-jerk compression is often criminal and painful to listen to. Keep in mind that
dynamic range gives art music expressive power. Compression flattens that dimension. A
century of technological progress and yet popular recordings have less dynamic range than an
Edison phonograph cylinder of 1909.
There are two cases where I will use compression on classical performances; to squash
Mr. enthusiastic concert goer, eager to demonstrate his erudition by bolting into an obnoxious
applause before that last beautiful note fades in the hall (did that sound sarcastic?), and to lower
ever so slightly operatic vocalists, who are notorious for singing an entire concert around -12 dB,
then nailing one note at -2 dB, defining the limits of the entire recording.
Figure 9.7 shows three examples of differing levels of compression. The first is a NY
style (She's Got a Girlfriend Now, Reel Big Fish), then LA (Stardust, Willie Nelson), then a
classical program (Kantate Nr. 2, op. 31, Webern). The first is in your face all the time. The




87
second is consistent, but expressive, the last certainly has loud spots, but very, very soft spots
too, which is the whole point of most classical work.
Fig. 9-7 NY, LA, Classical Styles



Other common applications:
To increase the sustain of a guitar or snare. By compressing the first and loudest part of
the attack you are then able to raise the decay substantially. In effect you are turning the
volume down just as the note is played, then raising it as it dies away. (For this effect you must
have a fast release.) This is one of the techniques (including riding the faders) used for the final
"infinite chord" on A Day in the Life, Beatles. (Listen carefully for Ringo's shoes creaking in
the right channel near the end.)
In PA work, especially political speeches, compression is apparently mandatory. It
usually raises the noise floor.
The commentary in sporting events is compressed with a fast attack and slow release.
This isolates nicely the color commentary while maintaining the sports ambiance. When the
announcers stop speaking, you hear the crowd behind them, then they disappear at the start of
the commentators next sentence.
"Ducking" is a type of compression where the volume of a background musical track is
lowered whenever the voice-over is present. (Covered in more depth under side-chains.)
Reverbs and Delays
account for the depth of a mix. It is the second most common omission (after image)
by inexperienced composers and engineers.



88
Fig. 9-8 Reverb

! There are three key parameters in a delay; delay time, feedback, and mix. The delay time
is set in milliseconds. Feedback controls how many repetitions there are before the echo dies
away. (You can increase this until the delays perpetually build on themselves rather than
decrease. Combine this with an EQ to carefully control the evolving echoes.) The mix controls
the blend between the original ("dry") signal and the delay ("wet"). It is either a single control
labeled mix, or two controls labeled dry and wet. Delays are more effective in stereo. Selecting
the plug-in Stereo Delay-mono to stereo, will split the source into two channels so that they can
be treated differently, for example slightly different delay times in each channel.
Doubling Delay
Fig. 9-9 Slap Echo, Doubling
creates an effect similar to overdubbing. This is
intended for a mono track. Leave it panned center. Add a stereo
delay (mono " stereo). Turn Beat Sync off. Turn the right output
mix to 0% (no delay) and the left mix to 100% (all delay). Set the
left delay very short, say 80 ms, which produces a doubling of the
original track. Increase the feedback for a similar early Beatles
treatment. (Lovely Rita Meter Maid, A Day in the Life, Being for
the Benefit of Mr. Kite, Beatles, but also Still Rock & Roll to Me,
Billy Joel.) Alternate method: leave both output mix levels at 50%
and set left delay to 50 ms, right to 80 ms. This places the original
in the center and the two doubling delays left and right. Once you've settled on the effect you
like, adjust the location within the stereo field using a Directional Mixer as described above.
Synced Delays
match the tempo of the song. For example, there is a sixteenth-note triplet delay (on
the "sh-k") at the beginning of Come Together.
! Since tempo is expressed in beats per minute, but delay time is set in milliseconds,
getting the correct delay requires some math. To calculate the duration of each beat, divide the
tempo by 60: 60/bpm. Multiply that by 1000 to convert to milliseconds. Each beat of a tempo at
120 bpm (60/120 * 1000) is 500 millisecond. This doesn't mean you have to set the delay to 500
ms, but good choices would be multiples of that; 250 (for an eighth note delay), 125 (sixteenth).




89
The tempo of Come Together is 82 bpm. Eighth notes would be at 164. Sixteenth triplets
(multiply by 3) would be 492 bpm. 60/492 * 1000 = 122. So that delay was set to 122ms. The
formula simplifies to 60000/bpm = ms delay.
You would expect Apple to include a method to sync a delay to a tempo automatically,
and of course they have. To use it, the session needs to have the correct tempo. If you recorded
the session using Logic's metronome, then the tempo is already correct. Most musicians prefer to
work without a metronome. In this case, the first step for a synched delay is to set the tempo of
the session. This is done in the transport bar by clicking the default 120 and dragging up or
down, or double clicking and entering a value. Next, in the delay select the Beat Sync button.
You can now select quarter, half, eighth, or sixteenth. You can also adjust the Groove to deviate
from the exact tempo. I never have two delays exactly the same, adjusting one groove slightly off
from the other (52.3% in the example). Note there is no option for a sixteenth triplet, so to
replicate the Beatles effect you're just going to have to do the math.
Synced delays are used in NY and LA style, to add a pulse that breaths with the beat. In
London Style use
Asynchronous Delays
to create complex effects that stand out. Crazy and Arsenal by Kidney Thieves are
both good examples. Delay Designer has so many modulation options it transcends delay (as a
tool to add depth) into the realm of modulation. The Warped collection (where I always start)
should keep you busy for hours.
Chorus
performs a similar function to a doubling or slap delay. The signal is duplicated then
detuned or delayed by a small enough amount that the two blend as if doubled. The sound is very
homogeneous, maybe too much so, since it is a precise duplication.
Serial Routing
describes an effect that is inserted directly into the signal flow. A good example of
serial routing is an electric guitar with pedals. The guitar plugs into one unit, then out of it into
another, then another, then another. If any item in the chain lost power you would lose all signal.
Everything we've done so far has been serial. Since all of the signal passes through serial routing,
all the signal is processed. That is why some effects give you the option to mix dry signal with
wet. EQs and compression process the entire signal, and cannot be blended with dry signal in a
serial path.
Fig. 9-10 Channel Strip, Serial Signal Flow
! Since the signal is processed in series, order matters. Should you apply EQ
after the reverb? Or apply reverb to the EQ? If you place the reverb after the
compressor, then you are reverberating a compressed signal. If you place it after,
then you are compressing the reverb, and it will change the decay.
In logic, signal flow is from top to bottom. The channel strip in Figure 9.10
has a Tuner first (which is disabled), then a Noise Gate, Flanger, BitCrusher, EQ,
then compressor. After the inserts the signal passes through the level control and
pan. When a new plug-in is inserted, Logic virtually disconnects the cable between



90
two units, places a new one between them, then plugs the output of the one above into the one
below, then that out into the one below it. Figure 9.11 shows what the channel would look like if
it were laid out on stage like a guitarists set of pedals:
Fig. 9-11 Signal Flow

! Many engineers place an EQ before and after a set of DSP inserts to adjust the original
signal and adjust after DSP. Compressing after a reverb will exaggerate the length of the decay.
As a general rule: Amp models, flangers, phasers, complex filters and modulation (that are
intended to create a sound rather than adjust it) first, then EQ, compression, delays, reverbs.
Exercises
9:1 Begin with a source that is rich in upper harmonics (live or recorded). Add a delay
and increase the feedback until it perpetuates, then pull it down slightly. Add an EQ
and boost a narrow band, sweeping for frequencies. Adjust both the feedback and
EQ to "play" the evolving patterns.
9:2 Start with a four-track session (stereo drum set, bass, and two rhythm or lead
instruments). On one rhythm instrument, pan slightly right; add a slap delay with
dry signal in one channel and the delay in the other. On the other rhythm instrument,
pan left with a sync'd delay, dry in one channel, wet in the other. Apply a
complimentary EQ to these two. Add a reverb to the drums. Adjust the EQ of the
drums and bass. Add a compressor to the bass and drum set. Add a compressor,
gain, and multi-meter to the master channel. Check the mix in mono and in reversed
phase. Demonstrate "before" and "after" with automation; begin with all your
modifications off (pan center, level at 0, fx bypassed), then turn them all on at once.
9:3 Begin with a simple five or six track dry mix. Mix in both LA and London styles.
9:4 Using examples in Chapter 12 as a template, provide an analysis of your 5 favorite
mixes.
9:5 From your music collection, list work, composer, and minutes and seconds (if
appropriate) of five examples each: NY style, LA style, London Style, Fill, Rhythm,
Pad, and overdubbing. Find one example each of a slap delay, synced delay,
asynchronous delay, and dynamic panning.
> > > > > > > >




91
10. Auxiliaries
Sub-mixes, sends, and headphones. Post and pre-fader.
When preparing for a remote recording I go through a mental checklist that links outputs
with inputs, tracing the audio all the way from the instrument to my ears. This helps me pack all
the correct gear: Piano " microphone (clip, stand) " cable from mic to house patch bay (do I
need a gender adapter?) " patch bay in the control room " patch bay cables to the preamp or
mixer (power for the mixer) " cable from the mixer to the laptop (400 to 800 adapter?) "
power for the laptop " headphones from the laptop to my ears (ears to brain, brain to frontal
cortex, etc). This is a very common
Signal Chain
When there is a problem, say a hum in the left channel (which I had just last night), you
need to locate the weak link in the chain using a swap and follow strategy. At any point in the
path you can swap another signal chain (if stereo, left w/ right). If the noise moves with the swap
(i.e., it was in your left ear, now it's in your right), it is somewhere between that point and the
mic. If it does not move, it's between that point and your ears. For example, you have a stereo
pair connected to a stereo cable, white for left, red for right (red is always right) plugged into the
mixer. You hear noise in the left ear (the white cable). At the mixer, switch the white cable to
channel 2 and switch the red cable to channel 1. If it's now in your right ear, the noise is the
cable, mic, or something in the piano. If it is still in your left ear, its the preamp, channel, a dirty
pot, your headphone, in the room, or your ear (no kidding).
With this particular hum I first tried turning around the headphones, that is, swapping left
and right. (Rule of thumb: the headphone cable is always the left signal.) It stayed in the left ear.
That meant it was after the headphoneseither my ears or in the room. It was from a candy
machine through the wall.
If you're working with a lot of mono channels, replacing components or choosing
different patch-points will give you the same information.
Digital audio workstations also have a signal flow, though more illusive since you can't
physically trace it down cables. Each audio channel strip (and plug-in for that matter) has in
input and output. The top slot of the I/O for audio tracks allows you to choose an input source
from the interface, which then connects to a real mic on the floor. The default output for each
track is stereo out. Since the output channel is the final destination before it is sent to your
interface and headphones, it has no choices for input or output.
Instrument tracks also have an input, but the connection is to one of Logic's built-in
synthesizersjust as you would connect a keyboard into the line input of a mixer.
It is often useful to arrange tracks in
Groups
A drum set may have 5 to 7 mics. You can adjust the level of each one, but what if you
want to bring them all down proportionally? It would also be useful to mute them all at once, or
solo them all. One method of modifying a group of tracks is to first select them using click drag



92
or shift click. All changes will be applied across the selection. This is temporary. They are
grouped only as long as they are selected.
The group feature creates a permanent group. The group select window is between the
track name (e.g., Audio 1) and the automation (default set to off). Select all the tracks you want
grouped and click in this window to define a group and choose what actions are applied as a
group. !-G toggles the group on and off ("clutch") if you want to modify only one setting in a
group. Truth is, I rarely use groups because
Busses and Auxiliary Routing
! give the same functionality plus allow more efficient use of serial effects. Busses are
virtual patch cables behind the user interface. They are not assigned to any input or output by
default and are meaningless until assigned. There are three applications of auxiliaries;
monitoring, parallel effects, and
Sub-masters
where you send a group of channels to an intermediary mix between the original track
and the final Stereo Output.
In a single session you may have 7 mics on a single drum set. You can adjust the gain on
each track, and use groups or select to adjust several. This is also true for background elements;
drums, bass, guitar, maybe piano. But how would you add an effect (compression, reverb, delay)
to just those tracks? The solution is routing these tracks to a sub-mix. To insert a sub-mix you
have to disconnect the output from Stereo Out and reroute it to a bus. Which bus? It doesn't
matter. It's just a cable.
Select all the tracks you want mixed together and click on the output (Stereo Out) of any
selected track and use the pull down menu to select bus, then any bus number. Choose 47 to
reinforce that it doesn't matter. (Of course you should eventually order them logically. I do
auxiliaries subs on 1-16, reverbs and delays 17-32, and above that monitoring. But it really
doesn't matter.)
This single action has several results. It will connect the output of all the selected
channels to bus 47. It will create a new auxiliary channel, which will appear near the right of the
mix window. The input of that auxiliary will automatically be set to 47, essentially connecting
the output of all selected tracks to the input of this new auxiliary track. The output of the
auxiliary track also defaults to Stereo Out. You now have a sub-mix.
More channels can be added to this sub-mix at any time, and you can change the bus it
uses or output to another bus. You might do this in order to stack sub-mixes, sending all the
drums to a "drum" sub, then that to a "foundation" sub, and that (along with horns sub, strings
sub, voices sub) to an "orchestra" sub.
Figure 10.1 shows the I/O section of a sample session with sub-mastering. The outputs
and corresponding inputs are color coded. The output for Audio 1-3 are no longer Stereo
Output, but rather Bus 47. Auxiliary 1 has bus 47 as it's input. This is the drum sub-master. The
output of the drum track is not Stereo Out, but bus 50, which is routed to Aux 2; my foundation
sub-master. The bass track is also routed to bus 50. The guitars and keys (49) go to a rhythm sub
(Aux3), which in turn is routed to Aux 2. So Aux 2 is a sub-mix of sub-mixes (and bass), but it is




93
still not routed to the main output, but rather Aux 5 via bus 53. Track 8-9 have a sub-mix, then
they join the foundation sub-mix at Aux 5. Audio 10 has no sub-master. It is routed directly to
Stereo Out. Follow the output (bottom color) to the matching color input in the upper slot.
Fig. 10-1 Sub-Masters


I may have gone overboard with this example to demonstrate the flexibility of grouping
this way. At any time I can listen to just the guitars, or all the foundation, the voices and the
rhythm, the rhythm and the drums, and so on. The beauty of DAWs is that you are not limited to
the number of sub-mixes, where in real life you'll be lucky to have one or two (stereo) subs.
A single effect (compression, reverb, EQ) can be applied to the sub-master. This is more
efficient in terms of DSP, but also your workflow. One change to that single plug-in effects the
entire sub-mix (as opposed to placing a compressor on each channel, then having to change the
settings on them all if you want to tighten up the entire set). You can adjust the level, mute, or
solo all the instruments at once. The balance you spent hours achieving between each individual
element of the drum set will be preserved. If you want to adjust a single item, you can do that on
its own track.
I like to have my sub-mixes next to the channels they are receiving. Unfortunately, you
can only rearrange tracks in the arrange window, not the mixer. To do that, you have to place
them in the arrange window. To do that, select all auxiliaries, control click and choose
create/select arrange track. Finally, add colors for clarity, festivity, or added confusion.



Other tricks.
Double click on any output (say, Bus 47) and the auxiliary channel that receives that bus will
become highlighted.
In the inspector there are two channels shown; the selected channel, and the next channel in the
signal chain.
In the upper right hand corner of the mixer click on Single to show the entire path of any single
selected channel.
When soloing a track, logic automatically solos all sub-mixes along that chain.



94
Parallel Effects
are the second application of auxiliary routing. Consider a mix with six vocals; four
backups and two leads. You will probably want the backup vocals deeper in the field (more
reverb) than the leads. You also may feel a female vocal benefits more from the reverb than the
male vocal. Placing a reverb on each channel is inefficient, yet using a single reverb on a master
does not allow the flexibility of a different wet/dry mix for each instrument. The problem is this:
you want independent control over the dry and wet mix, but you want to use a single reverb. You
need two mixes, the dry mix, and the reverb mix.
Fig. 10-2 Reverb Mix vs Dry Mix
The solution; split them into two mixes.
One main mix, the other an auxiliary mix for
reverb. Figure 10.2 shows a possible dry/wet
mix. Blue is the dry mix, green the reverb mix.
Note that all the backups are at the same level,
but the reverb for these same channels is greater,
and all the reverb levels for the backing
vocalists are greater than the leads. Similarly,
the male vocal is louder than the female in the dry mix, but the female has more reverb. The only
way to achieve this is with an auxiliary send. Of course, Logic, and any mixer, digital or steel
and plastic, will auxiliary sends.
! All the plug-ins we've used so far were placed as an insert in the channel strip. This is
called serial routing. The effects on a channel strip are part of the main routing, in series. When
you use an auxiliary mix it is called parallel routing. The signal is syphoned off to create a
second auxiliary signal flow which is treated with DSP then re-inserted into the final mix.
It is parallel because it runs parallel to the serial flow. Imagine a park with water pipes.
You have a main pipe carrying water to the fountains, but you want to add treatment in precise
amounts, so precise that you can't add it to the main stream, which varies in size. So you attach a
small pipe that takes some of the water along a parallel route for treatment. It is then added back
to the main flow before exiting at the destination.
Note that with serial reverbs and delays it's important to set the balance between dry and
wet signal on each plug-in. In a parallel system the dry signal is supplied through the main
routing. For this reason the parallel reverbs don't need and shouldn't have any dry signal. The
amount of the effect heard in the mix is controlled by the level of the dry signal being sent into
the auxiliary channel.
! In short, serial reverbs: blend of dry and wet mix. Parallel reverbs and delays: 100% wet
(no dry signal).
To add an auxiliary send, select all the tracks you want to send (and there is really no
reason not to select them all, so select them all), then click on an open Sends slot and choose a
bus. Which bus number? It doesn't matter. A new auxiliary track will be created with that bus as
its input. On this new auxiliary track you can place a reverb, delay, or even compressor. This is a
parallel effect. How is this different from a sub-master auxiliary track? The sub-master is serial;
in series. It is part of your main mix, and you adjust the levels using the gain sliders. The
auxiliary track is parallel; independent of the main signal flow. You adjust their levels with the
small knobs to the right of each send. These levels can and should be different from the main.




95
Fig. 10-3 Auxiliary Sends vs. Sub-masters



Figure 10.3 shows the three different types of auxiliaries. Tracks 11 and 12 (BU Voc) are
being routed to Bus 51 using the I/O section, which runs to Aux 4 (labeled Voices). Auxiliary
send 2 (the second row of blue boxes) are connected to Bus 17, which is routed to the input of
Aux 6, labeled Reverb. To the right of each Bus 17 is a small knob. This is the level being sent to
Auxiliary 6. While the main mix has all the channels at the same level except Voices and Backup
(-7.2 and -1.4), the auxiliary mix 1, routed to Bus 17, therefore Aux 6, which has a Space Dsn
plug-in, is the reverb mix. It's levels are very different; some of track 13, more of track 14, none
of 15, 11, or 12. The reverb (Aux 6) is sent to the final mix with these relative amounts of reverb.
So the Voices will have some reverb, and Backup will have a lot. The third type is send 1, Bus
11. This is being used as a monitor (covered next).
As you raise the level with the knob to the right of each Bus 17 you send more signal to
the reverb. It is not uncommon to have four or five auxiliary fx sends. They are handy for trying
different types of reverbs. Real life example: a marching band had recorded in a very dry room
and wanted to match another recording done in a very live stadium. We did 10 auxiliary sends.
On each auxiliary channel placed a Space Designer with a different stadium convolution reverb.
The directors could easily solo one stadium, adjust the level, even mix and match. They found a
matching sound within a half hour. As a matter of fact, most of your reverb and delays will be
auxiliary. The only reason for a serial reverb is if you're doing a London style effect to set that
instrument off with a delay or character of its own.
! There are now five critical mix points you need to monitor and adjust: The dry signal,
controlled by main sliders of each track; the wet signal, controlled by the small knobs next to
send 17 on each track; the sub-master, controlled by slider on the sub-master track; the master
reverb mix, controlled by the slider on the reverb track; and the master, controlled by the slider
on Out 1-2 (was that five?).



96
Auxiliary routing should be standard procedure in any session. A project can be filled
with creative, well performed material or sophisticated concrete treatment with stacks of plug-ins
on every track, rife with automation and invention, but missing auxiliary mixes or sends is
telling. Auxiliary routing is, for me at least, a touch stone of an engineer's ability.
Auxiliaries add efficiency. There are two additional strategies for efficiency:
Freezing and Distributed Processing
Reverbs, delays, and (covered later) physical models tax the CPU because they generate
signal in real-time. You can monitor both CPU (real-time calculations to generate audio) and
disk I/O (reading and writing audio from the disk) by choosing Options/Audio/System
Performance. You can also control click on the transport and choose Customize Transport
Bar then check Load Meters.
Freezing a track can transfer CPU load to I/O load. It commits the real time effects on
that track to an audio file; essentially bouncing it to disk. In the mixer area or window, $click on
any track and choose Freeze. This will add a snowflake icon to each track. The next time you
press play Logic will take a few seconds to bounce that track to the hard drive. Once it has been
frozen, pressing play will read the track from disk. When unchecked, the freeze file will be
discarded and audio will be generated from scratch. Freezing cost very little, so it makes sense to
freeze all tracks that are more or less finished, or even that are not the current focus.
The second CPU management technique requires several computers. Distributed
processing can turn a 15 station lab into a parallel processing supercomputer. There is a small
app called Logic Node that will accept audio processing load over a (high speed) network. On
the master station you can select, say, tracks 1 through 10 and send those to be processed on
station 2, 11 through 20 on station 3, and so on. It takes a little time to set up, but once in place
your CPU overhead can be increased dramatically.
Auxiliaries for Monitors
In addition to subs and effect sends, auxiliaries are used for monitoring (or any mix that
differs from your main mix). Consider a live mix scenario. An engineer may spend hours getting
the house to sound exactly the way he wants. But the main house sound is only one several
mixes that need attention. In the middle of the performance you often see the lead vocal point to
her monitor and mime "more piano." The engineer is certainly not going to turn up the piano in
the house. It's right where he wants it. Then the bassist will mime less piano in his monitor. How
can the engineer increase the piano only in the monitor for the vocalist and decrease it in the
bass, but not change either in the house? A similar conversation may occur in a studio session. In
this scenario you are laying down additional solo tracks to an existing mix. The vocalist, in one
isolation booth, will want more piano in her headphones, but the guitarist only wants drums,
bass, and himself in his headphones. But the producer, sitting next to you, only wants to hear the
vocalist. How can you satisfy all three? The only solution is three separate mixes; separate from
the mains but also from each other. This can only be done with auxiliary sends.
You create them in the same way as an effects send, with one added step. Select the
tracks that you want sent to the auxiliary mix (and you just as well select them all, including the
effect mastersperformers may want to hear some reverb), then click on an open auxiliary slot
and choose a bus. Any bus will do. A new auxiliary track will be created. Name each one




97
monitor 1, monitor 2, etc. The second step is to make them pre-fader. Click the send once more
and select pre-fader.
With a parallel reverb you want the level of the reverb to match that of the main mix. If
you turn down the guitar in the main mix, you will want the reverb to come down too, to
maintain balance. For that reason, effect reverbs are post-fader. That is to say, they inherit the
level set by the main channel strip fader. Monitors are the opposite. You may spend hours getting
two headphone mixes just the way the artists want, then you decide the guitar is too loud in your
main mix and turn it down. You don't want that to change the mix in the headphones. Similarly,
you may mute several channels in your main mix to focus on the foundation instruments. If your
headphone sends are post-fader, they will be muted too, and the artist can no longer play along
with the tracks. If they are pre-fader, in both cases they will be unchanged by either changes in
the fader or muting/soloing.
! As a general rule: effect sends are post-fader, monitor sends are pre-fader.
Fig. 10-4 Routing for Headphone Sends


One final step: Signal is sent to these mixes by increasing the gain using the knob to the
right of the bus, just like the reverb. The difference is the output. With a reverb auxiliary, you
want the reverb to be mixed with the main signal, so the output on parallel effect sends will be
Stereo Out. But monitors need to be routed to a different output; 3 and 4, or 5 and 6, etc. Figure
10.4 shows the possible routing choices for an 18 channel interface. (You were wondering what
those other outputs were for, weren't you?) The send can be stereo for headphones, but for stage
monitors, or if you're doing a lot of them, you can choose mono. If, for example, you choose 5
and 6, then you would connect the outputs 5 and 6 of your interface to the headphone amp. Take
another look at Figure 10.3. Auxiliary send 1 is routed to Bus 11, which is connected to the input
of Aux 7, with an output to 3-4.
It may take a few sessions or live mixes for auxiliary mixes to sink in. It's one of those
things that you don't really get until you're faced with the problem. You'll be in the studio, laying
down tracks with the performer who is listening (via a splitter which is how everyone does it
until you get it) to the same main output as you, then the artist will ask if they can just hear the
foundation. You'll solo the foundation and sit there thinking, "but I still want to hear the other
parts to work on the mixI wish there were a way to do that." Then you'll come back and read
this chapter. The same is true for the post/pre-fader options. When your soloist yells at you for
muting one of the tracks in his mix, you'll think "how can I mute it in my mix, but not in his?"
Pre-fades are the answer.




98
Exercises
10:1 Start with a session provided by the instructor. Add serial effects, compression, EQ, where necessary.
Add sub-masters, two effects sends, and two monitoring sends.
10:2 Route all your drum tracks to an auxiliary, parallel send. On the resulting auxiliary track, place a
compressor and apply extreme compression: very low threshold and high ratio. Blend the two so that
the heavily compressed auxiliary is just below the natural track. That is, treat the compression as you
would a reverb.
10:3 Use the image below to practice your skills with the following scenario: You are in the studio
prepared to record two additional tracks; guitar and bass, each in a separate isolation booth with
headphones. They can only hear themselves through their headphones. Though no output is shown in
this image, assume the bass is hearing Aux 4, the guitar Aux 5. Plus; the producer is looking over
your shoulder and thinks his distracting comments are helpful. Match each of the requests using the
correct component in the mix window for the producer (P) in the main mix or one of your two
performers (G and B). The rows are labeled A through M, the tracks P through Z. Include in your
answer the correct term for each item used. For example, if the producers asks you to pan the Bass
guitar to the left, your answer would be: K-S, pan control. D through F refers to the gain knob to the
right of the Bus 1, 27, 28. M is mute. N is solo. You should be able to answer in less than two
seconds. During the third and fourth seconds the producer or performers are thinking "does he know
what he's doing?"

1. (P) More reverb in just in the snare.
2. (P) Compress all the drums.
3. (P) Less snare in the main mix.
4. (P) More of all the drums.
5. (B) I don't hear the click track.
6. (B) The balance is good, but it's all a little too loud.
7. (G) My click is too loud.
8. (G) Turn the organ up as high as I am.
9. (P) Group the guitar and bass.
10. (P) Send the click to the drum sub-master.
11. (P) Pan the organ to the left.
12. (P) Duplicate the roll-off to the overheads
13. (G) My balance is good, but could be higher overall.
14. (P) Adjust the OH balance to the right.
15. (G) I'm switching my guitar to input 3. (??!!?)
16. (B) Could you mix a little reverb in my headphone?
17. (P) Solo the guitar and drums. Toggle them.
18. (B) Can you take the organ out of the reverb?
19. (P) I want to hear it. Duplicate it as a serial effect.
20. (G) Add that funky delay we tried earlier to my track.
21. (P) Toggle the reverb on and off.
22. (P) Increase the master reverb.
23. (P) Boost the highs in the reverb.
24. (P) Compress the bass.







99
Answers
1. D Q, turn the dial up
2. C W, click, choose compressor
3. L Q, move down
4. L W, move up
5. E V, turn the dial up
6. L Y, turn it down
7. F V, turn the dial down
8. F U, turn dial to 12:00
9. Select S and T, click J
10. I V, click and choose bus/17
11. B U (! not K U), double click, pan left
12. A T, option-click-drag to R
13. L Z, move up
14. K U, dial right
15. H T, click, choose input 3
16. E X, dial up
17. Shift click T and W, N
18. D U, dial down
19. B X, option, command, drag to U, adjust dry/wet
20. C T, click, select delay designer
21. M X, click
22. L X, up
23. A X, adjust
24. B or C S, click, choose compressor





100
11. Adding Sound Effects
which often depends on style. Don't over do it.
Auxiliary reverbs and delays are more efficient, but only if you want to apply the same
style reverb to all instruments. In electro-acoustic composition and a London style mix you may
very well want two or three independent delays or reverbs on each channel.
London Effects
Fig. 11-1 Loop Browser
Logic is littered with sophisticated DSP modules. To try them
out, first find a dry drum loop with a broad frequency spectrum from
the Media area, Loops. Clicking on a category narrows your search
to items in that category. Drag a handful of similar loops for
experimenting. Insert a plug-in and browse through the presets to
familiarize yourself with the effect. Once you find something
interesting, adjust the controls to see how the sound changes. For now just explore. (I always
gravitate to the presets in the warped folder.) Later chapters will cover many of these processes
in greater detail. This chapter contains some of my favorites, with a few hints for each one.
Media/Library, Shortcuts, User Settings
Fig. 11-2 Channel Strip Focus
We are about to rifle through presets for these plug-ins, so I'll draw your
attention to the Library tab of the Media area. The content of this window changes to
reflect the focused item on each track. Click once on any plug-in, including the main
channel strip or an instrument in the I/O input slot, and the Media Library shows all
the presets for that plug-in. From here you can use the up and down arrows to select
items and the left and right to move up to a higher folder.
You can also select new plug-in settings and presets using a shortcut. Logic's
shortcut structure is flexible and extensive. Choose Logic/Preferences/Key Commands to learn
existing shortcuts or to create your own. (It's worth reading through them all once, but you'll
never remember or understand them all. Review them periodically.) In the search field type
"Plug-in" to find the shortcut for Next and Previous Plug-in Setting or EXS instrument. Start
playback, click on the plug-in window to bring it to focus, then use this shortcut to quickly scroll
through the presets. You can collect your favorite presets using the Save As menu. This will
move that setting, whether renamed or not, to the top of the menu. An alternate method is to
open Hard Drive/Library/Application Support/Logic/Plug-In Settings/<Current Plug-in> and
option drag your favorites to your own library: ~/Library/Application Support/Logic/Plug-In
Settings/<Current Plug-in>.
Delay Designer
Try the complex and warped categories.
This effect allows you to precisely control the
character of each reflection. Find an interesting




101
preset and click each of the tabs; cutoff, reso, transp, pan, and level. Adjust a single reflection
and note the effect.
Evoc 20 Filterbank
Adjust the LFOs at the bottom. The column in the
middle allows you to choose the shape of the wave that is used.
(LFOs are covered in depth later.) The buttons on the left are
for the left LFO, the right for the right. The Rate is how fast
each LFO repeats its cycle. If you choose either of the ramps,
with a rate of 1 Hz, the aspect of the sound being controlled by
that LFO will rise 1 time per second. The right side of the knob sets a free rate independent of
the project metronome. The left side syncs the rate to the tempo of the current song. This is a
powerful feature.
Evoc 20 TrackOscillator
Likewise, experiment with the LFO settings and wave form, as well as
the Formant stretch, shift, and resonance. There is a tiny piano keyboard which
sets the scale being used to modify the pitch. Try deselecting most of the keys
for a more exaggerated effect.
Spectral Gate
This effect is very similar to noise reduction systems (where you sample a section of
noise then suppress it), which, though ineffective with music, creates interesting effects;
frequencies pop up above a given threshold. The spectral gate works on the same principle.
Change the center frequency, band width, sub and super energy. Change the threshold to blend
the dry and processed signal.
Flanger, Modulation Delay, Phaser
These are all variations of phase shifting (the thing I told you to avoid in Chapter 6). The
input signal is duplicated, delayed, and detuned in various ways. This thickens the signal, similar
to over-dubbing. It also increases spatial effects as did the old Leslie system with a speaker that
physically rotated, sending signal cascading around the performance space. Try the presets,
fiddle with the knobs.
Ring Shifter
In brief, a ring shifter blends two signals together, one modulating the other. This process
generates improbable and complex overtones (sidebands). The details of this process are covered
in the FM chapter.
Side Chains
A side chain links a plug-in on one channel with the content of another (usually audio)
track. The best example of a side-chain is the Ducker. The Ducker is only available on sub-
masters (which doesn't make sense to me). Once in place, turn on the Ducker, click on the side
chain pull down menu and select the track you want the sub-master to duck. When there is signal
present in the ducked track the ducking track will duckthe track being ducked. Other typical



102
side chains are compressors (which then have the same function as a ducker) and the vocoder,
which uses the side-chain track as input for synthesis.
EVOC 20 PolySynth
Though this is an instrument, not a plug-in, it is a good illustration of a side-chain and
would be very well suited for a London effect. It can be used as a stand alone synthesizer, but it's
most impressive settings are in the vocoder presets. It requires another source of audio which is
used as an input to be modulated. For best results, first try speech. Record or import an audio file
with spoken dialog (make sure it is optimized) into an audio track. Create a new software
instrument track and select the EVOC 20 PolySynth in the input slot. First choose one of the
Synthesizer presets just to make sure you're getting sound. Press the Caps Lock to bring up the
caps lock keyboard (or use an external keyboard) and play a few notes. This is the stand alone
synthesizer. Next, choose one of the Vintage or Warped vocoder settings. These settings require
input from another audio track. To link the two, click on the Side
Chain pull down menu and select the track that contains the spoken
audio. Start playback and while the audio track is playing, press notes
on keyboard to play the vocoder synth. You should hear (and should be
astonished by) the speech being "sung" at the pitches played by the
keyboard. This is the same effect as Imogen Heap's Hide and Seek,
though I can't say what program or instrument she used. Mute the
original audio for the Evoc effect only. Enjoy.
Spatialization
Reverbs and delays can serve two roles. In a popular mix or electro-acoustic composition
they thicken, enrich, or change the character of the source. The effect helps define the sound.
That is why a post-fader send makes sense. The effect is integral to the material and should
increase or decrease when increasing or decreasing the dry signal. Otherwise the carefully
balanced effect will be compromised. But they can also be used for spatial effects; the sense that
a sound is moving around in a space, or the listener is moving around a space filled with sounds.
This is an interesting (though all too often omitted) technique in electro-acoustic composition. In
film sound tracks it is absolutely necessary. The complexity of spatialized audio in film goes
unnoticed until pointed out.
! Anything moving on screen, or any change of perspective of the lens (for example cutting
from outside a cafe to the inside where a couple is having a conversation) changes the nature of
the sound in five ways: 1) the overall volume of the source 2) the relative volume in the left and
right ears 3) the ratio of reverb to source 4) the timbre and 5) Doppler.
Of course the volume of an object will change relative to its distance and position left and
right, but unlike a post-fade send, the reverb doesn't change in relation to the dry signal. When
someone walks away from you in a hall their footsteps get quieter, but the actual volume of the
steps stays the same, so it will generate the same amount of reverb in the hall. In other words, to
create the sense of motion in a space, the reverb must be pre-fader.
High frequencies travel further than low frequencies, so the timbre will also change as the
source position changes. Finally, motion creates a Doppler effect. As a sound approaches you the
wave forms are compressed relative to the speed of the object. As it passes and moves away it
becomes decompressed. In other words, when sounds are approaching the pitch is slightly




103
higher, and slightly lower when moving away. This effect is most evident, even clich in
emergency vehicle sirens.
Fig. 11-3 Binaural Panner
To automate these effects with the tools you currently understand
you would first need to change your auxiliary reverb send to pre-fade (or
with a serial reverb automate the mix), then automate the volume, but also
the panclosely coordinated with the volume, and even more difficult, the
EQ, also carefully aligned to the volume and pan. Oh, and don't forget
Doppler.
Of course, Logic provides a tool that combines all of these.
Click on the output slot and choose Binaural. Double click on the
resulting pan knob to create spatial effects with a single control point. (A
stereo binaural control will include a left and right spread. I'll cover just the
mono parameters.) Adjusting the blue dot in the center will adjust the volume of the source
without changing the level of the reverb (i.e., it is a post auxiliary send), the timbre, and if
Doppler is selected, the pitch. Change the size for a more exaggerated effect (greater change in
volume). With a large size, the edges of the circle will result in nearly all reverb and no dry
signal. Small footnote: you might be tempted to use this in place of a directional mixer. But be
aware that this does more than change the pan location. It also modifies the character of the
sound. It's best used only for spatialisation.
Automation
Just a little perspective so you can appreciate the power of automation. Thirty years after
the seminal Forbidden Planet (the first major motion picture to take electronic "tonalities"
seriously), composers mixed from an 8 or 16-track analog tape. Creating spatial effects in four
channels required two hands, sometimes more, per track. One had to assign the output to
determine the two panning points, then adjust the volume and pan at the same time, and
sometimes the auxiliary send. After preparing all the "parts" on the tape deck, one might write a
musical score on staff paper, for four engineers, each controlling two tracks. They (ok, it's me
and my three comrades) then perform the piece by playing the mixer.
With Logic Pro, it's a click away. Specifically the automation icon in the toolbar. This
changes each track into a timeline. (Check the shortcut for your system; probably "A".) These
timelines represent a parameter on the track, effect, or instrument, and the luxury of carefully
planned and executed dynamic change. It would be criminal not to exploit such power.
Fig. 11-4 Automation Menu
Any parameter can be automated. If you can change it
with the interface, it can be automated. The default timeline is
volume. Click on the pull down menu of another track to change
it to pan. Automating these two parameters should be routine in a
London style mix.
Add an instrument track and choose the ES1 as the input.
Change the automation menu to ES1 and notice the complication
of nine sub-menus, one of which has 70 items (duplication, but
still). With these complex machines I never discourage blind






104
exploration. You're not going to break anything. (As always, use headsets and turn them down
before trying something unusual.) Click and dial away. That's how we all start out. (In an
interview I can no longer find, Louis and Bebe Baron were asked about their methods when
working on Forbidden Planet. They admitted that they often had no plan, but rather just tried
patches, adjusted knobs, and stood back in awe, tape deck always running to capture the
serendipity of their poke and rummage method. During my first electronic music course, which
used vintage patch and dial modular synthesizers, our instructor put a grad student in charge
when he was out of town. Our group of five quickly hi-jacked his agenda and proceeded with
this single goal: use up every patch cable and every module. It was one of my favorite classes.)
The problem is, you will stumble onto an interesting parameter and not be able to identify it in
the automation list. Turns out, even when you know the name and understanding how the
parameter works they are difficult to find.
Solution:
Latch
Just below the group field is the automation menu (default "off"). Click and choose
Latch. When engaged, during playback (not record) Logic will automatically register any
change made on any parameter on that track, plug-in or instrument.
Fig. 11-5 Multiple Timelines
This may seem handy, but in order to smoothly replicate
your movements it splatters the timeline with unnecessary break
points. In most cases you will want a smooth line, not precise
duplication of your imperfect motion. I prefer to work with the
timeline itself, creating and moving breakpoints with smooth lines
between. You can also view and edit automation using the event
list in the Lists field.
Clicking anywhere in the track will generate a break
point and move the timeline to that spot. You don't need to create
a break point then drag it. Just click where you want the next one.
Use the Marquee tool (the crosshair) to select a section.
Click and hold on the selection to create four break points at the
ends of the selection. You can now drag an entire section down.
A click with a quick release will create a break point. But click-hold will grab the line
and move that entire section.
Shift click-drag to select a section of automation. You can then click and drag to move,
option drag to duplicate, or copy and paste.
Click the reveal triangle to open up another timeline (Figure 11.5). Each click will
bring up a new timeline for that track. Choose a new parameter for each. This way you
can closely coordinate several parameters.
But latch does another very useful thing: it brings to focus (i.e., selects in the pull down
menu) the parameter timeline of anything you change. Just touching (clicking) a parameter
during playback will bring up that timeline. So I use latch to find parameters. Try this: click on
the automation track reveal triangle in the lower left corner of the track to open a new




105
automation timeline. Click on its triangle to open another. Continue until you have six or seven
timelines. They may all show the same automation at this point. Open a plug-in or instrument
with plenty of dials, sliders, and buttons. Start playback and click away on five or six parameters.
They each pop up in a new track timeline. Automate at will.
Exercises
11:1 Drag a short video excerpt from a science fiction movie (say, Forbidden Planet)
into the arrange track of a Logic session. (Choose something with lots of special
effects.) Populate the tracks with sound effects. Focus on spatialization, using
Doppler for moving items and automation to adjust levels with scene changes.
11:2 Add a voice-over in the style of MST3K. Route all the incidental music and sound
effects to a sub-master. Place a ducker on the sub-master, and duck your voice over
track.
11:3 Pick four of your favorite DSP effects. For each one find three interesting presets.
Explore the parameters without reading any explanations. When you arrive at an
interesting sound, save it to a folder.



106
12. Review, Examples
First a session start to end. Then analysis.
Review Session
Create a session or open a template with instrument or audio tracks. You can add more
later, or drag content (either MIDI or audio loops) into a blank space in the Arrange window,
which creates a new track.
Check the preferences for input interface, sampling
rate, buffer size, etc.
Set the audio input by clicking on the upper slot in the
I/O section. Choose an input source that matches the
interface input (that corresponds with the physical mic that is
sitting in front of the real musician). Note that the input
source may not and often does not match the track number.
You may be using mic 1 (input 1 of the interface) on Logic's
track 13. This is true especially when limited with a 2-channel interface.
Choose an instrument on software instrument tracks by
clicking on an input slot in the I/O section.
Add a channel EQ and compressor, at the least, to each
track. If you're going for a particular sound, give in to the
channel strip settings, but with this caveat: Try to get the sound
you want before it hits the mic. Adding EQ, compression, or even reverb at this point will
weaken the final product. Exposed tracks inspire better musicianship.
Record content, either live audio or MIDI on the instrument tracks. Click the R button
to arm the audio tracks for recording. MIDI tracks are automatically armed when selected.
Alternate: Add content by dragging loops from the Media area or dragging items from
the desktop into the arrange window, either in an existing track or a blank area to create a new
track.
Familiarize yourself with the material and plan the rest of
the session. Get it to sound the way you like before moving on.
Adding sub-mixes, sends, and plug-ins too early risks obscuring
the original intent and quality of the work.
Foundation: identify elements of the foundation, group
them or route them to a sub-mix by clicking on the output of the
I/O and selecting a bus. Still in mono, adjust the balance of each
using the volume sliders.
Create an image for the foundation by panning. Be sure to avoid big mono by panning
stereo tracks with a directional mixer.




107
Next work on rhythms, sub-mixing when appropriate, setting levels, then image using
pan and directional mixers.
It's likely that you haven't yet recorded the leads, fills, or pads. So you will need to add
headphone mixes using the sends (select Pre Fader). Choose any bus. On the resulting auxiliary
track select the output under I/O and choose an output other than 1-2. Connect those outputs to
your headphone amp.
Finally, record lead, fills, and pads. Still, you are mixing dry. Engage
the cycle to loop record. This will create comps, or multiple takes joined into
one region. You then can select very short segments of a given take.
Use the comping feature to select which sections of
which takes you want to keep.
Adjust EQ for each track. Start with the presets. Add
roll-offs on everything that has no low end. Adjust the drum
tracks or guitar tracks for crispness and sizzle. Consider unusual
EQs if a London mix. Use boost/sweep/cut to find and cut
annoying spectra. You may end up leaving it flat, but it never
hurts to explore.
Compressors, gates, limiters next. Likewise, there's not much reason not to compress
everything, even just slightly. Compression and EQ take very little CPU. (The exception would
be synthesizer tracks or apple loops, which typically have compression built in, or as discussed
above, classical works.) Solo individual or groups of instruments (bass and guitar, then drums
and bass, guitars and drums, then all three), adjusting as you go, slowly adding more and more
instruments.
Now turn your focus back to individual instruments and improve them
with slap delays, synced delays, exotic filters, reverbs and overdubbing. As a
general rule the order of inserts should be EQ, compression, filters, delays, noise
gates, reverbs. (Signal flow on a channel strip is top to bottom.) You may also
want to put a compressor or limiter and another EQ at the bottom of the list of
processors.
Automation next, since you are now working on the character of the
individual instruments, and especially if this is a London mix. First automate image (panning).
Even in LA mixes, a subtle pan can be effective. Automate main levels next, but mostly to
correct small flaws in the mix, or to fade elements in and out.
If a London style, consider automating the parameters of software instruments or plug-
ins.
Depth: select one of the sends slots and choose a bus. On
the newly created auxiliary add a reverb (100% wet). Dial each
instrument into the "space" using the level control to the right of
the bus. Solo, mute, engage groups or sub-masters to listen how
instruments interact with the other. Consider at least three levels
of depth; far, middle, and close. To hear the quality of the space,
raise the level much higher than it should be and mute the main track or pause playback to hear



108
the reverb tails. When happy with the sound, dial the reverb down until it is no longer apparent
(LA mix). Then A/B the dry/wet by muting the reverb master to see if it improves the sound
without sacrificing clarity, adjusting accordingly.
Listen to the mix and review style (NY, London, LA, Garage) and ask what's missing
or can be improved. Consider the elements of the mix; are there two rhythms? Do they
compliment each other? Are they panned to compliment each other? Should one be removed?
Consider panning according to function and frequency spectrum. Do both left and right
channels have plenty of highs? plenty of punch? crispness? Is there a frequency spectrum that
needs to be filled? A position in the image that is empty?
You may very well decide not to fill a particular spectrum or not pan hard left and right,
or even exclude an element (e.g., a pad). You may choose not to do three levels of depth, or no
depth (for an intimate, LA style). But you need to consciously choose not to. It would be a
mistake to omit something because you haven't considered it. Plus, it doesn't hurt to try. You
might discover something interesting.
Try a parallel compression for a more natural sound. That is, use a send to route signal
to an auxiliary. Send a group of instruments (drums, typically) to that auxiliary. Apply
aggressive compression, then blend that signal just below the level of the natural signal (as you
would a reverb).
At this point, you might want to listen to some of your favorite mixes, in particular
those you want to replicate. Compare and adjust.
Approach automation again. For a fresh sound in a chorus or middle verse, consider
changing the position, EQ, or depth of an element. Remove
instruments entirely for a variation in texture.
Fine tune volume levels using a ducker or a compressor
side-chained to a lead track. (Not all plug-ins have side-chains, and
those that do apply them differently. Read the manual for specific
functions.) For example, add a compressor to a rhythm guitar
track, adjusted to reduce the volume slightly. Use bypass to test the
compressed and uncompressed version. Side-chain the compressor
to the vocal track so that it kicks in only when signal is
present. If you want to do this with a group of tracks, send
them to a sub-master with a ducker.
Add to the master track (and possibly sub-masters)
an EQ, (yet again) compressor, gain control and a multi-
meter. Make any final adjustments to the EQ, but be subtle.
Likewise, compress discreetly. On the gain control select
mono, flip the phase of one channel. Check the multimeter
for phasing (correlation). Blue is good, red is bad. If you see
or hear problems, EQ, pan in mono, low roll-offs.
Now you can listenwith headphones, through
speakers, through a ghetto blaster, ear buds, cranked, barely audible, through the crack of a
door, with the vacuum cleaner running, in the car, in the space where it will be performed (do




109
three mixes; for a dry hall, medium hall, and wet hall), in the morning when you're fresh, in the
afternoon after listening to other things all day, after two weeksand make adjustments.
Electro-acoustic mix
It is a common fault to electro-acoustic works should be treated differently, or that
outrageous or even clever and inventive material exempts one from following elements of mix,
composition, organization, and style. This error leads to indulgent works filled with all the
material developed during the semester in the foreground, as lead, without discrimination.
Foundation, rhythm, pad, lead, fill, depth, height, width, EQ, compression, repetition and
variation work just as well with more artistic or intellectually challenging material.
Examples and Analyses
Below is a collection of the topics we've covered with examples from the popular
literature. The next section provides a synopsis of analysis in style, elements, and image from my
own collection.
LA Style: Doobie Brothers; Norah Jones; Steely Dan; Eagles; Ricky Lee Jones; Tracy Chapman;
God Bless the Child, Blood, Sweat, and Tears (panned as if on stage); Girl Talk, Chaise Lounge
NY Style: We Built This City, Starship; After The Boys Of Summer Have Gone, Don Henley; Life
in the Fast Lane, Those Shoes, Eagles; The Bitch Is Back, Elton John; Gypsy, Fleetwood Mac;
Everything, Dixie Chicks, Heart, Marc Broussard, Pretenders, ZZ Top
London Style: Most of, Because They Invented It, Beatles; Crazy, Zero Space, What to Do
Before I'm Dead, Kidney Thieves; Voodoo Child, Anglique Kidjo; Sunshine Superman, Chaise
Lounge; Everything, Queen
Garage Style: Tom Waits, Rolling Stones, Bob Dylan, Grateful Dead, Hendrix
Fill: Give Me One Reason, Nora Jones, Guitar (R); Stardust, Willy Neilson, Guitar and
Harmonica; Knockin' on Heaven's Door, Clapton, Wah Guitar; Fooled Around and Fell in Love,
Elvin Bishop, Piano; Roly Poly, Asleep at the Wheel, Guitar
Rhythm: Give Me One Reason, Nora Jones, Guitar (L); Fooled Around and Fell in Love, Elvin
Bishop, Offbeat Guitar pops; Everything, Doobies, Guitars; Oh Girl, Chi-Lites (what a great
mix), Guitars; Every Breath You Take, Police, guitar
Pad: Give Me One Reason, Organ; Stardust, Willy Neilson, Organ; Knockin' on Heaven's Door,
Clapton, Organ; Fooled Around and Fell in Love, Elvin Bishop, Organ; We Can Work It Out,
Beatles, Accordion; Every Breath You Take, Police, strings?
Height, Width, Depth, Elements (exemplary mixes): Steely Dan; Most of Toto; Owner of a
Lonely Heart, Yes; Crazy, What to Do Before I'm Dead, Arsenal, Zero Space, Kidney Thieves;
Voodoo Child, Anglique Kidjo; Reanon, Fleetwood Mac; Every Little Thing, Seven Days,
Brand New Day, Sting/The Police; Nikita, Elton John; Low Down, Boz Skaggs; One Love, Bob
Marley; Home, Marc Broussard; Have a Good Time, 50 Ways to Leave Your Lover, Paul Simon;
Englishman in New York, Sting
Concrte treatment (covered in chapter 14): We Have Heaven, Yes; Owner of a Lonely Heart,
Yes; Revolution 9, Beatles (though not a great exampletoo obscure), but how about
Strawberry Fields Forever, For the Benefit of Mr. Kite and the gobbledygook at the end of A



110
Day in the Life; 2000 Light Years From Home, Rolling Stones; Magic Man, Heart, Opening
guitar solo; Brand New Day, Sting; Another One Bites the Dust, Queen (reversal); Castles Made
of Sand, Hendrix, left channel guitar solo is reversed
Overdub: A Venture, Yes; Fast Car, Chapman; Red Red Wine, (vocal) Marley; Sunshine
Superman, (vocal) Chaise Lounge; Eyes of Silver, Dependin' on You, Listen to the Music, Black
Water, Long Train, Little Bitty Pretty, Pretty Much Everything? At least pre-McDonald, (guitars)
Doobie Brothers; And Most of the Eagles For That Matter, Eagles; Every Single Word He Sang,
Sometimes Even Different Lyrics, Except Maybe the Live and Unplugged Stuff, But Who Cares,
He's a Genius, Clapton; The Bitch is Back, guitars, Elton John; Gold Dust Woman, guitars, lead
vocal, Fleetwood Mac; Dog and Butterfly, Heart, Guitars; Brand New Day, Sting, Chorus;
Another One Bites the Dust, Queen
Filtering, Creative EQ: Voodoo Child, Anglique Kidjo; Voodoo Child, Hendrix; Stir It Up,
Marley; Gold Dust Woman, (drone) Fleetwood Mac; Magic Man, Heart, at 4'00"; Let My Love
Open the Door, Pete Townshend; Higher Ground, Stevie Wonder; Who Are You, The Who
Creative imaging: Crazy, Kidney Thieves; Beatles
Doubling or slap delay: Owner of a Lonely Heart (1:17), all three guitars, Every Breath You
Take, The Police; She's So Cold (guitar left), Rolling Stones; Shine Star, (guitar, vocals), Earth,
Wind, and Fire; Got to Get You Into My Life, (horns) Beatles; D'yer Mak'er, Zeppelin, vocal;
Every Breath You Take, Police, guitar; It's Raining Again, Supertramp, everything, I think
Synced delay: The Battle of Evermore, Whole Lotta Love, (mandolin) Led Zeppelin; Is This
Love (organ), One Love, Red Red Wine, (snare) Marley; Crazy, Kidney Thieves; Under Cover,
Rolling Stones; Lido Shuffle, (snare) Scaggs; Drive, (tambourine?) Cars; Sunshine Superman,
(0'37"), Chaise Lounge; Tell it Like it Is, (vocal) Heart; Keep Comin' Back, Marc Broussard;
Every Breath You Take, Brand New Day, Police
London style delays, panning: Kidney Thieves; Little Wing, Hendrix
Compression: I'm Yours, Jason Mraz, Sunshine Superman, Chaise Lounge; Dixie Chicks
Chorus/Flange: Owner of a Lonely Heart (1:04), Yes; What to Do Before I'm Dead (1'50"),
Kidney Thieves; Life In the Fast Lane, 3'40", Eagles; Little Wing, Hendrix
Notes about the analyses: I omit obvious things such as foundation and lead. The chart details
items that are the most difficult to distinguish, and what you might expect on the exams; style,
fill, rhythm, pad, and (since it's so common) overdubbing. The third column maps out the image:
hard left, left, center, right, and hard right.





111

Title, Artists, section in m:ss. Comments.
Style Fill Rhythm Pad Dubbing
Hard left Left Center Right Hard Right
Give Me One Reason, Chapman, 1:00-2:30. There are two fills, one is mixed near, the other quite deep.
LA Guitar on right, Deep Gtr Guitar on left Organ Gtrs
Rhym Gtr
Bu vocals
Set
Voice, organ, gtr fill
Set
Gtr fill
Set

Is This Love, Marley, 0-1:00. Synced, panned delays in drums, organ. Nice example of height. Slap delay on guitar fill hard left.
London Organ on far left Bass, guitars
Organ,
bright lead
gtr
Various percussion Voice, Organ, Bass, Guitars Percussion Percussion
delays
Rocky Raccoon, Beatles, 1:30-3:30. Why not LA? It's too raw. Notice the extreme image. Many of their early works were 4 track, so things were
grouped at extremes.
Garage Harmonica, Accordion Guitar Accordion?
Set!
Bass!
Vox Acoustic Guitar Harm
Honky-Tonk
Accord
Janie's Got a Gun, Aerosmith, 4:25-5:30. Excellent depth, width, and height. Vocals in background: imitating reverse Concrte? Dynamic
change in image (voice and synth).
NY (Ln?) Synth Strings Popped Guitar Guitar harmonics? HL
Harmonics
BU Vocals

BU Vocals
Set
Vox
Bass
Pseudo Reverse BU Vocals
Set
Popped guitar
Set
Synth Strings
BU Vocals
Voodoo Child, Angelique Kidjo, 1:15-1:40. Excellent depth, width, and height. Several examples of filtering. The didgerido-esque instrument is
a filtered sharp wave with random LFO cutoff. Unusual EQ of lead voice. Envelope follower on wa-wa fill. Sweeping sound dynamically
panned. I like this example because of the varied treatment of vocals. Every voice has a different EQ, pan position, and depth.
UK BU Vocals, Wa-Wa Didgerido-ish synth
Vocals

Vocals
BU Vocals
Lead Vocals
Didgerido-ish
Vocals, wa-wa
BU Vocals
Vocals
You Ain't Seen Nothing Yet, BTO, 0-0:45. I'm saying NY because of the wave form: very consistent. Great example of dubbing (even playing
different chords) and synced delays (lead guitar). The lead guitar is not a fill; never really exchanges with the lead. When it's there, it is the lead.
NY None! All other guitars None! Guitars
Guitar
Cymbals
Lead Guitar
Bu vocals
Set
Voice
Set
Lead Guitar delay
Set
Guitar
Cymbals
Louis Loon, Bare Naked Ladies 0-1:00. I love this example. Piano and banjo are both rhythm, but panned hard left and right. Note that they pull
a little Zeppelin trick; the drums and bass are playing perfectly normal, standard 1 and 3, but offset by one beat (4 and 2). Very clever. Very dry,
just a little reverb on the lead. BU vocals are slightly deep in the field.
NY Vocals and bells Piano, Banjo
Piano BU vocals
Set
Lead BU Vocals
Set
Banjo
Like a Rolling Stone, Dylan. Entire track.
Garage Sometimes the guitar Everything
Detuned
piano
Everything else Bob Everything else Set!
Sunshine Superman, Chaise Lounge. Absurd amounts of reverb, delays, and compression. Distorted guitars, clean blues guitars, overdubbing a
flawless, silky voice that has absolutely no reason to be dubbed. Genius.
London Bluesy and distorted guitar None None
Voice
Set
Horns Set (snare, kick, ratchet), Bass Horns, Distorted guitar Voice
Set
The New Kid in Town, Eagles. 1:30-2:00; Great example of elements. Set is panned mostly right. Not much on the left.
LA Rhodes Piano Off beat guitar, right Organ Rhodes and
lead guitars



112
Strummed
guitar
Organ
BU Vocals
Lead Vocal Organ delay
Rhythm guitar
BU Vocals
Set
Set
Life in the Fast Lane, Eagles. 0:30-1:15; Lots of doubling; voice (which would sound much worse undoubled), guitars, lead and rhythm. The
riff during the chorus is not a fill or lead, it's too repetitive. It's a rhythm.
NY Guitars trade off rhythm and fill Guitars (opening riff) Voice
Guitars
Rhythm
guitar
Rhythm guitars Lead (and doubled takes) Rhythm guitars
Set
Rhythm
Guitars
Set
Right Down the Line, Gerry Rafferty. 0:30-1:30; Textbook foundation, rhythm, pad, lead, sparse fill.
LA? Very sparse, guitar Guitar, far left Organ, close right Vocal
Guitar Set Lead (all overdubs)
Set, Bass
Organ
Set
Guitar delay
How Sweet it is To Be Loved By You, James Taylor. Choruses
LA Piano, Sax Guitar (very subtle) Strings None
Set Set Pretty much everything else Set Set
A Day in the Life, Beatles. complete; Unusual delay (un-synced, probably tape delay), kit is close mic'd with lower heads removed, heavy
compression. Dynamic panning (voice moves to center, then right). Phone ringing was a joke, happy accident. Generative "chaotic" transition,
Paul's instructions were to start low and play high. Middle segment mic is intentionally muffled. Contrasting depth between lead of second
section and "ahs" in the background. Image reverses for third section. Concrte loop after pause at the end. First example of time code? Good
grief, just read Emerick's book.
London Drums Shaker (not the guitar) None None
Shaker
piano
Set Bass
Set
Set Vocal
Anything from Come Away With Me, but let's do Cold, Cold Heart, Norah Jones. 1:00; Perfect example of an intimate, close mic position on
all instruments, very little reverb
LA Piano Guitar (left) Steel Guitar None
Guitar Piano Voice
Piano
Bass
Steel Guitar ?
Oh What the Heck, Let's Do Turn Me On, Norah Jones. 0:44; It's such a great example.
LA Nothing? Piano/Guitar Organ None
Guitar
Piano
Bass
Voice
Set
Organ
Set

Englishman in New York, Sting. 2:34; Height, depth, width. Seven Days is very similar.
LA/London? Saxophone, Piano Pizz. Strings The reverb? None
Percussion Saxophone
Strings
Set
Voice
Strings
Set
Most of the set Piano
Give Me , Sting. 2:34; Height, depth, width. Seven Days is very similar.
LA/London? Saxophone, Piano Pizz. Strings The reverb? None
Percussion Saxophone
Strings
Set
Voice
Strings
Set
Most of the set Piano

Exercises
12:1 Reproduce this chapter using examples from your own collection.





113
13. SC 3 Quick Start
Just a quick introduction. Skip it if you want.
When you first launch SC a window appears with three sections. On the left is an editor.
This is the window where you type and edit lines of code. The right side of the window is split
into a help browser and a post window that prints information about the program during startup.
This is called the IDE (integrated development environment). It's new to 3.6. You can detach,
close, or rearrange these three windows.
SC Intro
A second program, sclang (the interpreter), will launch at the same time. You won't
interact with this element except when it presents a window (such as a signal plot, open file
dialog, or scope). This collection of windows is called the client, where you type and develop
code. Those commands and algorithms are sent to the server, which actually makes the sound.
The text editing functions (select, copy, replace, etc.) are similar to any basic editor. But there
are editing features that are especially useful for (and unique to) editing code; toggling
comments, moving a line down or up, or moving the cursor by block, region, or empty line.
Figure 13.1 shows the defaults. An asterisk shows those that I had to change in the preferences
dialog to be more OS X friendly. If you've never written code their value is not immediately
apparent. Review these once you have a few patches under your belt.
Fig. 13-1 SuperCollider IDE Shortcuts

"! P Clear Post Window
! = Split Window at Bottom
! E Command Line for Quick Code Evaluation
"! R Select Region
" & Evaluate Current Selection or Region
! & Evaluate Current Region
! . Stop All Playback
#! ' (() Duplicate Line Down (Up)
$! [ ( ] ) *Move Line Down (Up)
! F, G, R Find, Find Next, Replace
"! G Find Previous
! L Go To Line
! ] ( [ ) *Go To Next (Previous) Region
#! ] ( [ ) *Go To Next (Previous) Empty Line
#! 0 ( 9 ) *Go To Next (Previous) Block
"! [space] Engage Auto-Prompt (Shows Arguments)
! / Toggle Comment
"! D Enter Text To Look Up In Documentation
! D Look Up Documentation for Text Under Cursor
! M Show Server Meter




114
Hello World
International geek protocol binds all programming authors to use "hello world" as the
first coding example. Le voici. Type this single line precisely into the left window, position the
cursor anywhere in the line (or select it), and press ![enter]. Check the post window. You
should see the program echo your first line of code by simply printing it to the screen.
13.1:: Hello World
"Hello World";

::
You are now a programmer.
This next example is a bit more pretentious; demonstrating how far we've come since I
first saw "Hello World" flash on a computer screen. They use Apple's speech algorithms. It may
take a second to engage.
13.2:: Hello Hal
"Hello World".speak;

"I've just picked up a fault in the AE35 unit. It's going to go a hundred percent failure within
seventy-two hours.".speak;
::
You are now a 20
th
C programmer, 2001, to be precise.
Note that each line is terminated with a semi-colon. In computerese this indicates the end
of an expression. Example 13.3 incorporates some music math. Run each of the following lines
separately, but in sequence. As you type you will notice some contextual menus popping up
offering auto-completions, matching enclosures, and information about the items you're typing.
These will make sense as you become more familiar with the program.
13.3:: Music Math
a = 5 + 4;

b = (440 * 3/2);

c = 60.midicps.round(0.1).asString;

a.asString.speak;

speak("The frequency for E5 is " ++ b.asString);

("The frequency for middle C is " ++ 60.midicps.round(0.1).asString).speak;

::
There is a good reason for calling this code. It's cryptic, a new language, just like French
or, maybe more apt, Greek. Once you understand it, it can be read just as you would a sentence




115
in English, although sometimes you read from the inside out. Here is a translation of the last line
in the example above: Convert the MIDI (midi) number 60 into cycles per second (cps), then
round that value to 0.1, convert it to a string. Concatenate (++) with "The frequency" and
speak the results.
The examples above don't make use of the Server because they don't generate sound. The
next will. Turn it on ("boot") using !B. You only need to start (i.e. boot, or power on) the server
once for each session and leave it running.
In the lower right hand corner you should now see green numbers in the server monitor.
The first two indicate how much processor is being used. This is important information, as we
will most likely be stretching the limits of your hardware.
Before we start a sound, it's a good idea to know how
to stop (true for many things). !-period stops all playback (but leaves the server running). This
text assumes you will stop playback after each example. Type and execute the following line.
13.4:: First Patch
// Start the server first: Language/Boot Server

{SinOsc.ar(LFNoise0.kr([10, 15], 400, 800), 0, 0.3)}.play;

::
Translation: play the stream of values generated with the function ( {} ) that uses a
control rate (kr) low frequency noise generator (LFNoise0) with a range of 400 above and below
800 at a frequency of 10 times per second in the left channel, 15 in the right, to give values for
the frequency of a sine oscillator (SinOsc) at an audio rate (ar) at a volume of 0.3.
Example 13.5 is more complicated, with several lines of code. This time, as you type, see
if you can make sense of the auto-completion features. Note that indents are applied
automatically (according to code formatting conventions), and that enclosures (parentheses,
brackets, and braces) turn red when the cursor is next to its matching enclosure. Try pressing
return when the auto-completion offers the correct word. Finally, the program automatically
colors words based on syntax. All of these features are extremely helpful when developing code.
This time position the cursor anywhere in the text (on any line) and press ! [return]
13.5:: Second Patch
(
{
RLPF.ar(
LFSaw.ar([8, 12], 0, 0.2),
LFNoise1.ar([2, 3].choose, 1500, 1600),
0.05,
mul: 0.4
)
}.play
)
::



116
Error messages
By now, you may have encountered an error message. (The examples in this chapter will
be omitted from the code fileavailable by request to those who prove that DRMs are
unnecessary and buy the textso that you can learn how to resolve error messages.) You will
quickly notice that the compiler is unforgiving when it comes to syntax, spelling, and
punctuation. Every comma, period, upper and lower case, and semicolon needs to be correct. If
not, an error message will appear in the data window. Figure 13.2 shows a common error.
Fig. 13-2 Error Message

ERROR: syntax error, unexpected INTEGER, expecting ')'
in file 'selected text'
line 1 char 40:
{SinOsc.ar(LFNoise0.kr([10, 15], 400 800), 0, 0.3)}.play;
^^^
-----------------------------------
ERROR: Command line parse failed
nil
"Parse error" usually is the result of a typo. The third line of the error message tells you
the line (1) and character (char 40) of the mistake. The fourth line places carets (^) at the position
of the error. But the error is often several characters or lines before that. Compare the line in the
error message to the original to see if you can spot the problem.
There is a missing comma. Don't be discouraged with error messages. They are normal.
While I was writing one of the examples below (about 12 lines of code) I had to run and correct
errors six times (not just six errors, but running it, correcting it and running it again six times). I
should probably be more careful, but my point is, it's normal, like spell check.
Elements of Code
! It is essential that you learn to identify these elements code.
Enclosures Parentheses define argument lists, braces define functions, and brackets define
arrays: (0, 100, 555), {arg next; next = 100}, [100, 200, 500]
Objects Objects do something. While technically everything in SC is an object, for the
next few chapters we will focus on objects that are paired with a message. These
include upper case words, numbers, anything in enclosures, and quoted text:
Synth, SinOsc, LFNoise, EnvGen, [1, 2, 4], 5, 6.7, "string", {rand(100, 200)}, (4
+ 25), etc.
Messages Messages tell the objects what to do. These are lower case words, sometimes on
their own, but usually connected to objects by a dot (.): play, scope, ar, max, rand,
midicps.
Arguments Arguments tell the object how to do the message. They are a list of items
separated by commas, enclosed in parentheses:
(1, 2, 4), ("string", 45, myVar), ({function}, 0.1, [1, 2, 3])
UGens Unit generators are the combination of an object, message, and argument list that
result in some type of output. UGens are analogous to antique synthesizer
modules which are connected together to create a patch. Examples of UGens are
LFNoise0.ar(0.5), SinOsc.ar(440, 0, 0.4), Sequencer.ar(s, r, j)




117
Arrays Similar to argument lists, but used very differently, they are a collection of items
that are used as a group. Each item is separated by commas, enclosed in brackets:
[1, 2, 3], ["C", "D"], [a, b, c]
Functions Anything enclosed in braces: {arg next; next = 100}, {possibly many pages of
code}, {SinOsc.ar(60.midicps)}
Variables User defined names of memory locations, beginning with lower case letters (not a
number), contiguous (no spaces), and often words strung together with caps in the
middle: pitchClass, nextCount, freqArray, myVar, a1, start4, etc. Local variables
are declared using var myVar1, myVar2;. Global variables a through z can be
used at any time and work throughout all patches. You can also declare global
variables by simply preceding the name with the tilde character: ~myGlobalVar.
Floats Short for a floating point number: 1.235, 167.24, 78.127489273. The "point," or
decimal, floats around to different positions. Values below 1 must be expressed
with a leading 0: 0.123, 0.15, 0.5.
Integers Integers are whole numbers: 1, 56, 109. They have no decimal.
Expression A line of code punctuated by a semicolon. "Hello World".speak;
Comments Comments are identified with two slashes; "//". Everything from that point to the
end of the line is ignored by the compiler. They are used to clarify sections of
code. They can also be offset with /* (start) and */ (end).
Enclosures (parentheses, braces, brackets)
! Enclosures are used to group things together and indicate the order of execution. Each
opening parenthesis, bracket, and brace has a matched closing parenthesis, bracket, and brace.
This is why the editor has a built in aid for seeing the matches. The compiler runs or evaluates
the code from the inner most matching enclosures, then works outward. When items are nested
you often will see six or seven open enclosures as you read left to right, then all of the closing
enclosures later in that line, as illustrated below. (This is a fabricated example for demonstration.
It won't run.)
Fig. 13-3 Matched Enclosures

{Saw.ar(Pulse.ar(max(rrand(rrand([12,15],5))),400,800),0,0.3)}.play
[ ]
{Saw.ar(Pulse.ar(max(rrand(rrand([12,15],5))),400,800),0,0.3)}.play
( ) etc.
{Saw.ar(Pulse.ar(max(rrand(rrand([12,15],5))),400,800),0,0.3)}.play
{Saw.ar(Pulse.ar(max(rrand(rrand([12,15],5))),400,800),0,0.3)}.play
{Saw.ar(Pulse.ar(max(rrand(rrand([12,15],5))),400,800),0,0.3)}.play
{Saw.ar(Pulse.ar(max(rrand(rrand([12,15],5))),400,800),0,0.3)}.play
{Saw.ar(Pulse.ar(max(rrand(rrand([12,15],5))),400,800),0,0.3)}.play
1 2 3 4 5 67 7 654 3 21

The outer most enclosures of any section of code define a region. That is why most of the
examples are encased in opening and closing parenthesis. "!R will select the region. Choosing
!-return will select that entire section (block) and evaluate it.



118
White space (spaces, returns, tabs) are often used to clarify matching enclosures. SC
ignores all white space, so it can be used to visually line up enclosures and argument lists. In
practice, one should strike a balance of concise code and open clarity. Variables, discussed later,
will also clarify coding.
13.6:: Balanced Formatting
// too dense?
{SinOsc.ar(SinOsc.ar(3,0,500,1000),mul:max(0, LFNoise1.kr([12, 14])))}.play

// clearer, but too spread out?
(
{
SinOsc.ar
(
SinOsc.ar
(
3,
0,
500,
1000
),
mul:
max
(
0,
LFNoise1.kr
(
[
12,
14
]
)
)
)
}.play
)

// clear
(
{
SinOsc.ar(
SinOsc.ar(3, 0, 500, 1000),
mul: max(0, LFNoise1.kr([12, 14]))
)
}.play
)

// clarity using variables.
(




119
{
a = SinOsc.ar(3, 0, 500, 1000);
b = LFNoise.kr([12, 14]);
c = max(0, b);
SinOsc.ar(a, mul: c)
}.play
)
::
! Look again at all the examples so far and practice identifying each of the components
we've discussed. I'll do the first patch: {SinOsc.ar(LFNoise0.kr([10, 15], 400, 800), 0, 0.3)}.play;
The objects are SinOsc, LFNoise0, the function ({}), the array ([10, 15]), and all the numbers.
The messages are play, kr and ar. Functions and arguments are a little harder to spot. All of the
text {SinOsc 0.3)} is a function (everything between { and }). Arguments can be confusing if
they are nested. The arguments for LFNoise0.kr are ([10, 15], 400, 800). The array [10, 15] is
the first argument, 400 the second, 800 the third. For the SinOsc.ar the arguments are
(LFNoise0.kr([10, 15], 400, 800), 0, 0.3). The first is LFNoise0.kr([10, 15], 400, 800) (yes, the
entire UGen), the second is 0, the third is 0.3.
Arguments
Arguments are control parameters. They are similar in function to the knobs on analog
synthesizer that change frequency range, filter cutoff, amplitude, sequencer speed, etc.
In example 13.7 the arguments for LFNoise1.ar are (10, 400, 800). Change these three
values and run the code to see how they change the sound. Try 15, 25, 30, or 40 for the first
argument. Try 100 and 700, 30 and 100, 1600 and 1700 for the second two arguments.
13.7:: Arguments
{SinOsc.ar(abs(LFNoise1.ar(10, 400, 800)), 0, 0.3)}.play

::
The knobs on synthesizers are labeled. These controls typically are not. How do you
know what the arguments represent, or how they change the sound? The first step is to look up
the help file; highlight the item you want help with and press !D.
Object.Message
The examples above are difficult to understand because of the cryptic syntax but also the
foreign words (SinOsc, LFNoise1). It would be helpful to use more familiar, though fictitious,
objects and messages to explain how they work. (These examples won't work in SC!) If you are
comfortable with these terms, skip this section.
If SC were designed to test recipes for sandwiches it might have the fictitious objects
Sandwich and Tofu. Every object understands a collection of messages. The messages tell the
object what to do. Likewise, there are many objects that understand any given message. For
example, let's assume that Sandwich understands three messages: make, cut, and bake, and that
Tofu understands three messages: bake, fry, and marinate. The power of object-oriented
languages lies in the way you can mix and match messages and objects. The syntax for sending
the make message to the Sandwich might be this:



120

Sandwich.make;
If you wanted the Tofu to be baked you might write:

Tofu.bake;
Notice there are no argument lists to describe what the sandwich is made of or how the
tofu is baked. Most messages have default values. Try running the lines in example 13.8. The
first uses no arguments in the .ar or .play messages. Next, run the example with an argument list
for both .ar and .play.
13.8:: SinOsc defaults
{SinOsc.ar}.play

{SinOsc.ar(800, 0, 0.1)}.play(s, 0, 10)

::
The first result is a sine tone at 440 Hz, 0 phase, 1.0 amplitude, played on the default
server, output bus 0, no fade. Those are the defaults for SinOsc and play. Often you are able to
use one or two of the defaults, but rarely will you use a message with defaults only. The second
example overrides the defaults and plays a sine tone at 800 Hz, 0 phase, 0.1 amplitude, on server
s, bus 0, with a 10 second fade in.
To see the help file for SinOsc, position the cursor inside it and press !D.
In each of the help files are prototypes of all the messages (with argument lists)
understood by that object. Sandwich and Tofu might be documented this way:

Sandwich

*make(vegArray, bread, meat)
*cut(angle, number)
*bake(temp, rackLevel)

Tofu

*bake(temp, baste, rackLevel)
*fry(temp, length, pan, oil)
*marinate(sauce, time)

It is important to understand that argument lists are not interchangeable between objects.
The bake message used with Sandwich has two arguments, while the Tofu bake argument has
three. Not understanding this, and using the same arguments with a message to different objects
is a common beginner error and will have unexpected (and possibly interesting, but don't do it)
results. When bake is used with Sandwich, as in Sandwich.bake(20, 2) the 2 is rack level, while
in Tofu.bake(20, 2) the 2 is baste time.
Now that we understand what the arguments for Sandwich.make are, we could put
together a Sandwich with this mock code.





121
Sandwich.make([lettuce, tomato, pickle], rye, chicken)
or

Sandwich.cut(90, 1)
and

Tofu.marinate(peanut, 160)
The first line will make the Sandwich using an array (list) of vegetables, bread, and
chicken. The second line will make one cut of the Sandwich at an angle of 90 degrees. The Tofu
will be marinated with peanut sauce for 160 minutes.
Another powerful aspect (the whole point, really) of SC and object oriented languages is
that everything is an object, and you can substitute them freely. Instead of chicken as the third
argument, the entire section of Tofu code could be used (nested).

Sandwich.make([lettuce, tomato, pickle], rye, Tofu.marinate(peanut, 160)))
When a program evaluates the code it begins with the inner most parts, and uses the
results of those values to run the subsequent outer layers. In English, the example above might
read: Marinate tofu in peanut sauce for 160 (minutes?). After marinating the tofu, use it as the
meat (third argument) for a sandwich with lettuce, tomato, and pickle, on rye bread.
It is possible to link messages. For example Sandwich.make.bake.cut would first make
the sandwich (in this case using defaults), then bake it (using defaults), then cut it (with defaults).
One object can be used as an argument for another instance of the same object. For example, you
could write Tofu.marinate(Tofu.marinate(peanut, 60), 60). In this case, a batch of tofu will be
marinated in peanut sauce for 60 minutes, then another batch of tofu will be marinated in that
batch of marinated tofu (yum!).
Exercises
13:1 Below are two patches. Read the help files associated with each object. You may
not completely understand all the terms, such as mul and add, and how they work in
the patch, but it's ok to suppress some questions and be satisfied with what you do
know. In both, identify objects, messages, argument lists, functions, matched
enclosures, floats, integers, and arrays.
13:2 Look at the help documentation for the second patch. See if you can make sense of
the arguments in relation to the actual sound. Try to predict how the changes you
make will change the sound before you run the code. I've commented ("//") values
you might want to change. Feel free to experiment. There is indeed a danger of
crashing the machine or getting error messages or possibly startling a resident pet.
But otherwise you can experiment at will. If you make changes that result in an
interesting sound you can easily save it to a file. To do this choose save as and name
the file or copy and paste the patch into a new file.
13.9:: Experimenting with a patch
{SinOsc.ar(abs(LFNoise0.ar(10, 400, 800)), 0, 0.3)}.play

(



122
{
RLPF.ar(
LFSaw.ar([8, 12], 0, 0.2),
abs(LFNoise1.ar([2, 3].choose, 1500, 1600)),
0.05
)
}.play
)

::

13.10:: Rising Sines
// Rising Sines

(
{
CombN.ar( // Delay Ugen
SinOsc.ar( // Sine Osc Ugen provides input for delay
LFNoise1.kr( // Step Noise Ugen provides freq for Sine
4, // LFO of step noise, for "wandering"
24, // range in MIDI of step noise wandering
LFSaw.kr(
[8,7.23], //second LFO for "sweep"
0,
3, // range in MIDI of sweep
80 // offset in MIDI of sweep
)
).midicps,
0,
0.04
),
0.2, // max delay
0.2, // actual delay
4 // delay decay
) }.play
)

::





123
14. Concrte Procedures
Splicing blocks and razor blades; no longer useful.
Concrte
To illustrate the impact recorded sound has had on music and communications, take a
quick inventory of the music you listen do daily; live vs. recorded. Is it even close to 50/50?
Would we have to extend the challenge to a week before we could include a single incidence of
live performance? I've encountered students who have never attended a live concert of any kind,
yet their collections contain thousands of works. Early recordings were used as parlor
entertainment. Guests were shocked to hear, for example, horses in a room.
I love classic science fiction, in particular tech spotting; taking note of what they got
right, or how far off they were in other ways. (They were much too pessimistic.) No flying cars
from the Jetsons, but video phones? There is one sitting next to me on the couch. Two that still
seem to elude us are teleportation and time travel. Yet one could argue that recordings do both.
They are time and space machines.
The tape deck's intended contribution to the music world, reproduction, was quickly hi-
jacked by the likes of Ussachevesky, Sheaffer, Leuning, McCartney, and the minimalist school.
These pioneers were more interested in extending the capabilities of natural instrumentsfor
example exploring the sound of a piano if the keyboard were several octaves lower, or higher
but were easily distracted by entirely novel treatment; sounds that had literally never been heard
before, and were unique to the medium. The Beatles continued to explore Concrte treatment on
nearly every album after Revolver, the most notable, striking, and ignored being Revolution 9. It
would fit in nicely at most electro-acoustic concerts. Once dismissed as hair-brained, this
technique is now common in Rock, a staple in Rap, Techno, Industrial, and similar styles. It is
the foundation for sampling synthesis and sample libraries. Examples of Concrete treatment in
popular media include Strawberry Fields and For the Benefit of Mr. Kite (Beatles), Another One
Bites the Dust (Queen), pretty much everything Daft Punk does, but I like Face to Face, Vox
Humana (Kenny Loggins), and the entire Year Zero album, NIN. I can't pick just one. Maybe
God Given.
There used to be a pronounced schism between purely electronic and Concrte
composers. The two have since merged. The Concrte camp were drawn to the built in
complexity due to the rich source material. Concrte and additive synthesis, (covered later
which can also be very rich and surreal) are my favorite electronic techniques.
! Most think of Concrte as manipulating recordings of real sounds in artistic ways, any
recorded sound is "set in concrete." That is in fact the inspiration for the term. Even a recording
of a classical work with full orchestra is like a statue; set in stone.
This definition reminds us that live music has a dimension recorded pieces do not; the
potential for growth and change. A written work that has to be realized is not the performance,
but the potential for a performance, or a failed performance, or a brilliant performance, or in the
case of aleatory and improvisation, something completely new, never heard before. I believe too
many people equate a recording with a performance. In a sense it has tainted our expectations:
we attend a concert expecting what we heard on the CD. The Beatles were one of the first to



124
realize they could subvert the standard practice of releasing recordings just to bring people to
concerts. They saw that the recordings could stand on their own merit. They became the medium,
and the principal source of income. As digital rights management fails there could be a return to
the previous model; give away the recording to attract audiences to live performance, which
holds the promise of fresh material.
Concrte introduced us to sounds that had never been heard before. Indeed all recordings,
even those not intended for concrte treatment, have exposed us to rare and exotic sounds,
previously only heard by natives of a particular environment. Exploring sounds unique to
recorded reproduction is an important goal of this chapter. My first exposure to an EVI
(electronic valve instrument) was a concerto that could have been, and probably should have
been played on trumpet. I was disappointed that the performer never changed the timbre, never
leapt six octaves, never bent the pitches, never fired off notes at the speed of sound. (Well,
technically, yes.) Many electronic performances since have left me wondering; what is the point?
I see the stage filled with mics, computers, wires, and speakers, but hear music that could have
been performed before the electronic revolution.
The power of Tchaikovsky, Bach, Vivaldi, and Hendrix lies in the exploitation of their
chosen medium; the power of the piano, carefully crafted vocal lines, flashy violin arpeggios,
controlled harmonic feedback. We should judge electronic music the same way; does it
exemplify its unique power? For Concrte, we have to ask; what can digital manipulation do that
can't be done on any other instrument?
An additional appeal to concrte material is the inherent contextual baggage. If a sound is
drawn from the human experience (and how can it not?), then the audience will bring that
association to the work. You can dodge association through obfuscation or foreign languages, or
you can embrace it as part of the work; juxtaposing, for example, a speech with iconic religious
inflection over cartoon sound effects. Auto-tuning the news is an excellent example; it is
precisely the intended hubris and arrogant context that makes vocalized parodies so effective.
! Concrte is capable of four treatments (which we now take for granted) that cannot be
performed on any other instrument; precise loops, pitch and time shift, reversal, and abrupt edits.
Looping
is rampant in popular media, evidenced by the Apple Loops library. Early loops were
executed on magnetic tape decks, splicing a section of tape to itself then threading it around the
room using mic stands for support. Tomorrow Never Knows, Beatles, is an early example of
loops. (These were created by Paul on a newly purchased open reel tape deck. As far as I have
read Paul worked this out on his own, without exposure to any of the art music experiments
happening at Columbia. From Geoff Emerick's book: "Every tape machine in every studio was
commandeered and every available EMI employee was given the task of holding a pencil or
drinking glass to give the loops the proper tensioning. In many instances, this meant they had to
be standing out in the hallway, looking quite sheepish. Add in the fact that all of the technical
staff were required to wear white lab coats, and the whole thing became totally surreal.")
Looping appeals to me in two ways; the precision of repetition, and the rhythmic patterns
possible with mathematically related loops. Our brains are finely tuned to recognize pattern. We
recognize in electronic loops minute details. No other musical instrument is capable of such
accurate repetition.




125
Pitch and Time Shift
were, until only recently, inextricably linked. Change the speed of playback and the
pitched changed. Today's wizardry can change one and not the other. (This is analogous to
increasing the length of a book without changing the content.) Taking this process too far results
in aliasing (in itself an interesting effect). Speed change with spoken samples borders on clich,
but other soundspercussion, ambient noise, instruments, sounds from nature, still keep my
attention. The Beatles also experimented with tape speeds. The solos on Misery were recorded
with the tape at half speed, partly out of necessity (George was having difficulty with them),
partly for effect. This is not readily apparent, but blatantly obvious when the track is played at
half speed. But the backing track to Rain was intentionally recorded at a faster tape speed, then
slowed down for effect, not out of convenience.
Reversal
also trickled from the experimental academic studios to popular recordings. Rain,
Beatles (and nearly everything else on Revolver because of Rain) uses reversal. They hit on the
idea because John mis-threaded a rough mix on his home machine. Other examples include
Another One Bites the Dust, Queen, 2000 Light Years From Home, Rolling Stones and the entire
left channel guitar solo in Castles Made of Sand, Hendrix.
Abrupt Edits
is another technique that is unique to recording technology. No natural sound or
instrument can change it's timbre, subtly or radically, with millisecond accuracy. In Yellow
Submarine, Beatles, Emerick snipped up the brass band section into small segments, threw them
in the air, then spliced them back together again. His intention was to avoid copyright
infringement, which worked, but also hit on a unique treatment. Daft Punk has built a career
around sampling, abrupt edits and looping.
Of course there are, and I encourage you to explore, excellent examples of concrte from
the academic world. I use popular examples to illustrate their viability. These techniques were
dismissed and even derided among academics. They were obviously wrong to do so. The 1998
documentary Modulations chronicles the link between experimental academia and the electronic
styles that evolved in clubs and raves.
There are two tools in Logic that give quick concrte results. They are designed as
sampling synthesizers. Like recording technology in general, they are intended for exact
reproduction of natural instruments, but can be repurposed for concrte. The first is the
EXS24
You can import samples and play them back on the keyboard for precise control of a
large collection of loops.



126
! When you first launch the EXS24 there is no instrument
assigned. (If there is an instrument, choose no instrument.) Pressing
the edit button when no instrument is loaded will create a new
instrument and open the editor. You
can drag and drop samples onto this
field. Use the bars just above the
keyboard to specify which keys
trigger a given sample. Set the Key field to where you want
normal speed played back. In the local View menu choose
Zone: Loop to turn looping on and to specify the start and end
point (in frames) of each loop. Now you can play these samples on the keyboard and record them
as MIDI events. They will play at different speeds for each key. The most interesting application,
for me, is precisely coordinated loops. Try intervals such as a fifth, fourth, or octave. As
discussed in Chapter 8, the samples will go in and out of sync at those ratios.
UltraBeat
has similar functionality with drag and drop simplicity. The advantage over the
EXS24 is the built in looping. It can manage 24 separate samples, each with 32 step sequences,
and virtually unlimited sets of patterns. It is a Concrte composer's dream.
In a Logic session add an instrument track and insert UltraBeat in the I/O input menu.
UltraBeat has three synthesizers to generate its drum loop sounds. We will work with the
sampler at the bottom (see Figure 14.1, first image). In the Media/Library choose the Hip Hop
90s Kit preset or the Drag and Drop Samples preset. (I choose Hip Hop kit because most of the
sounds are real samples that can be replaced, and it is pre-loaded with sequences and loops. Feel
free to explore, others, but find something that uses primarily samples. Use Drag and Drop to
start from scratch.) Press the power button, then the play button. Turn on pattern mode, set to
toggle or one-shot trigger, then to the bottom left click on the pull down menu next to pattern
to select one of the 24 sequences assigned to the lower octaves of a MIDI keyboard (C -1
through B 0).
The far left of the UltraBeat window is a keyboard (see Figure 14.1), each key labeled
with the name of the loaded sample, a mute, solo, and pan control. While playing back, load a
new concrte sample by dragging it to the window displaying a wave form. Click the red arrow
to reverse, click the piano key to test. Continue to experiment with different sequences and
replacing existing drum sounds with your concrte material. This alone, if improvised, would be
an interesting concert performance.
The sequencer (Figure 14.1, second image) has 32 steps. Each can be shortened by
dragging the bar just below the step numbers. Clicking on a number adds a gate to that step. A
gate is a trigger with duration. The sound continues to play until the gate is released. A 4 second
sample needs at least the same length of gate (though it can certainly be shorter). Once you have
loaded and tested a Concrte sample, click on the numbers to add several gates. Click and drag
across several trigger positions to create longer or shorter gates. Repeat for each new key and
each new sample, building a collection of looped Concrte sequences.




127

Fig. 14-1 UltraBeat
To the right of the sample window is a complex dial (labeled
OSC2) that allows you to modify the pitch, amplitude, and velocity.
Experiment with the reverse switch as well as the pitch of the playback.
Feel free to load the same sample into several key locations for
different treatments (reverse, pitch, envelopes).
In the lower left hand corner of the UltraBeat window click full
view. This changes the display from synthesizer to a graph showing all
sequences. Control click any track to reveal a handy set of editing
features, including copy, paste, clear, randomized creation and replacement. No one takes me
seriously, but seriously, you could stop coming to class and do an entire project with this plug-in
alone.
There is a mysterious grid icon just to the left of the MIDI key
assignment pull down menu. Drag the small box to the arrange window to
duplicate the pattern as a region.
For a generative dimension, name all your samples 01.aif, 02.aif, etc.,
have a colleague collect new samples (perhaps before the concert from the
audience) and also name them 01, 02, etc. Drag these new samples to your sample folder,
relaunch the session and it will read and play the replacements.
Concrte using SC
is a little more involved, but the results, especially the granular treatment in the next
chapter, are worth it. Since this is the first example in this chapter (and perhaps coming to this
example afresh), remember to launch the server before running any examples.
14.1:: Loading an Audio Buffer
// Boot the server first

b = Buffer.loadDialog; // Switch to sclang to open file

[b.bufnum, b.numChannels, b.path, b.numFrames] // confirm that it opened correctly

b.play; // test playing it back

::
Buffer.loadDialog brings up an OS X dialog (in the interpreter) which you will use to
find an audio example. I suggest you use a mono, 16 bit, 44.1k aif file longer than 10 seconds. It



128
will play back only in the left channel. Stereo comes later. And while I'm suggesting, how about
a two second clip from any cut out of Tom Waits' Bone Machine or a segment from Cage's brief
interview on the activity of sound. The sound is stored at the variable b using the equals sign.
The next line of code can be used to make sure the buffer loaded correctly. It displays the buffer
number, the number of channels in the file, the path, and the number of frames. A frame is the
collection of samples for all channels. So a 5 channel audio file will have five samples per frame,
but that single frame represents a single sample of time. A one second stereo file will have 44100
frames, but 88200 samples.
For now we will loop using PlayBuf. The help file for PlayBuf shows the third argument
is the playback speed. Negative numbers will play backward.
14.2:: Pitch and Direction
// change the third argument to values between -2.0 and 2.0
{PlayBuf.ar(1, b, 1)}.play;

// Be patient. You may have to listen a while.
{PlayBuf.ar(1, b, LFNoise0.kr(1, 3))}.play;

::
The fourth and fifth argument of PlayBuf can be used to generate loops. The fourth is a
trigger that resets playback to the start position. The fifth argument is the position, in frames,
where the loop returns to. Example 14.3 is a loop browser. A MouseX returns values based on
mouse position and is used to supply the playback position of each loop. It uses a minimum
value of 0 and a max value of the total number of frames in the sample. Move the mouse to the
left for the beginning of the sample, right for the end.
The trigger argument is the frequency, in seconds, of the trigger to reset the loop. This
essentially becomes the length (in time) of the loop. The example below uses Impulse. The
LFNoise0 from the previous example has been removed so you can experiment with the
playback start and trigger frequency without speed being changed. Replace it if you'd like. Try
values between 0.1 and 4 for the trigger frequency.
14.3:: Loop, Playback Position, Triggers
// The numFrames message returns the number of frames.
// It's used below for the MouseX min, max value.
b.numFrames;

// Impulse sends a single pulse as a trigger.
// You will hear a tick
{Impulse.ar(1)}.play

//
{PlayBuf.ar(1, b, 1, Impulse.kr(1), MouseX.kr(0, b.numFrames))}.play;

::




129
Envelopes
You might notice that some start positions produce a pop, or click at each loop. This is
the same effect caused by poor edits; an abrupt change from positive to negative values. When
fishing around for a start position, it's impossible to know where 0 crossings are, so the solution
is to apply an envelope over each loop. Envelopes are essential components for instrument
design. They describe the change of the sound over the duration of a single instance of the sound
(usually amplitude, but also timbre and sometimes pitch). A piano, for example, will have a fast
attack and a long decay. A violin can create complex envelopes, including a long attack and a
very fast decay. Envelopes are set in motion with a trigger or gate. Pressing a piano key is a real
world example of a trigger. It is a single event that sets the sound in motion. You have no control
once the key is pressed. A gate is similar to an organ key. It will continue to produce sound until
the key is released, at which point it will decay.
Example 14.4 illustrates envelopes. (The plot windows will appear in the interpreter. You
will have to switch back and forth.) The fist shows a plot of noise without an envelope. The
second shows a millisecond of plotted noise to better illustrate the probability that the beginning
and ends of the audio are not at 0 crossings. If this example were looped, you would hear a tick.
The next two multiply the white noise source by an envelope generator. The first plots, so a
trigger is unnecessary. The last uses a trigger (Impulse) at one time per second.
14.4:: Envelopes
// Steady state noise.

{WhiteNoise.ar}.plot(1)

{WhiteNoise.ar}.plot(0.001)

// Same signal multiplied by an envelope with 0.1 second attack
// 0.6 second sustain, and 0.1 second decay.

{WhiteNoise.ar*EnvGen.kr(Env.linen(0.1, 0.6, 0.1))}.plot(1)

{WhiteNoise.ar*EnvGen.kr(Env.linen(0.1, 0.6, 0.1), Impulse.kr(1) )}.play

::
Variables, Frequency and Duration
The single letters a through z are defined by SC as global variables during startup. Some
of these are reserved by the program. The variable s is always used for the server. Example 13.3
used the variables a, b, and c. Variables store items that will be used several times in a patch or
several patches. In these examples, the variable b retains the buffer for each new execution of a
patch. Otherwise, it would require the load-buffer dialog to choose a file each time.
Local variables are confined to the function where they are declared. They are used to
link components of a patch together, and to organize code by breaking it down into smaller
statements. In the example below, each section is stored in the variable mix. Think of it as a bowl
into which you mix and combine ingredients; mix = eggs and flour; mix = mix + butter;. They
are declared in the top line as var myVar1, myVar2, myVar3;



130
Periodic events have both a frequency and duration. They don't have to correspond. For
example, a trigger with a frequency of 2 (times per second) will have a 0.5 second duration. Each
event between those triggers can be independent of the trigger duration. They could have a
duration of 0.5 seconds, but also 4 or 0.1 seconds. If 0.1, then the sound will die away between
each event. If 4 seconds the events would overlap.
Either way, there is a connection, and it is useful to set durations in relation to frequency.
As discussed in an earlier chapter, frequency and duration are reciprocal. Invert each to convert
one to the other; d = 1/f, and f = 1/d. A 10 second duration has a frequency of 1/10 (think of it as
one in ten seconds). A 10 Hz frequency will result in a duration (between each cycle) of 1/10
th
of
a second. To link the two, set the duration to some percentage of the frequency. For example, d =
1/f * 0.5. If the frequency changes the duration will change too, and will always be 50% of the
time between each event.
Example 14.5 introduces a handy convention. The first patch is everything between the
first, the code that actually produces the sound, is everything from { // patch and }.play;. But
this entire patch is enclosed in parentheses. These parentheses have no real impact within the
patch, but they define a region. You can double click on the top parentheses to select the entire
patch, or use !-return to select and execute.
Try inserting the CombN used in the rising sines. Insert a line before the final mix; with
something like CombN(mix, etc.).
14.5:: Variables
(
{ // patch without variables
PlayBuf.ar(1, b, 1, Impulse.kr(1), MouseX.kr(0, b.numFrames))*
EnvGen.kr(Env.linen(0.1, 0.8, 0.1), Impulse.kr(1));
}.play;
)

(
{ // same patch with shorter duration (higher frequency) Impulse
PlayBuf.ar(1, b, 1, Impulse.kr(0.5), MouseX.kr(0, b.numFrames))*EnvGen.kr(Env.linen(0.05, 0.4,
0.05), Impulse.kr(0.5));
}.play;
)


(
{ // Variables for clarification
var mix, loop, duration;
duration = 0.5; // duration in seconds of the loop
loop = Impulse.kr(1/duration); // duration converted to frequency
mix = PlayBuf.ar(1, b, 1, loop, MouseX.kr(0, b.numFrames));
mix = mix * EnvGen.kr(Env.linen(0.1, 0.8, 0.1), loop, 1, 1, duration);
mix;
}.play;
)





131
::
The last line of code is simply mix. This is called the return, or the final results of the
function that are passed to the message play.
Aside from spreading out this patch for clarity, the variables solve a critical problem. The
envelope (in this case at least) needs to match the duration of each loop. In the second patch, not
only did I have to change both Impulse frequencies from 1 to 0.5, but I had to calculate the
attack, sustain, and decay of the envelope given a duration of 0.5. All that is done automatically
in the last example. Mix, which is a single loop, is multiplied by the envelope, which in turn is
scaled to the duration with the fifth argument of EnvGen; timeScale. The result is an envelope
that changes for any given duration, and changes in the other channels (covered soon). Imagine
doing 8 channels, each with a different duration, each with different attack, sustain, and release
times. With a variable, when the value for duration is changed, the attack, sustain, and release is
set to 10%, 80%, and 10% of the duration, whether 1/10
th
of a second or 5 seconds. Variables are
also (albeit slightly) more efficient since this patch uses a single Impulse in two places rather
than two Impulse UGens.
User Defined Arguments
The problem with variables is they cannot be changed once sent to the server. Like
existing Ugens, you can create your own arguments, which are variables that have a link to the
outside world and can be changed once a synth is running. They are declared before variables,
directly after the opening brace of a function. One additional component, the synth must be
loaded into a variable so that we can refer to it when changing the parameter. (But see SynthDefs
below.) The syntax is a.set(\argName, value).
14.6:: Arguments

// b = Buffer.loadDialog;

(
a = { // Arguments for control
arg speed = 1, position = 0.5;
var mix, loop, duration = 0.5;
loop = Impulse.kr(1/duration); // duration converted to frequency
mix = PlayBuf.ar(1, b, speed, loop, position * b.numFrames);
mix = mix * EnvGen.kr(Env.linen(0.1, 0.8, 0.1), loop, 1, 1, duration);
mix;
}.play;
)


a.set(\speed, -0.5);
a.set(\speed, 1.25);
a.set(\position, 0.2); // must be between 0 and 1
a.set(\position, 0.75);

a.set(\speed, rrand(-1.2, 1.2)); // execute these several times for different values
a.set(\position, rrand(0, 1.0));



132
::
Multi-Channel Expansion
! I love this trick: if any UGen argument, anywhere in a patch, is an array (e.g., [1, 3]), the
entire patch is duplicated using the first value for the left channel, the second for the right. (There
are some exceptions, discussed in later chapters.) If arrays are used for other arguments, they are
likewise split between the two channels. This is an extremely efficient way to expand a patch
into 2, 4, 8, heck, 16 channels.
Steve Reich's Come Out illustrates both looping and phase shift, which became a staple
of the minimalist style. The patch above is ready for similar treatment. We only have to change
one valuethe Impulse triggerreplacing the single 0.5 to an array of [1, 61/60]. This makes
the duration of the left channel 1 second, the right 61/60 seconds, or slightly longer. Stop for a
second and imagine what the resulting loops will do.
Both channels will start in phase, slowly shift out of phase, then back over sixty seconds.
In order to focus better on the phase shift I've replaced the MouseX.kr with a rrand, which picks
a value between 0 and total number of frames. Change it back if you'd like. Also replace it with
Line.kr(0, b.numFrames, 60) and it will not only move slowly out of phase, but also gradually
advance across the entire buffer.
Try running it several times.
14.7:: 60 Second Phase
(
{
var mix, loop, duration;
duration = [1, 61/60]; // duration in seconds of the loop
loop = Impulse.kr(1/duration); // duration converted to frequency
mix = PlayBuf.ar(1, b, 1, loop, rrand(0, b.numFrames));
mix = mix * EnvGen.kr(Env.linen(0.1, 0.8, 0.1), loop, timeScale: duration);
mix;
}.play;
)

::
You will know when the loop as come full cycle because it will sound like a mono signal;
both left and right channels will be the same.
Steve Reich slowed down one of the channels by pressing his thumb against the reel of
tape. In SC, it's just as easy, but with much more flexibility and precision. Change the 60/61 to
other ratios. May I suggest common interval ratios: 2/1, 3/2, 4/3, 8/5, 15/16, 45/32, etc. After
working with this patch for a few days you may bolt up in bed realizing the flaw; a 1 second loop
in the left channel and a 3/2 second loop in the right will have different durations, so the
smoothing envelopes also should be adjusted. If, for example, the left channel is a frequency of 1
and the right has a frequency of 61/60, it's loop will be slightly shorter, or is it longer? and by
how much? Well lay back down and rest easy. Since we used a variable it happens automatically.
If the duration is an array, say [1, 1.234] then the left envelope will be 1 * the envelope, the right
will be 1.234 * the envelope, because we used the timeScale argument.




133
Experiment
Now we can have some fun. First up are TRand, TIRand and TChoose, which return
random values with each trigger. TIRand returns integers only, which will be useful for our
ratios. TChoose selects items from an array.
14.8:: Generative Choices
(
{
var mix, loop, duration, rate, gen, start;
gen = Impulse.kr(1/15); // every 15 seconds
// choose another speed and direction at each gen trigger
rate = TRand.kr(-2.0, 2.0, gen); // Choose values between -2 and 2
start = TIRand.kr(0, b.numFrames, gen); // start location
duration = [1, 15/16]; // match the gen trigger; could I use a variable?
loop = Impulse.kr(1/duration); // duration converted to frequency
mix = PlayBuf.ar(1, b, rate, loop, start);
mix = mix * EnvGen.kr(Env.linen(0.1, 0.8, 0.1), loop, 1, 1, duration);
mix;
}.play;
)

(
{ // Be patient; change happens gradually.
var mix, loop, duration, rate, gen, start, baseloop, buffer;
gen = Impulse.kr(1/20); // every 20 seconds
baseloop = TRand.kr(0.5, 3.0, gen); // select a base loop time
// choose another speed and direction at each gen trigger
rate = TRand.kr(-2.0, 2.0, gen);
start = TIRand.kr(0, b.numFrames, gen);
duration = [baseloop, baseloop * TChoose.kr(gen, [3/2, 4/3, 5/4, 6/5])];
loop = Impulse.kr(1/duration); // duration converted to frequency
mix = PlayBuf.ar(1, b, rate, loop, start);
mix = mix * EnvGen.kr(Env.linen(0.1, 0.8, 0.1), loop, 1, 1, duration);
mix;
}.play;
)

// Load a new buffer on the fly
b = Buffer.loadDialog(bufnum: b.bufnum);

// This will switch you over to the sclang interpreter.
// To continue editing, or stop the sound, switch back to SuperCollider

::
The second differs slightly. The generative choice is lengthened to once every 20 seconds
to allow each pattern to play through, but each pattern is shorter, between 1 and 4 seconds. The
duration first takes a base loop time, chosen with a TRand, then the left channel uses that base



134
loop while the right uses the base loop multiplied by one of a collection of ratios, which is
chosen by TChoose at each gen trigger.
Finally, we wrap up the patch by loading a new buffer on the fly.
Exercises
14:1 Modify any of the patches above to include arguments rather than variables so that
you can change parameters on the fly.
14:2 In the studio, record samples of instruments or items to use in the experiments in the
next few chapters. Save the files as 01.aif, 02.aif, etc., so that you can easily swap
with other students.
14:3 With your prepared Concrte files handy, locate an existing preset in UltraBeat with
built in loops. Start the loop and drag and drop your samples, gradually turning the
drum beat into a sample beat.
14:4 Record yourself saying "come out to show 'dem." Import the sample into an empty
EXS24 instrument. First, try to reproduce Reich's seminal work with a gradual
phase shift. Continue with a study of phased patterns using intervals (octave, fifth,
fourth, third, second) and no more than two notes at a time.
14:5 Finish the comments in the following patch, documenting what each line does and
how it modifies the patch.

(
{
// This line ...
var mix, loop, duration, rate, gen, start, baseloop, buffer;
// Every 20 seconds gen...
gen = Impulse.kr(1/20);
// baseloop is...
baseloop = TRand.kr(0.5, 3.0, gen);
// rate changes... TRand chooses values...
rate = TRand.kr(-2.0, 2.0, gen);
// start resets the loop... TIRand returns...
start = TIRand.kr(0, b.numFrames, gen);
// duration is the duration of each...
duration = [baseloop, baseloop * TChoose.kr(gen, [3/2, 4/3, 5/4, 6/5])];
// loop defines...
loop = Impulse.kr(1/duration);
// mix is used to combine...
mix = PlayBuf.ar(1, b, rate, loop, start);
// The envelope generator smooths...
// The arguments are loop and duration, which...
mix = mix * EnvGen.kr(Env.linen(0.1, 0.8, 0.1), loop, 1, 1, duration);
mix;
}.play;
)





135
15. SC to Logic
Recording direct to disk. Granular systems.
When Apple introduced a Graphic User Interface, the computer world became more
accessible. But there was a trade off. Easier usually means slower, less flexible, and less depth.
UltraBeat and EXS24 offer images, dials, icons, menus, and drop fields that greatly simplify
building a sequence of loops. The disadvantage is being stuck with the interface as it was
designed. It's like driving modern cars. You have a lot of control, but only what the manufacturer
will allow. Despite incredible flexibility, sooner or later an idea will surface for which there is no
dial or lever. SuperCollider is a car part warehouse, filled with not just spark plugs and gears, but
machining tools with which you can make components from scratch. It allows you, requires you,
to get your hands dirty. It does have GUI objects, which we will cover later. This chapter offers a
few controls that are less involved. The first is a system for triggering events from the keyboard.
The second shows how to link SC and Logic, to exploit the strengths of each: SC's flexibility and
depth with Logics slick interface, routing, reverbs, and mix tools.
KeyState.kr
converts key presses from the computer keyboard into triggers. (See also;
KeyboardWindow.) The first argument identifies each key with a keycode. Modifiers (shift,
option, command) had no effect. It will still return the same number. You might expect a pattern
(a = 1, b = 2, etc.), but there is none. Figure 15.1 maps them out, more or less as they appear on
the keyboard, then in order. In Example 15.1 they are simply used as triggers to select a new
Rand value. I use only three codesleft, right, and down arrow.
15.1:: Keyboard Triggers

(
{
SinOsc.ar(
LFNoise0.kr(
TRand.kr(4, 12, KeyState.kr(123)), // Left arrow triggers new rate
mul: 6,
// Right arrow triggers new octave
add: TIRand.kr(4, 8, KeyState.kr(124))*12).midicps)
}.play
)

// If beginning from scratch
// b = Buffer.loadDialog;

(
{
var mix, loop, duration, rate, start, baseloop, buffer;
baseloop = TRand.kr(0.5, 3.0, KeyState.kr(125)); // Down arrow, new loop
rate = TRand.kr(-2.0, 2.0, KeyState.kr(123)); // Left arrow, new speed



136
start = TIRand.kr(0, b.numFrames, KeyState.kr(124)); // Right arrow, new start
duration = [baseloop, baseloop *
TChoose.kr(KeyState.kr(125), [3/2, 4/3, 5/4, 6/5])];
loop = Impulse.kr(1/duration);
mix = PlayBuf.ar(1, b, rate, loop, start);
mix = mix * EnvGen.kr(Env.linen(0.1, 0.8, 0.1), loop, timeScale: duration);
mix;
}.play;
)

::
Fig. 15-1 Keycode map
[1] 18 [2] 19 [3] 20 [4] 21 [5] 23 [6] 22 [7] 26 [8] 28 [9] 25 [0] 29 [-] 27 [=] 24
[q] 12 [w] 13 [e] 14 [r] 15 [t] 17 [y] 16 [u] 32 [i] 34 [o] 31 [p] 35 [ [ ] 33 [ ] ] 30 [\] 42
[a] 0 [s] 1 [d] 2 [f] 3 [g] 5 [h] 4 [j] 38 [k] 40 [l] 37 [;] 41 ['] 39 [(] 126
[z] 6 [x] 7 [c] 8 [v] 9 [b] 11 [n] 45 [m] 46 [,] 43 [.] 47 [/] 44 [)] 123 [*] 124
[space] 49 ['] 125

[ [ ] 33
[ ] ] 30
[-] 27
[,] 43
[;] 41
[.] 47
['] 39
[/] 44
[\] 42
[=] 24

[)] 123
[*] 124
[(] 126
['] 125
[space] 49

[0] 29
[1] 18
[2] 19
[3] 20
[4] 21
[5] 23
[6] 22
[7] 26
[8] 28
[9] 25

[a] 0
[b] 11
[c] 8
[d] 2
[e] 14
[f] 3
[g] 5
[h] 4
[i] 34
[j] 38

[k] 40
[l] 37
[m] 46
[n] 45
[o] 31
[p] 35
[q] 12
[r] 15
[s] 1
[t] 17

[u] 32
[v] 9
[w] 13
[x] 7
[y] 16
[z] 6

By now you should be generating material worth saving, to be used on its own or
compiled into a collage style composition using Logic as an editing tool. There are several ways
this can be done. The first is
Recording to Disk
The quickest method requires a GUI window for the server that can be created with the
code s.makeWindow. When you boot the server, it is automatically assigned to the variable s.
This variable can be used to send commands to the server, such as creating a GUI, starting a
recording, or changing record options. Once created, simply click on the record button to start
and stop the recording. Note also the mute and volume controls, Quit, and CPU information.
When the server GUI is focused you can press 0 to reset the volume to 0, s to bring up a
signal scope, m to mute, l to bring up a level meter, and f to open a frequency spectrum.




137
Fig. 15-2 Server GUI

Recording this way may be complicated by a number of factors. The first occurs if you
are using mouse controls; the slightest change in position will alter the audio considerably.
Relocating it to hit the record button will defeat the purpose and you may never find that precise
location again. To remedy this, click on the server window and note whether the record button is
highlighted with a border. If it is, you can start and stop recording with the space bar. If it is not,
try pressing tab repeatedly until it is. (You may have to turn full keyboard access on in the
system preferences.) Next, the server window belongs to the sclang application, so you will have
to switch to it before engaging record. The last complication is more critical in a multi-user (and
tightly administrated) lab: where are the files saved? Do you have write permissions for that
folder? The default location is the Music folder of the home user. Another solution is to set the
record directory explicitly. (You can also specify a file name, but this is more work, and slightly
dangerous. If you neglect to change the file name each time you want to record your previous
recording will be overwritten without warning.) Change your_user_name to, uh, your user name.
15.2:: Options for Record
thisProcess.platform.recordingsDir = "/Users/Change_to_your_user_name/Desktop/"

s.prepareForRecord; // or Server.local
s.record;
s.stopRecording;

// Run these variations before to change file formats.
s.recSampleFormat = "int16"; // change format
s.recChannels = 1; // change from the default stereo

// saves file with specific name in the default folder, will be overwritten if repeated
s.prepareForRecord("myAudio.aif");

// Specific location
s.prepareForRecord("/Users/your_user_name/Desktop/myAudio.aif");

::
Once saved, these files can be opened in Amadeus or dragged into a Logic session. A
more direct method is to record directly into Logic by connecting
SC to Logic using Soundflower
which is an open source plug-in that allows you to change the routing of applications
within the operating system. (See also: JackPilot.)



138
(Install Soundflower.) Launch Logic and SC. In Logic, open the audio preferences dialog.
Choose Soundflower (16ch) as the input source. Add four audio tracks, set the inputs to 1, 2, 3,
and 4, and click on the I to monitor the input.
The whole point of this exercise is to combine the features in Logic with the sounds
created in SC. To that end, create two auxiliary sends for all four tracks. On one of the resulting
auxiliaries add a reverb, add a delay designer on the other.
In SuperCollider, run the lines in Example 15.3. The first line has two statements. The
first sets the output to Soundflower. The next reboots the server. The next line sends a test tone
to the first four channels. You should see signal in the Logic tracks and hear signal in your
speakers. This may take a little tweaking to get it right. Take your time. I can wait. Note that all
buffers are cleared when the server is rebooted. You will have to load them again. Once you get
the test-tone to work, try some of the previous patches.
To switch the system back to the default audio device, just use "nil."
15.3:: SC to Soundflower to Logic
s.options.device_("Soundflower (16ch)"); s.reboot;

// Test tone
{SinOsc.ar([400, 600, 800, 1000])*0.3}.play//

// To switch back to the system default device, use nil

s.options.device_(nil); s.reboot;

// Note that if you've restarted the server to use a different routing,
// you will have to reload all buffers. We will use two buffers in the next examples.

b = Buffer.loadDialog;
c = Buffer.loadDialog;

::
Add two more tracks in Logic Pro. Pan each track to a different position: hard left, left,
barely left, barely right, right, hard right.
The next patches expand previous examples to illustrate the possibilities using the outputs
0 through 5 of SC, and inputs 1 through 6 of Logic. (You read correctly. Computers start
counting at 0, humans start at 1. Sorry.) You can change the outbus simply to route it to different
tracks in Logic. For example, working in stereo you might record a patch using outbus: 0 to
record to tracks 1 and 2, then switch to outbus: 2 to record to tracks 3 and 4, and so on.
When working with generative looped concrte the output levels can change drastically.
You may stumble on an interesting loop and mouse position that uses a quiet part of the original
sample. Remember there is a volume adjustment in the server window. If you turn on full
keyboard access you can tab to the slider and use the arrows to increase or decrease the output
(so that you don't have to move the mouse from the position you want to capture).
When you find an interesting sound, simply arm the logic tracks and click record.




139
Real-Time Analysis
is another advantage to using SoundFlower. You can link SC to both Logic and
Amadeus Pro and use analysis tools in either. In Amadeus Pro, open any of the real-time analysis
windows under the Analysis menu. Click on Soundflower as an input and also Playthrough.
Every patch you run in SC will be analyzed in the waveform, sonogram, spectrogram, etc. It's a
slick and simple way to get a visual reinforcement of a particular process. It's also handy for
teaching.
Example 15.4 shows a number of variations based on Reich's original idea for
Come Out
Some of them use two buffers. But I'm not convinced it is effective. (Technology invites
complexity. But remember sophisticated treatment is not intelligent treatment. Two buffers are
difficult to focus on.) I prefer the variations that use one. I collect the buffers, as well as the
buffer durations in two global arrays for convenience. Items in an array are recalled (referenced)
with the syntax array.at(n), so in this example, ~durs.at(0). Remember that computers begin
counting with 0.
In addition to the global variables a through z, you can create your own by preceding a
variable name with the tilde (~) character. Here I also introduce the commented alternatives
technique. That is, a line of code is followed by an alternative line, but commented. To try this
alternative, remove the comments. It is not necessary to comment the line that it replaces, since
the new line will replace the one above when executed.
15.4:: Come Out Variations
// Note that if you've restarted the server to use a different routing,
// you will have to reload all buffers.

b = Buffer.loadDialog;
c = Buffer.loadDialog;

// Collect the buffers into a single array.
~buffers = [b, c];

~durs = [b, c];

// Test to see if you are getting signal to all channels in Logic.
// Modify this to two items if you're working in stereo.

{SinOsc.ar([400, 600, 800, 1000, 1200, 1400])*0.3}.play

// Test the buffers in two channels.

{PlayBuf.ar(1, ~buffers)}.play

(
{ // This uses a single loop, but different ratios or rate
// be sure to engage down, left, and right arrows



140
var mix, loop, duration, rate, start, baseloop, buffer;
baseloop = TRand.kr(0.5, 3.0, KeyState.kr(125)); // Down arrow
rate = TRand.kr(-2.0, 2.0, KeyState.kr(123)); // Left arrow
start = TIRand.kr(0, b.numFrames, KeyState.kr(124)); // Right arrow
// start = LFTri.kr(1/60, 0, 0.5, 0.5)*(c.numFrames);
duration = 1;
// duration = baseloop*[1, 3/2, 4/3, 5/4];
// duration = [20, 21, 22, 23, 24, 25]/20;
loop = Impulse.kr(1/duration);
mix = PlayBuf.ar(1, b, rate, loop, start);
// mix = PlayBuf.ar(1, c, rate*[1, 3/2, -3/2, 2], loop, start);
// mix = PlayBuf.ar(1, ~buffers, rate, loop, start);
mix = mix * EnvGen.kr(Env.linen(0.1, 0.8, 0.1), loop, timeScale: duration);
mix*0.3;
}.play(outbus: 0);
)

// Load new buffers on the fly

b = Buffer.loadDialog(bufnum: b.bufnum);
c = Buffer.loadDialog(bufnum: c.bufnum);

(
{ // Single loop, more gradual phase shift over 30 seconds, six channels.
// This one uses a mouse control
var mix, loop, duration, rate = 1, start, baseloop = 1, buffer = b;
start = LFTri.kr(1/[60, 61, 62, 63, 64, 65], mul: 0.5, add: 0.5) * buffer.numFrames;
baseloop = [30, 31, 32, 33, 34, 35]/30;
baseloop = MouseX.kr(1, 25); // Grains
duration = 1/baseloop;
loop = Impulse.kr(1/duration);
mix = PlayBuf.ar(1, buffer, rate, loop, start);
mix = mix * EnvGen.kr(Env.linen(0.1, 0.8, 0.1), loop, timeScale: duration);
mix*0.3;
}.play(s);
)


(
{ // Single loop, start position phase shift.
// Mouse control size of loop and speed of shift.
var mix, loop, duration, rate = 1, start, baseloop = 1, buffer = b;
start = LFTri.kr(MouseY.kr(1, 60)/[60, 61, 62, 63, 64, 65],
mul: 0.5, add: 0.5) *
buffer.numFrames;
baseloop = MouseX.kr(1, 25); // When loop is very small, they become "grains."
duration = 1/baseloop;
loop = Impulse.kr(1/duration);
mix = PlayBuf.ar(1, buffer, rate, loop, start);
mix = mix * EnvGen.kr(Env.linen(0.1, 0.8, 0.1), loop, timeScale: duration);
mix*0.3;




141
}.play(s);
)

(
{ // This example uses channels 0 and 1, adjust panning.
var srate = 44100, start = 0, end = 3, duration, rate = 1, signal;
duration = abs(end - start);
// or
// end = [2.3, 3.5];
signal = BufRd.ar(1, b, // Buffer 0
LinLin.ar(
LFSaw.ar(rate/duration, 1), -1, 1, start, end)*srate
)*EnvGen.kr(Env.linen(0.01, 0.98, 0.01), timeScale: duration,
gate: Impulse.kr(1/duration));

SinOsc.ar(LFNoise1.kr([0.4, 0.43], mul: 200, add: 200))*signal;
// or
SinOsc.ar(LFNoise0.kr([12, 15], mul: 300, add: 600))*signal;
// or
// SinOsc.ar(LFNoise1.kr([0.4, 0.43], mul: 500, add: 1000))*signal;

}.play(s)
)


// Pulsing in and out

(
{ // Also only stereo. Adjust panning
var srate = 44100, start = 0, end = 3, duration, rate = 1;
var pulse;
pulse = [6, 10];
duration = abs(end - start);
BufRd.ar(1, b, // Buffer 0
LinLin.ar(
LFSaw.ar(rate/duration, 1), -1, 1, start, end)*srate
)*EnvGen.kr(Env.linen(0.01, 0.3, 0.01), timeScale: duration/pulse,
gate: Impulse.kr(pulse/duration));
}.play(s)
)

// Filtered

(
{ // Stereo
var srate = 44100, start = 0, end = 3, duration, rate = 1, signal;
duration = abs(end - start);
signal = BufRd.ar(1, c, // Buffer 0
LinLin.ar(
LFSaw.ar(rate/duration, 1), -1, 1, start, end)*srate
)*EnvGen.kr(Env.linen(0.01, 0.98, 0.01), timeScale: duration,



142
gate: Impulse.kr(1/duration));
RLPF.ar(signal, LFNoise1.kr([12, 5], mul: 700, add: 1000), rq: 0.05)*0.2;
}.play(s)
)
::
Granular Synthesis
The first examples above have a loop time between 0.5 and 3 seconds. In the last few
examples the size of the loops can be very small; 1/25
th
of a second. This wasn't possible in the
days of tape splicing, though they certainly dreamed about it. Of course now it is possible, but
we use the term grains, or granular synthesis.
TGrains is similar to PlayBuf, but the envelope (interpolation) is not as steep. The grains
can overlap, and there is a pan argument, which we can put to good use. Since there is a pan, the
minimum value for numChannels is 2. The centerpos is analogous to the start position in
PlayBuf. The trate in 15.5 moves according to the mouse position. Near the top is very slow; 1 in
4 seconds, so you can hear what a grain is, and what is going on at very high rates, such as 200
Hz. As with the previous examples, the duration of each grain can be different from the rate. A
duration of 1/trate leaves quite a bit of space between the grains because of the interpolation. A
4/trate is 4 times the length of each grain, but this overlap makes the grains more effective at
faster speeds.
In this example we load the buffer using read rather than loadDialog. This is faster if you
are using the same audio file over and over. Note that it must be a mono audio file to work.
Replace "REPLACE_WITH_User" with your user name. Alternately; you can drag the file
anywhere in the editor and it will produce the path name in quotes.
15.5:: Granular Synthesis
b = Buffer.read(s, "/Users/REPLACE_WITH_User/Desktop/Cage_quote.aif");

// or drag the file to the second argument position below: read(s, HERE);
b = Buffer.read(s, );

b.play;


(
{
var trate, trigger, dur, center;
trate = MouseY.kr(1/4,200,1);
dur = 4 / trate;
trigger = Impulse.kr(trate);
center = MouseX.kr(0,BufDur.kr(b));
// numChannels, trigger, bufnum, rate, centerPos, dur, pan, amp, interp
TGrains.ar(2, trigger, b, 1, center, dur, 0, 0.5, 4);
}.play;
)

::




143
The next example engages the pan position and speed using a TRand as before. Pan can
be -1 (left channel) to 1 (right channel). If you are still routing the signal through Logic, adjust
the pan on the first two channels to hard left and hard right.
The first (commented) alternative is an interesting twist. The center position pops around
the file using a random generator. Another center alternative is below the panpos. It links the
center location with the pan position, so that the beginning parts of the file will be left, the
middle, center, etc. The speed alternative links rate with panpos also; fast grains on the outsides,
slow ones in the middle, backward loops on the left, forward on the right. Try that with just a
tape deck and splicing blocks.
15.6:: Grains with Pan and Speed
(
{
var trate, trigger, dur, center, panpos, speed;
trate = MouseY.kr(1/4,200,1);
trigger = Impulse.kr(trate);
dur = 4 / trate;
center = MouseX.kr(0,BufDur.kr(b));
// center = TRand.kr(0, BufDur.kr(b), trigger);
// center = Dseq([0, 0.1, 0.9, 0.7, 0.4, 0.5, 0.6, 0.4, 0.3, 0] * b.numFrames, inf);
panpos = TRand.kr(-1.0, 1.0, trigger);
// panpos = Dseq([-1, -0.3, 0, -0.6, 0, 0.1, 1, 0.5, 0.3, 1], inf);
speed = TRand.kr(-2.0, 2.0, trigger);
// center = (panpos /2 + 0.5) * BufDur.kr(b);
// speed = panpos * 2;
// speed = Dseq([-1, 1, -0.1, 0.5, -0.5, 3, 1, 0.3, -0.3, -1], inf);
TGrains.ar(2, trigger, b, speed, center, dur, panpos, 0.5, 4);
}.play;
)

::

Have I mentioned there is absolutely nothing on earth that can generate these kinds of
sounds. (I'm speaking of granular synthesis in general, not SC specifically.) But there are
precious few synthesis packages that can do granular synthesis.
Sequenced Granular Synthesis
The last set of commented lines uses a Dseq, which returns an array of values in sequence
with each triggered event. (More on this laterafter I figure out how it works.) The first
argument is the array of values, the second is the number of repeats. In this patch it is set to inf or
infinite repeats. The current version has 10 values for each array. This ensures the patterns
match. Making them different lengths8, 9, and 10will set the patterns into a phase shift.
Setting center, panpos, and speed to a Dseq is too repetitive. Setting them to different lengths is
too much variation. As with all music, search for a balance between variation and repetition. I
prefer leaving at least one with a mouse control.



144
Exercises
15:1 Choose your favorite version of the patches above and document each line with
comments. You may have to change the values, then listen to the patch as you
document.
15:2 In Logic, add auxiliary reverbs, delays, and possibly serial effects to the channels.
When you arrive at an interesting variation, commit it to disk by recording it in
Logic. Continue in Logic to build a foundation for an electro-acoustic work.
15:3 Use the granular synthesis patch with mouse controls to add a "lead" to your
composition. Perform it live and record several takes. Choose from the takes using
the comp features in Logic.





145
16. Wave Generators
Analog synthesizers; but now digital.
Visual arts use color, shape, texture, and brightness. Similarly, music can be broken down
into frequency, amplitude, and timbre, as described in previous chapters. The following
illustrates how to control these three characteristics using SC wave form generators.
Frequency, Amplitude, Timbre
The arguments for a SinOsc are frequency, phase, mul, and add. Frequency is the number
of cycles per second. Amplitude (mul) changes the height of the wave. Phase changes where in
the cycle the wave begins. (Changing the offset moves the wave up or down. This makes no
sense, and shouldn't be done with a simple audio wave. Offset is used for control sources,
covered later.)
Changing the frequency and amplitude translate into pitch and volume. We don't hear a
change in phase, but when several waves of different phase are combined, we hear the results of
the interaction.
Voltage Control
Early synthesizer modules were labeled VCO,
VCA, and VCFacronyms for voltage controlled
oscillator (to control pitch), amplifier (to control
amplitude), and filter (to control upper harmonic
structure). Nearly all previous patches have used voltage
controls (MouseX, TRand, LFNoise, etc.). The term
voltage is not technically correct for what happens inside a
computer, but the results are the same, so the term lingers.
They are also what you will see on analog synthesizers and
most Logic instruments. Control simply means changing a
parameter. When you turn the volume of your stereo up
you are manually controlling the amplitude parameter.
When you press your finger down on the string of a guitar you manually control the length of the
string and therefore the frequency. Controlling these parameters with the precision, accuracy,
speed, and flexibility inherent in electrical circuitry is what inspired early pioneers. The
limitations inherent in real instruments and humans playing them (how high we can sing, how
fast we can play, how loud a piano can be) could be surpassed with electrically generated and
controlled sound. They were right, and today there are virtually no limits to what you can do in
computer music. They can easily exceed our ability to perceive. The limits, dear Brutus, is not in
the machines, but in ourselves.
Example 16.2 shows three SinOsc patches. The first has a static value for frequency, the
second replaces that static value with a MouseX control (which is still, technically, manual
control), the third replaces it with a TRand. TRand supplies a string of values to the SinOsc,
which uses them for the frequency argument, at the rate specified by the Impulse trigger. This is
a basic voltage controlled frequency. The frequency is being supplied by the TRand.



146
16.1:: VCO SinOsc
{SinOsc.ar(freq: 440)}.play

{SinOsc.ar(freq: MouseX.kr(200, 2000))}.play

{SinOsc.ar(freq: TRand.kr(200, 2000, Impulse.kr(5)))}.play

::
The arguments for TRand are lo, hi, and trigger. The trigger is Impulse.kr. It takes only
one argument for frequency. There are, therefore, two frequencies in the third patch. This is often
confusing. There is the frequency of the SinOsc, which are changing values between 200 and
2000. This is the frequency we hear as pitch. The frequency of the Impulse is 5 Hz, or 5 times
per second. We don't hear this frequency as a pitch, but as a tempo; the number of times per
second a new pitch is heard. Frequencies below 20 Hz are called LFOs; low frequency
oscillators.
Example 16.2 shows controls of frequency, amplitude, and timbre using three TRands as
VCO, VCF, and VCA in a Blip. The arguments for Blip are frequency, number of harmonics
(more give a brighter timbre, fewer a duller sound, so essentially a filter), and mul, or amplitude.
Recall the exercise where you sang into an Amadeus oscilloscope and changed frequency but not
timbre or amplitude, then amplitude only, then timbre only. This is the same thing, but using an
automated, voltage control.
16.2:: VCO, VCF, VCA using Blip
// Controlling frequency
{Blip.ar(TRand.kr(200, 2000, Impulse.kr(5)))}.play

// Controlling filter (number of harmonics)
{Blip.ar(300, TRand.kr(0, 20, Impulse.kr(5)))}.play

// Controlling amplitude
{Blip.ar(300, 4, TRand.kr(0.1, 0.9, Impulse.kr(5)))}.play

// All three
(
{Blip.ar(
TRand.kr(200, 600, Impulse.kr(5)),
TRand.kr(0, 20, Impulse.kr(5)),
TRand.kr(0.1, 0.9, Impulse.kr(5)))}.play
)
::
Scale and Offset
Notice that all three TRands differ only in lo and hi value. In the last example, the three
TRands are combined as VCO, VCF, and VCA. If this were a much more complicated patch
with hundreds of components, this duplication could eat up CPU. It would be more efficient to
use a single TRand for all three, but we cannot do that if the values required are so disparate.




147
The solution is offset and scale; use a single TRand with a range of 0 to 1 and modify the
range with simple math. Example 16.3 shows how a TRand with a range of 0 to 1 can be
transformed using offsets and scales. It uses poll, which prints the values to the data window, so
you can monitor the output. Run the first line. You should see values between 0 and 1. The
second example uses a single TRand but the values are multiplied by 100. The last adds 100.
Adding or subtracting changes the offset. Multiplying changes the scale.
16.3:: Scale and Offset Examples
{(TRand.kr(0, 1.0, Impulse.kr(10))).poll(label: 'rand')}.play // range of 0 to 1

{(TRand.kr(0, 1.0, Impulse.kr(10)) * 100).poll(label: 'rand')}.play // range of 0 to 100

{(TRand.kr(0, 1.0, Impulse.kr(10)) + 100).poll(label: 'rand')}.play // range of 100 to 101

[0, 0.5, 1, 0.5, 0, -0.5, -1, -0.5, 0] .plot("default", minval: -5, maxval: 5); // triangle

// scale by 3
([0, 0.5, 1, 0.5, 0, -0.5, -1, -0.5, 0] * 3) .plot("*3", minval: -5, maxval: 5);

// scale by 2, offset by 3
([0, 0.5, 1, 0.5, 0, -0.5, -1, -0.5, 0] * 2 + 3) .plot("*2, + 3", minval: -5, maxval: 5);

// scale by 100, offset by 300
([0, 0.5, 1, 0.5, 0, -0.5, -1, -0.5, 0] * 100 + 300) .plot("*100, +300", minval: -500, maxval: 500);

::
You can think of any wave generator as a stream (or array) of numbers describing the
shape of the wave (because, uh, that's what it is). The second half of example 16.3 shows how
offset and scale can change a wave. The first array of values describe, albeit at a very low sample
rate, a triangle wave. The message plot realizes them in a plot in the sclang program. (The size of
the plot is -5 to 5. The wave shows up between -1 and 1.) When scaled by 3, the shape of the
wave doesn't change, but the range of values produced is greater: -3 to 3. The next shows a scale
of 2, then offset of 3. Note that the triangle retains it's shape, only the range that it covers
changes. The last, a scale of 100, offset of 300, resulting in a range of 200 to 400.
Figure 16.1 shows the resulting plots. Of course, this triangle wave is no longer useful as
an audio output, since 1 and -1 are the maximum values of the audio output. Scaling and
offsetting in this way adjusts a single source so that it can be used with arguments that require
different ranges, typically, as controls. The -3 to +3 could be used to control playback speed of a
concrte patch. The next example, with a range of 1 to 5, might be used to control the number of
overtones in Blip. The last example has a range of 200 to 400. These numbers are appropriate as
a control source for frequency.




148


Fig. 16-1 Scale and Offset
Precedence
! in SC is different from what you might expect. In a math class 10 + 5 * 6 and 6 * 5 +
10 would be the same (40) because the rules of precedence are; multiplication then the addition.
In SC the rules of precedence are simple, but very different; operations are performed from left
to right. So 10 + 5 * 6 = 90, but 6 * 5 + 10 = 40, and 10 + 6 * 5 = 80. If you need to force
precedence, use parentheses (10 + (5*6) = 10 + (6*5) = (6*5) + 10 = 40).
In the patch below a single TRand and single Impulse are stored in the variable control.
That single control, producing values between 0 and 1, is used as a VCO, VCF, and VCA. The
VCA (mul) doesn't need to be scaled or offset, since it's values are already 0 to 1. The VCF
(number of harmonics) is scaled by 20. The VCO (frequency) is first scaled by 500, then offset
by 500. Each control is enclosed in parentheses and passed to the poll message, which prints the
value ten times a second. Once you've confirmed that the values are correct for frequency,
harmonics, and amplitude, try faster rates4, 10, 20for the Impulse. It is worth patching this
example through SoundFlower, then monitoring it using Amadeus' oscilloscope. This allows you
to see the controls in the wave. Frequency will change the number of peaks in the scope,
amplitude the height of the peaks, timbre the shape (how sharp the peak is).
16.4:: Scale and Offset Patch
(
{
var control;
control = TRand.kr(0, 1.0, Impulse.kr(1));
Blip.ar(
(control * 500 + 500).poll(10, "freq"),
(control * 10).poll(10, "timbre"),
control.poll(10, "amp")
)
}.play
)





149
::
Keyword Assignment
Arguments have to be in the correct order. The fourth argument for a SinOsc is mul. If
you want to give it a value, you need to supply values for freq, and phase even if the defaults are
sufficient. They are needed as place markers so that the mul is in the correct position.
This becomes a problem if there are, say, six arguments, and you want to change the
sixth. You would have to enter arguments 1-5 just so the sixth argument is in position six. This is
not only cumbersome, but invites error.
! The solution is keyword assignment. You can precede an argument with a keyword and
colon. Keyword names can be found in the documentation files and are seen in the help bubbles
while typing. The documentation for SinOsc.ar shows: SinOsc.ar(freq, phase, mul, add). The
keywords then are freq, phase, mul, and add. Using keywords not only allows you to enter a
single argument out of order, but to mix the order of the arguments. Here are several versions of
the SinOsc example written using keywords. All of them have precisely the same meaning and
will sound the same.
16.5:: Keywords
{SinOsc.ar(freq: 440, phase: 0, mul: 0.4, add: 0)}.play;

{SinOsc.ar(phase: 0, freq: 440, add: 0, mul: 0.4)}.play;

{SinOsc.ar(freq: 440, mul: 0.4)}.play;

::
! Another good reason for using keywords is clarity. The keyword provides an explanation
of what each value means, like a short comment.
The last reason for using keywords is portability. As mentioned earlier, argument lists are
not interchangeable. Consider these two lines: Saw.ar(100, 500, 600) and SinOsc.ar(100, 500,
600). The arguments for Saw are freq, mul, and add. But for SinOsc they are freq, phase, mul,
and add. So the two lists are not interchangeable. I can certainly use 100, 500, and 600 as
arguments for the SinOsc, but they don't mean the same thing as they did with the Saw. A phase
of 500 makes no sense, and a mul of 600 without an add will produce negative values, probably
not what I want.
Keywords (provided the two UGens have the same keywords) make the objects
interchangeable: SinOsc.ar(freq: 100, mul: 500, add: 1000) and Saw.ar(freq: 100, mul: 500,
add: 1000) will have a similar effect in a patch. Warning: this can be either dangerous or a
source of serendipity. You should always double check the keywords and understand what they
mean in a patch.
Here is the first patch using keywords followed by dangerous swapping.
16.6:: First Patch using Keywords
{SinOsc.ar(freq: LFNoise0.ar(freq: [10, 15], mul: 400, add: 800), mul: 0.3)}.play



150

{Saw.ar(freq: LFNoise0.ar(freq: [10, 15], mul: 400, add: 800), mul: 0.3)}.play

{SinOsc.ar(freq: LFNoise1.ar(freq: [10, 15], mul: 400, add: 800), mul: 0.3)}.play

{Pulse.ar(freq: LFNoise1.ar(freq: [10, 15], mul: 400, add: 800), mul: 0.3)}.play

{Pulse.ar(freq: LFSaw.ar(freq: [10, 15], mul: 400, add: 800), mul: 0.3)}.play

{LFTri.ar(freq: LFPulse.ar(freq: [10, 15], mul: 400, add: 800), mul: 0.3)}.play

{LFTri.ar(freq: LFTri.ar(freq: [10, 15], mul: 400, add: 800), mul: 0.3)}.play

::
Vibrato
is a simple voltage control common on most synthesizer patches. On a live instrument,
vibrato is a slight oscillation (convenient, since we have oscillators) in either the amplitude (in
the case of voice) or pitch (in the case of stringed instruments). String musicians generate vibrato
by rolling the finger forward and backward on the string. Given an A 440 the actual pitch with
vibrato would move between, say 435 and 445, essentially moving in and out of tune about 5
times per second. In some previous SinOsc patches the frequency argument was a static value
(such as 440). We need to replace the static value with some function or UGen that will change
smoothly over time between 435 and 445. A sine wave moves back and forth between two
values at a periodic and predictable rate, but not 435 and 445. We can use a slow moving SinOsc,
scaled and offset correctly, as the input or freq argument for another SinOsc.
The example below shows SinOsc UGens attached to a poll to print the values it
produces. The frequency is 1 cycle in 4 seconds. Its default output is similar to the triangle wave
earlier. It starts at 0 then moves to 1 then back to 0, then negative 1, then 0. More precisely, it's
range is 0 +/-1 (zero plus and minus one). The difference between frequency and output is very
confusing to beginners. The frequency is the number of times the wave moves up and down in
one second. The output is the string of numbers that are actually generated by the up and down
motion. In each of these examples the frequency is the same: 1/4 (once every four seconds). The
output, however, is modified in each one. While the oscillation is still 1 in 4 seconds, the output
of the first example is 0 +/-1. In the second example the frequency is still 1 in 4, but the output is
now 0 +/-5. In the third example the output is 440, +/-1. The last example has both: scale by 5,
offset by 440. Finally, the plot.
16.7:: SinOsc poll
{SinOsc.ar(1/4).round(0.01).poll; 0}.play // -1 to 1

{(SinOsc.ar(1/4) * 5).round(0.01).poll; 0}.play // -5 to 5

{(SinOsc.ar(1/4) + 440).round(0.01).poll; 0}.play // 339 to 441

{(SinOsc.ar(1/4) * 5 + 440).round(0.01).poll; 0}.play // 395 to 405





151
{(SinOsc.ar * 5 + 440)}.plot
::
Example 16.8 illustrates how this offset and scaled LFO sine oscillator can be linked to a
second SinOsc to create a subtle vibrato. Use a MouseX to determine which parameter is
responsible for the speed of the vibrato, which is the depth, and which is the pitch we hear. Try
higher depths. Try faster speeds until you find a natural sounding vibrato. Try a lower speed to
clearly see the poll results. (Do not try speeds or depths higher than 20 Hz! In fact, it is
irresponsible of me to bring it up. Forget I said anything.)
16.8:: VCO Vibrato
(
{ var control;
control = SinOsc.kr(4) * 5 + 600;
SinOsc.ar(control.poll);
}.play
)

::
When I first tried a VCO control on a vintage machine the offset and scale were
absolutely clear because I had a knob at my finger tips that changed them both. Sometimes that
tactile feedback helps. Example 16.9 creates a GUI (covered later, and I'm taking a lot of
shortcuts here) with sliders to control the three key components of a low frequency control; the
rate or frequency of the controlling wave, the scale of the wave, and the offset. Note that none of
these sliders control the parameters of the sine that we hear. Not directly, at least. They are only
linked to the controlling wave. The audio wave (the one we hear as a pitch) gets its frequency
directly from the controlling oscillator. Again, it would be useful to watch the change using
Amadeus' real time sonogram. To stop this, close the window, switch back to SC and press !-
period. Sorry for the kluge.
16.9:: Rate, Scale, and Offset Sliders
(
var inst, gbutton;
var gkfreq, gscale, goffset, gWin;

inst = {arg rate = 4, scale = 30, offset = 800;
SinOsc.ar(SinOsc.kr(rate, mul: scale, add: offset), mul: 0.3)}.play;

gWin=Window.new.front;
gWin.view.decorator = FlowLayout(gWin.view.bounds);
gkfreq = EZSlider(gWin, 400@20, "Rate", [1, 20, \lin, 0.1, 4].asSpec)
.action_({|sl| inst.set(\rate, sl.value)});
gscale = EZSlider(gWin, 400@20, "Scale", [10, 1000, \lin, 10, 30].asSpec)
.action_({|sl| inst.set(\scale, sl.value)});
goffset = EZSlider(gWin, 400@20, "Offset", [100, 3000, \exp, 10, 800].asSpec)
.action_({|sl| inst.set(\offset, sl.value)});
)




152
::
Offset and scale are so integral to synthesis that most UGens have a mul and add
argument built in. In fact, the first line should have been written SinOsc.kr(4, mul: 5, add: 440).
(Note the keywords to avoid using the phase argument.) The results are the same.
This is a fairly believable vibrato, if a bit crude, manufactured, or flat; like a lot of early
electronic music. (And to be fair, we all knew it. Many early works seem comical; like the first
attempts at moving pictures. This explains, in part, the appeal of Concrte. At the time tape work
was much more sophisticated, just because the sounds were so complex. But we also saw the
potential of analog synthesis. Logic Pro illustrates how it has matured, and how we benefit from
the vision of analog pioneers.)
Real musicians don't dive right into a vibrato. They usually start with a pure tone then
gradually increase the speed and width of the vibrato. Which values would you change to make
the vibrato more natural? How would you change them?
The envelope Line.kr can make a gradual change over time. The example below adds a
second layer of controls. Supply the missing arguments.
16.10:: Vibrato Envelope
( { var vibrato, speed, depth;
speed = Line.kr(start, end, duration);
depth = Line.kr(start, end, duration);
vibrato = SinOsc.kr(speed, mul: depth, add: 440);
SinOsc.ar(vibrato);
}.play
)

::
Lest you get too comfortable in your grasp of offset and scale, I'm going to add the
following complication. Values for offset and scale differ depending on the type of UGen
Unipolar/Bipolar
! The first KRand used to illustrate offset and scale was unipolar; it generated only positive
values between 0 and 1. The SinOsc is bipolar, and returns positive and negative values between
-1 and 1. Most UGens are bipolar, but many are unipolar. The difference is important when
calculating offset and scale. Below are two arrays of values. The first is unipolar, the second
bipolar. They are both scaled by 100 and offset by 100. But notice how different the results are.
[0, 0.1, 0.5, 0.4, 0.9] * 100 = [0, 10, 50, 40, 90] + 100 = [100, 110, 150, 140, 190]
[0, -0.1, -0.5, 0.4, 0.9] * 100 = [0, -10, -50, 40, 90] + 100 = [100, 90, 50, 140, 190]
An easy way to remember is that in both cases the offset replaces the 0 and the scale
replaces the 1s. A unipolar UGen's output is 0 to 1. When offset by 100 then scaled by 100, 0
becomes 100 and 1 becomes 200. A bipolar UGen's output is 0 +/-1. When offset by 100 then
scaled by 100, 0 becomes 100, -1 becomes 0, and 1 becomes 200. Said a different, possibly (but I
won't guarantee) less confusing way; offset is what 0 used to be, scale is the deviation from that.
The EnvGen is a unipolar control. It creates, by default, values between 0 and 1.




153
Fig. 16-2 Unipolar Output

When scaled, zero also stays the same, but 1 is replaced by the value of scale. Notice that this
does not produce negative values (when offset is 0) nor values below the offset (when offset is
different from 0).
Fig. 16-3 Unipolar Scaled by 5

Fig. 16-4 Unipolar Offset by 100, Scaled by 5

Offset and scale are not temporary asides along our path to the real topics of synthesis. It took
me several days. You have to have the same eureka moment. They are the core of every patch we
will build. Skip ahead and complete exercise 16.1 before moving onto the Theremin.
Audio UGen, Control UGen (Carrier, Modulator)
The vibrato example uses two SinOsc UGens but in very different ways. One is the sound
you hear (carrier) and the other changes the sound you hear (modulator). Each has a frequency
that determines the aggregate sound, but in different ways. The freq of the modulator determines
the speed of the vibrato. The freq argument of the carrier is the pitch we hear. The scale of the
carrier (5) is the width of the vibrato. The offset (600) is the pitch that we hear, + and - 5 Hz.
Change each of these values to confirm how they are related to the vibrato.
! The difference is the rate. The carrier SinOsc uses the ar message while the modulator
SinOsc uses kr. The ar stands for audio rate while kr is control rate. The carrier SinOsc is
generating actual audio so it needs to be audio rate (44.1k). But controls that are not heard as
audio, but rather transfer their shape as a control, or that trigger other UGens, do not need such
high resolution and are more efficient if generated at a lower rate. A SinOsc.kr will generate a



154
sine wave at 1/64th the rate of a SinOsc.ar. In short, kr is more efficient, and should be used for
control UGens.
Theremin
The Theremin was one of the first universally popular electronic instruments. It's the only
instrument I know that is played without touching. One of the first film scores to included the
Theremin won an academy award; Spellbound. Hitchcock didn't like it, but became so pervasive
and closely linked to the alien worlds of early sci-fi that it surfaces in stand up comedy (Robert
Klein) and MST3K riffs ("I know that Theremin is around here somewhere"). Most people think
they recognize it in the Beach Boys' Good Vibrations. In fact, they were unable to find a real
Theremin, so they used an analog synthesizer to imitate the iconic sound. I include it here as an
application of vibrato, because the two characteristics we most identify with this instrument are
the glissando between pitches (a continuum rather than discrete pitches) and a solid wide vibrato.
The vibrato was not the result of a voltage control (as in these examples), but generated by the
performer's hand. Perhaps they felt the need for some added dimension to compensate for the
cold character of a pure sine wave and inevitable difficulties with intonation.
Below is a virtual Theremin with controls connected to mouse position: up and down for
amplitude, left and right for pitch.
In the first vibrato, the control wave generates frequencies. The problem with this method
is that the width of a vibrato should be wider with higher pitches. A range of +/-5 worked for
440, but as we've noted previously, we perceive pitch logarithmically, not linearly. Given a pitch
of 1000 a width of +/-100 will sound more correct. For that reason, the control oscillator has an
offset (add) of 1 and scale (mul) of 0.02. This means it moves 0.02 above and below 1. The
frequency is multiplied by that value, so if you hold the mouse at 800 Hz, the vibrato will move
above and below 800 by 2% (16 Hz), but if you are at 3000, it will deviate by 60 Hz.
16.11:: Theremin
(
{
var vibrato;
vibrato = SinOsc.kr(6, mul: 0.02, add: 1);
SinOsc.ar(
freq: MouseX.kr(200, 3200, 1, 0.5) *
vibrato, //Vibrato
mul: MouseY.kr(1, 0.02) //Amplitude; top is louder
)
}.play
)

::





155
Exercises
16:1 Fill in the following charts. The first presents an offset and scale. You provide the
bipolar and unipolar results. The second offers a common control and a range that
would work for that control, you supply the mul (scale) and add (offset).

Offset Scale Bipolar range Unipolar range
500 100 400 to 600 500 to 600
800 1000
1 0.5
0 0.01
1000 1000
10 20

Control type Typical range Bipolar offset/scale Unipolar offset/scale
MIDI 48 to 72 mul: 12, add: 60 mul: 24, add: 48
Amplitude 0.1 to 0.9
Frequency 100 to 900
Harmonics 2 to 12
Phase 0 to 6.28
Duration 1 to 6
16:2 Do not, repeat, do not even think of changing the Theremin patch vibrato to speeds
higher than 20 and widths between 0.1 and 0.9. Are you mad?
16:3 In the Theremin patch, add keywords to all arguments. Then swap out the control
SinOsc with LFTri, LFSaw, LFPulse, LFNoise0, and LFNoise1.
16:4 Modify the Blip patch by replacing the TRand UGens with properly scaled and
offset SinOsc, LFTri, LFSaw, LFPulse, LFNoise0, or LFNoise1.





156
17. Sources of Control
Impart their shape to the sound; smooth or chaotic.
Periodic Waves
repeat. Aperiodic waves do not (this is technically untrue). Both types of waves are
useful as controls. Figure 17.1 shows graphs of sine, saw, triangle, pulse, interpolated random
and step random waves. The first block of code in example 17.1 produces this plot. The second
block of lines applies each wave shape as a frequency control in a SinOsc. It uses a GUI (covered
in chapter 18). Press start to begin the patch, then select (with the slider or the number box) the
control. Sine wave is 1, saw is 2, triangle 3, pulse 4, interpolated noise 5, and step noise 6.


Fig. 17-1 Wave shapes
17.1:: Wave Shapes

// Periodic waves
{[SinOsc.ar, LFSaw.ar, LFTri.ar, LFPulse.ar, LFNoise1.ar(3000), LFNoise0.ar(3000)]}.plot;

// Each shape above used to control frequency. MouseY chooses different controls

(
SynthDef("Waves", { |con=0|
Out.ar(16 - con, [SinOsc.ar(2), LFSaw.ar(2), LFTri.ar(2), LFPulse.ar(2),
LFNoise1.ar(8), LFNoise0.ar(8)] * 100 + 500);
Out.ar([0, 1], SinOsc.ar(In.ar(16, 1))*0.8);
}
).add;

ControlSpec.specs[\con] = ControlSpec(0, 5, \lin, 1, 0, "Control");
SynthDescLib.global[\Waves].makeWindow




157
)
::
VCA
UGens intended for amplitude control have a range of 0 to 1, therefore do not need to be
scaled or offset. Bipolar UGens must be scaled by 0.5 then offset by 0.5. Alternately, a bipolar
control can be run through a max function with 0 as the first argument. This sets the floor at 0.
Anytime the control moves to negative values they are replaced by the maximum 0. This creates
longer periods of 0 volume. This control source can then be applied to the mul of a SinOsc.
17.2:: VCA
{LFNoise1.kr}.plot(0.1);

{max(0, LFNoise1.kr)}.plot(0.1, minval: -1, maxval: 1);

{SinOsc.ar(1000, mul: max(0, LFNoise1.kr(5)))}.play;
::
As before, we now layer another control inside the LFNoise to modify it's amplitude also;
a Line.kr. The first line in 17.3 plots the control, the next plays with a duration of 10 seconds.
This single sound, on it's own, is not very appealing. But adding a bunch of them together in
example 17.4 using a Mix.ar with random frequencies is, and illustrates how a simple idea can
become complex very fast.
17.3:: VCA With LFNoise and Line

{max(0, LFNoise1.kr(mul: Line.kr(0.9, 0, 0.1)))}.plot(0.1, minval: -1, maxval: 1)

{SinOsc.ar(1000, mul: max(0, LFNoise1.kr(5, Line.kr(0.9, 0, 10))))}.play

::
The next example uses the single LFNoise1, offset and scaled properly to control both the
amplitude and the frequency of the SinOsc. It also places the function inside a Mix.fill. The first
argument is the number of items to mix, the second is the function that generates each instance to
be mixed. Since it is a function, the random elements will be executed for each instance,
therefore different for each instance. (Place a .postln after the rrand(100, 800) to confirm this.)
This means the control will have a range of 100 with the value supplied by rrand as the center, a
value between 100 and 800. Also, each instance will have an independent LFNoise1. Try
changing the speed of the LFNoise1 (1/3), the duration of line (30), and swap LFNoise0.
17.4:: VCO, VCA With LFNoise And Line
(
{
Mix.fill(30,
{ var control;
control = LFNoise1.kr(freq: 1/3, mul: Line.kr(1.0, 0, 30));



158
Pan2.ar(SinOsc.ar(control * 100 + rrand(100, 800), 0,
max(0, control/30)), 1.0.rand2)})
}.play
)

::
Aperiodic Triggers, Complex Envelopes
Periodic and aperiodic sources are constantly in motion. Triggered controls such as
KRand and envelopes supply values only when triggered. The trigger can be periodic or
aperiodic. The first few patches used the periodic trigger Impulse.kr. Dust.kr is an aperiodic
trigger. Though not their intended application, you can play both of these triggers. You will hear
a tick at each trigger. Note the stereo expansion.
17.5:: Aperiodic Triggers
{Impulse.ar([3, 2])}.play

{Dust.ar([5, 6])}.play

::
The Line UGen in the previous patch is a type of envelope. Envelopes are a single event
(as opposed to periodically repeating events) that change over time. They are periodic only if
triggered periodically.
! Common envelopes have attack, decay, sustain, and release sections (ADSR). Simpler
envelopes may include only AR, or attack and release. Below is a graph showing an envelope
with an attack and decay. Below are graphs of common envelopes. You can also specify the type
of curve between each breakpoint; linear, exponential, welch, sine, etc. In SC, envelopes provide
an additional argument: done action, or what to do when the envelope closes. The default action
is to stop playing that UGen, which frees up processing. Without this feature the events in a
composition would add up and eventually choke the CPU.


Fig. 17-2 AR, ASR, ADSR, Aussie Opera
! Fixed duration envelopes are always the same duration, typically the attack and release
combined. The duration of a sustain envelope will change depending on the length of a gate, e.g.
how long a key is held down. Percussion instruments such as cymbals, marimba, chimes, etc.,
have fixed duration envelopes. Once they are set in motion you can't control the decay. Organs,
voice, violins, brass, etc., have sustaining envelopes. The sustain time is provided by some type
of gate, for example holding down a key. Each note on an organ will sound until the key is
released. At that point the pitch dies away. Complex envelopes look like Aussie opera houses.




159
While amplitude is an obvious application of envelopes, most instruments also change
timbre over the duration of a note. The patch below uses a PMOsc (phase modulation oscillator,
covered later) as a VCO, VCA, and VCF. The first argument is pitch (the carrier), the second is
the modulator, which effects the character or shape of the wave, the third argument is the
pmindex which effects the number of harmonics (or sidebands), the mul argument is amplitude.
A trigger is defined, which is used in the Linen envelope. The trigger is also used to generate
new pitches (MIDI values) which are converted to cycles per second, and also for a random
choice of mod.
The key is how the envelope is used. It is placed, unmodified, in the mul, argument,
which accounts for amplitude. But it is also used as the third argumentindexwhich
determines the number of harmonics. A higher number is brighter, lower dull. It requires values
well above 1, which is the default output of the unipolar Linen. To achieve correct values it is
scaled by 6. An array is used for the first argument for TIRand, which makes the patch stereo.
17.6:: VCA and VCF Envelope
(
{ var envelope, rate = 1, pitch, trigger, mod;
trigger = Impulse.kr(rate);
envelope = Linen.kr(trigger, 0, 1, 1/rate);
pitch = TIRand.kr([48, 48], 72, trigger).midicps;
mod = TChoose.kr(trigger, [3/2, 4/3, 5/4, 6/5, 7/6]);
PMOsc.ar(pitch, pitch*mod, envelope * 6, mul: envelope) * 0.5
}.play
)

::
The rate is 1 so that you can focus on the decay in both the volume and the timbre. Once
you've listened closely to the character, feel free to change it to higher rates; 10 to 15. Note also
that rate is given a value in the same line where it is declared.
Below is a sonogram of the results. Color is amplitude, showing how the sound dies away
with the envelope, but also since the envelope is applied to both amplitude and timbre (pmindex)
notice that the harmonics are tapered smoothly as the amplitude dies away.



160

Dseq
illustrates another common, classic, control source; the sequencer, which runs through
an array of values when called by Demand.kr. Dseq takes two arguments; the sequence, in the
form of an array, and the number of repetitions before it stops.
17.7:: Dseq
(
{
var rate = 7, trigger, duration;
trigger = Impulse.kr(rate);
duration = 1/rate;
SinOsc.ar(
Demand.kr(Impulse.kr(rate), 0,
Dseq([60, 62, 64, 65, 67, 69, 71].midicps, 5)))*
Linen.kr(Impulse.kr(rate), 0, duration * 0.3, duration * 0.5)
}.play
)

// Used to control timbre

(
{
var rate = 7, trigger, duration;
trigger = Impulse.kr(rate);
duration = 1/rate;
Blip.ar(600,
Demand.kr(Impulse.kr(rate), 0,
Dseq([1, 4, 2, 7, 9, 20, 1, 4, 2, 6, 1].midicps, 5)))*
Linen.kr(Impulse.kr(rate), 0, duration * 0.3, duration * 0.5)
}.play




161
)

::
These control sources can be nesteda sequence of sequencesfor greater variety:
Demand.kr(trigger, [Dseq(etc.), Dseq(etc), Dseq(etc], inf). As a generative composer, I'm rarely
invested in a specific series. I prefer to be surprised by the outcome. The generative process
embraces all the possibilities within a range of instructions as equally valid. This does not mean
completely random choices, but rather choices within a range of appropriate values for the
desired effect. As an example, random frequencies would not be heard as pitch or any scale. For
that reason the choice for pitch might be limited to MIDI values, or even a major scale using
MIDI values. Sequences require arrays. A quick and easy way to fill an array with values is
Array.fill
The two arguments are size of the array and a function for generating values.
Functions are enclosed in braces. The function runs its enclosing code from scratch each
time it is called. Note the difference between the first two lines in example 17.8. The dup
message duplicates its object. The first chooses a random number and that object is duplicated.
The second duplicates the function of choosing a random number, and each function returns a
different random value. The second becomes [10.rand, 10.rand, 10.rand, 10.rand, 10.rand, etc.].
Array.series is also useful. The arguments are size, start, and step. This is useful for creating a
harmonic series. The final example fills an array with a pentatonic scale, the last scrambles a
pentatonic scale (to avoid repeated notes, if that's the desired effect). In the actual code, an
octave would be chosen then added to the MIDI note: 60 + 4, 48 + 7, etc.
17.8:: Filling Arrays
10.rand.dup(10) // No function, duplicates a single random choice.

{10.rand}.dup(10); // Function repeats, 10 random numbers, not ten of a random number

Array.fill(10, 10.rand) // no function, a single random number repeated

Array.fill(10, {10.rand}) // the function repeats, so random numbers

Array.series(10, 1, 1)

Array.series(10, 1, 1) * 440 // returns harmonic series

Array.fill(30, {[0, 2, 4, 7, 9].choose}) // 30 items from a pentatonic scale (any octave)

[0, 2, 4, 7, 9].scramble; // scramble a series

::
This is why all of our patches were enclosed in a function. A SinOsc on its own would
just generate a single value; the first value of a sine wave. But placing it in a function allows it to
repeat the process of generating values in the shape of a sine wave.



162
The {function}.dup(n) seems more efficient, but the Array.fill includes a useful feature. It
passes a value to the function as it runs. These
Function Arguments
can be used inside the function as it repeats. A real life example might be instructions
for someone to repeat an action, say, cut up ten apples. If you wanted them all cut the same way,
you could use a single sentence: "cut all apples in half." But what if you wanted each one cut
differently; leave the first one whole, cut the second one in half, the third in threes, the fourth in
fourths, and so on. Rather than list explicit instructions for each apple, you could just include in
the instructions to count the number of repetitions and cut each apple into that many pieces. In
order to do this, the system has to keep count so as to know which iteration it is on.
Array.fill has a built in counter, passed to the function as an argument. It can have any
name, but must be declared as an argument. The first example simply fills the array with the
count of each repetition; not very useful. But the counter can be used, like Array.series, to
generate harmonics.
Example 17.9 illustrates filling an array using the count argument.
17.9:: Array.fill counter
Array.fill(20, {arg count; count}) // fill the array with the count argument

Array.fill(20, {arg count; count+1*440}) // Use count to generate a harmonic series

Array.fill(20, {12.rand}) // 20 random MIDI pitches, 0 through 12

Array.fill(20, {48.rand + 36}) // 20 random pitches spread out over 4 octaves

// This line first picks a value from the first array, then adds it to the second
// The first is a pentatonic scale, the second octave Cs. This preserves the
// pentatonic scale.

Array.fill(20, {[0, 2, 4, 7, 9].choose + [36, 48, 60, 72].choose})

// An array of Dseq's each filled using Array.fill.

Array.fill(6, {Dseq(Array.fill(10, {[60, 62, 64, 67, 69].choose}), 5)})

::
The last line fills an array with Dseq UGens. Each of the Dseq's is in turn filled with an
array of 10 values, chosen from a pentatonic scale, with a repeat value of 5. You could change
this single 5 to another random choice, say rrand(2, 6). This can now be placed in the Demand
UGen, which is placed in the previous patch. It is now generative. As I said previously, I'm
satisfied with any of the resulting variations. Why impose one particular sequence over another?
If you love your music, set it free.




163
17.10:: Complex Demand Sequence

(
{ var envelope, rate = 9, pitch, trigger, mod, seq, oct;
trigger = Impulse.kr(rate);
envelope = Linen.kr(trigger, 0, 1, 1/rate);
seq = Array.fill(10, {Dseq(Array.fill(12, {[0, 2, 4, 7, 9].choose}), rrand(2, 6))});
oct = Array.fill(10, {Dseq(Array.fill(12, {[60, 72].choose}), rrand(2, 6))});
pitch = Demand.kr(trigger, 0, Dseq(seq, inf) + Dseq(oct, inf)).midicps;
mod = TChoose.kr(trigger, [3/2, 4/3, 5/4, 6/5, 7/6]);
PMOsc.ar([pitch, pitch*2], pitch*mod, envelope * 6, mul: envelope) * 0.3
}.play
)
::
VCO, VCF, VCA in Logic Instruments
! Most Logic instruments are laid out in a VCO, VCF, VCA model. The skin is even
designed to look as though the oscillator section on the left flows into the filter in the middle,
then out again into the amplifier to the right. Figure 17.3 shows the ES2 broken down into VCO,
VCF, then VCA. Following that are images of the ES1, ES2, EVOC, and EXS24, which all have
a similar layout. Launch Logic, select the ES1 or ES2 as an instrument and scroll through the
presets using the caps lock keyboard to play back (press the [caps lock] key) and the Next Plug-
in Setting shortcut (either [ ] ] or !-down arrow) to choose a new instrument. When you find
something interesting, explore each component. Use the left section (VCO) to choose a different
wave form to confirm how the shape is linked to timbre. Adjust the resonance and cutoff to
explore the filter in the middle section (VCF). The right controls effect volume.
Fig. 17-3 Logic Voltage Control Instruments





164

Control Sources in logic
! The control sources are at the bottom of each of these
instruments. The ES1 has an ADSR, Mod Envelope, and an LFO
(low frequency oscillator). The ADSR is patched to the VCA.
Adjust it to shape the attack, decay, sustain level, and release of
the amplitude. The Mod envelope is patchable, and changes
whatever is selected in the router just to the left. The amount of
control is set with the split slider. The bottom sets the control at
low keyboard velocity, the top at high velocity. (The effect is
passed through the velocity control.) For our experiments keep them the same. Try controlling
pitch first, since it is easy to hear. The image to the right shows the LFO set with a 2-second
attack for pitch. When using it to control cutoff or resonance, be sure to adjust the cutoff and the
resonance in the filter itself so that the envelope has room to work. If the cutoff is set too high
the envelope will have little effect.
! The Low Frequency Oscillator has a similar layout.
Choose the shape of the control with the wave selector, the
amount of control with the split slider, and the destination in
the router. Again, try pitch first. This image shows an
aperiodic step wave controlling pitch at a rate of 8.01 Hz.
The SC equivalent would be ({SinOsc.ar(LFNoise0.kr(8.01)
* 600 + 1000)}.play). The left side of the rate dial syncs the
rate to the current tempo; a very useful feature. Try controlling
resonance and cutoff.
! The EXS24 and ES2 have a more sophisticated router. Each has a
source, via, and destination. Click on the Src to choose a source, via to
set an intermediate control, and Dest to choose a destination. Use the
split slider to set the amount of change. The center of this slider is 0
change. The top part of the slider is positive values, the bottom are
negative (which typically inverts the wave). This image shows LFO1
controlling pitch, by way of Ctrl #1. Ctrl #1 is a controller on a
synthesizer. It will change with each studio setup. If the split
sliders are at different points, Ctrl #1 will change the amplitude of
the LFO1 that is applied to the pitch. If they are together, the Ctrl
will have no effect, and the full value of the LFO will be sent to
pitch. Once a control is assigned, use the LFO1 and LFO2
(bottom image) to choose a wave and rate.




165
The EXS24 control sources can be used to modify the Concrte samples loaded into an
instrument (see previous chapter).
Synchronized Controls
Events have, as discussed earlier, both frequency and duration. (I've covered this several
times, but we are about to apply it, so a quick review is in order.) They are often linked, so it is
useful to know how to express both as a ratio. In the case of frequency the number of events is
the numerator and the time (usually in seconds) is the denominator. For example, 40 Hz is 40
events in 1 second, or 40/1. A frequency of 1 Hz is 1/1. Frequencies lower than 1 Hz can be
expressed as a ratio or decimal. 1/10 and 0.1 are both a frequency of 1 event in 10 seconds. The
ratio seems clearer to me. In short: events/seconds.
Duration can also be expressed as a ratio. An event that lasts 5 seconds can be expressed
as 5/1 (five seconds for one event). Events less than a second long can also be fractional or
decimal: 5/1 is 5 seconds for one event, 1/2 is one second for two events, each event lasting !
second (0.5). Since SC understands both decimal and fractional notation it may seem easier to
always use fractional notation and let SC do the math.
Using fractions facilitates synchronization of LFO controls. In example 17.11 the LFO
SinOsc UGens have frequencies of 1 in 5, 2 in 5, 3 in 5, so that they will all come into sync every
5 seconds. Uncomment the first three lines to add more sines. The second example is similar,
with triggers that are synched every 5 seconds. This is a nice illustration of harmonic structure.
When the individual bells sound at once, we hear them blend into a single bright tone. This
example also illustrates how a composer can exploit the unique capabilities of a computer. This
kind of precision is extremely difficult in analog systems.
Both of these patches repeat the SinOsc line for clarity. It would be more efficient to use
an Array.fill. See if you can make the change on your own.
17.11:: Synched LFO
(
{
var scale = 600, offset = 1000;
Mix.ar([
Pan2.ar(SinOsc.ar(SinOsc.ar(6/5, mul: scale, add: offset), mul: 0.1), -1),
Pan2.ar(SinOsc.ar(SinOsc.ar(5/5, mul: scale, add: offset), mul: 0.1), -0.5),
Pan2.ar(SinOsc.ar(SinOsc.ar(4/5, mul: scale, add: offset), mul: 0.1), -0.2),
Pan2.ar(SinOsc.ar(SinOsc.ar(3/5, mul: scale, add: offset), mul: 0.1), 0.2),
Pan2.ar(SinOsc.ar(SinOsc.ar(2/5, mul: scale, add: offset), mul: 0.1), 0.5),
Pan2.ar(SinOsc.ar(SinOsc.ar(1/5, mul: scale, add: offset), mul: 0.1), 1),
])
}.play
)

( // synchronized triggers
{
Mix.ar([
Pan2.ar(SinOsc.ar(100, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(1/5))), -1),
Pan2.ar(SinOsc.ar(300, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(2/5))), -0.66),



166
Pan2.ar(SinOsc.ar(500, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(3/5))), -0.33),
Pan2.ar(SinOsc.ar(700, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(4/5))), 0),
Pan2.ar(SinOsc.ar(900, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(5/5))), 0.33),
Pan2.ar(SinOsc.ar(1100, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(6/5))), 0.66),
Pan2.ar(SinOsc.ar(1300, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(7/5))), 1)]) * 0.1
}.play
)

::
Figure 17.3 shows graphs of the synchronized elements of each patch.



Fig. 17-4 Synchronous LFOs

Mix.fill combines Mix and Array.fill. Examples below.
17.12:: Mix.fill

(
//frequency linked to envelope length
//high notes short, low long
// uncomment lines for alternatives
{
var frequency, trigger;
Mix.fill(40, //number of items
{arg count;
frequency = exprand(40, 5000); // expon. frequency choice for each




167
// frequency = count + 1 * 30; // harmonic series
// frequency = exprand(count+1*40, count+2*40); // enharmonic, but evenly dispersed
trigger = Dust.kr(0.05);
// trigger = Impulse.kr(count + 1 / 20);
// trigger = Impulse.kr(count + 1 / 10);
// trigger = Impulse.kr(rrand(1, 40)/20);
Pan2.ar( // pan position
SinOsc.ar( // sine osc
frequency, // freq for this sine osc
mul: EnvGen.kr( // envelope (VCA)
// the frequency is used to determine duration of envelope
Env.perc(0.001, 500/frequency),
trigger, // aperiodic trigger
0.6 // overall volume
/ (count + 1) // amp of this harmonic
)
),
rrand(-1.0, 1.0) // pan position
)
}
)
}.play
) // this one spawns involuntary maniacal laughter


( // blends from random to ordered
{
Mix.fill(40, //number of items
{arg count;
Pan2.ar( // pan position
SinOsc.ar( // sine osc
exprand(40, 1000), // freq for this sine osc
mul: EnvGen.kr( // envelope (VCA)
// the frequency is used to determine duration of envelope
Env.perc(0.001, rrand(0.2, 3)),
Dust.kr(0.5) * Line.kr(1, -1, rrand(20, 40));,
0.6 // overall volume
/ (count + 1) // amp of this harmonic
)
),
rrand(-1.0, 1.0) // pan position
) +
Pan2.ar( // pan position
SinOsc.ar( // sine osc
count + 1 * 100, // freq for this sine osc
mul: EnvGen.kr( // envelope (VCA)
// the frequency is used to determine duration of envelope
Env.perc(0.001, rrand(0.2, 3)),
Dust.kr(0.5) * Line.kr(-1, 1, rrand(10, 40)),
0.6 // overall volume
/ (count + 1) // amp of this harmonic



168
)
),
rrand(-1.0, 1.0) // pan position
)

}
)
}.play
)


(//reversed envelope
{var frequency;
Mix.ar({
frequency = rrand(100, 3000);
Pan2.ar(SinOsc.ar(frequency,
mul: EnvGen.kr(Env.perc(200/frequency, 0.0001),
Dust.kr(0.05), 0.2)), rrand(-1.0, 1.0)) }.dup(100))}.play
)

(//
{var frequency;
Mix.ar({
frequency = rrand(100, 1000);
Pan2.ar(SinOsc.ar(frequency,
mul: EnvGen.kr(Env.perc(frequency/500, 0001),
Dust.kr(0.05), 0.05)), rrand(-1.0, 1.0)) }.dup(100))}.play
)

::




169
Exercises
17:1 Browse and find an interesting patch in the ES1, ES2, or EXS24. Adjust the
waveforms or filters. Once you discover an interesting variation, use the patch bay
to attach a voltage control to the parameter.
17:2 Import Concrte samples into the EXS24. Attach controls for pitch.
17:3 Begin with your favorite SC patch from this section. Document as much as you can
using comments. Try to identify control sources and destinations. Look up the help
files and place keywords in front of all parameters. Then swap out the control
sources. For example, change the LFSaw to SinOsc, LFPulse, LFNoise1 or
LFNoise0. Each time you hit on an interesting variation, chose "save as" and save
the patch for future use.
17:4 Listen to each patch in the 17.11 and 17.12. Draw what you think the sonogram
might look like. Open the preferences and set the output to Soundflower16. In
Amadeus open a real-time sonogram. Compare your diagram with the actual
sonogram.




170
18. SynthDef and GUIs
An interface for humans. Perhaps not worth it?
SynthDef
Until now we have been doodling on scratch paper, so to speakcrumpling up each
patch and tossing it in the trash when we're done. Each time we send an audio patch to the server,
it creates a virtual synth based on our specifications and plays it until !-. is pressed. The post
window displays the ad hoc synth definitions with temporary names and node numbers such as
Synth("temp__23" : 1000).
Using a SynthDef creates a synth, like a preset in Logic Pro, and saves it with a specific
name. They take a little more code, but they have several advantages: 1) They are saved to the
hard drive and can be recalled even after restarting the computer. 2) They can be called and
controlled independently. So far, we've been stopping each example with command period,
which halts all processes. 3) The definition can include arguments that can be changed after the
synth is running. Finally, (4) since parameters can be changed after the fact, GUI interfaces can
be used to add greater control during live performance.
The first two arguments for the SynthDef are name and the UGen function. The UGen
function is what was attached to the .play message in previous examples with one new wrinkle.
In our ad hoc examples the output was automatically set to 0. In definitions the patch must be
enclosed, sooner or later, in an Out.ar UGen. SynthDef understands the play and add message.
Both are temporary definitions. They will not persist after restart.
18.1:: SynthDef
// ad hoc synth
{SinOsc.ar(400, mul: SinOsc.kr(5, mul: 0.3, add: 0.5))}.play;

// saved as a "preset"
SynthDef("testtone", {Out.ar([0, 1], SinOsc.ar(400, mul: SinOsc.ar(5, mul: 0.3, add: 0.5)))}).add;

// Play the synth, and assign it to the variable 'a'
a = Synth("testtone")

// This time don't use !-period to stop it. Use the following line.

a.run(false);

(
b = SynthDef("computer",
{Out.ar(0, Mix.ar(
Array.fill(5, {SinOsc.ar(SinOsc.ar(1/10, rrand(0, 6.0), 200, 500))}))*0.03)}).play
)

(
c = SynthDef("string",




171
{Out.ar(1, RLPF.ar(Dust.ar(12), LFNoise1.ar(1/3, 1500, 1600), 0.01))}).play
)

a.run(true);
b.free;
c.free;
a.free;
::
SynthDef arguments
allow you to change, as we did with examples in chapter 14, parameters after a synth
is running. They are similar to those we've been using, for example, with SinOsc and LFNoise0.
To illustrate the internal workings (and the declaration of arguments) in the SinOsc Ugen, the
source code can be examined by pressing !I. SinOsc is in the Osc.sc file, and shows:
SinOsc : PureUGen {
*ar {
arg freq=440.0, phase=0.0, mul=1.0, add=0.0;
^this.multiNew('audio', freq, phase).madd(mul, add)
}
In this core code file the SinOsc Ugen is defined with arguments that are similar to
variables. They are declared and given default values with arg freq=440.0, phase=0.0, etc. The
same can be done with synth definitions. The key difference is, and the value is, variables can't
be changed once a synth is running, arguments can. If a synth definition is a box that makes
sounds, the arguments are the knobs that can be adjusted to change the sound. For the next
examples we use load which defines and also writes the def to a file (in the user library). Use
play or add for temporary experiments, load for synths you want to continue to use.
18.2:: SynthDef arguments
(
SynthDef("RisingSines", // create a synth def
{ arg out=0, kfreq=0.1, scale=200, offset=500;
Out.ar(out, Mix.ar(
Array.fill(5, {
Pan2.ar(SinOsc.ar(SinOsc.ar(kfreq, rrand(0, 6.0), scale, offset)),
LFNoise1.kr(1))}))*0.03)}).load
)

// Run these in sequence
a=Synth("RisingSines"); // start the synth
a.set(\kfreq, 1); // change kfreq
a.set(\kfreq, 0.1); a.set(\scale, 1000); a.set(\offset, 1200); // change a group
a.set(\out, 1); // change output channel

(
SynthDef("GratingString",
{ arg out=1, trig=12, kfreq=0.3, scale=1500, offset=1600;
Out.ar(out, RLPF.ar(Dust.ar(trig),
LFNoise1.ar(kfreq, scale, offset), 0.01))}).load



172
)

b=Synth("GratingString");
b.set(\kfreq, 4);
b.set(\offset, 3000);

a.free;
b.free;

// Start and change several instances of a single synth. Run each line in succession.

a = Synth("RisingSines", [\kfreq, 0.2, \scale, 200, \offset, 400])
b = Synth("RisingSines", [\kfreq, 0.03, \scale, 700, \offset, 1000, \out, 1])
b.set(\out, 0); a.set(\out, 1);
b.set(\kfreq, 4); a.set(\kfreq, 1, \scale, 4000);
a.free; b.free;

::
A SynthDef is not required to create arguments. They can be added to any ad hoc synth
and changed after it is running. The SynthDef just commits it to memory.
18.1:: Ad Hoc Arguments


(
c = { arg out=0, kfreq=0.1, scale=200, offset=500;
Mix.ar(
Array.fill(5, {
Pan2.ar(SinOsc.ar(SinOsc.ar(kfreq, rrand(0, 6.0), scale, offset)),
LFNoise1.kr(1))}))*0.03}.play;
)

c.set(\kfreq, 1);
c.set(\kfreq, 0.1); c.set(\scale, 1000); c.set(\offset, 1200);
c.set(\out, 1);

(
d = { arg out=1, trig=12, kfreq=0.3, scale=1500, offset=1600;
RLPF.ar(Dust.ar(trig),
LFNoise1.ar(kfreq, scale, offset), 0.01)}.play
)

d.set(\kfreq, 4);
d.set(\offset, 3000);

c.free;
d.free;

::




173
Which parameters should be set as arguments? It's up to you. I try to keep them
manageable by skipping those that are integral to the patch, and unlikely to change. In the
"string" patch, for example, 0.01 is the resonance, and probably needs to stay at 0.01.
Even though we can now make changes while the synth is running, typing in each change
by hand is cumbersome. In a live performance it can be used to carefully orchestrate specific
changes, but it does not lend itself to improvisation or exploration. For that, we need a
GUI slider
Following is a very simple example. To link an interface with a synth three things have to
happen. Start the synth and give it a variable. Create the interface and place it in a variable.
Finally, link the action of the interface with the argument you want to control.
The first argument for EZSlider is the parent window. In this case, there is none, so it is
set to nil. The second is the size of the slider; 400 is the width, 24 is the height. The third is the
name of that slider. The forth is a ControlSpec, which sets the minimum, maximum, warp, step
value, default, and units. All GUIs belong to the sclang application. You will have to switch back
and forth for these experiments.
18.2:: Single Slider
(
a = Synth("GratingString");
g = EZSlider(nil, 400@24, " kfreq ", [1/4, 12, \lin, 0.1, 1].asSpec);
g.action_({|ez| a.set(\kfreq, ez.value)});
)
::
A button is a little more involved. It requires an if statement, covered later. This tests to
see what state the button is, 0 or 1, and performs one action if true, the other if not. A button can't
exist on its own, as the slider example above. It needs to be placed in a parent window. This
example assumes the synth definition "string" has already been sent to the server.
18.3:: GUI Button, Parent Window
(
b = Button(Window.new.front, Rect(20, 20, 340, 30))
.states_([["Start"],["Stop"]])
.action_({|view| if (view.value == 1) {a = Synth("GratingString")} {a.free}});
)

// Essentially, this, wrapped in a button, wrapped in a window:
a = Synth("GratingString");
a.free;

::
Next we can place some sliders in the same window by replacing the 'nil' with a GUI
window. The Flowlayout manages each item added to the window and places it in the next
logical location, so the order in which you create each interface item matters. We will be dealing
with two sets of variables/arguments. It's useful to give them similar names, (e.g. scale), so that



174
it's easy to keep things straight, but not exactly the same. The window will have a scale slider
that will be linked to the scale of the "sines" synth. It would probably work to name them both
scale, but if you ever want to replace one or the other, they are no longer unique. For that reason
I've named the GUI variables with a preceding 'g'. So it's easy to see the relationship in this line:
\kfreq, gkfreq.value. But the first kfreq is the argument from the 'sines' synth and the gkfreq is the
value returned from the slider. The names could be completely different, but the similarity makes
for faster coding, and for slicker shortcuts, covered later.
To illustrate how SynthDefs can be reused, the first example builds an interface assuming
the "RisingSines" synth has already been defined. If you're starting from scratch, run 18.2 again.
The second patch repeats the Theremin earlier but with more arguments, more sliders, an
amplitude control, and a control that allows you to select the output bus.
18.4:: Sines and Theremin with Interface

(
// Build the GUI interface
var inst, gbutton;
var gkfreq, gscale, goffset, gWin;


// Create and name a window
gWin=Window.new.front;

// This line ensures each component is added to the window
// in an orderly way.
gWin.view.decorator = FlowLayout(gWin.view.bounds);

gbutton = Button(gWin, 100 @ 24);
gbutton.states = [["Start", Color.black, Color.green(0.7)],
["Stop", Color.white, Color.red(0.7)]];
gbutton.action = {|view|
if (view.value == 1) {inst = Synth( "RisingSines")} {inst.free}};

// This looks complicated, but it's just duplication.
// The specs array is low value, high value, warp, step, and initial value

gkfreq = EZSlider(gWin, 400@20, "KFreq", [0.05, 4, \lin, 0.1, 0.1].asSpec)
.action_({|sl| inst.set(\kfreq, sl.value)});
gscale = EZSlider(gWin, 400@20, "Scale", [10, 1000, \lin, 10, 200].asSpec)
.action_({|sl| inst.set(\scale, sl.value)});
goffset = EZSlider(gWin, 400@20, "Offset", [100, 3000, \exp, 10, 600].asSpec)
.action_({|sl| inst.set(\offset, sl.value)});
)

// The theremin example is more complicated, but again, mostly duplication.

(
SynthDef("Theremin", {




175
arg speed=6, depth=0.02, out=0,
lDelay = 1.123, rDelay = 1.1, amp = 0.5;
var mix;
mix = SinOsc.ar(
freq: MouseX.kr(200, 3200, 1, 0.5) * SinOsc.kr(speed, mul: depth, add: 1),
mul: MouseY.kr(1, 0.02));
mix = mix + CombN.ar(mix, 3.0, [lDelay, lDelay*rDelay], 6);
Out.ar(out, mix * amp)
}).load
)

// After defining the synth, build the interface.

(
var synthNode, gbutton, gmenu;
var gspeed, gdepth, gout, glDelay, grDelay, gamp, gWin;


// Create and name a window
gWin=Window.new.front;
// This line ensures each component is added to the window
// in an orderly way.
gWin.view.decorator = FlowLayout(gWin.view.bounds);

gbutton = Button(gWin, 100 @ 24);
gbutton.states = [["Start", Color.black, Color.green(0.7)],
["Stop", Color.white, Color.red(0.7)]];
gbutton.action = {|view|
if (view.value == 1) {synthNode = Synth( "Theremin",
// These lines set the instrument to the current slider location.
// This preserves settings when stopping and starting.
[\out, gmenu.value * 2,
\speed, gspeed.value,
\depth, gdepth.value,
\lDelay, glDelay.value,
\rDelay, grDelay.value,
\amp, gamp.value
])} {synthNode.free}};
gmenu = EZPopUpMenu(gWin, 150@24, " Output ",
[\1 -> {synthNode.set(\out, 0)}, \3 -> {synthNode.set(\out, 2)},
\5 -> {synthNode.set(\out, 4)}, \7 -> {synthNode.set(\out, 6)}]);
// Here we've added a static text that allows a little longer explanation
// of each slider.
StaticText(gWin, 400@12).string = "Vibrato Speed";
gspeed = EZSlider(gWin, 400@20, "Speed", [0.5, 50, \exp, 0.1, 4].asSpec)
.action_({|sl| synthNode.set(\speed, sl.value)});
StaticText(gWin, 400@12).string = "Vibrato Depth";
gdepth = EZSlider(gWin, 400@20, "Depth", [0.01, 50, \exp, 0.01, 0.02].asSpec)
.action_({|sl| synthNode.set(\depth, sl.value)});
StaticText(gWin, 400@12).string = "Left Delay";
glDelay = EZSlider(gWin, 400@20, "Left D", [0.1, 3, \lin, 0.1, 0.5].asSpec)



176
.action_({|sl| synthNode.set(\lDelay, sl.value)});
StaticText(gWin, 400@12).string = "Right (percentage of left).";
grDelay = EZSlider(gWin, 400@20, "Right %", [1.0, 2.0, \lin, 0.1, 1.001].asSpec)
.action_({|sl| synthNode.set(\rDelay, sl.value)});
StaticText(gWin, 400@12).string = "Volume.";
gamp = EZSlider(gWin, 400@20, "Amp ", [0.1, 1.0, \lin, 0.1, 0.5].asSpec)
.action_({|sl| synthNode.set(\amp, sl.value)});

)

::
The button can be toggled with the space bar when the window is front, and the button is
highlighted (press the tab key to move focus). The sliders respond to a number of key presses
when highlighted: [r] chooses a random value, [c] centers, [n] sets to 0 (nil), [x] to highest value,
[ [ ] and [ ] ] as well as the arrow keys increment and decrement the value.
If these examples look intimidating, notice they are mostly duplication. The next example
is more verbose than previous examples. I'm always too anxious to get to the sounds and use
quick variables such as variables a, b, etc. I typically regret it when a year later I can't figure out
what my own code does. One could argue that more verbose methods don't take that much more
time, they certainly don't use up much more hard drive space, or make any difference in CPU.
Also, using more descriptive variables are better if you ever decide to change a screwball name
such as synthLFNoiseFreq to lf, it's easier to do a search and replace. If you name all your
variables a, b, or c you'd have to replace them by hand. There's always a point in a patch where I
decide I'm committed and take the time to clean up and add better variables and comments.
18.5:: Synth with GUI: 2666
// First define the synth
(
SynthDef("RisingSines", {
arg out=0, sawRate=1.5, sawScale=50, noiseRate=0.5, noiseScale=500,
noiseOffset=600, amp=0.1, delay=1.35, panRate=0.1;
var mix, effect;
mix = SinOsc.ar(
abs(LFSaw.kr(sawRate, mul: sawScale,
add: LFNoise1.kr(noiseRate, noiseScale, noiseOffset))), mul: amp);
mix = Pan2.ar(mix, LFNoise1.kr(panRate));
effect = CombN.ar(mix, 3.0, delay, 6 );
Out.ar(out, mix + effect)
}).load;
)

// Then create the GUI
(
var synthNode, gbutton, gmenu;
var gnoiseRate, gsawRate, gpanRate;
var gnoiseScale, gsawScale, gnoiseOffset;
var gdelay, gamp, gWin;





177

// Create and name a window
gWin=Window.new.front;
// This line ensures each component is added to the window
// in an orderly way.
gWin.view.decorator = FlowLayout(gWin.view.bounds);

gbutton = Button(gWin, 100 @ 24);
gbutton.states = [["Start", Color.black, Color.green(0.7)],
["Stop", Color.white, Color.red(0.7)]];
gbutton.action = {|view|
if (view.value == 1) {synthNode = Synth( "RisingSines",
[\out, gmenu.value * 2,
\noiseRate, gnoiseRate.value,
\sawRate, gsawRate.value,
\panRate, gpanRate.value,
\noiseScale, gnoiseScale.value,
\sawScale, gsawScale.value,
\noiseOffset, gnoiseOffset.value,
\delay, gdelay.value,
\amp, gamp.value
])} {synthNode.free}};
gmenu = EZPopUpMenu(gWin, 150@24, " Output ",
[\1 -> {synthNode.set(\out, 0)}, \3 -> {synthNode.set(\out, 2)},
\5 -> {synthNode.set(\out, 4)}, \7 -> {synthNode.set(\out, 6)}]);
StaticText(gWin, 400@12).string = "Rate that all the saws wander.";
gnoiseRate = EZSlider(gWin, 400@20, "Rate", [0.1, 10, \lin, 0.1, 0.1].asSpec)
.action_({|slider| synthNode.set(\noiseRate, slider.value)});
StaticText(gWin, 400@12).string = "Frequency of each saw.";
gsawRate = EZSlider(gWin, 400@20, "Rate", [0.1, 20, \lin, 0.1, 1].asSpec)
.action_({|slider| synthNode.set(\sawRate, slider.value)});
StaticText(gWin, 400@12).string = "Rate of panning.";
gpanRate = EZSlider(gWin, 400@20, "Rate", [0.1, 20, \lin, 0.1, 2].asSpec)
.action_({|slider| synthNode.set(\noiseScale, slider.value)});
StaticText(gWin, 400@12).string = "Scale of wandering.";
gnoiseScale = EZSlider(gWin, 400@20, "Scale", [50, 1000, \lin, 10, 600].asSpec)
.action_({|slider| synthNode.set(\noiseScale, slider.value)});
StaticText(gWin, 400@12).string = "Scale of each saw.";
gsawScale = EZSlider(gWin, 400@20, "Scale", [50, 1000, \lin, 10, 500].asSpec)
.action_({|slider| synthNode.set(\sawScale, slider.value)});
StaticText(gWin, 400@12).string = "Offset of wandering.";
gnoiseOffset = EZSlider(gWin, 400@20, "Offset", [10, 1000, \lin, 10, 50].asSpec)
.action_({|slider| synthNode.set(\noiseOffset, slider.value)});
StaticText(gWin, 400@12).string = "Delay in seconds.";
gdelay = EZSlider(gWin, 400@20, "Delay ", [0.1, 3.0, \lin, 0.01, 1.23].asSpec)
.action_({|slider| synthNode.set(\delay, slider.value)});
StaticText(gWin, 400@12).string = "Volume.";
gamp = EZSlider(gWin, 400@20, "Amp ", [0.01, 0.2, \lin, 0.01, 0.1].asSpec)
.action_({|slider| synthNode.set(\amp, slider.value)});
)




178
::
What the heck was I thinking? This was such a simple patch to begin with.
My first computer music instructor often observed that 95% of coding is interface.
Telling a computer what to do is fast and simple. Deciding what you want it to do takes months.
Pandering to humans takes years. To illustrate, here is the original (brief) patch. It takes 138
characters; 5% of the 2666 above.
18.6:: No GUI: 138 Characters
(
{
var out, delay;
out = SinOsc.ar(
abs(LFSaw.kr(1.5, mul: 50, add: LFNoise1.kr(0.5, 500, 600))), mul: 0.1);
delay = CombN.ar(out, 3.0, [1.35, 0.7], 6 );
out + delay
}.play
)

::

So I usually find a way around using GUIs. For example, though I could wrap a GUI
around nearly every example in this text, I don't. The code required just for the GUI would
obscure the components of synthesis, which is our focus.
Iteration
can be used to automate code. Wherever there is repetition, there is opportunity for
elegance and refinement. I love elegant solutions, and that is what usually keeps me up late at
night. But for the most part, I'm a sledgehammer programmer.
Previous examples used Array.fill and Mix.fill to automate generating a collection of
sounds or elements. Both have two arguments; the number of iterations, and the function used to
fill the array. In all these examples the results of each repetition were independent of one
another. That is, Array.fill(10, {100.rand}) generates 100 random values and none of them are
related. It is often useful to generate an array of sequential values, or lines of code that are
related. Array.series and Array.geom allow greater control over the contents, but only in terms of
numbers.
Another method of iteration is simply called do. The expression 10.do({"ping".postln})
will post 'ping' 10 times. Both of these functions have a built in counter that increments with
each repetition. This value is transferred to the function by way of an argument, similar to a
variable. The name can be anything. Remember that computers begin counting with 0. I often
write the do in functional notation: do(10, {"ping".postln}). In receiver notation the first
argument is moved ahead of the message and dot. In functional notation the object is placed as
the first argument. The two versions are precisely the same, and this can be done with any Object
message pair: 100.rand, rand(100), Array.fill(10, {10.rand}), fill(Array, 10, {10.rand}). Which
do you use? It's a matter of style and context.




179
18.7:: Array, Do, Counters
Array.fill(10, {arg myName; myName}); // fill the array with the counter

Array.fill(10, {arg anotherName; anotherName*100});

// Since the counter starts at 0, you often have to add 1, for
// example with harmonics. Remember precedence is
// left to right: harm + 1, then * 100. Try harm * 100 + 1

Array.fill(10, {arg harm; harm + 1 * 100});

50.do({arg anyNameButAlwaysCounter; "Count: ".post; anyNameButAlwaysCounter.postln})

do(50, {arg count; count.postln}) // This sounds more like English: "do 50."

::
! In addition to numbers, you can do an array of items. In this case two arguments are sent
to the function. The first is each item in the array being "done" (used in some sort of function).
The second is a counter. Again, they can have any name, but they will always be each item in the
array and a counter in that order. Note that the array can be a collection of unrelated data types.
There is a shortcut for naming the arguments: |one, two|. Those are pipes.
18.8:: Array Iteration
["One", 2, {10.rand}, [1, 2]].do({ | arrayItem, count | count.post; " is ".post; arrayItem.postln})

[0, 1, 2, 3, 4, 5, 6].do({ | item, count | [item, count].post; " is redundant".postln;})

[0, 1, 2, 3, 4, 5, 6].do({ | item, count | [item + 1 * 500, count].post; " is not redundant".postln;})

// Swapping the names does not swap the meaning. The first argument
// will always be each item, the second a counter.

["this", "that", "other", "item"].do({ | count, item | [count, item].post; " still item, count".postln;})

// This generates merged lines of code.
["SinOsc", "LFSaw", "LFNoise1"].do({arg each; ("{" ++ each ++ ".ar}.plot").postln})

// This generates merged lines and executes them.
["SinOsc", "LFSaw", "LFNoise1"].do({arg each; ("{" ++ each ++ ".ar}.plot").interpret})

::
The counter is useful for generating harmonics, but the array can also contain text or
values that differ in the repetitious section of the code; a type of document merge. Multiple
sliders are a perfect example. So much of each is repeated that it can be encapsulated in an
iteration. The more uniformity we can create the better, so here are two additional shortcuts.
First, synth arguments can be set by index number. The second argument of the synth
"RisingSines" was sawRate. This value can be set with a.set(\sawRate, 4) or a.set(1, 4). The



180
second work around is naming each slider by number then putting a text message at the bottom
explaining what each slider does after the iteration.
18.9:: Sliders Using Do()
(
// Create the parent window
var gWin;
gWin=Window.new.front;
gWin.view.decorator = FlowLayout(gWin.view.bounds);

// Create duplicate sliders.
10.do({arg each, count;
EZSlider(gWin, 350@20, count+1,
[0, 10, \lin, 1, 0].asSpec).action_({|slider| slider.value.postln});
});
StaticText(gWin, 350@24).string =
"Slider 1 = offset, 2 = scale, 3 = rate, 4 = amp";
)

::
It's a trade off. This code is more concise, but the resulting dialog is less refined. Choose
your battles. I prefer a simpler interface and cleaner code.
There are several parameters of the slider that are worth adjusting in each. The specs
array; low and high value, warp, step value, and initial value should be different for each. If you
left them all 0 to 10, then you would have to write the synth with offsets and scales to change the
0-10 range to, e.g., 1000 and 3000. That seems like a reasonable strategy. But then you wouldn't
see the values in the number boxes, which I think is useful.
Synth Browser
offers a slicker method. We've used add, play and load when defining a synth. I like
play because I'm constantly experimenting and it gives immediate feedback. But for the trick
below, you have to use add, or load. Turns out, they can be chained, but add or load must come
first. Here is the Theremin patch with load and play. Since we've already defined the Theremin,
the file will be overwritten. Once defined, you can browse this and all the synths that have been
added using SynthDescLib.read.global.browse. (The read messages loads the saved files. See
below for a way to automate this at startup.)
18.10:: SynthDef.load.play
(
SynthDef("Theremin", {
arg out=0, speed=6, depth=0.02,
lDelay = 1.123, rDelay = 1.1, amp = 0.5;
var mix;
mix = SinOsc.ar(
freq: MouseX.kr(200, 3200, 1, 0.5) * SinOsc.kr(speed, mul: depth, add: 1),
mul: MouseY.kr(1, 0.02));




181
mix = mix + CombN.ar(mix, 3.0, [lDelay, lDelay*rDelay], 6);
Out.ar(out, mix * amp)
}).load.play
)

SynthDescLib.read.global.browse
::
At the top of the window is a test and window button. Test starts the synth. Window
brings up a simple GUI with an interface for each argument. Select both default and Theremin
and press the window button. These interfaces are very similar to those in the previous
examples. Notice the sliders for the default instrument (freq, amp, pan) have specs appropriate
for each value. The Theremin window only offers a logical specs for the amp slider. The other
values just have number boxes. Furthermore, if you try using the up and down arrows, you get
values far out of the appropriate range. How does SC know to format the specs of a slider for
freq, amp, and pan, but not speed, depth, and delays?

Fig. 18-1 Synth Browser Windows
The answer is in the default control specifications. Out of the box, SC comes with the
control specs listed below. It is an identity dictionary (pairing of a symbol with a set of values).
When a GUI window is created, if any of the arguments in the synthdef match the default control
specs, it uses those specs. Note that freq is 20 to 20000 with 440 as a default starting point, as
seen in the default window.
\symbol = [minval, maxval, curve, stepval, start, units]
\amp = [0, 1, 'amp', 0, 0, ""]
\audiobus = [0, 127, 'linear', 1, 0, ""]
\beats = [0, 20, 'linear', 0.0, 0, " Hz"]
\bipolar = [-1, 1, 'linear', 0.0, 0, ""]
\boostcut = [-20, 20, 'linear', 0.0, 0, " dB"]
\controlbus = [0, 4095, 'linear', 1, 0, ""]
\db = [-inf, 0.0, 'db', 0.0, -inf, " dB"]
\delay = [0.0001, 1, 'exp', 0, 0.3, " secs"]
\detune = [-20, 20, 'linear', 0.0, 0, " Hz"]
\freq = [20, 20000, 'exp', 0, 440, " Hz"]
\lofreq = [0.1, 100, 'exp', 0, 6, " Hz"]
\midfreq = [25, 4200, 'exp', 0, 440, " Hz"]
\midi = [0, 127, 'linear', 0.0, 64, ""]
\midinote = [0, 127, 'linear', 0.0, 60, ""]
\midivelocity = [1, 127, 'linear', 0.0, 64, ""]
\pan = [-1, 1, 'linear', 0.0, 0, ""]
\phase = [0, 6.2831853071796, 'linear', 0.0, 0, ""]
\rate = [0.125, 8, 'exp', 0, 1, ""]



182
\rq = [0.001, 2, 'exp', 0, 0.707, ""]
\unipolar = [0, 1, 'linear', 0.0, 0, ""]
\widefreq = [0.1, 20000, 'exp', 0, 440, " Hz"]
We got lucky with the amp argument in Theremin. Choosing the name amp, which is in
the defaults, allows SC to pair it with the specs above. If we change the name of the argument
speed to rate, it will have a nice slider too. Using the defaults is less flexible. A synth may
require four rates, and the default rate can be used this way only once. Also, the defaults for
minimum, maximum, step, and default may not correspond with how the patch works.
One solution is to define your own. Once a spec is defined you can and should reuse it in
future synth definitions. Example 18.11 adds control specs for all the patches in this text. The
arguments are minval, maxval, warp, step, default, and units (used by some GUIs as a label). If
units is blank, the GUI will use the symbol.
The last line launches a window for the Theremin synth without having to use the
browser window button. Now that speed, depth, lDelay, and rDelay have been added as control
specs, they will have sliders for more accurate adjustments. You can run it several times to create
several synths, each controlled by its own window. (See also Instr, and Patch from the Crucial
library.)
18.11:: Add Control Specs
(
ControlSpec.specs.addAll(
[
\out -> ControlSpec(0, 16, \lin, 1, 0, " chan"),
\in -> ControlSpec(0, 16, \lin, 1, 0, " chan"),
\loop -> ControlSpec(0.1, 16, \lin, 0, 1, " chan"),
\speed -> ControlSpec(0.1, 24, \lin, 0.1, 6),
\depth -> ControlSpec(0.001, 1, \lin, 0.02, 1),
\fadd -> ControlSpec(60, 20000, \exp, 1, 440, " offset"),
\send1 -> ControlSpec(0, 1, \lin, 0.01, 0.5),
\send2 -> ControlSpec(0, 1, \lin, 0.01, 0.5),
\send3 -> ControlSpec(0, 1, \lin, 0.01, 0.5),
\fmul -> ControlSpec(1, 2000, \lin, 1, 100, " scale"),
\lDelay -> ControlSpec(0.001, 3.0, \lin, 0.001, 1.123, " ld"),
\rDelay -> ControlSpec(0.001, 3.0, \lin, 0.001, 1.6, " rd"),
\dur -> ControlSpec(0.1, 5.0, \lin, 0.1, 1, " secs"),
\damp -> ControlSpec(-1.0, 1.0, \lin, 0.1, 0.3),
\slider1 -> ControlSpec(0, 1, \lin, 0.01, 0.5),
\slider2 -> ControlSpec(0, 1, \lin, 0.01, 0.5),
\slider3 -> ControlSpec(0, 1, \lin, 0.01, 0.5),
\slider4 -> ControlSpec(0, 1, \lin, 0.01, 0.5),
\lfospeed -> ControlSpec(0.1, 200, \exp, 0.1, 1),
\lfoscale -> ControlSpec(100, 500, \exp, 1, 200),
\pindex -> ControlSpec(1, 50, \lin, 0.1, 2.5),
\fmlfo -> ControlSpec(0.1, 200, \exp, 0.1, 1),
\fmscale -> ControlSpec(100, 2000, \exp, 1, 1500),
\fmoffset -> ControlSpec(2000, 4000, \exp, 10, 3000),
\lfo2speed -> ControlSpec(1/4, 10, \lin, 0.1, 4, " lfo2sp"),




183

]);

// Create a GUI window for this synth
SynthDescLib.global[\Theremin].makeWindow;
)

::
An alternate method is to modify an existing specification. Example 18.12 illustrates a
patch using the default freq argument after its step value, minval, and maxval have been
changed. But if you're going to change that many arguments, might as well define a new spec.
18.12:: Modify Control Spec
(
\freq.asSpec.step = 100;
\freq.asSpec.minval = 1000;
\freq.asSpec.maxval = 2000;
SynthDef("ChangeSpec", {|freq = 1100| Out.ar(0, SinOsc.ar(freq))}).add;
SynthDescLib.global[\ChangeSpec].makeWindow;
)
::
Startup File
As you become more adept at SC you will want to do some customization. Control specs,
record defaults, variables, synth browser, or synth windows can be loaded at startup. For
example, since I work in so many different locations, I use the Theremin as a test tone, checking
my system for sound. To create or edit an existing startup choose File/Open startup file. Place
the ControlSpec lines (and, if you like, the Theremin synth and SynthDescLib line) in the file and
it will be run each time you launch or recompile SC. I use the following file to set the record
depth, open the server window, create a test tone, and add control specs.
18.13:: Startup.rtf
s.recSampleFormat="int16";
s.makeWindow;

SynthDescLib.read;

ControlSpec.specs.addAll(
[
\out -> ControlSpec(0, 16, \lin, 1, 0, " chan"),
\speed -> ControlSpec(0.1, 24, \lin, 0.1, 6, " speed"),
\depth -> ControlSpec(0.001, 1, \lin, 0.02, 1, " depth")
// etc.
]);

// A handy test tone
SynthDescLib.global[\Theremin].makeWindow;



184


::

Exercises
18:1 Create a startup file with customized code. Add a synth definition and control specs.
18:2 Choose your favorite patches from previous chapters and create a synth definition
with GUI interface.





185
19. Filtering, SoundIn
The methods of synthesis; starting with filters.
Real instruments have resonant qualities. The body of the instrument filters and shapes
the character of the sound. Humans have one of the most complex and flexible filters attached to
the top of their necks. The raw sound produced by vocal chords alone resemble a kazoo, but are
still a rich fundamental source. (Open wide and say "aah." That's what you would sound like
without a head.) The tongue, sinus cavities and shape of the mouth filter the raw vocal chords
into the consonants and vowels of speech.
Filtering, or subtractive synthesis begins with a sound or wave that has a rich spectrum
and removes harmonics.
RLPF
(resonant low pass filter) filters frequencies above a given threshold (hence, low-
passsee also high-pass filter and band-pass filter). The arguments for RLPF are input,
frequency cutoff, and rq. The cutoff is where filtering begins. The rq is the width of the band. In
musical terms a narrow rq (low number) focuses the filter so sharply on the cutoff that nearly any
source will resonate on that pitch. These are the same parameters we explored in Logic's EQ
plug-ins. The big difference, the point in fact, is that an RLPF is voltage controlled.
To illustrate, we will use SoundIn to listen to and filter the ambient noise in your
environment. (You might want to move to a noisy location, but also try speech, instruments,
etc.). First, since we've experimented with Soundflower, set the audio device back to your
default input using device(nil). In example 19.1 the poll message posts the value of MouseY.
Note at which value a pitch emerges. Be careful: of both feedback and too narrow of rq. Both can
have startling results. Use headsets and turn the volume down.
19.1:: SoundIn, RLPF
s.options.device_(nil); s.reboot

({RLPF.ar(SoundIn.ar,
MouseX.kr(100, 5000, [1, 1]), MouseY.kr(0.05, 1.0).poll)}.play
)

({RLPF.ar(SoundIn.ar,
LFNoise0.kr([10, 6], mul: 300, add: 500),
MouseY.kr(0.05, 1.0).poll)}.play
)

({RLPF.ar(Saw.ar(40, 0.2), LFNoise0.kr([10, 6], mul: 300, add: 500), 0.05)}.play)

::
The second example places an LFNoise0 control on the frequency cutoff. It sounds like a
VCO (controlling frequency), but that is just the narrow Q, which brings out a pitch. Try
replacing the Saw with LFPulse, LFTri, and PinkNoise. Be sure to check the parameters to see if



186
they match. In Saw they are frequency (40 is used so there are plenty of harmonics in the 200 to
800 range) and mul.
To illustrate how effectively a narrow Q can resonate, the next example uses a single
trigger: Dust as a "rich" source. The first line is Dust without any filtering. The second is Dust
with a very narrow filter. This example sounds quite natural because many real instruments work
this way; some type of excitation, the source (a pluck, tick, strike or bow) that is filtered by the
resonance of the instrument's body.
19.2:: RLPF With Dust
{Dust.ar([13.1, 15.6])}.play

{RLPF.ar(Dust.ar([12.1, 15.6]), LFNoise1.ar(1/5, 1000, [1100, 2200]), 0.02)}.play

::
Logic ES1, ES2
Both the ES1 and ES2 are primarily filtering synthesizers. The examples above can be
recreated in the ES1 using the settings in Figure 19.1. For a noise source set the Wave Mix to
Sub, choose the noise waveform. The resonance is set very high and the cutoff is about in the
middle (this gives the filter some headroom so that the LFO control has room to work). The LFO
is a step random wave, 7 Hz, set to control the cutoff. Try adjusting the Resonance, the Cutoff,
the Rate, the LFO Wave, and the Oscillator waveform.
Fig. 19-1 ES1, Filter
With either the ES1 or ES2, peruse the presets,
find something interesting and make your own
modifications. See if you can predict what each dial will
control, or the sound that will result from a modification.
Complex Resonance
Resonant low pass filters are single pole, that is,
they only filter a single frequency. Though distinct, and
perhaps retro (used heavily in the 70sto warn an
unsuspecting teen of the slasher in a closet), they now
sound clich, immature.
Fig. 19-2 Single Pole Filter Sweep
Figure 19.2 shows a sonogram of a filter sweep using
a single pole resonant filter (like Bright Swell Pad in the ES1
or . Compare with the sonogram below of a real bell in Figure
19.3. Note that each harmonic has a different and independent
envelope. One harmonic does not even appear until several
others have died away.
For more complex filtering, we can use




187
Klank
a component modeling filter that imitates the resonant nodes of a body or space. It
allows you to specify a set of frequencies to be filtered (resonated), matching amplitudes, and
independent decay rates.
Fig. 19-3 Complex Resonance
The first argument for Klank is the frequency specifications. It is
an array of arrays (two dimensional array). That is each item in the array
is also an array (like a box filled with boxes). The outer array begins with
a "`" (back tick? accent grave?) to disable multi-channel expansion. (If
this character were left off, SC would expand the array into different
channels. Go ahead and try it.) The first inner array is the set of
frequencies that resonate, the second is the amplitude of each frequency
(default is 1), and the last is the decay rates of each frequency.
The first example in 19.3 is a single frequency in the array.
Filtering a single frequency has the exact result of an RLPF in the
examples above. The second example fills the arrays using Array.series. The third example loads
an array with random frequencies. The last example adds an amplitude control: an LFTri. Its
output is bipolar, that is, -1 to 1. Placing it inside a max with 0 as an argument returns the greater
of 0 and the LFTri. Negative numbers become 0, creating a nice envelope with silence between.
Run this last example several times to confirm the frequency array is random and to create a
group of rotating wheels.
19.3:: Klank
// Single pole
{Klank.ar(`[[300]], PinkNoise.ar(MouseX.kr(0.01, 0.04)))}.play

(
{ // Harmonic resonance
Klank.ar(
`[[100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]],
PinkNoise.ar([0.01, 0.01]))
}.play
)

(
{ // Using Array.series
Klank.ar(
`[Array.series(10, 50, 50).postln,
Array.series(10, 1.0, -0.1).postln],
ClipNoise.ar([0.005, 0.005])
)
}.play
)

(
{ // Enharmonic Spectrum;



188
Klank.ar(
`[{exprand(60, 10000)}.dup(15)],
PinkNoise.ar([0.005, 0.005])
)
}.play;
)


(
SynthDef("Wheel",
{ arg amp=0.7, out=0;

Out.ar( out,
Pan2.ar(
Klank.ar(
`[{ExpRand(60, 10000)}.dup(15)],
PinkNoise.ar(0.005) *
// Try LFNoise1 and LFNoise0
max(0, LFTri.kr(Rand(1/3, 5)))),
Rand(-1.0, 1.0)))
}).load;
)
Synth(\Wheel);

6.do({Synth(\Wheel)})

::
The sound is rich, natural, evolving, because the excitation source (input) is noise. A
violin bow has a similar effect. The physical body or space described by Klank extracts patterns
from the noise, but the noise gives variety to the body or space. The noise source by itself is too
chaotic to be interesting. The single pole filter sweep is too predictable and manufactured. This
last example strikes, for me anyway, a satisfying balance between the two.
Bells
are resonant bodies. The clapper striking the side of a bell is a burst of noise. (Try
holding a bell so it doesn't resonate and hit the striker. You just hear a short tick.) The shape and
material of the bell or chime resonates on certain frequencies. Those frequencies are sustained
and all others die away quickly. The remaining frequencies are what make up the character of the
bell or chime. The bell patch below begins with an extremely short burst of noise.
Fig. 19-4 Noise Burst

The image in Figure 19.4 shows three of these
bursts. Each is unique. Though they are only a
thousandth of a second, our ears (brains) can distinguish
them. The first example in 19.4 produces these bursts.
Notice the slight differences in each. Because the bursts are different they excite the resonance of
frequency banks in Klank differently, and each strike of the bell produces similar but distinct
sounds. Likewise, run the last example several times to create different bells.




189
19.4:: Chimes

(
{
var burstEnv, att = 0, burstLength = 0.0001, strike;
burstEnv = Env.perc(0, burstLength);
strike = PinkNoise.ar(EnvGen.kr(burstEnv, gate: Impulse.kr(1)));
strike;
}.play
)

(
{
var chime, freqSpecs, burst, totalHarm = 10;
var burstEnv, att = 0, burstLength = 0.0001;

freqSpecs = `[
{rrand(100, 1200)}.dup(totalHarm), //freq array
// .normalizeSum ensures sums to 1
{rrand(0.3, 1.0)}.dup(totalHarm).normalizeSum, //amp array
{rrand(2.0, 4.0)}.dup(totalHarm)]; //decay rate array

burstEnv = Env.perc(0, burstLength);
burst = PinkNoise.ar(EnvGen.kr(burstEnv, gate: Impulse.kr(1)));

Klank.ar(freqSpecs, burst)*MouseX.kr(0.1, 0.8)
}.play
)

(
{ // The triggers are random, so you may have to wait for sound
var chime, freqSpecs, burst, totalHarm = 10;
var burstEnv, att = 0, burstLength = 0.0001;

freqSpecs = `[
{rrand(100, 1200)}.dup(totalHarm), //freq array
{rrand(0.3, 1.0)}.dup(totalHarm).normalizeSum, //amp array
{rrand(2.0, 4.0)}.dup(totalHarm)]; //decay rate array

burstEnv = Env.perc(0, burstLength);
burst = PinkNoise.ar(EnvGen.kr(burstEnv, Dust.kr(1/3)));

Pan2.ar(
Klank.ar(freqSpecs, burst)*MouseX.kr(0.1, 0.8),
1.0.rand2)
}.play
)

::



190
Experiment with a different range of harmonics and fewer or more total harmonics. Use
Array.fill to tune the harmonic frequencies as with the examples above. If the harmonics are
detuned slightly, it will sound a little more like a tuned bell. How would you detune the
harmonics by + or 10%? Change the range of choices for decay rates.
These chimes sound very natural, realistic. That is because they are chaotic. Each burst of
noise is different, and the resonant body is excited differently, and the harmonics ring differently.
The code does not describe a single sound, but the process of creating a sound. It describes the
body of the instrument, its nature, then sets it in motion with a chaotic event. Though Klank is a
filter, it is also an example of physical modeling, covered later.
The previous examples show both harmonic and inharmonic collections of frequencies.
How can you be sure the frequency collection is what you wanted (random, odd, even, detuned,
etc.)? Likewise, how do you go about isolating problems in a patch that isn't doing what you
want? By
Debugging
When something isn't quite right, one of my first steps is to isolate and evaluate small
pieces of code. The example below shows an entire line of code with smaller sections in red.
These smaller sections can be selected and evaluated individually. An earlier patch is reproduced
below it. See if you can find sections that can be evaluated in isolation.
19.5:: Isolate, Evaluate
Array.fill(5, {exprand(10, 100)}).round(1) * ([1, 2, 5, 7].choose)
Array.fill(5, {exprand(10, 100)}).round(1) * ([1, 2, 5, 7].choose)
Array.fill(5, {exprand(10, 100)}).round(1) * ([1, 2, 5, 7].choose)
Array.fill(5, {exprand(10, 100)}).round(1) * ([1, 2, 5, 7].choose)

(
{ // Run this several times
Pan2.ar(
Klank.ar(
`[{exprand(60, 10000)}.dup(15)],
PinkNoise.ar(0.005) *
max(0, LFTri.kr(rrand(1/6, 5)))),
1.0.rand2)

}.play;
)

::
You have to be careful about commas and variables. For example, if you select and
evaluate this section: {rrand(100, 1200)}.dup(totalHarm), you will get an error because of the
comma and missing variable declaration for totalHarm. But if you replace the totalHarm with 10
and select everything but the comma, it can be evaluated separately and SC will print the results
in the post window.




191
Two other methods for finding problems: you can copy and paste a section of code to
another file or outside your patch, fiddling with it until it produces what you need. For example,
the max(0 LFTri.kr(rrand(1/6, 5)) could be placed in a function with a plot. Also, !E brings up
a command line for evaluating code sections immediately.
You can also isolate problems by replacing suspect parts of the code with safer values,
and by removing a section with comments. Comments are identified by "//" or "/*" to begin the
comment and "*/" to end the comment. Again, you have to be careful about semicolons and
commas. If you suspect a problem with the freqSpecs arrays you could insert a single "safe"
value in place of the random array: {0.2 /*rrand(0.3, 1.0)*/}.dup(totalHarm). This will fill the
entire array with 0.2 rather than the rrand(0.3, 1.0).
Array.fill(5, {exprand(10, 100)}) /* .round(1) * ([1, 2, 5, 7].choose) */
Lines of code are evaluated from top to bottom. This means you can replace suspect lines
by simply placing new lines just below. Place the cursor on the second line and you now have an
A/B switch that is turned on and off by toggling comments (!/). Run the first example, then
uncomment the "this I know works" and run it again. The sentence "this is experimental" is
simply replaced.
19.6:: Safe Alternatives
(
a = "this is experimental";
// a = "this I know works";
a;
)

( // an example in real code
{
var chime, freqSpecs, burst, totalHarm = 10;
var burstEnv, att = 0, burstLength = 0.0001;

freqSpecs = `[{rrand(100, 2000)}.dup(10)]; // experimental
// freqSpecs = `[[100, 200]]; // safe

Klank.ar(freqSpecs, PinkNoise.ar(0.01));
// SinOsc.ar // test tone if I get no sound at all
}.play
)

::
When the second freqSpecs is commented it is not included in the patch. If you remove
the comments then the safe section will replace the experimental section. (You don't have to
comment out the experimental section, it is just reassigned.) If the patch then runs correctly,
there is something wrong with the experimental part.
If there is no sound at all, you can narrow down the issue (e.g., is it a system problem, an
SC malfunction, or something in the code) with a simple SinOsc.ar as the last line of the function
and that line will be played while everything above it is ignored.



192
Monitoring Data
will also help to isolate issues. The next example uses post and poll messages to print
the results of an operation to the Data window. This is similar to selecting and evaluating a
section. The difference is that you can evaluate several places at once. There are intentional
errors in the patch below. When you run it, it will explode into several screen's worth of error
data. But the first lines should reveal the items connected to a postln. Can you spot them by
examining the posted data? (Hint: nil means no data has been assigned.) Press !P to clear the
post window.
19.7:: Post And Poll
( // intentional errors
{
var chime, freqSpecs, burst, totalHarm = 10;
var burstEnv, att = 0, burstLength;

freqSpecs = `[
rrand(100, 1200).dup(totalHarm).postln,
{rrand(0.3, 1.0)}.dup(totalHarm).normalizeSum.round(0.1).postln,
{rrand(2.0, 4.0)}.dup(totalHarm).round(0.1).postln];

burstEnv = Env.perc(0, burstLength.postln); //envelope times
burst = PinkNoise.ar(EnvGen.kr(burstEnv, gate: Impulse.kr(1))/*.poll*/);

Klank.ar(freqSpecs.postln, burst)*MouseX.kr(0.1, 0.8)/*.poll*/
}.play
)

::
The first error is the fourth item postedburstLength, which was nil. The second error is
revealed by the first postln; all the values in the array are the same because the rrand is not
enclosed in a function. Once these errors are fixed, uncomment the poll messages to post the
values of MouseX and EnvGen as the patch runs.
The postln message can be nested within a message chain, as shown in this example. You
can remove them using find and replace.
19.8:: Nested Postln
(
[[60, 62, 68], [65, 67], [61, 63, 55, 23]].choose.postln.midicps.postln
.round(0.1).postln.reciprocal.postln.round(0.0001).postln
)

::
The post message prints to the post window, postln prints the object then begins a new
line. If you use post repeatedly the information is merged into one blob. The obvious solution is




193
to use postln, but that eats up the post window quickly. It is also difficult to examine related data
if everything is on a separate line.
The solution is to format the output by placing it in an array or to use scatArgs, which
concatenates a string with a list of arguments, and finally postf, which has as its first argument a
string containing text interspersed with the "%" character. Following that are additional
arguments that will be placed in the string where the "%" characters were (in order). For the
second example there are three methods. In this case, when you uncomment a new alternative,
you must comment the current postln line. Otherwise they will both print.
19.9:: Formatting Posted Information

(
// too spread out
var pitch, duration, amplitude, voice;
20.do({
pitch = [60, 62, 64, 65, 67, 69, 71].choose.postln;
duration = 4.0.rand.round(0.1).postln;
amplitude = 1.0.rand.round(0.1).postln;
voice = 10.rand.postln;
})
)

(
var pitch, duration, amplitude, voice;
"pitch, duration, amplitude, voice".postln;
20.do({
pitch = [60, 62, 64, 65, 67, 69, 71].choose;
duration = 4.0.rand.round(0.1);
amplitude = 1.0.rand.round(0.1);
voice = 10.rand;
// Collect variables in an array
[pitch, duration, amplitude, voice].postln;
// or prepend identifiers
// "p d a v".ccatArgs(pitch, duration, amplitude, voice).postln;
// interleve the identifiers %. Also, \t = tab, \n = new line
// "p %\t d %\t a %\t v %\n".postf(pitch, duration, amplitude, voice)

})
)

::
In strings a backslash has special meaning. It is an escape character which gives the
character immediately following special meaning. The most useful are \t, \n, \\, and \".



194
Exercises
19:1 Begin with two ES1 presets. Generate three new patches by adjusting each of these
items: Oscillator Wave and Sub, Cutoff and Resonance, Low Frequency Wave
and Rate, and ADSR. When you create something interesting, save it as a preset.
19:2 Open the ES2 instrument. Experiment with the randomize feature. Save three of
your favorite results.
19:3 Modify the "Wheel" patch. Change the number of harmonics and the range of
harmonics. How many harmonics push the CPU to the limit? Try a wide and narrow
range of harmonics. Pick three that represent the most difference from the original
and name the patch accordingly; bent metal, crotale, sheet metal, explosion, etc.
19:4 Add "safe" values to the "Wheel" patch. Find sections of code that can be isolated.
Add monitoring points with formatted posts.





195
20. Phase Modulation
Formerly AM, FM. Rich, and efficient.
The vibrato example in Chapter 16 used one oscillator in low frequency to control
another in audio range. Hopefully you ignored my warning not to exceed 20 Hz for the speed of
the control frequency. When the control rate of this kind of patch moves into audio range
something unexpected, almost magical occurs: new frequencies appear above and below the
frequency being controlled. The vibrato morphs into a blend of frequencies.
Several examples in this chapter (and from now on) assume you have run example 18.12
to add control specs. They will run without this, but the GUI window is not as accurate.
Frequency Modulation
Example 20.1 illustrates the transition from low frequency modulation to high frequency
modulation. As you increase the LFO speed the wide vibrato will slowly evolve into a much
more complex sound. You might recognize an antique radio being tuned because controls that
enter audio range become frequency and amplitude modulation; the same technology used by
AM and FM bands for radio transmissions.
20.1:: From LFO to FM
(
SynthDef("LFOtoFM", {|lfospeed = 1, lfoscale = 200|
Out.ar(0, SinOsc.ar(SinOsc.ar(lfospeed, mul: lfoscale, add: 800)))
}).add;

// Run 18.12 first
SynthDescLib.global[\LFOtoFM].makeWindow;
)
::

Fig. 20-1 LFO to FM
! The magical frequencies are upper and lower sidebands; the product of the two
modulated frequencies.
The example below uses scope. The scope belongs to the sclang program. Once it
appears, move it to the lower right hand corner then return to SuperCollider. Alternately, you can
replace all scopes with play and use SoundFlower to route audio to Amadeus, then open
oscilloscope and sonogram. Notice in the scope that you can create patterns identical to the
interference patterns of intervals from chapter 8.



196
20.2:: AM Synthesis
{SinOsc.ar(500, mul: SinOsc.ar(MouseX.kr(1, 400), mul: 0.5))}.scope(1)

{Saw.ar(500, mul: SinOsc.ar(MouseX.kr(1, 400), mul: 0.5))}.scope(1)

::
First impressions of AM and FM are distinctly sci-fi, alien. What starts out as a natural
vibrato, when extended to extremes, becomes a uniquely synthetic sound. Yet FM modulation
occurs in the natural world, specifically, the songs of birdsMother Nature's little FM and AM
modulation synthesizers. Their vocal chords (a detailed description of which, even if within my
grasp, is not going to happen here) are arranged such that one can modulate the other. 20.3 is a
patch that simulates the AM and FM effect in bird song. The speed of the two controls are set to
MouseX and Y UGens. Slight movement seems most effective. The second example adds a GUI,
though I think the mouse version is better.
20.3:: AM, FM, Bird Song
(
{
var fm, am;
fm = SinOsc.ar(MouseY.kr(1, 100), mul: 1500, add: 3000);
am = SinOsc.ar(MouseX.kr(1, 100), mul: 0.5, add: 0.5);
Pan2.ar(SinOsc.ar(fm, mul: am * max(0, Pulse.kr(1/2))))
}.play
)


(
SynthDef("Syrinx", {
|fmlfo = 15, fmscale = 1500, fmoffset = 3000, lfospeed = 20, lfo2speed = 4|
var fm, am, pitchmod;
fm = SinOsc.ar(fmlfo, mul: fmscale, add: fmoffset);
am = SinOsc.ar(lfospeed, mul: 0.5, add: 0.5);
pitchmod = LFNoise1.kr(lfo2speed, 0.3, 1);
Out.ar(0, Pan2.ar(SinOsc.ar(fm * pitchmod, mul: am * max(0, Pulse.kr(1/2)))))
}).add;

// Run 18.12 first
SynthDescLib.global[\Syrinx].makeWindow;
)


::
! The oscillator that is being controlled is the carrier and the controlling oscillator is the
modulator. In amplitude modulation the sidebands produced are the sum and difference of the
two. If the carrier is 500, and the modulator is 50, then the two sidebands will be 550 and 450.
The carrier will also be heard; three frequencies total.




197
! In FM the sidebands are also the sum and difference of the carrier and modulator, but
many more sidebands can be generated. The exact number depends on the modulation index. The
modulation index is how far the modulating frequency deviates from the carrier (the amplitude of
the modulating wave). If the carrier is 500, and the modulator is 50, then the sidebands will be
550, 600, 650, etc., and 450, 400, 350, 300, etc. (depending on the index). In SC both the carrier
and modulator frequencies can appear as arguments in a single SinOsc. For clarity I've used this
form: 400 + SinOsc(124, mul: 100). The 400 is the carrier frequency, 124 is the modulator
frequency and 100 is the index.
20.4:: FM Synthesis

{SinOsc.ar(400 + SinOsc.ar(124, mul: 100), mul: 0.5)}.play

::
FM synthesis was developed by John Chowning during the 60s and used extensively in
the 80s, specifically in the Yamaha DX7 series. Its success comes from its efficiency; using only
two waves to generate theoretically unlimited sidebands of harmonic or inharmonic (but still
mathematically related) spectra.
In subtractive synthesis you can only remove what is already there. The advantage of FM
is the ability to generate and change the harmonic content. The most common sources for
filtering are noise or waves with harmonic spectra; square, saw, triangle. These overtones are
whole number multiples of the fundamental; x1, x2, x3, x4, x5, etc. In FM, the sidebands (ergo,
'harmonics') are the determined by the ratio of the carrier to the modulator. A 440 Hz carrier and
67 Hz modulator (a ratio of 0.15227) will generate one set of sidebands. Changing the carrier
only slightly65 Hz (a ratio of 0.1477)will produce a completely different set of sidebands.
Below is a chart showing sidebands for a 440 Hz carrier and modulators of 67, 65, and 65.13.
Modulator Sidebands
67 [ 38, 105, 172, 239, 306, 373, 507, 574, 641, 708, 775, 842 ]
65 [ 50, 115, 180, 245, 310, 375, 505, 570, 635, 700, 765, 830 ]
65.13 [ 49.22, 114.35, 179.48, 244.61, 309.74, 374.87, 505.13, 570.26, 635.39, 700.52, 765.65, 830.78 ]
Remember that the character of a wave is determined by the presence and strength of
harmonics (or sidebands). Each of these sets of sidebands will have a different character. The
possible variations in sound quality are literally endless. The code for calculating sidebands is
((-n..n)*m+c).abs.sort.round(0.01), where m is modulator, c is carrier, and n is the number of
sidebands produced.
20.5:: Complex Sets of Sidebands
20.do({((-20..20)*rrand(100, 1000) + rrand(100, 1000)).abs.sort.round(0.01).postln});

::
And of course the ratio can be voltage controlled, therefore changed in real time. With
filtering, even if you began with a source containing any of these sets of harmonics, you can only
remove or add them. You can't modulate them on the fly.



198
! To summarize the appeal of FM:
Efficiencyrich spectra with only two oscillators
Complex spectralimitless patterns of harmonics
Voltage controlled spectraharmonics can be changed in real time.
Phase Modulation
SC's PMOsc (phase modulating oscillatorMarvin the Martian had one) is a more
efficient cousin to FM. The difference is academic, and the results are the same. Example 20.6
illustrates the efficiency of PM. The first uses a mouse control for exploration, similar to the FM
example. The second uses static values, but note the CPU and number of UGens in the server
window. The third creates a similar set of sidebands using additive synthesis (covered later). It
uses nearly ten times the number of UGens and three to four times the CPU.
20.6:: Phase Modulator Efficiency
(
SynthDef("PMOscEx", {|fmlfo = 100, pindex = 2.5|
Out.ar(0, PMOsc.ar(400, [fmlfo, fmlfo*2], pindex), mul: 0.5)}).add;
SynthDescLib.global[\PMOscEx].makeWindow;
)

{PMOsc.ar(1000, 1367, 12, mul: EnvGen.kr(Env.perc(0, 0.5), Impulse.kr(1)))}.play

(
{
Mix.ar(
SinOsc.ar(abs((-20..20)*1367 + 1000),
mul: 0.1*EnvGen.kr(Env.perc(0, 0.5), Impulse.kr(1)))
)}.play
)

::
! The ratio of the carrier and modulator determine the sidebands and hence the quality or
timbre, the index controls the number of sidebands, hence the brightness of the wave. The carrier
is more or less the fundamental pitch. Changing the carrier while the modulator and index remain
the same will sound like one instrument with a changing pitch. Changing the modulator only will
sound like different instruments playing the same pitch. Changing the index will sound like one
instrument being filtered. Of course, you can change all three.
20.7:: Phase Modulation
(
{PMOsc.ar(LFNoise0.kr(5, 300, 700), // carrier (pitch)
134, 4, mul: 0.4)
}.play
)

(
{PMOsc.ar(700,




199
LFNoise0.kr(5, 500, 700), //modulator (timbre)
12, mul: 0.4
)}.play
)

(
{PMOsc.ar(700, 567,
LFNoise0.kr(5, 6, 12), //index (filter)
mul: 0.4
)}.play
)

(
// All three.
{PMOsc.ar(LFNoise0.kr([9, 9], 300, 700),
LFNoise0.kr([9, 9], 500, 700),
LFNoise0.kr([9, 9], 6, 12),
mul: 0.5
)}.play
)

::
Similar to the ratios that give us musical intervals, if the sidebands are related by low
ratios, then they will blend into a clear pitch. For this reason it is useful to calculate the
modulating frequency as a ratio of the carrier frequency (freq*ratio). Example 20.8 uses a slider
interface with a numerator and denominator (super-particular just out of convenience). Notice
that low ratios2/1, 3/2, 4/3are mild, clear pitches. But as the ratio increases, the timbre
darkens. Each of these ratios is reflected in the value of the fine tune slider. Use this slider to
adjust the ratio to more complex numbers (e.g., 2.293). This will generate more distantly related
sidebands and more obscured pitch. The result is more metallic, bell-like timbres. Values that are
very close to a simple ratio, such as 2.01, will detune a harmonic spectrum slightly. The other
advantage of using a ratio is that the modulator is linked to the carrier. When the carrier (which
is the pitch we hear, if a simple ratio) changes, the collection of sidebands will remain the same
in relation to the carrier. The practical result is a consistent timbre, even though the pitch
changes. Notice I am using MIDI numbers for frequency.
20.8:: PM Ratio
(
SynthDef("PM",
{
arg ratio=1, rate=1, amp=0.4, low=24, hi=48, index=10;
var freq, mix, env;
env = EnvGen.kr(Env.perc(0, 2/rate), Impulse.kr(rate));
freq = TIRand.kr(low, hi, Impulse.kr(rate)).midicps;
mix = PMOsc.ar(freq, freq*ratio, //modulator
index*env, mul: amp);
Out.ar(0, mix*env);
}).add;



200
)


(
// Interface
w=Window.new.bounds_(Rect(20, 400, 500, 160)).front;
w.view.decorator=FlowLayout(w.view.bounds);
w.view.background = Color.rand;
Button(w, 100@20)
.states_([["Start"],["Stop"]])
.action_({|view| if (view.value == 1) {a = Synth("PM")} {a.free}});
EZSlider(w, 392@16, " ", [1, 12, \lin, 1, 3].asSpec,
{|ez| var ev; ev = ez.value; h.value_(ev + 1); i.value_(ev);
g.value_((ev+1)/ev); a.set(\ratio, (ev+1)/ev)},
numberWidth: 0);
h = EZNumber(w, 100@20, "num ", [1, 12, \lin, 1, 1].asSpec);
i = EZNumber(w, 100@20, "den ", [1, 12, \lin, 1, 1].asSpec);
g = EZSlider(w, 392@16, "fine ", [0.0, 4.0, \lin, 0.001, 1].asSpec,
{|ez| a.set(\ratio, ez.value)});
EZSlider(w, 392@16, "rate ", [1/10, 12, \lin, 0.1, 3].asSpec,
{|ez| a.set(\rate, (ez.value))});
EZRanger(w, 392@16, "range ", [12, 96, \lin, 1, 24].asSpec,
{|ez| a.set(\low, ez.value.at(0), \hi, ez.value.at(1))}, [24, 48])

)

::
These timbres are not possible using noise as a source or any periodic waveform alone.
They are unique to FM/PM, at least in the synthesis realm. They do occur naturally in bells,
birds, (bangles and beads). But we're not done yet. Controlling the ratio, therefore the sidebands,
in real time produces results that cannot be found anywhere else, except maybe the Krell
laboratory on Altair IV.
20.9:: Voltage Controlled PM Ratio
(
{
var env, trig, rate, carrier, mix;
rate = 1/2;
trig = Dust.kr(rate);
env = EnvGen.kr(Env.perc(1/rate, 0.1), trig);
carrier = LFNoise1.kr(1/20, 500, 2000);
mix = Pan2.ar(
PMOsc.ar(
carrier,
carrier * LFNoise0.kr(12, 0.2, 2),
10 * env
) * env,
LFNoise1.kr(1/20));
mix + CombN.ar(mix, 3, 0.167);




201
}.play
)

::
Here is an earlier example that pairs each of the parameters with a demand sequence.
20.10:: PMOsc and Demand Sequence
(
{ var envelope, rate = 9, pitch, trigger, mod, seq, oct;
trigger = Impulse.kr(rate);
envelope = Linen.kr(trigger, 0, 1, 1/rate);
seq = Array.fill(10, {Dseq(Array.fill(12, {[0, 2, 4, 5, 7, 9, 10].choose}) + 48, rrand(2, 6))});
pitch = Demand.kr(trigger, 0, Dseq(seq, inf)).midicps;
mod = Demand.kr(trigger, 0, Dseq([1.5, 1.5, 1.5, 1.65, 1.25, 2.223, 2.567], inf));
PMOsc.ar(pitch, pitch*mod, envelope * 6, mul: envelope) * 0.3
}.play
)

::
EFM1
Logic, of course, has an FM synthesizerthe EFM1. Having worked through the
previous examples, you should recognize the carrier frequency, the modulator frequency, and
modulation envelope. The FM depth is equivalent to index in PMOsc. Selecting fixed links the
modulator and carrier as we did with a ratio. Scroll through the presets and note the similarities
in the bell-like patches to our experiments. Of course, SC allows much more flexibility in
designing control sources for each parameter. There is no random LFO in the EFM1, but there is
a randomize button, which you should try.
Logic Pro Modulators, Ringshifter
In addition to the EFM1 instrument, Logic has a good collection of modulation plugins.
Most are variations of chorus, flangers, and phase shifters. These all work by duplicating the
signal and shifting the phase, exactly what we said you should avoid when placing mics in pairs.
Choruses are generally used to thicken the sound. Flangers are more extreme versions that
created a distinctive swirling effect; Experienced, Hendrix, Listen to the Music, Doobies (just
before the 'lazy flowing river'), Owner of a Lonely Heart, Yes ('oh much better than'), and
Killer Queen, Queen ('gunpowder, guillotine, dynamite with a laser beam').
By far the most interesting Logic insert is the Ringshifter, which applies FM techniques
to any track. Start with the presets and explore by adjusting the knobs. The side chain always
looks promising, but it's never given me satisfying results.
Latch (Sample and Hold)
While we're listing missing features, sample and hold is a control source that was lost in
the transition from modular synthesizers to digital workstations. They are a type of sequencer,
but capable of a greater variety in patterns; more variety than a sequencer, but more cohesive



202
than a noise source. Though I haven't researched it, I'm pretty sure sample and hold units led to
the notion and subsequent revolution of digital audio. It is certainly the logical extension. Digital
audio is simply a sample and hold with a very high sample rate.
The effect of Latch is similar to aliasing, and the results are aliased patterns. Below is a
patch with an upper graph that shows the control values that are sent to the frequency parameter
of the carrier sine wave.
20.11:: Sample and Hold Patterns
(
var gWin, audio, aNode, gbutton, xrate=0.1, yrate;

yrate = 0.01;
aNode =
SynthDef("Alias", {arg rate = 5, freq = 0.25;
Out.ar(0, SinOsc.ar(
Latch.ar(SinOsc.ar(freq, mul: 200, add: 500), Impulse.ar(rate))) * [0.2, 0.2])
}).play;

gWin = Window.new("Aliasing Illustration (rough draft)", Rect(20, 600, 1160, 350)).front;
gWin.view.decorator = FlowLayout(gWin.view.bounds);

x = MultiSliderView(gWin, Rect(10, 38, 1110, 150)).drawLines_(true)
.value_(Array.fill(100, ({arg i; (i * xrate).sin * 0.5 + 0.5})))
.thumbSize_(5).gap_(6).valueThumbSize_(4).colors_(Color.red(0.7))
.background_(Color.new255( 92, 206, 255, 40 ))
.action_{|v| v.value.round(0.01)};
y = MultiSliderView(gWin, Rect(10, 38, 1110, 150)).drawLines_(true)
.value_(Array.fill(1000, ({arg i; (i * yrate).sin * 0.5 + 0.5})))
.background_(Color.new255( 209, 95, 238, 40))
.thumbSize_(0.1).valueThumbSize_(4).colors_(Color.blue(0.5))
.action_{|v| v.value.round(0.01)};
g = EZSlider(gWin, 1000@24, nil, [0, 4.0, \lin, 0.001, 0].asSpec)
.action_({|ez|
x.value_(Array.fill(100, ({arg i; (i * ((ez.value * 10 + 1) * xrate)).sin * 0.5 + 0.5})));
y.value_(Array.fill(1000, ({arg i; (i * ((ez.value * 10 + 1) * yrate)).sin * 0.5 + 0.5})));
aNode.set(1, (0.25 + (ez.value * 1.25)));
});

gbutton = Button(gWin, 100 @ 24);
gbutton.states = [["Stop Audio", Color.white, Color.red(0.7)],
["Start Audio", Color.black, Color.green(0.7)]];
gbutton.action = {|view|
if (view.value == 1) {aNode.run(false)} {aNode.run(true)}};
)

::
The patterns that emerge from a sample and hold are the product of the sample rate and
frequency of the sampled wave. If either is set to a very gradual voltage control, the shifting




203
patterns seem improvised. They have a logic; predictable yet surprising. Figure 20.2 shows a
sonogram of a latched saw wave (from patch 20.12). The first few patterns reflect the saw that is
being sampled, but as the speed of the wave changes, the patterns change. They are complex, but
logical.


Fig. 20-2 Sample and Hold (Latch) Patterns
Patch 20.12 contains latch variations. The first uses a SynthDef, allowing the creation of a
window. The frequency of the sampled wave (and therefore the patterns) can be explored using
the slider (or click the number box and use the up and down arrows). The next uses a Line,
followed by a slowly changing LFNoise in the third, and a step noise in the fourth. The very last
example combines a rhythmic pattern that adds to the sense of direction. It is accomplished by
simply turning notes on or off. That is, rather than determining patterns by constructing a set of
durations, a potential note is created at each pulse, then they actually fire, or don't fire according
to some random (or sequenced) pattern. In this case, it is an LFNoise0 filtered through a max(0,
LFNoise0) which returns 0 when LFNoise0 falls below 0. In short, and with fewer 0s, negative
numbers don't "fire", positive values do.
20.12:: Sample and Hold Improvisation

(
ControlSpec.specs.addAll([\latchlfo -> ControlSpec(0.1, 24, \lin, 0.1, 6, " latchlfo")]);

SynthDef("Latch", { arg lowfreq=10, latchlfo = 0.1;
var trig, env, out;
trig = Impulse.kr(lowfreq);
env = Linen.kr(trig, 0, 1, 1/lowfreq);
out = SinOsc.ar(Latch.kr(LFSaw.kr(latchlfo, 0, [500, 250], 600), trig), mul: env);
Out.ar(0, out)
}).add;

SynthDescLib.global[\Latch].makeWindow;
)

(
{ // Line control
var env, trig, speed=10;
trig = Impulse.kr(speed);
env = Linen.kr(trig, 0, 1, 1/speed);



204
SinOsc.ar(
Latch.kr( // spread out a little
LFSaw.kr(Line.kr(0.1, 20, 60), 0, [500, 250], 600),
trig),
mul: env
)
}.play
)

(
{ // Ramp noise control
var env, trig, speed=10;
trig = Impulse.kr(speed);
env = Linen.kr(trig, 0, 1, 1/speed);
SinOsc.ar(Latch.kr(LFSaw.kr(LFNoise1.kr(1/20, 10, 10.1), 0, [500, 250], 600), trig), mul: env)
// SinOsc.ar(Latch.kr(LFSaw.kr(LFNoise0.kr(1/3, 10, 10.1).poll, 0, [500, 250], 600), trig), mul: env)
}.play
)

(
{ // Choosen from a predetermined set: patterns will return.
// Dial in the balance of repetition and variation by the
// number of sets
var env, trig, speed=10, set, setSize=5;
set = Array.fill(setSize, {rrand(1.1, 2.7)}).round(0.001).post;
trig = Impulse.kr(speed);
env = Linen.kr(trig, 0, 1, 1/speed);
SinOsc.ar(Latch.kr(LFSaw.kr(
Demand.kr(Impulse.kr(1/5), 0, Drand(set, inf)), 0, 12, [60, 72]).midicps, trig), mul: env)
}.play
)


(
{ // controlling modulator and carrier freq (timbre)
var env, trig, speed=10;
trig = Impulse.kr(speed);
env = Linen.kr(trig, 0, 1, 1/speed);
f = Latch.kr(LFSaw.kr(MouseX.kr(1.1, 30), 0, 1000, 1100), trig);
PMOsc.ar([f, f*3/2], f*2, 12, mul: env)
}.play
)

(
{ // controlling index (filter)
var env, trig, speed=10;
trig = Impulse.kr(speed);
env = Linen.kr(trig, 0, 1, 1/speed);
i = Latch.kr(LFSaw.kr(MouseX.kr(1.1, 30), 0, 5, 5), trig);
PMOsc.ar([300, 350], 356, i, mul: env)
}.play




205
)

(
{ // controlling ratio (pitched timbre)
var env, trig, speed=10;
trig = Impulse.kr(speed);
env = Linen.kr(trig, 0, 1, 1/speed);
r = Latch.kr(LFSaw.kr(MouseX.kr(1.1, 30), 0, 2.0, 3.0), trig);
PMOsc.ar(300, [300*r, 400*r], 12, mul: env)
}.play
)

(
{ // and of course, scaled to control all three
var env, trig, speed=10;
trig = Impulse.kr(speed);
env = Linen.kr(trig, 0, 1, 1/speed);
c = Latch.kr(LFSaw.kr(MouseX.kr(1.1, 30), 0, 0.5, 0.5), trig);
f = c*1000+200;
o = PMOsc.ar(f, f*(c*3+4), c*5+6, mul: env);
[o, CombL.ar(o, 2, 2)]
}.play
)

(
SynthDef("SH_Variations",
{
// out is included as an argument so you
// can switch the output to other tracks if
// in Logic (if using Soundflower).
arg speed=6, out=0;
var env, trig, set, setSize=10, mix;
set = Array.fill(setSize, {rrand(1.1, 2.7)}).round(0.001).post;
trig = Impulse.kr(speed);
env = Linen.kr(trig, 0, 1, 1/speed);
c = Latch.kr(
LFSaw.kr(Demand.kr(Impulse.kr(1/5), 0, Drand(set, inf)),
0, 0.5, 0.5),
trig);
f = (c*48+24).round(1).midicps;
// Tone down the ratio
r = LFNoise1.kr(1/5, 2.0, 3.0).round(0.1);
mix = PMOsc.ar(f, f*r, c*5+6 * env, mul: env);
// add an on/off decision + amplitude variation
mix = mix * max(0, TRand.kr(-1.0, 1.0, trig));
// Kanon
// mix = [mix, CombL.ar(mix, 2, 2)]
// Triple Kanon
// mix = FreeVerb.ar(mix, LFNoise0.kr(1/3, 0.3, 0.3), 0.6);
mix=Pan2.ar(mix, -1) + Pan2.ar(CombL.ar(mix, 2, 2), 0) +
Pan2.ar(CombL.ar(mix, 4, 4), 1);



206
Out.ar(out, mix*0.3)
}).add
)

SynthDescLib.global[\SH_Variations].makeWindow

::
Another method for generating interest is to sample a more complex waveform. Even
though complex, it is periodic, and patterns in the wave will be evident in the control values.
In this example three waves are mixed together to create a more complex, but still
periodic, wave. The first line of code shows four waves at 100, 200, 300, and 550 Hz, mixed to
one wave. The second part places the mixed wave into a Latch.
20.13:: Complex Wave as Source
{Mix.ar(SinOsc.ar([100, 200, 300, 550], mul: 0.1))}.plot;

(
//Used in a sample and hold
{
f = Latch.kr(
Mix.ar(SinOsc.ar([100, 200, 300, 550], mul: 100, add: 110)),
Impulse.kr(7));
e = EnvGen.kr(Env.perc(0, 0.2), Impulse.kr(7));
m = PMOsc.ar(f, f*1.25, e*5, mul: e*0.3);
[m, CombL.ar(m, 2, 2)]
}.play
)

::

In case you haven't guessed, I really like these systems. We should use them more. I can't
think of any other method of organization that generates such interesting evolving patterns so
quickly and elegantly. In the example below try an attack of 1/rate and a decay of 0. Uncomment
the alternate latchrates, which move either gradually or stepwise through random values between
1.53 and 1.63. The patch is expanded to stereo with the [freq, freq * 1.5]. This creates a fifth in
the right channel. Try other intervals such as 1.2, 1.7, 2, 1.25, etc. Also uncomment the
alternative frequency, and ratios, or add your own.
The key is to find that sweet spot where you can still follow the emerging patterns, yet
have enough variety to keep your attention for long periods of time. Isn't that really what
composition is all about; a blend of predictability and surprise?
The second example does not use an S&H or sequencer (maybe you could add one?), but
closes out this chapter by illustrating PM. It generates PM events with complex ratios, therefore
inharmonic spectra (like a crotale) with a collection of envelopes (fast attack, long decay, and
long attack, fast decay, which sounds reversed) for amplitude and modulation index.




207
The code that actually generates crotale events is a routine that uses random functions,
but remember it gets values from a random number generator. Read further on to see how to
reset the seed of the random number series, reproducing precisely a given sequence of values.
The third task does this, and the occasional repetition gives a sense of cognizant improvisatory
gestures. It sends "seeds" periodically, either chosen from the clock (70 percent of the time), or
repeating the previous seed (30%). You can think of this task as a conductor, instructing the
performer to either move on to something new (from the collection of billions of possible
gestures) or repeating something you already did. More on this later.
Try both examples at once. Adjust the overall volume of the first one. Comment out the
FreeVerb lines and use Soundflower to send the output to Logic Pro and use it's more
sophisticated spatial effects.
This completes our discussion of typical electro-acoustic control sources. Later we will
cover external data and probabilities, but I think of them as composition tools, not synthesis
sources. Below is a review.
Control Source Review
Character Examples
Periodic Wave Forms Exact repetition, classic (clich) Sine, Saw, Pulse
Aperiodic Wave Forms Random, classic (clich) LFNoise1, LFNoise0
Sequencers Exact, but custom, complex repetition Dseq
Sample and Hold Evolving patterns, blend between variation/repetition Latch
External data Complex, meaning through context, natural patterns transfer Data files
Probabilities Artificially intelligent Data tables, if()
20.14:: Sample and Hold, PM
(
// This example is not placed in a SynthDef because there are commented variations.
// Once you settle on an interesting combination, create a SynthDef.
{
var freq, latchrate, index, ratio, env, speed = 9;
speed = MouseX.kr(2, 20);
latchrate = speed*1.61803399;
// latchrate = speed*LFNoise1.kr(1/7, mul: 0.03, add: 1.6);
// latchrate = speed*LFNoise0.kr(1/3, mul: 0.03, add: 1.6);

index = Latch.kr(
LFSaw.kr(latchrate, mul: 4, add: 8),
Impulse.kr(speed)
);
freq = Latch.kr(
LFSaw.kr(latchrate, mul: 36, add: 60),
Impulse.kr(speed)
).round(1).midicps;
// freq = 200; //uncomment this line to hear just the index

ratio = 2.01;
// ratio = LFNoise1.kr(1, mul: 2.3, add: 3.0);
// ratio = LFNoise0.kr(1, mul: 2.3, add: 3.0);



208
// ratio = LFNoise1.kr(1/5, mul: 2.0, add: 5.0);

env = EnvGen.kr(Env.perc(0, 2/speed), gate: Impulse.kr(speed));

Out.ar(0, PMOsc.ar([freq, freq * 1.5],
[freq*ratio, freq*1.5*ratio],
index,
mul: env*0.5)
)}.play
)

// Variation. I love this example.

(
SynthDef("SH_PMv",
{|speed = 9|
var freq, latchrate, index, ratio, env, mix;
speed = 9;
latchrate = speed*LFNoise0.kr(1/10, mul: 0.03, add: 1.6);
index = Latch.kr(
LFSaw.kr(latchrate, mul: 5, add: 6),
Impulse.kr(speed)
);
freq = Latch.kr(
LFSaw.kr(latchrate,
mul: max(0, LFNoise1.kr(1/5, 24, 10)),
add: LFNoise0.kr(1/7, 12, 60)),
Impulse.kr(speed)
).round(1).midicps;
ratio = LFNoise1.kr(1/10, mul: 2.0, add: 5.0);

env = EnvGen.kr(Env.perc(0, LFNoise0.kr(speed, 1, 1.5)/speed), Impulse.kr(speed), LFNoise1.kr([5, 5], 2,
1).max(0).min(0.8));
mix = PMOsc.ar(
[freq, freq * 1.5],
freq*ratio, index, mul: env);
Out.ar(0, FreeVerb2.ar(mix.at(0), mix.at(1), 0.2, 0.6))
}).add;

SynthDescLib.global[\SH_PMv].makeWindow;
)


// Crotale
// Run this code first to define the instrument,
// then execute the "task" below as many times
// as you want.

(
SynthDef("crotale", {
arg param = #[500, 3, 2, 0, 6, 5, 0, 0.9];




209
var factor, env, out, freq, index, dur;
var bus, ratioa, ratiob, attack, decay, panCont;
freq = param.at(0); index = param.at(1); dur = param.at(2);
bus = param.at(3); ratioa = param.at(4); ratiob = param.at(5);
attack = param.at(6); decay = param.at(7);

env = Env.perc(attack, decay);
factor = gcd(ratioa, ratiob);
ratioa = div(ratioa, factor);
ratiob = div(ratiob, factor);

panCont = (EnvGen.kr(env, timeScale: dur*1.1,
levelBias: -1, levelScale: 2))
* (IRand(0, 1) * 2 - 1); // 0*2-1 = -1, 1*2-1 = 1

out = PMOsc.ar(
ratioa*freq, //or try ratioa*freqCont,
ratiob*freq, //or try ratioa*freqCont,
pmindex: EnvGen.kr(env, timeScale: dur,
levelBias: 1, levelScale: index),
mul: EnvGen.kr(env, timeScale: dur, levelScale: 0.3));

out = Pan2.ar(out, panCont);

out = out * EnvGen.kr(env, timeScale: 1.3*dur,
levelScale: Rand(0.1, 0.5), doneAction:2);
out = FreeVerb2.ar(out[0], out[1], 0.3, 0.5);
Out.ar(0, out); //Out.ar(bus, out);

}).add;
)

// Define the instrument by running the code
// above, then run this task to actually play
// the instrument.

(
r = Task({
var freq, indexDepth, indexRange, synthIndex, dur, repeat;
var next, count, countDown, offset, ratioa, ratiob, envs, env;
var range = 60, outBus = 0;
count = 0; countDown = 0; offset = 0;
envs = [[0, 0.9], [0.01, 0.9], [0.1, 0.8], [0.8, 0.01]];
repeat = Array.fill(10,
{[rrand(range, range+24).round(1).midicps, 3,
2.1 - exprand(0.1, 2.0), 0, 1, 1, 0, 0.9]});
next = Array.fill(10, {[3, 0.75, 0.5, 0.25, 0.125].choose});
freq = rrand(range, range*2); // these two are just starting points
indexDepth = 1;

inf.do({



210
if(countDown <= 0,
{
env = envs.choose;
next.put(count%10, [3, 0.5, 0.25, 0.125, 0.125].choose);
repeat.put(count%10, [
rrand(range, range + 24).round(1).midicps,
rrand(0.1, 12.0),
2.1 - exprand(0.1, 2.0), outBus, rrand(1, 12),
rrand(1, 12), env.at(0), env.at(1)]);
});

Synth("crotale").setn(\param, repeat.wrapAt(count));
next.wrapAt(count).wait;
if((count > 10).and(countDown <= 0),
{offset = countDown = [0, 3.rand, 6.rand].choose;
count = count - offset});
count = count + 1;
countDown = countDown - 1;
});
}).play(SystemClock);
)

::




211
Exercises
20:1 What are the AM sidebands of a carrier at 440 Hz and a modulator of 130?
20:2 List the first 10 upper and lower PM sidebands of a carrier at 400 Hz and a
modulator at 50?
20:3 Create a PM patch where the modulator frequency is controlled by an LFNoise1 and
the modulation index is controlled by an LFSaw UGen.
20:4 Create a PM patch using Latch sampling a random source mixed with a periodic
source. Add a control that adjusts the mix.
20:5 Create a PM patch where the carrier frequency, modulator frequency, and
modulation index are controlled by separate Dseq UGens (with arrays of different
lengths) but all using the same trigger.
20:6 Create a PM patch where the carrier frequency is controlled by a TRand, the
modulator is controlled by an S&H, and the index a sequencer, all using the same
trigger.
20:7 Pick your favorite patch and write a user interface. I double dog dare you.




212
21. Physical Models
Holy Grail of synthesis? Only at Apple.
The previous chapters have covered synthesis techniques in roughly chronological order:
Concrte, filtering, and FM. The goal for many developers right into the 90s was the practical
application of reproducing natural instruments. It's difficult to imagine a time when the only way
you could include a flute in your sound track was to hire a musician who played the flute. Today
it's nearly the opposite.
Chaos
The most recent advance toward natural instruments is sampling synthesis. Back in the
Moog/Arp/Steiner days I asked a professor why we couldn't just record a perfect piano note and
"somehow" (this was long before digital recordings) play that back each time a key is pressed.
He said it wouldn't work, and his reason was baffling, as we'll see, but he should have said
they've already done it; the Chamberlin and the Mellotron. The Mellotron is a keyboard
instrument that played recordings of actual instruments using the current technologyaudio
tape. It has an iconic sound, one of John Lennon's favorite toys, used first in Strawberry Fields
and up through the White Album.
Sampling synthesis is the next development after FM, and is now state of the art. There
are some interesting techniques (reversing the sample and playing both for a smoother sustain),
but not very useful to Concrte composers. Though the EXS allows voltage control, which is
useful, a sampler is generally intended for natural orchestration. Once the sample is loaded,
there's not much else you need to do. So this paragraph is all the treatment it will get.
As good as sampled instruments sound, most professionals can still hear the difference
between samples and real recordings. Why, after nearly 50 years of electronic music and
instrument design, do synthesized sounds, even samples of real instruments, fall short of natural
instruments? The baffling response from my professor was that we don't know what a real
instrument sounds like. What he meant was, it's impossible to select a single instance, one
recorded note, as a perfect representation of any instrument.
The beauty we see in the tonal quality of an instrument relies on chaos and change.
Vocalists work their whole lives to achieve a "perfect" tone. But what is a perfect sound?
Perfection is easy on a synthesizer. Raw wave formssine, saw, squareare perfectly
homogenous, and we hate them. They are so annoying that they make us want to leave a building
or get out of the way, as in a fire alarm or emergency vehicle siren (usually a square wave with a
saw, sine, or pulse LFO control). What, then, is a vocalist striving for? If a choral director's goal
were just homogeneity, then why not record just one strong performer 16 times? It worked for
Freddie Mercury. And it works for overdubs. But neither of these examples are the same. They
are close, but very different. If perfect homogeneity were the goal, you would simply duplicate a
single vocal track.
! What sampling and most synthetic models lack are complexity and chaos. An exact
duplication of a single note from any instrument, or reproducing a single vocalist is not a true
representation of that instrument or the potential of a choir, rather a single instance of many
possibilities. A single high-resolution digital photo of a leaf, duplicated hundreds of times, would




213
not look like a tree. All the leaves on a tree are different, and they change in real time. The same
is true for a piano. Each key has its own harmonic fingerprint. Even the same key when struck
successively will produce different strengths of partials depending on the position of the
vibrating string and body from the previous strike. There is no single perfect piano sound. That's
because the piano is not a sound. It's a systema generative system. Physical models change the
focus from the sound to the system.
Klank is a multi-band filter, but also a type of physical model. It has an array of
frequencies, amplitudes and decays. The difference, and secret, is the source of excitation; what
puts the process in motion. To illustrate, below is the Klank patch from earlier. This time there
are two sources of excitation; a Buffer filled with random numbers (which will be the same every
time) and an LFNoise run through an envelope (different every time). Move the mouse all the
way to the left for the truly random burst, to the right for the static buffer burst. The difference is
subtle, but important. The left side is modeled, the right is (or at least could be) sampledthe
same every time. The sonograms in Figure 22.1 show this difference. The right is uniform. The
left is different, and not just relative volume but in the resonance of each harmonic. There are six
harmonics. Compare the fundamental with the third just above 320 Hz. Sometimes the first is
louder, sometimes the third is.



Fig. 21-1 Chaotic vs. Static Excitation
21.1:: Sample vs. Modeled Bell
// Run these lines one at a time

b = Buffer.alloc(s, 40, 1); // create a buffer

// load it with random values
b.setn(0, Array.fill(40, {1.0.rand2}));

b.plot; // confirm it's noise-like

// listen
{PlayBuf.ar(1, b, trigger: Impulse.kr(1))}.play

//Compare to a true random burst


{PinkNoise.ar(EnvGen.kr(Env.perc(0, 0.001), gate: Impulse.kr(1)))}.play




214

(
{
var chime, freqSpecs, totalHarm = 10;
var staticBurst, randBurst, blend, burst, trig;
trig = Impulse.kr(1);
// Right side of screen sets static burst--a thing
staticBurst = PlayBuf.ar(1, b, trigger: trig)*0.2;
// Left side of screen sets random burst--a process
randBurst = PinkNoise.ar(EnvGen.kr(Env.perc(0, 0.0001), trig))*5;
blend = MouseX.kr(0, 1.0);
burst = (staticBurst * blend) + (randBurst * (1-blend));

freqSpecs = `[
{rrand(100, 1200)}.dup(totalHarm), //freq array
{rrand(0.3, 1.0)}.dup(totalHarm).normalizeSum, //amp array
{rrand(2.0, 4.0)}.dup(totalHarm)]; //decay rate array
Pan2.ar(
Klank.ar(freqSpecs, burst)
*MouseX.kr(0.1, 0.8), 0)
}.play
)

::


Karplus-Strong Pluck Instrument
An earlier chapter showed how a segment of an aperiodic wave becomes a periodic wave
by simply duplicating a millisecond sample just three times. The Karplus-Strong (named for
Alexander Strong and Kevin Karplus, the original developers) instrument achieves the same
effect using a delay. A burst of noise is released into an echo chamber. The repeating and
decaying echoes become a periodic wave.
CombL(in, maxdelaytime, delayTime, decayTime, mul, add) is the echo chamber. The
CombL takes, as a third argument, a duration (delay). When this delay is short enough we hear a
pitch that is the reciprocal of the duration. A duration of 1/100
th
of a second fits into a second
100 times, so it becomes a frequency of 100. The decaytime is how long it takes for the echo to
die away, and therefore creates a natural envelope. In the example below the delay time is
controlled by a Line.kr. It starts at a frequency of 1, which just sounds like noise. As the delay
shortens, a plucked pitch emerges. Once it settles into a steady state pitch, continue to listen and
confirm that each instance has a slightly different timbre, as if being plucked by an imperfect
human. Fig. 21-2 shows several of these wave forms back to back. Because the shape of each is
unique, they sound unique.





215

Fig. 21-2 Chaotic Pluck Waveforms

21.2:: Karplus-Strong with CombL
(
{
// Be patient
var burstEnv, freq, dec;
var out, delayTime=0.5, delayDecay=3;
freq = XLine.kr(1, 200, 30);
dec = 1/freq;
burstEnv = EnvGen.kr(Env.linen(0, dec, 0), gate: Impulse.kr(1));
out = LeakDC.ar(PinkNoise.ar(burstEnv));
out = out + CombL.ar(out, delayTime,
freq.reciprocal,
delayDecay);
Pan2.ar(out*3)
}.play
)

::
Pluck
The example above is just an illustration using CombL, which is intended for delay. Pluck
works the same way but includes a one-pole filter. The coefficient argument controls the filter
and corresponds with the amount of dampening, position of strike, and pickup of the vibrating
string. Negative numbers shorten the strike; anything below -0.8 is not a convincing pitch.
Values between 0 through 0.5 have a nice ring, above 0.5 sounds are dampened. Since Pluck is a
delay module it requires the maximum length to allocate a buffer efficiently. This example uses
reciprocal and midicps to convert human language (MIDI) into delay language (duration of each
vibration).
21.3:: Pluck

(
{
var trig;
trig = Impulse.kr(MouseX.kr(2, 20));
Pluck.ar(BrownNoise.ar(0.5), trig,



216
10.reciprocal, // lowest pitch you will use
TRand.kr([24, 48], [48, 72], trig).midicps.reciprocal, // actual pitch
2, // duration
// coef = dampening. Change to .at(1) to explore with mouse control
coef: [LFNoise1.kr([1/2, 1/3], 0.6, 0.4), MouseY.kr(0.8, -0.8)].at(0)
)
}.play
)
::
Ten years ago we were, like everyone else, a [big name DAW] school. I was asked to
look into Logic. After only two days I started a campaign to switch not just the music school, but
the workstations over the entire campus to Logic. Faculty and students, even those who doggedly
resisted, are now protagonists. There were quite a few impressive features, improvements over
[big name], but I started typing the memo the minute I saw the advanced synthesis techniques.
Logic Pro, as far as I have seen, is the only commercially available package that includes
physically modeled instruments.
The first advantage to physical models is a very natural sound. The second advantage is
only evident when working with a
Physical Model Interface
In the previous chapter we examined the EFM1. Figure 21.3 shows some of the control
parameters: modulator, carrier, FM depth, harmonic, modulation env, fixed, LFO, modulation
envelope, and so on. These are very cryptic terms. How, for example, will the sound change if
you adjust the FM depth? What about fixed vs. unfixed? The only way the average musician will
know what these mean is by either trial and error or reading up on FM synthesis and probably
reading the description for this particular instrument, since terminology isn't standardized.
Compare that with two interface components of Sound Sculpture. There are also some cryptic
parameters, but many are terms and items we recognize from real instruments; the vibrating
string, the pickup (a and b) position over the string, the location of the pluck (1, 2, and 3). The
second window allows you to choose the material that is vibrating. Most guitarist understand
how pickup and pluck position change sound, and nearly any musician understands the
properties of nylon, steel, wood and glass.
Fig. 21-3 FM vs. Physical Model


The question is, are
Physical Model Results
really differentbetter than sampling?




217
Figure 21.4 shows three audio graphs. These were generated from a MIDI track with
three copied and pasted notes to ensure consistency. They are split and stacked one per track so
you can compare the waves. The first is from the EVD3, a tone wheel organ. Confirm that each
wave has slight variations. I repeat, these are exactly the same pitch and velocity. The small
variations come from some random source of excitation. That is, it is not a sound, but a process.
The second example is the EVD6, where I include three cycles of the wave as well as
three identical MIDI events stacked in different channels. Note the differences in the vertical
waves (different events) but also the differences in each cycle of a single event (the horizontal
plane). For comparison, the last image is an EXS24 sampled electric piano. On the horizontal
plane there is variation. They fall short in the generative dimension; the stacked waves of
different events are precisely the same.


Fig. 21-4 EVD3, EVD6, EXS24 Waves

Sculpture (Modeling Synth)
is Logic's flagship modeling synth. Besides being modeled, it has revolutionary, novel
features you could spend years mastering. But you don't need to, because it is modeled, and a
brief overview (all I will do here) is enough to get started. You can read a more in depth
explanation of how inner loss and stiffness relate to the sound, but you know the differences
between wood, glass, metal, and nylon when struck or bowed.
As revolutionary as this instrument is, the layout is essentially the same as all the others
we've seen. The left side is the source of the sound, the VCO. Their literature calls it a string,
though it can function as a reed or buzzing lips. In fact, you see the animation of the vibrating
string each time a note is struck. It is different with each strike. In fact, it calculates the position
of the string from the previous event, and incorporates that state in the next event. The image of
the vibrating string has no effect on the sound, and can be turned off.
There are three of these objects (note the SCish terminologyobjects) that serve the
same function as oscillators in other synths. But this source has adjustments for strength, timbre,
and velocity sensitivity. Next is the type of excitationa pull down menu where you choose
strike, pick, blow, or bow, among others. Think of the objects as the names imply; a pick, a
finger, a violin bow, a column of air. There are two pickupsA and Bwith adjustable
positions along the string.



218
The materials (analogous to the filter section of other synths) are nylon, wood, glass,
steel. No further explanation needed. Drag the little ball. Done.
Keyscale deserves some discussion. It changes the sound as you move up the keyboard.
For example, you can have a metallic sound in the lower registers and a glass sound in the higher
pitches. Yes, you can read that sentence again. It's an amazing design feature. To test it, I suggest
you first generate some simple arpeggios over a few looped measures that span 6 octaves. Start
playback and explore the differences in overall material by dragging the grey ball. Then turn on
the Keyscale. Blue controls high ranges and green low. As the loop plays move one to wood, the
other to steel, then switch them.
Finally, adjust the tension, resolution, and media loss.



Fig. 21-5 Sculpture Interface
The VCA has a built in delay, EQ, and envelope, which you should recognize from
previous chapters. The filter defaults to low, mid, and high, as you might see on a mixer. Click
on the pull down menu to select the body of a familiar, real-world, physically modeled
instrument.
Take a second look at the Klank and Karplus-Strong instrument. The random noise
source in the first steady state Klank are similar to bowing or blowing. The burst in the other
examples is the excitation of a pluck or strike. The type of attack and decay of the burst define
it's character.
The resonant array is similar to the pluck, pickup position, and type of material. In the
Pluck UGen the coefficient performs the same function as the material section, adjusting media
loss, tension, and resolution.
While extremely sophisticated, Sculpture has a solid academic pedigree. It's the product
of a successful, visionary corporation teamed with music geeks who understand the
fundamentals of synthesisthe best of both worlds.
The lower section, as with other synths, has assignable controls; LFO1, LFO2, target,
source, etc. There is also a randomize button, but it's connected to what sets Sculpture's control
section apart; the Morph pad.




219


Fig. 21-6 Sculpture Controls
Morph does what you're hopingmorph between two slightly or radically different
sounds. Here is a simple illustration:
Find a preset with a sustained envelope (perhaps from the blown instruments, or
choose a non-blown instrument and choose blow as an excitation source) and no
Morph information (the red morph button should be in the
middle, as seen here).
Be sure Auto Select is on, and Pad is on.
Click on the center point, labeled 0 inside two circles. Glance up
at the string and filter sections. Parameters colored orange are
morphable. In Figure 21.5 the morphable parameters are orange.
Click on the morph point labeled A and note the changes in the
morph-able parameters. If they are not different, click the random button to make
them different. (All the ones I tried were different.)
Engage the caps lock keyboard, or use an external keyboard to play a sustained note.
While holding down the note, drag the ball from the center to position A. Note the
changes in the morph-able parameters and also the changes in the timbre.
Optional; try position B or C.
(If not selected, select Note + Mve in the Record Trigger pull-down
menu.) Press the R, play a note and move the red ball from point 0 to
A and back to 0. When you release the mouse recording stops. Play
another note. The morph will move to A, then return.
Jitter
is a chaotic noise source. (I used to call
them "fuzzy" parameters.) Select Jitter in the LFO
section. Click on the 1 on Jitter 1, select pitch as the
target and move the slider to the far + side (to see the
extreme effect). Return the slider closer to the middle,
which is where I think it was intended to be used; as a
subtle additional chaotic control.
Fig. 21-7 Jitter
Earlier we sent the audio of SC to Logic. It is also possible to link Logic to SC using



220
MIDI Input
can be used to play back a traditional work using an instrument you've designed in SC
(but see also the Score UGen), then record those events back in Logic. We can use the pluck
instrument, but it must be defined as a synth. See if you can do it on your own. You will need to
include arguments for the trigger, pitch (in MIDI), and duration. If this seems presumptuous, I
have a reason. Seriously, try it. I'll wait. The rest of this page is symbolic of passing time.




221
Here is where you probably got stuck (and this was my intention): the trigger. In previous
SynthDefs we embedded the triggers inside the definition. That is, once the synth is started it
generates triggers or gates that create events as it runs. MIDI driven instruments require a gate,
or a note on and a note off. Even if the envelope is a fixed duration, you need a trigger.
If you declare the trigger or gate as an argument, what do you use as a default value? If
you use 1, then .play will create a note, but the gate will never close and the event never stops. If
you set it to 0, then .play will not play a note, and Synth("Pluck", [\gate, 1]) will execute a single
note, but now gate is 1.
The first examples below illustrate this dilemma; first a synth with an internal envelope
and internal trigger. Once started, the triggers are supplied by the synth itself. The second uses a
fixed duration envelope, but how do you send a trigger then reset it to 0?
The answer is a trigger rate argument, which is identified with a preceding t_. Once
triggered, it will release automatically.
When working with a gate, you simply have to name the argument "gate." This identifies
it to the synth as a gate, and when you send the release message it closes the gate first.
21.4:: SynthDef and Triggers
(
SynthDef("InternalTrig", {
Out.ar(0, PinkNoise.ar(Linen.kr(Impulse.kr(1), 0, 1, 1)))}
).add
)

a = Synth("InternalTrig");
a.free;


(
// won't play because trigger is 0
SynthDef("ExtTrig?", { | trig=0 | // try 1
Out.ar(0, PinkNoise.ar(Linen.kr(trig, 0, 1, 1)))}
).play
)

Synth("ExtTrig?", [\trig, 1])
// Setting gate to 0 will not stop sound
Synth("ExtTrig?", [\trig, 0])

(
// t_ identifies first argument as a trigger
SynthDef("ExtTrig", { | t_trig=1 |
Out.ar(0, PinkNoise.ar(Linen.kr(t_trig, 0, 1, 1)))}
).play
)

Synth("ExtTrig", [\t_trig, 1]) // this starts the gate



222

(
SynthDef("ExtGate", { | gate=0 |
Out.ar(0, PinkNoise.ar(EnvGen.kr(Env.asr(0, 1, 1), gate)))}
).play
)

a = Synth("ExtGate", [\gate, 1])
a.release;

::
The Pluck instrument has a natural decay, so a trigger can be used. The name t_trig
identifies that argument as a trigger. Each new synth call reacts to the trigger value 1 and a pitch
is created. Since the Pluck decays on it's own (as part of the delay mechanism), you might
suspect that the Linen.kr at the end is redundant, therefore can be commented out, but we will
use it soon. First, let's set a process in motion using Task, which surrounds a do and adds this
important option: it can be paused with a wait message.
The first example illustrates the Task and also wrapAt. Remember that array.at(index)
returns the item at that position in the array. But p.at(5) will return nil because p has only 3
items. The wrapAt message wraps back to the beginning each time the number exceeds the size
of the array.
The next section defines the Pluck without an envelope, because it decays on its own.
The last section uses a Task to rotate through an array of pitches and octaves at different
multiples (sort of like, well, exactly like a sample and hold). If it's unclear how each value for
midi and oct are chosen, uncomment either line that monitors midi, ct1 and ct2. Likewise, define
the instrument, define the task, then run the line r.start. Just for giggles. Watch the server
internal window.
21.5:: Pluck and Task
// Run each line separately
p=["C", "D", "E"];
r=Task({20.do({|ct| [ct, p.wrapAt(ct)].postln; 1.wait;})})
r.start;
r.stop;

// Define Pluck. Do we need the envelope?

(
SynthDef("Pluck",
{
| t_trig=1, midi=60, dur=1, vel=0, pan=0, out=0 |
Out.ar(out,
Pan2.ar(
Pluck.ar(BrownNoise.ar(0.5), t_trig,
10.reciprocal, midi.midicps.reciprocal, dur, vel),
pan)) // * Linen.kr(t_trig, 0, 1, dur, 2)
}).add.play




223
)

( // Bach/Webern mutation
var wtk, octaves, op27;
r = Task({
// Try other versions
wtk = [12, 0, 2, 4, 2, 0, 7, 4, 12, 7, 4, 7, 5, 4, 5, 7, 0, 4, 7, 11];
op27 = [0, 8, 7, 11, 10, 9, 3, 1, 4, 2, 6, 5, 5, 6, 2, 4, 1, 3, 9, 10, 11, 7, 8, 0];
octaves = [60];
80.do({arg ct1;
wtk.size.do({arg ct2;
var midi, oct, pan;
midi = wtk.wrapAt(ct2);
oct = octaves.wrapAt(ct2);
pan = (midi + oct - 48)/18 - 1;
//[ct1, ct2, ct2*(ct1+1), midi, oct].postln
//if((ct1%20 == 19), {midi.postln}, {midi.post; " ".post});
Synth("Pluck", [\midi, midi + oct, \t_gate, 1, \pan, pan]);
0.1.wait;

});
if(ct1%4==3, {
octaves = octaves.add([48, 60, 72].choose).scramble;
wtk.put(ct1/4 - 1, op27.at(ct1/4 - 1));
wtk.postln; octaves.postln;
})
});
});
)

r.start;
r.stop;

::
Fig. 21-8 CPU Overload
I set you up for an error. The messages begin after
about 150 notes. Suddenly SC runs out of memory. You
should have noticed in the CPU and the number of UGens
steadily climb in the internal server windo. The reason is
each event is a new instance ("node"the number you see
reported in the data window when playing a synth) of the
synth Pluck. It is necessary to engage multiple instances of
Pluck since the time between each event (0.1) is shorter
than the duration of each event (the default of 1 second). One note continues to ring while the
next nine fires. The problem is each of those notes continues to run after they have stopped
sounding. They need to be freed. You could certainly write an elaborate system for keeping track
of each node, freeing them when they are done, but there is a simpler method. The last argument
for an envelope is doneAction. When set to 2, the action, when done, is to free the synth. (I use
envelope, though redundant, because it is more common in patches. See also DetectSilence.)



224
Uncomment the envelope, redefine the synth and run the task again. You don't have to redo the
Task section of code, just run the r.start line. Monitor the CPU and UGens to confirm that synths
are being released.
MIDI In
With trigger generated instrument definitions, external MIDI becomes useful. These
examples should work with an external keyboard. But you can also connect internal programs
such as a virtual keyboard or Logic to SC using the IAC driver. Use Audio MIDI Setup, Show
MIDI Window, double click IAC Driver and check Device is Online. In Logic, create an
External MIDI track and use the media library to connect to the IAC Driver. WARNING: do not
engage record on this track. This is difficult because any change you make will flip it on
automatically. Running the examples below with Logic and SC connected and record enabled
will lock up your system, possibly requiring a hard reboot. It is probably safest to import a MIDI
track, or record MIDI events into the track before linking the two. Then control click on the
track, select protect and click on the lock.
Run the following lines to initialize SC's MIDI connections then test for MIDI input.
You should see channel, midi, and velocity information posted to SC's data window. Assuming
you have already run the Pluck synthdef (with the Linen uncommented), run the final lines to
connect the MIDI input action to the Pluck synth. Now you can play this instrument from the
external MIDI equipment or the Logic track. It responds quite well to differences in velocity.
21.6:: Logic to IAC to SC to Pluck
// Only if the server is not already running

MIDIIn.connectAll;
s.latency = 0;

// Test midi input
MIDIIn.noteOn = {| src, chan, num, vel | [chan, num, vel].postln};

(
MIDIIn.noteOn = {arg src, chan, num, vel;
Synth("Pluck",
[\midi, num, \gate, 1,
\vel, 1 - (vel/127), \pan, (num/50) - 1])
// [chan, num, vel].postln;
};
)

::
Finally, come full circle by adding an audio track in Logic, connect SC's audio output to
Soundflower, Logic's input to Soundflower, and record what you play and SC realizes.
21.7:: Logic to IAC to SC to Logic
s.options.device_("Soundflower (16ch)"); s.reboot;





225
::
Exercises
21:1 Set up a track in Logic Pro and enter a single MIDI note using the pencil tool to
make sure it has default velocity. Option-drag it to reproduce it several timesthe
goal being precisely the same note, velocity, etc. Insert the EXS24 and bounce to an
audio file. Replace the EXS24 with any of the modeling synths. Choose a tame
preset; a mallet or keyboard instrument; one the ostensibly generates a consistent
sound. Bounce and open in Amadeus Pro to compare the sampled sound with the
modeled sound.
21:2 Combine the pluck example with a granular synthesis example from Chapter 15. For
each event, choose a random spot from the sampled file, but set the grain size to the
reciprocal of the MIDI pitch required. Use Logic to play this instrument.
21:3 Create a Sculpture instrument that morphs.
21:4 Import a short Bach MIDI file into a Logic session. Place all the regions on a single
track with Sculpture. Choose a relatively natural sounding instrument. Explore all
morphable parameters and choose one or two that have a clear effect on the
character. Set each of the morph pad locations so that each is clearly a different
instrument. Automate changing between positions so that the traditional Bach
blends between natural sounding instruments.




226
22. Additive Synthes..
es. Which is six syllables. So I split it up.
Harmonic Series
Density and tension being equal, short strings vibrate faster than long. A string that would
normally vibrate at 100 Hz, when divided in half (e.g. by pressing your finger on the finger board
at the half-way point) will vibrate at 200 Hz. If you shorten it to one third its original length, by
pressing your finger higher, it will vibrate at 300 Hz. Shortening it to one fourth generates a
frequency four times faster; 400 Hz. When touching a stringed instrument lightly at these points,
way we call the resulting frequencies harmonics, which are the foundation for the scale degrees
of Western music. With brass and woodwinds, a single finger position will also produce all of
these pitches, dependent on the amount of tension in the player's embouchure. Figure 22.1 shows
the pitches, MIDI values (and cents), and frequencies that form the harmonic series above C2.
Note the relation of harmonics to a C chord (fifths, thirds, lowered seventh, etc). Examine the
frequency row carefully to confirm they are multiples (65.4 * (1..16)). The MIDI row shows
midi number (but remember, this is also cents) to illustrate how our equal temper scale deviats
from the actual overtone series. The thirds are a little flat, as well as the flatted sevenths The two
most interesting are the 11
th
harmonichalfway between F and Fand the 13
th
, nearly halfway
between A and A. The SC code for calculating both frequency and MIDI is
(m.midicps * (1..n)).round(0.01).postln.cpsmidi.round(0.01) where m is MIDI number and n is
number of harmonics. For frequency; (f * (1..n)).round(0.01).postln.cpsmidi.round(0.01).
Fig. 22-1 Harmonic Series

Most strings (and musical instrument bodies) vibrate at their full length, but also in half,
thirds, fourths, and so on, simultaneously. (As an illustration, try wobbling a coiled headphone
cable up and down. At just the right energy, it will split in half, or thirds.) All strings therefore
have the potential to create any frequencies of the harmonic spectrum simultaneously. The
presence and strength of these harmonics defines timbre. Since each overtone is a sine. They
could theoretically be generated independently, with an oscillator for each. This is called additive
synthesis; adding together individual sines to create an aggregate sound. One might, for example,
examine the sonogram of a saxophone tone then build it from scratch. A chaotic element (such as
Jitter) could be included. While recreating natural sounds is an interesting application, the real
power of additive methods is its potential for surreal, unnatural, but stunning sounds. That's
because
Additive Synthesis
allows independent control over the parameters for each harmonic; greater control
than any other method of synthesis. Example 22.1 shows the simplest additive experiment;
SinOsc UGens tuned to multiples of 400. The result is a very sharp saw or pulse wave. The next




227
example adjusts each harmonic to a fractional amplitude. In natural instruments upper harmonics
are progressively softer. The second and third patch use Mix.fill to accomplish the same thing,
but with a Line.kr to present each harmonic one second apart.
22.1:: Additive Saw, Square

s.scope

(
{
SinOsc.ar(400) + SinOsc.ar(800) + SinOsc.ar(1200) +
SinOsc.ar(1600) + SinOsc.ar(2000) + SinOsc.ar(2400) +
SinOsc.ar(2800) + SinOsc.ar(3200) + SinOsc.ar(3600) +
SinOsc.ar(4000) + SinOsc.ar(4400) + SinOsc.ar(4800) * 0.4
}.play
)

(
{
SinOsc.ar(400, mul: 1) + SinOsc.ar(800, mul: 1/2) +
SinOsc.ar(1200, mul: 1/3) + SinOsc.ar(1600, mul: 1/4) +
SinOsc.ar(2000, mul: 1/5) + SinOsc.ar(2400, mul: 1/6) +
SinOsc.ar(2800, mul: 1/7) + SinOsc.ar(3200, mul: 1/8) +
SinOsc.ar(3600, mul: 1/9) + SinOsc.ar(4000, mul: 1/10) +
SinOsc.ar(4400, mul: 1/11) + SinOsc.ar(4800, mul: 1/12) * 0.4
}.play
)

(
{Mix.fill(18, {arg ct;
var amp;
amp = max(0, Line.kr(ct.neg, 1, ct + 1));
SinOsc.ar(100 * (ct+1),
mul: (1/(ct+1))*amp)}) * 0.6
}.play
)

(
// Square wave, odd harmonics
{Mix.fill(18, {arg ct;
var amp;
amp = max(0, Line.kr(ct.neg, 1, ct + 1));
SinOsc.ar(100 * (ct*2+1),
mul: (1/(ct*2+1))*amp)}) * 0.6
}.play
)

::



228
Fig. 22-2 Additive Saw Sonogram
Figure 22.2 shows the resulting sonogram. As
you listen, notice that each harmonic's entrance is clear;
you hear a sine tone, but within seconds it seems to
disappear. Yet the amplitude doesn't change. It simply
blends into the whole timbre. We notice the change, but
then interpret it as part of the overall sound. This
suggests that timbre is not a thing, but a result of
perception and interpretation.
Figure 22.3 is the plot from Example 22.2 which
spreads the sine waves across different output busses.
Press s to overlay the waves. The resulting image
illustrates how sines come into sync to create a saw wave.

=
Fig. 22-3 Additive Sine Scope
At the beginning of each phase all waves are pushing toward their peak. This is what
creates the sharp edge of a saw tooth wave. As the higher harmonics move into their downward
phase they begin to cancel out the energy of the lower harmonics. The aggregate of this process
is a gradually descending ramp of energy as more harmonics move into the negative phase of
their cycle. At the end of the pattern you see they are all more or less in the negative part of the
graph. This is the bottom of the saw wave. A nice visual would be swinging balls (search the net)
that all start at the same time, then because the attached strings are at different lengths, they
move out of sync. Eventually, however, they will again be in sync, and all pushing in the same
direction at the same time.

=
Fig. 22-4 Additive Sine, Random Phase
The graph in 22.3 requires that all phases match. The second and third example in 22.2
use a random phase. The phases no longer line up, as shown in Figure 22.4, and when mixed to




229
one channel no longer produce a clean, clear sawtooth. Curiously, we still hear a sawtooth.
Phase doesn't matter. Timbre is a matter of interpretation. Our brain supplies the details. Replace
Array with Mix to see the mixed wave.
22.2:: Additive Graph
(
// Saw spread across channels. Use 's' to overlay.
a = {Array.fill(16, {arg ct;
SinOsc.ar(400 * (ct+1), phase: 0,
mul: (1/(ct+1)))}) * 0.6
};
a.plot; a.play;
)

(
// With random phase
a = {Mix.fill(16, {arg ct;
SinOsc.ar(400 * (ct+1), phase: pi.rand,
mul: (1/(ct+1)))}) * 0.6
};
a.plot; a.play
)

::
The last two examples in 22.1 sound like a low pass filter with a narrow Q. But they are
not. It seems like a lot of work (and CPU) to achieve a saw wave with a filter sweep. The
difference is independent control. Example 22.3 adds a simple amplitude modulation to each sine
wave to illustrate the independent control. One might argue that this still could be accomplished
through sophisticated filters. So the next example adds a control that bends each harmonic
occasionally and independently. As far as I know, this harmonic structure can only be achieved
through additive methods, and I don't know any natural process that will produce such a sound.
Further, I don't know of any other software or hardware synthesizer that can produce it so
elegantly and precisely (12 lines of code).
I once found myself working on these examples at 30,000'. Flying is pretty common now,
but seeing the earth from that perspective is still a rare experience. I love to fly and spend most
of the time, even with cloud cover, staring out the window. I find the same fascination in these
examples. Of the 7 billion people on earth today, there are about 1000 that have heard this sound
(.00001%). It is surreal, artificial, and rare.



230

Fig. 22-5 Additive Saw Modulation
22.3:: Additive Saw Modulation
(
{
var rate = 14;
f = 150;
t = Impulse.kr(1/3);
Mix.fill(12, {arg ct;
Pan2.ar(SinOsc.ar(ct+1*f,
mul: max(0, LFNoise1.kr(rrand(rate, rate*2))/1)),
1.0.rand2)
})*0.1
}.scope(1)
)

(
{ // let it run a while
var rate = 6, globalBend;
f = 150;
globalBend = max(0, LFNoise1.kr(1/5, 0.7, -0));
t = Impulse.kr(1/3);
Mix.fill(12, {arg ct;
var bend;
bend = 1 + (globalBend * rrand(-1.0, 1.0));
Pan2.ar(SinOsc.ar(ct+1*(f*bend),
mul: max(LFTri.kr(1/10, mul: 0.3, add: 0.3), LFNoise1.kr(rrand(rate, rate*2))/1)),
0.2.rand2)
})*0.1
}.scope(1)
)

::
Try changing the value for rate, which controls the frequency of the LFNoise. Then try
replacing LFNoise1 with LFNoise0, LFSaw, or Pulse. Finally, replace f = 100 with f =
someOtherControl such as a sine wave, another LFNoise or a mouse. Add a line that will set
each rate to a random choice using rrand, or add a control to change the rate in real time. Save
your favorites as SynthDefs using arguments and an interface.




231
Syntax Shortcuts
Additive patches tend to be redundant. That's one of the reasons they are so difficult to do
with programs that are based on a GUI. (You know who you are.) You have to draw a line for
each component. If you want to change something, you have to redraw them. With code, a patch
can evolve quickly and radically by changing a single number. In addition to this efficiency,
code allows for syntax shortcuts. Having done a few examples, they will make more sense. Here
are a handful.
22.4:: Syntax Shortcuts
if (0<3) {\abc} {\def}

10.do {|x| x.postln };

(5, 7..21) do: {|x| x.postln; _.postln;}

// Duplicate

{1.0.rand} ! 20

100 ! 4

// Reference item in an array

[1, 2, 3, 4][0]

// Set item in an array

[1, 2, 3, 4][2] = 8

// Wrap at

30.do({|i| ([0, 1, 2, 3] @@ i).postln})

// Array range

[1, 2, 3, 4, 5, 6, 7][2..4]

[1, 2, 3, 4, 5, 6, 7][2..4] = 0

[1, 2, 3, 4, 5, 6, 7][..4] // = 0

[1, 2, 3, 4, 5, 6, 7][4..] // = 0

// Creating arrays

(1..20)

(1, 3..20)




232
(440, 880..3960)

// Synced triggers using shortcuts

( // original
{
Mix.ar([
SinOsc.ar(100, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(1/5))),
SinOsc.ar(300, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(2/5))),
SinOsc.ar(500, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(3/5))),
SinOsc.ar(700, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(4/5))),
SinOsc.ar(900, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(5/5))),
SinOsc.ar(1100, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(6/5))),
SinOsc.ar(1300, mul: EnvGen.kr(Env.perc(0, 1), Impulse.kr(7/5)))]) * 0.1
}.play
)

// Shortcuts

{Mix.ar(SinOsc.ar((100, 300..1300), 0, EnvGen.kr(Env.perc(0, 1), Impulse.kr((1..7)/5))))*0.1}.play

::
Inharmonic Spectra
! Harmonic spectra blend into a single pitch. Inharmonic spectra blend too, but into
metallic, non-pitched sounds. Few sounds fall neatly into one or the other category, but rather
along a continuous scale. The more harmonic, the more pitched.
The source waves for early synthesizers had two extremes: perfect waveforms or
complete noise. Modulation synthesis filled in the gap with complex relationships, but they were
still mathematically predictable. None of these earlier methods would allow a small combination
of completely unrelated frequencies. Klank can be used to filter a random set of frequencies, but
the envelopes of upper harmonics could not be controlled precisely. Additive synthesis is the
only system that can easily create truly inharmonic spectra. The results are metallic, non-pitched
sounds, but the method is reversed: Klank begins with a rich source and removes harmonics.
Additive synthesis builds the spectrum from scratch.
Inharmonic spectra are collections of frequencies that have no relationship with one
another; random, so to speak. Generating a set of unrelated frequencies requires an unpredictable
process, say, a shuffled deck of playing cards. For example, to get an even spread we could use
three cards per frequency, royalty and 10s add 1000. Here is the result of a trial I did with a real
life shuffled deck: [744, 2835, 1246, 188, 1895, 664, 2517, 2931, 1173, 6952, 1762, 293].
Example 22.5 mixes these together. The first has a metallic tone. The next adds an envelope, the
next independent decay times, and finally, an illustration of how quickly you can move from the
mundane to the surreal.
22.5:: Additive Inharmonic Spectrum
(
{




233
Mix.ar(
SinOsc.ar(
[744, 2835, 1246, 188, 1895, 664, 2517, 2931, 1173, 6952, 1762, 293],
mul: 0.1
))}.play
)


// With envelope and random frequency function

(
{
var e;
e = Linen.kr(Dust.kr(1), 0, 1);
Mix.ar(
SinOsc.ar(
{exprand(100, 1000)} ! 11,
mul: 0.1 * e
))}.play
)

// Still a little stiff, so add random decay rates.
// Similar to Klank, but opposite approach
(
{
var e;
e = Linen.kr(Dust.kr(1), 0, {rrand(2.0, 4.0)} ! 5);
Mix.ar(
SinOsc.ar(
{exprand(100, 1000)} ! 5,
mul: 0.1 * e
))}.play
)

// That's more natural, but the next two are surreal.
// You have to let it run for a while. The frequencies
// will bend and bubble up.

(
{
var e, m, h=8, t, bend;
t = Dust.kr(1/5);
bend = LFNoise1.kr(1/3);
m = Mix.ar(
Pan2.ar(
SinOsc.ar(
{LFNoise1.kr(1/12, max(0, bend)*200, exprand(200, 1000))} ! h, 0,
mul: max(0.1, LFNoise0.kr(8 ! h, 0.2, bend*0.4))),
{1.0.rand2*bend} ! h)) * 0.3;
}.play
)



234

// Same with harmonic spectrum.

(
{
var e, m, h=8, t, bend;
t = Dust.kr(1/5);
bend = LFNoise1.kr(1/3);
m = Mix.ar(
Pan2.ar(
SinOsc.ar(
LFNoise1.kr(1/12, max(0, bend)*200, (100, 200..(h*100))), 0,
mul: max(0.1, LFNoise0.kr(8 ! h, 0.2, bend*0.4))),
{1.0.rand2*bend} ! h)) * 0.3;
}.play
)

// As a bell. Run it several times

(
{
var mix, har=8, trig, bend, decays;
trig = Dust.kr(1/5);
bend = LFNoise1.kr(1/3);
decays = Env.perc(0, {rrand(3.0, 5.0)} ! har);
mix = Mix.ar(
Pan2.ar(
SinOsc.ar(
{LFNoise1.kr(1/12, max(0, bend)*200, exprand(200, 1000))} ! har, 0,
mul: max(0, LFNoise0.kr(8 ! har, 0.2, bend*0.4)) *
EnvGen.kr(decays, Dust.kr(1))),
{1.0.rand2*bend} ! har)) * 0.3;
mix;
}.play
)

::
The last two examples are unique to additive synthesis. When at rest, we hear a single
metallic timbre in the first example, a narrow pulse wave in the second, both panned center.
Amplitude, pitch, and pan position are being modulated by a combination of noise sources. The
key source is bend. A single LFNoise is passed through a max function that gates the signal at 0.
The LFNoise0 amplitude control is also passed through a max gate, but at 0.1. When the bend
value falls below 0, it has no effect, and we are left with a single, stable, quiet combination of
tones. When bend rises above 0, the values are applied to all three controls: the amplitude of the
LFNoise0, which in turn controls the amplitude of the sines, the amplitude of the LFNoise1,
which in turn controls the pitch of each sine, and finally the random pan position.
The variable h determines the number of sines in the patch. The arrays are being created
using several short hand methods: exprand(200, 1000))} ! h, 8 ! h, and {1.0.rand2*bend} ! h. In




235
the second patch, the harmonic series is created using (100, 200..(h*100))). The 8 ! h seems
redundant, but necessary to generate an independent LFNoise control for each sine oscillator.
These examples are perfect for investigating sections of code through selective
evaluation. The global variable h will retain it's value after the first execution so that snippets of
code that include h can be run in isolation: (100, 200..(h*100))) or 8 ! h. To further investigate,
you can set h to 1. This will reproduce a single sine wave. The complex controls will be easier to
hear. You might also try replacing all of the randomly generated arrays with static arrays.
Consider frequencies that match natural phenomena or astrological data (scaled, of course). Try
increasing the number of sines. You may need to reduce the final amplitude control: 0.3. Note
the amount of CPU for higher numbers of sines. What is the capacity of your machine? (Save
before trying!) This is the trade off for the complexity of additive control; high processor
demand.
See Celestial Bells in chapter 27 for another example of inharmonic spectra.
When harmonic waves are added together the pattern of the fundamental is preserved.
Adding or removing harmonics does not change the pitch, just the brightness. When random
waves are blended, the interference patterns are not in sync. They do not blend, but retain their
identities. As you add more and more waves, the sound progresses from bell to metal, then
machine gone berserk, and finally
Noise
Noise can be thought of as equal representation of all frequencies. We can test that theory
using an additive model. The first patch in example 22.6 introduces each new frequency in
random order. Notice that as with the saw example, when a pitch first appears it is easy to
identify. But the longer you listen, even though the pitch does not dissipate, it disappears,
blending into the whole. This is a matter of perception, not actual sound.
The next sorts the frequencies before generating the array of sines, so they are introduced
in order. The last uses PM synthesis to generate noise. Additive synthesis is CPU intensive. With
the efficiency of PM it approximates noise more closely with only 100 oscillators. Figure 22.6
shows sonograms of each.
22.6:: Additive Noise
(
{ // Watch the CPU
var h = 1000, a = 0, amp;
amp = Line.kr(0, h, 60);
Pan2.ar( Mix.fill(h,
{|c| SinOsc.ar(exprand(20.0, 22000.0)) *
min(max(0, c.neg + 1 + amp), 0.7)}
) * 0.01, 1.0.rand2)
}.play
)

// In order

(



236
{
var h = 200, a = 0, amp, freq;
amp = Line.kr(0, h, 60);
freq = ({exprand(20.0, 11000.0)} ! h).sort;
Pan2.ar( Mix.fill(h,
{|c| SinOsc.ar(freq[c]) *
min(max(0, c.neg + 1 + amp), 0.7)}
) * 0.1, 1.0.rand2)
}.play
)

// Using PM synthesis, more efficient. Compare CPU.

(
{
var h = 100;
Mix.fill(h,
{Pan2.ar(PMOsc.ar(exprand(1000.0, 3000.0),
exprand(1000.0, 2000.0), MouseX.kr(1, 50)), 1.0.rand2)}) * 0.05
}.play
)

::
Fig. 22-6 1000 Sines vs. 100 PM Osc's


White and Pink Noise
is distinguished by how the energy is distributed over the frequency spectrum. (See
also BrownNoise, ClipNoise, Crackle, Dust, Dust2, GrayNoise, Hasher, LFClipNoise,
LFDClipNoise, LFDNoise0, LFDNoise1, LFDNoise3, LFNoise0, LFNoise1, LFNoise2, Logistic,
MantissaMask, PinkerNoise, and Rossler)
Example 22.7 illustrates the difference between white and pink noise by filling two arrays
with random numbers. The first line picks numbers with a linear distribution between 100 (close
to an A2) and 1600 (A6). The second uses an exponential random function. Here is a sample
result from the linear function:
[ 128, 180, 186, 204, 289, 360, 364, 403, 404, 438, 445, 446, 579, 581, 598, 610, 697, 789, 855, 899, 916, 1026,
1053, 1059, 1073, 1138, 1152, 1191, 1191, 1224, 1262, 1292, 1299, 1308, 1417, 1433, 1478, 1496, 1578, 1579 ]




237
Ordered in 100s, it shows fairly even distribution:
Freq: 100s 200s 300s 400s 500s 600s 700s 800s 900s 1000s 1100s 1200s 1300s 1400s 1500s
3 2 2 5 3 2 1 2 1 4 4 4 1 4 2
But when arranged in octaves, there are nearly 7 times more in the last octave than the first:
Octaves: 100-200 200-400 400-800 800-1600
3 4 11 22
When compared to a sampling from the exponential function, the results are skewed to
the lower end, but when arranged in octaves, it's about equal.
[ 108, 120, 126, 144, 160, 164, 178, 185, 189, 193, 201, 223, 248, 249, 261, 298, 303, 314, 324, 349, 357, 379, 449,
524, 543, 570, 614, 684, 686, 716, 717, 763, 785, 958, 1030, 1169, 1191, 1385, 1404, 1571 ]
Freq: 100s 200s 300s 400s 500s 600s 700s 800s 900s 1000s 1100s 1200s 1300s 1400s 1500s
10 6 6 1 3 3 4 0 1 1 2 0 1 1 1
Octaves: 100-200 200-400 400-800 800-1600
10 12 11 7
! White noise has equal energy across the spectrum. Pink noise has equal energy (number
of frequencies) per octave band. In short; white noise is linear and has equal frequency
distribution, but sounds bright and thin. Pink noise(s) is exponential and has more lower
frequencies, but sounds natural and full. This is because though octaves are exponentially larger,
we hear them as being equal.
22.7:: Linear/White, Exponential/Pink
Array.fill(40, {rrand(100, 1600).round(0.1)}).sort.round(1) ;
Array.fill(20, {exprand(100, 1600).round(0.1)}).sort.round(1) ;
::
Additive Examples
always get my attention. They stand out in any composition. Here are some extra
examples of additive systems. Route them through Soundflower and then Amadeus' sonogram.
22.8:: Additive Synthesis Examples

(
{
var fund, trigger, sines = 16;
trigger = Dust.kr(3/7); // rate of triggers
fund = rrand(100, 400); // fundamental pitch
Mix.ar(
Array.fill(sines, {arg counter; var partial;
partial = counter + 1;
Pan2.ar(
SinOsc.ar(fund*partial) *
EnvGen.kr(Env.adsr(0, 0, 1.0, 5.0), trigger, 1/partial
) * max(0, LFNoise1.kr(rrand(5.0, 12.0))),
1.0.rand2)
})
)*0.5; //overall volume



238
}.play;

)

//Several of the above mixed down

(
{
var trigger, fund, flashInst, totalInst = 5, sines = 16;
flashInst = Array.fill(totalInst,
{
trigger = Dust.kr(3/7);
fund = rrand(100, 400);
Pan2.ar(
Mix.ar(
Array.fill(sines, {arg counter; var partial;
partial = counter + 1;
SinOsc.ar(fund*partial) *
EnvGen.kr(Env.adsr(0, 0, 1.0, 5.0), trigger, 1/partial) *
max(0, LFNoise1.kr(rrand(5.0, 12.0)))
})
)*0.2,
1.0.rand2)
});
Mix.ar(flashInst)*0.6
}.play
)

// Gaggle of sines varations

(
{
var harmonics = 16, fund = 50, speeds;
speeds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]/5;
Mix.fill(harmonics,
{ arg count;
Pan2.ar(
FSinOsc.ar(
fund * (count + 1),
mul: max(0, FSinOsc.kr(speeds.wrapAt(count)))),
1.0.rand2)
}
) / (2*harmonics)
}.play;
)

(
{
var harmonics = 16, fund, speeds;
speeds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]/20;
fund = (MouseX.kr(0, 36).round(7) + 24).midicps;




239
Mix.fill(harmonics,
{ arg count;
Pan2.ar(
FSinOsc.ar(
fund * (count + 1),
mul: max(0, FSinOsc.kr(speeds.choose))),
1.0.rand2)
}
) / (2*harmonics)
}.play;
)

// Use mouse to change fundamental

(
{
var harmonics = 16, fund;
fund = (MouseX.kr(0, 36).round(2) + 24).midicps;
Mix.fill(harmonics,
{ arg count;
Pan2.ar(
FSinOsc.ar(
fund * (count + 1),
mul: max(0, FSinOsc.kr(rrand(1, 1/3), mul: 20).softclip)),
1.0.rand2)
}
) / (2*harmonics)
}.play;
)

(
{
var harmonics = 16;
Mix.fill(harmonics,
{ arg count;
Pan2.ar(
FSinOsc.ar(
exprand(100, 2000),
mul: max(0, FSinOsc.kr(rrand(1/3, 1/6))*rrand(0.1, 0.9))),
1.0.rand2)
}
) / (2*harmonics)
}.play;
)



// Dissipating and converging gongs illustrates how a patch can be built
// from duplicating one idea; classic additive synthesis. It also shows
// how additive synthesis can be used to control each harmonic.
// Listen in stereo to hear the harmonics diverge.



240

(

{
var dur = 6, base, aenv, fenv, out, trig;
base = Rand(40, 100);
trig = SinOsc.ar(1/10);
out = Mix.fill(15,{
var thisDur;
thisDur = dur * rrand(0.5, 1.0);
aenv = EnvGen.kr(Env.perc(0, thisDur), trig);
fenv = EnvGen.kr(Env.new([0, 0, 1, 0], [0.25*thisDur, 0.75*thisDur, 0]), trig);
Pan2.ar(SinOsc.ar( Rand(base, base * 12) *
LFNoise1.kr(10, mul: 0.02 * fenv, add: 1), // freq
mul: aenv // amp
), ([1, -1].choose) * fenv)
}) * 0.05;
out
}.play;
)

(
{
var dur = 6, base, aenv, fenv, out, trig, detune;
base = Rand(40, 60);
detune = 0.1; // increase this number to detune the second bell
trig = SinOsc.ar(1/10, pi);
out = Mix.fill(15,
{ arg count;
var thisDur;
thisDur = dur * rrand(0.5, 1.0);
aenv = EnvGen.kr(Env.perc(0, thisDur), trig);
fenv = EnvGen.kr(Env.new([1, 1, 0, 1], [0.05*thisDur, 0.95*thisDur, 0]), trig);
Pan2.ar(SinOsc.ar( base*(count+1+ detune.rand) *
LFNoise1.kr(10, mul: 0.02 * fenv, add: 1), // freq
mul: aenv // amp
), ([1, -1].choose) * fenv)
}) * 0.05;
out
}.play;
)

// Decaying bell

(
{
var aenv, fenv, out, trig, dur, base;
dur = rrand(1.0, 6.0);
base = exprand(100, 1000);
trig = Impulse.kr(1/6);
out = Mix.ar(




241
Array.fill(15,{
arg count;
var thisDur;
thisDur = dur * rrand(0.5, 1.0);
aenv = EnvGen.kr(
Env.new([0, 1, 0.4, 1, 0], [0, 0.5, 0.5, 0]), trig,
timeScale: thisDur);
fenv = EnvGen.kr(
Env.new([0, 0, 0.5, 0.5, 0], [0.25, 0.5, 0.25, 0]),
trig, timeScale: thisDur);
Pan2.ar(SinOsc.ar( Rand(base, base * 12) *
LFNoise1.kr(10, mul: 0.1 * fenv, add: 1), // freq
mul: aenv // amp
), ([1, -1].choose) * fenv)
})
) * EnvGen.kr(Env.linen(0, dur, 0), Impulse.kr(6), timeScale: dur,
levelScale: 0.05, doneAction: 2);
out*0.3;
}.play;
)
::
This concludes our discussion of synthesis methods. They all have individual characters,
strengths and weaknesses. Below is a summary.
Synthesis Review
Character (pro, con) Logic Instruments, SC UGens
Concrte Rich sounds, interest comes through context, often clich,
but also ubiquitous
UltraBeat, EXS24, PlayBuf
Filtering Synthetic, Sci-fi, dated, but also classic, ubiquitous ES's (ES1, ES2), RLPF, Klank
FM/PM Complex spectra, metallic, bells, implementation is
difficult to grasp, dated?
EFM1, RingShifter, PMOsc
Sampling Natural, hard drive space EXS24
Models Real, but also can be surreal, rare, cpu intensive EVB3, EVD6, EVP88, Sculpture, Klank
Additive Surreal, distinctive, cpu intensive, implementation None (Mix.fill? and SinOsc?)



242
Exercises
22:1 Write a patch with 100+ additive sines that use the same envelope so that they are
heard as a single sound. Begin with an inharmonic spectrum that gradually tunes to
another inharmonic spectrum with only 5 additive sines. Don't fade them out, detune
them to the next set of frequencies.
22:2 Write a bell patch with 10 sines that begin with one set of inharmonic frequencies
then gradually morph to another set, then another set. Be sure the control remains on
one set long enough for the frequencies to gel into a bell sound.





243
23. K and A Busses
Auxiliary Routing, just like in Logic.
SynthDef's are little synthesizers; virtual modules that generate audio. Once sent to the
serverlike real hardware devicesthe virtual internal wiring can't be changed. A sine
oscillator with a random LFO control will always be a sine oscillator with random LFO control.
Using arguments allows you to change parameters, maybe the speed of the LFO, but not the
routing, that is, you can't change it to a periodic LFO.
To change the control source to something else, an LFNoise1, a sequencer, or Latch, we
would have to rewrite the patch with those controls; build a new box, so to speak. A modular
approach would be more efficient, that is build the LFNoise0, LFNoise1, and Latch controls as
separate units from the SinOsc, then patch any of them at execution or after. SC3's architecture
was designed with this in mind. It allows you connect separate patches together using
Audio and Control Busses
Out.ar, Out.kr, In.ar, and In.kr connect inputs and outputs via busses. The kr is for
control rate signals, the ar is for audio rate. By default, there are 128 audio busses and 4096
control busses. Think of them as a snake or patchbay with 128 patch points and another
completely separate snake with 4096 patch points numbered 0 through 127 and 0 through 4095.
Like a patchbay, there are some default connections. On most systems the audio busses 0 and 1
are routed to the left and right channel output of your hardware (computer sound out). Confirm
this with {Out.ar(0, SinOsc.ar)}.play and {Out.ar(1, SinOsc.ar)}.play. Input busses are a little
more complicated, so SoundIn was created to simplify the connections. We used this in the
filtering chapter.
In previous chapters the output of SC was sent to SoundFlower, which was routed to
Logic Pro. With this connection a stereo patch could be routed to [0, 1] which corresponds with
1 and 2 in Logic, [2, 3] = 3, 4 and so on. (If this mismatch irritates you as much as it does me,
you can open Options/Audio/I/O Labels and rename Logic's inputs 00, 01, 02, etc. Not very
satisfying, but resistance is futile. Be sure to change both the mono name and stereo pair names.)
Like Logic, SC can use busses to route signal to sub masters or to auxiliary sends. Similar to the
patch bays and LFO controls in Logic, control buses can be used to route control sources to
different destinations of the same synth, or different synths altogether.
Example 23.1 should be familiar. It connects the output of SC to the input of Logic so
that you can clearly monitor the routing experiments. The first six lines are all sent to a sub
master 2 and 4, the next three to 4 and 5. (Note that when the patch generates a stereo signal the
single argument 2 and 4 is expanded to [2, 3] and [4, 5].)
The last line uses In.kr to gather the signals from both sub masters ([2, 3], [4, 5]) and
send them to out 0 (therefore [0, 1]). Important note: order of execution matters when setting up
chains of signal. The rule is: destinations first. So the last line in this example must be executed
before the lines above it. This seems backwards, and I realize it might make more sense place it
at the top before the oscillators, but I leave it at the end to reinforce that order is critical, and the
opposite of what you might expect.



244
Before running these lines, open Logic and before opening a session open preferences
and set the input source to Soundflower. Be sure to set the output to anything but SoundFlower,
or you will get a feedback loop. Double check this. My experience is that when you change input
or output to Soundflower, it sets the other to Soundflower also, even if you had something else
selected. Start a new session. Choose Ascending and the inputs will be assigned automagically.
Also select input monitoring. Create 6 stereo tracks with inputs set to 1/2, 3/4, 5/6, etc.
Here is what you should be listening for and watching the inputs in Logic for: Each line
has a SinOsc with a unique and easily distinguishable control. The first line will send the signal
to out 0 only (1 in Logic, left channel of track 1) because it is a mono patch. The next will send
signal to 0 and 1 because it is a stereo patch. The third line sends signal to out 1 (2 in Logic, right
channel of track 1). The next three do the same with outs 2 and 3. You should hear and see each
appear in the respective tracks of Logic.
The last line uses In.ar to gather all of these signals and route them to out 4 (and 5) as a
sub-master. The first time you try this the sub-master won't work, because I've ordered them with
the sub-master line last. Run them in that order, the sub-master last, to confirm that the sub-
master does not send any signal to Logic's inputs 5 and 6. This is because it was executed after
the signals it is supposed to receive. Remember: destinations must always be executed first. Stop
playback and reverse the order. Run the last line, which sets up signal routing from 0, 1, 2, and 3,
to 4 (and 5), then run the sources above to confirm that signal is now present in the individual
tracks and the sub-master 4-5 (5/6 in Logic).
23.1:: Busses as Sub Masters

s.options.device_("Soundflower (16ch)"); s.reboot;
// s.options.device_("JackRouter");

// Run these one at a time

{Out.ar(0, SinOsc.ar(1000, mul: LFPulse.kr(12))*0.1)}.play;
{Out.ar(0, SinOsc.ar(3000, mul: LFPulse.kr([4, 5]))*0.1)}.play;
{Out.ar(1, SinOsc.ar(4000, mul: LFPulse.kr(2))*0.1)}.play;
{Out.ar(2, SinOsc.ar(LFSaw.kr(4, 0, 1000, 2000))*0.1)}.play;
{Out.ar(2, SinOsc.ar(LFSaw.kr([1/3, 1/4], 0, 200, 300))*0.1)}.play;
{Out.ar(3, SinOsc.ar(LFSaw.kr(2, mul: -400, add: 500))*0.1)}.play;

// First try running this last, stop, then run it first.

{Out.ar(4, In.ar([0, 1]) + In.ar([2, 3]))}.play // Sub-master

::
You wouldn't normally route all these signals to Logic in this way. In fact, there isn't
much reason to use busses as sub-masters. But they are useful as
Auxiliary Sends.
Example 23.2 adds a delay to each of the examples above. Run the ControlSpec line only
if you haven't defined these specs previously. Each SynthDef will define a simple SinOsc with an




245
easily distinguishable control. They are not that interesting, kind of tacky, actually, precisely so
that you can keep track of them.
Each synth is defined, added to the library, then a window for controlling that synth is
created. They will be on top of each other. Rearrange them and start each. Notice each is being
sent to a different output bus, so they should appear in different tracks in Logic.
23.2:: Three Simple Independent Synths

(
ControlSpec.specs.addAll(
[
\speed -> ControlSpec(0.1, 24, \lin, 0.1, 6, " speed"),
\fadd -> ControlSpec(60, 20000, \exp, 1, 440, " offset"),
\fmul -> ControlSpec(1, 2000, \lin, 1, 100, " scale"),
]);
)

(
SynthDef("BusEx1",
{ arg speed=1, fmul=500, fadd=2000, out = 0;
var mix;
mix = Pan2.ar(
SinOsc.ar(LFSaw.kr(freq: speed, mul: fmul, add: fadd)),
LFNoise1.kr(1));
mix = mix + CombL.ar(mix, 1.0, [0.4, 0.6], 1);
Out.ar(out, FreeVerb.ar(mix, LFNoise1.kr(1)*0.5+0.5, 0.6)*0.5)
}).add;
SynthDescLib.global[\BusEx1].makeWindow;

SynthDef("BusEx2",
{ arg speed=1/3, fmul=200, fadd=400, out = 2;
var mix;
mix = Pan2.ar(
SinOsc.ar(SinOsc.kr(freq: speed, mul: fmul, add: fadd)),
LFNoise1.kr(1));
mix = mix + CombL.ar(mix, 1.0, [0.4, 0.6], 1);
Out.ar(out, FreeVerb.ar(mix, LFNoise1.kr(1)*0.5+0.5, 0.6)*0.5)
}).add;
SynthDescLib.global[\BusEx2].makeWindow;

SynthDef("BusEx3",
{ arg speed=4, fmul=200, fadd=800, out = 3;
var mix;
mix = Pan2.ar(
SinOsc.ar(LFPulse.kr(freq: speed, mul: fmul, add: fadd)),
LFNoise1.kr(1));
mix = mix + CombL.ar(mix, 1.0, [0.4, 0.6], 1);
Out.ar(out, FreeVerb.ar(mix, LFNoise1.kr(1)*0.5+0.5, 0.6)*0.5)
}).add;



246
SynthDescLib.global[\BusEx3].makeWindow;
)
::
When working with Logic we learned that serial reverbs and delays are inefficient for
two reasons: each reverb uses CPU, and they have to be controlled and modified independently.
That is, if you wanted to change the depth of the virtual room, you will have to make the change
in each patch (that is, provided you want them all to be in the same space). All of the previous
examples have a delay and reverb built into the patch; a serial reverb, so to speak. The next
example rewrites both patches without the reverb or the delay. Instead, both effects are defined
as synths on their own with a bus input. For clarity I've declared the variables ~reverbBus and
~delayBus as 15 and 16. This simply allows me to use a name rather than a number for each bus,
which is less confusing.
Each of the instruments below are defined as synths, and opened using makeWindow. In
this case the order of execution doesn't matter, because the window for each has a start button.
The order in which you press the start buttons does matter. You have to start the reverb and delay
first. Otherwise the other synths will not reach those destinations.
The routing happens in the last few lines, the Out.ar statements. These are analogous to
the main output and the auxiliary sends in Logic. The first Out.ar sends signal to bus 15
(~reverbBus), the second to 16 (~delayBus). The last routes the dry signal to out 0.
For clarity, you might want to switch to the sclang and close all the previously created
windows.
23.3:: Auxiliary Send Using Out and In

~reverbBus = 15;
~delayBus = 16;

SynthDef("Delay", {arg lDelay = 0.3, rDelay = 0.5, audioBus = 0, amp = 0.6;
Out.ar(audioBus, CombL.ar(In.ar(~reverbBus), 4.0, [lDelay, rDelay], 4)*amp);
}).add; SynthDescLib.global[\Delay].makeWindow(w);

SynthDef("Verb", {arg delay = 0.6, audioBus = 0, amp = 0.6;
Out.ar(audioBus, FreeVerb.ar(In.ar(~delayBus), 1, delay)*amp);
}).add; SynthDescLib.global[\Verb].makeWindow;

SynthDef("Blip",
{ arg amp = 0.6,
send1 = 0.5, send2 = 0.5;
var mix;
mix = Pan2.ar(
SinOsc.ar(LFNoise0.kr(12, 300, 800), mul: LFPulse.kr(freq: 1/2, width: 0.1)),
LFNoise1.kr(1));
Out.ar(~reverbBus, mix*send1); // reverb send
Out.ar(~delayBus, mix*send2); // delay send
Out.ar(0, mix * amp); // dry mix
}).add;




247
SynthDescLib.global[\Blip].makeWindow;

SynthDef("PMBlip",
{ arg amp = 0.6,
send1 = 0.5, send2 = 0.5;
var mix;
mix = Pan2.ar(
PMOsc.ar(300, LFNoise1.kr(1, 100, 300), 7, mul: LFPulse.kr(freq: 1/2, width: 0.1)),
LFNoise1.kr(1));
Out.ar(~reverbBus, mix*send1);
Out.ar(~delayBus, mix*send2);
Out.ar(0, mix * amp);
}).add;
SynthDescLib.global[\PMBlip].makeWindow;

::
Once executed, you should see four windows. Again, they are on top of each other. The
windows with amp and send1 sliders are the two synths. The one marked delay only is the
reverb, the LDelay and RDelay is the delay.
Start the delay and verb synths first, then launch the PMBlip and Blip. Adjust the controls
to confirm that send1 is routed to the delay and send2 is routed to the reverb. Adjust the
amplitude or delay times of each component. On the delay and reverb change the AudioBus to
something other than 0. This will route the output to a track other than 1 and 2 in Logic.
Of course, having routed these examples to Logic you have access to all the on board
delays and reverbs, making this example a bit academic.
Control Busses
can be used to swap patching between different control sources. The next example
first creates a synth with controls only. The first is an LFNoise sent to control bus 25, the next is
a simple Saw sent to 26, then a Latch, similar to what we used with phase modulators, then a
demand sequence, and finally a phase modulator.
The second synth definition is the receiving synth. It is a playback buffer with a single
control for speed (and direction). The control is linked to one of the busses 25 through 28 using
In.kr. All of these are accessible from the newly created synth window because we have defined
the arguments as control specs, or we have chosen arguments that already have control spec
definitions. For that reason some may not make sense, for example the second argument of the
PMOsc is "rate", but it's actually the modulator. The control specs for rate happen to be in the
correct range.
Run the first two lines to load a buffer, then play it just to make sure it loaded correctly.
Run the final group, which will create two windows: one is the control, the other is the synth.
There is only one slider on the control synth. It is used to change the rate of all of the controls.
I've done this as a matter of convenience. In an actual composition you would probably want to
create more elaborate arguments.



248
Select a different control source by changing the controlBus parameter. You can use the
slider, but it is more accurate to just click on the number box and use the up and down arrows to
switch busses.
Note that you can also control the output buss of the buffer synth. You should see it
appear in different tracks of logic. These examples are routed to output 0 and 1. If you are still
using Logic, be sure you are using stereo tracks, or if mono tracks, pan track 1 hard left and track
2 hard right for the stereo effects.
23.4:: Control Busses

// Load an audio buffer
~playBuf = Buffer.loadDialog;

// Check playback
{PlayBuf.ar(1, ~playBuf.bufnum, 1, loop: 1)}.play

(
// Create the controls synth, each routed to a different control bus
SynthDef("Controls", {arg rate = 1;
Out.kr(25, LFNoise0.kr(rate));
Out.kr(26, LFSaw.kr(rate));
Out.kr(27, Latch.kr(LFSaw.kr(25), Impulse.kr(rate)));
Out.kr(28, Demand.kr(Impulse.kr(rate), 0,
Dseq(Array.fill(12, {rand2(1.0)}), inf)));
Out.kr(29, PMOsc.ar(60, rate, 7))
}).add;
SynthDescLib.global[\Controls].makeWindow.bounds_(Rect(20, 400, 440, 120)).name_("Controls").front;


// Start the playback synth
SynthDef("Buffer",
{ arg kbus25 = 25, out = 0, loop = 1;
var mix, kontrol, trig;
trig = Impulse.kr(loop);
kontrol = In.kr(kbus25) * 2;
mix = PlayBuf.ar(1, ~playBuf.bufnum, [kontrol, kontrol.neg], loop: loop);
mix = mix * EnvGen.kr(Env.linen(0.1, 0.8, 0.1), trig, timeScale: loop);
Out.ar(0, mix);
}).add;
SynthDescLib.global[\Buffer].makeWindow.bounds_(Rect(20, 600, 440, 120)).name_("Buffer").front;

)

// Additional example using modeled0 bells. With a random trigger, you may have to wait a while.
// Don't turn the volume up!

// Start the Delays (destination) first.
(
SynthDef("Delays",




249
{var delay1, delay2, delay3;
delay1 = AllpassN.ar(In.ar(37, 2), 2.5, // input from 37
[LFNoise1.kr(2, 1.5, 1.6), LFNoise1.kr(2, 1.5, 1.6)],
3, mul: 0.8);
// input from 38
delay2 = CombC.ar(In.ar(38, 2), 0.5, [Rand(0.2, 0.5), Rand(0.2, 0.5)], 3);
// input from 39
delay3 = Mix.arFill(3, { CombL.ar(In.ar(39, 2), 1.0, LFNoise1.kr(Rand([0.1, 0.1], 0.3), 0.4, 0.5), 15) });
Out.ar(0, [delay1 + delay2 + delay3]);
}).load;
SynthDescLib.global[\Delays].makeWindow.bounds_(Rect(20, 600, 440, 120)).name_("Delays").front;

)

// Then start as many bells as you like.
// Use the sends to route each bell to a delay.
(
SynthDef("Bells",
{arg send1 = 0.6, send2 = 0, send3 = 0, rate = 0.3;
var mix, delay, freq = 100;
mix = SinOsc.ar(freq, mul: 0.5)*EnvGen.kr(Env.perc(0, 0.01), gate: Dust.kr(rate));

mix = Pan2.ar(Klank.ar(`[Array.fill(10, {Rand(500, 5000)}),
Array.fill(10, {Rand(0.01, 0.1)}),
Array.fill(10, {Rand(1.0, 6.0)})], mix), Rand(-1.0, 1.0));

Out.ar(0, mix*1); //send dry signal to main out
Out.ar(37, mix*send1); //auxiliary send to bus 37
Out.ar(38, mix*send2); //to 38
Out.ar(39, mix*send3); //to 39
}).load;

SynthDescLib.global[\Bells].makeWindow.name_("Bells: start after Delays!").front;
)

::




250
Exercises
23:1 Continue to develop the last example by adding additional control sources. Create
additional synths with output routed to control busses, then connect those controls
using In.kr in the destination synth.
23:2 Combine the two examples by routing the output of the playBuff synth to auxiliary
busses connected to the reverb and delay synths.





251
24. On Random Numbers
We used to use the I Ching, before computers.
Computers Cannot be Random
They only do what you tell them, nothing more, nothing less. With the power and
sophistication of voice recognition and speech, it's hard not to characterize an unexpected and
perplexing crash as random. But data is just 0s and 1s. It's very simple. Every single bit is one or
the other. They only change if you change them. If something's wrong it's because someone gave
bad instructions; 0s where 1s should be. Many times during a semester I say "the computer picks
a random number." For nearly fifteen years no one objected. Then one smart aleck pointed out
the paradox in my statement: "How," he asked, "can a machine do anything random?"
It's true. A CPU can no more act randomly than a chair, or more aptly, a printing press.
(Computers are, in a sense, a versatile printing press; more flexible, but an even simpler platform
nonetheless.) The only way to get random numbers from a printing press would be to write down
a long list of random numbers on paper, typeset them, and print them. Odd as that sounds, it's
been done, by the RAND Corporation back in the 50s. The book is called A Million Random
Digits and it contains, no kidding, a million random digits. Why? The forward explains:
For cryptography, game playing, sociological surveys and various
scientific calculations, people often need a series of numbers that are
devoid of pattern. And that is a tall order. Generating true randomness
is one of computer science's most difficult challenges. George
Johnson, "Connoisseurs of Chaos Offer a Valuable Product:
Randomness," New York Times, June 12, 2001.
The reviews at Amazon underline the absurdity of such a text. Some offer corrections,
others give spoiler alerts, one is written entirely in digits, there are suggestions that it be
translated into German or the original binary or made into an audio book, that the numbers
would be easier to find if sorted, complaining that there are only 10 random digits (0 through 9),
and my favorite dismisses all the previous reviewers, claiming they have missed the point; that
the entire volume is allegorical.
Entertaining, but serious, and essential for its time and yes, it is a 600-page hardbound,
printed-on-real-paper book filled with random numbers, used by scientists to do random studies.
(Before that we, and by we I mean the Chinese, and by before that I mean 3 million years BC by
some accounts, used the I Ching or Book of Changes.)
Fig. 24-1 A Million Random Digits (Excerpt)
I have both hard and soft copies of A Million Random
Digits. Here are a few numbers from the first page:
[23209, 02560, 15953, 34764, 35080, 33606,
99019, 02529, 09376, 70715, 38311, 31165,
88676, 74397, 04436, 27659, 12807, 99970,
80157, 36147, 64032, 36653, 98951, 82956]
They do indeed seem random, and when graphed look very



252
similar to a noise wave (Figure 24.1). There is no apparent pattern.
Random, maybe, but useful? Not any more. Once I've shown this series they must be
discarded. If I ever use them again they become perfectly predictable. We learned this with our
experiments on periodic waves. Any set of numbers becomes music when repeated. Repetition
negates randomness. Figure 24.2 shows the same numbers repeated six times. The pattern is
clear. The wave is periodic, and would produce pitch.
Fig. 24-2 When Repeated, Not Random
The obvious solution: turn to a different page.
But the conundrum continues. Those numbers can never
be used in that order again. The truth is A Million
Random Digits is not at all random. If I memorize the
first number of page 431 I can predict it every time. I can
predict what your copy of the book says at page 431. It's
the same every time and every copy of the text is exactly
the same. As one Amazon reviewer remarks, it's the
opposite of random, it's exactly the same. To be truly
random the text should show different numbers on the
first page each time it's opened. The title should be A Million of the Same Digits but That Seem
Random if You Don't Memorize Them. I'm sure they considered it, but it wouldn't fit on the spine.
Randomness is elusive. Like subatomic particles, it evaporates once observed.
The solution is a random method for choosing a page from the random number book.
How about this: get two books and use the first to decide which page to use in the second. Or
maybe riffle through the pages and have a colleague point. But then you would bias toward the
middle of the text. Smart alecky student is still waiting for an answer. You could build a big
rolodex machine that continuously riffles through all the pages without beginning or end and at
the moment you need a random number turn it off and that's where you start. Less cumbersome,
same results; use a stopwatch showing tenths of a second, resetting every minute. When you
need to start a random process, hit lap and start on that page: 45.1" = page 451.
A Million Random Digits is more than a curious side note. Each time you boot up a
computer it creates a virtual rendition of A Million Random Digits using a
Random Number Generator
Like the text, it is always the same, every boot, every time it is invoked it produces the
same series of numbers every time. Furthermore, computers with the same operating system use
the same algorithm. In a very literal sense your computer generates a copy of a text containing
34,359,738,352 random digits when it starts up. (That's 34 billion.) Take that RAND.
! It has the same problems. It's not random. If you start at the beginning of the sequence it
will return precisely the same set of numbers. Yes, you can start in the middle, but if you pick the
same spot every time the numbers will be the same. As with the text, it's the opposite of random.
It is absolutely predictableif you know the algorithm.
To illustrate what I mean by "knowing the algorithm," imagine this method for shuffling:
start with a fresh deck of cards, split in half and alternate exactly one from each pile in turn,
repeat four times. The final shuffled deck will have a perfectly predictable order. The top five




253
cards will be a great poker hand: four aces and a king of spades. The only difference between a
real shuffle and a carefully orchestrated one is a human's grasp of the process. If I were able to
use this method without others knowing it, they would think the deck was randomized, when I
would know it is not. What random really means is mixed up to the point where a particular
human can't see the pattern nor predict the outcome. Randomness then is a matter of context and
perception. We decide a number is random not if it corresponds with the numbers that came
before or after but rather whether we can see any correspondence.
To ensure the shuffle was not orchestrated fellow poker players cut the deck, just as we
might rolodex through A Million Random Digits. This is called a
Random Seed
In Example 24.1 ten arrays are filled with random numbers. Just before they are filled,
the seed is set to 0. This means the numbers are chosen from the very beginning of the random
number generator. (The actual numbers are larger than 1000. The code 1000.rand performs a
math operation to bring them below 1000.)
In the second example (and all our examples to this point) there is no seed, and each array
is filled with a different set of numbers. When no seed is provided, the OS picks one for you. It
uses the clock, just like our example earlier. Each of the numbers from the clock are a sequence,
thus predictable. But if used as a seed, they will point to a non-predictable number from the
random number series. In practical application, you could say that each clock number is matched
with a random number from the series. It's as if the random number series is spinning by along
with the clock, like the riffling pages or cards. When you execute any random function it grabs a
card from the constantly riffling deck. Below, just as an illustration, are sample clock values that
would be matched to random number choices.
Clock Random number series
22562.36 323285.46
22562.37 701351.76
22562.38 478870.03
22562.39 970076.8
22562.40 793066.74
22562.41 608190.06 // number chosen when you execute code at 22562.41?
22562.42 703109.74
22562.43 229301.21
22562.44 107420.56
22562.45 178472.04
22562.46 539228.68
22562.47 511396.65
The third example creates a window that shows four number boxes. The first is the clock,
refreshed every 100
th
of a second. Below that is the same clock, but showing the current value at
the press of any key. To the left of the clock is the random numbers that match up to each of the
clock positions if each were chosen as a seed. In reality the number generator isn't constantly
spinning by, but in practicality it is, when matched to the clock seed. The last is the number that
happened to match up to the clock when a new seed is chosen. I cheat a little with the code to
keep it simple, but it gives an accurate visual illustration of the process.
The last example chooses, sorts, then plots 10000 random choices. You can use this code
to test distribution of biased random choices, covered next.



254
24.1:: Random Seed
// Set seed to 0 before picking 10 random numbers
10.do({thisThread.randSeed = 0; ({1000.rand} !10).postln })

10.do({ ({1000.rand} !10).postln }) // no seed

(
var rWin;
rWin = Window.new("Random Numbers", Rect(20, 600, 400, 80)).front;
rWin.view.decorator = FlowLayout(rWin.view.bounds);

a = EZNumber(rWin, 150@20, "Clock ",
[1.0, 10000000.0, \lin, 0.000001, 0].asSpec);
b = EZNumber(rWin, 150@20, "#@Clock ",
[1.0, 10000000.0, \lin, 0.000001, 0].asSpec);
c = EZNumber(rWin, 150@20, "Seed ",
[1.0, 10000000.0, \lin, 0.000001, 0].asSpec);
d = EZNumber(rWin, 150@20, "#@Seed ",
[1.0, 10000000.0, \lin, 0.000001, 0].asSpec);

StaticText(rWin, 350@24).string =
"Press any key to choose random number.";

AppClock.sched(0.0, {|time| a.value_(time);
b.value_(1000000.0.rand); 0.01});
rWin.view.keyDownAction = {
d.value_(1000000.0.rand);
rWin.view.background = Color.rand;
c.value_(AppClock.sched(0.0, {|time| c.value_(time)}));
}
//AppClock.sched(0.0, {|time| c.value_(time);
// d.value_(1000000.0.rand);
// rWin.view.background = Color.rand;
// rrand(2.0, 5.0)})
)

// Linear distribution
({10.0.rand} ! 10000).sort.plot // test distribution

::
The line thisThread.randSeed seeds on the client side (where you type and evaluate
code). This means we can control the choice of random values for the initial construction of the
patch, but once sent to the server, they cannot be changed or reset. RandSeed allows you to send
a seed to the server, resetting in real time during playback. This is useful to manipulate events as
they happen.
In the examples below, the first starts an LFNoise control without any seed. Each time it's
run you should get different values. The second seeds the random number then chooses a rate.
That rate is sent to the server as part of the synth. It will always be the same. (It will be




255
8.9959564208984How do I know? Because it's not really random.) But the values generated
by the LFNoise, which is a random process on the server side, are different every time. The
second example uses RandSeed, which sends a seed to the server each time it receives a trigger
(down arrow). In that example the rate is different every time (because the client side seed has
been removed), but the values generated by LFNoise are now not only the same each time you
run it (103.724, 238.201, 317.462, 782.221, 113.28, 562.014.), but reset every time you press the
down arrow (at the trigger).
24.2:: Client/Server Seed
{SinOsc.ar(LFNoise0.ar(rrand(2.0, 6.0).postln, 100, 500))}.play;

(
{ // Client random seed. Run several times to confirm rate is the same.
var seed = 1768236, rate;
thisThread.randSeed = seed; // comment out for clock seed
"*****rate: ".post;
rate = rrand(6.0, 10.0).postln;
SinOsc.ar(LFNoise0.ar(rate, 100, 500).poll(rate, "freq"))
}.play;
)

(
{ // Server
var seed = 1768236, rate;
"*****rate: ".post;
rate = rrand(6.0, 10.0).postln;
RandSeed.kr(KeyState.kr(125), 1956); // down arrow seeds server. Press several times.
SinOsc.ar(LFNoise0.ar(rate, 400, 500).poll(rate, "freq"))
}.play;
)

(
{ // Both: the same every time
var seed = 1768236, rate;
thisThread.randSeed = 1956;
"*****rate: ".post;
rate = rrand(6.0, 10.0).postln;
RandSeed.kr(Impulse.kr(1), 1956);
SinOsc.ar(LFNoise0.ar(rate, 400, 500).poll(rate, "freq"))
}.play;
)

(
{ // Both: different every time
var seed = 1768236, rate;
thisThread.randSeed = Date.seed.postln;
rate = rrand(6.0, 10.0).postln;
SinOsc.ar(LFNoise0.ar(rate, 400, 500).poll(rate, "freq"))
}.play;



256
)

(
// Even something as complex as PinkNoise can be seeded
// Change 4 to 10, 100.
{
RandSeed.kr(Impulse.kr(4), 1956);
PinkNoise.ar;
}.play
)

(
{
var trig;
trig = Impulse.kr(4);
SinOsc.ar(
TIRand.kr(60, 72, trig).midicps,
mul: EnvGen.kr(Env.perc(0.01, 1/8), Impulse.kr(4))
)
}.play
)

a = {|rate = 1.5, num = 1916| RandSeed.kr(Impulse.kr(1), num);}.play
a.set(\num, 1912);
a.set(\num, 1883);
a.set(\num, 1901);
a.set(\num, 1937);
a.set(\num, 1936);

::
The last example creates two processes; the random function, and the random seed. The
sine wave is being driven by the TIRand which is reading values from the random number
generator. The next lines sets up a RandSeed in a separate synth. Since we declared the seed
(num) as an argument, it can be used with a.set to change periodically. The loop comes about
from the trigger (Impulse). The number indicates where in the RNG the values are taken.
! A rationalist might argue that nothing is random. Given enough information about any
system the results are predictable. Card tricks work on the illusion that a shuffling has not been
orchestrated when it has, and that the order of cards is not being managed and controlled when
they are. Even though I can predict the frequencies generated by an LFNoise when seeded with
1956 on the server side of SC running on Mac OS 10.x, if you can't then it's random. We arrive at
the improbable conclusion that the random number generator is completely random, if we want it
to be, and absolutely predictable, when we need it to bethe best of both.
Earlier we described aperiodicity as waves with no pattern. We now have to adjust that
definition slightly. In SC, aperiodic waves are streams of numbers with patterns, but so complex
that humans can't grasp their periodicity. {PinkNoise.ar([0.3, 0.3])}.play, essentially streams the
random number generator through the speakers. It will repeat after a mere 108 hours. By
comparison, A Million Random Digits, if converted to an aiff file, will only play for four
seconds. Trust me, I've tried it. That's using the groupings of five for values in the range of 0 to




257
10000. But if you took each digit alone that's still just 20 seconds. A serial composition using
random number generators (playing MIDI equipment, assuming 10 decisions per note and an
average length of 1 second per event) will repeat after 153,351 years. But it will repeat.
! This puts a rather existential spin on computer assisted generative composition. It is not
random, since any performance can be duplicated with the same seed. It seems random because
we havent heard that series of numbers before and even if we have, chances are we aren't going
to remember it. But each seed (billons of them) represents a specific repeatable generation of the
sequence described by the composition. So instead of a random process, it can be thought of as a
billion possible variations, each identified by that seed. The code you write then is the DNA for
billions of variations, of which one is chosen at each performance, depending on the exact time it
is run. Would it strain the metaphor to imagine the clock spinning through not random seeds,
thus random numbers, but complete performances, each played in a parallel universe, waiting to
be chosen and experienced at the touch of the enter key.
Probably.
! How is all this information useful to a composer? The reasons for using the seed again
include repetition during a performance, repeating a performance verbatim even though the
design of the performance includes aleatoric events, or finally to consistently reproduce a crash
for debugging purposes.
Example 24.3 illustrates how to manage the best of both: Seed both the client and the
server using the date or a random choice, but print that date-seed for reference. In essence;
shuffle the deck to use for the random choices, but remember the exact sequence for later use.
(This is a common feature in gaming software. You can retrieve a game "number" that will
reproduce, for example, the precise ordering of a bridge shuffle, in case you want to play
duplicate with yourself.) Using control ugens such as if this example could be expanded into a
system that chooses it's own random server seeds for, say, 30 seconds, compiling them into an
array, then sometimes choosing a repeated gesture, sometimes choosing a new gesture.
24.3:: Pick a Card, but Show Me

( // Start a process
{
var trig;
thisThread.randSeed = Date.seed.postln; // Pick seed, but print for future use
trig = Impulse.kr(rrand(4.0, 9.0));
SinOsc.ar(
TIRand.kr(60, 72, trig).midicps,
mul: EnvGen.kr(Env.perc(0.01, 1/8), trig)
)
}.play
)

// Run the first line several times, note the numbers posted.

a = {|rate = 1.5, num| RandSeed.kr(Impulse.kr(1), 100000.rand.postln);}.play;

a.set(\num, 33653); // repeat any of those by replacing 33653 with the posted number



258

::
To further dispel the myth of random events, not only is everything a computer does
absolutely predictable, but even if we concede that a clock seeded random number generator is
sufficient obfuscation to be unpredictable by me, it's still not random because of built in
Random Bias
! Though I can't predict the exact number, I can predict it will be a number. To be truly
random, rand might occasionally produce a sperm whale and a bowl of petunias in mid air, both
coming to terms with their identity. 1000.rand is biased in at least four ways: it returns a number,
a positive number, a positive number between 0 and 999, and a positive integer between 0 and
999. These biases have come from the human who wrote the code for rand.
In chapter 22 I proposed generating random frequencies using a deck of cards. Though at
the time this system might have made sense, it was also very biased toward whole numbers and
lower frequencies. This is because of the rule using three numbers per frequency and royalty and
tens adding 1000. To produce a frequency above 1000, you need several royalty in a row. Odds
are against this. Furthermore, if several royalty are in a row, you do get a higher pitch, but that
removes those cards from the line up. While it would be possible to produce a frequency in the
14000 range (fourteen royalty grouped with three non-royalty), it is very improbable, and even if
you did, that would mean only two other frequencies, maybe only one, above 1000. There is 0
chance for frequencies above 17k.
But bias is normal. All music circumscribes choices. Describing bias amounts to
teaching. For example, in common practice style the leading tone resolves up to tonic 90% of the
time. It occasionally moves down a third in the tenor or alto, and it occasionally remains the
same as a common tone to the seventh of the next chord. That is a bias that we teach first year
music students. If your goal is singable, tonal, counterpoint, in common practice style then you
follow that bias.
In previous code we have used exprand, which biases choices toward lower numbers; [0,
2, 4, 7, 9].choose, which biases to only numbers in the array, rrand(2, 10) which biases to
integers between 2 and 10, and so on. The next example shows a variety of bias choices. I use
histo to track the random choices. The last method is wchoose, which picks from the array with
weighted probabilities. The probabilities are given in the array as the first argument.
24.4:: Random Bias
// A histogram returns the total number of occurrences
// of integers within a range. 0 0s, 4 1s, 2 2s, 0 3s, 1 4, 4 7s, etc.
[1, 1, 1, 1, 2, 2, 4, 7, 7, 7, 7, 9, 9, 9, 9].histo(10, 0, 10)

({exprand(1.0, 100.0).round(1)}!20000).histo(100, 0, 100).plot

({[0, 20, 40, 50, 70, 90].choose}!100).histo(100, 0, 100).plot

({rrand(30.0, 66.0).round(1)}!20000).histo(100, 0, 100).plot // Bart's head

({min(100.rand, 100.rand).round(1)}!20000).histo(100, 0, 100).plot




259

({max(100.rand, 100.rand).round(1)}!20000).histo(100, 0, 100).plot

({div(100.rand+100.rand, 2).round(1)}!20000).histo(100, 0, 100).plot

({[0, 20, 40, 50, 70, 90]
.wchoose([0.1, 0.1, 0.3, 0.3, 0.17, 0.03])}!100).histo(100, 0, 100).plot

(Array.fill(20000, {if(0.4.coin, {20.rand * 2},{20.rand*2 + 1})})).histo(100, 0, 20).plot

::
Aleatory and Generative Composition
provide the performer (in this case, the computer) with a general set of parameters and
freedom of choice for others. All live music has varying degrees of generative elements. Many
early works have no instructions for instrumentation, leaving it up to the performers. But even
works that we think of as being well defined, that have been performed and refined over
hundreds of years, even recorded, cured in our minds as definitive realizations can come to life
with subtle differences in interpretation, perhaps a slightly faster tempo, more fluid tempo, wider
dynamic interpretation (hey, sort of like physically modeled instruments). Improvisation, of
course, is a defining characteristic of jazz. The instructions for performance may be as general as
"let's jam." Even so, there is still an implied bias; the jam will probably be blues, tonal,
traditional, 16 bars, trading solos. "What key," someone might ask. Specifying a key is a bias. A
Day in the Life, Beatles, has a famous generative segment between two sections. At first Paul
wanted the orchestra to play randomly. George Martin objected, so Paul refined the general
instructions; have them start on a low note then slowly play to the top of their range.
! The more general the instructions, the less control the composer has over the outcome. In
this style of composition the focus moves from each event to groups of events, and often the
entire work. Rather than obsess over the duration of this particular series of pitches, this phrase,
this dynamic, the composer's vision is global; the overall level of dissonance, density of events,
amount of overlap, tempo, or instrument change. And though you can always describe generally
what the results will be, you can never predict any specific event at a specific time. Like physical
models, generative scores set a process in motion. The biases described help maintain the
character of the work, but the random choices embrace billions of possible variations.
I'll balance my enthusiasm for aleatory with this: It can spawn indifference. I've seen
many works where I feel the composer is just lazy, intent on imitating the carefully controlled
styles popular a century ago (!) by writing a score with vague graphics because they know the
performers will conform by playing pseudo random serialist/atonal "bee blonk" events. If asked
to perform, I do my best to hang them with their own rope, and have been uninvited from several
aleatoric performances because I realized the score in ways that most annoyed the composer
while still within the bounds of the instructions. That is, in fact, an advantage to working with a
computer (see chapter 25). It keeps you honest. It doesn't know what you "mean" when you're
coping. It will do exactly what you say, so if you want bee blonk (carefully crafted distribution
of elements in a total control style), you better understand bee blonk style.
Computers may not be intentionally subversive, but the results are often different from
what you expect. The next few examples create a random walk. Students often complain that it



260
doesn't sound very random. That's because sequences emerge that fall into our realm of
experience. The pitch sequence C, D, E, C, (Frere Jacques) is a plausible result of a random
walk. This set of pitches would sound ordered even to those who had never heard Frere Jacque
because of it's tonal structure. But even a seemingly random set of pitches, say, C E D B B E
F F, would be recognized by nearly anyone who has lived anywhere but under a rock in the last
half of this century as the Twilight Zone theme, and therefore not random. (This raises yet
another interesting conundrum; is random just lack of exposure?) Being random and sounding
random are very different propositions. The pitch collection can't belong to any structure I know
nor can it call on any work I know, even if the work was conceived using random, pseudo
random, complexly ordered systems.
Though the distinction is blurring, I divide computer music into two broad categories; the
first half of this text covered synthesis or sound design. The second half covers the organization
of events and structure design. Orchestrating events deals with pitch, duration, next event
scheduling, instrument choice, and so on. For me at least, when working on this style of
composition instrumentation is a secondary consideration because I am focused on pitch,
duration, etc. (For the same reason, many of Bachs works have no instrumentation, and even
those that do are transcribed for other instruments. The essence of his music is in the notes the
notes.) For that reason, these examples use
MIDI Out
Once you design a process you simply send it to the MIDI synth.
MIDI is complicated by local variation. The example below shows how to connect MIDI
to the IAC driver, which should be automatically routed to other software synths. I usually use
SimpleSynth because it consistently works as expected. While Logic has wonderful instruments
they don't respond to MIDI program changes or (as far as I can determine) events sent to
different channels. Similar steps should work with Sibelius, virtual synths, and outboard synths.
Each event in MIDI requires a note on and note off command (which creates a gate). The
rest of the MIDI examples in this text assume you have initialized MIDI, assigned an out, and
that it is called m. First review the MIDI out section and follow the instructions for enabling the
IAC driver. Launch SimpleSynth, choose an instrument, then try the lines below.
24.5:: MIDI Init
(
MIDIClient.init;
m = MIDIOut(0, MIDIClient.destinations.at(0).uid);
)

// Test

m.noteOn(1, 60, 100); //channel, MIDI note, velocity (max 127)

m.noteOff(1, 60); //channel, MIDI note, velocity (max 127)

::
Now we can try a simple




261
Random Walk
Here is the seed example with a twist. First, when MIDI is used to generate notes the
server never comes into play, so to speak, just the client which sends messages to a synth. For
that reason we can seed on the client side. A Task is used as in a previous example, with an
infinite do with a two second wait. Be sure to save your work before inviting an infinite do on
board. It's a sure fire lock up if it isn't done correctly. (Sure, I could have used 100000.do, but
this is, after all, an infinite monkey experiment.) Inside the first do is a second that plays 8
randomly chose notes between 60 and 72 with a 0.25 wait time. Each note is played with by
sending a noteOn message to the IAC driver, which will play on anything that is connected to the
driver. The duration is executed by scheduling the clock for a length of 0.25, which then sends
the note off.
Before playing the eight notes an if statement (read below) checks to see if a seed other
than 0 was given. If not, the thread is seeded by the clock and that value is posted to the data
window so you can use it again. If you hear something you recognize, hopefully the Twilight
Zone theme, note the seed, replace 0 with it, then email it to me. Seriously. I'll also take anything
from Gilligan's Island. I pronounce this my latest composition, in which you are a participant
monkey; the missing twilight zone episode where Marius Constant dreams of infinite monkeys
plunking at the keyboard.
24.6:: Constant Monkeys

// MIDIClient.init; m = MIDIOut(0, MIDIClient.destinations.at(0).uid);

(
r = Task({
inf.do({
var seed;
seed = 0; // replace with a seed once you recognize a phrase
if(seed == 0, // Read about "if" below
{ "Do you recognize this? -- ".post; thisThread.randSeed = Date.seed.postln;},
{ thisThread.randSeed = seed;});
8.do({
var note;
note = rrand(60, 72);
m.noteOn(1, note, 100);
thisThread.clock.sched(0.25, {m.noteOff(1, note); nil});
0.25.wait
});
2.wait;
});
});
r.start;
)

// Stop all and send MIDI note off on all channels
r.stop; 127.do({arg i; m.noteOff(1, i, 0)})




262
::
These examples do not respond to !-period to stop playback. Rather, run the last line,
which stops the routine and sends noteOff commands to all channels. This next example expands
our walk to include octave, amplitude, and duration. The dur value determines both the length of
the current event, and the time of next event.
24.7:: Random Walk
// MIDIClient.init; m = MIDIOut(0, MIDIClient.destinations.at(0).uid);

(
r = Task({
50.do({
var note, dur, oct, amp;
note = 12.rand;
oct = (4.rand + 4)*12;
note = note + oct;
amp = rrand(50, 100);
dur = 8.rand * 0.125;
m.noteOn(1, note, amp);
thisThread.clock.sched(dur, {m.noteOff(1, note); nil});
(dur).wait
});
});
r.start;
)

r.stop; 127.do({arg i; m.noteOff(1, i, 0)})

::
Though any trained musician would characterize this as "random" it is biased in many
ways. Pitches are biased to discrete equal tempered values between 48 and 84. Try 48.0 for
microtonal pitches. Durations are multiples of 0.125, resulting in a pulse. Try rrand(0.125, 2.0)
for a free meter. Each event is sequential without overlap. This is because the duration of the
current event and the time until next event are the same. Read further for variations.
This model is expanded to include instrument choice and articulation next. Articulation
essentially treats duration and next event differently allowing events to overlap or die away
before the next is played. For instrumentation we can use both program changes or several
channels with different instruments assigned. SimpleSynth uses the Apple DLS sound set, which
conforms (with slight naming variation) to the general MIDI sound set. Here is a list.
This really should have been two chapters. Sorry.





263

Keyboards
0 Acoustic Grand Piano
1 Bright Acoustic Piano
2 Electric Grand Piano
3 Honky-tonk Piano
4 Rhodes Piano
5 Chorused Piano
6 Harpsichord
7 Clavinet
Tuned Percussion
8 Celesta
9 Glockenspiel
10 Music Box
11 Vibraphone
12 Marimba
13 Xylophone
14 Tubular Bells
15 Dulcimer
Organs
16 Hammond Organ
17 Percussive Organ
18 Rock Organ
19 Church Organ
20 Reed Organ
21 Accordion
22 Harmonica
23 Tango Accordion
Guitars
24 Acoustic Guitar (nylon)
25 Acoustic Guitar (steel)
26 Electric Guitar (jazz)
27 Electric Guitar (clean)
28 Electric Guitar (muted)
29 Overdriven Guitar
30 Distortion Guitar
31 Guitar Harmonics
Basses
32 Acoustic Bass
33 Electric Bass (finger)
34 Electric Bass (pick)
35 Fretless Bass
36 Slap Bass 1
37 Slap Bass 2
38 Synth Bass 1
39 Synth Bass 2
Strings
40 Violin
41 Viola
42 Cello
43 Contrabass
44 Tremolo Strings
45 Pizzicato Strings
46 Orchestral Harp
47 Timpani
Strings 2
48 String Ensemble 1
49 String Ensemble 2
50 SynthStrings 1
51 SynthStrings 2
52 Choir Aahs
53 Voice Oohs
54 Synth Voice
55 Orchestra Hit
Brass
56 Trumpet
57 Trombone
58 Tuba
59 Muted Trumpet
60 French Horn
61 Brass Section
62 Synth Brass 1
63 Synth Brass 2
Reeds
64 Soprano Sax
65 Alto Sax
66 Tenor Sax
67 Baritone Sax
68 Oboe
69 English Horn
70 Bassoon
71 Clarinet
72 Piccolo
Winds
73 Flute
74 Recorder
75 Pan Flute
76 Bottle Blow
77 Shakuhachi
78 Whistle
79 Ocarina
Synth Leads
80 Lead 1 (square)
81 Lead 2 (sawtooth)
82 Lead 3 (calliope lead)
83 Lead 4 (chiff lead)
84 Lead 5 (charang)
85 Lead 6 (voice)
86 Lead 7 (fifths)
87 Lead 8 (bass + lead)
Synth Pads
88 Pad 1 (new age)
89 Pad 2 (warm)
90 Pad 3 (polysynth)
91 Pad 4 (choir)
92 Pad 5 (bowed)
93 Pad 6 (metallic)
94 Pad 7 (halo)
95 Pad 8 (sweep)
Synth Effects
96 FX 1 (rain)
97 FX 2 (soundtrack)
98 FX 3 (crystal)
99 FX 4 (atmosphere)
100 FX 5 (brightness)
101 FX 6 (goblins)
102 FX 7 (echoes)
103 FX 8 (sci-fi)
Folk Instruments
104 Sitar
105 Banjo
106 Shamisen
107 Koto
108 Kalimba
109 Bagpipe
110 Fiddle
111 Shanai
Percussion
112 Tinkle Bell
113 Agogo
114 Steel Drums
115 Woodblock
116 Taiko Drum
117 Melodic Tom
118 Synth Drum
119 Reverse Cymbal
120 Guitar Fret Noise
Sound FX
121 Breath Noise
122 Seashore
123 Bird Tweet
124 Telephone Ring
125 Helicopter
126 Applause
127 Gunshot

Total Randomization
randomizes all musical parameters: duration, next event, instrument, pitch,
articulation, amplitude, etc.
24.8:: Random Walk
MIDIClient.init; m = MIDIOut(0, MIDIClient.destinations.at(0).uid);

// Set synth channels to different programs
m.program(0, 6); m.program(1, 12); m.program(2, 8); m.program(3, 24);

// Pan them, 0 is left, 127 is right.
m.control(0, 10, 0); m.control(1, 10, 42); m.control(2, 10, 84); m.control(3, 10, 127)


(
~note = {rrand(36, 84)};
~dur = {rrand(0.125, 1.0)};



264
~inst = {rrand(0, 3)};
~amp = {rrand(33, 120)};
~nextE = {[0.125, 0.25, 0.325, 0.5, 0, 0].choose};
r = Task({
"I\tPC\t\tAmp\t\tDur\t\tNxt\t\t".postln;
100.do({
var note, inst;
inst = ~inst.value.post; "\t".post;
note = ~note.value.post; "\t\t".post;
m.noteOn(inst, note, ~amp.value.post); " \t\t".post;
thisThread.clock.sched(~dur.value.round(0.1).post,
{m.noteOff(inst, note); nil}); " \t\t".post;
(~nextE.value.postln).wait
});
});
r.start;
)

// Execute these during playback to swap functions.

~note = {[0, 2, 4, 7, 9].choose + [36, 48, 60, 72].choose};
~note = {[0, 2, 4, 5, 7, 9, 11].choose + [48, 60, 72].choose};
~note = {(0, 2..36).choose + 48};

// 0.125 is the smallest division of the tempo
~dur = [1, 2, 3, 4, 5, 6].choose * 0.125
~amp = 120; // constant amplitude
~inst = 0; // single instrument

// Rhythms come about through "play" (50, 70, 100)
// or "don't play" (0) choice.
~dur = 0.125; amp = {[0, 50, 70, 100].choose};

r.stop; 4.do({|e| 127.do({|i| m.noteOff(e, i, 0)})})

::
You may not find these examples very interesting because they are not. Randomness
rarely is. (Bee blonk is interesting because it is not random. It's carefully crafted and balanced.)
Even in the natural environment randomness is rare. I can listen to birds, crickets, rain, and wind
much longer than anything by Wagner, and I stare at the branches of trees long enough to
concern neighbors, but none of those are random. They are complexthe results of biased
generative processes. Complex, biased, chaotic processes are beautiful.
Another way to bias a choice is to create a condition. For example, if there are already 3
notes in the chord don't pick another one, if we are about halfway through the work increase the
density, or if the random seed is 0, generate a seed using the clock and print it to the data
window. The if message is an example of




265
Conditional Control
! The if function takes three arguments: an expression to be evaluated, a function to be
executed if the expression is true, and a function for false. It evaluates the expression, returns the
results of the first function if true, the second if false.
if(expression, {true function}, {false function})
The true or false often results form a comparison of two values separated by operators
such as < or > for greater/lesser than, <= or >= for greater/lesser than or equal to, != not equal to
(In computer parlance the exclamation point, or bang means not. The inside joke is that it lends a
more accurate representation of advertising, such as "The must see movie of the year!"), and ==
for equals. (Note the difference between =, which means store this number in the variable and ==
which means "is it equal to?") The message or combines two statements, returning true if either
are correct; or(a > 20, b > 100). The message and combines two statements, returning true only
if both are correct; and(a > 20, b > 100). The word true is true and false is false.
24.9:: Control Using If
(
Task({
40.do({ |a|
if(a%10==9, {"ten repetitions".postln}, {a.postln});
0.3.wait;
})
}).play;
)

if((1 == 1).and(5 < 7), {"both are true"},{"maybe only one is true";})

if((1 == 20).and(5 < 7), {"both are true";},{"one or both are false";})

if((1 == 20).and(24 < 7), {"both are true";},{"one or both are false";})

if((1 == 4).or(true), {"true is always true";},{"1 does not equal 4";})

if(false.or(true), {"true is always true";},{"true wins with or";})

if(false.and(true), {"true is always true";},{"but false wins with and";})

// Can you predict these two before running?

if(or(10 > 0, 10 < 0), {34},{78})

if((1 == 1).and((10 > 0).or((5 < 0).or(100 < 200))), {78},{88})

::
The if function is usually used in combination with some iterative process such as do.
Example 24.10 first shows how it can be used to manage the range of MIDI interval choices. It
begins with 60, then adds each new choice to m and returns that new value. I've biased the



266
choices so that there are more intervals up than down. Eventually the MIDI values exceed a
reasonable range for most instruments. Even if I carefully balanced the choices it is conceivable
that a positive value is chosen 20 times in a row. (There are better schemes for managing interval
choice. For example, you could always choose positive values then reduce that result to a single
octave using modulo, so that all values are between 0 to 12, then choose the octave separately.)
The if statement below checks the value during each iteration and reduces it by two octaves if it
exceeds 72 and increases it by two octaves if below 48.
24.10:: Range Control with If
(
Task({
m = 60;
50.do(
{
var next;
next = [6, 17, 14, 2, 11, 8, -12, -16, -1, -3].choose;
"next interval is : ".post; next.postln;
m = m + next;
"before being fixed: ".post; m.post;
if(m > 72, {m = m - 24});
if(m < 48, {m = m + 24});
// Same thing
// m = m.wrap(48, 72);
" after being fixed: ".post; m.postln;
1.wait;
};
)
}).play
)

::
It is worth poking around in SC to see if a function already exists that will do what you
want. There is wrap, which wraps a value around, but in this example we are buffering, not
wrapping. So in this case we really do need the extra lines of code.
The situations where I most use if, do, while, is parsing data files (chapter 27).
Below shows a do iteration over an array of pitch classes with an if test to look for C, E,
or G. The computer doesn't understand these as actual pitches (see the discussion on strings
below), but just text. Even so, it does know how to compare to see if they are equal.
The second example uses a series of if statements to define a region on the screen. When
the mouse enters the region with an x greater than 0.3, but less than 0.5, and a y that is greater
than 0.3, but less than 0.7 (all conditions are "true") it generates a positive value, or a trigger. In
this example the * is equivalent to and. There are no true or false functions, just the values 1 (on)
and 0 (off).
The last example controls when to postln rather than post. This formats the output more
concisely.




267
24.11:: More If
(
["C", "C#", "D", "Eb", "E", "F", "F#", "G", "Ab", "A", "Bb", "B"].do(
{arg item, count;
if((item == "C").or(item == "E").or(item == "G"), //Boolean test
{item.post; " is part of a C chord.".postln;}, //True function
{item.post; " is not part of a C chord".postln;} //False function
)
}
)
)

(
{ // Use Mouse to trigger event
var aenv, fenv, mgate, mx, my;
mx = MouseX.kr(0, 1);
my = MouseY.kr(0, 1);
mgate = if((mx>0.3) * (mx<0.5) * (my>0.3) * (my<0.7), 1, 0);
aenv = EnvGen.kr(Env.asr(0.1, 0.5, 2), mgate);
fenv = EnvGen.kr(Env.asr(1, 1, 2), mgate, 1000, 100);
RLPF.ar(Saw.ar(100)*aenv, fenv, 0.1)
}.play
)

// Control data monitoring
(
100.do(
{
arg count;
100.rand.post;
if(count%10 == 9, //Every 9th time
{" new line: ".postln;}, //print a carriage return
{" : ".post;} //just " * " without a return
);
}
)
)

::
Structural Control
The most common application of control statements is to modify parameters over the
duration of a generative composition. If, for example, there have been 50 events, change the
scale, increase the density, add a voice, change the register, or alter the level of dissonance.
24.12:: Structural Control
/*
// run if necessary



268
MIDIClient.init; m = MIDIOut(0, MIDIClient.destinations.at(0).uid);
m.program(0, 6); m.program(1, 12); m.program(2, 8); m.program(3, 24);
m.control(0, 10, 0); m.control(1, 10, 42); m.control(2, 10, 84); m.control(3, 10, 127)
*/

(
~note = {[0, 2, 4, 7, 9].choose + [48, 60].choose};
~dur = {rrand(0.125, 1.0)};
~inst = {[1, 2].choose};
~amp = {rrand(33, 120)};
~nextE = 0.2;
~density = 0.25;
r = Task({
500.do({ |ct|
var thisEvent;
thisEvent = [~inst.value, ~note.value, ~amp.value, ~dur.value.round(0.1), ~nextE.value, ~density.coin];

if( thisEvent@5,
{ m.noteOn(thisEvent@0, thisEvent@1, thisEvent@2);
thisThread.clock.sched(thisEvent@3, {m.noteOff(thisEvent@0, thisEvent@1); nil});
ct.post; " ".post; thisEvent.postln; },
{"rest".postln});

if(ct == 100, {
~density = 0.5; // increased density
~note = {12.rand + [36, 48, 60, 72].choose}; // change scale, increase range
~inst = {[0, 1, 2, 3].choose}; // add instruments
~amp = 120; // louder
});
if(ct == 300, { /* add your variations */ });
if(ct == 400, { /* add your variations */ });

(thisEvent@4).wait;

});
});
r.start;
)

r.stop; 4.do({|e| 127.do({|i| m.noteOff(e, i, 0)})})

::





269
Exercises
24:1 Using Random Walk ii as a model, create an aleatoric composition using biases. For
pitch try microtonal choices, scale choices (from an array), separate choices for
pitch class and octave.




270
25. Computer Music
Machines can't create music. Only people can.
But people use musical instruments or machines, and the computer is just another music
machine. The piano makes music easy and accessible by presenting a mechanized, clearly
organized system for getting the right pitch and playing many pitches at once. It is within reach,
literally, of any two year old. A computer presents a similar opportunity; reducing complex,
difficult, precise ideas to snippets of code.
! Composers use computers because they are fast, accurate, methodical, obedient, obtuse,
and autonomous. They will do precisely what you ask, and only what you ask without complaint
or question. They will never interpolate or interject their own ideas.
Speed
facilitates experimentation. After each example in previous chapters I've suggested
alternatives. You no doubt tried a few on your own. Consider the transformations (Example
25.1) of the first 19 measures of Bach's first prelude from the Well Tempered Clavier. It took
some time to enter all those MIDI values, and I've invested years learning the code, but each
variation takes no more time than working out the mutation formula.
25.1:: Fast

// MIDIClient.init; m = MIDIOut(0, MIDIClient.destinations.at(0).uid);

// Pan center
// m.control(0, 10, 64);

(
~pc = [60, 64, 67, 72, 76, 60, 62, 69, 74, 77,
59, 62, 67, 74, 77, 60, 64, 67, 72, 76, 60, 64, 69, 76, 81,
60, 62, 66, 69, 72, 59, 62, 67, 74, 79, 59, 60, 64, 67, 72,
57, 60, 64, 67, 72, 50, 57, 62, 66, 72, 55, 59, 62, 67, 71,
55, 58, 64, 67, 73, 53, 57, 62, 69, 74, 53, 56, 62, 65, 59,
52, 55, 60, 67, 72, 52, 53, 57, 60, 65, 50, 53, 57, 60, 65,
43, 50, 55, 59, 65, 48, 52, 55, 60, 64];

r = Task({
var set;
// Normal, quarter, whole tone, inversion, scramble
set = [~pc, ((~pc - 60.0)/2) + 60, ((~pc - 60)*2) + 60,
(60 - ~pc) + 60, ~pc.scramble]@0; // change to @1, @2, @3, @4 for alternatives
2000.do({ |c|
var mutate, amp;
// Normal, multiples, reverse, random
mutate = [c, c*2, c.neg, set.size.rand, 12.rand + 60]@0; // change for alternatives
amp = [100, [100, 0].choose,




271
[100, 0].wchoose([c, 100].normalizeSum)]@2; // change for alternatives
m.noteOn(0, set.wrapAt(mutate), amp);
thisThread.clock.sched(max(0.1, 3 - (c*0.001)),
{m.noteOff(0, set.wrapAt(mutate)); nil});
(0.1).wait
});
});
r.start;
)

r.stop; 127.do({|i| m.noteOff(0, i, 0)})

::
Alternative sections of code in earlier examples were disabled with comments. In this
example they are chosen from an array: [a, b, c]@0. Change @0 to @1, @2, etc., to select
alternatives. The first set of alternatives change the pitch content. The next halves every interval,
the next doubles them, 3 flips the intervals on the C4 axis, and 4 scrambles them (which is
different from random). The variable mutate is used to modify the series by manipulating c.
Multiply by 2 will yield every other pitch. The first time through it will play even pitches, odd
the second time through. If that doesn't interest you, try every third, fifth, or 97
th
. It doesn't
matter. It's a computer. Using c.neg reverses the series. Multiply this for reversal and multiples.
The simplest modifications return surprisingly effective results. For example, try replacing the
100 with [100, 0].choose. This maintains the sequence but randomly turns notes on and off.
[100, 0].wchoose([c, 100].normalizeSum) slowly increases the density of pitches.
See chapter 26 (Kinderstuck Variations) for more examples.
Accuracy
allows precise execution. I am fascinated with microtones and alternate tunings. This
is, in my opinion, the next big step for art music. For hundreds of years the microtuning
community has existed in all but exile. Practitioners were (are?) seen as eccentrics and outcasts
living on another plane (planet?). Some (Partch) had to build their own instruments. Others
(Johnston) created scores filled with excruciatingly contrived notation. They gather dust, because
no one can play them.
A computer has no difficulty at all distinguishing between 440 and 440.001. This
accuracy can be employed as performer or educator: training performers in the subtle differences
of microtuning. The pianoa machineis also fast and accurate. It taught us the equal tempered
scale, which is now accepted as the norm. (It's just not as flexible.) Most college level choirs are
trained to sing using just intervals and equal tempered intervals when working with a piano.
Its role could also be notation. The system we use now is the most current and convenient
method of communicating the composer's intention to the performer. We use paper and pen
because that's the technology most performers know. Why use paper at all? Why use note heads?
Couldn't we say the 0s and 1s coming from the computer are the notation? If we can format it in
a way the performer understands then it will serve as notation. Performers understand raw sound
the most readily. Complex accidentals are a code that represent a particular pitch. We use them
only because we have to work with paper. Why not just give the performer the pitch? The truth is
we often do; these days a score is usually accompanied by a CD as a practical aid.



272
Compositions are always constrained by existing technology. We use an equal tempered
scale because the piano, or more precisely pianists, can't manage the number of keys and strings
required for both A and G. So we compose as though they were the same pitch. They are not.
Shouldn't a composer make use of both? Arguably many do, and strings, voices, even brass can
make the distinction. But it's not that way in our collective consciousness.
The same is true for rhythm. We write tempo and meter based music partly because it is
satisfying, but also because we have to put it on paper. There has to be a reference point that you
and the performer agree on: the meter and tempo. Occasionally a composer will dare to venture
into asymmetric divisions (7:8), but rarely compound asymmetry (quarter, sixteenth, sixteenth,
eighth, dotted quarter of a 7:8) and rarely anything more difficult. If you do write something
more complex (11/8 against 7/8), who is going to play it? You know someone? Who is going to
play it correctly? Who is going to play it correctly on a new music recital in three months? Who
is going to play it correctly the first time out of the gate, and every subsequent performance?
A computer has no difficulty with rhythms accurate to 0.0001 seconds. Again, I'm not
suggesting the computer be the performer in all cases. Maybe it's the notation. Why not just give
the performer the rhythm: when they hear the tick or see an event scroll to a stationary bar on the
screen they sing it. The term for this technique is animation notation. It has a long history,
including the bouncing ball sing-alongs. Consider this variation: five performers watching a
projected screen with five circles. Inside the circle is displayed the next pitch to be played, the
arc of the circle is used for timing (a dot or shading). When the shaded area reaches the top of the
circle, the performer plays. Duration and amplitude could be illustrated with shading or color.
Timbre could be illustrated with color. I've watched just a few illustrations of this method and
seen complete novices, most with no musical training, perform extremely complex rhythmic
patterns. (Spacial or static timeline notation has never seemed very convincing to me. Performers
guess at the timing and it becomes aleatoric.)
The computer is the notation and the conductor. Is that cheating? When monks ran out of
red ink (it was expensive) they hit on the idea of using hollow notes and pretending they were
red. We now use that system. Was that cheating?
25.2:: Mixed Tuplets, Atonal Just Tuning
// MIDIClient.init; m = MIDIOut(0, MIDIClient.destinations.at(0).uid);

[12, 10, 13].do({| nm, cnt | m.program(cnt, nm); m.control(cnt, 10, (cnt/2)*127);})

(
~meter = 4;
~ct = 0;
// ~pitchC = [0, 1, 9, 8, 7, 10, 11, 6, 5, 4, 3, 2]; // Kinderstuck
~interval = [3/2, 4/3, 5/4, 6/5, 7/6, 8/7, 9/8];
~freq = 440;
p = Task({
100.do({
var tuplet;
tuplet = [3, 4, 5, 6, 7].choose;
tuplet.do({ |lct|
var amp, pc;




273
([~interval.wrapAt(~ct),
(~interval.wrapAt(~ct)).reciprocal].choose);
~ct = ~ct+1;
amp = [0, 0, 50, 75, 100].choose;
if(~freq > 880, {~freq = ~freq/4});
if(~freq < 110, {~freq = ~freq*4});
m.noteOn(0, ~freq.cpsmidi.round(0.001).postln, amp);
thisThread.clock.sched(0.5,
{m.noteOff(0, ~freq.cpsmidi); nil});
(~meter/tuplet).wait
})
});
});
q = Task({
100.do({
var tuplet;
tuplet = [3, 4, 5, 6, 7].choose;
tuplet.do({
var amp, pc;
~freq = ~freq*
([~interval.wrapAt(~ct),
(~interval.wrapAt(~ct)).reciprocal].choose);
~ct = ~ct+1;
amp = [0, 50, 75, 100].choose;
m.noteOn(2, ~freq.cpsmidi.round(0.001).postln, amp);
thisThread.clock.sched(0.5,
{m.noteOff(2, ~freq.cpsmidi); nil});
(~meter/tuplet).wait;
})
});
});
r = Task({
100.do({
var lfreq;
~freq = ~freq*
([~interval.wrapAt(~ct),
(~interval.wrapAt(~ct)).reciprocal].choose);
~ct = ~ct+1;
lfreq = ~freq;
~meter.do({
m.noteOn(1, lfreq.cpsmidi.round(0.001).postln, 30);
thisThread.clock.sched(0.1,
{m.noteOff(1, lfreq.cpsmidi); nil});
(~meter/4).wait;
})
});
});
p.start; q.start; r.start;
)
// Stop all, send note offs to all channels, all notes.
p.stop; q.stop; r.stop; 4.do({|e| 127.do({|i| m.noteOff(e, i, 0)})})



274

::
In Logic Pro, the accuracy inherent to computer systems is illustrated by the number of
precise tunings instantly available under the File/Project Settings/Tuning menu. There are
close to 100, eight by Andreas Werckmeister, and many non-traditional ensembles such as
Javanese Gamelan and 17
th
C Hrdayakautaka. You can even define your own and make up even
more absurd names. The most fascinating is Hermode tuning, which rectifies the limitations of
12 piano keys by calculating and adjusting intervals on the fly.
Methodical
treatment can lead to new horizons. An algorithmic treatment will reveal combinations
that we may dismiss because of our bias. Consider a minimalist treatment of "I dig you don't
work." Our classes usually find thirty or so that make sense: I work, you don't, dig? I don't work,
you dig. I work, you don't dig. Don't dig, you. I work. But a computer can quickly show you
every combination. You are then encouraged to consider each variation as valid because it is true
to the design or system (every possible iteration).
Below is the SC version of this exercise. This is an exhaustive iteration with no repeated
words. Nearly all except those where you and I are consecutive make sense. (And even they
work with creative inflection, or interpreting "I" as its homonym "eye.") Having every iteration
before you forces you to think out of the box.
25.3:: I Don't Dig You Work
var text;
text = ["I", "DON'T", "DIG", "YOU", "WORK"];
121.do({arg i; i.post; text.permute(i).postln;})

// run this first it may take a second to warm up the speech components
"I'm ready to speak.".speak;

(
Task({
t = ["i ", "don't ", "dig ", "you ", "work "];
t.size.factorial.do(
{ |i|
t.permute(i).join.postln.speak;
// t.permute(i).join.reverse.postln.speak;
3.0.wait
})
}).play
)

::
In the spirit of As Slow As Possible (Cage), the next example performs every possible
twelve tone row.
This is an example of conceptual or imaginary music. That is, it's more about the idea
than realization. Tom Johnson's Imaginary Music includes a "score" with a treble staff, about 100




275
ledger lines, on top of which sits a chord. It's called Celestial Music for Imaginary Trumpets.
Clever, ironic, but music? It's easy to dismiss, but we slow down recordings of insects in
Concrte, or speed up the frequency of planets, why not celestial chords? No one is going to
listen, uninterrupted, to this next example. Can I still call it a composition? Is a written score
music, or does it have to be played? Couldn't the code itself, with the potential of every 12-tone
row be a representation of every possible 12-tone melody? Is there a beauty that transcends the
waves of sound that might happen in the next 30 seconds?
It doesn't include inversions, retrograde, or inverted-retrograde because theoretically
those will emerge as originals. It begins somewhere in the middle, but then wraps around, so it
will eventually play every variation.
The number of permutations are calculated as the original array's size factorial. Next
determines the next event, art determines the length of the event, as a function of next. Add lines
of code that modify either of these. The total playback time is an estimate given the duration of
next. While some notes are stacked, they are also skipped, so I think they even out. The variable
nxt is used to allow chords. Either the global next is used, or 0, which results in a simultaneous
event. The wchoose sets the probabilities for each; 70% next, 30% 0, or a chord 30% of the time.
The octave is assigned separately. The wait time is also set using wchoose. This varies the
rhythm while maintaining a pulse. 1 is essentially an eighth note, 2 a quarter, 3 dotted quarter,
and 4 a half.
25.4:: As Fast As Reasonable
// Permute

25.do({arg count;
postf("Permutation %: %\n", count, [1, 2, 3, 4].permute(count));})

//Every row

(
var original, total, begin, next, art;
original = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
total = original.size.factorial; // 479001600
begin = total.rand;
next = 0.125;
art = 0.1;
("Total playback time aprox. " ++ (total*next/43200).asString ++ " days. " ++
(total*next/43200/365).asString ++ " years.").postln;
r = Task({
total.do({arg count;
var thisVar;
thisVar = original.permute(count+begin);
thisVar.postln;
(thisVar).do({arg note;
var oct, nxt;
nxt = [next, 0].wchoose([0.7, 0.3]);
oct = [36, 48, 60, 72, 84].choose;
m.noteOn(0, note + oct, 100);



276
thisThread.clock.sched(next*art, {m.noteOff(0, note + oct, 100); nil});
(nxt * [1, 2, 3, 4].wchoose([0.5, 0.3, 0.1, 0.1])).wait
});
})
});
r.start;
)

r.stop; 127.do({arg i; m.noteOff(0, i, 0)})

::
It sounds, at least in terms of pitch, more random than the random walk. Yet it's the
opposite of a random walk. It's completely determinant.
In addition to being fast and methodical, computers are
Obedient and Obtuse
They make no observations or conclusions. Humans, on the other hand, are incapable of
suppressing observation and conclusion. Consider this series: G E D C D C A G E. It's almost
impossible for you, a human, to look at those symbols without making meaningful assumptions
or searching for a pattern. First, you assumed they were music. You probably assumed they were
pitch classes. You might even have sung them to see if you recognized the melody, maybe
spotted a composer's name. A computer will not make any of those assumptions.
! This is useful in two ways. The first is proving compositional method. If you write code
that produces something different from what you wanted the error is not the performer (the
CPU), but your system (the code). In the random numbers chapter we saw that a random walk
could produce the series C, D, E, C, C, D, E, C. That is not what you would expect, or want, but
the error wouldn't be in the mechanics of realization, but the system, and that is evident because
of an unbiased performer. If, on the other hand, we had asked a pianist to play "random" notes,
they would intuitively avoid octaves, arpeggios, and familiar tunes. This system is flawed, but
not evident because the performer is not being honest or true to the system. They are applying
their own bias. To be truly random, the pianist must include the possibility of familiar tunes.
! When the system, if realized honestly, returns something unexpected you have two
choices; accept this aberration as a new idea to consider, or refine your instructions to better
reflect what you want. The first time I tried to realize "I Don't Dig You Work", a mistake in the
code returned "I", then "I, I", then "I, I, I." It was doing what I asked, but not what I expected. I
had two choices: rewrite the code or include these possibilities in my poem.
Escaping Human Bias
is the key to fresh ideas. When writing in existing styles, say children's songs for
educational videos, our methods are intuitive: The producers described an idea for a song, the
composer imagines that song and writes it out. In that job intuition was essential.
Intuitive composers imagine an event, describe the circumstances that will result in that
event, give the description to performers, then make adjustments to the description and the
performer's understanding until the event imagined is realized. I like to think of this as backward
composition. You are working back to something you imagined. You are reproducing something




277
that already exists conceptually. Douglas Hofstadter in David Cope's Virtual Music draws into
question whether this method of composition is creativity or craft, since it can be reproduced
mechanically.
The systematic composer works the opposite way; describing a set of circumstances and
discovering the results. In my mind this is what constitutes forward composition. The difference
is political. All true innovators work this way. Instead of thinking "this is what I want" they ask
"what would happen if."
A composer escapes bias through some method of iteration (like trying every interval in
turn until one strikes you as useful) or with a random system (plunking at the piano for new
ideas). Both are systems. But what does it mean when this method reveals a useful combination?
Is the combination something you recognize? Are you just repeating something you've already
heard, already learned to like?
The traditional method for escaping or maturing your own bias is to listen to other
composers. We've all seen this evolution in students. They are initially shocked, even offended
by a new style. (And it doesn't have to be art music, such as Crumb's Black Angels. On first
hearing, Bebop was indecipherable to many seasoned musicians.) Eventually they accept it,
study it, study with composers who write that way, until it is infused into their own style. It
becomes one of their biases.
But what happens when you have picked the brains of all of your instructors? Where do
you go after you have studied all existing styles? How do you move on to ideas so new that they
would surprise your instructors and you? Can you become the next composer that challenges and
stretches your own music?
You use a system. You ask the question first, as did these composers:
"My next piece, which I have not yet learned to like." Herbert
Brn
"The key to real freedom and emancipation from local dependence
[human bias] is through scientific method Originality is the
product of knowledge, not guesswork. Scientific method in the arts
provides an inconceivable number of ideas, technical ease,
perfection and, ultimately, a feeling of real freedom, satisfaction
and accomplishment." Joseph Schillinger, The Scientific Basis for
the Arts
"Since I have always preferred making plans to executing them, I
have gravitated towards situations and systems that, once set into
operation, could create music with little or no intervention on my
part. That is to say, I tend towards the roles of planner and
programmer, and then become an audience to the results" -Brian
Eno (cite Alpern).
I've observed many faculty and student composers resist letting go of control. Embracing
a system can be unsettling. It can also be liberating. Either way, it raises some issues that
intuitive composers take for granted.



278
A visiting Russian student, anxious to impress our staff, showed our secretaries a
discovery he had made: "true" music. His scores were filled with floating point numbers, so they
sent him to my office. Turns out he had figured out (on his own, apparently) that the piano was
not tuned to pure intervals and had worked out the calculations for correct, just tunings. His
method resulted in drifting pitches (free just intonation). I asked "won't the pitches eventually
drift from the original tonic?" He realized they would. "Wouldn't you find that offensive to the
ears?" His response: "It can't be offensive, because it is true [to the system]." I had to agree. Who
am I to say what is beautiful? To him integrity to the system was more important than the actual
sound. We have become acclimated to equal temperament, which is out of tune. In 100 years will
we accept pitch shift in free-just intonation? When the computer prints "I", "I, I", "I, I, I" am I
obligated to accept that as the work simply because it is true to my system?
Could all musical taste be a matter of exposure and repetition? We've proven several
times that even random (?) noise becomes music when repeated. While our intervals and tuning
systemmoving from high ratios or dissonance to low ratios or consonanceis based on scientific
principle, Javanese Gamelan are tuned to irrational intervals. Their melodies are just as musical.
Nurture or nature? Probably both.
You might consider the system a genetic code where millions of variations co-exist. I've
often been unhappy with a particular realization of a generative work while other performances
are gems. The system is a seed that encapsulates hundreds, millions of possible results. You can
pick one to admire, or admire them all. In the Kinderstuck segment in Chapter 26, my sense is
they are all equally valid variations of the same work. Webern wrote the genetic code, I grew lots
of flowers. Could that have been his intention, which was at the time out of practical reach?
"When one arrives at this correct conception of art, there can be
no more distinction between science and inspired creating. The
farther one presses, the more everything becomes identical, and at
last one has the impression of encountering no human work, but
rather a work of Nature." Webern
Finally, the last level of integrity is that the results of the system are used simply as
inspiration; ideas to be worked out intuitively, or discarded completely. You get to decide.
Autonomy
gives you the freedom to pursue your vision unobstructed by the mechanics of
working with live musicians, or the social pressure, implied or inferred, to write in a given style.
I dare suggest that the composer would do himself and his music
an immediate and eventual service by total, resolute, and voluntary
withdrawal from this public world to one of private performance
and electronic media, with its very real possibility of complete
elimination of the public and social aspects of musical
composition. By so doing, the separation between the domains
would be defined beyond any possibility of confusion of categories,
and the composer would be free to pursue a private life of
professional achievement, as opposed to a public life of
unprofessional compromise and exhibitionism. Milton Babbitt




279
This article was originally titled Musician as Specialist. When published the title was
changed, without permission from Babbitt, to Who Cares if you Listen? Babbitt draws a parallel
between science and music, quoting E. T. Bell:
"In the eighteenth century the universities were not the principal
centers of research in Europe. They might have become such
sooner than they did but for the classical tradition and its
understandable hostility to science. Mathematics was close enough
to antiquity to be respectable, but physics, being more recent, was
suspect. Further, a mathematician in a university of the time would
have been expected to put much of his effort on elementary
teaching; his research, if an, would have been an unprofitable
luxury" E. T. Bell
This could very well read: "In the current century, live performance is not the principal
venue for new music in America. It might become so but for the classical tradition and its
understandable hostility to new music. Webern, Schoenberg, and even Babbitt are close enough
to antiquity to be respectable. But <insert your name> is suspect. Further, a composer of today is
expected to put much of his effort on traditional styles (serialism, minimalism, neo-classicism,
pan-tonality); his experimental ideas, if any, are an unprofitable luxury"
Autonomy (another virtue of the piano), absence of bias, obtuse obedience, and
methodical, accurate speed, leads to virtually unlimited choices. Those choices can be
Absolute or Proportional
An absolute value will always be the same, for example, the absolute value C4 will
always be C4. A proportional value is based on the previous value. It will use the same
proportion each time, but return different absolute values. Intervals are proportional values.
Proportional values work for pitch, next event, duration, and amplitude. It is especially useful in
the case of amplitude, allowing the serialization of gradual changes between volumes (i.e.
crescendo and decrescendo).
Proportional events work well with music, since structure involves relationships. The
logic of a melody comes from the ratio of each pitch to the previous. Rhythms are based on
ratios of a beat: for example this new beat has twice as many events as the last beat. In addition,
if proportional values are used to generate timed events the overall speed of these events can be
adjusted using a tempo, while retaining the structure of the timings.
When choosing absolute pitches you might be able to control the probabilities of one
pitch over another. For example, you could weight the choices towards C and G, which would
result in a greater sense of tonic. But with proportional values you could weight choices toward
consonant intervals, or more dissonant intervals, thereby controlling the level of dissonance.
There are two important things to consider when using a proportional scheme for
Pitch
If you are working with frequencies you would express the intervals as fractions of the
current value. For example, if you are currently playing an A 440 and you want an octave for the
next value, then the ratio is 2:1, (value*2). Be aware that interval ratios such as 2.0 (octave), 1.5



280
(fifth), 1.333 (fourth), 1.25 (third), etc., are just intervals. We use the equal tempered scale in
most modern music.
If, on the other hand, you want equal temperament, then use MIDI numbers. Each MIDI
number represents a key on the piano and the tuning is determined by the synthesizer, which is
usually equal. The math for proportional MIDI values is different. Rather than multiply you add
or subtract. Add 7 for fifth, 5 for fourth, 4 for third, -4 for a third down, etc. The inversion of a
set of MIDI intervals is pretty easy: midiArray.neg. This inverts the positive/negative sign, such
that 5 becomes -5, -10 becomes 10.
25.5:: Proportional MIDI inversion

// If used as MIDI intervals this is unison, 4th up, M3rd up,
// 5th up, M2 down, M6th down, 2nd up, ttone down

[0, 5, 4, 7, -2, -9, 2, -6].neg;

::
Duration and Next Event
can become very complex very fast; nearly impossible to play or represent in
traditional notation. Here is a deceptively simple series of proportional values; 1, 1.5, 1.5, 1.5,
0.5, 0.5. If the tempo is 1 second, the realization would be: 1 * 1 = 1 (quarter note) * 1.5 = 1.5
(dotted quarter) * 1.5 = 2.25 (half tied to a sixteenth) * 1.5 = 3.375 (dotted half tied to sixteenth
tied to thirty-second) * 0.5 = 1.6875 (??) * 0.5 = 0.84375 (??). How would such a passage be
notated in tradition meters? Is this a failing of the computer to think in human terms, or another
box we should think out of?
There is nothing inherently wrong with subdivisions of metered music. We like it because
it's an easy pattern to follow. A proportional scheme could still be used for each beat: this beat
has twice as many divisions as the previous.
Another problem with a proportional duration scheme is the value 0. In SC a 0 for next
event is legal, and represents a chord or a simultaneous event. But once you hit the value 0 you
will never escape, because 0 * anything is 0. All of the "next" values beyond that will be 0 and
therefore part of an infinite chord. The solution is to either test for 0 using an if condition and
correct for the next choice (but then you will never have more than two notes in a chord), or
better, consider a chord a single event and make the decision about whether or not this event is a
chord and how many elements there are in the chord separate from next event. For example,
determine if each event is a rest, a single note, or a chord. If it is a chord, determine how many
pitches are in the chord. Make them all the current duration and then determine the next event
that could also be a chord, a rest, or a single pitch.
Another possibility is to never allow 0 as a choice, but conceive simultaneous events as
counterpoint: devise two or three lines that will sometimes come together as a chord. The
difficulty this presents (since Italian Motets, in fact) is keeping track of the intervals that result
from two separate systems. Another method for accommodating rests and simultaneous events is
to calculate duration separately from




281
Next Event
In this case the next event could be in 1 second while the current event is set to four
seconds. Next event could be 0, generating simultaneous events, while the duration of each of the
simultaneous events could be different for each. Rests would occur when the next event is longer
than the duration of the current event.
Non-Sequential Events
are possible if the entire work is calculated before performance. Too often we assume
that events should be linear and successive. For example, first determine the length of a work
(e.g. 4 minutes), and then place items anywhere along that continuum. Pitch 1 could be placed at
2'23", have a duration of 3 seconds, pitch 2 then might be placed at 1'13". This poses a problem
in regard to coherence. We recognize style sequentially, so it would be difficult to maintain
thematic consistency if events are not calculated sequentially. One solution might include a
mixture of sequential and non-sequential events. Themes or motives may be fleshed out
sequentially but placed within the space of time as described above. However, I think the
difference in sequential and non-sequential approaches is largely academic.
Of course, there is no such dilemma with non-pitched concrte work.
Rhythmic Inversion
Prime, retrograde, and inversion are simple propositions when considering pitch.
Rhythmic retrograde is also simple. But how do you invert a rhythmic set? Solutions offered in
other documents fail to capture the spirit of rhythmic inversion. It is logical that a set of durations
should invert to something opposite, slow to fast, long values to short values, etc. There are two
methods I've used that satisfy this requirement. Both are also problematic.
The first is inversion of density. It requires that you first decide what the smallest
allowable articulation is, say, an eighth note. That means that the densest measure would be
filled with all eighths, the least dense would be a single whole note. (Or even less dense might be
a whole note tied to the previous measure, such that there are no articulations in the current
measure.) Each possible point of articulation (each eighth note) is either 0 or 1, a 0 meaning no
articulation, a 1 meaning a single articulation. Using this method, four quarter notes would be
[10101010]. Two half notes would be [10001000]. The logical inversion then would be to simply
swap 0s for 1s. The quarter note measure would invert to [01010101], or a syncopated eighth
note passage. The two half notes would invert to [01110111], or an eighth rest followed by three
eighths, then another eighth rest followed by three eighth notes.
The first problem with this method is that you are boxed into using only the declared
legal values. The second problem is that inversions may generate an unequal number of
articulations, and will therefore require different sizes of pitch, and dynamic series. One solution
is to make sure you always use exactly half of all the articulation points, so that the inversion
would be the other half. The total number of values would always remain the same. But this
seems to be a narrow constraint.
Proportional divisions are no less complicated. Quarter notes are 1.0, half notes are 2.0,
eighth notes are 0.5, etc. The inversion to a rhythm then would be the reciprocal: 2 inverts to 1/2,
1/2 inverts to 2. This scheme maintains the number of articulations in a series and satisfies the
logic of an inversion (fast to slow, slow to fast, dense to less dense; an active dense line, say, all



282
sixteenth notes, would invert to a relaxed long line, all whole notes). The problem with this
system is the amount of time that passes during an inversion may be radically different from the
original. If you are working with several voices this could throw the other elements of the row
out of sync. (It didn't seem to bother Bach.)
One solution would be to force the proportions to fit into a prescribed time frame using
the normalizeSum message. Take, for example, the array [1, 1.5, 0.25, 4, 0.25]. They total 6
seconds in duration. The "reciprocal" inversion (I'm rounding to 0.01) would be [1, 0.67, 4, 0.25,
4 ], which totals 9.92 seconds in duration. Using normalizeSum reduces each element in the array
such that they all total 1.0. The results of this line is [ 0.1, 0.07, 0.4, 0.03, 0.4 ]. Those values
total 1.0, and we want to fit it into a duration of 6 seconds. This is done by simple multiplication:
[ 0.1, 0.07, 0.4, 0.03, 0.4 ]*6 = [ 0.6, 0.42, 2.4, 0.18, 2.4 ].
The results are usually complex, and likewise quickly stray from most composer's narrow
view of rhythmic possibilities.
25.6:: Rhythmic Inversion
var rhythmArray, orLength, inversion;

rhythmArray = [1, 1.5, 2, 1.25, 0.25, 0.25, 1.5, 0.333];
orLength = rhythmArray.sum;
inversion = rhythmArray.reciprocal.normalizeSum*orLength;
inversion.postln;
rhythmArray.sum.postln;
inversion.sum.postln;

::
One might argue that any attempt to preserve the total duration is a convolution and that
when you invert time you invert time and should get a different total duration. I guess if you take
this view then you need to make sure you invert all voices at once. That, or not care that the
results in other voices don't match. You have my blessing.
Pbind
links together different parameters of musical events. It streams those values using a
pattern to the current Environment. The Environment is another behind the scenes structure we
haven't worried about until now. It contains a group of global default values attached to symbols.
Below is an incomplete list. Notice that the same value is often expressed in different ways: freq
and midinote, amp and dB.
Values are passed to the environment with Pbind by matching a symbol (e.g. \freq) with
the value (e.g. 400) or a function that returns a value (e.g. rrand(400, 900)). If none is supplied,
defaults are used. Defaults allow you to focus on one or two elements of composition. If you just
want to experiment with pitch you don't have to specify amplitude, duration, instrument, etc. It
will use the defaults (\amp = 0.1, \db = -20, \degree = 0, \dur = 1, \freq = 261.62, \legato = 0.8,
\midi = 60, \note = 0, \octave = 5, \out = 0, \pan = 0, \root = 0, \scale = [0, 2, 4, 5, 7, 9, 11],
\server = default, \velocity = 64, \instrument = default, \out = 0, \group = 0). For example, the
simplest line of code is ().play. It generates a single pitch.




283
25.7:: Environment Variables and Defaults
().play // uses all defaults

('pan': -1, 'sustain': 0.1, 'freq': 1000).play // overrides defaults

::
Before using Pbind you have to load the synth description library. For all the examples in
this chapter I will assume you have run the code below. The following line shows the simplest
Pbind, which sets just one value; frequency. The symbol is \freq, the value is 600.
25.8:: Read global library

SynthDescLib.global.read

Pbind(\freq, 600).play
::
Below are some examples. The first shows a Pfunc that evaluates any function, in this
case random values for pitch. The second adds duration. The third passes midi pitches by way of
the symbols \degree and \octave. Degree is a scale degree, octave is the octave, where 5 is the
octave above middle C (C4 to B4).
25.9:: Pbind with frequency function

Pbind(\freq, Pfunc({rrand(100, 900)})).play;

Pbind(\freq, Pfunc({rrand(100, 900)}), \dur, Pfunc({rrand(0.1, 1.5)})).play

(
Pbind(
\degree, Pfunc({8.rand}),
\octave, Pfunc({rrand(3, 7)}),
\dur, 0.2).play
)

(
Pbind(
\scale, [0, 2, 4, 6, 8, 10],
\degree, Pfunc({6.rand}),
\octave, Pfunc({rrand(3, 7)}),
\dur, 0.2).play
)

(
Pbind(
\scale, [0, 2, 3, 5, 6, 8, 10, 11],
\degree, Pfunc({8.rand}),



284
\octave, Pfunc({rrand(3, 7)}),
\dur, 0.2).play
)
::
All of the instruments you've designed up until now are available in the environment. All
of the arguments that you created in conjunction with those instruments are symbols that can be
matched to values. If you happened to have used arguments like midinote, then they will fit right
into the existing Environment. If you named them something else, such as midiPitch and art for
articulation, you just need to use those symbols. Earlier we defined an instrument called Pluck.
I've reproduced it below in case you want to redefine it.
25.10:: Pbind, Previous Instrument Def

(
SynthDef("Pluck",
{
| t_trig=1, midi=60, legato=1, vel=0, amp = 0.7, pan=0, out=0 |
Out.ar(out,
Pan2.ar(
Pluck.ar(BrownNoise.ar(0.5), t_trig,
10.reciprocal, midi.midicps.reciprocal, legato, vel, amp),
pan)) *Linen.kr(t_trig, 0, 1, legato, 2)
}).add.play
)

(
Pbind(
\instrument, "Pluck",
\midi, Pfunc({rrand(34, 72)}),
\dur, 0.4,
\legato, 0.8, // try longer values
\vel, 0.1,
\amp, 0.9
).play
)
::
Legato
is a bit of a misnomer. As mentioned early, I distinguish between duration and next
event. In Pbind, dur is used as both. The actual duration of an event is determined by legato,
which is a percentage of dur. The default is 0.8. Given a duration (time until next event) of 4 the
actual duration would be 3.2 (4 * 0.8). Legato could be used for actual duration. For this reason
the Pluck has been modified slightly. The argument dur has been replaced with legato. A legato
of 2 and a duration of 4 becomes a duration of 8 with next note at 4.
Pbind is a powerful tool for mutation. The next example is a model for interpolation
studies in pitch. The midinote is determined by a routine; a function that remembers previous
states, such as the counter. The melody is a Bach invention. If you are familiar with the original I




285
should point out a couple of cheats: the melody is transposed to a single octave (once we get into
the transformations the effect is the same) and I repeat some notes to dodge the issue if rhythmic
values. Likewise, the effect is the same. Rather than enter exact MIDI values the pitches are
referenced using a degree and scale array. Scale is the whole/half-step orientation of harmonic
minor. Degree is which step of that scale to use. The advantage of these two combined is that it
allows you to change the mode (e.g. from harmonic minor to Lydian) without having to reenter
all the notes from scratch.
The degree array is adjusted by 1 only to cater to the musical mind. Index numbers are
normally 0, 1, 2, for scale steps 1, 2, and 3. But typing out or changing notes in the melody is
much easier if 1 is the first step of the scale. [1, 3, 5] is a tonic arpeggio rather than [0, 2, 4].
25.11:: Pitch Model for Mutation
(
var degreeSeq, nextPitch, scale, mul = 1;

scale = [0, 2, 3, 5, 7, 8, 11];

degreeSeq = [1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2,
3, 3, 5, 5, 1, 1, 4, 4, 7, 7, 2, 2] - 1;


nextPitch = Routine({
inf.do({arg count;
scale.wrapAt(degreeSeq.wrapAt(count*mul)).yield;
if(count%20 == 19, {mul = mul + 1});
//if(count%6 == 5, {12.rand.yield});
//if(count%6 == 5, {scale.put(scale.size.rand, 12.rand)});
})
});

Pbind(
\instrument, "Pluck",
\midi, nextPitch + 60,
\dur, 0.1
).play
)

::
Of course the instrument can be a MIDI client. This immediately multiplies the variety of
instruments available.
There are a dozen or so useful patterns (look in the Streams help file). I'll demonstrate
Prand, Pseries, Pseq
Prand returns a random choice from an array (see also Pwrand, for weighted random
pattern), Pseries returns a series of values with arguments for start, step, and length. Pseq steps
through an array of values. They can all be nested, as shown in the last example.



286
25.12:: Patterns

(
f = 100;

Pbind(
\instrument, "Pluck",
\midi, Pfunc({
f = ([3/2, 4/3].choose) * f;
if(f > 1000, {f = f/8}); //.fold or .wrap didn't do what I wanted
f.cpsmidi
}),
\dur, 0.2
).play

)

(
Pbind(
\instrument, "Pluck",
\midi, Prand([60, 62, 64, 65, 67, 69, 70], inf),
\dur, 0.1
).play

)

(
// The dur array is 1s and 2s, representing eighth notes.

Pbind(
\instrument, "Pluck",
\midi, Pseq([70, 58, 60, 62, 60, 58, 65, 62, 70,
65, 62, 65, 63, 62, 63, 65, 58, 62, 65, 69], inf),
\dur, Pseq([2, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 1, 1, 1, 1, 2, 2, 2, 2, 2] * 0.2, inf)
).play
)
::
And of course, you can run several Pbinds. (Bach would have wanted it that way.) Try 1
or 0.5 as the last dur for 2 and 3. Pbind also responds to mute and unmute. Listen to this example
long enough to hear the phase shift:
25.13:: Parallel Pbinds
(
a = Pbind(
\instrument, "Pluck",
\midi, Pseq([70, 58, 60, 62, 60, 58, 65, 62, 70,
65, 62, 65, 63, 62, 63, 65, 58, 62, 65, 69], inf),




287
\dur, Pseq([2, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 1, 1, 1, 1, 2, 2, 2, 2, 2] * 0.1, inf),
\pan, -1
).play;

b = Pbind(
\instrument, "Pluck",
\midi, Pseq([70, 58, 60, 62, 60, 58, 65, 62, 70,
65, 62, 65, 63, 62, 63, 65, 58, 62, 65, 69, 72], inf),
\dur, Pseq([2, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2] * 0.1, inf),
\pan, 0
).play;

c = Pbind(
\instrument, "Pluck",
\midi, Pseq([70, 58, 60, 62, 60, 58, 65, 62, 70,
65, 62, 65, 63, 62, 63, 65, 58, 62, 65, 69, 72, 69], inf),
\dur, Pseq([2, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2] * 0.1, inf),
\pan, 1
).play;
)

a.mute;
b.mute;
a.unmute;
c.mute;
b.unmute;
c.unmute;

// Phase shift with consistent beat; 'q' allows it to evolve

(

p = Array.fill(20, {[0, 2, 4, 7, 9].choose + [60, 72].choose}).postln;
q = p.copyRange(0, p.size - 2).postln;
Pbind(
\instrument, "Pluck",
\midi, Pseq([Pseq(p), Pseq(p), Pseq(p)], inf),
\dur, 0.1,
\pan, -1
).play;

Pbind(
\instrument, "Pluck",
\midi, Pseq([Pseq(p), Pseq(p), Pseq(q)], inf),
\dur, 0.1,
\pan, 1
).play;
)



288

// Or gradual phase between beats
(

p = Array.fill(20, {[0, 2, 4, 7, 9].choose + [60, 72].choose}).postln;
Pbind(
\instrument, "Pluck",
\midi, Pseq(p, inf),
\dur, 0.1,
\pan, -1
).play;

Pbind(
\instrument, "Pluck",
\midi, Pseq(p, inf),
\dur, 0.101,
\pan, 1
).play;

Pbind(
\instrument, "Pluck",
\midi, Pseq(p, inf),
\dur, 0.102,
\pan, 0
).play;
)
::
Pbind is a perfect tool for serialization. Below is a 12-tone example with rhythm partially
serialized (mixed with aleatory), and dynamic levels also part serialized part random.
25.14:: Serialism

(

// If seed is any number other than 0 that seed will be used.
// If 0, a random seed will be picked and posted. Use it to
// repeat a performance.

var seed = 0;

if(seed !=0, {thisThread.randSeed = seed},
{thisThread.randSeed = Date.seed.postln});

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].scramble.postln;
r = [0.1, 0.1, 1.0, 0.2, 0.3, 0.166, 0.166] * 16;
l = [1, 1, 0.7, 0.1, 2, 4];
v = [0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9];
o = [48, 60, 72];





289
Pbind(
\instrument, "Pluck",
\pan, 0,
\midi, Prand(
[ //P, R, I, IR
Pseq(a) + o.choose,
Pseq(a.reverse) + o.choose,
Pseq(12 - a) + o.choose,
Pseq((12 - a).reverse) + o.choose
], inf),
\dur, Pseq([Prand([0.1, 0.2, 0.5, 1.0], 7),
Prand([Pseq(r), Pseq(r.reverse)], 1)], inf),
\legato, Prand([Pseq(l), Pseq(l.reverse)], inf),
\vel, Pseq(v, inf),
\amp, Prand([
Pseries(0.1, 0.1, 5), // cresc
Pseries(0.9, -0.1, 6), // decresc
Prand([0.1, 0.3, 0.5, 0.7], 5)
], inf)
).play;

Pbind(
\instrument, "Pluck",
\pan, -1,
\midi, Prand(
[ //P, R, I, IR
Pseq(a) + o.choose,
Pseq(a.reverse) + o.choose,
Pseq(12 - a) + o.choose,
Pseq((12 - a).reverse) + o.choose
], inf),
\dur, Pseq([Prand([0.1, 0.2, 0.5, 1.0], 7),
Prand([Pseq(r), Pseq(r.reverse)], 1)], inf),
\legato, Prand([Pseq(l), Pseq(l.reverse)], inf),
\vel, Pseq(v, inf),
\amp, Prand([
Pseries(0.1, 0.1, 5), // cresc
Pseries(0.9, -0.1, 6), // decresc
Prand([0.1, 0.3, 0.5, 0.7], 5)
], inf)
).play;

Pbind(
\instrument, "Pluck",
\pan, 1,
\midi, Prand(
[ //P, R, I, IR
Pseq(a) + o.choose,
Pseq(a.reverse) + o.choose,
Pseq(12 - a) + o.choose,
Pseq((12 - a).reverse) + o.choose



290
], inf),
\dur, Pseq([Prand([0.1, 0.2, 0.5, 1.0], 7),
Prand([Pseq(r), Pseq(r.reverse)], 1)], inf),
\legato, Prand([Pseq(l), Pseq(l.reverse)], inf),
\vel, Pseq(v, inf),
\amp, Prand([
Pseries(0.1, 0.1, 5), // cresc
Pseries(0.9, -0.1, 6), // decresc
Prand([0.1, 0.3, 0.5, 0.7], 5)
], inf)
).play;
)

::
This model can realize any serial works you would write out by hand. The code doesn't
have to be the work or the performance. It could be a testing ground. Once you've found a
variation you like (change the random seed for different variations), copy it out and hand it to
performers.
Exercises
25:1 Transcribe one of Webern's piano works into arrays of numbers. Do a single array
for pitch class, another for octave, duration (time until next) and legato (duration of
this event). For pitch class use a single array with P0. Construct a Pbind with nested
Pseq to accurately reproduce the work as written. (Optional: For pitch, use single
array containing only P0, then reverse, (12-array)%12) and +, -n for retrograde,
inversion, and transpositions). Continue to experiment by swapping out versions of
the row, inverting or reversing durations, dynamics, or inserting occasional random
choices. Are you able to generate variations that retain the essential character of the
original? At what point does it cease to be Webern, and begin to be you?






291
26. Working With Data
Twelve-tone and set class theory. Some background in text.
ASCII
is the American Standard Code for Information Interchange. Like MIDI, it allows for
accurate interchange of text characters between operating systems and programs. The numbers 0
through 31 are non-printing characters; computer commands such as carriage returns, warning
beeps, end of line, back space, and synchronous idle in case you need your idles to be
synchronized. The numbers 32 through 126 are characters that make up text. The current
incarnation of ASCII is Unicode, which in its latest version accounts for every character in every
language ever written, and yes, it includes dead languages. That is frickin' cool. ASCII will serve
in converting information from text to numbers and vice versa. The chart below shows the most
useful of the first 127 characters.

0 00 Null char
7 07 Bell
8 08 Back Space
9 09 Horizontal Tab
10 0A Line Feed
13 0D Carriage Return
22 16 Synchronous Idle
24 18 Cancel
27 1B Escape
32 20
33 21 !
34 22 "
35 23 #
36 24 $
37 25 %
38 26 &
39 27 '
40 28 (
41 29 )
42 2A *
43 2B +
44 2C ,
45 2D -
46 2E .
47 2F /
48 30 0
49 31 1
50 32 2
51 33 3
52 34 4
53 35 5
54 36 6
55 37 7
56 38 8
57 39 9
58 3A :
59 3B ;
60 3C <
61 3D =
62 3E >
63 3F ?
64 40 @
65 41 A
66 42 B
67 43 C
68 44 D
69 45 E
70 46 F
71 47 G
72 48 H
73 49 I
74 4A J
75 4B K
76 4C L
77 4D M
78 4E N
79 4F O
80 50 P
81 51 Q
82 52 R
83 53 S
84 54 T
85 55 U
86 56 V
87 57 W
88 58 X
89 59 Y
90 5A Z
91 5B [
92 5C \
93 5D ]
94 5E ^
95 5F _
96 60 `
97 61 a
98 62 b
99 63 c
100 64 d
101 65 e
102 66 f
103 67 g
104 68 h
105 69 i
106 6A j
107 6B k
108 6C l
109 6D m
110 6E n
111 6F o
112 70 p
113 71 q
114 72 r
115 73 s
116 74 t
117 75 u
118 76 v
119 77 w
120 78 x
121 79 y
122 7A z
123 7B {
124 7C |
125 7D }
126 7E ~
127 7F Delete

String is short for string of characters. In SC, a string is defined by quotes. But it is
equivalent to an array of numbers that correspond to characters. The string can therefore be
treated as an array. Try each line of code in example 26.1 one at a time. The message ascii
returns the ASCII numbers for a string. It can be converted to and from text.



292
26.1:: String as Array
"This is a string"

"But it is also an array".ascii

"Equals".ascii == [ 69, 113, 117, 97, 108, 115 ]

"Items can be referenced".at(3)

"Items can be referenced".at(3).ascii

"Each character has an ascii value.".do({|ch, ct| [ct, ch.ascii, ch].postln})

["an", "array", "of", "arrays"].ascii

(
[ 67, 111, 110, 118, 101, 114, 116, 32, 97,
110, 32, 97, 114, 114, 97, 121, 46 ].do({|ch| ch.asAscii.post}); ""
)

[ 83, 116, 114, 105, 110, 103 ].asString // works, but not the result you might expect

"440".ascii

"440".asInteger // converts the string to the number it represents

::
12-Tone Matrix
It's fitting (and ironic) that the computer came into wide use near the end of the 20
th

century. The styles that emerged earlier in that centuryserialism, total control, set theory, but
also minimalism, aleatory, and micro-tonalityare perfectly suited for programming.
Dodecaphonic styles carefully balance the interval content to avoid tonality. This is achieved
through even distribution of all 12 pitches and a series that excludes stable intervals.
Composition (and analysis) in this style begins with the series or row, then a matrix which
represents 144 possible variations: original in all 12 transpositions, retrograde in 12
transpositions, inversion and inverted retrograde, also in all 12 transpositions.
These examples use the row from Webern's Kinderstuck: E E C B B C D A A G, F
F, or 3, 4, 0, E, T, 1, 2, 9, 8, 7, 6, 5. The first step in parsing this series is to transpose it down a
minor third to produce the original then produce all other transpositions. Transposition up or
down presents a small problem. Transposing beyond 12 presents a problem. T plus 5 equals 13,
which is out of the range of a 12-tone set. Transposing down presents a similar issue; 0, 1, and 2,
when reduced by 3 are negative, which are not appropriate values for pitch. Both problems can
be solved using a modulo 12 (%12), which keeps the values within the range of a single octave
(0 to 11). You can think of a modulo as wrapping around 0 and the mod number. Positive and
negative numbers both wrap around. Below is a series of positive and negative numbers mod 3:




293
0 1 2 3 4 5 6 7 8 9 10 11 and -9 -8 -7 -6 -5 -4 -3 -2 -1 0
%3: 0 1 2 3 0 1 2 3 0 1 2 3 and 3 0 1 2 3 0 1 2 3 0
Notice that when negative numbers wrap, they seem to be going backwards. But this
should be familiar to anyone who has worked with a 12-tone "clock" in dodecaphonic analysis.
It's also consistent with how musicians parse subsequent octaves. G (7) plus a sixth (9) equals
16, but we think of it as 4 (E) in the next octave. Similarly G (7) minus a sixth (9) is -2, but we
think of it as 10 (B) in the lower octave.
Pitch: Bb B C C# D Eb E F F# G Ab A Bb B C C# D Eb E
%12: T E 0 1 2 3 4 5 6 7 8 9 T E 0 1 2 3 4
-2 -1 0 1 2 3 4 5 6 7 8 9 T E 12 13 14 15 16
Inversion has must be treated the same way. It flips the interval on the 0 axis. G (a fifth
above, or 7) inverts to F (a fifth below, -7, but 5). An interval plus its inversion equals 12. But
modulo will help here too. 7.neg%12 will return 5.
26.2:: 12 Tone Math
// Original
[3, 4, 0, 10, 11, 1, 2, 9, 8, 7, 6, 5]

// Transpose down 3 with %12 for original
r = ([3, 4, 0, 10, 11, 1, 2, 9, 8, 7, 6, 5] - 3)%12;

// Transposition
(r + 5)%12 // O5

// Inversion
r.neg%12 // I0

// Inversion and transposition
(r.neg + 5)%12 // I5

// Retrograde transposition
(r.reverse + 5)%12 // R5

// IR transposition
(r.neg.reverse + 5)%12 // IR5

// Matrix

r.neg.do({|i| postln((r + i)%12) }); ""

::
A matrix is every transposition of the original row, but ordered from top to bottom by
inversion. To generate a matrix, calculate the inversion first, then do the inversion, passing each
inversion value to be used for the transposition. Simple, concise. But there are still a few more
tricks. Most post-tonal theorists use either A and B or T and E for 10 and 11. It's faster to write,
and things line up better. To use this nomenclature in SC two things have to happen: every time



294
we type a T or E in code, the program must read that as 10 and 11. The second is that whenever
SC generates a 10 or 11, it must print T and E. The first trick is simple, with a footnote; set the
global variables t and e to 10 and 11. The footnote, printed up here in the main text, is that you
have to use lower case letters because variables cannot be upper case. The second trick requires a
map. This is done with an array containing the numbers 0 through 9 then the strings "T" and "E".
The array is referenced using the @ symbol, which works on single items and arrays. p@11 =
"E". p@[0, 10, 5, 11] = [0, T, 5, E]. It may seem superfluous to translate 0 through 9 into 0
through 9 just to get to ten and eleven. All other methods I know are more convoluted, requiring
if statements. This method also works with pitch class letters. If p is ["C ", "C#", "D ", etc., then
p@1 is C#.
Note the extra space character after pitches without accidentals. This is to keep things
tidy. You can also use a fixed font to line up the columns better. Switch to the post window, open
Format/Font/Show Fonts and choose courier (or ~post.font_(Font("Courier", 18));). This will
line all characters evenly. You can include the e, t, and the p definitions in the startup file (see
Chapter 19) so it will be available in any code.
26.3:: T and E
t = 10; e = 11;

p = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "T", "E"];

//p=["C ", "C#", "D ", "Eb", "E ", "F ", "F#", "G ", "Ab", "A ", "Bb", "B "];

p@0

p@10

p@[0, 5, 10, 4, 11]

// Transpose down 3 using t and e
r = ([3, 4, 0, t, e, 1, 2, 9, 8, 7, 6, 5] - 3)%12;

// Matrix

(r.neg).do({|i| postln(p@((r + i)%12)) }); ""
::
To illustrate serial variation we will use a short quotation from the Kinderstuck. The first
step is to transcribe the events into arrays representing each dimension; pitch, octave, begin time,
duration and amplitude. In the dodecaphonic style, pitches can be repeated, but must be
contiguous. For this reason we need two arrays for pitch; one with the series of pitches, and one
that tracks how each is used, including repeated pitches. For example, the row may be [6, 0,
4], but the actual piece may use the pitch at position 1 four times in a row, so the pitch array
will be [0, 1, 1, 1, 1, 2].
The octave component is parsed separately. This is not only simpler, easier to realize, but
allows for interesting variations.




295
The next two parameters are begin time and duration. Since this work is metered, integers
can be used to represent the smallest possible duration. The sequence 1, 2, 1, 4, for example, can
represent units of 0.125 seconds. Duration uses the same system.
Finally, amplitude can have a range of 0 to 127. Webern uses only three dynamics: 50
(pp), 70 (p), and 90 (mp).
These values are stored in an array of arrays. The enclosed arrays contain row, row
position, octave, start time, duration, then amplitude. The heart of the playback is the k.do. In
previous examples playback was managed with a Task and a wait time between events. In this
example, since the events are scheduled, they can be set all at once. This short quotation is then
enclosed in a task with a wait time equal to the total events in the sample. Each time the task is
repeated thisRow is set to one of the 144 versions, original, inversion, retrograde, and inverted
retrograde, which is randomly transposed from 0 through 11.
The variable thisRow has built-in alternatives enclosed in an array. Choose different
alternatives using @0 through @3. The first is the original row, the second a random collection
of 12 pitches, then a whole tone scale (0 through 22, so that the total is 12), the pitch set 0, 1, 5
and 6, (again duplicated to total 12), and finally the 144 possible versions of the row.
26.4:: Kinderstuck Segment
MIDIClient.init; m = MIDIOut(0, MIDIClient.destinations.at(0).uid); m.program(0, 4);


~pc = ["C ", "C#", "D ", "Eb", "E ", "F ", "F#", "G ", "Ab", "A ", "Bb", "B "];

// Kinderstuck: row position, octave, duration, start time, vel
// pp = 50, p = 70, mp = 90

k = [[ 0, 3, 0, 1, 70 ], [ 1, 6, 0, 1, 70 ], [ 0, 3, 1, 1, 70 ], [ 1, 6, 1, 1, 70 ], [ 0, 3, 2, 1, 70 ], [ 1, 6, 2, 1, 70
], [ 2, 5, 4, 1, 70 ], [ 2, 5, 5, 1, 70 ], [ 2, 5, 6, 1, 70 ], [ 3, 4, 10, 1, 50 ], [ 4, 5, 10, 1, 50 ], [ 3, 4, 11, 1,
50 ], [ 4, 5, 11, 1, 50 ], [ 3, 4, 12, 1, 50 ], [ 4, 5, 12, 1, 50 ], [ 5, 5, 14, 1, 90 ], [ 5, 5, 15, 1, 90 ], [ 5, 5,
16, 1, 90 ], [ 6, 6, 20, 4, 70 ], [ 7, 6, 20, 4, 70 ], [ 8, 5, 20, 4, 70 ], [ 9, 4, 24, 1, 70 ], [ 10, 5, 24, 1, 70
], [ 11, 6, 24, 1, 70 ]];

~or = [ 0, 1, 9, 8, 7, 10, 11, 6, 5, 4, 3, 2 ];
(([~or, 12-~or, ~or.reverse, (12-~or).reverse] + 12.rand)%12).choose;

(
r = Task({
var thisRow;
4.do({
thisRow = [ ~or, {12.rand}!12, (0, 2..22), {[0, 1, 5, 6].choose}!12,
(([~or, 12-~or, ~or.reverse, (12-~or).reverse] + 12.rand)%12).choose.postln]@0;
~pc.at(thisRow).postln;
k.do({|i|
var note;
note = thisRow.at(i.at(0)) + (i.at(1) * 12);
thisThread.clock.sched(i.at(2) * 0.125,
{m.noteOn(0, note, i@4)});



296
thisThread.clock.sched((i.at(2) * 0.125) + (i.at(3) * 0.125),
{m.noteOff(0, note); nil});
}); nil;
(26 * 0.125).wait;
});
});
r.start
)

m.allNotesOff(1); m.allNotesOff(0);

::
Here is what I hope you discover. The original version of the row will repeat the same
pitches. One time through gives the impression of randomness, but its random quality fades with
each repetition. Yet the essential character of the phrase remains the same. This is because it is
not random, rather a carefully composed dodecaphonic series which avoids reference to tonic.
The whole tone scale has a very clear character too, as does the pitch class set. But the first
(original version) and the fourth (any version of the row), though clearly different from each
other, belong to the same genus. Each just as valid as the last. It is, as Webern states, a work of
nature. But the first and second versions have very different characters; different species, so to
speak.
The entire work can easily be coded in half an your. It does take time, but once it's
entered variations can be explored with instant results. Try these
Kinderstuck Variations
The first variation employs the non-linear placement of start and stop times. Since the
notes aren't being generated in real time, the start and stop time can be arbitrary. For example,
you first pick the pitch, then choose where along the 24 beat timeline it will appear. Non-tonal
styles rely heavily on dissonant intervals. To maintain this coherence intervals must be
contiguous. This method thwarts that style of organization. Will it maintain it's dodecaphonic
distribution?
The next is similar, and construes Webern's choice of sequence by replacing his row with
a simple chromatic scale: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]. Again, will it retain a non-tonal
character? If it does, is 12-tone practice necessary?
Substitute Webern's row with the subject to Bach's "12-tone" fugue: [6, 2, 11, 7, 6, 11,
10, 4, 3, 0, 11, 6, 5, 2, 1, 0, 9, 6, 8, 9]. This work illustrates the difference between non-tonal and
highly chromatic music. Bach uses all 12 tones, but the music is clearly tonal. Try both ordered
and non-linear placement. Does that make a difference?
Substitute the row position with a simple counter. That is, no repeated notes. Each event
advances to the next pitch in the row. Better? Worse? Interesting?
Next try a quarter tone row, perhaps: [0, 0.5, 4.5, 4, 3.5, 5, 5.5, 3, 2.5, 2, 1.5, 1, 6, 6.5,
10.5, 10, 9.5, 11, 11.5, 9, 8.5, 8, 7.5, 7] (the row halved, then the same halved row up a tritone).
Will it sound even more non-tonal, or have the same degree of even distribution?




297
How about Josie by Steely Dan?
[4 2 5 1 3 t 4 e 4 2 5 1 3 t e 5 2 9 4 9 8 7 5 e 5 4 7 0 4 6 1 e 4 9 e 2 9 2 5 8 0 5 7]
Also highly chromatic, but still tonal. The tritone is used only once. Clever composition
skills or accident?
Enter the times and durations of Josie, but use Webern's row. Dig up a copy of
Microcosmos (Bartok) for more material.
This is further illustration of the last chapters claim to fast turn around in computer
music. All of these variations can be done within an hour.
Working With Files
When using large collections of modular data, and switching between different sets of
data, it is practical to store information in a separate file. The composition, that is the organizing
method, can exist separate from the data files. OS X is Unix, so SC has a full set of Unix file
management tools (getLine, getChar, getInt8, getInt16, etc.). There is a FileReader class, but I
didn't have much luck with it. We will use the File class.
A word about
Path Names
When SC (and most programs) is asked to open a file it first looks for that file in its own
home directory. In such a case the pathname can just be the name of the file ("MyFile"). If it
resides anywhere else, a folder hierarchy must be included. The hierarchy is indicated with folder
names separated by a slash. ("/Users/Students/Documents/Computer Music/Data Files/MyFile")
If the data file resides in a folder which is in the folder where SC resides, then the pathname can
begin with that folder ("/Data Files/MyFile").
SC can manage a number of file types including pure zeros and ones. The most useful for
us is text, because it can be edited easily. Most applications use hidden format characters (similar
to html). To illustrate, create a new file in TextEdit and type k = [[0, 3, 0, 1, 70]], save it as
myfile in the SuperCollider folder (in the Applications folder), then run the lines below one at a
time. Note that even though you saved the file as myfile, File needs the full name, which is
myfile.rtf.
26.5:: Reading a File
g = File("myfile.rtf","r");
g.readAllString;
g.close;

::
You will see much more than the single line of code.
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fnil\fcharset0 Chalkboard;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\
pardirnatural
\f0\fs36 \cf0 k = [[ 0, 3, 0, 1, 70 ], [ 1, 6, 0, 1, 70 ], etc,



298
Word files are worse. Not only do they contain prodigious amounts of formatting
information, but each file is a package containing a dozen files with similar formatting material:
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"
xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-
compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml"
[removed about 16 lines]
<w:body><w:p w:rsidR="000A0AD8" w:rsidRDefault="00635552"><w:proofErr w:type="gramStart"/><w:r><w:rPr><w:szCs
w:val="36"/></w:rPr><w:t xml:space="preserve"> = [ 0, 3, 0, 1, 70 ], [ 1, 6, 0, 1, 70 ], [ 0, 3, 1, 1, 70 ], [ 1, 6, 1, 1, 70
];</w:t></w:r><w:bookmarkStart w:id="0" w:name="_GoBack"/><w:bookmarkEnd w:id="0"/></w:p><w:sectPr w:rsidR="000A0AD8"
w:rsidSect="0059217E"><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800"
w:header="720" w:footer="720" w:gutter="0"/><w:cols w:space="720"/></w:sectPr></w:body></w:document>
The default SC format is simple text (though with the ".scd" extension). To test this,
repeat Example 26.5 but first enter text into an SC document and save it in the SC folder. Change
"myfile.rtf" to "myfile.scd". This is handy, because we don't have to parse the extra formatting
characters. (If working with rtf files, replace readAllString with readAllStringRTF, which strips
the file of rich formatting. I prefer plain text files because they can be used as data files, and text
is more portable and easier to parse.)
There are also options for reading the data. You can retrieve a line at a time, a character,
or blocks of 0s and 1s (see UnixFile help). If the file requires a lot of parsing it may not be worth
the trouble. Typically I use external files for a single large block of data that can be read and
interpreted all at once.
One last step. The readAllString reads the information as a string, not code. If you want
to use it as code, the message interpret takes a string and executes it as if it were code.
26.6:: Interpret
{100.rand}!10 // code that runs

"{100.rand}!10" // just prints the string

"{100.rand}!10".interpret // interprets a string as code

::
We also have choices in identifying the file. If the file changes often, and you're not
always sure where it is, use openDialog, as we did with the audio files (Example 26.7). The open
dialog takes three arguments. The first is the prompt, which as far as I can determine has no
effect, the function to be executed on a successful open, and the function (usually an error
message) if the open fails, which is unlikely given you used the dialog to select the file. But if
you are using the same file over and over, the open dialog is a few extra steps, so entering it
explicitly works well. Finally, a clever shortcut for determining the file path name: drag a file to
an open SC window. It will place the path in quotes, which can then be used as an explicit
location.
It is useful to use a global variable to open the file, so that it will be available throughout
your code.




299
26.7:: Open File
// Open then print any pathname for later use

File.openDialog("Select a file", { arg pathName; pathName.postln});

// Open using a dialog
(
var input, filePointer; //declare variables
File.openDialog("", {arg pathname;
filePointer = File(pathname, "r");
input = filePointer.readAllString;
input.postln;
// Everything has to be inside this function
},
{"File not found".postln});
)

// Or open file and store in global

(
var filePointer; //declare variables
File.openDialog("", {arg pathname;
filePointer = File(pathname, "r");
~input = filePointer.readAllString;
},
{"File not found".postln});
)

// Explicit location:

~fp = File("/Users/Students/Documents/Work/Test.txt", "r");


// Then

~input.postln;

// Or include ~input in the patch.


::
SC can be used in for analysis or composition in the style of
Set Theory
Any of the examples above could be modified using sets, or, as with the Kinderstuck,
several works can be mixed, swapping pitch set data. As an exercise, we will do some analysis. I
will assume the reader has a basic understanding of set theory.



300
Fig. 26-1 Set Theory Clock
The steps to finding the normal form (most compact arrangement)
of a pitch class set are intuitive and simple, especially when using a clock
face. Figure 26.1 shows a set theory clock with the pitches 6, 9 and T
highlighted. For normal order, first locate the largest gap in a set. The two
pitches at the beginning and end of that gap are candidates for the first
pitch of normal order. In this example, T and 6. The next step is to quickly
invert the set (or just go backward on the clock) to see which produces the
smallest intervals. That is normal order. The final step is to transpose that
form to 0. Just a glance shows that T, 9, 6 are more compact, because 6, 9, T has the 6 to T
interval, but also the 6 to 9, which is larger than T to 9. To calculate normal order, start at T and
move counterclockwise; 0, 1, 4.
Such a simple process for us, but very difficult to describe to a computer. I've spent
many, many hours trying to work out a clever way to parse a set of pitches. But as much as I love
elegance ((r.neg).do({|i| postln(p@((r + i)%12)) });), the "hammer" method takes about 10
minutes (human time) and milliseconds (CPU). This method requires a data file with all possible
set classes. Once you have that collection in place, you can simply do a search. To search, you
have to produce all possible variations of the set with each pitch as 0, forward and backward.
26.8:: Set Versions
p = [6, 9, t];

// rotate to start at each pitch in set, transposed to 0
q = Array.fill(p.size, {|i| (p.rotate(i) - p.rotate(i).at(0))%12});

q ++ (q.neg)%12; // add inversions

::
From there it's a simple match operation with the entire collection of possible sets. First,
create a separate file with the sets below and save it as pclasses in the SuperCollider folder (in
the applications folder). Most pitch class charts show number, Forte number, prime, and vector.
In this example I just use the set and the interval vector. I've also entered just the first three
dozen sets. The entire collection is, of course, in my startup file.
[["0", "000000"], ["01", "100000"], ["02", "010000"], ["03", "001000"], ["04", "000100"],
["05", "000010"], ["06", "000001"], ["012", "210000"], ["013", "111000"], ["023", "111000"],
["014", "101100"], ["034", "101100"], ["015", "100110"], ["045", "100110"], ["016", "100011"],
["056", "100011"], ["024", "020100"], ["025", "011010"], ["035", "011010"], ["026", "010101"],
["046", "010101"], ["027", "010020"], ["036", "002001"], ["037", "001110"], ["047", "001110"],
["048", "000300"], ["0123", "321000"]];
26.9:: Locate Pitch Class Set

// First save the data above to a file: pclasses.scd.

~sampleSets = File("pclasses.scd", "r").readAllString.interpret;
// ~sampleSets = File("/SomeOtherDirectory/pclasses.scd", "r").readAllString.interpret;




301

// Test to make sure it read the data and understood it. Should display "[01, 10000]".
~sampleSets.at(1);

(
var set, or, inv, all;

// choose one to test
set = [[4, 5, 1], [2, e, 0], [5, 6, 7, 8], [2, 9, 5]].choose;
"Example: ".post; set.postln;
// rotate and transpose to 0
or = Array.fill(set.size,
{|i| set.rotate(i) - set.rotate(i).at(0)});
all = (or ++ or.neg)%12; // add inversions
all.postln; "Set class: ".post;
~sampleSets.do({|eachSet|
var setArray;
setArray = eachSet.at(0).ascii -48; // Convert string to interval array
all.do({|eachForm| if(eachForm == setArray, {eachSet.postln})})
});
""
)

::
The test sets are a transposition and/or inversion of one of the sample sets. (Replace
sample sets with the entire collection if you want to try your own. You will have to deal with the
"T" and "E" conversion.) To locate prime the set is rotated then transposed to 0. The inversion is
added to create all possible permutations, one of which must be prime. Note that %12 only needs
to be applied once. These are all compared in turn to the sample sets.
There is one trick of conversion. Sets are presented as a string, but the set being tested is
an array of integers. Conversion is simple since we now know strings are an array of ASCII
integers representing letters. "243".ascii returns [50, 52, 51], which are the ASCII numbers for
characters 2, 4, and 3. Converting them to ASCII, then subtracting 48, which is the ASCII
number for 0, translates a string of numbers into an array of actual numbers.
Cyphers
Using ~pc.at(thisRow) is a sort of cypher or code; systematically replacing one set of
characters with another. In fact, SC can be used to generate a secret-decoder-ring style message.
In the example below, each character in a string is converted to ASCII number then reduced by
32 so that all printable characters become integers 0 through 95. Those numbers are used as an
index to a scrambled array containing 32 through 127. The line [32] ++ (33, 34..127) places 32
at the beginning of the array and scrambles the rest. This preserves 32 as a space. These numbers
are then converted into ASCII. Decoding is a similar process.
The last example is a sloppy reproduction of an old encryption method; rot13.



302
26.10:: Cypher

// seeding is the key to the code
thisThread.randSeed = 1977;
// [32] ++ preserves the position of the space
~code = [32] ++ (33, 34..127).scramble;
// scrambles only lower case
// ~code = (32, 33..96) ++ (97, 98..122).scramble ++ (123, 124..126);

(
// encode
"This is a very simple method for coding text. It will not only scramble and unscramble letters, but
all printing characters such as numbers - 1, 2, 5, 3, 6".do({|ea| ~code.at(ea.ascii - 32).asAscii.post});
""
)

// decode
// you must select it, the "(" throws off the auto select using ( and )

"REFP FP L %G/X PFrusG rG9EWV :W/ =WVFHB 9G<9+ x9 (Fss HW9 WHsX P=/LrNsG LHV
fHP=/LrNsG sG99G/P\ Nf9 Lss u/FH9FHB =EL/L=9G/P Pf=E LP HfrNG/P ? '\ K\ .\ a\ v".do({|ea|
(~code.indexOf(ea.ascii) + 32).asAscii.post}); ""

// rot13; only works with lower case
(
"in the early days of newsgroups and bulletin boards, the function rot13 was a quick and simple way
to encrypt text. it was used to hide punch lines, spoilers, puzzle solutions, or offensive material. if
you performed a rot13 you were essentially saying, ok, let me see it.".do({|ea| if(ea.isAlpha, {(((ea.ascii
+ 13)%26) + 97).asAscii.post}, {ea.post})}); ""
)
::
The Kinderstuck variations are a type of cryptography, swapping out one set of values for
another. The compositional advantage is, as with computers in general, masking our own bias to
explore new ideas.
Cryptograms are common in puzzle magazines. They are easy to crack using distribution
frequency. The letter e is the most common letter in English, followed by t, a, then o. Example
26.11 shows a famous quote as a cryptogram (converted with a variation of 26.10). The text is
converted to ASCII numbers, then stored in a histogram. It is then ordered and compared to the
frequency of letters in English. In the coded example the letter t is the most common, with 56
occurrences. The letter a is next, with 47. These do indeed correspond with e and t from the
original. The next most frequent are f and k (40 and 34), which are probably a or o. The first
word in the cryptogram (af) is either ta or to, so f must be o and k must be a. You can probably
do the rest from that much information.




303
26.11:: To Be
~hist = "af ht, fz lfa af ht, amja gk amt oxtkagfl: bmtamtz 'agk lfhctz gl amt wgle af kxuutz amt
kcglrk jle jzzfbk fu fxazjrtfxk ufzaxlt, fz af ajqt jzwk jrjglka j ktj fu azfxhctk, jle hp fvvfkglr tle
amtw: af egt, af kcttv lf wfzt; jle hp j kcttv, af kjp bt tle amt mtjza-jdmt, jle amt amfxkjle
ljaxzjc kmfdqk amja uctkm gk mtgz af? 'agk j dflkxwwjagfl etsfxacp af ht bgkmte. af egt af kcttv,
af kcttv, vtzdmjldt af eztjw; jp, amtzt'k amt zxh, ufz gl amja kcttv fu etjam, bmja eztjwk wjp
dfwt, bmtl bt mjst kmxuucte fuu amgk wfzajc dfgc, wxka rgst xk vjxkt.".ascii.histo(25, 97, 122);

// order of letter frequency in English
~eng = "etaoinshrdlcumwfgypbvkjxqz".ascii;

~freq = 0!25;
~hist.order.reverseDo({|ea, ct| ~freq.put(ct, [~hist.at(ea), (ea + 97).asAscii, ~eng.at(ct).asAscii])})
~freq

::
A Vigenere system was considered "unbreakable" for hundreds of years.
26.12:: Vigenere Cipher

e = "WITH A SIMPLE ROTATION, EACH LETTER OF THE ALPHABET IS ROTATED BY A GIVEN
AMOUNT. A ROT 1 FOR EXAMPLE, WILL ENCODE THE LETTERS ABC AS BCD. A ROT2 WILL RETURN
CDE. THESE ARE EASY TO CRACK USING PERCENTAGES BECAUSE EACH LETTER WILL HAVE THE
SAME SUBSTITUTION. A VEGENERE CIPHER IS A TYPE OF ROTATION, BUT EACH NEW LETTER IS
ROTATED A DIFFERENT AMOUNT, ACCORDING TO A KEY WORD. IF THE KEY WORD IS BED, THEN
THE FIRST LETTER WILL BE ENCODED WITH ROT 1 (B), THE NEXT IS ROT 4 (E), THEN ROT 3 (D),
AND SO ON. YOU CAN QUICKLY CHECK A VIGENERE BY EXAMINING ALL LETTER A'S IN THE
ORIGINAL. THEY WILL CORRESPOND TO LETTERS IN THE KEYWORD. AAAAAAAAAAA WILL ENCODE
AS BEDBEDBEDBED, IN SOME VARIATION".ascii - 65;

k = "BED".ascii - 65;
// replace with "AAA" for no encoding (rot0), or "LEMONADE" for a more secure code

e.do({|ea, ct| if(ea >= 0, {(ea + k.wrapAt(ct)%25 + 65).asAscii.post}, {(ea + 65).asAscii.post})}); ""

d = "XMWI D WLNTOF UPXDUMRO, FEFI OFXWFV PJ ULH EOQLDCIW MV VRUEWFH CD B JJAHO
DNSXOX. E SSW 1 GSU IBBQSMI, BLMP FRFPHH XKF OFXWFVV EED DT EDH. E SSW2 AJPO
VHUYUO FEI. XKFWH EUF HBWC XR GUBGN YVJRJ THSGHOXDHIV FHDEXTI FEFI OFXWFV XMOM
KBAH XKF VBQH WXCWWJXXUMRO. B YFKHOIUF FJTKFV JW B WATH SI VRUEWJSQ, EVX FEFI
QFB MIWUIU MV VRUEWFH B GJJIFVHOX BQRVRW, DDGRSHLOK US B NFD XSUE. JJ ULH OHA
APVG MV FHE, ULHO WII GMUTX MIWUIU BLMP CI FRFPHHE AJXK VRU 1 (E), ULH RHYX JW SSW
4 (I), WIIQ VRU 3 (G), BRG WR SQ. CPY DEQ UXJGNMD DLHDO B YJKHOIUF EA HYEPJRLOK BPO
PHUXHS D'W JR ULH SUJKLOEO. WIIC BLMP DSUSIVQSQE WP OFXWFVV MQ XKF NFDAPVG.
DBEDBEDBEDB AJPO IQDSGF DT EFHEFHEFHEFH, MQ WRNI WEUJEWJSQ".ascii - 65;

// To decode, simply subtract
d.do({|ea, ct| if(ea >= 0, {(ea - k.wrapAt(ct)%25 + 65).asAscii.post}, {(ea + 65).asAscii.post})}); ""




304
// Gives the illusion of "thinking" about it.
(
r=Task({
d.do({|ea| (ea + 65).asAscii.post; 0.01.wait});
"\n\nTranslation:\n\n".post;
d.do({|ea, ct|
if(ea >= 0, {(ea - k.wrapAt(ct)%25 + 65).asAscii.post}, {(ea + 65).asAscii.post});
0.03.wait})
}).start;
)

r.stop;

::
As a final example of working with files and characters, here is what I use to extract all
the code examples from this document, after saving as a text file.
26.13:: Extracting Code
(
var input = 1, fpr, count = 0, lnct = 0, nm;
nm = Date.getDate.bootSeconds;
fpr = File("/Users/blah/Desktop/ SCDoc.txt", "r");
~fp = File("/Users/blah/Desktop/" ++ nm ++ ".scd", "w");
// read and discard most of the beginning of the document
while({lnct < 500}, {fpr.getLine.postln; lnct = lnct + 1;});
while({input.notNil}, {
input = fpr.getLine; lnct = lnct + 1;
// [input, input.isNil].postln;
if(input.asString.find("----") != nil,
{count = count + 1; ~fp.write("\n" ++ lnct ++ "\n")});
// count turns the write process on and off
if(count%2 == 1, {~fp.write(input)});
});
~fp.close;
)

::





305
Exercises
26:1 Realize two of the Kinderstuck variations.
26:2 Find a sound effect for a single typewriter key press. Add playback of this effect to
the last example of 26.12.
26:3 Write your own Kinderstuck variation.




306
27. Maps, Masks, and Markovs
Probability tables, external sources.
Music from Non-Musical Ideas
Nearly all music is influenced by some extra-musical criteria. In traditional styles it may
be a text, a painting, geometric patterns, or philosophical ideas. In the 20
th
Century composers
have expanded this influence to include natural data such as electrical impulses from plants,
position of stars, a mountain silhouette, or rain and snow patterns. Given the freedom of styles in
modern music (not bound, for example, with the rules of tonality), the connection can be and
often is much more transparent. These data sources could include human structures such as other
music, text, bus timetables, or masked input such as an audience whose motion through a
performance space is being mapped to pitch, amplitude, tone, etc. The appeal of external sources
is that the patterns and structure of the subject can be transferred from the extra-musical source
to the composition. A star map, for example, would provide x and y locations that would
generate a fairly even distribution of events, while a mountain silhouette would provide a smooth
contiguous stream of events. There is also a philosophical connection that can bring additional
meaning to the composition, e.g. pitch choices taken from the voice print or favorite poem of one
of the performers.
With text, musicians may paint the character of a single word, but also generate the exact
replica of the word in musical symbols, as in Bach's double fugue which begins with the four
pitches Bb, A, C, B (in German musicianship: B, A, C, H).
Any data stream, whether read from an existing file or from a real time input source such
as a mouse or video link, can be used in influencing musical parameters. SC provides a number
of outside control sources such as MouseX and Y, Wacom pad controls, MIDI input, a data file,
or Open Sound Control (which can be linked to iPhones, iPads, etc.). Text has many advantages,
and is a good place to start.
The ASCII values for 'a' through 'z' are 97 to 122, and 'A' through 'Z' are 65 through 90.
This conveniently corresponds with MIDI values, though a bit high. They could easily be offset
to a lower range, but
Mapping
allows greater control over the correlation between notes and letters therefor better
control over the nature of the composition while retaining the link to the patterns in the stream.
In text, for example, we know that vowels occur about every other letter. Sometimes there are
two in a row. They are separated by as many as four consonants. With this understanding we can
map key pitches to vowels and achieve (for example) a sense of tonality; a = C4, e = E4, i = G4,
o = C5 (a = 60, e = 64, i = 67, o = 72), etc. A map also allows you to confine data structures to
characters in use, omitting (or including) characters such as spaces, punctuation, etc.
In example 27.1 the variable ~pm is assigned the IdentityDictionary array. It contains
pairs of elements; the original character and its associated value. The association is made with
dash and greater than sign, such as $b -> 4, which reads "make the character b equal to the
integer 4." The numbers associated with the characters are MIDI intervals or pitch classes.




307
27.1:: Pitch Map
~pm = IdentityDictionary[
$H -> 6, $x -> 6, $b -> 6, $T -> 6, $W -> 6, $e -> 11, $o -> 11, $c -> 11,
$, -> 11, $. -> 11, $n -> 3, $y -> 3, $m -> 4, $p -> 8, $l -> 9
];

::
After using the IdentityDictionary for a few projects settled on a computationally less
efficient, but more logical algorithm using a two dimensional array and a search. The first item in
the enclosed arrays is the list of charactersa stringthe second element is the value to be
associated with all items in that string. The obvious advantage over a dictionary is that a group of
letters can be mapped to one value more concisely. They are parsed using a do function which
looks at each of the first elements and if a match is found (using includes) the mappedValue
variable is returned.
27.2:: Mapping Array
~intervMap = [
["ae", 2], ["io", 4], [" pstc", 5], ["Hrn", -2],
["Sxm", -1], ["lfg", -4], ["Th", -5], [".bdvuw", 1]
];

"Sample text, which can be mapped to intervals".do({|char|
~intervMap.do({|each|
if(each.at(0).includes(char), {char.post; ": ".post; each.at(1).post; " ".post})
})
}); ""
::
Here is a patch which controls only pitched elements in an absolute relationship (that is,
pitch classes rather than intervals).
27.3:: Extra-Musical Criteria, Pitch Only

MIDIClient.init; m = MIDIOut(0, MIDIClient.destinations.at(0).uid);


// Test
m.noteOn(1, 60, 100);
m.noteOff(1, 60);

(
var noteFunc, blipInst, midiInst, channel = 0, port = 0, prog = 0,
intervMap, count = 0, ifNilInt = 0, midin = 0, inputString;

//The input stream.

inputString = "Here is an example of mapping. The, them, there, these,"



308
"there, then, that, should have similar musical interpretations."
"Exact repetition; thatthatthatthatthatthat will also"
"be similar.";

//intervMap is filled with arrays containing a collection of
//characters and a value. In the functions below the character
//strings are associated with the numbers.

intervMap = [
["ae", 2], ["io", 4], [" pst", 5], ["Hrn", 7],
["xmp", 1], ["lfg", 3], ["Th", 6], [".bdvu", 11]
];


"// [Char, Interval, ifNilInt, midi interval, octave, midi]".postln;

noteFunc = Pfunc({var parseInt, octave;

//Each array in the intervMap is checked to see if the
//character (inputString.wrapAt(count)) is included. If
//it is then parseInt is set to the value at item.at(1)

intervMap.do({arg item;
if(item.at(0).includes(inputString.wrapAt(count)),
{parseInt = item.at(1)})
});

//If parseInt is notNil, midin is set to that.
//ifNilInt is for storing each parseInt to be used if
//no match is found and parseInt is nil the next time around.

if(parseInt.notNil,
{midin = parseInt; ifNilInt = parseInt},
{midin = ifNilInt}
);

octave = 60;

"//".post; [inputString.wrapAt(count), parseInt,
ifNilInt, midin, octave/12, midin + octave].postln;

count = count + 1;

midin + octave
});

Pbind(
\type, \midi,
\midiout, m, // must provide the MIDI target here
\midinote, noteFunc,
\dur, 0.125,




309
\amp, Prand([0.4, 0.6, 0.8], 180);
).play
)
m.allNotesOff(1); m.allNotesOff(0);

::
To achieve a particular balance of interval choices the intervMap should contain
proportional interval values rather than absolute pitches. The numbers may look pretty much the
same, but in the actual parsing use midin = parseInt + midin%12 (thus parseInt becomes an
interval) rather than midin = parseInt. Interest can also be added by mapping pitches across
several octaves, or mapping octave choices to characters.
Notice in this next example the series "thatthatthatthat" results in an intervallic motive,
rather than repeated pitches.
27.4:: Text Map, Intervals
(
var noteFunc, blipInst, midiInst, channel = 0, port = 0, prog = 0,
intervMap, count = 0, ifNilInt = 0, midin = 0, ifNilDur = 1,
durMap, durFunc, ifNilSus = 1, susMap, susFunc, ifNilAmp = 0.5,
curAmp = 0.5, ampMap, ampFunc, inputString;

//The input stream.

inputString = "Here is an example of mapping. The, them, there, these,"
"there, then, that, should have similar musical characters."
"Exact repetition; that that that that that that will also"
"be similar.";

//intervMap is filled with arrays containing a collection of
//characters and a value. In the functions below the character
//strings are associated with the numbers.

intervMap = [
["ae", 6], ["io", 9], [" pst", 1], ["Hrn", -3],
["xmp", -1], ["lfg", -4], ["Th", -5], [".bdvu", 1]
];

durMap = [
["aeiouHhrsnx", 0.125], ["mplf", 1.5], ["g.T,t", 0.25],
["dvc", 2], [" ", 0]
];

susMap = [
["aei ", 1.0], ["ouHh", 2.0], ["rsnx", 0.5], ["mplf", 2.0], ["g.T,t", 4.0],
["dvc", 1.0]
];

ampMap = [



310
["aeHhrsnx ", 0.8], ["ioumplfg.T,tdvc", 1.25]
];

noteFunc = Pfunc({var parseInt, octave;

//Each array in the intervMap is checked to see if the
//character (inputString.wrapAt(count)) is included. If
//it is then parseInt is set to the value at item.at(1)

intervMap.do({arg item;
if(item.at(0).includes(inputString.wrapAt(count)),
{parseInt = item.at(1)})
});

//If parseInt is notNil, midin is set to that plus previous
//midin. ifNilInt is for storing each parseInt to be used if
//no match is found and parseInt is nil.

if(parseInt.notNil,
{midin = parseInt + midin%12; ifNilInt = parseInt},
{midin = ifNilInt + midin%12}
);
octave = [24, 36, 48, 60, 72].choose;
[inputString.wrapAt(count)].post;
["pitch", parseInt, midin, octave/12, midin + octave].post;

midin + octave
});

durFunc = Pfunc({var parseDur, nextDur;

durMap.do({arg item;
if(item.at(0).includes(inputString.wrapAt(count)),
{parseDur = item.at(1)})
});

if(parseDur.notNil,
{nextDur = parseDur; ifNilDur = parseDur},
{nextDur = ifNilDur}
);
["dur", nextDur].post;
nextDur
});

susFunc = Pfunc({var parseSus, nextSus;

susMap.do({arg item;
if(item.at(0).includes(inputString.wrapAt(count)),
{parseSus = item.at(1)})
});





311
if(parseSus.notNil,
{nextSus = parseSus; ifNilSus = parseSus},
{nextSus = ifNilSus}
);
["sustain", nextSus.round(0.01)].post;
nextSus
});

ampFunc = Pfunc({var parseAmp;

ampMap.do({arg item;
if(item.at(0).includes(inputString.wrapAt(count)),
{parseAmp = item.at(1)})
});

if(parseAmp.notNil,
{curAmp = curAmp*parseAmp; ifNilAmp = parseAmp},
{curAmp = curAmp*ifNilAmp}
);

count = count + 1;
if(0.5.coin, {curAmp = rrand(0.2, 0.9)});
["amp", curAmp.round(0.01)].postln;

curAmp.wrap(0.4, 0.9)
});


a = Pbind(
\type, \midi,
\midiout, m, // must provide the MIDI target here
\midinote, noteFunc,
\dur, durFunc,
\legato, susFunc,
\amp, ampFunc
).play
)
a.stop; m.allNotesOff(1); m.allNotesOff(0);

::
Artificial Intelligence begins by describing human phenomena in a language the
computer understands: numbers, probabilities, and formulae. Restricting choice in any way
teaches bias because the CPU makes an informed choice. The random walk in Chapter 24 was
biased in many ways. A map represents a set of ratios and probabilities. In a simple biased
random choice there is only one level of probability; a probability for each possible choice in the
set. This is known as a



312
Markov Process
with a zeroth order probability. Building a probability table is as simple as counting all
pitches in a work and dividing by the total number in the work. It would take barely an afternoon
to download Bach's entire opus from a MIDI site, read and parse each note (transposed to C) and
calculate the probabilities that, say, C will appear at any given time. (Any theory student might
take a stab at it without going to all that bother, say, 14%.) Writing a biased random walk with
those probabilities would not recreate Bach because we perceive melody and musical
progression in the relationship of the current pitch to the next pitch, and the last three pitches,
and the pitches we heard a minute ago. To describe a melody, you have to describe the
connections between pitches. For this we use a higher order Markov chain; first or second at
least. A first order chain describes the connection between two notes. Given the current note,
what are the probabilities for the next note?
! For example, if the current pitch is G (in the key of C), what are the probabilities that the
next pitch is C? Quite high (resulting in a V-I relationship) in tonal systems, higher than say F
would follow G (a retrogressive V-IV). If the current pitch is F on the other hand, then there is a
greater chance that the next pitch is E (resolution of the IV) than C (retrogressive). In non-tonal
music you might likewise describe relationships by avoiding the connection G to C. If the current
pitch is G and avoiding a tonal relationship is your goal, the probability that the next pitch is D-
sharp, or A-flat would be higher than C.
To illustrate, consider the first four bars of Frere Jacque. They contain only five pitches,
so a chart listing only C through G is required. Current pitches are in the first column and next
probabilities are in each subsequent column.
C D E F G
C 0 0 0 0 0
D 0 0 0 0 0
E 0 0 0 0 0
F 0 0 0 0 0
G 0 0 0 0 0
To calculate each probability, count up all the times C is followed by D and enter that
number (2) in the D column of the C row. Next we examine all other Cs and count the number of
times C is followed by C, E, F, G, and enter each of those totals into the table. We do the same
for the pitch D, then E, and so on. This is the resulting transition table:
C D E F G Total
C 1 2 1 0 0 4
D 0 0 2 0 0 2
E 2 0 0 2 0 4
F 0 0 0 0 2 2
G 0 0 1 0 0 1
The final probability is the number of actual occurrences in that column divided by the
total possible outcomes in the final row. The C column row will be 1/4, 2/4, and 1/4.
C D E F G Total
C .25 .5 .25 0 0 4
D 0 0 1.0 0 0 2
E .5 0 0 .5 0 4
F 0 0 0 0 1.0 2
G 0 0 1.0 0 0 1




313
! This is a first order transition table. A second order table adds a pitch to the chain. That is
to say, given the last two pitches, what is the probability of the next pitch being C, D, etc. Here is
the same chart expanded to include all of Frere Jacque in a second order of probability.
Combinations that never occur (e.g., C-A) are left off, leaving 36 combinations.

C D E F G A Total
C-C 1 2 3
C-D 2 2
C-E 1 1
C-G 2 1 3
D-E 2 2
E-C 2 1 1 4
E-F 2 1
F-E 2 2
F-G 1 1 2
G-C 1 1
G-E 1 1
G-F 2 2
G-G 1 1
G-A 2 2
A-G 2 2
Total 9 1 6 4 8 2 30
Note that the total combinations are at the bottom. This is a quick way to check if you
have the correct number of total connections. The total should equal the number of notes in the
piece minus two (because the first two don't have a connection of three itemsor second order).
Also note the combination C-C has no probability for F. If there were one, then the combination
C, C, F could result. But there are no probabilities for C-F. This broken link would return a nil
value and crash (or get stuck in a loop). I don't have a quick or clever way to check to make sure
you don't have any bad leads. You just have to proof carefully.
Here is the chart with percentages.
C D E F G A Total
C-C 33 66 3
C-D 100 2
C-E 100 1
C-G 66 33 3
D-E 100 2
E-C 5 25 25 4
E-F 1.0 1
F-E 100 2
F-G 5 5 2
G-C 100 1
G-E 100 1
G-F 100 2
G-G 100 1
G-A 100 2
A-G 100 2
Total 9 1 6 4 8 2 30



314
Charts can eat up memory. If, for example, you were to do a chart for the piano works of
Webern (which wouldn't make sense because that's not how his music worksbut that shouldn't
stop you from trying it), assuming a four octave range, 12 pitches for each octave, second order
probability would require a matrix of 110,592 references for pitch alone. If you expanded the
model to include rhythm and instrument choice, dynamic and articulation, you could be in the
billions in no time. So there needs to be efficient ways of describing the matrix. In the Foster
example below I do a few space saving short cuts.
27.5:: Transition Table
//A collection of the pitches used

~legalPitches = [60, 62, 64, 65, 67, 69];

//An array of arrays, representing every possible previous pair.

~transTable = [
[0, 0], //C, C
[0, 1], //C, D
[0, 2], //C, E
[0, 4], //C, G
[1, 2], //D, E
[2, 0], //E, C
[2, 3], //E, F
[3, 2], //F, E
[3, 4], //F, G
[4, 0], //G, C
[4, 2], //G, E
[4, 3], //G, F
[4, 4], //G, G
[4, 5], //G, A
[5, 4] //A, G
];

// Parsing the transTable

transTable.do({arg index, i; if(index == currentPair,
{nextIndex = i; true;}, {false})});

::
Since so many midi values are skipped in a tonal scheme, ~legalPitches is used to limit
the number of pitches used. The actual code looks for and works around array positions, not midi
values. The variable ~transTable describes the first column of my transition table. Each of the
possible previous pitches are stored in a two dimensional array.
The value used to compare and store the current two pitches is currentPair. It is a single
array holding two items, the first and second pitch in the chain. At the beginning of the program
they are set to 0, 0, or C, C.




315
The values in currentPair are matched with the array transTable. This is done with a do
iteration. In this function each of the two position arrays will be compared to the variable
currentPair, which is also a two position array. When a match is found the index of that match
(or position in the array where it was found) is stored in nextIndex. In other words, I have found
the index position of currenPair. This is necessary because the table has been pared down to
include only existing combinations.
Next the index for each previous pair is located. If, for example, the current pair was D,
E. Their values in the transTable would be [1, 2], and the lines of code above would find a match
at array position 4 (remember to count from 0). That means the probability at position 4 is used.
In this chart it says there is a 100% chance that C follows the currentPair D, E.
27.6:: Probability chart

nPitchProb =
[
//C D E F G A
[0.00, 0.33, 0.00, 0.00, 0.66, 0.00], //C, C
[0.00, 0.00, 1.00, 0.00, 0.00, 0.00], //C, D
[0.00, 0.00, 0.00, 1.00, 0.00, 0.00], //C, E
[0.66, 0.00, 0.00, 0.00, 0.00, 0.33], //C, G
[1.00, 0.00, 0.00, 0.00, 0.00, 0.00], //D, E
[0.50, 0.00, 0.25, 0.00, 0.25, 0.00], //E, C
[0.00, 0.00, 0.00, 0.00, 1.00, 0.00], //E, F
[1.00, 0.00, 0.00, 0.00, 0.00, 0.00], //F, E
[0.00, 0.00, 0.50, 0.00, 0.50, 0.00], //F, G
[1.00, 0.00, 0.00, 0.00, 0.00, 0.00], //G, C
[0.00, 0.00, 0.00, 1.00, 0.00, 0.00], //G, E
[0.00, 0.00, 1.00, 0.00, 0.00, 0.00], //G, F
[0.00, 0.00, 0.00, 0.00, 0.00, 1.00], //G, G
[0.00, 0.00, 0.00, 0.00, 1.00, 0.00], //G, A
[0.00, 0.00, 0.00, 1.00, 0.00, 0.00] //A, G

];
::
The choice is actually made using windex (weighted index), which takes an array of
probabilities as its first argument. The array nPitchProb is a two dimensional array used for the
next probability array, say index 4, identified as nPitchProb.at(4). Since it is a multi-dimensional
array, there are two indexes, e.g. nPitchProb.at(4).at(5).
Using variables this becomes: (nPitchProb.at(prevPitch).at(nextIndex). The array for
windex has to total 1 which is accomplished with normalizeSum. The return from windex is an
array position, which is stored in nextIndex.
The variable nextPitch is an array position that can then be used in conjunction with
legalPitches to return the midi value for the correct pitch: legalPitches.at(nextPitch). It is also
used for some necessary bookkeeping; rearranging currentPair to reflect the new choice. The
value in the second position of the array currentPair is moved to the first position, and the



316
nextPitch value is stored in the second position. (In other words, currentPair was D, E, or array
positions 1, 2, C or 0 was just picked according to the table, so what was [1, 2] becomes [2, 0].)

currentPair.put(0, currentPair.at(1));
currentPair.put(1, nextPitch);
A more complex example of a transition table and Markov process is demonstrated in
Example 27.7. It uses a small section of Harry F. Olsen's transition table for the works of
Stephen Foster.
The system does not control duration using a Markov, and has no information about
phrase structure or cadences, which is apparent. Predetermined phrases could be gathered in a
series of Pseq arrays, which would give more structure, but would not account for placement of
tonic vs. leading tones. The result? It is very Fosterish, F nearly always moves to G.
27.7:: Foster Markov
MIDIClient.init(0, 1); m = MIDIOut(0);

m.program(0, 4);
m.noteOn(0, 60);
m.noteOff(0, 60);

/* For tests
a = Pbind(\tempo, 1, \amp, 0.8, \type, \midi, \midiout, m, \channel, 4, \dur, 0.1, \sustain, 0.05,
\midinote, Pfunc({48.rand + 36})).play;
a.stop;

*/

(

var wchoose, legalPitches, previousIndex, prevPitch,
currentPitch, nextIndex, nextPitch, nPitchProb,
pchoose, blipInst, envelope, pClass, count, resopluck, seed;

seed = 0; // random seed
// seed = = Int32Array[ -571935851, 1571969825, 1165557446 ]; // randData seed

if(seed == 0, {thisThread.randData.postln}, {thisThread.randData_(seed)});
{1000.rand}.dup(10);

prevPitch = 3;
currentPitch = 1;
count = 1;
pClass = #["A3", "B3", "C4", "D4", "E4", "F4", "F#4",
"G4", "A4", "B4", "C5", "D5"];

//pchoose is the mechanism for picking the next value.

pchoose =




317
{
legalPitches = [57, 59, 60, 62, 64, 65, 66, 67, 69, 71, 72, 74];

//Both prevPitch and nextPitch are not pitches, but array positions.

previousIndex = [
[2], //previous is 0 or A3
[2], //1 or B3
[0, 1, 2, 3, 4, 5, 7, 9, 10], //2: C4
[1, 2, 3, 4, 7, 10], //3: D4
[2, 3, 4, 5, 7, 8], //4: E4
[4, 5, 7, 8], //5: F4
[7], //6: F#4
[2, 4, 5, 6, 7, 8, 10], //7: G4
[2, 4, 5, 6, 7, 8, 10], //8: A4
[8, 10], //9: B5
[7, 8, 9, 10, 11], //10: C5
[7, 9] //11: D5
];

previousIndex.at(prevPitch).do({arg index, i; if(index == currentPitch,
{nextIndex = i; true;}, {false})});

nPitchProb =
[
// [00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11] array position
// A, B, C, D, E, F, F#, G, A, B, C, D
[ //arrays for A3
[00, 00, 16, 00, 00, 00, 00, 00, 00, 00, 00, 00] // one array: C4
],
[ //arrays for B3
[00, 00, 05, 06, 00, 00, 00, 05, 00, 00, 00, 00] // C4 only
],
[ //arrays for C4
[00, 00, 16, 00, 00, 00, 00, 00, 00, 00, 00, 00], // A3
[00, 00, 16, 00, 00, 00, 00, 00, 00, 00, 00, 00], // B3
// [00, 02, 02, 09, 02, 10, 00, 00, 00, 00, 00, 00], original C4
[00, 06, 02, 09, 02, 06, 00, 00, 00, 00, 00, 00], // C4
[00, 00, 03, 04, 08, 00, 00, 01, 00, 00, 00, 00], // D4
[00, 00, 00, 07, 03, 02, 00, 04, 00, 00, 00, 00], // E4
[00, 00, 00, 00, 11, 00, 00, 00, 05, 00, 00, 00], // F4
[00, 00, 00, 00, 04, 00, 00, 12, 00, 00, 00, 00], // G4
[00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 16, 00], // A4
[00, 00, 00, 00, 00, 00, 00, 02, 11, 03, 00, 00] // C5
],
etc.
];

nextPitch = (nPitchProb.at(prevPitch).at(nextIndex).normalizeSum).windex;

//current is set to previous, next is current for next run. The actual pitch



318
//is returned from legal pitch at nextPitch.

[pClass.at(nextPitch), legalPitches.at(nextPitch)].post;
// if((count%10) == 0, {"".postln};);
count = count + 1;
prevPitch = currentPitch;
currentPitch = nextPitch;
legalPitches.at(nextPitch)
};

a = Pbind(\tempo, 1, \amp, 0.8, \type, \midi, \midiout, m, \channel, 4,
\dur, Prand([
Pseq(#[1]),
Pseq(#[0.5, 0.5]),
Pseq(#[0.5, 0.5]),
Pseq(#[0.25, 0.25, 0.25, 0.25]),
Pseq(#[0.5, 0.25, 0.25]),
Pseq(#[0.25, 0.25, 0.5])
], inf),

//\dur, 0.1,
\art, 0.5, \midinote, Pfunc(pchoose)).play;

)

a.stop
// All notes off:
m.allNotesOff(1); m.allNotesOff(0);

::
This concludes our discussion of control sources. Below is a summary.
Control Source Review
Character Examples
Periodic Wave Forms Exact repetition, classic (clich) Sine, Saw, Pulse
Aperiodic Wave Forms Random, classic (clich) LFNoise1, LFNoise0
Sequencers Exact, but custom, complex repetition Dseq, Ultrabeat
Sample and Hold Evolving patterns, blend between variation/repetition Latch
External data Complex, meaning through context, natural patterns transfer Data files
Probabilities Artificially intelligent Data tables, if()
Music of the Spheres
Music, art, and nature is made of varying degrees of repetition and variation. Humans are
hard wired to recognize and interpret repetition and variation. Effective music strikes the correct
balance (for the desired effect) between repetition and variation. Too much and it approaches
noise, seems random. Too little results in trite, uninteresting events. It's all subjective and
relative. It is subject to our ability to perceive. Our personal and collective sense for structure
matures and evolves. Our taste for musical style likewise evolves.




319
Though inharmonic spectra are not heard as pitch, the constructive and destructive
interference still blend into a recognizable pattern. We are just as capable of distinguishing a set
of inharmonic frequencies, when repeated, as we do a melody. The harmonics blend into a
unique timbre.
The Solar System patch translates astrological data into sound. The first example
transposes the rotation of each planet in our solar system to an audio frequency range. It is then
couched in a bell patch. Run the "Just us" segment, listen for a while, then the second segment,
which adds 8 other known planetary systems within our galaxy, and 4 outside our galaxy, each
transposed to a range that humans can perceive. Put yourself in a virtual space ship, traveling
between galaxies. You are lost, but your perception has evolved to include magnetic fields. You
listen to the rotations of each system you pass. Could you find ours? Is it random?
27.8:: Solar System

(
{ // Just us:
var scale, specs, freqs, amps, rings,
numRes = 5, bells = 20, pan;
scale = [60, 62, 64, 67, 69].midicps;
Mix.fill(1, {
freqs = 72.midicps * [175.94, 116.75, 1, 1.027491, 0.41011, 0.4264, 0.6125, 0.7667, 6.3863];
amps = Array.fill(9, {rrand(0.3, 0.9)});
rings = Array.fill(9, {rrand(1.0, 4.0)});
specs = [freqs, amps, rings].round(0.01);
// specs.postln;
pan = (LFNoise1.kr(rrand(3, 6))*2).softclip;
Pan2.ar(
Klank.ar(`specs,
Dust.ar(1/6, 0.03)),
pan)
})

}.play;
)



(
// 12 other known planetary systems*
{
var scale, specs, freqs, amps, rings,
numRes = 5, bells = 12, pan;
scale = [60, 62, 64, 67, 69].midicps;
Mix.fill(bells, {arg c;
freqs = Array.fill(numRes, {rrand(1, 15)*(scale.choose)});
amps = Array.fill(numRes, {rrand(0.3, 0.9)});
rings = Array.fill(numRes, {rrand(1.0, 4.0)});
specs = [freqs, amps, rings].round(0.01);



320
// specs.postln;
pan = (LFNoise1.kr(rrand(3, 6))*2).softclip;
Pan2.ar(
Klank.ar(`specs,
Dust.ar(1/6, 0.03)),
pan)
})
}.play;
)

// *Technically untrue
::

Exercises
27:1 Generate a second order Markov Chain for the melody of Lullaby of Birdland.
27:2 Invert the probabilities of the Foster Markov patch. Use only the existing values, but
add code so that they are the compliment of 16; 2 becomes 14, 10 becomes 6.
27:3 Generate pi to a few thousand places. Use it for the data component of one of the
examples in this chapter.

You might also like