Hans Mikelson
Introduction
Analog modeling has recently become a popular form of synthesis which allows a great deal of expression in performance. This article describes using Csound's analog modeling opcodes, vco and moogvcf. I tested these instruments using Gabriel Maldonado's DirectCsound 2.6 running on a Dell 300 MHz Pentium II computer with an AWE64 Soundblaster value card and Windows 95. I used an Alesis Quadrasynth + Piano as the controller keyboard with control knobs 1 and 2 assigned to continuous controllers 50 and 56.
Command line
The first step in using Csound for real-time performance is to determine an appropriate command line. I use the following command saved in a batch file:
csound -+K -+q -b128 -+p6 -+O %1.orc %1.sco
The flag -+K with no number following tells DirectCsound to prompt for the desired MIDI input device. The flag -+q with no number following tells DirectCsound to prompt for the desired audio output device. The flag -b128 allows for 128 byte buffers. The flag -+p6 allows for six buffers. After some experimenting I found that setting buffer size to128 bytes and setting the number of buffers to 6 with a 44100 sample rate provided a good compromise between responsiveness and sound quality. The flag -+O suppresses all output for better real-time performance. I like to save this command line as a batch file, csm.bat so DirectCsound can be activated by typing the command:
csm anmod
Analog modeling
Csound maps MIDI channels to instruments so that MIDI channel 1 controls instr 1, MIDI channel 2 controls instr 2 etc. The first step is to obtain the MIDI values for velocity and pitch. The veloc opcode returns the MIDI note velocity. This is then passed through a table to allow for different velocity response curves. The opcode cpsmidi returns the MIDI note frequency.
ivel veloc ; Velocity iamp tablei ivel, 3 ; Convert to amplitude ifqc cpsmidi ; Get the note in cps
The next step is to generate an amplitude envelope. For real-time performance the linenr envelope is used for the amplitude envelope since it allows for midi controlled note length. In this case I use it as a de-click envelope.
; Amp Rise, Dec, AtDec kamp linenr iamp, .05, .05, .05 ; Declick envelope
The next step is to read from the MIDI continuous controllers. In this instrument I use continuous controller 50 to modulate frequency and continuous controller 56 to modulate resonance. The opcode midictrl is used to read the MIDI continuous controller value. I use a table look-up to change the range of the continuous controller for frequency. I also generate an exponential envelope for sweeping the filter.
; Low pass filter frequency kfce expseg .2, .1, 1, .2, .8, .1, .8 ; Fco envelope kfcs midictrl 50, 10 ; Fco controller kfco tablei kfce*kfcs, 2 ; Change scaling form 0-127 to 20-20000 ; Low pass filter resonance krzs midictrl 56, 20 ; Q controller krez = krzs*.01 ; Adjust 0-127 to 0-1.27
The final step is to use the analog modeling opcodes. The vco opcode below is used to generate a sawtooth wave. This signal is then passed through the moogvcf four pole resonant low pass filter before output using outs.
; Amp Fqc Wave PW Sine Delay asig vco 1, ifqc, 1, 1, 1, .1 ; Oscillator 1 aout moogvcf asig, kfco, krez ; Filter 1
Stereo Pad
Instrument 2 simulates an analog stereo pad. Detuned frequencies are generated for the left and right channels to produce a wide stereo impression.
ifqcl = ifqc*.998 ; Stereo detuning for left oscillator ifqcr = ifqc*1.002 ; Stereo detuning for right oscillator
A low frequency oscillator is used to sweep the cut-off frequency which gives some animation to the sound.
klfo2 oscil .2, .5, 1 ; Low frequency sweep kfc2 tablei kfce*kfcs*(1+klfo2), 2 ; Change scaling form 0-127 to 20-20000
The resolution of MIDI is only 127 values. This coarse resolution sometimes results in a stepping sound when a control knob is swept. This stepping can be eliminated using the port command to smooth out the control value.
kfco port kfc4, .01
In this instrument I use MIDI controller 1, the mod wheel to add vibrato to the sound.
kmw midictrl 1 ; Modwheel klfo1 oscil kmw*.0001, 6, 1 kvbr = 1+klfo1
The vco opcode is used next to generate three sawtooth oscillator signals. The third oscillator is added and subtracted from the left and right channels respectively before they are passed through the moogvcf filter.
asig2 vco 1, ifqcl*kvbr*1.01, 1, 1, 1, iofqc ; Oscillator 3 ; Amp Fqc Wave PW Sine Delay asigl vco 1, ifqcl*kvbr, 1, 1, 1, iofqc ; Oscillator 1 aoutl moogvcf asigl+asig2, kfco, krezm ; Filter 1 asigr vco 1, ifqcr*kvbr, 1, 1, 1, iofqc ; Oscillator 2 aoutr moogvcf asigr-asig2, kfco, krezm ; Filter 2
Output is then generated for the left and right channels. This allows for a rich stereo pad sound.
Pulse Width Modulation
The next instrument implements pulse width modulation with portamento. To implement portamento I first initialize a global variable gifqc to 440 in the header of the orchestra. I can than use this variable to store the last frequency. Pitch is swept between the last frequency and the current frequency by the linseg opcode. The time it takes to get to the next frequency depends on how far apart the two frequencies are.
ifqco init gifqc ; Get the old frequency ifqc cpsmidi ; Get the note in cps gifqc = ifqc ; Update the global frequency idfqc = abs(ifqco-ifqc) ; Calculate the difference between frequencies kfqc linseg ifqco, .001*idfqc, ifqc, .1, ifqc ; Linear pitch portamento
I next modulate the pulse width with a low frequency sine wave to create a pulse width modulation effect.
klfo1 oscil .4, kfqc*.005, 1 kpw = 1+klfo1
The rate of modulation depends on the pitch of the instrument so higher pitches have faster modulation rate.
Other Filters
Some of Csound's other filters can be used in place of moogvcf. The opcodes rezzy, lowres, lowresx, vlowres and even pareq can produce analog sounding filters. I provide some examples of these in the orchestra file. You could also create your own filters using biquad.
Conclusion
Using analog modeling in real-time gives an opportunity to really test the quality of the opcodes. The instruments presented here have an analog sound and the moogvcf filter has a good self oscillation sound. For comparison purposes I used a Waldorf Pulse which has an all analog signal path and an analog four pole resonant low pass filter. In terms of analog sound quality the Pulse sound is fatter, warmer, more up front and grittier. The Csound analog modeling opcodes are fairly fat sounding and are extremely flexible. This type of flexibility can only be approached with the most expensive modular analog synthesizers.