In Seven
by Paul Batchelor
# 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:
- The table seq is used to store a sequence of note values to step through
- The variable clk is used to store clock signals.
- The variable send is used to store a signal to be sent to the reverb effect. In this patch, the amount of signal sent to reverb is modulated through a pulsed envelope, creating what is known as a "reverb throw".
- The variable dry contains a copy of the dry signal.
_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.
0.3
Carrier
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
Modulator
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.
fm
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.
dup
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
Reverb
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.
dcblk
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.
0.8
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 +