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.

преди 2 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. # Translator: Michael Scholz <mi-scholz@users.sourceforge.net>
  2. # Created: 02/11/20 02:24:34
  3. # Changed: 14/11/23 03:36:55
  4. # fm_violin(start, dur, freq, amp, *args)
  5. # play_fm_violin(start, dur, freq, amp, *args)
  6. # make_fm_violin(start, dur, freq, amp, *args)
  7. # jc_reverb(*args)
  8. require "ws"
  9. v_opts_str = "fm_violin(start=0.0, dur=1.0, freq=440.0, amp=0.5, *args)
  10. :fm_index = 1.0
  11. :amp_env = [0, 0, 25, 1, 75, 1, 100, 0]
  12. :periodic_vibrato_rate = 5.0
  13. :random_vibrato_rate = 16.0
  14. :periodic_vibrato_amp = 0.0025
  15. :random_vibrato_amp = 0.005
  16. :noise_amount = 0.0
  17. :noise_freq = 1000.0
  18. :ind_noise_freq = 10.0
  19. :ind_noise_amount = 0.0
  20. :amp_noise_freq = 20.0
  21. :amp_noise_amount = 0.0
  22. :gliss_env = [0, 0, 100, 0]
  23. :gliss_amount = 0.0
  24. :fm1_env = [0, 1, 25, 0.4, 75, 0.6, 100, 0]
  25. :fm2_env = [0, 1, 25, 0.4, 75, 0.6, 100, 0]
  26. :fm3_env = [0, 1, 25, 0.4, 75, 0.6, 100, 0]
  27. :fm1_rat = 1.0
  28. :fm2_rat = 3.0
  29. :fm3_rat = 4.0
  30. :fm1_index = false
  31. :fm2_index = false
  32. :fm3_index = false
  33. :base = 1.0
  34. :index_type = :violin"
  35. add_help(:fm_violin,
  36. "#{v_opts_str}
  37. :reverb_amount = 0.01
  38. :degree = kernel_rand(90.0)
  39. :distance = 1.0
  40. Ruby: fm_violin(0, 1, 440, 0.1, :fm_index, 2.0)
  41. Scheme: (fm-violin 0 1 440 0.1 :fm-index 2.0)
  42. Example: with_sound do fm_violin(0, 1, 440, 0.1, :fm_index, 2.0) end")
  43. def fm_violin(start = 0.0, dur = 1.0, freq = 440.0, amp = 0.5, *args)
  44. r = get_args(args, :reverb_amount, 0.01)
  45. d = get_args(args, :degree, kernel_rand(90.0))
  46. s = get_args(args, :distance, 1.0)
  47. fm_vln = make_fm_violin_gen(start, dur, freq, amp, *args)
  48. run_instrument(start, dur, :reverb_amount, r, :degree, d, :distance, s) do
  49. fm_vln.call(0)
  50. end
  51. end
  52. add_help(:play_fm_violin,
  53. "play_#{v_opts_str}
  54. Returns a fm_violin proc with no arg for play(proc).
  55. v = play_fm_violin(0, 1, 440, 0.5)
  56. play(v)
  57. or
  58. play(play_fm_violin(0, 1, 440, 0.5))")
  59. def play_fm_violin(start = 0.0, dur = 1.0, freq = 440.0, amp = 0.5, *args)
  60. fm_vln = make_fm_violin_gen(start, dur, freq, amp, *args)
  61. len = seconds2samples(dur)
  62. lambda do
  63. (len -= 1).positive? and fm_vln.call(0)
  64. end
  65. end
  66. #
  67. # make_fm_violin: returns lambda do |y| ... end
  68. #
  69. add_help(:make_fm_violin,
  70. "make_#{v_opts_str}
  71. Returns a proc with one arg for map_channel()
  72. *args are like fm_violin's
  73. ins = new_sound(:file, \"fmv.snd\", :srate, 22050, :channels, 2)
  74. # proc with one arg
  75. fmv1 = make_fm_violin(0, 1, 440, 0.5)
  76. map_channel(fmv1, 0, 22050, ins, 1)")
  77. def make_fm_violin(start = 0.0, dur = 1.0, freq = 440.0, amp = 1.0, *args)
  78. make_fm_violin_gen(start, dur, freq, amp, *args)
  79. end
  80. def make_fm_violin_gen(start, dur, freq, amp, *args)
  81. fm_index, amp_env, periodic_vibrato_rate, random_vibrato_rate = nil
  82. periodic_vibrato_amp, random_vibrato_amp, noise_amount, noise_freq = nil
  83. ind_noise_freq, ind_noise_amount, amp_noise_freq, amp_noise_amount = nil
  84. gliss_env, gliss_amount = nil
  85. fm1_env, fm2_env, fm3_env, fm1_rat, fm2_rat, fm3_rat = nil
  86. fm1_index, fm2_index, fm3_index, base, index_type = nil
  87. optkey(args, binding,
  88. [:fm_index, 1.0],
  89. [:amp_env, [0, 0, 25, 1, 75, 1, 100, 0]],
  90. [:periodic_vibrato_rate, 5.0],
  91. [:random_vibrato_rate, 16.0],
  92. [:periodic_vibrato_amp, 0.0025],
  93. [:random_vibrato_amp, 0.005],
  94. [:noise_amount, 0.0],
  95. [:noise_freq, 1000.0],
  96. [:ind_noise_freq, 10.0],
  97. [:ind_noise_amount, 0.0],
  98. [:amp_noise_freq, 20.0],
  99. [:amp_noise_amount, 0.0],
  100. [:gliss_env, [0, 0, 100, 0]],
  101. [:gliss_amount, 0.0],
  102. [:fm1_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0]],
  103. [:fm2_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0]],
  104. [:fm3_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0]],
  105. [:fm1_rat, 1.0],
  106. [:fm2_rat, 3.0],
  107. [:fm3_rat, 4.0],
  108. [:fm1_index, false],
  109. [:fm2_index, false],
  110. [:fm3_index, false],
  111. [:base, 1.0],
  112. [:index_type, :violin])
  113. frq_scl = hz2radians(freq)
  114. modulate = fm_index.nonzero?
  115. maxdev = frq_scl * fm_index
  116. vln = (index_type == :violin or index_type == 1)
  117. logfreq = log(freq)
  118. sqrtfreq = sqrt(freq)
  119. index1 = (fm1_index or [PI, maxdev * (vln ? 5.0 : 7.5) / logfreq].min)
  120. index2 = (fm2_index or [PI, maxdev * 3.0 *
  121. (vln ? ((8.5 - logfreq) / (3.0 + freq * 0.001)) :
  122. (15.0 / sqrtfreq))].min)
  123. index3 = (fm3_index or [PI, maxdev * (vln ? 4.0 : 8.0) / sqrtfreq].min)
  124. easy_case = (noise_amount.zero? and
  125. (fm1_env == fm2_env) and
  126. (fm1_env == fm3_env) and
  127. (fm1_rat - fm1_rat.floor).zero? and
  128. (fm2_rat - fm2_rat.floor).zero? and
  129. (fm3_rat - fm3_rat.floor).zero?)
  130. norm = ((easy_case and modulate and 1.0) or index1)
  131. carrier = make_oscil(freq)
  132. fmosc1 = fmosc2 = fmosc3 = false
  133. indf1 = indf2 = indf3 = false
  134. if modulate
  135. indf1 = make_env(fm1_env, norm, dur)
  136. if easy_case
  137. a = [fm1_rat.to_i, index1,
  138. (fm2_rat / fm1_rat).floor, index2,
  139. (fm3_rat / fm1_rat).floor, index3]
  140. coe = partials2polynomial(a)
  141. fmosc1 = make_polyshape(:frequency, fm1_rat * freq, :coeffs, coe)
  142. else
  143. indf2 = make_env(fm2_env, index2, dur)
  144. indf3 = make_env(fm3_env, index3, dur)
  145. if (fm1_rat * freq * 2.0) > mus_srate
  146. fmosc1 = make_oscil(:frequency, freq)
  147. else
  148. fmosc1 = make_oscil(:frequency, fm1_rat * freq)
  149. end
  150. if (fm2_rat * freq * 2.0) > mus_srate
  151. fmosc2 = make_oscil(:frequency, freq)
  152. else
  153. fmosc2 = make_oscil(:frequency, fm2_rat * freq)
  154. end
  155. if (fm3_rat * freq * 2.0) > mus_srate
  156. fmosc3 = make_oscil(:frequency, freq)
  157. else
  158. fmosc3 = make_oscil(:frequency, fm3_rat * freq)
  159. end
  160. end
  161. end
  162. ampf = make_env(amp_env, amp, dur, 0.0, base)
  163. frqf = make_env(gliss_env, gliss_amount * frq_scl, dur)
  164. pervib = make_triangle_wave(periodic_vibrato_rate,
  165. periodic_vibrato_amp * frq_scl)
  166. ranvib = make_rand_interp(random_vibrato_rate,
  167. random_vibrato_amp * frq_scl)
  168. fm_noi = if noise_amount.nonzero?
  169. make_rand(noise_freq, PI * noise_amount)
  170. else
  171. false
  172. end
  173. ind_noi = if ind_noise_amount.nonzero? and ind_noise_freq.nonzero?
  174. make_rand_interp(ind_noise_freq, ind_noise_amount)
  175. else
  176. false
  177. end
  178. amp_noi = if amp_noise_amount.nonzero? and amp_noise_freq.nonzero?
  179. make_rand_interp(amp_noise_freq, amp_noise_amount)
  180. else
  181. false
  182. end
  183. fuzz = modulation = 0.0
  184. ind_fuzz = amp_fuzz = 1.0
  185. if modulate
  186. if easy_case
  187. lambda do |y|
  188. vib = env(frqf) + triangle_wave(pervib) + rand_interp(ranvib)
  189. ind_fuzz = 1.0 + rand_interp(ind_noi) if ind_noi
  190. amp_fuzz = 1.0 + rand_interp(amp_noi) if amp_noi
  191. modulation = env(indf1) * polyshape(fmosc1, 1.0, vib)
  192. env(ampf) * amp_fuzz * oscil(carrier, vib + ind_fuzz * modulation)
  193. end
  194. else
  195. lambda do |y|
  196. fuzz = rand(fm_noi) if fm_noi
  197. vib = env(frqf) + triangle_wave(pervib) + rand_interp(ranvib)
  198. ind_fuzz = 1.0 + rand_interp(ind_noi) if ind_noi
  199. amp_fuzz = 1.0 + rand_interp(amp_noi) if amp_noi
  200. modulation = (env(indf1) * oscil(fmosc1, fm1_rat * vib + fuzz) +
  201. env(indf2) * oscil(fmosc2, fm2_rat * vib + fuzz) +
  202. env(indf3) * oscil(fmosc3, fm3_rat * vib + fuzz))
  203. env(ampf) * amp_fuzz * oscil(carrier, vib + ind_fuzz * modulation)
  204. end
  205. end
  206. else
  207. lambda do |y|
  208. vib = env(frqf) + triangle_wave(pervib) + rand_interp(ranvib)
  209. ind_fuzz = 1.0 + rand_interp(ind_noi) if ind_noi
  210. amp_fuzz = 1.0 + rand_interp(amp_noi) if amp_noi
  211. env(ampf) * amp_fuzz * oscil(carrier, vib + ind_fuzz)
  212. end
  213. end
  214. end
  215. add_help(:jc_reverb,
  216. "jc_reverb(*args)
  217. :volume = 1.0
  218. :delay1 = 0.013
  219. :delay2 = 0.011
  220. :delay3 = 0.015
  221. :delay4 = 0.017
  222. :low_pass = false
  223. :double = false
  224. :amp_env = false
  225. Chowning reverb")
  226. def jc_reverb(*args)
  227. low_pass, volume, amp_env, delay1, delay2, delay3, delay4, double = nil
  228. optkey(args, binding,
  229. [:volume, 1.0],
  230. [:delay1, 0.013],
  231. [:delay2, 0.011],
  232. [:delay3, 0.015],
  233. [:delay4, 0.017],
  234. [:low_pass, false],
  235. [:double, false],
  236. [:amp_env, false])
  237. chan2 = (@channels > 1)
  238. chan4 = (@channels == 4)
  239. if double and chan4
  240. error("%s: not set up for doubled reverb in quad", get_func_name)
  241. end
  242. allpass1 = make_all_pass(-0.7, 0.7, 1051)
  243. allpass2 = make_all_pass(-0.7, 0.7, 337)
  244. allpass3 = make_all_pass(-0.7, 0.7, 113)
  245. comb1 = make_comb(0.742, 4799)
  246. comb2 = make_comb(0.733, 4999)
  247. comb3 = make_comb(0.715, 5399)
  248. comb4 = make_comb(0.697, 5801)
  249. outdel1 = make_delay((delay1 * @srate).round)
  250. outdel2 = (chan2 ? make_delay((delay2 * @srate).round) : false)
  251. outdel3 = ((chan4 or double) ? make_delay((delay3 * @srate).round) : false)
  252. outdel4 = ((chan4 or (double and chan2)) ?
  253. make_delay((delay4 * @srate).round) : false)
  254. envA = if amp_env
  255. make_env(:envelope, amp_env,
  256. :scaler, volume,
  257. :duration, ws_duration(@revfile) + @decay_time)
  258. else
  259. false
  260. end
  261. comb_sum_1 = comb_sum = 0.0
  262. out_frample = Vct.new(@channels)
  263. run_reverb() do |ho, i|
  264. allpass_sum = all_pass(allpass3, all_pass(allpass2,
  265. all_pass(allpass1, ho)))
  266. comb_sum_2, comb_sum_1 = comb_sum_1, comb_sum
  267. comb_sum = (comb(comb1, allpass_sum) + comb(comb2, allpass_sum) +
  268. comb(comb3, allpass_sum) + comb(comb4, allpass_sum))
  269. all_sums = if low_pass
  270. 0.25 * (comb_sum + comb_sum_2) + 0.5 * comb_sum_1
  271. else
  272. comb_sum
  273. end
  274. delA = delay(outdel1, all_sums)
  275. if double
  276. delA += delay(outdel3, all_sums)
  277. end
  278. if envA
  279. volume = env(envA)
  280. end
  281. out_frample[0] = volume * delA
  282. if chan2
  283. delB = delay(outdel2, all_sums)
  284. if double
  285. delB += delay(outdel4, all_sums)
  286. end
  287. out_frample[1] = volume * delB
  288. if chan4
  289. out_frample[2] = volume * delay(outdel3, all_sums)
  290. out_frample[3] = volume * delay(outdel4, all_sums)
  291. end
  292. end
  293. out_frample
  294. end
  295. end
  296. # v.rb ends here