Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. # piano.rb -- translation of piano.scm -*- snd-ruby -*-
  2. # ;;; CLM piano.ins (Scott Van Duyne) translated to Snd/Scheme
  3. # Ruby Translator: Michael Scholz <mi-scholz@users.sourceforge.net>
  4. # Created: Thu Mar 06 03:58:02 CET 2003
  5. # Changed: Mon Nov 22 13:25:33 CET 2010
  6. module Piano
  7. require "ws"
  8. require "env"
  9. include Math
  10. Number_of_stiffness_allpasses = 8
  11. Longitudinal_mode_cutoff_keynum = 29
  12. Longitudinal_mode_stiffness_coefficient = -0.5
  13. Golden_mean = 0.618
  14. Loop_gain_env_t60 = 0.05
  15. Loop_gain_default = 0.9999
  16. Nstrings = 3
  17. # ;;keyNum indexed parameter tables
  18. # ;;these should all be &key variable defaults for p instrument
  19. Default_loudPole_table = [36, 0.8, 60, 0.85, 84, 0.7, 96, 0.6, 108, 0.5]
  20. Default_softPole_table = [36, 0.93, 60, 0.9, 84, 0.9, 96, 0.8, 108, 0.8]
  21. Default_loudGain_table = [21.0, 0.7, 36.0, 0.7, 48.0, 0.7, 60.0, 0.65, 72.0, 0.65, 84.0,
  22. 0.65, 87.006, 0.681, 88.07, 0.444, 90.653, 0.606, 95.515, 0.731,
  23. 99.77, 0.775, 101.897, 0.794, 104.024, 0.8, 105.695, 0.806]
  24. Default_softGain_table = [21, 0.25, 108, 0.25]
  25. Default_strikePosition_table = [21.0, 0.14, 23.884, 0.139, 36.0, 0.128, 56.756, 0.129,
  26. 57.765, 0.13, 59.0, 0.13, 60.0, 0.128, 61.0, 0.128, 62.0,
  27. 0.129, 66.128, 0.129, 69.0, 0.128, 72.0, 0.128, 73.0,
  28. 0.128, 79.0, 0.128, 80.0, 0.128, 96.0, 0.128, 99.0, 0.128]
  29. Default_detuning2_table = [22.017, -0.09, 23.744, -0.09, 36.0, -0.08, 48.055, -0.113,
  30. 60.0, -0.135, 67.264, -0.16, 72.0, -0.2, 84.054, -0.301,
  31. 96.148, -0.383, 108, -0.383]
  32. Default_detuning3_table = [21.435, 0.027, 23.317, 0.043, 36.0, 0.03, 48.0, 0.03, 60.0,
  33. 0.03, 72.0, 0.02, 83.984, 0.034, 96.0, 0.034, 99.766, 0.034]
  34. Default_stiffnessCoefficient_table = [21.0, -0.92, 24.0, -0.9, 36.0, -0.7, 48.0, -0.25,
  35. 60.0, -0.1, 75.179, -0.04, 82.986, -0.04, 92.24,
  36. -0.04, 96.0, -0.04, 99.0, 0.2, 108.0, 0.5]
  37. Default_singleStringDecayRate_table = [21.678, -2.895, 24.0, -3.0, 36.0, -4.641, 41.953, -5.867,
  38. 48.173, -7.113, 53.818, -8.016, 59.693, -8.875, 66.605,
  39. -9.434, 73.056, -10.035, 78.931, -10.293, 84.0, -12.185]
  40. Default_singleStringZero_table = [21.0, -0.3, 24.466, -0.117, 28.763, -0.047, 36.0, -0.03, 48.0,
  41. -0.02, 60.0, -0.01, 72.0, -0.01, 84.0, -0.01, 96.0, -0.01]
  42. Default_singleStringPole_table = [21.0, 0.0, 24.466, 0.0, 28.763, 0.0, 36.0, 0.0, 108, 0.0]
  43. Default_releaseLoopGain_table = [21.643, 0.739, 24.0, 0.8, 36.0, 0.88, 48.0, 0.91, 60.0, 0.94,
  44. 72.0, 0.965, 84.0, 0.987, 88.99, 0.987, 89.0, 1.0, 108.0, 1.0]
  45. Default_dryTapFiltCoeft60_table = [36, 0.35, 60, 0.25, 108, 0.15]
  46. Default_dryTapFiltCoefTarget_table = [36, -0.8, 60, -0.5, 84, -0.4, 108, -0.1]
  47. Default_dryTapFiltCoefCurrent_table = [0, 0, 200, 0]
  48. Default_dryTapAmpt60_table = [36, 0.55, 60, 0.5, 108, 0.45]
  49. Default_sustainPedalLevel_table = [21.0, 0.25, 24.0, 0.25, 36.0, 0.2, 48.0, 0.125, 60.0,
  50. 0.075, 72.0, 0.05, 84.0, 0.03, 96.0, 0.01, 99.0, 0.01]
  51. Default_pedalResonancePole_table = [20.841, 0.534, 21.794, 0.518, 33.222, 0.386, 45.127,
  52. 0.148, 55.445, -0.065, 69.255, -0.409, 82.905, -0.729,
  53. 95.763, -0.869, 106.398, -0.861]
  54. Default_pedalEnvelopet60_table = [21.0, 7.5, 108.0, 7.5]
  55. Default_soundboardCutofft60_table = [21.0, 0.25, 108.0, 0.25]
  56. Default_dryPedalResonanceFactor_table = [21.0, 0.5, 108.0, 0.5]
  57. Default_unaCordaGain_table = [21, 1.0, 24, 0.4, 29, 0.1, 29.1, 0.95, 108, 0.95]
  58. def p(start, *args)
  59. duration = get_args(args, :duration, 1.0)
  60. keyNum = get_args(args, :keyNum, 60.0)
  61. strike_velocity = get_args(args, :strike_velocity, 0.5)
  62. pedal_down = get_args(args, :pedal_down, false)
  63. release_time_margin = get_args(args, :release_time_margin, 0.75)
  64. amp = get_args(args, :amp, 0.5)
  65. detuningFactor = get_args(args, :detuningFactor, 1.0)
  66. detuningFactor_table = get_args(args, :detuningFactor_table, [])
  67. stiffnessFactor = get_args(args, :stiffnessFactor, 1.0)
  68. stiffnessFactor_table = get_args(args, :stiffnessFactor_table, [])
  69. pedalPresenceFactor = get_args(args, :pedalPresenceFactor, 0.3)
  70. longitudinalMode = get_args(args, :longitudinalMode, 10.5)
  71. strikePositionInvFac = get_args(args, :strikePositionInvFac, -0.9)
  72. singleStringDecayRateFactor = get_args(args, :singleStringDecayRateFactor, 1.0)
  73. loudPole = get_args(args, :loudPole, nil)
  74. loudPole_table = get_args(args, :loudPole_table, Default_loudPole_table)
  75. softPole = get_args(args, :softPole, nil)
  76. softPole_table = get_args(args, :softPole_table, Default_softPole_table)
  77. loudGain = get_args(args, :loudGain, nil)
  78. loudGain_table = get_args(args, :loudGain_table, Default_loudGain_table)
  79. softGain = get_args(args, :softGain, nil)
  80. softGain_table = get_args(args, :softGain_table, Default_softGain_table)
  81. strikePosition = get_args(args, :strikePosition, nil)
  82. strikePosition_table = get_args(args, :strikePosition_table, Default_strikePosition_table)
  83. detuning2 = get_args(args, :detuning2, nil)
  84. detuning2_table = get_args(args, :detuning2_table, Default_detuning2_table)
  85. detuning3 = get_args(args, :detuning3, nil)
  86. detuning3_table = get_args(args, :detuning3_table, Default_detuning3_table)
  87. stiffnessCoefficient = get_args(args, :stiffnessCoefficient, nil)
  88. stiffnessCoefficient_table = get_args(args, :stiffnessCoefficient_table,
  89. Default_stiffnessCoefficient_table)
  90. singleStringDecayRate = get_args(args, :singleStringDecayRate, nil)
  91. singleStringDecayRate_table = get_args(args, :singleStringDecayRate_table,
  92. Default_singleStringDecayRate_table)
  93. singleStringZero = get_args(args, :singleStringZero, nil)
  94. singleStringZero_table = get_args(args, :singleStringZero_table,
  95. Default_singleStringZero_table)
  96. singleStringPole = get_args(args, :singleStringPole, nil)
  97. singleStringPole_table = get_args(args, :singleStringPole_table,
  98. Default_singleStringPole_table)
  99. releaseLoopGain = get_args(args, :releaseLoopGain, nil)
  100. releaseLoopGain_table = get_args(args, :releaseLoopGain_table, Default_releaseLoopGain_table)
  101. dryTapFiltCoeft60 = get_args(args, :dryTapFiltCoeft60, nil)
  102. dryTapFiltCoeft60_table = get_args(args, :dryTapFiltCoeft60_table,
  103. Default_dryTapFiltCoeft60_table)
  104. dryTapFiltCoefTarget = get_args(args, :dryTapFiltCoefTarget, nil)
  105. dryTapFiltCoefTarget_table = get_args(args, :dryTapFiltCoefTarget_table,
  106. Default_dryTapFiltCoefTarget_table)
  107. dryTapFiltCoefCurrent = get_args(args, :dryTapFiltCoefCurrent, nil)
  108. dryTapFiltCoefCurrent_table = get_args(args, :dryTapFiltCoefCurrent_table,
  109. Default_dryTapFiltCoefCurrent_table)
  110. dryTapAmpt60 = get_args(args, :dryTapAmpt60, nil)
  111. dryTapAmpt60_table = get_args(args, :dryTapAmpt60_table, Default_dryTapAmpt60_table)
  112. sustainPedalLevel = get_args(args, :sustainPedalLevel, nil)
  113. sustainPedalLevel_table = get_args(args, :sustainPedalLevel_table,
  114. Default_sustainPedalLevel_table)
  115. pedalResonancePole = get_args(args, :pedalResonancePole, nil)
  116. pedalResonancePole_table = get_args(args, :pedalResonancePole_table,
  117. Default_pedalResonancePole_table)
  118. pedalEnvelopet60 = get_args(args, :pedalEnvelopet60, nil)
  119. pedalEnvelopet60_table = get_args(args, :pedalEnvelopet60_table,
  120. Default_pedalEnvelopet60_table)
  121. soundboardCutofft60 = get_args(args, :soundboardCutofft60, nil)
  122. soundboardCutofft60_table = get_args(args, :soundboardCutofft60_table,
  123. Default_soundboardCutofft60_table)
  124. dryPedalResonanceFactor = get_args(args, :dryPedalResonanceFactor, nil)
  125. dryPedalResonanceFactor_table = get_args(args, :dryPedalResonanceFactor_table,
  126. Default_dryPedalResonanceFactor_table)
  127. unaCordaGain = get_args(args, :unaCordaGain, nil)
  128. unaCordaGain_table = get_args(args, :unaCordaGain_table, Default_unaCordaGain_table)
  129. dur = seconds2samples(duration)
  130. freq = 440.0 * (2.0 ** ((keyNum - 69.0) / 12.0))
  131. wT = (TWO_PI * freq) / mus_srate
  132. # ;;look_up parameters in tables (or else use the override value)
  133. loudPole = (loudPole or envelope_interp(keyNum, loudPole_table))
  134. softPole = (softPole or envelope_interp(keyNum, softPole_table))
  135. loudGain = (loudGain or envelope_interp(keyNum, loudGain_table))
  136. softGain = (softGain or envelope_interp(keyNum, softGain_table))
  137. strikePosition = (strikePosition or envelope_interp(keyNum, strikePosition_table))
  138. detuning2 = (detuning2 or envelope_interp(keyNum, detuning2_table))
  139. detuning3 = (detuning3 or envelope_interp(keyNum, detuning3_table))
  140. stiffnessCoefficient = (stiffnessCoefficient or
  141. envelope_interp(keyNum, stiffnessCoefficient_table))
  142. singleStringDecayRate = (singleStringDecayRate or
  143. envelope_interp(keyNum, singleStringDecayRate_table))
  144. singleStringDecayRate = singleStringDecayRateFactor * singleStringDecayRate
  145. singleStringZero = (singleStringZero or envelope_interp(keyNum, singleStringZero_table))
  146. singleStringPole = (singleStringPole or envelope_interp(keyNum, singleStringPole_table))
  147. releaseLoopGain = (releaseLoopGain or envelope_interp(keyNum, releaseLoopGain_table))
  148. dryTapFiltCoeft60 = (dryTapFiltCoeft60 or
  149. envelope_interp(keyNum, dryTapFiltCoeft60_table))
  150. dryTapFiltCoefTarget = (dryTapFiltCoefTarget or
  151. envelope_interp(keyNum, dryTapFiltCoefTarget_table))
  152. dryTapFiltCoefCurrent = (dryTapFiltCoefCurrent or
  153. envelope_interp(keyNum, dryTapFiltCoefCurrent_table))
  154. dryTapAmpt60 = (dryTapAmpt60 or envelope_interp(keyNum, dryTapAmpt60_table))
  155. sustainPedalLevel = (sustainPedalLevel or envelope_interp(keyNum, sustainPedalLevel_table))
  156. pedalResonancePole = (pedalResonancePole or envelope_interp(keyNum, pedalResonancePole_table))
  157. pedalEnvelopet60 = (pedalEnvelopet60 or envelope_interp(keyNum, pedalEnvelopet60_table))
  158. soundboardCutofft60 = (soundboardCutofft60 or
  159. envelope_interp(keyNum, soundboardCutofft60_table))
  160. dryPedalResonanceFactor = (dryPedalResonanceFactor or
  161. envelope_interp(keyNum, dryPedalResonanceFactor_table))
  162. unaCordaGain = (unaCordaGain or envelope_interp(keyNum, unaCordaGain_table))
  163. detuningFactor = if detuningFactor_table.empty?
  164. envelope_interp(keyNum, detuningFactor_table)
  165. else
  166. detuningFactor
  167. end
  168. stiffnessFactor = if stiffnessFactor_table.empty?
  169. envelope_interp(keyNum, stiffnessFactor_table)
  170. else
  171. stiffnessFactor
  172. end
  173. # ;;initialize soundboard impulse response elements
  174. dryTap_one_pole_one_zero_pair = make_one_pole_one_zero(1.0, 0.0, 0.0)
  175. dryTap0 = dryTap_one_pole_one_zero_pair[0]
  176. dryTap1 = dryTap_one_pole_one_zero_pair[1]
  177. dryTap_coef_expseg = make_expseg(dryTapFiltCoefCurrent, dryTapFiltCoefTarget)
  178. drycoefrate = in_t60(dryTapFiltCoeft60)
  179. dryTap_one_pole_swept = make_one_pole_swept()
  180. dryTap_amp_expseg = make_expseg(1.0, 0.0)
  181. dryamprate = in_t60(dryTapAmpt60)
  182. # ;;initialize open_string resonance elements
  183. wetTap_one_pole_one_zero_pair =
  184. make_one_pole_one_zero(1.0 - signum(pedalResonancePole) * pedalResonancePole,
  185. 0.0, -pedalResonancePole)
  186. wetTap0 = wetTap_one_pole_one_zero_pair[0]
  187. wetTap1 = wetTap_one_pole_one_zero_pair[1]
  188. wetTap_coef_expseg = make_expseg(0.0, -0.5)
  189. wetcoefrate = in_t60(pedalEnvelopet60)
  190. wetTap_one_pole_swept = make_one_pole_swept()
  191. wetTap_amp_expseg = make_expseg(sustainPedalLevel * pedalPresenceFactor *
  192. (pedal_down ? 1.0 : dryPedalResonanceFactor),
  193. 0.0)
  194. wetamprate = in_t60(pedalEnvelopet60)
  195. sb_cutoff_rate = in_t60(soundboardCutofft60)
  196. # ;;initialize velocity_dependent piano hammer filter elements
  197. hammerPole = softPole + (loudPole - softPole) * strike_velocity
  198. hammerGain = softGain + (loudGain - softGain) * strike_velocity
  199. hammer_one_pole = Array.new(4)
  200. # ;;strike position comb filter delay length
  201. agraffe_len = (mus_srate * strikePosition) / freq
  202. 0.upto(3) do |i|
  203. hammer_one_pole[i] = make_one_pole(1.0 * (1.0 - hammerPole), -hammerPole)
  204. end
  205. vals = apfloor(agraffe_len, wT)
  206. dlen1 = vals[0]
  207. apcoef1 = vals[1]
  208. agraffe_delay1 = make_delay0(dlen1)
  209. agraffe_tuning_ap1 = make_one_pole_allpass(apcoef1)
  210. # ;;compute coefficients for and initialize the coupling filter
  211. # ;;taking L=g(1 - bz^-1)/(1-b), and computing Hb = -(1-L)/(2-L)
  212. attenuationPerPeriod = 10.0 ** (singleStringDecayRate / freq / 20.0)
  213. g = attenuationPerPeriod # ;;DC gain
  214. b = singleStringZero
  215. a = singleStringPole
  216. ctemp = 1 + -b + g + -(a * g) + Nstrings * (1 + -b + -g + a * g)
  217. cfb0 = (2 * (-1 + b + g + -(a * g))) / ctemp
  218. cfb1 = (2 * (a + -(a * b) + -(b * g) + a * b * g)) / ctemp
  219. cfa1 = (-a + a * b + -(b * g) + a * b * g + Nstrings * (-a + a * b + b * g + -(a * b * g))) /
  220. ctemp
  221. couplingFilter_pair = make_one_pole_one_zero(cfb0, cfb1, cfa1)
  222. cou0 = couplingFilter_pair[0]
  223. cou1 = couplingFilter_pair[1]
  224. # ;;determine string tunings (and longitudinal modes, if present)
  225. freq1 = if keyNum <= Longitudinal_mode_cutoff_keynum
  226. freq * longitudinalMode
  227. else
  228. freq
  229. end
  230. freq2 = freq + detuning2 * detuningFactor
  231. freq3 = freq + detuning3 * detuningFactor
  232. # ;;scale stiffness coefficients, if desired
  233. stiffnessCoefficient = if stiffnessFactor > 1.0
  234. stiffnessCoefficient - ((stiffnessCoefficient + 1) *
  235. (stiffnessFactor - 1))
  236. else
  237. stiffnessCoefficient * stiffnessFactor
  238. end
  239. stiffnessCoefficientL = if keyNum <= Longitudinal_mode_cutoff_keynum
  240. Longitudinal_mode_stiffness_coefficient
  241. else
  242. stiffnessCoefficient
  243. end
  244. # ;;initialize the coupled_string elements
  245. vals1 = tune_piano(freq1, stiffnessCoefficientL, Number_of_stiffness_allpasses,
  246. cfb0, cfb1, cfa1)
  247. delayLength1 = vals1[0]
  248. tuningCoefficient1 = vals1[1]
  249. vals2 = tune_piano(freq2, stiffnessCoefficient, Number_of_stiffness_allpasses,
  250. cfb0, cfb1, cfa1)
  251. delayLength2 = vals2[0]
  252. tuningCoefficient2 = vals2[1]
  253. vals3 = tune_piano(freq3, stiffnessCoefficient, Number_of_stiffness_allpasses,
  254. cfb0, cfb1, cfa1)
  255. delayLength3 = vals3[0]
  256. tuningCoefficient3 = vals3[1]
  257. string1_delay = make_delay0(delayLength1 - 1)
  258. string1_tuning_ap = make_one_pole_allpass(tuningCoefficient1)
  259. string1_stiffness_ap = Array.new(8)
  260. string2_delay = make_delay0(delayLength2 - 1)
  261. string2_tuning_ap = make_one_pole_allpass(tuningCoefficient2)
  262. string2_stiffness_ap = Array.new(8)
  263. string3_delay = make_delay0(delayLength3 - 1)
  264. string3_tuning_ap = make_one_pole_allpass(tuningCoefficient3)
  265. string3_stiffness_ap = Array.new(8)
  266. # ;;initialize loop_gain envelope
  267. loop_gain_expseg = make_expseg(Loop_gain_default, releaseLoopGain)
  268. looprate = in_t60(Loop_gain_env_t60)
  269. adelOut = 0.0
  270. loop_gain = Loop_gain_default
  271. is_release_time = false
  272. string1_junction_input = 0.0
  273. string2_junction_input = 0.0
  274. string3_junction_input = 0.0
  275. couplingFilter_output = 0.0
  276. sampCount = 0
  277. noi = make_noise()
  278. 0.upto(7) do |i|
  279. string1_stiffness_ap[i] = make_one_pole_allpass(stiffnessCoefficientL)
  280. end
  281. 0.upto(7) do |i|
  282. string2_stiffness_ap[i] = make_one_pole_allpass(stiffnessCoefficient)
  283. end
  284. 0.upto(7) do |i|
  285. string3_stiffness_ap[i] = make_one_pole_allpass(stiffnessCoefficient)
  286. end
  287. run_instrument(start, duration + release_time_margin) do
  288. if is_release_time
  289. loop_gain = loop_gain_expseg.call(looprate)
  290. elsif sampCount == dur
  291. is_release_time = true
  292. dryamprate = sb_cutoff_rate
  293. wetamprate = sb_cutoff_rate
  294. end
  295. dryTap = (dryTap_amp_expseg.call(dryamprate) * \
  296. dryTap_one_pole_swept.call(one_pole_one_zero(dryTap0, dryTap1, noi.call(amp)),
  297. dryTap_coef_expseg.call(drycoefrate)))
  298. openStrings = (wetTap_amp_expseg.call(wetamprate) * \
  299. wetTap_one_pole_swept.call(one_pole_one_zero(wetTap0, wetTap1, noi.call(amp)),
  300. wetTap_coef_expseg.call(wetcoefrate)))
  301. adelIn = dryTap + openStrings
  302. 0.upto(3) do |i| adelIn = one_pole(hammer_one_pole[i], adelIn) end
  303. combedExcitationSignal = hammerGain * (adelOut + adelIn * strikePositionInvFac)
  304. adelOut = agraffe_tuning_ap1.call(delay0(agraffe_delay1, adelIn))
  305. string1_junction_input += couplingFilter_output
  306. 0.upto(7) do |i|
  307. string1_junction_input = string1_stiffness_ap[i].call(string1_junction_input)
  308. end
  309. string1_junction_input = (unaCordaGain * combedExcitationSignal + \
  310. loop_gain * delay0(string1_delay,
  311. string1_tuning_ap.call(string1_junction_input)))
  312. string2_junction_input += couplingFilter_output
  313. 0.upto(7) do |i|
  314. string2_junction_input = string2_stiffness_ap[i].call(string2_junction_input)
  315. end
  316. string2_junction_input = (combedExcitationSignal + \
  317. loop_gain * delay0(string2_delay,
  318. string2_tuning_ap.call(string2_junction_input)))
  319. string3_junction_input += couplingFilter_output
  320. 0.upto(7) do |i|
  321. string3_junction_input = string3_stiffness_ap[i].call(string3_junction_input)
  322. end
  323. string3_junction_input = (combedExcitationSignal + \
  324. loop_gain * delay0(string3_delay,
  325. string3_tuning_ap.call(string3_junction_input)))
  326. couplingFilter_input = string1_junction_input + string2_junction_input +
  327. string3_junction_input
  328. couplingFilter_output = one_pole_one_zero(cou0, cou1, couplingFilter_input)
  329. sampCount += 1
  330. couplingFilter_input
  331. end
  332. end
  333. # ;;; converts t60 values to suitable :rate values for expseg
  334. def in_t60(t60)
  335. 1.0 - (0.001 ** (1.0 / t60 / mus_srate))
  336. end
  337. # ;;; expseg (like musickit asymp)
  338. def make_expseg(cv = 0.0, tv = 0.0)
  339. lambda do |r|
  340. old_cv = cv
  341. cv = cv + (tv - cv) * r
  342. old_cv # ; (bil) this is slightly different (getting clicks)
  343. end
  344. end
  345. # ;;; signal controlled one-pole lowpass filter
  346. def make_one_pole_swept
  347. y1 = 0.0
  348. lambda do |input, coef|
  349. y1 = (coef + 1) * input - coef * y1
  350. end
  351. end
  352. # ;;; one-pole allpass filter
  353. def make_one_pole_allpass(coeff)
  354. coef = coeff
  355. x1 = 0.0
  356. y1 = 0.0
  357. lambda do |input|
  358. y1 = (coef * (input - y1)) + x1
  359. x1 = input
  360. y1
  361. end
  362. end
  363. def one_pole_one_zero(f0, f1, input)
  364. one_zero(f0, one_pole(f1, input))
  365. end
  366. def make_one_pole_one_zero(a0, a1, b1)
  367. [make_one_zero(a0, a1), make_one_pole(1.0, b1)]
  368. end
  369. # ;;; very special noise generator
  370. def make_noise
  371. noise_seed = 16383
  372. lambda do |amp|
  373. noise_seed = (noise_seed * 1103515245 + 12345) & 0xffffffff
  374. # ;; (bil) added the logand -- otherwise we get an overflow somewhere
  375. amp * (((noise_seed / 65536).round % 65536) * 0.0000305185 - 1.0)
  376. end
  377. end
  378. # ;;; delay line unit generator with length 0 capabilities...
  379. def make_delay0(len)
  380. len > 0 ? make_delay(len) : false
  381. end
  382. def delay0(f, input)
  383. f ? delay(f, input) : input
  384. end
  385. def ap_phase(a1, wT)
  386. atan2((a1 * a1 - 1.0) * sin(wT), 2.0 * a1 + (a1 * a1 + 1.0) * cos(wT))
  387. end
  388. def opoz_phase(b0, b1, a1, wT)
  389. s = sin(wT)
  390. c = cos(wT)
  391. atan2(a1 * s * (b0 + b1 * c) - b1 * s * (1 + a1 * c),
  392. (b0 + b1 * c) * (1 + a1 * c) + b1 * s * a1 * s)
  393. end
  394. def get_allpass_coef(samp_frac, wT)
  395. ta = tan(-(samp_frac * wT))
  396. c = cos(wT)
  397. s = sin(wT)
  398. (-ta + signum(ta) * sqrt((ta * ta + 1) * s * s)) / (c * ta - s)
  399. end
  400. def signum(x)
  401. if x == 0.0
  402. 0
  403. elsif x < 0.0
  404. -1
  405. else
  406. 1
  407. end
  408. end
  409. def apfloor(len, wT)
  410. len_int = len.floor.round
  411. len_frac = len - len_int
  412. if len_frac < Golden_mean
  413. len_int -= 1
  414. len_frac += 1.0
  415. end
  416. if len_frac < Golden_mean and len_int > 0
  417. len_int -= 1
  418. len_frac += 1.0
  419. end
  420. [len_int, get_allpass_coef(len_frac, wT)]
  421. end
  422. def tune_piano(frequency, stiffnessCoefficient, numAllpasses, b0, b1, a1)
  423. wT = (frequency * TWO_PI) / mus_srate
  424. len = (TWO_PI + (numAllpasses * ap_phase(stiffnessCoefficient, wT)) +
  425. opoz_phase(1 + 3 * b0, a1 + 3 * b1, a1, wT)) / wT
  426. apfloor(len, wT)
  427. end
  428. end
  429. include Piano
  430. =begin
  431. with_sound(:clm, false, :channels, 1) do
  432. 7.times do |i|
  433. p(i * 0.5,
  434. :duration, 0.5,
  435. :keyNum, 24 + 12.0 * i,
  436. :strike_velocity, 0.5,
  437. :amp, 0.4,
  438. :dryPedalResonanceFactor, 0.25)
  439. end
  440. end
  441. with_sound(:clm, false, :channels, 1) do
  442. 7.times do |i|
  443. p(i * 0.5,
  444. :duration, 0.5,
  445. :keyNum, 24 + 12.0 * i,
  446. :strike_velocity, 0.5,
  447. :amp, 0.4,
  448. :dryPedalResonanceFactor, 0.25,
  449. :detuningFactor_table, [24, 5, 36, 7.0, 48, 7.5, 60, 12.0, 72, 20,
  450. 84, 30, 96, 100, 108, 300],
  451. :stiffnessFactor_table, [21, 1.5, 24, 1.5, 36, 1.5, 48, 1.5, 60, 1.4,
  452. 72, 1.3, 84, 1.2, 96, 1.0, 108, 1.0])
  453. end
  454. end
  455. with_sound(:clm, false, :channels, 1) do
  456. 7.times do |i|
  457. p(i * 0.5,
  458. :duration, 0.5,
  459. :keyNum, 24 + 12.0 * i,
  460. :strike_velocity, 0.5,
  461. :amp, 0.4,
  462. :dryPedalResonanceFactor, 0.25,
  463. :singleStringDecayRate_table, [21, -5, 24.0, -5.0, 36.0, -5.4, 41.953, -5.867, 48.173,
  464. -7.113, 53.818, -8.016, 59.693, -8.875, 66.605, -9.434,
  465. 73.056, -10.035, 78.931, -10.293, 84.000, -12.185],
  466. :singleStringPole_table, [21, 0.8, 24, 0.7, 36.0, 0.6, 48, 0.5, 60,
  467. 0.3, 84, 0.1, 96, 0.03, 108, 0.03],
  468. :stiffnessCoefficient_table, [21.0, -0.92, 24.0, -0.9, 36.0, -0.7, 48.0, -0.250, 60.0,
  469. -0.1, 75.179, -0.040, 82.986, -0.040, 92.240, 0.3, 96.0,
  470. 0.5, 99.0, 0.7, 108.0, 0.7])
  471. end
  472. end
  473. with_sound(:clm, false, :channels, 1) do
  474. p(0,
  475. :duration, 5,
  476. :keyNum, 24 + 12.0 * 5,
  477. :strike_velocity, 0.5,
  478. :amp, 0.4,
  479. :dryPedalResonanceFactor, 0.25,
  480. :singleStringDecayRateFactor, 1 / 10.0)
  481. end
  482. =end
  483. # piano.rb ends here