; 4track - an TASCAM-like multitrack recorder
;
; (s) Severák 2020
; licensed with MIT license
<Cabbage>
form caption("4track") size(445, 250),  colour(0, 51, 153), pluginid("4trk")
vslider bounds(40, 4, 50, 150) range(0, 1, 1, 1, 0.001) channel("vol1")
vslider bounds(95, 4, 49, 150) range(0, 1, 1, 1, 0.001) channel("vol2")
vslider bounds(150, 4, 50, 149) range(0, 1, 1, 1, 0.001) channel("vol3")
vslider bounds(204, 4, 50, 149) range(0, 1, 1, 1, 0.001) channel("vol4")
vslider bounds(256, 4, 50, 149) range(0, 1, 1, 1, 0.001) channel("volmix")

rslider bounds(42, 156, 52, 37) range(-0.5, 0.5, 0, 1, 0.001) channel("ch1bal")
rslider bounds(94, 156, 52, 37) range(-0.5, 0.5, 0, 1, 0.001) channel("ch2bal")
rslider bounds(150, 156, 52, 37) range(-0.5, 0.5, 0, 1, 0.001) channel("ch3bal")
rslider bounds(202, 156, 52, 37) range(-0.5, 0.5, 0, 1, 0.001) channel("ch4bal")


checkbox bounds(52, 194, 30, 30)  channel("ch1") radiogroup("ch") colour:1(255, 0, 0, 255)
checkbox bounds(104, 194, 30, 30) channel("ch2") radiogroup("ch") colour:1(255, 0, 0, 255)
checkbox bounds(160, 194, 30, 30) channel("ch3") radiogroup("ch") colour:1(255, 0, 0, 255)
checkbox bounds(214, 194, 30, 30) channel("ch4") radiogroup("ch") colour:1(255, 0, 0, 255)
checkbox bounds(266, 194, 30, 30) channel("mix")  radiogroup("ch") colour:1(255, 0, 0, 255)
checkbox bounds(320, 192, 108, 30) channel("ch0") radiogroup("ch") text("JUST PLAY")

checkbox bounds(318, 98, 108, 30) text("PLAY/REC") channel("running") colour:1(255, 0, 0, 255) fontcolour:1(255, 255, 0, 255) active(0) identchannel("playrec") 
filebutton bounds(316, 8, 122, 30) mode("directory") channel("dir") text("PROJECT", "PROJECT")
label bounds(6, 202, 39, 16) text("CH")
label bounds(48, 230, 37, 16) text("1")
label bounds(104, 230, 27, 16) text("2")
label bounds(158, 230, 33, 16) text("3")
label bounds(214, 228, 30, 18) text("4")

label bounds(320, 42, 118, 34) text("4track")
label bounds(262, 230, 38, 16) text("mix")

label bounds(4, 168, 35, 16) text("PAN")
label bounds(2, 130, 36, 17) text("VOL")
label bounds(342, 80, 91, 16) text("by Severák")
checkbox bounds(318, 132, 120, 30) text("listen to input") channel("listen") value(1)
label bounds(348, 168, 80, 16) text("00:00") identchannel("timer")
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d 
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

; ignore incoming MIDI events
massign 0,0

gkRunning init 0

; this will be a working dir:
; selectable by button DIR
gSdir init ""


; whole code is split into multiple instruments:
; - main recorder controls
; - playback head
; - record head
; - mixing head
; - timer


; recorder controls (always on)
instr 1


kch1 chnget "ch1"
kch2 chnget "ch2"
kch3 chnget "ch3"
kch4 chnget "ch4"
kch0 chnget "ch0"

kmix chnget "mix"

klisten chnget "listen"

gkRunning chnget "running"
gSdir chnget "dir"

if changed(gSdir)==1 && strcmpk(gSdir, "")==1 then
    ; TODO - here activate only on selecting project
    printks "activated! %s==%s %d\n", 0, gSdir, "", strcmpk(gSdir, "")
    event "i",5,0,1
endif

if changed:k(gkRunning)==1 && gkRunning==1 && kch1==1 then
    printks "REC 1 ON\n", 0.5
    event "i",200,0,900,1
endif

if changed:k(gkRunning)==1 && gkRunning==1 && kch2==1 then
    printks "REC 2 ON\n", 0.5
    event "i",200,0,900,2
endif

if changed:k(gkRunning)==1 && gkRunning==1 && kch3==1 then
    printks "REC 3 ON\n", 0.5
    event "i",200,0,900,3
endif

if changed:k(gkRunning)==1 && gkRunning==1 && kch4==1 then
    printks "REC 4 ON\n", 0.5
    event "i",200,0,900,4
endif

if changed:k(gkRunning)==1 && gkRunning==1 && kmix==1 then
    printks "MIX ON\n", 0.5
    event "i",300,0,900
endif


if changed:k(gkRunning)==1 && gkRunning==1 && kch1!=1 then
    printks "PLAY 1 ON\n", 0.5
    event "i",100,0,900,1
endif

if changed:k(gkRunning)==1 && gkRunning==1 && kch2!=1 then
    printks "PLAY 2 ON\n", 0.5
    event "i",100,0,900,2
endif

if changed:k(gkRunning)==1 && gkRunning==1 && kch3!=1 then
    printks "PLAY 3 ON\n", 0.5
    event "i",100,0,900,3
endif

if changed:k(gkRunning)==1 && gkRunning==1 && kch4!=1 then
    printks "PLAY 4 ON\n", 0.5
    event "i",100,0,900,4
endif

if changed:k(gkRunning)==1 && gkRunning==1 then
    ; tick of the clock
    event "i",400,0,900
endif

if kmix!=1 && klisten==1 then
    ; passtrough audio input when not mixing master and when its enabled
    aL, aR ins
    outs aL, aR
endif

endin

instr 5
    chnset "active(1)", "playrec"
endin


; playback head
instr 100

if gkRunning==0 then
    turnoff
endif


ich = p4
Sname sprintf "%s/ch%d.wav",  gSdir, ich
Schname sprintf "vol%d", ich
Sbalname sprintf "ch%dbal", ich
kVol chnget Schname
kVolmix chnget "volmix"
kBal chnget Sbalname

ivalid filevalid Sname
if ivalid==1 then
    
    kVol chnget Schname
    
    aL, aR diskin2 Sname, 1
    
    if kBal!=0 then
        aL, aR pan2 aL+aR, kBal+0.5
    endif
    
    outs aL* (kVol * kVolmix), aR * (kVol * kVolmix)
else
    turnoff
endif

endin

; record head
instr 200

if gkRunning==0 then
    turnoff
endif

aL, aR ins

ich = p4
Sname sprintf "%s/ch%d.wav",  gSdir, ich
printf_i "out=%s\n", 1, Sname

fout Sname, 9, aL, aR

endin


; mixing head
instr 300

if gkRunning==0 then
    turnoff
endif

aL, aR monitor

Sname sprintf "%s/mix.wav",  gSdir
printf_i "out=%s\n", 1, Sname

fout Sname, 9, aL, aR

endin

; timer
instr 400
if gkRunning==0 then
    turnoff
endif

ktime init -1
ktrig metro 1

if ktrig==1 then
    ktime = ktime + 1
    Stime sprintfk "text(\"%02d:%02d\")", floor(ktime/60), (ktime%60)    
    chnset Stime, "timer" 
endif

endin



</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
;starts instrument 1 and runs it for a week
i1 0 [60*60*24*7] 
</CsScore>
</CsoundSynthesizer>
