This past weekend I was happy to participate in the Algosix celebration of Algorave with a live code performance. (The first few minutes of the test sound were me trying to check sound on the stream and failing to realize it was working…).
The video shows a little bit of vim, csound, and csound-live-code. In particular, it demonstrates the hex beats work in the live code project, as well as using phasors and non-interpolating oscillator functions for pitch values. Drum sounds are from Iain McCurdy’s TR808 code and synth sounds were ones I have been working on in the live code project.
The event was a lot of fun with lots of different approaches, aesthetics, tools, etc. Lots of appreciation for the community and organizers of the event! (And many thanks for the opportunity to perform!)
Short version is that Pink has a number of new filters and effects, updates to minimize object allocations (e.g., Distruptor-style message ring buffers), and utility code for building streaming disk-based caches for pre-rendered (“frozen”) parts. Score has new functions geared towards live coding (e.g., euclidean and hexadecimal beats), a new mini-language for notating musical lines, and number of other updates.
Codox-generated documentation/site is now published at:
I have long avoided FM (Frequency Modulation) synthesis in my own musical practice as I never felt connected with the results I was able to get myself. However, I recently had the great pleasure to attend a talk about the 50th anniversary of FM synthesis, given by its creator, John Chowning, and I was very inspired to explore FM once again. In so doing, I came across the Yamaha reface DX synthesizer and became fascinated with reproducing its feedback system to morph an operator’s output from a Sine to either Saw or Square waveform.
Now, I do not own a reface DX, so most of my research into it was through looking at manuals and watching video demonstrations on YouTube to try to get an idea of how it might be done. I knew from going through literature on FM and PM (Phase Modulation) that using PM with feedback could get an operator’s signal to move from a Sine to Sawtooth wave, depending upon the amount of feedback. I was quickly able to setup a PM instrument in Csound and test this out and it sounded much like what I had heard for the reface DX.
In the code above, one can see that the acar output from tablei is also used as input into the opcode. The code above runs in a single-sample context (in Csound parlance, with ksmps=1).
Now, the part I could not find anywhere in literature or discussion online was how to use operator feedback to morph from Sine to Square. (This is done by using 0 to -127 range for feedback on the reface DX.) After a couple days of research and exploration, I stumbled upon a calculation that sounded to my ears very much like what I had heard on the reface DX videos.
This instrument is virtually the same as the first instrument with the exception of one additional calculation: the multiplication of the acar feedback by itself. (This is seen in the acar*acar calculation.) Adding this one additional multiplication made the signal move from Sine to Square.
I posted this to the Csound User list and Iain McCurdy gave great feedback that the waveform could be morphed between Saw and Square by interpolating between acar and 1. This made a lot of sense as when one of the acar‘s becomes 1, it reduces back down to the normal feedback addition to produce a Saw sound. After some further emails, I did some experiments to use a cosine-based mapping for the interpolation that resulted in a nice transition.
;; feedback PM - feedback moves from square to saw
;; Based on Iain McCurdy's comments on Csound User List
ifreq = p4
iamp = p5
kfb = 0.25
;;kfb = linseg(0, p3 * .5, 0.5, p3 * .5, 0)
kwaveshape = linseg(0, p3 * .5, 1, p3 * .5, 0) ;; range 0-1 for saw->square
kwaveshape *= kwaveshape ;; adjust curve
kwaveshape = $M_PI * (kwaveshape + 1) ;; adjust from PI->2PI
kwaveshape = (cos(kwaveshape) * 0.5) + 0.5 ;; adjust to 0-1
aphs = phasor(ifreq)
; init for feedback
acar init 0
acar = tablei(aphs+(ntrpol(acar, a(1), kwaveshape)*acar*kfb), 1, 1, 0, 1)
acar *= linen:a(1, 0.1, p3, 0.1) * iamp
I do not know if these calculations are what are used in the reface DX, but regardless, the sine->square sounded good to my ear and I felt it was usable for the kind of sound work I was interested in doing. For now, I have posted the Csound CSD project file here. The audio example at the top of this post is an MP3 version of the output rendered from this project.
Hexadecimal (base 16) has been used in various forms of computer music for a very long time, generally as a condensed way to notate values within a power-of-two range. For example, rather than write out “15” as a decimal value (base 10), one can use “F”, and rather than write out “255”, one can use “FF”. The notation of hexadecimal numbers, in general, take up less horizontal space on the screen than its base 10 counterpart.
The differences in screen real estate is even more pronounced when comparing the binary value (base 2) to the decimal and hex values. Let’s compare some values here:
A chart showing the binary, decimal, and hex values for number 0-255 are available here.
Now, one of the interesting challenges in live coding pattern-oriented music for me has been trying to have a very condensed notation for expressing beats (onsets). One way I’ve seen used is to notate values in a binary form within a string, such as “1000100010101000” which would mean “play notes where there are 1’s, but don’t play notes where there are 0’s”. In this case, on beat 1, 5, 9, 11, and 13.
Binary values in a string, on the one hand, quite clearly notates when an instrument should play. On the other hand, I’ve found it visually takes up quite some space and can be a bit slow to parse mentally.
One thing I’ve found rather useful is to notate onset patterns using hexadecimal strings. I first explored this in my Clojure systems Pink and Score, but recently translated the function I was using to Csound code. The Csound code turned out to be quite simple:
opcode hexbeat, i, Si
Spat, ibeat xin
;; 4 bits/beats per hex value
ipatlen = strlen(Spat) * 4
;; get beat within pattern length
ibeat = ibeat % ipatlen
;; figure which hex value to use from string
ipatidx = int(ibeat / 4)
;; figure out which bit from hex to use
ibitidx = ibeat % 4
;; convert individual hex from string to decimal/binary
ibeatPat = strtol(strcat("0x", strsub(Spat, ipatidx, ipatidx + 1)))
;; bit shift/mask to check onset from hex's bits
xout (ibeatPat >> (3 - ibitidx)) & 1
The above is saying: “within the hexadecimal beat string of f0d0d0f0, and given the current beat value between 0 and 32, check if the onset is a 1 and, if so, perform Synth 1”.
The code above may be a little tricky to grok at first glance. I’ve started a Github repository for this code and made an online web app for live coding with Csound and this library. The live web site is available at:
In working with the hex beat patterns, I found it took a little practice but the meaning of various hex values started to become intuitive over time. Hexadecimal works really well, in my opinion, for notating pattern onsets as each hex value maps to 4 bits, which works perfectly for 4 16th-notes. With this, 4 hex values can be used to notate a single measure of 16 16th-notes, 8 hex for 2 measures, and so on.
Reflections is a three-movement study that arose out of exploration into randomly generated symmetric odd/even signal wave tables for synthesis. The piece uses a number of different “reflected” table generation methods with each movement developed intuitively according to the sound qualities of the table methods. Each piece has some indeterminant qualities in form as well as sound, thus each rendering of the piece is its own unique performance.
In Max Mathews’ “The Technology of Computer Music,” (the manual to Music V, for those who haven’t encountered it before), are two wonderful quotes:
“Scores for the instruments thus far discussed contain many affronts to a lazy composer, and all composers should be as lazy as possible when writing scores.” – pg. 62
“Furthermore, the note duration is already written in P4; it is an indignity to have to write P6 (= .02555/duration).” – pg. 63
I think these quotes describe that even in 1969, a schism was identified between what one writes that is relevant to them and their work and the underlying representation that is necessary for the operation of the musical system. It’s been an interesting thing to think about what it signifies and how it presents itself even today.
The above quotes come from the section describing C0NVT, the routine one defined to transform what the composer wrote into the instructions that would work within the MUSIC V base system. While C0NVT would later see a descendant in Csound’s SCOT system, I think the general idea would be superceded by custom tools and/or language changes that allowed users to customize things in other ways. Thinking more broadly outside of just the world of MUSIC N systems, today’s computer music systems generally involve many layers between what the user uses (i.e., the GUI interface of a DAW, a custom score language, programming in a general purpose language) and the representation used for performance (text score events, MIDI, OSC).
These layers of notation–what the composer writes, the various processes of transformation, and arriving at what is used for performance–need not be seen only to the digital music world. For example, the metric modulation notation of Carter might represent well what the performer needs for performing material that changes tempi in synchrony with other performers in other tempi, but it obscures the musical character of the material, which is often much simpler rhythmically when viewed within its native tempo. This might be seen then as score that has already been processed by C0NVT, and we are left to analyze and make out the pre-processed material. (I do wonder then if Carter might have seen the modulations as a kind of indignity in having to write…)
Returning to the digital world, it is somewhat of a painful thing to see composers who must jump through many hoops to use the technologies available to realize their goals for which the technologies were not designed. Here I am thinking of the microtonal composer using MIDI, who might resort to using tuning tables and pitch bends to arrive at their desired tuning. When microtonal composers use tools that allows them to write in one notation and transforms the material to one suitable for the target system automatically, it is quite a delight to see the notation and to hear the results and to clearly see the mapping between the two. But for those who must work within tunings with many divisions of the octave, to see the coercion of a MIDI piano roll to fulfill their notation needs is quite painful.
On a personal note, these musings touch on recent issues in my musical practice of finding the right balance between how I would like to write and notate ideas and what I need to do to realize them in sound. Sometimes text/code works so well and is so precise and clear, yet other times visual interfaces yield more overall information and provide intuitive handling and development of material. Both have their appeals and drawbacks, and I suppose Blue represents a kind of hybrid system that allows one to not only explore either end of the spectrum but also the area in-between. I have thought of this off an on for a long time, but not so much recently. Perhaps some quiet time to meditate upon it all and experiment with different designs is in order.
“Wuji” was written for the Eastman Mobile Acousmonium (EMA), “an ensemble of individual custom-built loudspeakers” that is a project developed out of the Eastman Audio Research Studio, lead by Oliver Schneller. The piece is designed for any number of available speakers spatially distributed in a room. It is made up of multiple renderings of the primary single-channel source that is then mapped with one rendering per speaker.
In writing for EMA, one of the sonic experiences that came mind were memories of performing in instrumental ensembles and sitting there on stage within a field of sound. It has been many years now since I last performed in an ensemble, but I remember that sound world as a unique and wonderful experience, one not easily reproduced by typical speaker setups that might surround the periphery of the listener. It is my hope that the listener experiences this work by not only being surrounded by the sound but also within it.
Many thanks to Oliver Schneller and the members of EARS for the opportunity to compose for the EMA speaker ensemble.
“Wuji” was originally designed as a realtime work. The primary Csound CSD project uses limited amounts of indeterminacy to provide unique performances every render. The concept was first designed to be performed by multiple computers and/or mobile devices that would then be connected to various speakers spatially distributed in a room. However, as the nature of the hardware ensemble changed, it became easier to pre-generate multiple renders of the core project and provide them as a single 24-channel audio file. The 24-channel file would then be played back with each channel mapped to an available speaker.
To simulate the experience of the realtime rendering, the 24 single-channel renders were created, each unique by the nature of the indeterminacy in the CSD. A second 24chanmix CSD was developed to take each single-channel file and map it to one of the 24 channels. The channels were played in groups roughly 2 seconds apart from each other, with slight randomness used to offset the start times of the channels within the group. To cover about 8 seconds of group offsets, the channels were batched into four 6-channel groups. This matches the intended realtime performance to start groups of machines rendering about every two seconds and to simulate the slight imprecisions in trying to start separate machines at the same time.
For the 2-channel mix, the same 24 single-channel renders were used with a second 2chanmix CSD. The 2chanmix CSD uses the same offset time algorithm as the 24-channel mix (four 6-channel groups, roughly 2 seconds apart). Each channel is randomly panned within the stereo field and a random gain applied. The 2-channel mix is, at best, a rough approximation of the intended experience. The effect of listening to a heterogenous group of speakers–each with their own filtering characteristics, frequency responses, and directionality–performing sound and interacting with a room, and the freedom to walk around the roomas a listener, can not be adequately captured in a 2-channel mix. A better 2-channel mix that could account for some of these factors could certainly be done and may be revisited in the future.
A Makefile is provided that will, by default, render the 24 single-channel renders, render the 2-channel mix to WAV file, then process the WAV to create MP3, OGG, and FLAC versions. To build the 24-channel performance version, a separate Makefile target (make syi_wuji_24chanmix.wav) must be run manually. A “repl” target is also provided that will start the project using Csound with –port=10000, suitable for use with Vim csound-repl plugin. It will also define the REPL macro so that running the project CSD will not execute the main score generating command. This allows one to load the project then go about experimenting with live coding.
“Wuji” is made up of three sound groups: a justly-tuned major chord, an ascending and descending pattern of dyads in Bohlen-Pierce tuning (equal-tempered version), and a multi-LFO modulated “chaotic” sound. The first two groups use the same simple instrument made up of a sawtooth oscillator filtered by the moogladder 24/db lowpass filter. The chaotic sound was designed around a triangle wave oscillator filtered by the moogladder filter. The two tunings were chosen for their particular sonic qualities for both their respective materials alone as well as their rich interactions.
It captures my thoughts on the importance of extensibility in computer music software and different ways of approaching it for both developers and users. The thesis discusses various extensibility strategies implemented in Csound, Blue, Pink and Score, from 2011-2016.
Looking back at the thesis, I’m proud of the work I was able to do. I am sure my thoughts will continue to evolve over time, but I think the core ideas have been represented well within the thesis. I hope those who take a look may find something of interest.
In addition to my acknowledgements in the thesis, I would also like to thank Ryan Molloy and Stephen Travis Pope for their close readings of my thesis as part of the Viva process. I will be forever grateful for their comments and insights.
“Transit” was inspired by listening to the music of Terry Riley to create a work that involved long feedback delay lines. I began with a mental image of performers in a space working with electronics and worked to develop a virtual system to mimic what I had in mind. Once the setup was developed, I experimented with improvising material live and notating what felt right. I then continued this cycle of improvisation and notation to extend and develop the work.
This release introduces Pink processes. It reuses the state machine
macro system from core.async to allow writing event generation code
using loops and waits. The state machine execution is wrapped in a
Pink control function and run synchronously with the engine. Waits
may wait upon a given time value in seconds, a Pink Signal (i.e. cues
or latches), or upon a predicate function. The use of signals and
predicates provides a means for interprocess communication, enabling
things like Lutoslawski-style aleatory (i.e., ad libitum writing)
where performers and conductors signal one other. Further information
is available in the documentation for processes  and example code
is shown in . (For those unfamiliar with Lutoslawski’s writing, the
performance instructions given at the bottom of pages 1 and 2 of his
3rd Symphony  may shed some light.)
This release also provides a translation of Scott Van Duyne’s piano
model from Common Lisp Music, biquad-based filters, and a number of
other audio, control, and utility functions.
Many thanks to Timothy Baldridge and other core.async contributors for
making the core.async ioc_macros easily extensible and reusable, and
again to Tim for the wonderfully clear videos on YouTube explaining
the design of the macros.