vco2 — Implementation of a band-limited oscillator using pre-calculated tables.


vco2 is similar to vco. But the implementation uses pre-calculated tables of band-limited waveforms (see also GEN30) rather than integrating impulses. This opcode can be faster than vco (especially if a low control-rate is used) and also allows better sound quality. Additionally, there are more waveforms and oscillator phase can be modulated at k-rate. The disadvantage is increased memory usage. For more details about vco2 tables, see also vco2init and vco2ft.


ares vco2 kamp, kcps [, imode] [, kpw] [, kphs] [, inyx]


imode (optional, default=0) -- a sum of values representing the waveform and its control values.

One may use any of the following values for imode:

  • 16: enable k-rate phase control (if set, kphs is a required k-rate parameter that allows phase modulation)

  • 1: skip initialization

One may use exactly one of these imode values to select the waveform to be generated:

  • 14: user defined waveform -1 (requires using the vco2init opcode)

  • 12: triangle (no ramp, faster)

  • 10: square wave (no PWM, faster)

  • 8: 4 * x * (1 - x) (i.e. integrated sawtooth)

  • 6: pulse (not normalized)

  • 4: sawtooth / triangle / ramp

  • 2: square / PWM

  • 0: sawtooth

The default value for imode is zero, which means a sawtooth wave with no k-rate phase control.


Setting inyx to 0.25 (sr/4), or 0.3333 (sr/3) can produce a “fatter” sound in some cases, although it is more likely to reduce quality.


ares -- the output audio signal.

kamp -- amplitude scale. In the case of a imode waveform value of 6 (a pulse waveform), the actual output level can be a lot higher than this value.

kcps -- frequency in Hz (should be in the range -sr/2 to sr/2).

kpw (optional) -- the pulse width of the square wave (imode waveform=2) or the ramp characteristics of the triangle wave (imode waveform=4). It is required only by these waveforms and ignored in all other cases. The expected range is 0 to 1, any other value is wrapped to the allowed range.

[Warning] Warning

kpw must not be an exact integer value (e.g. 0 or 1) if a sawtooth / triangle / ramp (imode waveform=4) is generated. In this case, the recommended range is about 0.01 to 0.99. There is no such limitation for a square/PWM waveform.

kphs (optional) -- oscillator phase (depending on imode, this can be either an optional i-rate parameter that defaults to zero or required k-rate). Similarly to kpw, the expected range is 0 to 1.

[Note] Note

When a low control-rate is used, pulse width (kpw) and phase (kphs) modulation is internally converted to frequency modulation. This allows for faster processing and reduced artifacts. But in the case of very long notes and continuous fast changes in kpw or kphs, the phase may drift away from the requested value. In most cases, the phase error is at most 0.037 per hour (assuming a sample rate of 44100 Hz).

This is a problem mainly in the case of pulse width (kpw), where it may result in various artifacts. While future releases of vco2 may fix such errors, the following work-arounds may also be of some help:

  • Use kpw values only in the range 0.05 to 0.95. (There are more artifacts around integer values)

  • Try to avoid modulating kpw by asymmetrical waveforms like a sawtooth wave. Relatively slow (<= 20 Hz) symmetrical modulation (e.g. sine or triangle), random splines (also slow), or a fixed pulse width is a lot less likely to cause synchronization problems.

  • In some cases, adding random jitter (for example: random splines with an amplitude of about 0.01) to kpw may also fix the problem.


Here is an example of the vco2 opcode. It uses the file vco2.csd.

Example 483. Example of the vco2 opcode.


; Select audio/midi flags here according to platform
; Audio out   Audio in    No messages
; For Non-realtime ouput leave only the line below:
; -o vco2.wav -W ;;; for file output any platform

sr      =  44100
ksmps   =  10
nchnls  =  1

; user defined waveform -1: trapezoid wave with default parameters (can be
; accessed at ftables starting from 10000)
itmp    ftgen 1, 0, 16384, 7, 0, 2048, 1, 4096, 1, 4096, -1, 4096, -1, 2048, 0
ift     vco2init -1, 10000, 0, 0, 0, 1
; user defined waveform -2: fixed table size (4096), number of partials
; multiplier is 1.02 (~238 tables)
itmp    ftgen 2, 0, 16384, 7, 1, 4095, 1, 1, -1, 4095, -1, 1, 0, 8192, 0
ift     vco2init -2, ift, 1.02, 4096, 4096, 2

        instr 1
kcps    expon p4, p3, p5                ; instr 1: basic vco2 example
a1      vco2 12000, kcps                ; (sawtooth wave with default
        out a1                          ; parameters)

        instr 2
kcps    expon p4, p3, p5                        ; instr 2:
kpw     linseg 0.1, p3/2, 0.9, p3/2, 0.1        ; PWM example
a1      vco2 10000, kcps, 2, kpw
        out a1

        instr 3
kcps    expon p4, p3, p5                ; instr 3: vco2 with user
a1      vco2 14000, kcps, 14            ; defined waveform (-1)
aenv    linseg 1, p3 - 0.1, 1, 0.1, 0   ; de-click envelope
        out a1 * aenv

        instr 4
kcps    expon p4, p3, p5                ; instr 4: vco2ft example,
kfn     vco2ft kcps, -2, 0.25           ; with user defined waveform
a1      oscilikt 12000, kcps, kfn       ; (-2), and sr/4 bandwidth
        out a1


i 1  0 3 20 2000
i 2  4 2 200 400
i 3  7 3 400 20
i 4 11 2 100 200

f 0 14



See Also

vco, vco2ft, vco2ift, and vco2init.


Author: Istvan Varga

New in version 4.22