; LoscilFilePlayer.csd
; Written by Iain McCurdy, 2014
;
; Load a user selected sound file into a GEN 01 function table and plays it back using loscil3.
; This file player is best suited for polyphonic playback and is less well suited for the playback of very long sound files .
;
; The sound file can be played back using the Play/Stop button (and the 'Transpose' / 'Speed' buttons to implement pitch/speed change)
; or it can be played back using the MIDI keyboard.
;
; The loop points can be set either by using the loop 'Start' and 'End' sliders or by clicking and dragging on the waveform view -
; - loscil will take the values from the last control input moved.
form caption("Loscil File Player") size(700,400), colour(0,0,0) pluginID("Losc")
groupbox bounds(0, 0, 698, 110), plant("Instrument1"), text("K I C K"), fontcolour(243, 73, 73, 255), colour("lightgrey"),
rslider bounds(5, 22, 50, 50), channel("MidiRef1"), range(-6, 6, 1, 1), text("Pitch"), colour(195, 71, 176, 255), trackercolour(173, 19, 150, 255), textcolour(173, 19, 150, 255)
rslider bounds(50, 22, 49, 49), channel("level1"), range( 0, 1.00, 0.5, 0.5,0.01), text("Level"), colour(195, 71, 176, 255), trackercolour(173, 19, 150, 255), textcolour(173, 19, 150, 255)
label bounds(100, 94, 95, 9), text("E N V E L O P E"), fontcolour(22, 114, 209, 255),
rslider bounds(100, 22, 50, 50), channel("AttTim1"), range(0, 5, , 0.5, 0.001), text("Att.Tim"), colour(53, 59, 176, 255), trackercolour(22, 114, 209, 255), textcolour(22, 114, 209, 255),
rslider bounds(145, 22, 50, 50), channel("RelTim1"), range(0.01, 5, 0.05, 0.5, 0.001), colour(53, 59, 176, 255), trackercolour(22, 114, 209, 255), text("Rel.Tim"), textcolour(22, 114, 209, 255)
label bounds(200, 94, 95, 9), text("F I L T E R"), fontcolour(76, 26, 166, 255),
rslider bounds(200, 22, 50, 50), channel("Filtercutoff1"), range( 20, 20000, 1, 0.5), text("CutOff"), colour(102, 36, 221, 255), trackercolour(76, 26, 166, 255), textcolour(76, 26, 166, 255)
rslider bounds(245, 22, 50, 50), channel("FilterRes1"), range(1, 100, 1, 0.5, 0.001), text("Res."), colour(102, 36, 221, 255), trackercolour(76, 26, 166, 255), textcolour(76, 26, 166, 255)
combobox bounds(215, 72, 60, 19), channel("FilterChoice1"), items("None", "LowP", "HiP"), value(1), fontcolour("white") ,colour(76, 26, 166, 255),
label bounds(300, 94, 150, 9), text("R E V E R B"), fontcolour(5, 108, 62, 255),
rslider bounds(300, 22, 50, 50), channel("RoomSize1"), range(0, 1, 0.85, 0.5, 0.001), text("Room"), colour(6, 135, 84, 255), trackercolour(4, 111, 62, 255), textcolour(5, 108, 62, 255),
rslider bounds(345, 22, 50, 50), channel("Damping1"), range(0, 1, 0.5, 0.5, 0.001), text("Damp"), colour(6, 135, 84, 255), trackercolour(4, 111, 62, 255), textcolour(5, 108, 62, 255),
rslider bounds(390, 22, 50, 50), channel("Mix1"), range(0, 1, 0.5, 0.5, 0.001), text("Mix"), colour(6, 135, 84, 255), trackercolour(4, 111, 62, 255), textcolour(5, 108, 62, 255),
checkbox bounds(345, 73, 60, 15), channel("ReverbOnOff1"), items("On/Off"), colour(4, 111, 62, 255), fontcolour(5, 108, 62, 255),
soundfiler bounds(460, 24, 216, 79), identchannel("filer1"), colour(0, 255, 255, 255), fontcolour(160, 160, 160, 255), zoom(-1)
filebutton bounds(4, 84, 70, 22), text("Open File","Open File"),colour(53, 59, 176, 255), fontcolour("white") channel("filename1"), shape("ellipse")
label bounds(410, 5, 150, 10), text("Filename"), fontcolour(5, 108, 62, 255),identchannel("FilenameLabel1")
checkbox bounds(670, 5, 8, 8), value(0), colour:0("black"),colour:1("white"), shape("circle"), identchannel("bng1"), corners(2)
}
;===============================================================================================================
combobox bounds(350, 250, 100, 25), channel("combo_Preset"), populate("*.snaps")
filebutton bounds(150, 250, 60, 25), channel("but_Preset"), text("Save"), populate("*.snaps")
keyboard bounds(0, 308, 700, 43)
-n -+rtmidi=NULL -M0 -dm0
sr = 44100
kr = 4410
;ksmps = 64
nchnls = 2
0dbfs = 1
; massign 0,3
massign 1,11
gichans1 init 0
giReady1 init 0
gSfilepath1 init ""
gkTabLen1 init 2
giFilterType1 init 0
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
LOOP: ; Loop back to here when checking for a backslash
iasc strchar Ssrc, icnt ; Read ascii value of current letter for checking
if iasc==92 igoto ESCAPE ; If it is a backslash, escape from loop
loop_gt icnt,1,0,LOOP ; Loop back and decrement counter which is also used as an index into the 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
; INSTRUMENT FOR DEALING WITH FILENAMES AND REQUEST LOADING WAV INTO TABLE
instr 1
gklevel1 chnget "level1" ;Deal with filename of Instrument 1
gSfilepath1 chnget "filename1"
kNewFileTrg1 changed gSfilepath1 ; if a new file is loaded generate a trigger
if kNewFileTrg1==1 then ; if a new file has been loaded...
event "i",101,0,0 ; call instrument to update sample storage function table
endif
endin
;INSTRUMENTS LOADING THE WAV FILE INTO A GEN01 TABLE
instr 101 ; load sound file
gitable1 ftgen 1,0,0,1,gSfilepath1,0,0,0 ; load sound file into a GEN 01 function table
gichans1 filenchnls gSfilepath1 ; derive the number of channels (mono=1,stereo=2) in the sound file
giReady1 = 1 ; if no string has yet been loaded giReady will be zero
gkTabLen1 init ftlen(gitable1)/gichans1 ; table length in sample frames
Smessage1 sprintfk "file(%s)", gSfilepath1 ; print sound file to viewer
chnset Smessage1, "filer1"
Smessage2 FileNameFromPath gSfilepath1
Smessage3 sprintfk "text(%s)",Smessage2
chnset Smessage3 ,"FilenameLabel1"
endin
; MIDI TRIGGERED INSTRUMENTS
instr 11
gisr1 filesr gSfilepath1
printks "Sample rate of file %d %n",0,gisr1
iJMmidiLoc notnum
iampLoc veloc
; BASS DRUM NOTE 36
if iJMmidiLoc =36 then
chnset "value(1)","bng1"
a11,a12 subinstr 201,iJMmidiLoc,iampLoc
out a11,a12
endif
if iJMmidiLoc =48 then
chnset "value(1)","bng1"
a11,a12 subinstr 201,iJMmidiLoc,iampLoc
out a11,a12
endif
if iJMmidiLoc =60 then
chnset "value(1)","bng1"
a11,a12 subinstr 201,iJMmidiLoc,iampLoc
out a11,a12
endif
if iJMmidiLoc =72 then
chnset "value(1)","bng1"
a11,a12 subinstr 201,iJMmidiLoc,iampLoc
out a11,a12
endif
endin
instr 201 ; sample triggered by midi note
; icps cpsmidi ; read in midi note data as cycles per second
iJMmidi = p4
iamp = p5
; print p4
; print p5
iamp = iamp / 127.0 ; read in midi velocity (as a value within the range 0 - 1)
kCutOff1 chnget "Filtercutoff1"
kReson1 chnget "FilterRes1"
iMidiRef chnget "MidiRef1"
; recupere la note midi jouee
kChoiceFilt chnget "FilterChoice1"
kReverb1 chnget "ReverbOnOff1"
kRoom1 chnget "RoomSize1"
kDamp1 chnget "Damping1"
kMix1 chnget "Mix1"
kMyChannel = gichans1
iAttTim chnget "AttTim1" ; read in widgets
iRelTim chnget "RelTim1"
iNewNote = iJMmidi+iMidiRef
; iJMmidiFreq = (440.0 / 32.0) * (2 ^ (( iNewNote - 9) / 12));
if giReady1 = 1 then ; i.e. if a file has been loaded
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.)
ispeed =2^( iMidiRef/12) ; decalage de frequence pour changer le pitch
klevel portk gklevel1,kporttime ; apply portamento smoothing to changes in level
kjmamp = klevel*aenv*iamp
if gichans1==1 then ; if mono...
if kChoiceFilt =1 then
a11 loscil3 kjmamp,1,gitable1,1,0 ; use a mono loscil3 -> Plays too slowly WHY ????
;a11 loscil3 klevel*aenv*iamp,ispeed,gitable1,1,0 ; use a mono loscil3 -> Plays too slowly
endif
if kChoiceFilt =2 then
a1 loscil3 klevel*aenv*iamp,ispeed,gitable1,1,0 ; use a mono loscil3
a11 rezzy a1, kCutOff1 ,kReson1, 0
endif
if kChoiceFilt =3 then
a1 loscil3 klevel*aenv*iamp,ispeed,gitable1,1,0 ; use a mono loscil3
a11 rezzy a1, kCutOff1 ,kReson1, 1
endif
if kReverb1=1 then
;write audio into the named software channel: l instrument REverb 800 est toujours en fonctionnement
chnset kRoom1,"Reverb_Room"
chnset kDamp1 ,"Reverb_Damp"
chnset kMix1 ,"Reverb_Mix"
chnset kMyChannel, "Reverb_Chan"
chnmix a11, "ReverbSend"
else
outs a11,a11
endif
elseif gichans1==2 then ; otherwise, if stereo...
if kChoiceFilt =1 then
a11,a12 loscil3 klevel*aenv*iamp,ispeed,gitable1,1,0 ; use a mono loscil3
endif
if kChoiceFilt =2 then
a1,a2 loscil3 klevel*aenv*iamp,ispeed,gitable1,1,0 ; use a mono loscil3
a11 rezzy a1, kCutOff1 ,kReson1, 0
a12 rezzy a2, kCutOff1 ,kReson1, 0
endif
if kChoiceFilt =3 then
a1,a2 loscil3 klevel*aenv*iamp,ispeed,gitable1,1,0 ; use a mono loscil3
a11 rezzy a1, kCutOff1 ,kReson1, 1
a12 rezzy a2, kCutOff1 ,kReson1, 1
endif
if kReverb1=1 then
;write audio into the named software channel: l instrument REverb 800 est toujours en fonctionnement
chnset kRoom1,"Reverb_Room"
chnset kDamp1 ,"Reverb_Damp"
chnset kMix1 ,"Reverb_Mix"
chnset kMyChannel, "Reverb_Chan"
chnmix a11, "ReverbSendL"
chnmix a12, "ReverbSendR"
else
outs a11,a12
endif
endif
else printks "No soundfile loaded%n",1
endif
; chnset "value(0)","bng1"
endin
instr 800 ; reverb (always on)
;kTime init 4 ; reverb time
;kHDif init 0.5 ; 'high frequency diffusion' (0 - 1)
;aRvb nreverb aInSig, kTime, kHDif ; create reverb signal
kRoom chnget "Reverb_Room"
kDamp chnget "Reverb_Damp"
kMix chnget "Reverb_Mix"
kMyChannel chnget "Reverb_Chan"
if kMyChannel =1 then
aInSig chnget "ReverbSend" ; read audio from the named channel
aRvbL,aRvbR freeverb aInSig* kMix,aInSig* kMix, kRoom, kDamp
aRvbL= aRvbL+ aInSig
aRvbR= aRvbR+ aInSig
outs aRvbL, aRvbR ; send audio to outputs
chnclear "ReverbSend" ; clear the named channel
else
aInSigL chnget "ReverbSendL" ; read audio from the named channel
aInSigR chnget "ReverbSendR" ; read audio from the named channel
aRvbL,aRvbR freeverb aInSigL* kMix,aInSigR* kMix, kRoom, kDamp
aRvbL= aRvbL+ aInSigL
aRvbR= aRvbR+ aInSigR
outs aRvbL, aRvbR ; send audio to outputs
chnclear "ReverbSendL" ; clear the named channel
chnclear "ReverbSendR"
endif
endin
i 1 0 [60*60*24*7]
i 800 0 3600
;i 3 0 [60*60*24*7]