Extra "ports" of juce-based plugins using the distrho build system
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

339 lines
17KB

  1. RubbedResonators.csd
  2. This example introduces a method of 'exciting' mode filters that creates an imitation of a resonant object being bowed or rubbed. The excitation signal consists of a stack of sine wave oscillators that match the number and frequencies of the mode filters being used. This arrangement can cause the mode filters to resonate with great intensity so the amplitudes of the sine wave oscillators should be kept low to prevent overloading. Additionally the frequency of each sine wave oscillator is individually modulated using a random 'jitter' function created using 'gaussi' (interpolating gaussian noise generator). This technique results is a shifting spectral response from the filters. Adjusting the rate and amplitude of this jitter function can imitate a variety of bowing and rubbing techniques. Increasing 'Jit.Dep.' while 'Jit.Rate' is kept low gives the impression of the resonator being rubbed with greater pressure. If both 'Jit.Dep.' and 'Jit.Rate' are high the impression is of the resonator begin brushed.
  3. If 'Q' is low then more of the character of the impulse sound (the sine wave oscillators) will be apparent (and therefore the jitter modulation will be more apparent). If 'Q' is higher then the character of the mode filters will dominate and modulation of the impulse sound frequencies will be less apparent. A key aspect of this instrument is that once the impulse sound is removed ('Impulse Amp.' is brought to minimum) the sound produced is solely the residual resonance of the mode filters, therefore any modulation within the sine wave oscillators becomes irrelevant.
  4. For brightness (damping) control to work properly modal ratios in their function table will need to be in ascending order.
  5. Chorus effect is disabled when 'Mix' is zero
  6. Number of partials in the chosen algorithm is printed to the GUI for the user's information. Algorithms with high numbers of partials will demand more CPU and lower polyphony will be possible.
  7. <Cabbage>
  8. form caption("Rubbed Resonators"), size(440, 320), pluginID("RubR")
  9. image pos(0, 0), size(440, 290), colour("Sienna"), shape("rounded"), outline("brown"), line(4)
  10. ;IMPULSE
  11. groupbox bounds(10, 10, 260, 90), text("Impulse"), fontcolour("white"){
  12. rslider bounds( 10, 35,60,60), text("Amp."), colour("Chocolate"), channel("ImpDB"), range(-70, 0, 0)
  13. rslider bounds( 60, 35,60,60), text("HPF"), colour("Chocolate"), channel("HPF"), range(20, 20000, 20, 0.5)
  14. rslider bounds(110, 35,60,60), text("LPF"), colour("Chocolate"), channel("LPF"), range(20, 20000, 20000, 0.5)
  15. rslider bounds(160, 35,60,60), text("Jit. Dep."), channel("JitDep"), colour("Chocolate"), range(0, 5, 0.4,0.5)
  16. rslider bounds(210, 35,60,60), text("Jit. Rate"), channel("JitRte"), colour("Chocolate"), range(0.01,100, 3,0.5)
  17. }
  18. ;RESONATORS
  19. groupbox bounds(270, 10,160,180), text("Resonators"), fontcolour("white"){
  20. label bounds(320, 40,120, 12), text("Instrument"), colour("white")
  21. combobox bounds(280, 55,140, 25), channel("sound"), value(4), text("Single", "Dahina", "Banyan", "Xylophone", "Tibetan Bowl 180mm", "Spinel Sphere", "Pot Lid", "Red Cedar Wood Plate", "Tubular Bell", "Redwood Wood Plate", "Douglas Fir Wood Plate", "Uniform Wooden Bar", "Uniform Aluminium Bar", "Vibraphone 1", "Vibraphone 2", "Chalandi Plates", "Tibetan Bowl 152mm", "Tibetan Bowl 140mm", "Wine Glass", "Small Handbell", "Albert Clock Bell", "Wood Block","Harmonic 10","Harmonic 20","Harmonic 30","Harmonic Odd 10","Harmonic Odd 20")
  22. rslider bounds(315, 85, 70, 30), text("N.Partials"), TextBox(1), channel("npartials"), range(1, 10000, 1, 1, 1)
  23. rslider bounds(270,125, 60, 60), text("Q"), colour("orange"), channel("Q"), range(50, 10000, 2000, 0.5)
  24. rslider bounds(320,125, 60, 60), text("Bright"), colour("orange"), channel("bright"), range(-4, 4, 0)
  25. rslider bounds(370,125, 60, 60), text("Gain"), colour("orange"), channel("gain"), range(0, 8, 1)
  26. }
  27. ;POLYPHONY
  28. groupbox bounds( 10,100,100, 90), text("Polyphony"), fontcolour("white"){
  29. button bounds( 20,125, 80, 20), text("poly","mono"), channel("monopoly"), value(0), fontcolour("lime")
  30. hslider bounds( 15,143, 90, 38), colour("chocolate"), channel("GlissTime"), range(0.005, 0.3, 0.1, 0.25, 0.001)
  31. label bounds( 32,174, 90, 12), text("Gliss Time")
  32. }
  33. ;CHORUS
  34. groupbox bounds(110,100,160, 90), text("Chorus"), fontcolour("white"){
  35. rslider bounds(110,125, 60, 60), text("Mix"), channel("ChoMix"), range(0, 1, 0.5), colour("yellow")
  36. rslider bounds(160,125, 60, 60), text("Depth"), channel("ChoDep"), range(0, 0.1, 0.01,0.5, 0.001), colour("yellow")
  37. rslider bounds(210,125, 60, 60), text("Rate"), channel("ChoRte"), range(0, 20, 0.96, 0.5), colour("yellow")
  38. }
  39. keyboard bounds(10, 195, 420, 85)
  40. image bounds(5, 295, 240, 22), colour(75, 85, 90, 100), plant("credit"){
  41. label bounds(0.03, 0.15, .9, .7), text("Author: Iain McCurdy |2012|"), colour("white")
  42. }
  43. </Cabbage>
  44. <CsoundSynthesizer>
  45. <CsOptions>
  46. -dm0 -n -+rtmidi=null -M0
  47. </CsOptions>
  48. <CsInstruments>
  49. sr = 44100
  50. ksmps = 64
  51. nchnls = 2
  52. 0dbfs = 1 ;MAXIMUM AMPLITUDE
  53. massign 0,2 ;MIDI DATA DIRECTED TO INSTRUMENT 2
  54. ;Author: Iain McCurdy (2012)
  55. ;FUNCTION TABLES STORING MODAL FREQUENCY RATIOS------------------------------------------------------------------------------------------------------------------------------------------------
  56. ;single
  57. girtos1 ftgen 0,0,2, -2, 1,1
  58. ;dahina
  59. girtos2 ftgen 0,0,-6,-2, 1, 2.89, 4.95, 6.99, 8.01, 9.02
  60. ;banyan
  61. girtos3 ftgen 0,0,-6,-2, 1, 2.0, 3.01, 4.01, 4.69, 5.63
  62. ;xylophone
  63. girtos4 ftgen 0,0,-6,-2, 1, 3.932, 9.538, 16.688, 24.566, 31.147
  64. ;tibetan bowl (180mm)
  65. girtos5 ftgen 0,0,-7,-2, 1, 2.77828, 5.18099, 8.16289, 11.66063, 15.63801, 19.99
  66. ;spinel sphere with diameter of 3.6675mm
  67. girtos6 ftgen 0,0,-24,-2, 1, 1.026513174725, 1.4224916858532, 1.4478690202098, 1.4661959580455, 1.499452545408, 1.7891839345101, 1.8768994627782, 1.9645945254541, 1.9786543873113, 2.0334612432847, 2.1452852391916, 2.1561524686621, 2.2533435661294, 2.2905090816065, 2.3331798413917, 2.4567715528268, 2.4925556408289, 2.5661806088514, 2.6055768738808, 2.6692760296751, 2.7140956766436, 2.7543617293425, 2.7710411870043
  68. ;pot lid
  69. girtos7 ftgen 0,0,-6,-2, 1, 3.2, 6.23, 6.27, 9.92, 14.15
  70. ;red cedar wood plate
  71. girtos8 ftgen 0,0,-4,-2, 1, 1.47, 2.09, 2.56
  72. ;tubular bell
  73. girtos9 ftgen 0,0,-10,-2, 272/437, 538/437, 874/437, 1281/437, 1755/437, 2264/437, 2813/437, 3389/437, 4822/437, 5255/437
  74. ;redwood wood plate
  75. girtos10 ftgen 0,0,-4,-2, 1, 1.47, 2.11, 2.57
  76. ;douglas fir wood plate
  77. girtos11 ftgen 0,0,-4,-2, 1, 1.42, 2.11, 2.47
  78. ;uniform wooden bar
  79. girtos12 ftgen 0,0,-6,-2, 1, 2.572, 4.644, 6.984, 9.723, 12
  80. ;uniform aluminum bar
  81. girtos13 ftgen 0,0,-6,-2, 1, 2.756, 5.423, 8.988, 13.448, 18.680
  82. ;vibraphone 1
  83. girtos14 ftgen 0,0,-6,-2, 1, 3.984, 10.668, 17.979, 23.679, 33.642
  84. ;vibraphone 2
  85. girtos15 ftgen 0,0,-6,-2, 1, 3.997, 9.469, 15.566, 20.863, 29.440
  86. ;Chalandi plates
  87. girtos16 ftgen 0,0,-5,-2, 1, 1.72581, 5.80645, 7.41935, 13.91935
  88. ;tibetan bowl (152 mm)
  89. girtos17 ftgen 0,0,-7,-2, 1, 2.66242, 4.83757, 7.51592, 10.64012, 14.21019, 18.14027
  90. ;tibetan bowl (140 mm)
  91. girtos18 ftgen 0,0,-5,-2, 1, 2.76515, 5.12121, 7.80681, 10.78409
  92. ;wine glass
  93. girtos19 ftgen 0,0,-5,-2, 1, 2.32, 4.25, 6.63, 9.38
  94. ;small handbell
  95. girtos20 ftgen 0,0,-22,-2, 1, 1.0019054878049, 1.7936737804878, 1.8009908536585, 2.5201981707317, 2.5224085365854, 2.9907012195122, 2.9940548780488, 3.7855182926829, 3.8061737804878, 4.5689024390244, 4.5754573170732, 5.0296493902439, 5.0455030487805, 6.0759908536585, 5.9094512195122, 6.4124237804878, 6.4430640243902, 7.0826219512195, 7.0923780487805, 7.3188262195122, 7.5551829268293
  96. ;albert clock bell belfast
  97. ;girtos21 ftgen 0,0,-22,-2, 2.043260,1.482916,1.000000,3.328848,4.761811,1.477056,0.612007,2.661295,1.002793,4.023776,0.254139,2.043916,4.032463,2.659438,4.775560,5.500494,3.331014,0.809697,2.391301, 0.254098,1.901476,2.366563 ;,0.614968,2.046543,1.814887,3.130744,2.484426,0.558874,0.801697,0.070870,3.617036,2.782656
  98. girtos21 ftgen 0,0,-22,-2, 0.254098,0.254139,0.612007,0.809697,1.000000,1.002793,1.477056,1.482916,1.901476,2.043260,2.043916,3.331014,2.366563,2.391301,2.659438,2.661295,3.328848,4.023776,4.032463,4.761811,4.775560,5.500494
  99. ;wood block
  100. girtos22 ftgen 0,0,4,-2, 915/915,1540/915,1863/915,3112/915
  101. ;harmonic 10
  102. girtos23 ftgen 0,0,-10,-2, 1,2,3,4,5,6,7,8,9,10
  103. ;harmonic 20
  104. girtos24 ftgen 0,0,-20,-2, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
  105. ;harmonic 30
  106. girtos25 ftgen 0,0,-30,-2, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
  107. ;harmonic odd 10
  108. girtos26 ftgen 0,0,-10,-2, 1,3,5,7,9,11,13,15,17,19
  109. ;harmonic odd 20
  110. girtos27 ftgen 0,0,-20,-2, 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39
  111. seed 0 ;random number generators seeded from the system clock
  112. gasend init 0 ;initialise the global audio send variable
  113. gisine ftgen 0,0,4096,10,1 ;a sine wave
  114. ;table that stores indicators for each active note. 1=active 0=inactive index_location=note_number
  115. giNoteActive ftgen 0,0,128,2,0
  116. ;--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  117. gkbright init 0
  118. gasend init 0
  119. ;--UDOS--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  120. opcode SineVoice,a,kkkiiii
  121. kfreq,kjitdep,kjitrte,icount,invoices,irtos,isfn xin
  122. amix = 0 ;initialise audio mix variable (mixture of all sine wave oscillators)
  123. kjit gaussi kjitdep, 1, kjitrte ;jitter function (semitone deviation)
  124. irto table icount-1,irtos ;read the frequency ratio for this oscillator from the appropriate ratios table
  125. a1 oscili 1,semitone(kjit)*kfreq*irto,isfn ;create the oscillator
  126. if icount<invoices then ;if not all required oscillators have been created yet...
  127. amix SineVoice kfreq,kjitdep,kjitrte,icount+1,invoices,irtos,isfn ;call the udo again, with the incremented counter
  128. endif
  129. xout amix + a1 ;send mix of all oscillators back the the udo output
  130. endop
  131. opcode ModeVoice,a,akkkiii ;mode udo (k-rate base frequency) - used for non-midi mode
  132. ain,kfreq,kq,kdamp,icount,inmodes,irtos xin ;name input variables
  133. amix = 0 ;initialise audio mix variable (mixture of all mode filters)
  134. asig = 0 ;initialise audio for the mode filter in this iteration of the UDO. Only needed if only 1 mode is present.
  135. irto table icount-1,irtos ;read frequency ratio for current mode according to iteration counter
  136. kThisFreq = kfreq * irto ;derive modal frequency from product of ratio and base frequency
  137. if sr/kThisFreq>=$M_PI then
  138. asig mode ain, kThisFreq, kq ;create mode signal
  139. if kdamp>0 then
  140. kamp = ((inmodes-icount+1)^(-kdamp))*(kdamp+1)
  141. else
  142. kamp = icount^kdamp
  143. endif
  144. aamp interp kamp
  145. asig = asig*aamp
  146. if icount < inmodes then ;if all the modes in this current instrument have not yet been created...
  147. amix ModeVoice ain, kfreq,kq,kdamp,icount+1, inmodes,irtos ;...call modemodule udo again with incremented counter
  148. endif ;end of conditional branching
  149. endif
  150. xout amix+asig ;send all audio back to caller instrument
  151. endop ;end of udo
  152. ;--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  153. instr 1 ;read in widgets (always on)
  154. gkQ chnget "Q" ;read in widgets
  155. kImpDB chnget "ImpDB"
  156. gkHPF chnget "HPF"
  157. gkLPF chnget "LPF"
  158. gkJitDep chnget "JitDep"
  159. gkJitRte chnget "JitRte"
  160. gkbright chnget "bright"
  161. gkgain chnget "gain"
  162. gkmonopoly chnget "monopoly"
  163. gkGlissTime chnget "GlissTime"
  164. gksound chnget "sound"
  165. gkChoMix chnget "ChoMix"
  166. gkChoRte chnget "ChoRte"
  167. gkChoDep chnget "ChoDep"
  168. gkImpAmp = ampdbfs(kImpDB) ;convert from dB value to amp value
  169. gkbright port gkbright,0.02 ;smooth changes using portamento
  170. gkgain port gkgain,0.02 ;
  171. ktrig changed gksound ;if sound combobox changes...
  172. if ktrig==1 then
  173. event "i",5,0,0.001 ;...call instrument 5 to update 'N.Partials' number box
  174. endif
  175. endin
  176. instr 2 ;MIDI TRIGGERED INSTRUMENT
  177. gkNoteTrig init 1 ;at the beginning of a new note set note trigger flag to '1'
  178. ibase cpsmidi ;read in midi note number as a cps value
  179. gkbase = ibase
  180. ivel ampmidi 1 ;read in midi note velocity as a value within the range 0 to 1
  181. gkvel init ivel
  182. inum notnum ;read in midi note number as an integer (used for create a table of active notes flags)
  183. krelease release ;note release flag (0 = note held, 1 = note released)
  184. tablew 1-krelease,inum,giNoteActive ;write note release flag to table at the location corresponding to note number
  185. iactive active p1+1
  186. if iactive==0||i(gkmonopoly)==0 then ;if polyphonic mode or if this is the first in a series of notes in monophonic mode...
  187. event_i "i",p1+1,0,3600,ibase,inum ;call instrument 3 with the appropriate p-fields
  188. endif
  189. endin
  190. instr 3 ;impulse and modal resonators instrument
  191. ktrig changed gksound
  192. if ktrig==1 then
  193. reinit RESTART_INSTRUMENT
  194. endif
  195. RESTART_INSTRUMENT:
  196. isound init i(gksound)
  197. if gkmonopoly==1 then
  198. /*monophonic*/
  199. kporttime linseg 0,0.001,1
  200. kbase portk gkbase,kporttime*gkGlissTime
  201. kactive active p1-1
  202. kactive limit kactive,0,1
  203. else
  204. /*polyphponic*/
  205. kbase init p4 ;base frequency read from p4
  206. kactive table p5,giNoteActive ;check whether the midi key corresponding to this note is being held or has been released (1 = held, 0 = released). this value will be used to control whether the impulse scound should be active or not.
  207. endif
  208. inum = p5 ;note number
  209. icount = 1 ;counter to count iterations for recursive udos for sine oscillators and mode filters (starts at zero)
  210. irtos = girtos1 + isound - 1 ;derive actual function table number for ratios according to 'sound' chosen
  211. invoices = ftlen(irtos) ;derive the number of voices needed for the 'sound' chosen
  212. kactivePort port kactive,0.05 ;smooth note active on/off switching
  213. ktrig changed gkNoteTrig ;if a new note is started...
  214. if ktrig==1 then
  215. reinit RESTART_ENVELOPE ;...reinitialise from the given label
  216. endif
  217. RESTART_ENVELOPE: ;if a new note is trigger reinitialisation from here occurs to start a new impulse buid-up envelope based on new velocity value
  218. ivel init i(gkvel)
  219. kenv linseg 0,(1-ivel)+0.01,ivel ;create an amplitude envelope for the impulse sound. impulse sound will be velocity sensitive and the attack time of this envelope will be proportionate to the note velocity also.
  220. rireturn
  221. ktrig changed gksound ; to fix bug where sound would not update in mono mode
  222. if ktrig==1 then
  223. reinit RESTART_INSTRUMENT2
  224. endif
  225. RESTART_INSTRUMENT2:
  226. aSineMix SineVoice kbase,gkJitDep,gkJitRte,icount,invoices,irtos,gisine ;call sine oscillator udo (it will be recursively recalled within the udo the appropriate number of times according to invoices)
  227. aSineMix = aSineMix*0.002*kactivePort*kenv*gkImpAmp ;scale the mixture of sines audio signal
  228. aSineMix buthp aSineMix,gkHPF
  229. aSineMix butlp aSineMix,gkLPF
  230. amodes ModeVoice aSineMix,kbase,gkQ,gkbright,icount,invoices,irtos ;call sine oscillator udo (it will be recursively recalled within the udo the appropriate number of times according to invoices)
  231. amodes = (amodes*gkgain*0.2)/invoices ;scale the amplitude of the sound according to the number of modes in the chosen algorithm
  232. krms rms amodes ;track the amplitude of the sound as an rms value
  233. ithreshold = 0.0001
  234. if krms<ithreshold&&kactive=0 then ;if sound has died away and key is inactive...
  235. turnoff ;turn instrument off
  236. endif
  237. xtratim 0.1 ;this is needed to prevent initialisation crashes, I'm not sure why
  238. outs amodes,amodes ;send mode filters output mixture to output and rescale according to the number of modes used
  239. gasend = gasend+amodes*gkChoMix
  240. gkNoteTrig = 0 ;reset new-note trigger (in case it was '1')
  241. endin
  242. instr 4 ;Chorus effect
  243. if gkChoMix==0 goto SKIP_CHORUS
  244. kporttime linseg 0,0.001,1
  245. kporttime = kporttime/gkChoRte
  246. kdlt1 randomi ksmps/sr,gkChoDep,gkChoRte,1
  247. kdlt1 portk kdlt1,kporttime
  248. adlt1 interp kdlt1
  249. acho1 vdelay gasend,adlt1*1000,1*1000
  250. kdlt2 randomi ksmps/sr,gkChoDep,gkChoRte,1
  251. kdlt2 portk kdlt2,kporttime
  252. adlt2 interp kdlt2
  253. acho2 vdelay gasend,adlt2*1000,1*1000
  254. kpan1 randomi 0,1,gkChoRte,1
  255. kpan2 randomi 0,1,gkChoRte,1
  256. a1L,a1R pan2 acho1,kpan1
  257. a2L,a2R pan2 acho2,kpan2
  258. achoL = a1L+a2L
  259. achoR = a1R+a2R
  260. outs achoL, achoR
  261. clear gasend
  262. SKIP_CHORUS:
  263. endin
  264. instr 5 ;update 'Number of Partials' number box
  265. invoices = ftlen(girtos1+i(gksound)-1) ;derive the number of voices needed for the 'sound' chosen
  266. knvoices init invoices ;create krate version of invoices
  267. chnset knvoices,"npartials" ;send value to number box
  268. endin
  269. </CsInstruments>
  270. <CsScore>
  271. i 1 0 [60*60*24*7]
  272. i 4 0 [60*60*24*7]
  273. </CsScore>
  274. </CsoundSynthesizer>