<Cabbage>
form caption("Victor") size(400, 300), colour(58, 110, 182), pluginid("def1")
keyboard bounds(8, 158, 381, 95)
label bounds(28, 10, 310, 82) text("Victor")
</Cabbage>

; posted by Victor Lazzariny to CSound mail list
;
; Sometime ago there was a question here about divide down oscillators etc, and I mentioned
; that a multiplier scheme was possible instead. So here’s the full example of an
; emulation of a string machine. It’s commented so it should be more or less
; self-explanatory. There are five parts to the code
; 
; 1. Creating the bandlimited tables for each octave
; 2. The phase generation instrument, which produces the lowest octave phases
; in twelve instances recursively launched, placed in an audio-rate array
; 3. The note generator, which picks up one of the phase signals, scales it up
; to the right octave and looks up the table waveform
; 4. The single VCA which applies an envelope controlled by a gate signal
; 5. The stereo chorus.


<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d  --midi-key-pch=5 --midi-velocity-amp=4 
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

massign 1,2
massign 2,2
massign 3,2
massign 4,2

// phase signals
gaphs[] init 12
// lowest oct
ioct init 4
// partial arrays
iarr[] init sr/(2*cpspch(ioct+1))

// sawtooth table generation
while ioct < 12 do
// reset partial table
icnt = 0
while icnt < lenarray(iarr) do
iarr[icnt] = 0
icnt += 1
od
// fill partial table
icnt = 1
while icnt <= sr/(2*cpspch(ioct+1)) do
iarr[icnt-1] = 1/icnt
icnt += 1
od
// create bandlimited table
ifn ftgen ioct,0,16384,10,iarr
ioct += 1
od

// 12 phase signals
instr 1
inst = p4/100
gaphs[p4] = phasor:a(cpspch(inst))
if p4 < 11 then
inst += .01
schedule(1+inst,0,p3,p4+1)
endif
endin
schedule(1.,0,-1,0)

// note generator
gasig init 0
instr 2
indx = round(frac(p5)*100)
ioct = int(p5)
itab = ioct < 4 ? 4 : (ioct > 12 ? 12 : ioct)
a1 = tablei:a(gaphs[indx]*2^ioct,itab,1,0,1)
gasig += a1*linenr:a(.2,0,.2,.01)
endin

// VCA
instr 3
kact active 2
kgate = kact > 0 ? 1 : 0
if kgate > 0 then
kht = .2
else
kht = .1
endif
kenv = portk(kgate,kht)
gasig *= kenv
endin
schedule(3,0,-1)

// chorus
instr 4
aL, aR reverbsc gasig, gasig, 0.7, 10000

amod1 = randi:a(3,.75)+oscili(2,.35)+31
amod2 = randi:a(2,.65)+oscili(3,.55)+29
a1 = vdelay(aL*.5,amod1,35)
a2 = vdelay(aR*.5,amod2,35)
out((aL + a1),(aR + a2))
gasig = 0
endin
schedule(4,0,-1)

</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
</CsScore>
</CsoundSynthesizer>
