bounds(0, 0, 0, 0)
form caption("Velocity Curve DEMO") size(600, 300), colour(255, 255, 255), pluginID("def1")
keyboard bounds(10, 192, 581, 95) value(30) whitenotecolour(255, 255, 255, 255)
nslider bounds(484, 14, 105, 27) range(1, 100, 32, 1, 1) velocity(50) text("Max Polyphony") channel("maxPoly") increment(1) value(32) textcolour(144, 144, 144, 255)
label bounds(474, 48, 83, 12) text("Active notes:") colour(243, 3, 3, 0) align("right") fontcolour(144, 144, 144, 255)
label bounds(562, 48, 26, 12) text("0") colour(202, 238, 90, 0) fontcolour(34, 34, 34, 255) identchannel("activeNotes") align("right")
gentable bounds(12, 66, 147, 99) tablenumber(1111) amprange(0, 1, 1111, 0.01) tablegridcolour(236, 236, 236, 255) identchannel("table1"), tablebackgroundcolour(245, 245, 245, 255) active(1) tablecolour:0(111, 111, 111, 147)
label bounds(12, 168, 147, 13) text("Velocity Curve") fontcolour(43, 43, 43, 255)
combobox bounds(10, 40, 102, 20) channel("velPreset") text("Preset 1", "Preset 2", "Preset 3", "Preset 4")
button bounds(116, 40, 44, 20) text("SAVE", "SAVE") colour:1(0, 255, 0, 255) colour:0(0, 255, 0, 255) channel("velBtnSave")
-n -d -+rtmidi=NULL -M0 -m0d --midi-key-cps=4 --midi-velocity-amp=5 -+max_str_len=10000
; Initialize the global variables.
sr = 44100
ksmps = 256
nchnls = 2
0dbfs = 1
giVelCurveRes = 1024
giFT_velCurve ftgen 1111, 0, giVelCurveRes, -7, \
0, giVelCurveRes, 1
#define VELCURVE(vel) #
$vel tab_i floor(giVelCurveRes * $vel), giFT_velCurve
#
; ADD "FOR/NEXT" and "FOR_INDEX" SYNTAX TO CSOUND (by Mauro Giubileo):
#define FOR(initialization'condition) #
$initialization
while ($condition) do
#
#define NEXT(increment) #
$increment
od
#
#define FOR_INDEX('index' 'from' 'to') #
$index = ($from) - 1
$index.__LAST__ = $to
while ($index < $index.__LAST__) do
$index += 1
#
; ====================================================================
;=========================================
;modified version of UDO by Joachim Heintz
;(and Csound-classic-style indented by Mauro Giubileo)
;https://github.com/csudo/csudo/blob/master/strings/conversion/StrToArr.csd
;=========================================
opcode StrToArr, i[]i, SS
S_in, \
S_sep xin
;count the number of substrings
iLenSep strlen S_sep
iPos = 0
iPosShift = 0
iCnt = 0
while iPos != -1 do
iCnt += 1
S_sub strsub S_in, iPosShift
iPos strindex S_sub, S_sep
iPosShift += iPos + iLenSep
od
;create a string array and put the substrings in it
i_Arr[] init iCnt
iPos = 0
iPosShift = 0
iArrIndx = -1
while iPos != -1 do
iArrIndx += 1
S_sub strsub S_in, iPosShift
iPos strindex S_sub, S_sep
iEnd = (iPos == -1 ? -1 : iPosShift + iPos)
S_ToArr strsub S_in, iPosShift, iEnd
iPosShift += iPos + iLenSep
i_Arr[iArrIndx] = strtod(S_ToArr)
od
xout i_Arr, iCnt
endop
;===============================
opcode corda, a, ii
iFreq, iVel xin
setksmps 8
aNoise rand iVel
iDelayLdur = 1 / iFreq
aImpulse = aNoise * linseg:a(1, iDelayLdur, 1, 0, 0)
aOut delayr 1 / iFreq
aOut += aImpulse
aOut = (aOut + delay1(aOut)) * 0.5
delayw aOut
xout aOut
endop
instr 2
iFreq = p4
iVel = p5
$VELCURVE(iVel)
aOut corda iFreq, iVel
out aOut
endin
massign 0, 1
;instrument will be triggered by keyboard widget
instr 1
iFreq = p4
iAmp = p5
iNumKey = notnum() - 20
if (iNumKey < 1 || iNumKey > 88) goto skipnote
aOut subinstr 2, iFreq, iAmp
aOut = aOut * madsr(0.01, 0, 1, 5)
outs aOut, aOut
skipnote:
endin
instr Mntr
kMaxPoly chnget "maxPoly"
kVelPreset chnget "velPreset"
kVelBtnSave chnget "velBtnSave"
kActivNotes active 1
if (kActivNotes > kMaxPoly) then
turnoff2 1, 1, 0
endif
if (changed(kActivNotes) == 1) then
chnsetks sprintfk("text(\"%d\")", kActivNotes), "activeNotes"
endif
if (changed2(kVelBtnSave) == 1) then
event "i", "velPreset_write", 0, 1
endif
if (changed(kVelPreset) == 1) then
event "i", "velPreset_read", 0, 1
endif
endin
;=================================================
gS_curVelArgs init "" ; this will be updated with the args for the ftgen of the current velocity curve
instr velPreset_write ; WRITE THE VEL PRESET
iPreset chnget "velPreset"
Sargs getftargs giFT_velCurve, 1
if (strcmp(gS_curVelArgs, Sargs) != 0) then
; in this case, the user changed the control points of the current vel. curve,
; so, we have to write the new values in the preset file:
gS_curVelArgs \
= Sargs
gihand fiopen sprintfk("velPreset%d.txt", iPreset), 0
iArr[], \
iCnt StrToArr Sargs, " "
iBad = 2 ; <-- the points that gentable widget adds to the end, but that we don't need
fouti gihand, 0, 0, iCnt - iBad ; <-- writes the "corrected" number of control points
$FOR_INDEX('indx' FROM '0' TO 'iCnt - 1 - iBad')
fouti gihand, 0, 0, iArr[indx]
$NEXT()
ficlose gihand
endif
turnoff
endin
instr velPreset_read ; READ THE VEL PRESET
iPreset chnget "velPreset"
SvelFile sprintf "velPreset%d.txt", iPreset
iValid filevalid SvelFile
if (iValid == 0) then ; if the file doesn't exist, create it:
giHand fiopen SvelFile, 0
fouti giHand, 0, 0, 3
fouti giHand, 0, 0, 0
fouti giHand, 0, 0, giVelCurveRes
fouti giHand, 0, 0, 1
ficlose giHand
endif
giHand fiopen SvelFile, 1
iCnt init -1
fini giHand, 0, 1, iCnt
iTemp = 0
Stmp = ""
$FOR_INDEX('indx' FROM '1' TO 'iCnt')
fini giHand, 0, 1, iTemp
Stemp = Stmp
;Stmp sprintf ((indx == 1)? "%s%g" : "%s %g"), Stemp, iTemp
if (indx == 1) then
Stmp sprintf "%g", iTemp
else
Stmp sprintf "%s %g", Stemp, iTemp
endif
$NEXT()
ficlose giHand
Sscoreline sprintf "f 1111 0 %d -7 %s", giVelCurveRes, Stmp
scoreline_i Sscoreline
chnset "tablenumber(1111)", "table1"
gS_curVelArgs \
= Stmp
prints "gS_curVelArgs: %s\n", gS_curVelArgs
turnoff
endin
;causes Csound to run for about 7000 years...
f 0 z
i "Mntr" 0 z
;i3 0 1