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