[continue autosave] Learn Sporth
log in learn new browse

In Seven
by Paul Batchelor

# in seven # paul batchelor # january 2017 _seq "0 4 5 7 -2" gen_vals _clk var _dry var _send var 210 "++2(+-+)" prop _clk set _clk get 0 _seq tseq 58 + mtof 0.001 port 0.3 _clk get 1 3 trand floor _clk get 1 7 trand floor 30 inv 1 sine 0.1 2 biscale fm dup _clk get 0.2 maygate 0.01 port * _send set _clk get 0.001 0.01 0.4 tenv * _dry set _dry get _send get 2 * + dup 0.97 5000 revsc drop -27 ampdb * dcblk _send get 0.8 210 bpm2dur 1.5 * delay 800 butlp -7 ampdb * + _dry get +
show code >>
 # in seven
 # paul batchelor
 # january 2017 

The sporthling in seven is a recreation of an earlier csound live coding patch that I wrote. It can be summarized as being a sequenced FM synth with careful use of C:M ratio modulation and reverb throws.

Tables and Variables

To begin, a number of tables and variables are created:

 _seq "0 4 5 7 -2" gen_vals
 _clk var 
 _dry var 
 _send var 

Prop Clock

The main clock signal used in this patch is generated via prop, a micro-language for generating rhythms based on proportions. A full explanation of prop is beyond the scope of this document, but more information can be found here.

The main gist of what is happening is that "prop" is generating a 7/8 rhythm with a 223 subdivision. The tempo is set to 210 BPM. T

This signal is saved to the variable clk.

 210 "++2(+-+)" prop _clk set

FM patch

The crux of this patch is driven by FM oscillator. The parameters of an FM oscillator are ampltiude, frequency, C:M ratio, and a modulation index. Each of these parameters are carefully modulated to produce the range of timbres that you hear.

Frequency and Amplitude

The frequency is being modulated via tseq, a trigger sequencer. The clock generated by prop feeds this signal and causes it to cycle through the table seq in time. The sequence is then biased by 58 to put it in the key of B flat, then converted to frequency with mtof. To prevent clicks, a small portamento filter is added.

 _clk get 0 _seq tseq 58 + mtof 0.001 port 

The amplitude of this parameter is fixed, and is set to 0.3.



The carrier component is part of the C:M ratio. It is typically a positive integer value denoting the frequency of the "carrier" oscillator, which is the oscillator that you actually hear.

The clock signal in the variable clk is being used with the triggerable random number generator trand to produce a value between 1 and 3. This value is converted to a whole number integer via floor. It is important to keep this value as a whole number to prevent clangorous non-harmonic timbres. When the Carrier component is anything but 1, it makes the frequency appear to jump to Carrier * frequency.

 _clk get 1 3 trand floor 


The modulator component is the second part of the C:M ratio. This component determines the frequency of the modulator oscillator, which modulates the frequency of the carrier oscillator. Larger values will cause harmonics to be more sparsely spread out, and often will sound brighter.

Similar to the carrier signal, it is being modulated via trand, this time using values between 1 and 7. The signal is also being floored to keep timbres "tonal".

 _clk get 1 7 trand floor

Modulation Index

The modulatation index determines how much frequency modulation happens. A modulation index of 0 creates a sinusoidal tone. The modulation index can be crudely thought of as a brightness control or something analogous to filter cutoff in a subtractive synthesis patch.

The modulation index is controlled by a low-frequency sinusoidal oscillator moving at a period of 30 seconds, moving between 0.1 and 2 via biscale.

 30 inv 1 sine 0.1 2 biscale

This being the last argument, it is closed with the actual "fm" word.


Reverb Throw

To add excitement, some of the signal is occasionally thrown into a reverb in what as known as a reverb throw. In analogue days, this was done using a fader sporadically moved up from time to time.

To begin, a copy of the FM sound is created via dup. One of these signals will signal sent to the reverb.


To simulate the sporadically on fader, the clock signal clk is fed into a maygate. When triggered, maygate will have a 20% probability of turning on. This allows tempo-synced throws to occur.

 _clk get 0.2 maygate 

The maygate signal is either on or off, which can cause very sharp jumps. To smooth this out, a portamento filter is used.

 0.01 port 

This signal is then multiplied with one of the copies of FM signal, and stored into the variable send.

 * _send set

Envelopes for articulation

Right now, the FM signal is constantly "on"; there is no sense of articulation (authors note: the throw signal has no articulation. This was by accident, by it will be left in). To create articulation, an envelope signal is created via tenv. It is clocked by the global clock clk. The signal is then multiplied with the dry signal.

 _clk get 0.001 0.01 0.4 tenv *

This completes the dry signal, so it is set to the variable dry.

 _dry set

Effect Processing


For reverb, revsc is used. The input signal of the reverb module is a combination of the dry signal and the send signal boosted by a factor of 2. Since this reverb is stereo, it is duplicated.

 _dry get _send get 2 * + dup 

The reverb parameters are set to have a 0.97 decay rate (1.0 being an infinite hold reverb) with a 5000Hz cutoff.

 0.97 5000 revsc 

Since revsc is a stereo signal, one of the values is droped. The remaining signal is attenuated by 27 dB, making it only really audible when dry signal is "thrown" into it.

 drop -27 ampdb * 

ReverbSC causes a lot of DC offset, so a dc blocker filter dcblk is used.


Feedback Delay

In addition to reverb, a tempo-synced delay line is also processed with the signal in parallel.

The input signal is only the throw signal from the variable send.

 _send get 

The feedback parameter is set to 0.8, or 80 percent loss.


The delay time is set to be a dotted quarter note delay time. This is done by converting the BPM (210) to a duration, then multiplying that by 1.5.

 210 bpm2dur 1.5 * 

The output of the delay signal is sent into a butter lowpass filter butlp with a cutoff of 800Hz. This is done so it does not interfere with the spectrum of the dry signal. After that, it is attenuated by 7 dB.

 delay 800 butlp -7 ampdb * + 

The dry signal is added back in, thus completing the patch.

 _dry get + 

Compile & play Stop audio