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.

189 lines
9.8KB

  1. StringFeedback.csd - an emulation of a feeding back vibrating string
  2. ------------------
  3. Amplifier
  4. ---------
  5. Feedback - signal that is fed back into the vibrating string model. If a particular note doesn't sound, boost this!
  6. Drive - overdrive level
  7. Sustain - sustain of the string vibrations. Inverse of damping.
  8. Bright - brightness of the signal (lowpass filtering). Uses keyboard tracking, value stated is a ratio of the fundemental of the note played.
  9. Cut - remove lower partials of the signal (highpass filtering). Uses keyboard tracking, value stated is a ratio of the fundemental of the note played.
  10. Movement
  11. ---------
  12. Movement is a rough imitation of the effect of moving the vibrating string with respect to the location of the speaker. This is simply a modulating very short delay.
  13. Speed - speed of modulation (created using a random spline)
  14. Pick-up
  15. -------
  16. Settings pertaining to the location of the pick-up along the length of the vibrating string
  17. Position - manual positioning of the pick-up. 0 or 1 = either end. 0.5 = half-way along the string's length.
  18. Auto - if this is active, manual positioning is ignored and the pick-up moves around randomly
  19. Speed - speed of random movement of the pick-up
  20. Reverb
  21. ------
  22. Distance - Distance of the listener from the speaker (basically a dry/wet signal crossfader)
  23. Room - Room size
  24. Output
  25. ------
  26. Release - ampllitude envelope release for the feedback signal
  27. Level - Level control (pre reverb so reverberation will always die away natuarally)
  28. <Cabbage>
  29. form caption("String Feedback"), size(775, 205), pluginID("fbck"), colour("0,0,0")
  30. groupbox bounds( 0, 0, 290, 90), text("Amplifier"), fontcolour(195,126, 0){
  31. rslider bounds( 5, 25, 60, 60), text("Feedback"), colour(195,126, 0), FontColour(195,126, 0), channel("fback"), range(0, 8, 0.8,0.5)
  32. rslider bounds( 60, 25, 60, 60), text("Drive"), colour(195,126, 0), FontColour(195,126, 0), channel("drive"), range(0, 1, 0.25)
  33. rslider bounds(115, 25, 60, 60), text("Sustain"), colour(195,126, 0), FontColour(195,126, 0), channel("sustain"), range(0.0001, 1, 1, 0.5, 0.0001)
  34. rslider bounds(170, 25, 60, 60), text("Bright"), colour(195,126, 0), FontColour(195,126, 0), channel("LPF"), range(1, 32, 16)
  35. rslider bounds(225, 25, 60, 60), text("Cut"), colour(195,126, 0), FontColour(195,126, 0), channel("HPF"), range(0, 32, 1)
  36. }
  37. groupbox bounds(290, 0, 70, 90), text("Movement"), fontcolour(195,126, 0){
  38. rslider bounds(295, 25, 60, 60), text("Speed"), colour(195,126, 0), FontColour(195,126, 0), channel("speed"), range(0.001,1, 0.1,0.5,0.0001)
  39. }
  40. groupbox bounds(360, 0,170, 90), text("Pick-up"), fontcolour(195,126, 0){
  41. rslider bounds(365, 25, 60, 60), text("Position"),colour(195,126, 0), FontColour(195,126, 0), channel("PickPos"), range(0, 1, 0.1)
  42. checkbox bounds(425, 25, 70, 15), text("Auto") channel("auto"), FontColour(195,126, 0), colour("orange")
  43. rslider bounds(465, 25, 60, 60), text("Speed"),colour(195,126, 0), FontColour(195,126, 0), channel("PickPosSpeed"), range(0.001, 8, 1, 0.5,0.001)
  44. }
  45. groupbox bounds(530, 0,120, 90), text("Reverb"), fontcolour(195,126, 0){
  46. rslider bounds(535, 25, 60, 60), text("Distance"),colour(195,126, 0), FontColour(195,126, 0), channel("distance"), range(0, 1, 0.1)
  47. rslider bounds(590, 25, 60, 60), text("Room"), colour(195,126, 0), FontColour(195,126, 0), channel("room"), range(0.5,0.99, 0.85)
  48. }
  49. groupbox bounds(650, 0,125, 90), text("Output"), fontcolour(195,126, 0){
  50. rslider bounds(655, 25, 60, 60), text("Release"), colour(195,126, 0), FontColour(195,126, 0), channel("rel"), range(0.01, 8, 0.01, 0.5)
  51. rslider bounds(710, 25, 60, 60), text("Level"), colour(195,126, 0), FontColour(195,126, 0), channel("level"), range(0, 1, 0.5)
  52. }
  53. keyboard bounds(0, 95,775,80)
  54. image bounds(5, 180, 420, 20), colour(75, 85, 90, 50), plant("credit"){
  55. label bounds(0.03, 0.1, .6, .7), text("Author: Iain McCurdy |2013|"), colour("white"), FontColour(195,126, 0)
  56. }
  57. </Cabbage>
  58. <CsoundSynthesizer>
  59. <CsOptions>
  60. -dm0 -n -+rtmidi=null -M0
  61. </CsOptions>
  62. <CsInstruments>
  63. sr = 44100
  64. ksmps = 4
  65. nchnls = 2
  66. 0dbfs = 1
  67. massign 0,1 ; assign all midi to channel 1
  68. seed 0 ; random number generators seeded from system clock
  69. gasendL,gasendR,garvbL,garvbR init 0 ; initialise global variables to zero
  70. giscal ftgen 0,0,1024,-16,1,1024,4,8 ; amplitude scaling used in 'overdrive' mechanism
  71. gifbscl ftgen 0,0,128,-27, 0,1, 36,1, 86,3, 127,3 ; Feedback scaling function table. Higher notes need higher levels of feedback.
  72. instr 1
  73. kporttime linseg 0,0.001,0.05 ; used to smooth GUI control movement
  74. iplk = 0.1 ; pluck position (largely irrelevant)
  75. iamp = 1 ; amplitude
  76. icps cpsmidi ; midi note played (in cycles-per-second)
  77. inum notnum ; midi note number
  78. ifbscl table inum, gifbscl ; Feedback scaling. Higher notes need higher levels of feedback. This scaling function is defined earlier in a function table.
  79. ksustain chnget "sustain" ; string sustain (inverse of damping). Higher values = more sustain
  80. krefl = 1-ksustain ; string damping (derived from sustain value). Higher values = more damping. Range 0 - 1
  81. adel init 0 ; feedback signal from the modulating delay (initial value for the first pass)
  82. ; pick-up position
  83. kauto chnget "auto" ; 'auto' checkbox button.
  84. if(kauto==0) then ; if 'auto' button is off pick-up position is set manually
  85. kpick chnget "PickPos" ; 'Position' GUI knob
  86. kpick portk kpick,kporttime ; smooth changes made to the value to prevent glitches
  87. else ; other 'Auto' pick-up position modulation mode is used
  88. kPickposSpeed chnget "PickPosSpeed" ; pick-up position modulation 'Speed' GUI knob
  89. kpick rspline 0.01,0.99,kPickposSpeed,kPickposSpeed*2 ; pick-up position created using a random spline method
  90. kpick limit kpick,0.01,0.99 ; contain possible values. (N.b. rspline will generate values beyond its given limits.)
  91. endif
  92. irel chnget "rel" ; feedback signal release time
  93. aInRel linsegr 1,irel,0 ; feedback signal release envelope
  94. adust dust 0.1,1 ; generate a sparse crackle signal. This is used to help keep the string vibrating.
  95. kfback chnget "fback" ; 'Feedback' value from GUI knob
  96. asig repluck iplk, iamp, icps, kpick, krefl,( (adel*kfback*ifbscl) + ( (garvbL+garvbR) * 0.1) + adust) * aInRel ; vibrating string model
  97. ; overdrive
  98. kDrive chnget "drive" ; overdrive value from GUI knob
  99. ktrig changed kDrive ; if 'Drive' knob is moved generate a trigger. Reinitialisation will be needed to refresh the 'clip' opcode.
  100. if(ktrig==1) then ; if 'Drive' knob has been moved...
  101. reinit UPDATE ; reinitialise from 'UPDATE' label
  102. endif
  103. UPDATE: ; a label. Reinitialise from here.
  104. iClipLev = 1-(i(kDrive)*0.9) ; clip level remapped from 0 to 1 remapped to 1 to 0.1.
  105. asig clip asig,0,iClipLev ; clip the audio signal
  106. igain table i(kDrive),giscal,1 ; get amplitude compensation value according to the current 'Drive' setting
  107. asig = asig*igain ; compensate for gain loss
  108. rireturn
  109. ; filtering
  110. kLPF chnget "LPF" ; Lowpass filter ('Bright') GUI knob. This is a ratio of the fundemental frequency so the final cutoff frequency will depend on the note played (keyboard tracking).
  111. kLPF portk kLPF,kporttime ; smooth changes
  112. kLPF limit icps*kLPF,20,sr/2 ; derive cycles-per-second filter cutoff value (and protect against out of range values which would cause the filter to 'blow up')
  113. asig butlp asig, kLPF ; lowpass filter the signal
  114. kHPF chnget "HPF" ; same as the above but with a highpass filter. (Highpass filter called 'Cut' in GUI.)
  115. kHPF portk kHPF,kporttime
  116. kHPF limit icps*kHPF,1,sr/2
  117. asig buthp asig, kHPF
  118. ; amplitude enveloping
  119. aAmpEnv expsegr 0.001,.1,1,15,0.001 ; amplitude envelope
  120. asig = asig*aAmpEnv ; apply amplitude envelope
  121. ; delay (this controls how different harmonics are accentuated in the feedback process)
  122. kspeed chnget "speed" ; delay time modulation speed
  123. iDelMin = 0.0001 ; delay minimum...
  124. iDelMax = 0.01 ; ...and maximum. These could maybe be brought out as GUI controls
  125. kdeltim rspline iDelMin,iDelMax,kspeed,kspeed*2 ; random spline for delay time (k-rate)
  126. kdeltim limit kdeltim,iDelMin,iDelMax ; limit value (n.b. rspline will generate values beyond its given minimum and maximum)
  127. adeltim interp kdeltim ; interpolate to create a-rate verion for delay time (a-rate will give smoother results)
  128. adel vdelay3 asig, adeltim*1000, 1000 ; create modulating delay signal
  129. ; stereo spatialisation - this gives the dry (unreverberated) signal some stereo width
  130. kdelL rspline 0.001, 0.01, 0.05, 0.1 ; left channel spatialising delay
  131. kdelR rspline 0.001, 0.01, 0.05, 0.1 ; right channel spatialising delay
  132. kdelL limit kdelL,0.001, 0.01 ; limit left channel delay times (n.b. rspline will generate values beyond its given minimum and maximum)
  133. kdelR limit kdelR,0.001, 0.01 ; limit right channel delay times (n.b. rspline will generate values beyond its given minimum and maximum)
  134. adelL interp kdelL ; create a-rate of left channel delay time version using interpolation
  135. adelR interp kdelR ; create a-rate of right channel delay time version using interpolation
  136. aL vdelay3 adel,adelL*1000,10 ; delay signal left channel
  137. aR vdelay3 adel,adelR*1000,10 ; delay signal right channel
  138. ; create reverb send signals (stereo)
  139. klevel chnget "level" ; level control (pre reverb input therefore allows reverb to die away naturally)
  140. gasendL = gasendL+(aL*klevel) ; left channel reverb send signal accumulated with audio from this note
  141. gasendR = gasendR+(aR*klevel) ; right channel reverb send signal accumulated with audio from this note
  142. endin
  143. instr Reverb
  144. kroom chnget "room" ; room size
  145. garvbL, garvbR reverbsc gasendL, gasendR, kroom, 7000 ; apply reverb
  146. iDryLev = 0.1 ; dry signal level
  147. kRvbLev chnget "distance" ; reverb signal level
  148. outs (garvbL*kRvbLev*0.2)+(gasendL*iDryLev*(1-kRvbLev)), (garvbR*kRvbLev*0.2)+(gasendR*iDryLev*(1-kRvbLev))
  149. clear gasendL,gasendR
  150. endin
  151. </CsInstruments>
  152. <CsScore>
  153. i "Reverb" 0 3600
  154. </CsScore>
  155. </CsoundSynthesizer>