vmeter bounds(944, 8, 23, 68) channel(“vMeter1”) value(0.362802) overlayColour(70, 53, 53, 255) outlineThickness(0) meterColour:0(255, 0, 0, 255) meterColour:1(255, 0, 255, 255) meterColour:2(255, 255, 0, 255) meterColour:3(0, 255, 255, 255) meterColour:4(0, 0, 255, 255)
vmeter bounds(982, 8, 24, 68) channel(“vMeter2”) value(0.819532) overlayColour(70, 53, 53, 255) outlineThickness(0) meterColour:0(255, 0, 0, 255) meterColour:1(255, 0, 255, 255) meterColour:2(255, 255, 0, 255) meterColour:3(0, 255, 255, 255) meterColour:4(0, 0, 255, 255)
image bounds(938, 4, 36, 75) channel(“image328ce6c9ca1e4925879b765812e66900”) file(“grill.png”)
image bounds(978, 4, 36, 75) channel(“image328ce6c9ca1e4925879b765812e66900”) file(“grill.png”)
-n -d -+rtmidi=NULL -M0 --midi-key=4 --midi-velocity-amp=5 -m0d
sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1
; Assign midi channel 10 to the midi triggered instrument (instr 1)
massign 10, 1
;gSSamplePath init “”
giTable1 init 100
giTable2 init 101
giIndxTabGen[] init 6 ; Table containing the reference (number) to the GEN01 tables (mono or left channel)
giIndxTabGenR[] init 6 ; Table containing the reference (number) to the GEN01 tables (right channel if exists)
giNumChannel[] init 6 ; Table containing the number of channels for each sample
; giReady[] init 6 ; not used !!!
;-------------------------------------------------
; Extract Filename from the whole path
;-----------------------------------------------------
opcode FileNameFromPath,S,S ; Extract a file name (as a string) from a full path (also as a string)
Ssrc xin ; Read in the file path string
icnt strlen Ssrc ; Get the length of the file path string
ESCAPE: ; Escape point once the backslash has been found
Sname strsub Ssrc, icnt+1, -1 ; Create a new string of just the file name
xout Sname ; Send it back to the caller instrument
endop
opcode CleanStrng, S, S ;returns the ASCII numbers of the input string as string
reinit Toto1
Toto1:
ipos init 0
rireturn
Sin xin ;input string
ilen strlen Sin ;its length
ipos = 0 ;set counter to zero
Sres = “” ;initialize output string
loop: ;for all characters in input string:
ichr strchar Sin, ipos ;get its ascii code number
Stemp strsub Sin,ipos,ipos+1 ;extract the char
if ichr ==92 then ; if it is a backslash
Stemp ="/" ; replace it with a slash
endif
Sres strcat Sres, Stemp ;append this to the output string
loop_lt ipos, +1, ilen, loop ;see comment for ‘loop:’
xout Sres ;return output string
endop
opcode MyReverb,aa,aakkkk ;Opcode for adding a reverb and panning to the entry signal
aInL,aInR,kRoom,kDamp,kMix,kPan xin
aRvbL,aRvbR freeverb aInL, aInR,kRoom, kDamp
aOut1 = kMixaRvbL+(1-kMix)aInL
aOut2 = kMixaRvbR+(1-kMix)aInR
aOut1= sqrt(1-kPan)(aOut1 ) ; pan the signal using a sqrt rule
aOut2= sqrt(kPan)(aOut2 )
xout aOut1,aOut2 ; send audio to outputs
endop
;------------------------------------------------------------------
;always on instrument that waits for user to specify sample folder
;------------------------------------------------------------------
instr 100
SFilepath chnget “sampleFolderButton”
if changed:k(SFilepath) == 1 then
reinit TheFilePathreinit
TheFilePathreinit:
gSSamplePath CleanStrng SFilepath
rireturn
event “i”, 90, 0, 0.1
endif
endin
instr 4
if metro(20) == 1 then
chnset abs(randi:k(1.1, 100, 2)), “vMeter1”
chnset abs(randi:k(1.1, 100, 2)), “vMeter2”
endif
endin
;------------------------------------------------------------------
; READ a directory and load samples into gen tables
; when user has selected folder, load them into function tables.
; it will create the number of tables accordingly to the number
; of channels of the sample
;-----------------------------------------------------------------
instr 90
prints “Loading files to function tables\n”
gSFiles[] directory gSSamplePath , “.wav” ; Populate a table with the file names
iCnt init 0
while iCnt<6 do ; Let’s work with the 6 first samples in the table
printf_i “Loading :%s\n”,iCnt,gSFiles[iCnt]
;--------------------------------------------------------------
; Note :the function tables are indexed starting 100 -> 111
; and the indexes are stored in table
; giIndxTabGen[] : mono or left channel for stereo
; giIndxTabGenR[] : right channel (if exists)
;--------------------------------------------------------------
giNumChannel[iCnt] filenchnls gSFiles[iCnt] ; Read how many channel in sample and store it in table
if giNumChannel[iCnt] ==2 then ; test if sample is stereo
giIndxTabGen[iCnt] ftgen 100+iCnt,0,0,1,gSFiles[iCnt],0,0,1 ; The left channel is stored into the table, tables numbers from 100 -> 111
giIndxTabGenR[iCnt] ftgen 200+iCnt,0,0,1,gSFiles[iCnt],0,0,2 ; a similar table receives the right channel, tables numbers from 200 -> 211
else ; Case of Mono sample
giIndxTabGen[iCnt] ftgen 100+iCnt,0,0,1,gSFiles[iCnt],0,0,1 ; the only one channel is store in the table
endif
iCnt+=1 ; next sample
od
event_i “i”, 102, 1, 0 ; now it is finished : Lets fill up the sound filers
endin
;---------------------------------------------------------
;once files have been loaded to tables, update soundfilers
instr 102
iCnt init 0
while iCnt<6 do
SMessage sprintf “file(”%s")", gSFiles[iCnt]
printf_i “%s\n”,iCnt,gSFiles[iCnt]
SChannel sprintf “filer%d”, iCnt
chnset SMessage, SChannel
SLabel sprintfk “FilenameLabel%d”, iCnt
Smessage FileNameFromPath gSFiles[iCnt]
Smessage3 sprintfk “text(%s)”,Smessage
chnset Smessage3 ,SLabel
; giReady[iCnt] = 1
iCnt+=1
od
endin
;-------------------------------------------------------------------
;this instrument get triggered by the keyboard. It listens for
;a keypress and then trigger instr 3 to play the associated sample
;-------------------------------------------------------------------
instr 1
;----------------------------------------------------------------------
; Call instr 3 with Midi Note ,Velocity, index (0 -> 6)for widget and Gen01 table
;----------------------------------------------------------------------
; kick 1 NOTE 36
if p4 == 36 then ;check midi note cf GM midi drum table
chnset “value(1)”,“bng0” ; blink the little light on screen
a11 ,a12 subinstr 3,p4,p5,0 ;call inst 3 with corresponding table index
outs a11,a12 ;output the sound !!!
endif
; snare 1 NOTE 37
if p4 == 37 then
chnset “value(1)”,“bng1”
a11,a12 subinstr 3,p4,p5,1
outs a11,a12
endif
; openhi NOTE 39 openhi
if p4 == 39 then
chnset “value(1)”,“bng2”
a11,a12 subinstr 3,p4,p5,3
outs a11,a12
endif
; hihat 1 NOTE 38
if p4 == 38 then
chnset “value(1)”,“bng3”
a11,a12 subinstr 3,p4,p5,2
outs a11,a12
endif
; perc NOTE 41
if p4 == 41 then
chnset “value(1)”,“bng4”
a11,a12 subinstr 3,p4,p5,5
outs a11,a12
endif
; kick 2 NOTE 40
if p4 == 40 then
chnset “value(1)”,“bng5”
a11,a12 subinstr 3,p4,p5,4
outs a11,a12
endif
endin
;=============================================================================
;receives Note pitch P4, Velocity P5, table Number P6,index corresponding to widget
;=============================================================================
instr 3
SChn_AttTim sprintf “AttTim%d”,P6
SChn_RelTim sprintf “RelTim%d”,P6
SChn_Pan sprintf “Pan%d”,P6
SChn_ChoiceFilt sprintf “FilterChoice%d”,P6
SChn_Reverb sprintf “ReverbOnOff%d”,P6
SChn_Room sprintf “RoomSize%d”,P6
SChn_Damp sprintf “Damping%d”,P6
SChn_Mix sprintf “Mix%d”,P6
SChn_CutOff sprintf “Filtercutoff%d”,P6
SChn_Reson sprintf “FilterRes%d”,P6
SChn_Pitch sprintf “Pitch%d”,P6
SChn_Level sprintf “level%d”,P6
kVolume chnget “volume”
iAttTim chnget SChn_AttTim ; read in widgets
iRelTim chnget SChn_RelTim
kPan chnget SChn_Pan
kChoiceFilt chnget SChn_ChoiceFilt
kReverb chnget SChn_Reverb
kRoom chnget SChn_Room
kDamp chnget SChn_Damp
kMix chnget SChn_Mix
kCutOff chnget SChn_CutOff
kReson chnget SChn_Reson
kPitch chnget SChn_Pitch
kLevel chnget SChn_Level
iamp = p5 ; gain of signal = velocity of midi note
;---------------------------------------
; Mono signal
;----------------------------------------
if giNumChannel[P6]==1 then
if iAttTim>0 then ; is amplitude envelope attack time is greater than zero…
kenv linsegr 0,iAttTim,1,iRelTim,0 ; create an amplitude envelope with an attack, a sustain and a release segment (senses realtime release)
else
kenv linsegr 1,iRelTim,0 ; create an amplitude envelope with a sustain and a release segment (senses realtime release)
endif
kenv expcurve kenv,8 ; remap amplitude value with a more natural curve
aenv interp kenv ; interpolate and create a-rate envelope
kporttime linseg 0,0.001,0.05 ; portamento time function. (Rises quickly from zero to a held value.)
klevelF portk kLevel ,kporttime
iNumSamples = ftlen(giIndxTabGen[P6])
aPhasor phasor kPitch*sr/iNumSamples ;modulate phasor speed for reading the sample
a1 tab aPhasor, giIndxTabGen[P6], 1
a1 = a1 * klevelF*aenv*iamp
if kChoiceFilt ==1 then ; no filter
a11 = a1
endif
if kChoiceFilt ==2 then ; low pass filter
a11 rezzy a1, kCutOff ,kReson, 0
endif
if kChoiceFilt ==3 then ; high pass filter
a11 rezzy a1, kCutOff ,kReson, 1
endif
if kReverb==1 then ; reverb on
aRvbL,aRvbR MyReverb a11,a11,kRoom,kDamp,kMix,kPan
outs aRvbL,aRvbR
else ; reverb off
a11, a12 pan2 a11, kPan
outs a11,a12
endif
endif
;---------------------------------------
; Stereo signal
;
; Not done yet !
; need to use loscil 3 instead of
;----------------------------------------
if giNumChannel[P6]==2 then
if iAttTim>0 then ; is amplitude envelope attack time is greater than zero…
kenv linsegr 0,iAttTim,1,iRelTim,0 ; create an amplitude envelope with an attack, a sustain and a release segment (senses realtime release)
else
kenv linsegr 1,iRelTim,0 ; create an amplitude envelope with a sustain and a release segment (senses realtime release)
endif
kenv expcurve kenv,8 ; remap amplitude value with a more natural curve
aenv interp kenv ; interpolate and create a-rate envelope
kporttime linseg 0,0.001,0.05 ; portamento time function. (Rises quickly from zero to a held value.)
klevelF portk kLevel ,kporttime
iNumSamples = ftlen(giIndxTabGen[P6])
aPhasor phasor kPitch*sr/iNumSamples ;modulate phasor speed for reading the sample
aL tab aPhasor, giIndxTabGen[P6], 1
aR tab aPhasor, giIndxTabGenR[P6], 1
aL = aL * klevelF*aenv*iamp
aR = aR * klevelF*aenv*iamp
if kChoiceFilt ==1 then
a1L = aL
a1R = aR
endif
if kChoiceFilt ==2 then
a1L rezzy aL, kCutOff ,kReson, 0
a1R rezzy aR, kCutOff ,kReson, 0
endif
if kChoiceFilt ==3 then
a1L rezzy aL, kCutOff ,kReson, 1
a1R rezzy aR, kCutOff ,kReson, 1
endif
if kReverb==1 then
aRvbL,aRvbR MyReverb a1L,a1R,kRoom,kDamp,kMix,kPan
outs aRvbL,aRvbR
else
a1L =sqrt(1-kPan)* a1L
a1R =sqrt(kPan)* a1R
outs a1LkVolume,a1RkVolume
endif
endif
endin
i100 0 z
;i 800 0 z
i4 0 10000