; TRAVELLER
;
; simple analog synth inspired by KORG Synthe-Bass
;
; (s) Severák 2019
; licensed with MIT license
<Cabbage> bounds(0, 0, 0, 0)
form caption("Traveller (by Severák)") size(400, 300), colour(0, 51, 153), pluginid("trav")
keyboard bounds(4, 176, 381, 95) value(36)
hslider bounds(6, 148, 377, 23) range(0, 22000, 22000, 0.5, 0.01) channel("traveller")
label bounds(6, 94, 258, 47) text("TRAVELLER")
label bounds(264, 120, 112, 19) text("by Severák")
combobox bounds(154, 12, 80, 20) text("triangle", "square", "saw", "arp", "pwm", "noise", "tonal noise") channel("mode")
checkbox bounds(36, 66, 22, 22) channel("hold")
vslider bounds(286, 26, 27, 66) range(0.01, 1, 0.01, 1, 0.001) channel("attack")
label bounds(274, 6, 43, 16) text("slow")
label bounds(270, 96, 56, 17) text("instant")
label bounds(322, 6, 75, 16) text("singing")
label bounds(330, 96, 62, 17) text("bump")
vslider bounds(346, 26, 29, 67) range(0.01, 1, 1, 1, 0.001) channel("decay")
label bounds(10, 42, 80, 16) text("hold")
label bounds(94, 42, 80, 16) text("bite")

checkbox bounds(122, 64, 26, 24) channel("bite")
label bounds(182, 42, 80, 16) text("quack")
checkbox bounds(208, 62, 26, 25) channel("quack")
label bounds(20, 280, 339, 14) text("no presets included - YOU have to be creative")
rslider bounds(26, 4, 44, 34) range(0, 2, 1, 0.5, 0.001) channel("vol")
label bounds(122, 14, 28, 16) text("~")
label bounds(72, 14, 27, 16) text("vol")
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

gkLastNote init 0

;instrument will be triggered by keyboard widget
instr 1
    gkLastNote init p4
    
    if gkLastNote != 0 && gkLastNote != p4 then
        ; this is monophonic synth
        turnoff
    endif
    
    inotnum notnum
    
    iwave chnget "mode"
    if iwave==1 then
        ; triangle
        imode = 12
    elseif iwave==2 then
        ; square
        imode = 10
    elseif iwave==3 then
        ; saw
        imode = 0
    elseif iwave==4 then
        ; arp
        imode = 2
        ilfomode = 3
    elseif iwave==5 then
        ; pwm
        imode = 2
        ilfomode = 1
    elseif iwave==6 then
        ; noise
        imode = -1
    elseif iwave==7 then
        ; noise
        imode = -1        
    endif
    
    kVol chnget "vol"
    kfilter chnget "traveller"
    ibite chnget "bite"
    
    if ibite==1 then
        ires = 0.7
    else
        ires = 0
    endif
    
    isustain chnget "hold"
    iattack chnget "attack"
    idecay chnget "decay"
    
    iquack chnget "quack"
    
    klfo lfo 0.8, 5, ilfomode
    kpw limit klfo, 0.05, 0.9
    
    if isustain == 1 then
        kEnv madsr iattack, 0.0001, 1, idecay
    else
        kEnv linsegr 0, iattack, 1, idecay, 0, iattack+idecay, 0
    endif
    
    if imode == -1 then
        aOsc noise 0.5, 0.5
    else
        kbnd pchbend 0, 100
        aRawOsc vco2 0.8, p4 + kbnd, imode, kpw
        aHum noise 0.01, -0.4 ; this is old, so it has some noise in VCO
        aOsc = aRawOsc + aHum
    endif
    
    if iwave==7 then
        kfilter = cpsmidinn(inotnum + 24) + kbnd
    endif
    
    if iquack==1 then
        aOutFilter moogladder2 aOsc, kfilter * kEnv, ires
    else
        aOutFilter moogladder2 aOsc, kfilter, ires
    endif
    
    aOut clip aOutFilter * kEnv * kVol, 0, 1
    
    outs aOut, aOut
endin

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