; Changes no.2
; by Anthony M. Kozar Jr.
; Version for Csound
; December 16, 2004
; On the web at
; Email
; Intrument $INSNO by Anthony Kozar.
; Instruments 97 & 99 by Sean Costello (see below).
; I am placing the portions of this Csound orchestra file
; that are my original work into the public domain. I
; therefore waive all copyright interest in those portions.
sr = 44100
kr = 44100 ; kr must equal sr for phaser
ksmps = 1
nchnls = 2
; Standard Midi instrument macro
#define MidiInstr(INSNO'TABLE) #
instr $INSNO
idur = p3
iAttVel = p4 ; Midi Attack Velocity
idb = iAttVel/127 * 90 ; rescale MIDI velocity to 90db
iamp = ampdb(idb)
iAttDelta = 1.0 - (iAttVel/127) ; diff btw max attack and this note's
iAttTime = 0.5 * iAttDelta ; envelope attack time
iRelTime = (0.5 + (idur/20.0 * 4.0)) * iAttDelta ; envelope release time
iSusTime = idur - (iAttTime + iRelTime) ; envelope sustain time
iDecTime = 5.0 ; decay envelope time
iclicksus = idur - 0.10 ; sustain time for declick envelope
ipitch = octpch(p5) ; convert octave.pitchclass to octave.decimal
ifnum = $TABLE ; ftable number
kdclick linseg 0, 0.05, 1.0, iclicksus, 1.0, 0.05, 0 ; declick envelope
kenv linseg 0, iAttTime, iamp, iSusTime, iamp, iRelTime, 0 ; attack-release envelope
kdecay linseg 1.0, iAttTime, 1.0, iDecTime, .7 ; decay to about -3db
kamp = kdclick*kenv*kdecay
afund oscili kamp, cpsoct(ipitch), ifnum ; audio oscillator
acel1 oscili kamp, cpsoct(ipitch - .008), ifnum ; audio oscillator - flat
acel2 oscili kamp, cpsoct(ipitch + .012), ifnum ; audio oscillator - sharp
;;; asig = afund + acel1 + acel2
;;; kpan = (ipitch - 4) ; spread notes across stereo field
;;; asig1, asig2, a3, a4 pan asig, kpan, 1, 2, 1 ; function table 2 holds panning characteristics
outs (afund+acel1)/2, (afund+acel2)/2 ; send signals to stereo channels
gaPhaserSend = gaPhaserSend + (afund + acel1 + acel2)/3
endin
#
; global variables initialization
giTable ftgen 0, 0, 16384, 10, 1.0, 0.2, 0.1 ; mild organ tone
gaPhaserSend init 0 ; global variable to send instruments to ensemble section
gaReverbSend init 0 ; global variable to send output of ensemble to reverb
; instantiate instruments as needed
$MidiInstr(1'giTable)
$MidiInstr(2'giTable)
$MidiInstr(3'giTable)
$MidiInstr(4'giTable)
; ************************************************************************
; from stringphaser.orc
;
; by Sean Costello, August 23-26, 1999
;
; This orchestra is a digital recreation of the old analog "string
; ensemble." A string ensemble was an attempt to create a reasonably
; full string section sound, with full polyphony, using the limited
; technology available in the early 1970's. In this orchestra,
; the string ensemble section is followed by a 6-stage phase shifter
; (a digital recreation of a common 1970's analog effect), and is
; sent into a FDN (Feedback Delay Network) reverb, based upon the
; work of Stautner and Puckette.
; ************************************************************************
instr 97 ; Ensemble section. Takes static sawtooth waves,
; and produces an animated flanged/chorused/vibratoed
; output. The phase shifter follows the output
; of the ensemble.
; Initialization of feedback variables for allpass filters.
ay1 init 0
ay2 init 0
ay3 init 0
ay4 init 0
ay5 init 0
ay6 init 0
; Initialization of variable for phaser feedback.
afeed init 0
idur = p3
ivib = p4 * .00025 ; Determines amount of pitch change/vibrato/
; chorusing. A value of 1 gives moderately thick
; chorusing, without excessive vibrato. Vary this
; according to taste.
; Simulates the first of two 3-phase LFOs that were used
; in the ensemble sections. Each LFO had three outputs,
; seperated by 120 degrees. This first LFO provides a
; slow flanging component to the sound, and helps to
; prevent unpleasant phase cancellations of the faster vibrato
; component provided by the second LFO.
ktimea oscili 4, 0.33, 1
ktimeb oscili 4, 0.33, 1, .333
ktimec oscili 4, 0.33, 1, .667
; Simulates the second 3-phase LFO. This LFO provides
; a vibrato component to the sound. Note that the amplitude
; of this LFO is 1/4th the amplitude of the slower LFO.
ktimed oscili 1, 5.5, 1
ktimee oscili 1, 5.5, 1, .333
ktimef oscili 1, 5.5, 1, .667
; The outputs of the 2 LFOs are combines, so that the 0
; degree component of the slow LFO is combined with the
; 0 degree component of the fast LFO, the 120 degree
; component of the slow LFO is combined with the 120
; degree component of the fast LFO, and the 240 degree
; component of the slow LFO is combined with the 240
; degree component of the fast LFO. Each of the summed
; LFO signals is scaled by ivib.
ktime1 = (ktimea + ktimed) * ivib
ktime2 = (ktimeb + ktimee) * ivib
ktime3 = (ktimec + ktimef) * ivib
; Each of the summed & scaled LFO signals is used to
; modulate a deltapi delay line. This results in
; three parallel signals, each with a small amount of
; vibrato and pitch warble.
adummy delayr .030
asig1 deltap3 ktime1 + .012
asig2 deltap3 ktime2 + .012
asig3 deltap3 ktime3 + .012
delayw gaPhaserSend
; The delay line outputs are mixed together, resulting
; in a signal with complex phase, timbral and pitch
; shifts. Unlike most flangers or chorus generators, the
; dry input signal is NOT mixed in with the outputs of
; the delay lines. This results in a more animated signal,
; with multiple layers of "through-zero" flanging, and
; less of the characteristic comb-filter sound of normal
; flangers and choruses.
aout = (asig1 + asig2 + asig3) * .33
; kphs and kcoeff make up the modulation signal for the
; phaser. The phaser coefficient must be in the range of
; -1 < kcoeff < 1. For phase shifting purposes, the more
; interesting effects occur in the range -1 < kcoeff < 0.
; The modulating waveform uses an inverted half-sine
; (ranging from -1 to 0) as a table, which results in
; a nice phasing sweep.
kphs oscili .69, .1, 3, .25
kcoeff = kphs - .3
; Input to the phaser is the output of the delay lines,
; plus feedback from the output of the phaser. Feedback
; results in increased depth of the notch frequencies,
; making a more pronounced "sweeping" sound.
ain = aout + afeed
; Each allpass stage takes the form
;
; Output = (coeff * Input) + PreviousInput - (coeff * PreviousOutput)
;
; The allpass section consists of 6 of these stages in series,
; with each stage sharing the same coefficient. You can easily
; extend these by cutting and pasting. In my original orchestra,
; I used a unit generator of my own construction, allpassn, for
; the phase shifting. allpassn includes n stages of allpass filters
; in series, all sharing the same coefficient, with feedback amount
; variable. I will soon send this ugen to John ffitch, as it is
; nice to have this in a ugen so that the kr can be at a value different
; from sr.
ax1 delay1 ain
ay1 = kcoeff * ain + ax1 - kcoeff * ay1
ax2 delay1 ay1
ay2 = kcoeff * ay1 + ax2 - kcoeff * ay2
ax3 delay1 ay2
ay3 = kcoeff * ay2 + ax3 - kcoeff * ay3
ax4 delay1 ay3
ay4 = kcoeff * ay3 + ax4 - kcoeff * ay4
ax5 delay1 ay4
ay5 = kcoeff * ay4 + ax5 - kcoeff * ay5
ax6 delay1 ay5
ay6 = kcoeff * ay5 + ax6 - kcoeff * ay6
; Feedback to phaser. Increase the constant for a more
; pronounced effect. Feedback gain values outside of
; the range -1 < g < 1 may result in oscillation, overflow,
; and other nasty things.
afeed = .5 * ay6
; The output of the allpass filter series is summed with
; the input to the allpass filter series, to produce an
; output signal with 3 notches in it. As kcoeff is swept,
; the notches move in frequency, producing the classic
; "phaser" effect. The output is also scaled by 1/2 to
; keep the output level roughly the same as the input level.
aout2 = (aout + ay6) * .5
; The output of the phase shifting section is sent via
; a global variable to instr 99 (reverberation).
gaReverbSend = gaReverbSend + .37 * aout2
; declick envelope added by akozar
iclicksus = p3 - 0.05 ; sustain time for declick envelope
kdclick linseg 1.0, iclicksus, 1.0, 0.05, 0 ; declick envelope
; Phaser output sent to main outputs. If you want to
; use the straight ensemble output (with no allpass
; phase shifting), replace aout2 with aout in the line
; below, as well as in the gaReverbSend... line above.
outs kdclick*aout2, kdclick*aout2
gaPhaserSend = 0
endin
instr 99 ; Simple implementation of Feedback Delay Network (FDN)
; reverb, as described by John Stautner and Miller
; Puckette, "Designing Multi-Channel Reverberators,"
; Computer Music Journal, Vol. 6, No. 1, Spring 1982,
; p.52-65. This version sticks to implementing the
; basic FDN structure, and leaves out most of the
; FIR multitap delay lines and filtering used for
; the early reflections. For sounds with non-percussive
; attacks, this simple implementation works great.
afilt1 init 0
afilt2 init 0
afilt3 init 0
afilt4 init 0
igain = p4 * 0.70710678117 ; gain of reverb
ipitchmod = p5 ; amount of random pitch mod, between 0 and 1
idelaytime = p6 ; controls overall length of delay lines
ifilt = p7 ; controls cutoff of lowpass filters at
; outputs of delay lines
ifreq = p8 ; controls frequency of random noise
kgain linseg .94, 66, .94, 2, 1, p3 - 68, 1
k1 randi .001, 3.1 * ifreq, .06
k2 randi .0011, 3.5 * ifreq, .9
k3 randi .0017, 1.11 * ifreq, .7
k4 randi .0006, 3.973 * ifreq, .3
atap multitap gaReverbSend, 0.00043, 0.0215, 0.00268, 0.0298, 0.00485, 0.0572, 0.00595, 0.0708, 0.00741, 0.0797, 0.0142, 0.134, 0.0217, 0.181, 0.0272, 0.192, 0.0379, 0.346, 0.0841, 0.504
adum1 delayr 0.072
adel1 deltapi 0.0663 * idelaytime + k1 * ipitchmod
delayw gaReverbSend + afilt2 + afilt3
adum2 delayr 0.082
adel2 deltapi 0.0753 * idelaytime + k2 * ipitchmod
delayw gaReverbSend - afilt1 - afilt4
adum3 delayr 0.095
adel3 deltapi 0.0882 * idelaytime + k3 * ipitchmod
delayw gaReverbSend + afilt1 - afilt4
adum4 delayr 0.11
adel4 deltapi 0.0971 * idelaytime + k4 * ipitchmod
delayw gaReverbSend + afilt2 - afilt3
afilt1 tone adel1 * igain, ifilt
afilt2 tone adel2 * igain, ifilt
afilt3 tone adel3 * igain, ifilt
afilt4 tone adel4 * igain, ifilt
; declick envelope added by akozar
iclicksus = p3 - 0.05 ; sustain time for declick envelope
kdclick linseg 1.0, iclicksus, 1.0, 0.05, 0 ; declick envelope
outs kdclick*(afilt1 + afilt2 + atap), kdclick*(afilt4 + afilt3 + atap)
gaReverbSend = 0
endin