1# clm-ins.rb -- CLM instruments translated to Snd/Ruby 2 3# Translator: Michael Scholz <mi-scholz@users.sourceforge.net> 4# Created: 03/09/16 01:27:09 5# Changed: 14/11/28 02:16:54 6 7# Instruments work with 8# with_sound (CLM (sample2file gens) and Snd) 9# with_dac (dac output, except at least for fullmix) 10# 11# Tested with Snd 15.x and Ruby 2.x.x 12 13# pluck reson 14# vox cellon 15# fofins jl_reverb 16# fm_trumpet gran_synth 17# pqw_vox touch_tone 18# stereo_flute spectra 19# fm_bell two_tab 20# fm_insect lbj_piano 21# fm_drum resflt 22# gong scratch 23# attract pins 24# pqw zc 25# tubebell zn 26# wurley za 27# rhodey clm_expsrc exp_snd 28# hammondoid expfil 29# metal graph_eq 30# drone anoi 31# canter fullmix 32# nrev grani 33# 34# class Ssb_fm < Musgen 35# initialize(freq) 36# inspect 37# to_s 38# run_func(val1, val2) 39# ssb_fm(modsig) 40 41# bes_fm(start, dur, freq, amp, ratio, index) 42# 43# make_ssb_fm(freq) 44# ssb_fm?(obj) 45# ssb_fm(gen, modsig) 46# 47# class Fm2 < Musgen 48# initialize(f1, f2, f3, f4, p1, p2, p3, p4) 49# inspect 50# to_s 51# run_func(val1, val2) 52# fm2(index) 53# 54# make_fm2(f1, f2, f3, f4, p1, p2, p3, p4) 55# fm2?(obj) 56# fm2(gen, index) 57 58# comments from clm-ins.scm 59 60$now = 0.0 61 62require "ws" 63require "spectr" 64require "env" 65include Math 66with_silence do 67 require "matrix" 68end 69 70def normalize_partials(partials) 71 sum = 0.0 72 parts = partials.dup 73 len = parts.length 74 1.step(len - 1, 2) do |i| 75 sum += parts[i].abs 76 end 77 1.step(len - 1, 2) do |i| 78 parts[i] /= sum 79 end 80 parts 81end unless defined? normalize_partials 82 83# violin is defined as an example in ws.rb 84def violin_test(start = 0.0, dur = 1.0) 85 violin(start, dur, 440, 0.5) 86 $now = start + dur + 0.2 87end 88 89require "v" 90 91# fm_violin is defined in v.rb 92def fm_violin_test(start = 0.0, dur = 1.0) 93 fm_violin(start, dur, 440, 0.5) 94 $now = start + dur + 0.2 95end 96 97# PLUCK 98# 99# The Karplus-Strong algorithm as extended by David Jaffe and Julius 100# Smith -- see Jaffe and Smith, "Extensions of the Karplus-Strong 101# Plucked-String Algorithm" CMJ vol 7 no 2 Summer 1983, reprinted in 102# "The Music Machine". translated from CLM's pluck.ins 103add_help(:pluck, 104 "pluck(start, dur, freq, amp, weighting, lossfact) \ 105Implements the Jaffe-Smith plucked string physical model. 106WEIGHTING is the ratio of the once-delayed to the twice-delayed samples. \ 107It defaults to 0.5=shortest decay. 108Anything other than 0.5 = longer decay. \ 109Must be between 0 and less than 1.0. 110LOSSFACT can be used to shorten decays. \ 111Most useful values are between 0.8 and 1.0. pluck(0, 1, 330, 0.3, 0.95, 0.95)") 112def pluck(start, dur, freq, amp, weighting = 0.5, lossfact = 0.9) 113 get_optimum_c = lambda do |s, o, p| 114 pa = (1.0 / o) * atan2(s * sin(o), (1.0 - s) + s * cos(o)) 115 tmp_int = (p - pa).floor 116 pc = p - pa - tmp_int 117 until pc >= 0.1 118 tmp_int -= 1 119 pc += 1.0 120 end 121 [tmp_int, (sin(o) - sin(o * pc)) / sin(o + o * pc)] 122 end 123 tune_it = lambda do |f, s1| 124 p = @srate / f 125 s = s1.zero? ? 0.5 : s1 126 o = hz2radians(f) 127 t1, c1 = get_optimum_c.call(s, o, p) 128 t2, c2 = get_optimum_c.call(1.0 - s, o, p) 129 if s != 0.5 and c1.abs < c2.abs 130 [1.0 - s, c1, t1] 131 else 132 [s, c2, t2] 133 end 134 end 135 wt0, c, dlen = tune_it.call(freq, weighting) 136 lf = lossfact.zero? ? 1.0 : [1.0, lossfact].min 137 wt = wt0.zero? ? 0.5 : [1.0, wt0].min 138 tab = make_vct(dlen) 139 # get initial waveform in "tab" -- here we can introduce 0's to 140 # simulate different pick positions, and so on -- see the CMJ 141 # article for numerous extensions. The normal case is to load it 142 # with white noise (between -1 and 1). 143 allp = make_one_zero(lf * (1.0 - wt), lf * wt) 144 feedb = make_one_zero(c, 1.0) # or feedb = make_one_zero(1.0, c) 145 dlen.times do |i| 146 tab[i] = 1.0 - random(2.0) 147 end 148 run_instrument(start, dur) do 149 val = tab.clm_cycle 150 tab[tab.clm_cycle_index] = (1.0 - c) * one_zero(feedb, one_zero(allp, val)) 151 amp * val 152 end 153end 154 155def pluck_test(start = 0.0, dur = 1.0) 156 pluck(start, dur, 330, 0.3, 0.95, 0.95) 157 $now = start + dur + 0.2 158end 159 160# formant center frequencies for a male speaker (vox and pqw_vox) 161Formants = { 162 :I => [390, 1990, 2550], :E => [530, 1840, 2480], :AE => [660, 1720, 2410], 163 :UH => [520, 1190, 2390], :A => [730, 1090, 2440], :OW => [570, 840, 2410], 164 :U => [440, 1020, 2240], :OO => [300, 870, 2240], :ER => [490, 1350, 1690], 165 :W => [300, 610, 2200], :LL => [380, 880, 2575], :R => [420, 1300, 1600], 166 :Y => [300, 2200, 3065], :EE => [260, 3500, 3800], :LH => [280, 1450, 1600], 167 :L => [300, 1300, 3000], :I2 => [350, 2300, 3340], :B => [200, 800, 1750], 168 :D => [300, 1700, 2600], :G => [250, 1350, 2000], :M => [280, 900, 2200], 169 :N => [280, 1700, 2600], :NG => [280, 2300, 2750], :P => [300, 800, 1750], 170 :T => [200, 1700, 2600], :K => [350, 1350, 2000], :F => [175, 900, 4400], 171 :TH => [200, 1400, 2200], :S => [200, 1300, 2500], :SH => [200, 1800, 2000], 172 :V => [175, 1100, 2400], :THE => [200, 1600, 2200], :Z => [200, 1300, 2500], 173 :ZH => [175, 1800, 2000], :ZZ => [900, 2400, 3800], :VV => [565, 1045, 2400]} 174 175# MLBVOI 176# 177# translation from MUS10 of Marc LeBrun's waveshaping voice instrument 178# (using FM here) this version translated (and simplified slightly) 179# from CLM's mlbvoi.ins 180def vox(start, dur, freq, amp, ampfun, freqfun, freqscl, voxfun, index, vibscl) 181 f1 = [] 182 f2 = [] 183 f3 = [] 184 (voxfun.length - 1).step(1, -2) do |i| 185 phon = Formants[voxfun[i]] 186 x = voxfun[i - 1] 187 f1.unshift(phon[0]) 188 f1.unshift(x) 189 f2.unshift(phon[1]) 190 f2.unshift(x) 191 f3.unshift(phon[2]) 192 f3.unshift(x) 193 end 194 car_os = make_oscil(:frequency, 0) 195 of0 = make_oscil(:frequency, 0) 196 of1 = make_oscil(:frequency, 0) 197 of2 = make_oscil(:frequency, 0) 198 of3 = make_oscil(:frequency, 0) 199 of4 = make_oscil(:frequency, 0) 200 of5 = make_oscil(:frequency, 0) 201 ampf = make_env(:envelope, ampfun, :scaler, amp, :duration, dur) 202 frmf1 = make_env(:envelope, f1, :duration, dur) 203 frmf2 = make_env(:envelope, f2, :duration, dur) 204 frmf3 = make_env(:envelope, f3, :duration, dur) 205 freqf = make_env(:envelope, freqfun, :duration, dur, :scaler, freqscl * freq, :offset, freq) 206 per_vib = make_triangle_wave(:frequency, 6, :amplitude, freq * vibscl) 207 ran_vib = make_rand_interp(:frequency, 20, :amplitude, freq * 0.01) 208 run_instrument(start, dur) do 209 frq = env(freqf) + triangle_wave(per_vib) + rand_interp(ran_vib) 210 car = index * oscil(car_os, hz2radians(frq)) 211 frm = env(frmf1) 212 frm0 = frm / frq.to_f 213 frm_int = frm0.floor 214 if frm_int.even? 215 frq0 = hz2radians(frm_int * frq) 216 frq1 = hz2radians((frm_int + 1) * frq) 217 amp1 = frm0 - frm_int 218 amp0 = 1.0 - amp1 219 else 220 frq1 = hz2radians(frm_int * frq) 221 frq0 = hz2radians((frm_int + 1) * frq) 222 amp0 = frm0 - frm_int 223 amp1 = 1.0 - amp0 224 end 225 frm = env(frmf2) 226 frm0 = frm / frq.to_f 227 frm_int = frm0.floor 228 if frm_int.even? 229 frq2 = hz2radians(frm_int * frq) 230 frq3 = hz2radians((frm_int + 1) * frq) 231 amp3 = frm0 - frm_int 232 amp2 = 1.0 - amp3 233 else 234 frq3 = hz2radians(frm_int * frq) 235 frq2 = hz2radians((frm_int + 1) * frq) 236 amp2 = frm0 - frm_int 237 amp3 = 1.0 - amp2 238 end 239 frm = env(frmf3) 240 frm0 = frm / frq.to_f 241 frm_int = frm0.floor 242 if frm_int.even? 243 frq4 = hz2radians(frm_int * frq) 244 frq5 = hz2radians((frm_int + 1) * frq) 245 amp5 = frm0 - frm_int 246 amp4 = 1.0 - amp5 247 else 248 frq5 = hz2radians(frm_int * frq) 249 frq4 = hz2radians((frm_int + 1) * frq) 250 amp4 = frm0 - frm_int 251 amp5 = 1.0 - amp4 252 end 253 env(ampf) * (0.8 * (amp0 * oscil(of0, frq0 + 0.2 * car) + 254 amp1 * oscil(of1, frq1 + 0.2 * car)) + 255 0.15 * (amp2 * oscil(of2, frq2 + 0.5 * car) + 256 amp3 * oscil(of3, frq3 + 0.5 * car)) + 257 0.05 * (amp4 * oscil(of4, frq4 + car) + 258 amp5 * oscil(of5, frq5 + car))) 259 end 260end 261 262def vox_test(start = 0.0, dur = 1.0) 263 amp_env = [0, 0, 25, 1, 75, 1, 100, 0] 264 frq_env = [0, 0, 5, 0.5, 10, 0, 100, 1] 265 examp1 = [0, :E, 25, :AE, 35, :ER, 65, :ER, 75, :I, 100, :UH] 266 examp2 = [0, :I, 5, :OW, 10, :I, 50, :AE, 100, :OO] 267 268 $now = start 269 vox($now, dur, 170, 0.4, amp_env, frq_env, 0.1, examp1, 0.05, 0.1) 270 $now += dur + 0.2 271 vox($now, dur, 300, 0.4, amp_env, frq_env, 0.1, examp2, 0.02, 0.1) 272 $now += dur + 0.2 273 vox($now, 5, 600, 0.4, amp_env, frq_env, 0.1, examp2, 0.01, 0.1) 274 $now += 5.0 + 0.2 275end 276 277# FOF example 278add_help(:fofins, 279 "fofins(beg, dur, frq, amp, vib, f0, a0, f1, a1, \ 280f2, a2, ae=[0, 0, 25, 1, 75, 1, 100, 0]) \ 281Produces FOF synthesis: \ 282fofins(0, 1, 270, 0.2, 0.001, 730, 0.6, 1090, 0.3, 2440, 0.1)") 283def fofins(start, dur, frq, amp, vib, f0, a0, f1, a1, f2, a2, 284 ae = [0, 0, 25, 1, 75, 1, 100,0]) 285 ampf = make_env(:envelope, ae, :scaler, amp, :duration, dur) 286 frq0 = hz2radians(f0) 287 frq1 = hz2radians(f1) 288 frq2 = hz2radians(f2) 289 foflen = @srate == 22050.0 ? 100 : 200 290 vibr = make_oscil(:frequency, 6) 291 win_freq = TWO_PI / foflen 292 wt0 = make_wave_train(:size, foflen, :frequency, frq) 293 foftab = mus_data(wt0) 294 foflen.times do |i| 295 foftab[i] = (a0 * sin(i * frq0) + a1 * sin(i * frq1) + 296 a2 * sin(i * frq2)) * 0.5 * (1.0 - cos(i * win_freq)) 297 end 298 run_instrument(start, dur) do 299 env(ampf) * wave_train(wt0, vib * oscil(vibr)) 300 end 301end 302 303def fofins_test(start = 0.0, dur = 1.0) 304 fofins(start, dur, 270, 0.2, 0.001, 730, 0.6, 1090, 0.3, 2440, 0.1) 305 $now = start + dur + 0.2 306end 307 308# FM TRUMPET 309# 310# Dexter Morrill's FM-trumpet: from CMJ feb 77 p51 311def fm_trumpet(start, dur, *args) 312 frq1, frq2, amp1, amp2, ampatt1, ampdec1, ampatt2, ampdec2 = nil 313 modfrq1, modind11, modind12, modfrq2, modind21, modind22 = nil 314 rvibamp, rvibfrq, vibamp, vibfrq, vibatt, vibdec = nil 315 frqskw, frqatt, ampenv1, ampenv2 = nil 316 indenv1, indenv2, degree, distance, reverb_amount = nil 317 optkey(args, binding, 318 [:frq1, 250.0], 319 [:frq2, 1500.0], 320 [:amp1, 0.5], 321 [:amp2, 0.1], 322 [:ampatt1, 0.03], 323 [:ampdec1, 0.35], 324 [:ampatt2, 0.03], 325 [:ampdec2, 0.3], 326 [:modfrq1, 250.0], 327 [:modind11, 0.0], 328 [:modind12, 2.66], 329 [:modfrq2, 250.0], 330 [:modind21, 0.0], 331 [:modind22, 1.8], 332 [:rvibamp, 0.007], 333 [:rvibfrq, 125.0], 334 [:vibamp, 0.007], 335 [:vibfrq, 7.0], 336 [:vibatt, 0.6], 337 [:vibdec, 0.2], 338 [:frqskw, 0.03], 339 [:frqatt, 0.06], 340 [:ampenv1, [0, 0, 25, 1, 75, 0.9, 100, 0]], 341 [:ampenv2, [0, 0, 25, 1, 75, 0.9, 100, 0]], 342 [:indenv1, [0, 0, 25, 1, 75, 0.9, 100, 0]], 343 [:indenv2, [0, 0, 25, 1, 75, 0.9, 100, 0]], 344 [:degree, 0.0], 345 [:distance, 1.0], 346 [:reverb_amount, 0.005]) 347 dur = dur.to_f 348 per_vib_f = make_env(:envelope, 349 stretch_envelope([0, 1, 25, 0.1, 75, 0, 100, 0], 350 25, 351 [100 * (vibatt / dur), 45].min, 352 75, 353 [100 * (1.0 - vibdec / dur), 55].max), 354 :scaler, vibamp, :duration, dur) 355 356 ran_vib = make_rand_interp(:frequency, rvibfrq, :amplitude, rvibamp) 357 per_vib = make_oscil(:frequency, vibfrq) 358 dec_01 = [75, 100 * (1.0 - 0.01 / dur)].max 359 frq_f = make_env(:envelope, 360 stretch_envelope([0, 0, 25, 1, 75, 1, 100, 0], 361 25, 362 [25, 100 * (frqatt / dur)].min, 363 75, 364 dec_01), 365 :scaler, frqskw, :duration, dur) 366 ampattpt1 = [25, 100 * (ampatt1 / dur)].min 367 ampdecpt1 = [75, 100 * (1.0 - ampdec1 / dur)].max 368 ampattpt2 = [25, 100 * (ampatt2 / dur)].min 369 ampdecpt2 = [75, 100 * (1.0 - ampdec2 / dur)].max 370 mod1_f = make_env(:envelope, 371 stretch_envelope(indenv1, 25, ampattpt1, 75, dec_01), 372 :scaler, modfrq1 * (modind12 - modind11), :duration, dur) 373 mod1 = make_oscil(:frequency, 0.0) 374 car1 = make_oscil(:frequency, 0.0) 375 # set frequency to zero here because it is handled multiplicatively below 376 car1_f = make_env(:envelope, 377 stretch_envelope(ampenv1, 25, ampattpt1, 75, ampdecpt1), 378 :scaler, amp1, :duration, dur) 379 mod2_f = make_env(:envelope, 380 stretch_envelope(indenv2, 25, ampattpt2, 75, dec_01), 381 :scaler, modfrq2 * (modind22 - modind21), :duration, dur) 382 mod2 = make_oscil(:frequency, 0.0) 383 car2 = make_oscil(:frequency, 0.0) 384 car2_f = make_env(:envelope, 385 stretch_envelope(ampenv2, 25, ampattpt2, 75, ampdecpt2), 386 :scaler, amp2, :duration, dur) 387 run_instrument(start, dur, 388 :degree, degree, 389 :distance, distance, 390 :reverb_amount, reverb_amount) do 391 frq_change = hz2radians((1.0 + 392 rand_interp(ran_vib)) * 393 (1.0 + env(per_vib_f) * 394 oscil(per_vib)) * 395 (1.0 + env(frq_f))) 396 env(car1_f) * 397 oscil(car1, frq_change * 398 (frq1 + env(mod1_f) * oscil(mod1, modfrq1 * frq_change))) + 399 env(car2_f) * 400 oscil(car2, frq_change * 401 (frq2 + env(mod2_f) * oscil(mod2, modfrq2 * frq_change))) 402 end 403end 404 405def fm_trumpet_test(start = 0.0, dur = 1.0) 406 fm_trumpet(start, dur) 407 $now = start + dur + 0.2 408end 409 410# PQWVOX 411# 412# translation of CLM pqwvox.ins (itself translated from MUS10 of MLB's 413# waveshaping voice instrument (using phase quadrature waveshaping)) 414add_help(:pqw_vox, 415 "pqw_vox(start, dur, freq, spacing_freq, \ 416amp, ampfun, freqfun, freqscl, phonemes, formant_amps, formant_shapes) \ 417Produces vocal sounds using phase quadrature waveshaping.") 418def pqw_vox(start, dur, freq, spacing_freq, amp, ampfun, freqfun, freqscl, 419 phonemes, formant_amps, formant_shapes) 420 vox_fun = lambda do |phons, which, newenv| 421 # make an envelope from which entry of phoneme data referred to by phons 422 if phons.empty? 423 newenv 424 else 425 vox_fun.call(phons[2..-1], 426 which, newenv + [phons[0], Formants[phons[1]][which]]) 427 end 428 end 429 car_sin = make_oscil(:frequency, 0.0) 430 car_cos = make_oscil(:frequency, 0.0, :initial_phase, HALF_PI) 431 frq_ratio = spacing_freq / freq.to_f 432 fs = formant_amps.length 433 sin_evens = Array.new(fs) 434 cos_evens = Array.new(fs) 435 sin_odds = Array.new(fs) 436 cos_odds = Array.new(fs) 437 amps = Array.new(fs) 438 frmfs = Array.new(fs) 439 sin_coeffs = Array.new(fs) 440 cos_coeffs = Array.new(fs) 441 ampf = make_env(:envelope, ampfun, :scaler, amp, :duration, dur) 442 freqf = make_env(:envelope, freqfun, :scaler, freqscl * freq, 443 :duration, dur, :offset, freq) 444 per_vib = make_triangle_wave(:frequency, 6.0, :amplitude, freq * 0.1) 445 ran_vib = make_rand_interp(:frequency, 20.0, :amplitude, freq * 0.05) 446 fs.times do |i| 447 sin_evens[i] = make_oscil(:frequency, 0.0) 448 sin_odds[i] = make_oscil(:frequency, 0.0) 449 cos_evens[i] = make_oscil(:frequency, 0.0, :initial_phase, HALF_PI) 450 cos_odds[i] = make_oscil(:frequency, 0.0, :initial_phase, HALF_PI) 451 amps[i] = formant_amps[i] 452 shape = normalize_partials(formant_shapes[i]) 453 cos_coeffs[i] = partials2polynomial(shape, 1) 454 sin_coeffs[i] = partials2polynomial(shape, 0) 455 frmfs[i] = make_env(:envelope, vox_fun.call(phonemes, i, []), 456 :duration, dur) 457 end 458 run_instrument(start, dur) do 459 frq = env(freqf) + triangle_wave(per_vib) + rand_interp(ran_vib) 460 frqscl = hz2radians(frq * frq_ratio) 461 carsin = oscil(car_sin, frqscl) 462 carcos = oscil(car_cos, frqscl) 463 sum = 0.0 464 fs.times do |j| 465 frm = env(frmfs[j]) 466 frm0 = frm / frq 467 frm_int = frm0.floor 468 if frm_int.even? 469 even_freq = hz2radians(frm_int * frq) 470 odd_freq = hz2radians((frm_int + 1.0) * frq) 471 odd_amp = frm0 - frm_int 472 even_amp = 1.0 - odd_amp 473 else 474 odd_freq = hz2radians(frm_int * frq) 475 even_freq = hz2radians((frm_int + 1.0) * frq) 476 even_amp = frm0 - frm_int 477 odd_amp = 1.0 - even_amp 478 end 479 fax = polynomial(cos_coeffs[j], carcos) 480 yfax = carsin * polynomial(sin_coeffs[j], carcos) 481 sum = sum + amps[j] * 482 (even_amp * (yfax * oscil(sin_evens[j], even_freq) - 483 fax * oscil(cos_evens[j], even_freq)) + 484 odd_amp * (yfax * oscil(sin_odds[j], odd_freq) - 485 fax * oscil(cos_odds[j], odd_freq))) 486 end 487 env(ampf) * sum 488 end 489end 490 491def pqw_vox_test(start = 0.0, dur = 1.0) 492 ampfun = [0, 0, 50, 1, 100, 0] 493 freqfun = [0, 0, 100, 0] 494 freqramp = [0, 0, 100, 1] 495 sh1 = [[1, 1, 2, 0.5], 496 [1, 0.5, 2, 0.5, 3, 1], 497 [1, 1, 4, 0.5]] 498 sh2 = [[1, 1, 2, 0.5], 499 [1, 1, 2, 0.5, 3, 0.2, 4, 0.1], 500 [1, 1, 3, 0.1, 4, 0.5]] 501 sh3 = [[1, 1, 2, 0.5], 502 [1, 1, 4, 0.1], 503 [1, 1, 2, 0.1, 4, 0.05]] 504 sh4 = [[1, 1, 2, 0.5, 3, 0.1, 4, 0.01], 505 [1, 1, 4, 0.1], 506 [1, 1, 2, 0.1, 4, 0.05]] 507 508 $now = start 509 pqw_vox($now, dur, 300, 300, 0.5, ampfun, freqfun, 0.0, 510 [0, :L, 100, :L], [0.33, 0.33, 0.33], sh1) 511 $now += dur + 0.2 512 pqw_vox($now, dur, 200, 200, 0.1, ampfun, freqramp, 0.1, 513 [0, :UH, 100, :ER], [0.8, 0.15, 0.05], sh2) 514 $now += dur + 0.2 515 pqw_vox($now, dur, 100, 314, 0.1, ampfun, freqramp, 0.1, 516 [0, :UH, 100, :ER], [0.8, 0.15, 0.05], sh2) 517 $now += dur + 0.2 518 pqw_vox($now, dur, 200, 314, 0.1, ampfun, freqramp, 0.01, 519 [0, :UH, 100, :ER], [0.8, 0.15, 0.05], sh3) 520 $now += dur + 0.2 521 pqw_vox($now, dur, 100, 414, 0.2, ampfun, freqramp, 0.01, 522 [0, :OW, 50, :E, 100, :ER], [0.8, 0.15, 0.05], sh4) 523 $now += dur + 0.2 524end 525 526# STEREO-FLUTE 527# slightly simplified [MS] 528add_help(:stereo_flute, 529 "stereo_flute(start, dur, freq, flow, *key_args) 530 :flow_envelope = [0, 1, 100, 1] 531 :decay = 0.01 532 :noise = 0.0356 533 :embouchure_size = 0.5 534 :fbk_scl1 = 0.5 535 :fbk_scl2 = 0.55 536 :out_scl = 1.0 537 :a0 = 0.7 538 :b1 = -0.3 539 :vib_rate = 5 540 :vib_amount = 0.03 541 :ran_rate = 5 542 :ran_amount = 0.03 543is a physical model of a flute: \ 544stereo_flute(0, 1, 440, 0.55, :flow_envelope, [0, 0, 1, 1, 2, 1, 3, 0])") 545def stereo_flute(start, dur, freq, flow, *args) 546 flow_envelope, decay, noise, embouchure_size = nil 547 fbk_scl1, fbk_scl2, out_scl = nil 548 a0, b1, vib_rate, vib_amount, ran_rate, ran_amount = nil 549 optkey(args, binding, 550 [:flow_envelope, [0, 1, 100, 1]], 551 [:decay, 0.01], # additional time for instrument to decay 552 [:noise, 0.0356], 553 [:embouchure_size, 0.5], 554 [:fbk_scl1, 0.5], # these two are crucial for good results 555 [:fbk_scl2, 0.55], 556 [:out_scl, 1.0], 557 [:a0, 0.7], # filter coefficients 558 [:b1, -0.3], 559 [:vib_rate, 5], 560 [:vib_amount, 0.03], 561 [:ran_rate, 5], 562 [:ran_amount, 0.03]) 563 flowf = make_env(:envelope, flow_envelope, :scaler, flow, 564 :length, seconds2samples(dur - decay)) 565 periodic_vib = make_oscil(:frequency, vib_rate) 566 ran_vib = make_rand_interp(:frequency, ran_rate) 567 breath = make_rand(:frequency, @srate / 2.0, :amplitude, 1) 568 period_samples = (@srate / freq).floor 569 embouchure_samples = (embouchure_size * period_samples).floor 570 embouchure = make_delay(embouchure_samples, :initial_element, 0.0) 571 bore = make_delay(period_samples) 572 reflection_lp_filter = make_one_pole(a0, b1) 573 out_sig = current_diff = previous_out_sig = previous_dc_blocked_a = 0.0 574 run_instrument(start, dur) do 575 delay_sig = delay(bore, out_sig) 576 emb_sig = delay(embouchure, current_diff) 577 current_flow = vib_amount * oscil(periodic_vib) + 578 ran_amount * rand_interp(ran_vib) + env(flowf) 579 current_diff = (current_flow + noise * current_flow * rand(breath)) + 580 fbk_scl1 * delay_sig 581 current_exitation = emb_sig - emb_sig * emb_sig * emb_sig 582 out_sig = one_pole(reflection_lp_filter, 583 current_exitation + fbk_scl2 * delay_sig) 584 # NB the DC blocker is not in the cicuit. It is applied to the 585 # out_sig but the result is not fed back into the system. 586 dc_blocked_a = (out_sig - previous_out_sig) + 0.995 * previous_dc_blocked_a 587 previous_out_sig = out_sig 588 previous_dc_blocked_a = dc_blocked_a 589 out_scl * dc_blocked_a 590 end 591end 592 593def flute_test(start = 0.0, dur = 1.0) 594 stereo_flute(start, dur, 440, 0.55, :flow_envelope, [0, 0, 1, 1, 2, 1, 3, 0]) 595 $now = start + dur + 0.2 596end 597 598# FM-BELL 599add_help(:fm_bell, 600 "fm_bell(startime, dur, frequency, amplitude, \ 601amp-env=[...], index_env=[...], index=1.0) \ 602Mixes in one fm bell note." ) 603def fm_bell(start, dur, freq, amp, 604 amp_env = [0, 0, 0.1, 1, 10, 0.6, 25, 0.3, 605 50, 0.15, 90, 0.1, 100, 0], 606 index_env = [0, 1, 2, 1.1, 25, 0.75, 75, 0.5, 100, 0.2], 607 index = 1.0) 608 fm_ind1 = hz2radians(32.0 * freq) 609 fm_ind2 = hz2radians(4.0 * (8.0 - freq / 50.0)) 610 fm_ind3 = fm_ind2 * 0.705 * (1.4 - freq / 250.0) 611 fm_ind4 = hz2radians(32.0 * (20.0 - freq / 20.0)) 612 mod1 = make_oscil(:frequency, freq * 2.0) 613 mod2 = make_oscil(:frequency, freq * 1.41) 614 mod3 = make_oscil(:frequency, freq * 2.82) 615 mod4 = make_oscil(:frequency, freq * 2.4) 616 car1 = make_oscil(:frequency, freq) 617 car2 = make_oscil(:frequency, freq) 618 car3 = make_oscil(:frequency, freq * 2.4) 619 indf = make_env(:envelope, index_env, :scaler, index, :duration, dur) 620 ampf = make_env(:envelope, amp_env, :scaler, amp, :duration, dur) 621 run_instrument(start, dur) do 622 fmenv = env(indf) 623 env(ampf) * 624 (oscil(car1, fmenv * fm_ind1 * oscil(mod1)) + 625 0.15 * 626 oscil(car2, fmenv * (fm_ind2 * oscil(mod2) + fm_ind3 * oscil(mod3))) + 627 0.15 * 628 oscil(car3, fmenv * fm_ind4 * oscil(mod4))) 629 end 630end 631 632def fm_bell_test(start = 0.0, dur = 1.0) 633 fm_bell(start, dur, 440, 0.5) 634 $now = start + dur + 0.2 635end 636 637# FM-INSECT 638def fm_insect(start, dur, freq, amp, amp_env, 639 mod_freq, mod_skew, mod_freq_env, mod_index, mod_index_env, 640 fm_index, fm_ratio, *args) 641 degree, distance, reverb_amount = nil 642 optkey(args, binding, 643 [:degree, 0.0], 644 [:distance, 1.0], 645 [:reverb_amount, 0.005]) 646 carrier = make_oscil(:frequency, freq) 647 fm1_osc = make_oscil(:frequency, mod_freq) 648 fm2_osc = make_oscil(:frequency, fm_ratio * freq) 649 ampf = make_env(:envelope, amp_env, :scaler, amp, :duration, dur) 650 indf = make_env(:envelope, mod_index_env, 651 :scaler, hz2radians(mod_index), 652 :duration, dur) 653 modfrqf = make_env(:envelope, mod_freq_env, 654 :scaler, hz2radians(mod_skew), 655 :duration, dur) 656 fm2_amp = hz2radians(fm_index * fm_ratio * freq) 657 run_instrument(start, dur, 658 :degree, degree, 659 :distance, distance, 660 :reverb_amount, reverb_amount) do 661 garble_in = env(indf) * oscil(fm1_osc, env(modfrqf)) 662 garble_out = fm2_amp * oscil(fm2_osc, garble_in) 663 env(ampf) * oscil(carrier, garble_out + garble_in) 664 end 665end 666 667def fm_insect_test(start = 0.0, dur = 1.0) 668 locust = [0, 0, 40, 1, 95, 1, 100, 0.5] 669 bug_hi = [0, 1, 25, 0.7, 75, 0.78, 100, 1] 670 amp = [0, 0, 25, 1, 75, 0.7, 100, 0] 671 672 $now = start 673 fm_insect($now + 0.000, 1.699, 4142.627, 0.015, amp, 60, -16.707, 674 locust, 500.866, bug_hi, 0.346, 0.5) 675 fm_insect($now + 0.195, 0.233, 4126.284, 0.030, amp, 60, -12.142, 676 locust, 649.490, bug_hi, 0.407, 0.5) 677 fm_insect($now + 0.217, 2.057, 3930.258, 0.045, amp, 60, -3.011, 678 locust, 562.087, bug_hi, 0.591, 0.5) 679 fm_insect($now + 2.100, 1.500, 900.627, 0.060, amp, 40, -16.707, 680 locust, 300.866, bug_hi, 0.346, 0.5) 681 fm_insect($now + 3.000, 1.500, 900.627, 0.060, amp, 40, -16.707, 682 locust, 300.866, bug_hi, 0.046, 0.5) 683 fm_insect($now + 3.450, 1.500, 900.627, 0.090, amp, 40, -16.707, 684 locust, 300.866, bug_hi, 0.006, 0.5) 685 fm_insect($now + 3.950, 1.500, 900.627, 0.120, amp, 40, -10.707, 686 locust, 300.866, bug_hi, 0.346, 0.5) 687 fm_insect($now + 4.300, 1.500, 900.627, 0.090, amp, 40, -20.707, 688 locust, 300.866, bug_hi, 0.246, 0.5) 689 $now += 6.0 690end 691 692# FM-DRUM 693# 694# Jan Mattox's fm drum: 695def fm_drum(start, dur, freq, amp, index, high = false, 696 degree = 0.0, distance = 1.0, rev_amount = 0.01) 697 casrat = high ? 8.525 : 3.515 698 fmrat = high ? 3.414 : 1.414 699 glsf = make_env(:envelope, [0, 0, 25, 0, 75, 1, 100, 1], 700 :scaler, high ? hz2radians(66) : 0.0, :duration, dur) 701 ampfun = [0, 0, 3, 0.05, 5, 0.2, 7, 0.8, 8, 0.95, 702 10, 1.0, 12, 0.95, 20, 0.3, 30, 0.1, 100, 0] 703 atdrpt = 100 * (high ? 0.01 : 0.015) / dur 704 ampf = make_env(:envelope, 705 stretch_envelope(ampfun, 10, atdrpt, 15, 706 [atdrpt + 1, 707 100 - 100 * ((dur - 0.2) / dur)].max), 708 :scaler, amp, :duration, dur) 709 indxfun = [0, 0, 5, 0.014, 10, 0.033, 15, 0.061, 20, 0.099, 710 25, 0.153, 30, 0.228, 35, 0.332, 40, 0.477, 711 45, 0.681, 50, 0.964, 55, 0.681, 60, 0.478, 65, 0.332, 712 70, 0.228, 75, 0.153, 80, 0.099, 85, 0.061, 713 90, 0.033, 95, 0.0141, 100, 0] 714 indxpt = 100 - 100 * ((dur - 0.1) / dur) 715 divindxf = stretch_envelope(indxfun, 50, atdrpt, 65, indxpt) 716 indxf = make_env(:envelope, divindxf, :duration, dur, 717 :scaler, [hz2radians(index * fmrat * freq), PI].min) 718 mindxf = make_env(:envelope, divindxf, :duration, dur, 719 :scaler, [hz2radians(index * casrat * freq), PI].min) 720 devf = make_env(:envelope, 721 stretch_envelope(ampfun, 10, atdrpt, 90, 722 [atdrpt + 1, 723 100 - 100 * ((dur - 0.05) / dur)].max), 724 :scaler, [hz2radians(7000), PI].min, :duration, dur) 725 rn = make_rand(:frequency, 7000, :amplitude, 1) 726 carrier = make_oscil(:frequency, freq) 727 fmosc = make_oscil(:frequency, freq * fmrat) 728 cascade = make_oscil(:frequency, freq * casrat) 729 run_instrument(start, dur, 730 :degree, degree, 731 :distance, distance, 732 :reverb_amount, rev_amount) do 733 gls = env(glsf) 734 env(ampf) * 735 oscil(carrier, 736 gls + 737 env(indxf) * 738 oscil(fmosc, 739 gls * fmrat + 740 env(mindxf) * oscil(cascade, 741 gls * casrat + 742 env(devf) * rand(rn)))) 743 end 744end 745 746def fm_drum_test(start = 0.0, dur = 1.0) 747 $now = start 748 fm_drum($now, dur, 55, 0.3, 5, false) 749 $now += dur + 0.2 750 fm_drum($now, dur, 66, 0.3, 4, true) 751 $now += dur + 0.2 752end 753 754# FM-GONG 755# 756# Paul Weineke's gong. 757def gong(start, dur, freq, amp, *args) 758 degree, distance, reverb_amount = nil 759 optkey(args, binding, 760 [:degree, 0.0], 761 [:distance, 1.0], 762 [:reverb_amount, 0.005]) 763 mfq1 = freq * 1.16 764 mfq2 = freq * 3.14 765 mfq3 = freq * 1.005 766 indx01 = hz2radians(0.01 * mfq1) 767 indx11 = hz2radians(0.30 * mfq1) 768 indx02 = hz2radians(0.01 * mfq2) 769 indx12 = hz2radians(0.38 * mfq2) 770 indx03 = hz2radians(0.01 * mfq3) 771 indx13 = hz2radians(0.50 * mfq3) 772 atpt = 5 773 atdur = 100 * (0.002 / dur) 774 expf = [0, 0, 3, 1, 15, 0.5, 27, 0.25, 50, 0.1, 100, 0] 775 rise = [0, 0, 15, 0.3, 30, 1.0, 75, 0.5, 100, 0] 776 fmup = [0, 0, 75, 1.0, 98, 1.0, 100, 0] 777 fmdwn = [0, 0, 2, 1.0, 100, 0] 778 ampfun = make_env(:envelope, stretch_envelope(expf, atpt, atdur), 779 :scaler, amp, :duration, dur) 780 indxfun1 = make_env(:envelope, fmup, :scaler, indx11 - indx01, 781 :duration, dur, :offset, indx01) 782 indxfun2 = make_env(:envelope, fmdwn, :scaler, indx12 - indx02, 783 :duration, dur, :offset, indx02) 784 indxfun3 = make_env(:envelope, rise, :scaler, indx13 - indx03, 785 :duration, dur, :offset, indx03) 786 carrier = make_oscil(:frequency, freq) 787 mod1 = make_oscil(:frequency, mfq1) 788 mod2 = make_oscil(:frequency, mfq2) 789 mod3 = make_oscil(:frequency, mfq3) 790 run_instrument(start, dur, 791 :degree, degree, 792 :distance, distance, 793 :reverb_amount, reverb_amount) do 794 env(ampfun) * 795 oscil(carrier, 796 env(indxfun1) * oscil(mod1) + 797 env(indxfun2) * oscil(mod2) + 798 env(indxfun3) * oscil(mod3)) 799 end 800end 801 802def gong_test(start = 0.0, dur = 1.0) 803 gong(start, dur, 261.61, 0.6) 804 $now = start + dur + 0.2 805end 806 807# ATTRACT 808# 809# by James McCartney, from CMJ vol 21 no 3 p 6 810def attract(start, dur, amp, c) 811 a = b = 0.2 812 dt = 0.04 813 scale = (0.5 * amp) / c 814 x = -1.0 815 y = z = 0.0 816 run_instrument(start, dur) do 817 x1 = x - dt * (y + z) 818 y = y + dt * (x + a * y) 819 z = z + dt * ((b + x * z) - c * z) 820 x = x1 821 scale * x 822 end 823end 824 825def attract_test(start = 0.0, dur = 1.0) 826 attract(start, dur, 0.5, 2.0) 827 $now = start + dur + 0.2 828end 829 830# PQW 831# 832# phase-quadrature waveshaping used to create asymmetric (i.e. single 833# side-band) spectra. The basic idea here is a variant of sin x sin y 834# - cos x cos y = cos (x + y) 835def pqw(start, dur, spacing_freq, carrier_freq, 836 amp, ampfun, indexfun, partials, *args) 837 degree, distance, reverb_amount = nil 838 optkey(args, binding, 839 [:degree, 0.0], 840 [:distance, 1.0], 841 [:reverb_amount, 0.005]) 842 normalized_partials = normalize_partials(partials) 843 spacing_cos = make_oscil(:frequency, spacing_freq, :initial_phase, HALF_PI) 844 spacing_sin = make_oscil(:frequency, spacing_freq) 845 carrier_cos = make_oscil(:frequency, carrier_freq, :initial_phase, HALF_PI) 846 carrier_sin = make_oscil(:frequency, carrier_freq) 847 sin_coeffs = partials2polynomial(normalized_partials, 0) 848 cos_coeffs = partials2polynomial(normalized_partials, 1) 849 amp_env = make_env(:envelope, ampfun, :scaler, amp, :duration, dur) 850 ind_env = make_env(:envelope, indexfun, :duration, dur) 851 r = carrier_freq / spacing_freq.to_f 852 tr = make_triangle_wave(:frequency, 5, 853 :amplitude, hz2radians(0.005 * spacing_freq)) 854 rn = make_rand_interp(:frequency, 12, 855 :amplitude, hz2radians(0.005 * spacing_freq)) 856 run_instrument(start, dur, 857 :degree, degree, 858 :distance, distance, 859 :reverb_amount, reverb_amount) do 860 vib = triangle_wave(tr) + rand_interp(rn) 861 ax = [1.0, env(ind_env)].min * oscil(spacing_cos, vib) 862 fax = polynomial(cos_coeffs, ax) 863 yfax = oscil(spacing_sin, vib) * polynomial(sin_coeffs, ax) 864 env(amp_env) * 865 (oscil(carrier_sin, vib * r) * yfax - 866 oscil(carrier_cos, vib * r) * fax) 867 end 868end 869 870def pqw_test(start = 0.0, dur = 1.0) 871 pqw(start, dur, 200, 1000, 0.2, 872 [0, 0, 25, 1, 100, 0], [0, 1, 100, 0], [2, 0.1, 3, 0.3, 6, 0.5]) 873 $now = start + dur + 0.2 874 # to see the asymmetric spectrum most clearly, set the index function 875 # above to [0, 1, 100, 1] 876end 877 878# taken from Perry Cook's stkv1.tar.Z (Synthesis Toolkit), but I was 879# in a bit of a hurry and may not have made slavishly accurate 880# translations. Please let me (bil@ccrma.stanford.edu) know of any 881# serious (non-envelope) errors. 882# 883# from Perry Cook's TubeBell.cpp 884def tubebell(start, dur, freq, amp, base = 32.0) 885 osc0 = make_oscil(freq * 0.995) 886 osc1 = make_oscil(freq * 0.995 * 1.414) 887 osc2 = make_oscil(freq * 1.005) 888 osc3 = make_oscil(freq * 1.414) 889 ampenv1 = make_env(:envelope, [0, 0, 0.005, 1, dur, 0], 890 :base, base, :duration, dur) 891 ampenv2 = make_env(:envelope, [0, 0, 0.001, 1, dur, 0], 892 :base, 2 * base, :duration, dur) 893 ampmod = make_oscil(:frequency, 2.0) 894 g0 = 0.5 * amp * 0.707 895 g1 = 0.203 896 g2 = 0.5 * amp 897 g3 = 0.144 898 run_instrument(start, dur) do 899 (0.007 * 900 oscil(ampmod) + 0.993) * 901 (g0 * env(ampenv1) * oscil(osc0, g1 * oscil(osc1)) + 902 g2 * env(ampenv2) * oscil(osc2, g3 * oscil(osc3))) 903 end 904end 905 906def tubebell_test(start = 0.0, dur = 1.0) 907 tubebell(start, dur, 440, 0.2, 32) 908 $now = start + dur + 0.2 909end 910 911# from Perry Cook's Wurley.cpp 912def wurley(start, dur, freq, amp) 913 osc0 = make_oscil(freq) 914 osc1 = make_oscil(freq * 4.0) 915 osc2 = make_oscil(510.0) 916 osc3 = make_oscil(510.0) 917 ampmod = make_oscil(:frequency, 8.0) 918 g0 = 0.5 * amp 919 g1 = 0.307 920 g2 = 0.5 * amp * 0.307 921 g3 = 0.117 922 dur = [dur, 0.3].max 923 ampenv = make_env(:envelope, [0, 0, 1, 1, 9, 1, 10, 0], :duration, dur) 924 indenv = make_env(:envelope, [0, 0, 0.001, 1, 0.15, 0, dur, 0], 925 :duration, dur) 926 resenv = make_env(:envelope, [0, 0, 0.001, 1, 0.25, 0, dur, 0], 927 :duration, dur) 928 run_instrument(start, dur) do 929 env(ampenv) * 930 (1.0 + 0.007 * oscil(ampmod)) * 931 (g0 * oscil(osc0, g1 * oscil(osc1)) + 932 env(resenv) * g2 * oscil(osc2, g3 * env(indenv) * oscil(osc3))) 933 end 934end 935 936def wurley_test(start = 0.0, dur = 1.0) 937 wurley(start, dur, 440, 0.2) 938 $now = start + dur + 0.2 939end 940 941# from Perry Cook's Rhodey.cpp 942def rhodey(start, dur, freq, amp, base = 0.5) 943 osc0 = make_oscil(freq) 944 osc1 = make_oscil(freq * 0.5) 945 osc2 = make_oscil(freq) 946 osc3 = make_oscil(freq * 15.0) 947 dur = [dur, 0.3].max 948 ampenv1 = make_env(:envelope, [0, 0, 0.005, 1, dur, 0], 949 :base, base, :duration, dur) 950 ampenv2 = make_env(:envelope, [0, 0, 0.001, 1, dur, 0], 951 :base, base * 1.5, :duration, dur) 952 ampenv3 = make_env(:envelope, [0, 0, 0.001, 1, 0.25, 0, dur, 0], 953 :base, base * 4, :duration, dur) 954 g0 = 0.5 * amp 955 g1 = 0.535 956 g2 = 0.5 * amp 957 g3 = 0.109 958 run_instrument(start, dur) do 959 g0 * env(ampenv1) * oscil(osc0, g1 * oscil(osc1)) + 960 g2 * env(ampenv2) * oscil(osc2, env(ampenv3) * g3 * oscil(osc3)) 961 end 962end 963 964def rhodey_test(start = 0.0, dur = 1.0) 965 rhodey(start, dur, 440, 0.2, 0.5) 966 $now = start + dur + 0.2 967end 968 969# from Perry Cook's BeeThree.cpp 970def hammondoid(start, dur, freq, amp) 971 osc0 = make_oscil(freq * 0.999) 972 osc1 = make_oscil(freq * 1.997) 973 osc2 = make_oscil(freq * 3.006) 974 osc3 = make_oscil(freq * 6.009) 975 dur = [dur, 0.1].max 976 ampenv1 = make_env(:envelope, [0, 0, 0.005, 1, dur - 0.008, 1, dur, 0], 977 :duration, dur) 978 ampenv2 = make_env(:envelope, [0, 0, 0.005, 1, dur, 0], :duration, dur) 979 g0 = 0.25 * 0.75 * amp 980 g1 = 0.25 * 0.75 * amp 981 g2 = 0.5 * amp 982 g3 = 0.5 * 0.75 * amp 983 run_instrument(start, dur) do 984 env(ampenv1) * 985 (g0 * oscil(osc0) + 986 g1 * oscil(osc1) + 987 g2 * oscil(osc2)) + 988 env(ampenv2) * g3 * oscil(osc3) 989 end 990end 991 992def hammondoid_test(start = 0.0, dur = 1.0) 993 hammondoid(start, dur, 440, 0.2) 994 $now = start + dur + 0.2 995end 996 997# from Perry Cook's HeavyMtl.cpp 998def metal(start, dur, freq, amp) 999 osc0 = make_oscil(freq) 1000 osc1 = make_oscil(freq * 4.0 * 0.999) 1001 osc2 = make_oscil(freq * 3.0 * 1.001) 1002 osc3 = make_oscil(freq * 0.5 * 1.002) 1003 dur = [dur, 0.1].max 1004 ampenv0 = make_env(:envelope, [0, 0, 0.001, 1, dur - 0.002, 1, dur, 0], 1005 :duration, dur) 1006 ampenv1 = make_env(:envelope, [0, 0, 0.001, 1, dur - 0.011, 1, dur, 0], 1007 :duration, dur) 1008 ampenv2 = make_env(:envelope, [0, 0, 0.01, 1, dur - 0.015, 1, dur, 0], 1009 :duration, dur) 1010 ampenv3 = make_env(:envelope, [0, 0, 0.03, 1, dur - 0.04, 1, dur, 0], 1011 :duration, dur) 1012 g0 = 0.615 * amp 1013 g1 = 0.202 1014 g2 = 0.574 1015 g3 = 0.116 1016 run_instrument(start, dur) do 1017 g0 * 1018 env(ampenv0) * 1019 oscil(osc0, 1020 g1 * env(ampenv1) * oscil(osc1, g2 * env(ampenv2) * oscil(osc2)) + 1021 g3 * env(ampenv3) * oscil(osc3)) 1022 end 1023end 1024 1025def metal_test(start = 0.0, dur = 1.0) 1026 metal(start, dur, 440, 0.2) 1027 $now = start + dur + 0.2 1028end 1029 1030# DRONE 1031def drone(start, dur, freq, amp, ampfun, synth, 1032 ampat, ampdc, amtrev, deg, dis, rvibamt, rvibfreq) 1033 waveform = partials2wave(synth) 1034 amp *= 0.25 1035 s = make_table_lookup(:frequency, freq, :wave, waveform) 1036 amp_env = make_env(:envelope, 1037 stretch_envelope(ampfun, 25, 100 * (ampat / dur.to_f), 75, 1038 100 - 100 * (ampdc / dur.to_f)), 1039 :scaler, amp, :duration, dur) 1040 ran_vib = make_rand(:frequency, rvibfreq, 1041 :amplitude, hz2radians(rvibamt * freq)) 1042 run_instrument(start, dur, 1043 :distance, dis, 1044 :degree, deg, 1045 :reverb_amount, amtrev) do 1046 env(amp_env) * table_lookup(s, rand(ran_vib).abs) 1047 end 1048end 1049 1050# CANTER 1051def canter(start, dur, pitch, amp, deg, dis, pcrev, 1052 ampfun, ranfun, skewfun, skewpc, 1053 ranpc, ranfreq, indexfun, atdr, dcdr, 1054 ampfun1, indfun1, fmtfun1, 1055 ampfun2, indfun2, fmtfun2, 1056 ampfun3, indfun3, fmtfun3, 1057 ampfun4, indfun4, fmtfun4) 1058 amp *= 0.25 1059 dur = dur.to_f 1060 pitch = pitch.to_f 1061 rangetop = 910.0 1062 rangebot = 400.0 1063 k = (100 * (log(pitch / rangebot) / log(rangetop / rangebot))).floor 1064 mfq = pitch 1065 atpt = 100 * (atdr / dur) 1066 dcpt = 100 - 100 * (dcdr / dur) 1067 lfmt1 = envelope_interp(k, fmtfun1) 1068 harm1 = (0.5 + lfmt1 / pitch).floor 1069 dev11 = hz2radians(envelope_interp(k, indfun1) * mfq) 1070 dev01 = dev11 * 0.5 1071 lamp1 = envelope_interp(k, ampfun1) * amp * (1 - (harm1 - lfmt1 / pitch).abs) 1072 lfmt2 = envelope_interp(k, fmtfun2) 1073 harm2 = (0.5 + lfmt2 / pitch).floor 1074 dev12 = hz2radians(envelope_interp(k, indfun2) * mfq) 1075 dev02 = dev12 * 0.5 1076 lamp2 = envelope_interp(k, ampfun2) * amp * (1 - (harm2 - lfmt2 / pitch).abs) 1077 lfmt3 = envelope_interp(k, fmtfun3) 1078 harm3 = (0.5 + lfmt3 / pitch).floor 1079 dev13 = hz2radians(envelope_interp(k, indfun3) * mfq) 1080 dev03 = dev13 * 0.5 1081 lamp3 = envelope_interp(k, ampfun3) * amp * (1 - (harm3 - lfmt3 / pitch).abs) 1082 lfmt4 = envelope_interp(k, fmtfun4) 1083 harm4 = (0.5 + lfmt4 / pitch).floor 1084 dev14 = hz2radians(envelope_interp(k, indfun4) * mfq) 1085 dev04 = dev14 * 0.5 1086 lamp4 = envelope_interp(k, ampfun4) * amp * (1 - (harm4 - lfmt4 / pitch).abs) 1087 tampfun = make_env(:envelope, stretch_envelope(ampfun, 25, atpt, 75, dcpt), 1088 :duration, dur) 1089 tskwfun = make_env(:envelope, stretch_envelope(skewfun, 25, atpt, 75, dcpt), 1090 :scaler, hz2radians(pitch * skewpc.to_f), :duration, dur) 1091 tranfun = make_env(:envelope, stretch_envelope(ranfun, 25, atpt, 75, dcpt), 1092 :duration, dur) 1093 tidxfun = make_env(:envelope, stretch_envelope(indexfun, 25, atpt, 75, dcpt), 1094 :duration, dur) 1095 modgen = make_oscil(:frequency, pitch) 1096 gen1 = make_oscil(:frequency, pitch * harm1) 1097 gen2 = make_oscil(:frequency, pitch * harm2) 1098 gen3 = make_oscil(:frequency, pitch * harm3) 1099 gen4 = make_oscil(:frequency, pitch * harm4) 1100 ranvib = make_rand(:frequency, ranfreq, :amplitude, hz2radians(ranpc * pitch)) 1101 run_instrument(start, dur, 1102 :degree, deg, 1103 :distance, dis, 1104 :reverb_amount, pcrev) do 1105 frqval = env(tskwfun) + env(tranfun) * rand(ranvib) 1106 modval = oscil(modgen, frqval) 1107 ampval = env(tampfun) 1108 indval = env(tidxfun) 1109 lamp1 * 1110 ampval * 1111 oscil(gen1, ((dev01 + indval * dev11) * modval + frqval) * harm1) + 1112 lamp2 * 1113 ampval * 1114 oscil(gen2, ((dev02 + indval * dev12) * modval + frqval) * harm2) + 1115 lamp3 * 1116 ampval * 1117 oscil(gen3, ((dev03 + indval * dev13) * modval + frqval) * harm3) + 1118 lamp4 * 1119 ampval * 1120 oscil(gen4, ((dev04 + indval * dev14) * modval + frqval) * harm4) 1121 end 1122end 1123 1124# NREV (the most popular Samson box reverb) 1125# 1126# reverb_factor controls the length of the decay -- it should not 1127# exceed (/ 1.0 .823) 1128# lp_coeff controls the strength of the low pass filter inserted 1129# in the feedback loop 1130# volume can be used to boost the reverb output 1131def nrev(*args) 1132 reverb_factor, lp_coeff, volume = nil 1133 optkey(args, binding, 1134 [:reverb_factor, 1.09], 1135 [:lp_coeff, 0.7], 1136 [:volume, 1.0]) 1137 next_prime = lambda do |val| 1138 if val.prime? 1139 val 1140 else 1141 next_prime.call(val + 2) 1142 end 1143 end 1144 srscale = @srate / 25641 1145 dly_len = [1433, 1601, 1867, 2053, 2251, 2399, 1146 347, 113, 37, 59, 53, 43, 37, 29, 19] 1147 dly_len.map! do |x| 1148 val = (x * srscale).round 1149 val += 1 if val.even? 1150 next_prime.call(val) 1151 end 1152 comb1 = make_comb(0.822 * reverb_factor, dly_len[0]) 1153 comb2 = make_comb(0.802 * reverb_factor, dly_len[1]) 1154 comb3 = make_comb(0.773 * reverb_factor, dly_len[2]) 1155 comb4 = make_comb(0.753 * reverb_factor, dly_len[3]) 1156 comb5 = make_comb(0.753 * reverb_factor, dly_len[4]) 1157 comb6 = make_comb(0.733 * reverb_factor, dly_len[5]) 1158 low = make_one_pole(lp_coeff, lp_coeff - 1.0) 1159 chan2 = (@channels > 1) 1160 chan4 = (@channels == 4) 1161 allpass1 = make_all_pass(-0.7, 0.7, dly_len[6]) 1162 allpass2 = make_all_pass(-0.7, 0.7, dly_len[7]) 1163 allpass3 = make_all_pass(-0.7, 0.7, dly_len[8]) 1164 allpass4 = make_all_pass(-0.7, 0.7, dly_len[9]) # 10 for quad 1165 allpass5 = make_all_pass(-0.7, 0.7, dly_len[11]) 1166 allpass6 = (chan2 ? make_all_pass(-0.7, 0.7, dly_len[12]) : nil) 1167 allpass7 = (chan4 ? make_all_pass(-0.7, 0.7, dly_len[13]) : nil) 1168 allpass8 = (chan4 ? make_all_pass(-0.7, 0.7, dly_len[14]) : nil) 1169 out_frample = Vct.new(@channels, 0.0) 1170 run_reverb() do |val, i| 1171 rev = volume * val 1172 outrev = all_pass(allpass4, 1173 one_pole(low, 1174 all_pass(allpass3, 1175 all_pass(allpass2, 1176 all_pass(allpass1, 1177 comb(comb1, rev) + 1178 comb(comb2, rev) + 1179 comb(comb3, rev) + 1180 comb(comb4, rev) + 1181 comb(comb5, rev) + 1182 comb(comb6, rev)))))) 1183 out_frample[0] = all_pass(allpass5, outrev) 1184 if chan2 1185 out_frample[1] = all_pass(allpass6, outrev) 1186 end 1187 if chan4 1188 out_frample[2] = all_pass(allpass7, outrev) 1189 out_frample[3] = all_pass(allpass8, outrev) 1190 end 1191 out_frample 1192 end 1193end 1194 1195def drone_canter_test(start = 0.0, dur = 1.0) 1196 fmt1 = [0, 1200, 100, 1000] 1197 fmt2 = [0, 2250, 100, 1800] 1198 fmt3 = [0, 4500, 100, 4500] 1199 fmt4 = [0, 6750, 100, 8100] 1200 amp1 = [0, 0.67, 100, 0.7] 1201 amp2 = [0, 0.95, 100, 0.95] 1202 amp3 = [0, 0.28, 100, 0.33] 1203 amp4 = [0, 0.14, 100, 0.15] 1204 ind1 = [0, 0.75, 100, 0.65] 1205 ind2 = [0, 0.75, 100, 0.75] 1206 ind3 = [0, 1, 100, 1] 1207 ind4 = [0, 1, 100, 1] 1208 skwf = [0, 0, 100, 0] 1209 ampf = [0, 0, 25, 1, 75, 1, 100, 0] 1210 ranf = [0, 0.5, 100, 0.5] 1211 index = [0, 1, 100, 1] 1212 solid = [0, 0, 5, 1, 95, 1, 100, 0] 1213 bassdr2 = [0.5, 0.06, 1, 0.62, 1.5, 0.07, 2, 0.6, 2.5, 0.08, 3, 0.56, 1214 4, 0.24, 5, 0.98, 6, 0.53, 7, 0.16, 8, 0.33, 9, 0.62, 10, 0.12, 1215 12, 0.14, 14, 0.86, 16, 0.12, 23, 0.14, 24, 0.17] 1216 tenordr = [0.3, 0.04, 1, 0.81, 2, 0.27, 3, 0.2, 4, 0.21, 5, 0.18, 1217 6, 0.35, 7, 0.03, 8, 0.07, 9, 0.02, 10, 0.025, 11, 0.035] 1218 1219 $now = start 1220 drone($now, 4, 115, 0.125, solid, bassdr2, 0.1, 0.5, 0.03, 45, 1, 0.01, 10) 1221 drone($now, 4, 229, 0.125, solid, tenordr, 0.1, 0.5, 0.03, 45, 1, 0.01, 11) 1222 drone($now, 4, 229.5, 0.125, solid, tenordr, 0.1, 0.5, 0.03, 45, 1, 0.01, 9) 1223 canter($now, 2.100, 918.000, 0.175, 45.0, 1, 0.05, 1224 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1225 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1226 canter($now + 2.100, 0.300, 688.500, 0.175, 45.0, 1, 0.05, 1227 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1228 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1229 canter($now + 2.400, 0.040, 826.200, 0.175, 45.0, 1, 0.05, 1230 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1231 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1232 canter($now + 2.440, 0.560, 459.000, 0.175, 45.0, 1, 0.05, 1233 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1234 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1235 canter($now + 3.000, 0.040, 408.000, 0.175, 45.0, 1, 0.05, 1236 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1237 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1238 canter($now + 3.040, 0.040, 619.650, 0.175, 45.0, 1, 0.05, 1239 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1240 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1241 canter($now + 3.080, 0.040, 408.000, 0.175, 45.0, 1, 0.05, 1242 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1243 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1244 canter($now + 3.120, 0.040, 688.500, 0.175, 45.0, 1, 0.05, 1245 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1246 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1247 canter($now + 3.160, 0.290, 459.000, 0.175, 45.0, 1, 0.05, 1248 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1249 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1250 canter($now + 3.450, 0.150, 516.375, 0.175, 45.0, 1, 0.05, 1251 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1252 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1253 canter($now + 3.600, 0.040, 826.200, 0.175, 45.0, 1, 0.05, 1254 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1255 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1256 canter($now + 3.640, 0.040, 573.750, 0.175, 45.0, 1, 0.05, 1257 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1258 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1259 canter($now + 3.680, 0.040, 619.650, 0.175, 45.0, 1, 0.05, 1260 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1261 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1262 canter($now + 3.720, 0.180, 573.750, 0.175, 45.0, 1, 0.05, 1263 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1264 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1265 canter($now + 3.900, 0.040, 688.500, 0.175, 45.0, 1, 0.05, 1266 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1267 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1268 canter($now + 3.940, 0.260, 459.000, 0.175, 45.0, 1, 0.05, 1269 ampf, ranf, skwf, 0.050, 0.01, 10, index, 0.005, 0.005, 1270 amp1, ind1, fmt1, amp2, ind2, fmt2, amp3, ind3, fmt3, amp4, ind4, fmt4) 1271 $now += 4.4 1272end 1273 1274# RESON 1275def reson(start, dur, pitch, amp, numformants, 1276 indxfun, skewfun, pcskew, skewat, skewdc, 1277 vibfreq, vibpc, ranvibfreq, ranvibpc, 1278 degree, distance, rev_amount, data) 1279 # data is a list of lists of form 1280 # [ampf, resonfrq, resonamp, ampat, ampdc, dev0, dev1, indxat, indxdc] 1281 dur = dur.to_f 1282 pitch = pitch.to_f 1283 modulator = make_oscil(:frequency, pitch) 1284 carriers = Array.new(numformants) 1285 ampfs = Array.new(numformants) 1286 indfs = Array.new(numformants) 1287 c_rats = Array.new(numformants) 1288 frqf = make_env(:envelope, 1289 stretch_envelope(skewfun, 25, 100 * (skewat / dur), 75, 1290 100 - (100 * (skewdc / dur))), 1291 :scaler, hz2radians(pcskew * pitch), :duration, dur) 1292 pervib = make_triangle_wave(:frequency, vibfreq, 1293 :amplitude, hz2radians(vibpc * pitch)) 1294 ranvib = make_rand_interp(:frequency, ranvibfreq, 1295 :amplitude, hz2radians(ranvibpc * pitch)) 1296 totalamp = 0.0 1297 numformants.times do |i| 1298 totalamp += data[i][2] 1299 end 1300 numformants.times do |i| 1301 frmdat = data[i] 1302 ampf = frmdat[0] 1303 freq = frmdat[1] 1304 rfamp = frmdat[2] 1305 ampat = 100 * (frmdat[3] / dur) 1306 ampdc = 100 - 100 * (frmdat[4] / dur) 1307 dev0 = hz2radians(frmdat[5] * freq) 1308 dev1 = hz2radians(frmdat[6] * freq) 1309 indxat = 100 * (frmdat[7] / dur) 1310 indxdc = 100 - 100 * (frmdat[8] / dur) 1311 harm = (freq / pitch).round 1312 rsamp = 1.0 - (harm - freq / pitch).abs 1313 cfq = pitch * harm 1314 ampat = 25 if ampat.zero? 1315 ampdc = 75 if ampdc.zero? 1316 indxat = 25 if indxat.zero? 1317 indxdc = 75 if indxdc.zero? 1318 indfs[i] = make_env(:envelope, 1319 stretch_envelope(indxfun, 25, indxat, 75, indxdc), 1320 :scaler, dev1 - dev0, 1321 :offset, dev0, 1322 :duration, dur) 1323 ampfs[i] = make_env(:envelope, 1324 stretch_envelope(ampf, 25, ampat, 75, ampdc), 1325 :scaler, rsamp * amp * (rfamp / totalamp), 1326 :duration, dur) 1327 c_rats[i] = harm 1328 carriers[i] = make_oscil(:frequency, cfq) 1329 end 1330 run_instrument(start, dur, 1331 :degree, degree, 1332 :distance, distance, 1333 :reverb_amount, rev_amount) do 1334 vib = triangle_wave(pervib) + rand_interp(ranvib) + env(frqf) 1335 modsig = oscil(modulator, vib) 1336 outsum = 0.0 1337 numformants.times do |j| 1338 outsum += env(ampfs[j]) * 1339 oscil(carriers[j], 1340 vib * c_rats[j] + 1341 env(indfs[j]) * modsig) 1342 end 1343 outsum 1344 end 1345end 1346 1347def reson_test(start = 0.0, dur = 1.0) 1348 data = [[[0, 0, 100, 1], 1200, 0.5, 0.1, 0.1, 0, 1.0, 0.1, 0.1], 1349 [[0, 1, 100, 0], 2400, 0.5, 0.1, 0.1, 0, 1.0, 0.1, 0.1]] 1350 1351 reson(start, dur, 440, 0.5, 2, [0, 0, 100, 1], [0, 0, 100, 1], 1352 0.1, 0.1, 0.1, 5, 0.01, 5, 0.01, 0, 1.0, 0.01, data) 1353 $now = start + dur + 0.2 1354end 1355 1356# STK's feedback-fm instrument named CelloN in Sambox-land 1357def cellon(start, dur, pitch0, amp, ampfun, betafun, 1358 beta0, beta1, betaat, betadc, ampat, ampdc, dis, pcrev, deg, pitch1, 1359 glissfun = [0, 0, 100, 0], glissat = 0.0, glissdc = 0.0, 1360 pvibfreq = 0.0, pvibpc = 0.0, 1361 pvibfun = [0, 1, 100, 1], pvibat = 0.0, pvibdc = 0.0, 1362 rvibfreq = 0.0, rvibpc = 0.0, rvibfun = [0, 1, 100, 1]) 1363 1364 pit1 = pitch1.zero? ? pitch0 : pitch1 1365 car = make_oscil(:frequency, pitch0) 1366 low = make_one_zero(0.5, -0.5) 1367 fmosc = make_oscil(:frequency, pitch0) 1368 fm = 0.0 1369 dur = dur.to_f 1370 pitch0 = pitch0.to_f 1371 pvib = make_triangle_wave(:frequency, pvibfreq, :amplitude, 1.0) 1372 rvib = make_rand_interp(:frequency, rvibfreq, :amplitude, 1.0) 1373 ampap = (ampat > 0.0 ? (100 * (ampat / dur)) : 25) 1374 ampdp = (ampdc > 0.0 ? (100 * (1.0 - ampdc / dur)) : 75) 1375 glsap = (glissat > 0.0 ? (100 * (glissat / dur)) : 25) 1376 glsdp = (glissdc > 0.0 ? (100 * (1.0 - glissdc / dur)) : 75) 1377 betap = (betaat > 0.0 ? (100 * (betaat / dur)) : 25) 1378 betdp = (betadc > 0.0 ? (100 * (1.0 - betadc / dur)) : 75) 1379 pvbap = (pvibat > 0.0 ? (100 * (pvibat / dur)) : 25) 1380 pvbdp = (pvibdc > 0.0 ? (100 * (1.0 - pvibdc / dur)) : 75) 1381 pvibenv = make_env(:envelope, 1382 stretch_envelope(pvibfun, 25, pvbap, 75, pvbdp), 1383 :scaler, hz2radians(pvibpc * pitch0), 1384 :duration, dur) 1385 rvibenv = make_env(:envelope, stretch_envelope(rvibfun), 1386 :duration, dur, 1387 :scaler, hz2radians(rvibpc * pitch0)) 1388 glisenv = make_env(:envelope, 1389 stretch_envelope(glissfun, 25, glsap, 75, glsdp), 1390 :scaler, hz2radians(pit1 - pitch0), 1391 :duration, dur) 1392 amplenv = make_env(:envelope, stretch_envelope(ampfun, 25, ampap, 75, ampdp), 1393 :scaler, amp, 1394 :duration, dur) 1395 betaenv = make_env(:envelope, stretch_envelope(betafun, 25, betap, 75, betdp), 1396 :scaler, beta1 - beta0, 1397 :offset, beta0, 1398 :duration, dur) 1399 run_instrument(start, dur, 1400 :degree, deg, 1401 :distance, dis, 1402 :reverb_amount, pcrev) do 1403 vib = env(pvibenv) * triangle_wave(pvib) + 1404 env(rvibenv) * rand_interp(rvib) + 1405 env(glisenv) 1406 fm = one_zero(low, env(betaenv) * oscil(fmosc, fm + vib)) 1407 env(amplenv) * oscil(car, fm + vib) 1408 end 1409end 1410 1411def cellon_test(start = 0.0, dur = 1.0) 1412 cellon(start, dur, 220, 0.5, 1413 [0, 0, 25, 1, 75, 1, 100, 0], # ampfun 1414 [0, 0, 25, 1, 75, 1, 100, 0], # betafun 1415 0.75, 1.0, 0, 0, 0, 0, 1, 0, 0, 220, 1416 [0, 0, 25, 1, 75, 1, 100, 0], # glissfun 1417 0, 0, 0, 0, 1418 [0, 0, 100, 0], # pvibfun 1419 0, 0, 0, 0, 1420 [0, 0, 100, 0]) # rvibfun 1421 $now = start + dur + 0.2 1422end 1423 1424# JL-REVERB 1425def jl_reverb(*args) 1426 allpass1 = make_all_pass(-0.7, 0.7, 2111) 1427 allpass2 = make_all_pass(-0.7, 0.7, 673) 1428 allpass3 = make_all_pass(-0.7, 0.7, 223) 1429 comb1 = make_comb(0.742, 9601) 1430 comb2 = make_comb(0.733, 10007) 1431 comb3 = make_comb(0.715, 10799) 1432 comb4 = make_comb(0.697, 11597) 1433 outdel1 = make_delay((0.013 * @srate).round) 1434 outdel2 = (@channels > 1 ? make_delay((0.011 * @srate).round) : false) 1435 out_frample = Vct.new(@channels, 0.0) 1436 run_reverb() do |ho, i| 1437 allpass_sum = all_pass(allpass3, all_pass(allpass2, all_pass(allpass1, ho))) 1438 comb_sum = (comb(comb1, allpass_sum) + comb(comb2, allpass_sum) + 1439 comb(comb3, allpass_sum) + comb(comb4, allpass_sum)) 1440 out_frample[0] = delay(outdel1, comb_sum) 1441 if outdel2 1442 out_frample[1] = delay(outdel2, comb_sum) 1443 end 1444 out_frample 1445 end 1446end 1447 1448# GRAN-SYNTH 1449def gran_synth(start, dur, freq, grain_dur, interval, amp) 1450 grain_env = make_env(:envelope, [0, 0, 25, 1, 75, 1, 100, 0], 1451 :duration, grain_dur) 1452 carrier = make_oscil(:frequency, freq) 1453 grain_size = ([grain_dur, interval].max * @srate).ceil 1454 grains = make_wave_train(:size, grain_size, :frequency, 1.0 / interval) 1455 grain = mus_data(grains) 1456 grain_size.times do |i| 1457 grain[i] = env(grain_env) * oscil(carrier) 1458 end 1459 run_instrument(start, dur) do 1460 amp * wave_train(grains) 1461 end 1462end 1463 1464def gran_synth_test(start = 0.0, dur = 1.0) 1465 gran_synth(start, dur, 100, 0.0189, 0.02, 0.4) 1466 $now = start + dur + 0.2 1467end 1468 1469# TOUCH-TONE 1470def touch_tone(start, number) 1471 touch_tab_1 = [0, 697, 697, 697, 770, 770, 770, 852, 852, 852, 941, 941, 941] 1472 touch_tab_2 = [0, 1209, 1336, 1477, 1209, 1336, 1473 1477, 1209, 1336, 1477, 1209, 1336, 1477] 1474 number.length.times do |i| 1475 k = number[i] 1476 ii = if k.kind_of?(Numeric) 1477 k.zero? ? 11 : k 1478 else 1479 k == ?* ? 10 : 12 1480 end 1481 frq1 = make_oscil(:frequency, touch_tab_1[ii]) 1482 frq2 = make_oscil(:frequency, touch_tab_2[ii]) 1483 run_instrument(start + i * 0.3, 0.2) do 1484 0.25 * (oscil(frq1) + oscil(frq2)) 1485 end 1486 end 1487end 1488 1489def touch_tone_test(start = 0.0, dur = 1.0) 1490 touch_tone(start, [4, 8, 3, 4, 6, 2, 1]) 1491 $now = start + dur * 7 + 0.2 # 7 digits 1492end 1493 1494# SPECTRA 1495def spectra(start, dur, freq, amp, 1496 partials = [1, 1, 2, 0.5], 1497 amp_envelope = [0, 0, 50, 1, 100, 0], 1498 vibrato_amplitude = 0.005, 1499 vibrato_speed = 5.0, 1500 degree = 0.0, 1501 distance = 1.0, 1502 rev_amount = 0.005) 1503 waveform = partials2wave(partials) 1504 frq = hz2radians(freq) 1505 s = make_table_lookup(:frequency, freq, :wave, waveform) 1506 amp_env = make_env(:envelope, amp_envelope, :scaler, amp, :duration, dur) 1507 per_vib = make_triangle_wave(:frequency, vibrato_speed, 1508 :amplitude, vibrato_amplitude * frq) 1509 ran_vib = make_rand_interp(:frequency, vibrato_speed + 1.0, 1510 :amplitude, vibrato_amplitude * frq) 1511 run_instrument(start, dur, 1512 :degree, degree, 1513 :distance, distance, 1514 :reverb_amount, rev_amount) do 1515 env(amp_env) * 1516 table_lookup(s, triangle_wave(per_vib) + rand_interp(ran_vib)) 1517 end 1518end 1519 1520def spectra_test(start = 0.0, dur = 1.0) 1521 spectra(start, dur, 440.0, 0.8, P_a4, 1522 [0, 0, 1, 1, 5, 0.9, 12, 0.5, 25, 0.25, 100, 0]) 1523 $now = start + dur + 0.2 1524end 1525 1526# TWO-TAB 1527# 1528# interpolate between two waveforms (this could be extended to 1529# implement all the various wavetable-based synthesis techniques). 1530def two_tab(start, dur, freq, amp, 1531 partial_1 = [1.0, 1.0, 2.0, 0.5], 1532 partial_2 = [1.0, 0.0, 3.0, 1.0], 1533 amp_envelope = [0, 0, 50, 1, 100, 0], 1534 interp_func = [0, 1, 100, 0], 1535 vibrato_amplitude = 0.005, 1536 vibrato_speed = 5.0, 1537 degree = 0.0, 1538 distance = 1.0, 1539 rev_amount = 0.005) 1540 waveform_1 = partials2wave(partial_1) 1541 waveform_2 = partials2wave(partial_2) 1542 frq = hz2radians(freq) 1543 s_1 = make_table_lookup(:frequency, freq, :wave, waveform_1) 1544 s_2 = make_table_lookup(:frequency, freq, :wave, waveform_2) 1545 amp_env = make_env(:envelope, amp_envelope, :scaler, amp, :duration, dur) 1546 interp_env = make_env(:envelope, interp_func, :duration, dur) 1547 per_vib = make_triangle_wave(:frequency, vibrato_speed, 1548 :amplitude, vibrato_amplitude * frq) 1549 ran_vib = make_rand_interp(:frequency, vibrato_speed + 1.0, 1550 :amplitude, vibrato_amplitude * frq) 1551 run_instrument(start, dur, 1552 :degree, degree, 1553 :distance, distance, 1554 :reverb_amount, rev_amount) do 1555 vib = triangle_wave(per_vib) + rand_interp(ran_vib) 1556 intrp = env(interp_env) 1557 env(amp_env) * 1558 (intrp * table_lookup(s_1, vib) + 1559 (1.0 - intrp) * table_lookup(s_2, vib)) 1560 end 1561end 1562 1563def two_tab_test(start = 0.0, dur = 1.0) 1564 two_tab(start, dur, 440, 0.5) 1565 $now = start + dur + 0.2 1566end 1567 1568# LBJ-PIANO 1569$clm_piano_attack_duration = 0.04 1570$clm_piano_release_duration = 0.2 1571$clm_db_drop_per_second = -10.0 1572 1573Piano_Spectra = [[1.97, 0.0326, 2.99, 0.0086, 3.95, 0.0163, 4.97, 1574 0.0178, 5.98, 0.0177, 6.95, 0.0315, 8.02, 0.0001, 8.94, 0.0076, 1575 9.96, 0.0134, 10.99, 0.0284, 11.98, 0.0229, 13.02, 0.0229, 13.89, 1576 0.0010, 15.06, 0.0090, 16.00, 0.0003, 17.08, 0.0078, 18.16, 0.0064, 1577 19.18, 0.0129, 20.21, 0.0085, 21.27, 0.0225, 22.32, 0.0061, 23.41, 1578 0.0102, 24.48, 0.0005, 25.56, 0.0016, 26.64, 0.0018, 27.70, 0.0113, 1579 28.80, 0.0111, 29.91, 0.0158, 31.06, 0.0093, 32.17, 0.0017, 33.32, 1580 0.0002, 34.42, 0.0018, 35.59, 0.0027, 36.74, 0.0055, 37.90, 0.0037, 1581 39.06, 0.0064, 40.25, 0.0033, 41.47, 0.0014, 42.53, 0.0004, 43.89, 1582 0.0010, 45.12, 0.0039, 46.33, 0.0039, 47.64, 0.0009, 48.88, 0.0016, 1583 50.13, 0.0006, 51.37, 0.0010, 52.70, 0.0002, 54.00, 0.0004, 55.30, 1584 0.0008, 56.60, 0.0025, 57.96, 0.0010, 59.30, 0.0012, 60.67, 0.0011, 1585 61.99, 0.0003, 62.86, 0.0001, 64.36, 0.0005, 64.86, 0.0001, 66.26, 1586 0.0004, 67.70, 0.0006, 68.94, 0.0002, 70.10, 0.0001, 70.58, 0.0002, 1587 72.01, 0.0007, 73.53, 0.0006, 75.00, 0.0002, 77.03, 0.0005, 78.00, 1588 0.0002, 79.57, 0.0006, 81.16, 0.0005, 82.70, 0.0005, 84.22, 0.0003, 1589 85.41, 0.0002, 87.46, 0.0001, 90.30, 0.0001, 94.02, 0.0001, 95.26, 1590 0.0002, 109.39, 0.0003], 1591 [1.98, 0.0194, 2.99, 0.0210, 3.97, 0.0276, 4.96, 0.0297, 5.96, 0.0158, 1592 6.99, 0.0207, 8.01, 0.0009, 9.00, 0.0101, 10.00, 0.0297, 11.01, 1593 0.0289, 12.02, 0.0211, 13.04, 0.0127, 14.07, 0.0061, 15.08, 0.0174, 1594 16.13, 0.0009, 17.12, 0.0093, 18.16, 0.0117, 19.21, 0.0122, 20.29, 1595 0.0108, 21.30, 0.0077, 22.38, 0.0132, 23.46, 0.0073, 24.14, 0.0002, 1596 25.58, 0.0026, 26.69, 0.0035, 27.77, 0.0053, 28.88, 0.0024, 30.08, 1597 0.0027, 31.13, 0.0075, 32.24, 0.0027, 33.36, 0.0004, 34.42, 0.0004, 1598 35.64, 0.0019, 36.78, 0.0037, 38.10, 0.0009, 39.11, 0.0027, 40.32, 1599 0.0010, 41.51, 0.0013, 42.66, 0.0019, 43.87, 0.0007, 45.13, 0.0017, 1600 46.35, 0.0019, 47.65, 0.0021, 48.89, 0.0014, 50.18, 0.0023, 51.42, 1601 0.0015, 52.73, 0.0002, 54.00, 0.0005, 55.34, 0.0006, 56.60, 0.0010, 1602 57.96, 0.0016, 58.86, 0.0005, 59.30, 0.0004, 60.75, 0.0005, 62.22, 1603 0.0003, 63.55, 0.0005, 64.82, 0.0003, 66.24, 0.0003, 67.63, 0.0011, 1604 69.09, 0.0007, 70.52, 0.0004, 72.00, 0.0005, 73.50, 0.0008, 74.95, 1605 0.0003, 77.13, 0.0013, 78.02, 0.0002, 79.48, 0.0004, 82.59, 0.0004, 1606 84.10, 0.0003], 1607 [2.00, 0.0313, 2.99, 0.0109, 4.00, 0.0215, 5.00, 0.0242, 5.98, 0.0355, 1608 7.01, 0.0132, 8.01, 0.0009, 9.01, 0.0071, 10.00, 0.0258, 11.03, 1609 0.0221, 12.02, 0.0056, 13.06, 0.0196, 14.05, 0.0160, 15.11, 0.0107, 1610 16.11, 0.0003, 17.14, 0.0111, 18.21, 0.0085, 19.23, 0.0010, 20.28, 1611 0.0048, 21.31, 0.0128, 22.36, 0.0051, 23.41, 0.0041, 24.05, 0.0006, 1612 25.54, 0.0019, 26.62, 0.0028, 27.72, 0.0034, 28.82, 0.0062, 29.89, 1613 0.0039, 30.98, 0.0058, 32.08, 0.0011, 33.21, 0.0002, 34.37, 0.0008, 1614 35.46, 0.0018, 36.62, 0.0036, 37.77, 0.0018, 38.92, 0.0042, 40.07, 1615 0.0037, 41.23, 0.0011, 42.67, 0.0003, 43.65, 0.0018, 44.68, 0.0025, 1616 45.99, 0.0044, 47.21, 0.0051, 48.40, 0.0044, 49.67, 0.0005, 50.88, 1617 0.0019, 52.15, 0.0003, 53.42, 0.0008, 54.69, 0.0010, 55.98, 0.0005, 1618 57.26, 0.0013, 58.53, 0.0027, 59.83, 0.0011, 61.21, 0.0027, 62.54, 1619 0.0003, 63.78, 0.0003, 65.20, 0.0001, 66.60, 0.0006, 67.98, 0.0008, 1620 69.37, 0.0019, 70.73, 0.0007, 72.14, 0.0004, 73.62, 0.0002, 74.40, 1621 0.0003, 76.52, 0.0006, 77.97, 0.0002, 79.49, 0.0004, 80.77, 0.0003, 1622 81.00, 0.0001, 82.47, 0.0005, 83.97, 0.0001, 87.27, 0.0002], 1623 [2.00, 0.0257, 2.99, 0.0142, 3.97, 0.0202, 4.95, 0.0148, 5.95, 0.0420, 1624 6.95, 0.0037, 7.94, 0.0004, 8.94, 0.0172, 9.95, 0.0191, 10.96, 0.0115, 1625 11.97, 0.0059, 12.98, 0.0140, 14.00, 0.0178, 15.03, 0.0121, 16.09, 1626 0.0002, 17.07, 0.0066, 18.08, 0.0033, 19.15, 0.0022, 20.18, 0.0057, 1627 21.22, 0.0077, 22.29, 0.0037, 23.33, 0.0066, 24.97, 0.0002, 25.49, 1628 0.0019, 26.55, 0.0042, 27.61, 0.0043, 28.73, 0.0038, 29.81, 0.0084, 1629 30.91, 0.0040, 32.03, 0.0025, 33.14, 0.0005, 34.26, 0.0003, 35.38, 1630 0.0019, 36.56, 0.0037, 37.68, 0.0049, 38.86, 0.0036, 40.11, 0.0011, 1631 41.28, 0.0008, 42.50, 0.0004, 43.60, 0.0002, 44.74, 0.0022, 45.99, 1632 0.0050, 47.20, 0.0009, 48.40, 0.0036, 49.68, 0.0004, 50.92, 0.0009, 1633 52.17, 0.0005, 53.46, 0.0007, 54.76, 0.0006, 56.06, 0.0005, 57.34, 1634 0.0011, 58.67, 0.0005, 59.95, 0.0015, 61.37, 0.0008, 62.72, 0.0004, 1635 65.42, 0.0009, 66.96, 0.0003, 68.18, 0.0003, 69.78, 0.0003, 71.21, 1636 0.0004, 72.45, 0.0002, 74.22, 0.0003, 75.44, 0.0001, 76.53, 0.0003, 1637 78.31, 0.0004, 79.83, 0.0003, 80.16, 0.0001, 81.33, 0.0003, 82.44, 1638 0.0001, 83.17, 0.0002, 84.81, 0.0003, 85.97, 0.0003, 89.08, 0.0001, 1639 90.70, 0.0002, 92.30, 0.0002, 95.59, 0.0002, 97.22, 0.0003, 98.86, 1640 0.0001, 108.37, 0.0001, 125.54, 0.0001], 1641 [1.99, 0.0650, 3.03, 0.0040, 4.03, 0.0059, 5.02, 0.0090, 5.97, 0.0227, 1642 6.98, 0.0050, 8.04, 0.0020, 9.00, 0.0082, 9.96, 0.0078, 11.01, 0.0056, 1643 12.01, 0.0095, 13.02, 0.0050, 14.04, 0.0093, 15.08, 0.0064, 16.14, 1644 0.0017, 17.06, 0.0020, 18.10, 0.0025, 19.14, 0.0023, 20.18, 0.0015, 1645 21.24, 0.0032, 22.29, 0.0029, 23.32, 0.0014, 24.37, 0.0005, 25.43, 1646 0.0030, 26.50, 0.0022, 27.60, 0.0027, 28.64, 0.0024, 29.76, 0.0035, 1647 30.81, 0.0136, 31.96, 0.0025, 33.02, 0.0003, 34.13, 0.0005, 35.25, 1648 0.0007, 36.40, 0.0014, 37.51, 0.0020, 38.64, 0.0012, 39.80, 0.0019, 1649 40.97, 0.0004, 42.09, 0.0003, 43.24, 0.0003, 44.48, 0.0002, 45.65, 1650 0.0024, 46.86, 0.0005, 48.07, 0.0013, 49.27, 0.0008, 50.49, 0.0006, 1651 52.95, 0.0001, 54.23, 0.0005, 55.45, 0.0004, 56.73, 0.0001, 58.03, 1652 0.0003, 59.29, 0.0002, 60.59, 0.0003, 62.04, 0.0002, 65.89, 0.0002, 1653 67.23, 0.0002, 68.61, 0.0002, 69.97, 0.0004, 71.36, 0.0005, 85.42, 1654 0.0001], 1655 [1.98, 0.0256, 2.96, 0.0158, 3.95, 0.0310, 4.94, 0.0411, 5.95, 0.0238, 1656 6.94, 0.0152, 7.93, 0.0011, 8.95, 0.0185, 9.92, 0.0166, 10.93, 0.0306, 1657 11.94, 0.0258, 12.96, 0.0202, 13.97, 0.0403, 14.95, 0.0228, 15.93, 1658 0.0005, 17.01, 0.0072, 18.02, 0.0034, 19.06, 0.0028, 20.08, 0.0124, 1659 21.13, 0.0137, 22.16, 0.0102, 23.19, 0.0058, 23.90, 0.0013, 25.30, 1660 0.0039, 26.36, 0.0039, 27.41, 0.0025, 28.47, 0.0071, 29.64, 0.0031, 1661 30.60, 0.0027, 31.71, 0.0021, 32.84, 0.0003, 33.82, 0.0002, 35.07, 1662 0.0019, 36.09, 0.0054, 37.20, 0.0038, 38.33, 0.0024, 39.47, 0.0055, 1663 40.55, 0.0016, 41.77, 0.0006, 42.95, 0.0002, 43.27, 0.0018, 44.03, 1664 0.0006, 45.25, 0.0019, 46.36, 0.0033, 47.50, 0.0024, 48.87, 0.0012, 1665 50.03, 0.0016, 51.09, 0.0004, 53.52, 0.0017, 54.74, 0.0012, 56.17, 1666 0.0003, 57.40, 0.0011, 58.42, 0.0020, 59.70, 0.0007, 61.29, 0.0008, 1667 62.56, 0.0003, 63.48, 0.0002, 64.83, 0.0002, 66.12, 0.0012, 67.46, 1668 0.0017, 68.81, 0.0003, 69.13, 0.0003, 70.53, 0.0002, 71.84, 0.0001, 1669 73.28, 0.0002, 75.52, 0.0010, 76.96, 0.0005, 77.93, 0.0003, 78.32, 1670 0.0003, 79.73, 0.0003, 81.69, 0.0002, 82.52, 0.0001, 84.01, 0.0001, 1671 84.61, 0.0002, 86.88, 0.0001, 88.36, 0.0002, 89.85, 0.0002, 91.35, 1672 0.0003, 92.86, 0.0002, 93.40, 0.0001, 105.28, 0.0002, 106.22, 0.0002, 1673 107.45, 0.0001, 108.70, 0.0003, 122.08, 0.0002], 1674 [1.97, 0.0264, 2.97, 0.0211, 3.98, 0.0234, 4.98, 0.0307, 5.96, 0.0085, 1675 6.94, 0.0140, 7.93, 0.0005, 8.96, 0.0112, 9.96, 0.0209, 10.98, 0.0194, 1676 11.98, 0.0154, 12.99, 0.0274, 13.99, 0.0127, 15.01, 0.0101, 15.99, 1677 0.0002, 17.04, 0.0011, 18.08, 0.0032, 19.14, 0.0028, 20.12, 0.0054, 1678 21.20, 0.0053, 22.13, 0.0028, 23.22, 0.0030, 24.32, 0.0006, 25.24, 1679 0.0004, 26.43, 0.0028, 27.53, 0.0048, 28.52, 0.0039, 29.54, 0.0047, 1680 30.73, 0.0044, 31.82, 0.0007, 32.94, 0.0008, 34.04, 0.0012, 35.13, 1681 0.0018, 36.29, 0.0007, 37.35, 0.0075, 38.51, 0.0045, 39.66, 0.0014, 1682 40.90, 0.0004, 41.90, 0.0002, 43.08, 0.0002, 44.24, 0.0017, 45.36, 1683 0.0013, 46.68, 0.0020, 47.79, 0.0015, 48.98, 0.0010, 50.21, 0.0012, 1684 51.34, 0.0001, 53.82, 0.0003, 55.09, 0.0004, 56.23, 0.0005, 57.53, 1685 0.0004, 58.79, 0.0005, 59.30, 0.0002, 60.03, 0.0002, 61.40, 0.0003, 1686 62.84, 0.0001, 66.64, 0.0001, 67.97, 0.0001, 69.33, 0.0001, 70.68, 1687 0.0001, 73.57, 0.0002, 75.76, 0.0002, 76.45, 0.0001, 79.27, 0.0001, 1688 80.44, 0.0002, 81.87, 0.0002], 1689 [2.00, 0.0311, 2.99, 0.0086, 3.99, 0.0266, 4.97, 0.0123, 5.98, 0.0235, 1690 6.97, 0.0161, 7.97, 0.0008, 8.96, 0.0088, 9.96, 0.0621, 10.99, 0.0080, 1691 11.99, 0.0034, 12.99, 0.0300, 14.03, 0.0228, 15.04, 0.0105, 16.03, 1692 0.0004, 17.06, 0.0036, 18.09, 0.0094, 18.95, 0.0009, 20.17, 0.0071, 1693 21.21, 0.0161, 22.25, 0.0106, 23.28, 0.0104, 24.33, 0.0008, 25.38, 1694 0.0030, 26.46, 0.0035, 27.50, 0.0026, 28.59, 0.0028, 29.66, 0.0128, 1695 30.75, 0.0139, 31.81, 0.0038, 32.93, 0.0006, 34.04, 0.0004, 35.16, 1696 0.0005, 36.25, 0.0023, 37.35, 0.0012, 38.46, 0.0021, 39.59, 0.0035, 1697 40.71, 0.0006, 41.86, 0.0007, 42.42, 0.0001, 43.46, 0.0003, 44.17, 1698 0.0032, 45.29, 0.0013, 46.57, 0.0004, 47.72, 0.0011, 48.79, 0.0005, 1699 50.11, 0.0005, 51.29, 0.0003, 52.47, 0.0002, 53.68, 0.0004, 55.02, 1700 0.0005, 56.18, 0.0003, 57.41, 0.0003, 58.75, 0.0007, 59.33, 0.0009, 1701 60.00, 0.0004, 61.34, 0.0001, 64.97, 0.0003, 65.20, 0.0002, 66.48, 1702 0.0002, 67.83, 0.0002, 68.90, 0.0003, 70.25, 0.0003, 71.59, 0.0002, 1703 73.68, 0.0001, 75.92, 0.0001, 77.08, 0.0002, 78.45, 0.0002, 81.56, 1704 0.0002, 82.99, 0.0001, 88.39, 0.0001], 1705 [0.97, 0.0059, 1.98, 0.0212, 2.99, 0.0153, 3.99, 0.0227, 4.96, 0.0215, 1706 5.97, 0.0153, 6.98, 0.0085, 7.98, 0.0007, 8.97, 0.0179, 9.98, 0.0512, 1707 10.98, 0.0322, 12.00, 0.0098, 13.02, 0.0186, 14.00, 0.0099, 15.05, 1708 0.0109, 15.88, 0.0011, 17.07, 0.0076, 18.11, 0.0071, 19.12, 0.0045, 1709 20.16, 0.0038, 21.23, 0.0213, 22.27, 0.0332, 23.34, 0.0082, 24.34, 1710 0.0014, 25.42, 0.0024, 26.47, 0.0012, 27.54, 0.0014, 28.60, 0.0024, 1711 29.72, 0.0026, 30.10, 0.0008, 31.91, 0.0021, 32.13, 0.0011, 33.02, 1712 0.0007, 34.09, 0.0014, 35.17, 0.0007, 36.27, 0.0024, 37.39, 0.0029, 1713 38.58, 0.0014, 39.65, 0.0017, 40.95, 0.0012, 41.97, 0.0004, 42.43, 1714 0.0002, 43.49, 0.0001, 44.31, 0.0012, 45.42, 0.0031, 46.62, 0.0017, 1715 47.82, 0.0013, 49.14, 0.0013, 50.18, 0.0010, 51.54, 0.0003, 53.90, 1716 0.0006, 55.06, 0.0010, 56.31, 0.0003, 57.63, 0.0001, 59.02, 0.0003, 1717 60.09, 0.0004, 60.35, 0.0004, 61.62, 0.0009, 63.97, 0.0001, 65.19, 1718 0.0001, 65.54, 0.0002, 66.92, 0.0002, 67.94, 0.0002, 69.17, 0.0003, 1719 69.60, 0.0004, 70.88, 0.0002, 72.24, 0.0002, 76.12, 0.0001, 78.94, 1720 0.0001, 81.75, 0.0001, 82.06, 0.0001, 83.53, 0.0001, 90.29, 0.0002, 1721 91.75, 0.0001, 92.09, 0.0002, 93.28, 0.0001, 97.07, 0.0001], 1722 [1.98, 0.0159, 2.98, 0.1008, 3.98, 0.0365, 4.98, 0.0133, 5.97, 0.0101, 1723 6.97, 0.0115, 7.97, 0.0007, 8.99, 0.0349, 10.01, 0.0342, 11.01, 1724 0.0236, 12.00, 0.0041, 13.02, 0.0114, 14.05, 0.0137, 15.06, 0.0100, 1725 16.05, 0.0007, 17.04, 0.0009, 18.12, 0.0077, 19.15, 0.0023, 20.12, 1726 0.0017, 21.24, 0.0113, 22.26, 0.0126, 23.30, 0.0093, 24.36, 0.0007, 1727 25.43, 0.0007, 26.47, 0.0009, 27.55, 0.0013, 28.59, 0.0025, 29.61, 1728 0.0010, 30.77, 0.0021, 31.86, 0.0023, 32.96, 0.0003, 34.03, 0.0007, 1729 35.06, 0.0005, 36.20, 0.0006, 37.34, 0.0006, 38.36, 0.0009, 39.60, 1730 0.0016, 40.69, 0.0005, 41.77, 0.0002, 42.92, 0.0002, 44.02, 0.0003, 1731 45.24, 0.0006, 46.33, 0.0004, 47.50, 0.0007, 48.71, 0.0007, 49.87, 1732 0.0002, 51.27, 0.0002, 53.42, 0.0003, 55.88, 0.0003, 57.10, 0.0004, 1733 58.34, 0.0002, 59.86, 0.0003, 61.13, 0.0003, 67.18, 0.0001, 68.50, 1734 0.0001, 71.17, 0.0001, 83.91, 0.0001, 90.55, 0.0001], 1735 [0.98, 0.0099, 2.00, 0.0181, 2.99, 0.0353, 3.98, 0.0285, 4.97, 0.0514, 1736 5.96, 0.0402, 6.96, 0.0015, 7.98, 0.0012, 8.98, 0.0175, 9.98, 0.0264, 1737 10.98, 0.0392, 11.98, 0.0236, 13.00, 0.0153, 14.04, 0.0049, 15.00, 1738 0.0089, 16.01, 0.0001, 17.03, 0.0106, 18.03, 0.0028, 19.05, 0.0024, 1739 20.08, 0.0040, 21.11, 0.0103, 22.12, 0.0104, 23.20, 0.0017, 24.19, 1740 0.0008, 25.20, 0.0007, 26.24, 0.0011, 27.36, 0.0009, 27.97, 0.0030, 1741 29.40, 0.0044, 30.37, 0.0019, 31.59, 0.0017, 32.65, 0.0008, 33.59, 1742 0.0005, 34.79, 0.0009, 35.75, 0.0027, 36.88, 0.0035, 37.93, 0.0039, 1743 39.00, 0.0031, 40.08, 0.0025, 41.16, 0.0010, 43.25, 0.0004, 44.52, 1744 0.0012, 45.62, 0.0023, 45.85, 0.0012, 47.00, 0.0006, 47.87, 0.0008, 1745 48.99, 0.0003, 50.48, 0.0003, 51.62, 0.0001, 52.43, 0.0001, 53.56, 1746 0.0002, 54.76, 0.0002, 56.04, 0.0002, 56.68, 0.0006, 57.10, 0.0003, 1747 58.28, 0.0005, 59.47, 0.0003, 59.96, 0.0002, 60.67, 0.0001, 63.08, 1748 0.0002, 64.29, 0.0002, 66.72, 0.0001, 67.97, 0.0001, 68.65, 0.0001, 1749 70.43, 0.0001, 79.38, 0.0001, 80.39, 0.0001, 82.39, 0.0001], 1750 [1.00, 0.0765, 1.99, 0.0151, 2.99, 0.0500, 3.99, 0.0197, 5.00, 0.0260, 1751 6.00, 0.0145, 6.98, 0.0128, 7.97, 0.0004, 8.98, 0.0158, 9.99, 0.0265, 1752 11.02, 0.0290, 12.02, 0.0053, 13.03, 0.0242, 14.03, 0.0103, 15.06, 1753 0.0054, 16.04, 0.0006, 17.08, 0.0008, 18.10, 0.0058, 19.16, 0.0011, 1754 20.16, 0.0055, 21.18, 0.0040, 22.20, 0.0019, 23.22, 0.0014, 24.05, 1755 0.0005, 25.31, 0.0019, 26.38, 0.0018, 27.44, 0.0022, 28.45, 0.0024, 1756 29.57, 0.0073, 30.58, 0.0032, 31.66, 0.0071, 32.73, 0.0015, 33.85, 1757 0.0005, 34.96, 0.0003, 36.00, 0.0020, 37.11, 0.0018, 38.18, 0.0055, 1758 39.23, 0.0006, 40.33, 0.0004, 41.52, 0.0003, 43.41, 0.0028, 45.05, 1759 0.0003, 45.99, 0.0002, 47.07, 0.0003, 48.52, 0.0002, 49.48, 0.0003, 1760 50.63, 0.0003, 51.81, 0.0002, 54.05, 0.0002, 55.24, 0.0001, 56.62, 1761 0.0001, 57.81, 0.0004, 59.16, 0.0013, 60.23, 0.0003, 66.44, 0.0001, 1762 68.99, 0.0004, 75.49, 0.0001, 87.56, 0.0004], 1763 [0.98, 0.0629, 1.99, 0.0232, 2.98, 0.0217, 4.00, 0.0396, 4.98, 0.0171, 1764 5.97, 0.0098, 6.99, 0.0167, 7.99, 0.0003, 8.98, 0.0192, 9.98, 0.0266, 1765 10.99, 0.0256, 12.01, 0.0061, 13.02, 0.0135, 14.02, 0.0062, 15.05, 1766 0.0158, 16.06, 0.0018, 17.08, 0.0101, 18.09, 0.0053, 19.11, 0.0074, 1767 20.13, 0.0020, 21.17, 0.0052, 22.22, 0.0077, 23.24, 0.0035, 24.00, 1768 0.0009, 25.32, 0.0016, 26.40, 0.0022, 27.43, 0.0005, 28.55, 0.0026, 1769 29.60, 0.0026, 30.65, 0.0010, 31.67, 0.0019, 32.77, 0.0008, 33.81, 1770 0.0003, 34.91, 0.0003, 36.01, 0.0005, 37.11, 0.0010, 38.20, 0.0014, 1771 39.29, 0.0039, 40.43, 0.0012, 41.50, 0.0006, 43.38, 0.0017, 43.75, 1772 0.0002, 44.94, 0.0005, 46.13, 0.0002, 47.11, 0.0003, 48.28, 0.0005, 1773 48.42, 0.0005, 49.44, 0.0003, 50.76, 0.0004, 51.93, 0.0002, 54.15, 1774 0.0003, 55.31, 0.0005, 55.50, 0.0003, 56.98, 0.0003, 57.90, 0.0004, 1775 60.33, 0.0002, 61.39, 0.0001, 61.59, 0.0001, 65.09, 0.0002, 66.34, 1776 0.0001, 68.85, 0.0001, 70.42, 0.0002, 71.72, 0.0001, 73.05, 0.0003, 1777 79.65, 0.0001, 85.28, 0.0002, 93.52, 0.0001], 1778 [1.02, 0.0185, 1.99, 0.0525, 2.98, 0.0613, 3.99, 0.0415, 4.98, 0.0109, 1779 5.97, 0.0248, 6.99, 0.0102, 7.98, 0.0005, 8.98, 0.0124, 9.99, 0.0103, 1780 10.99, 0.0124, 12.00, 0.0016, 13.01, 0.0029, 14.03, 0.0211, 15.04, 1781 0.0128, 16.07, 0.0021, 17.09, 0.0009, 18.09, 0.0043, 19.14, 0.0022, 1782 20.13, 0.0016, 21.20, 0.0045, 22.21, 0.0088, 23.26, 0.0046, 24.29, 1783 0.0013, 25.35, 0.0009, 26.39, 0.0028, 27.49, 0.0009, 28.51, 0.0006, 1784 29.58, 0.0012, 30.70, 0.0010, 31.74, 0.0019, 32.75, 0.0002, 33.85, 1785 0.0001, 34.95, 0.0005, 36.02, 0.0003, 37.16, 0.0009, 38.25, 0.0018, 1786 39.35, 0.0008, 40.54, 0.0004, 41.61, 0.0002, 43.40, 0.0004, 43.74, 1787 0.0003, 45.05, 0.0001, 46.11, 0.0003, 47.40, 0.0002, 48.36, 0.0004, 1788 49.55, 0.0004, 50.72, 0.0002, 52.00, 0.0001, 55.58, 0.0002, 57.02, 1789 0.0001, 57.98, 0.0002, 59.13, 0.0003, 61.56, 0.0001, 66.56, 0.0001, 1790 87.65, 0.0002], 1791 [1.00, 0.0473, 1.99, 0.0506, 2.99, 0.0982, 3.99, 0.0654, 5.00, 0.0196, 1792 5.99, 0.0094, 6.99, 0.0118, 7.93, 0.0001, 8.99, 0.0057, 10.01, 0.0285, 1793 11.01, 0.0142, 12.03, 0.0032, 13.03, 0.0056, 14.06, 0.0064, 15.06, 1794 0.0059, 16.11, 0.0005, 17.09, 0.0033, 18.14, 0.0027, 19.15, 0.0014, 1795 20.17, 0.0010, 21.21, 0.0059, 22.26, 0.0043, 23.31, 0.0031, 24.31, 1796 0.0018, 25.33, 0.0009, 26.41, 0.0005, 27.47, 0.0015, 28.53, 0.0015, 1797 29.58, 0.0041, 30.65, 0.0025, 31.73, 0.0011, 32.83, 0.0010, 34.98, 1798 0.0003, 36.07, 0.0009, 37.23, 0.0001, 38.26, 0.0020, 39.41, 0.0014, 1799 40.53, 0.0005, 41.40, 0.0003, 42.80, 0.0002, 43.48, 0.0028, 43.93, 1800 0.0001, 45.03, 0.0003, 46.18, 0.0007, 47.41, 0.0001, 48.57, 0.0002, 1801 49.67, 0.0001, 50.83, 0.0002, 54.39, 0.0001, 55.58, 0.0002, 57.97, 1802 0.0005, 58.11, 0.0002, 59.21, 0.0001, 60.42, 0.0002, 61.66, 0.0001], 1803 [1.00, 0.0503, 2.00, 0.0963, 2.99, 0.1304, 3.99, 0.0218, 4.98, 0.0041, 1804 5.98, 0.0292, 6.98, 0.0482, 7.99, 0.0005, 8.99, 0.0280, 10.00, 0.0237, 1805 11.00, 0.0152, 12.02, 0.0036, 12.95, 0.0022, 14.06, 0.0111, 15.07, 1806 0.0196, 16.08, 0.0016, 17.11, 0.0044, 18.13, 0.0073, 19.17, 0.0055, 1807 20.19, 0.0028, 21.20, 0.0012, 22.27, 0.0068, 23.30, 0.0036, 24.35, 1808 0.0012, 25.35, 0.0002, 26.46, 0.0005, 27.47, 0.0005, 28.59, 0.0009, 1809 29.65, 0.0021, 30.70, 0.0020, 31.78, 0.0012, 32.89, 0.0010, 35.06, 1810 0.0005, 36.16, 0.0008, 37.27, 0.0010, 38.36, 0.0010, 39.47, 0.0014, 1811 40.58, 0.0004, 41.43, 0.0007, 41.82, 0.0003, 43.48, 0.0008, 44.53, 1812 0.0001, 45.25, 0.0003, 46.43, 0.0002, 47.46, 0.0002, 48.76, 0.0005, 1813 49.95, 0.0004, 50.96, 0.0002, 51.12, 0.0002, 52.33, 0.0001, 54.75, 1814 0.0001, 55.75, 0.0002, 56.90, 0.0002, 58.17, 0.0002, 59.40, 0.0004, 1815 60.62, 0.0002, 65.65, 0.0001, 66.91, 0.0002, 69.91, 0.0001, 71.25, 1816 0.0002], 1817 [1.00, 0.1243, 1.98, 0.1611, 3.00, 0.0698, 3.98, 0.0390, 5.00, 0.0138, 1818 5.99, 0.0154, 7.01, 0.0287, 8.01, 0.0014, 9.01, 0.0049, 10.00, 0.0144, 1819 11.01, 0.0055, 12.05, 0.0052, 13.01, 0.0011, 14.05, 0.0118, 15.07, 1820 0.0154, 16.12, 0.0028, 17.14, 0.0061, 18.25, 0.0007, 19.22, 0.0020, 1821 20.24, 0.0011, 21.27, 0.0029, 22.30, 0.0046, 23.34, 0.0049, 24.35, 1822 0.0004, 25.45, 0.0003, 26.47, 0.0007, 27.59, 0.0008, 28.16, 0.0009, 1823 29.12, 0.0002, 29.81, 0.0006, 30.81, 0.0009, 31.95, 0.0004, 33.00, 1824 0.0011, 34.12, 0.0005, 35.18, 0.0003, 36.30, 0.0008, 37.38, 0.0003, 1825 38.55, 0.0003, 39.64, 0.0006, 40.77, 0.0007, 41.52, 0.0006, 41.89, 1826 0.0006, 43.04, 0.0011, 43.60, 0.0009, 44.31, 0.0002, 45.68, 0.0002, 1827 46.56, 0.0003, 47.60, 0.0001, 48.83, 0.0006, 50.01, 0.0003, 51.27, 1828 0.0003, 56.04, 0.0005, 57.21, 0.0003, 58.56, 0.0004, 59.83, 0.0003, 1829 61.05, 0.0001, 62.20, 0.0001, 67.37, 0.0002, 76.53, 0.0001], 1830 [0.99, 0.0222, 1.99, 0.0678, 2.99, 0.0683, 4.00, 0.0191, 5.00, 0.0119, 1831 6.01, 0.0232, 6.98, 0.0336, 7.99, 0.0082, 9.01, 0.0201, 10.01, 0.0189, 1832 11.01, 0.0041, 12.01, 0.0053, 13.05, 0.0154, 14.04, 0.0159, 15.06, 1833 0.0092, 16.11, 0.0038, 17.12, 0.0014, 18.15, 0.0091, 19.16, 0.0006, 1834 20.30, 0.0012, 21.25, 0.0061, 22.28, 0.0099, 23.34, 0.0028, 24.38, 1835 0.0012, 25.43, 0.0016, 26.49, 0.0048, 27.55, 0.0025, 28.62, 0.0015, 1836 29.71, 0.0032, 30.78, 0.0077, 31.88, 0.0011, 32.97, 0.0007, 34.08, 1837 0.0006, 35.16, 0.0008, 36.28, 0.0004, 37.41, 0.0006, 38.54, 0.0005, 1838 39.62, 0.0002, 40.80, 0.0003, 41.93, 0.0001, 43.06, 0.0002, 44.21, 1839 0.0003, 45.38, 0.0002, 46.54, 0.0007, 47.78, 0.0003, 48.95, 0.0004, 1840 50.10, 0.0003, 51.37, 0.0002, 53.79, 0.0003, 56.20, 0.0001, 58.71, 1841 0.0002, 66.47, 0.0003], 1842 [1.01, 0.0241, 1.99, 0.1011, 2.98, 0.0938, 3.98, 0.0081, 4.99, 0.0062, 1843 5.99, 0.0291, 6.99, 0.0676, 7.59, 0.0004, 8.98, 0.0127, 9.99, 0.0112, 1844 10.99, 0.0142, 12.00, 0.0029, 13.02, 0.0071, 14.02, 0.0184, 15.03, 1845 0.0064, 16.07, 0.0010, 17.09, 0.0011, 18.11, 0.0010, 19.15, 0.0060, 1846 20.19, 0.0019, 21.24, 0.0025, 22.29, 0.0013, 23.31, 0.0050, 25.41, 1847 0.0030, 26.50, 0.0018, 27.53, 0.0006, 28.63, 0.0012, 29.66, 0.0013, 1848 30.77, 0.0020, 31.84, 0.0006, 34.04, 0.0001, 35.14, 0.0001, 36.32, 1849 0.0004, 37.41, 0.0007, 38.53, 0.0007, 39.67, 0.0009, 40.85, 0.0003, 1850 45.49, 0.0002, 46.65, 0.0001, 47.81, 0.0004, 49.01, 0.0002, 53.91, 1851 0.0002, 55.14, 0.0002, 57.69, 0.0002], 1852 [1.00, 0.0326, 2.00, 0.1066, 2.99, 0.1015, 4.00, 0.0210, 4.97, 0.0170, 1853 5.99, 0.0813, 6.98, 0.0820, 7.96, 0.0011, 8.99, 0.0248, 10.03, 0.0107, 1854 11.01, 0.0126, 12.01, 0.0027, 13.01, 0.0233, 14.04, 0.0151, 15.05, 1855 0.0071, 16.04, 0.0002, 17.10, 0.0061, 18.12, 0.0059, 19.15, 0.0087, 1856 20.23, 0.0005, 21.25, 0.0040, 22.30, 0.0032, 23.35, 0.0004, 24.40, 1857 0.0001, 25.45, 0.0030, 26.54, 0.0022, 27.60, 0.0003, 28.70, 0.0009, 1858 29.80, 0.0029, 30.85, 0.0006, 31.97, 0.0006, 34.19, 0.0004, 35.30, 1859 0.0003, 36.43, 0.0007, 37.56, 0.0005, 38.68, 0.0019, 39.88, 0.0013, 1860 41.00, 0.0003, 43.35, 0.0003, 44.51, 0.0002, 45.68, 0.0006, 46.93, 1861 0.0010, 48.11, 0.0006, 49.29, 0.0003, 55.58, 0.0002], 1862 [0.98, 0.0113, 1.99, 0.0967, 3.00, 0.0719, 3.98, 0.0345, 4.98, 0.0121, 1863 6.00, 0.0621, 7.00, 0.0137, 7.98, 0.0006, 9.01, 0.0314, 10.01, 0.0171, 1864 11.02, 0.0060, 12.03, 0.0024, 13.05, 0.0077, 14.07, 0.0040, 15.12, 1865 0.0032, 16.13, 0.0004, 17.15, 0.0011, 18.20, 0.0028, 19.18, 0.0003, 1866 20.26, 0.0003, 21.31, 0.0025, 22.35, 0.0021, 23.39, 0.0005, 25.55, 1867 0.0002, 26.62, 0.0014, 27.70, 0.0003, 28.78, 0.0005, 29.90, 0.0030, 1868 31.01, 0.0011, 32.12, 0.0005, 34.31, 0.0001, 35.50, 0.0002, 36.62, 1869 0.0002, 37.76, 0.0005, 38.85, 0.0002, 40.09, 0.0004, 43.60, 0.0001, 1870 44.73, 0.0002, 46.02, 0.0002, 47.25, 0.0004, 48.44, 0.0004], 1871 [0.99, 0.0156, 1.98, 0.0846, 2.98, 0.0178, 3.98, 0.0367, 4.98, 0.0448, 1872 5.98, 0.0113, 6.99, 0.0189, 8.00, 0.0011, 9.01, 0.0247, 10.02, 0.0089, 1873 11.01, 0.0184, 12.03, 0.0105, 13.00, 0.0039, 14.07, 0.0116, 15.09, 1874 0.0078, 16.13, 0.0008, 17.14, 0.0064, 18.19, 0.0029, 19.22, 0.0028, 1875 20.25, 0.0017, 21.32, 0.0043, 22.37, 0.0055, 23.42, 0.0034, 24.48, 1876 0.0004, 25.54, 0.0002, 26.61, 0.0017, 27.70, 0.0011, 28.80, 0.0002, 1877 29.89, 0.0019, 30.97, 0.0028, 32.09, 0.0007, 34.30, 0.0002, 35.44, 1878 0.0003, 36.55, 0.0001, 37.69, 0.0004, 38.93, 0.0002, 40.05, 0.0005, 1879 41.20, 0.0005, 42.37, 0.0002, 43.54, 0.0003, 44.73, 0.0001, 45.95, 1880 0.0002, 47.16, 0.0001, 48.43, 0.0005, 49.65, 0.0004, 55.90, 0.0002, 1881 59.81, 0.0004], 1882 [1.01, 0.0280, 2.00, 0.0708, 2.99, 0.0182, 3.99, 0.0248, 4.98, 0.0245, 1883 5.98, 0.0279, 6.98, 0.0437, 7.99, 0.0065, 8.99, 0.0299, 10.00, 0.0073, 1884 10.99, 0.0011, 12.03, 0.0122, 13.03, 0.0028, 14.08, 0.0044, 15.11, 1885 0.0097, 16.15, 0.0010, 17.17, 0.0025, 18.19, 0.0017, 19.24, 0.0008, 1886 20.28, 0.0040, 21.32, 0.0024, 22.38, 0.0008, 23.46, 0.0032, 24.52, 1887 0.0010, 25.59, 0.0008, 26.68, 0.0009, 27.76, 0.0012, 28.88, 0.0003, 1888 29.95, 0.0005, 31.05, 0.0017, 32.14, 0.0002, 33.29, 0.0003, 37.88, 1889 0.0002, 39.03, 0.0002, 40.19, 0.0004, 41.37, 0.0003, 43.74, 0.0002, 1890 46.20, 0.0001, 48.68, 0.0001, 49.93, 0.0001, 51.19, 0.0002], 1891 [1.00, 0.0225, 1.99, 0.0921, 2.98, 0.0933, 3.99, 0.0365, 4.99, 0.0100, 1892 5.98, 0.0213, 6.98, 0.0049, 7.98, 0.0041, 8.98, 0.0090, 9.99, 0.0068, 1893 11.01, 0.0040, 12.03, 0.0086, 13.02, 0.0015, 14.04, 0.0071, 15.09, 1894 0.0082, 16.14, 0.0011, 17.15, 0.0014, 18.18, 0.0010, 19.26, 0.0013, 1895 20.26, 0.0005, 21.33, 0.0006, 22.36, 0.0011, 23.46, 0.0016, 24.52, 1896 0.0004, 25.59, 0.0002, 26.70, 0.0006, 27.78, 0.0007, 28.87, 0.0002, 1897 30.03, 0.0008, 31.14, 0.0010, 32.24, 0.0006, 33.37, 0.0002, 35.67, 1898 0.0003, 37.99, 0.0004, 39.17, 0.0004, 40.35, 0.0005, 41.53, 0.0001, 1899 46.42, 0.0001], 1900 [1.00, 0.0465, 1.99, 0.0976, 2.98, 0.0678, 4.00, 0.0727, 4.99, 0.0305, 1901 5.98, 0.0210, 6.98, 0.0227, 8.00, 0.0085, 9.01, 0.0183, 10.02, 0.0258, 1902 11.05, 0.0003, 12.06, 0.0061, 13.05, 0.0021, 14.10, 0.0089, 15.12, 1903 0.0077, 16.16, 0.0016, 17.21, 0.0061, 18.23, 0.0011, 19.29, 0.0031, 1904 20.36, 0.0031, 21.41, 0.0007, 22.48, 0.0013, 23.55, 0.0020, 24.64, 1905 0.0004, 25.74, 0.0005, 26.81, 0.0006, 27.95, 0.0006, 29.03, 0.0001, 1906 30.22, 0.0010, 31.30, 0.0004, 32.48, 0.0001, 33.60, 0.0002, 38.30, 1907 0.0003], 1908 [1.00, 0.0674, 1.99, 0.0841, 2.98, 0.0920, 3.99, 0.0328, 4.99, 0.0368, 1909 5.98, 0.0206, 6.99, 0.0246, 8.01, 0.0048, 9.01, 0.0218, 10.03, 0.0155, 1910 11.05, 0.0048, 12.06, 0.0077, 13.00, 0.0020, 14.10, 0.0083, 15.15, 1911 0.0084, 16.18, 0.0015, 17.22, 0.0039, 18.27, 0.0032, 19.34, 0.0026, 1912 20.40, 0.0012, 21.47, 0.0009, 22.54, 0.0008, 23.62, 0.0016, 24.71, 1913 0.0005, 25.82, 0.0004, 26.91, 0.0002, 28.03, 0.0008, 29.17, 0.0002, 1914 30.32, 0.0028, 31.45, 0.0004, 32.61, 0.0005, 33.77, 0.0001, 36.14, 1915 0.0003, 37.32, 0.0002, 38.54, 0.0005, 39.75, 0.0002, 42.23, 0.0002, 1916 48.65, 0.0001], 1917 [1.01, 0.0423, 1.99, 0.0240, 2.98, 0.0517, 4.00, 0.0493, 5.00, 0.0324, 1918 6.00, 0.0094, 6.99, 0.0449, 7.99, 0.0050, 9.00, 0.0197, 10.03, 0.0132, 1919 11.03, 0.0009, 12.07, 0.0017, 13.08, 0.0023, 14.12, 0.0094, 15.16, 1920 0.0071, 16.21, 0.0020, 17.25, 0.0005, 18.30, 0.0027, 19.04, 0.0004, 1921 20.43, 0.0022, 21.51, 0.0002, 22.59, 0.0006, 23.72, 0.0018, 24.80, 1922 0.0002, 25.88, 0.0002, 27.03, 0.0002, 28.09, 0.0006, 29.31, 0.0002, 1923 30.46, 0.0004, 31.61, 0.0007, 32.78, 0.0005, 33.95, 0.0001, 36.34, 1924 0.0002, 37.56, 0.0001, 38.80, 0.0001, 40.02, 0.0001, 44.14, 0.0001], 1925 [1.00, 0.0669, 1.99, 0.0909, 2.99, 0.0410, 3.98, 0.0292, 4.98, 0.0259, 1926 5.98, 0.0148, 6.98, 0.0319, 7.99, 0.0076, 9.01, 0.0056, 10.02, 0.0206, 1927 11.04, 0.0032, 12.05, 0.0085, 13.08, 0.0040, 14.12, 0.0037, 15.16, 1928 0.0030, 16.20, 0.0013, 17.24, 0.0021, 18.30, 0.0010, 19.36, 0.0015, 1929 20.44, 0.0013, 21.50, 0.0009, 22.60, 0.0015, 23.69, 0.0014, 24.80, 1930 0.0006, 25.87, 0.0002, 27.02, 0.0006, 28.12, 0.0002, 29.28, 0.0003, 1931 30.43, 0.0002, 31.59, 0.0007, 32.79, 0.0001, 35.14, 0.0001, 37.57, 1932 0.0001, 40.03, 0.0002, 41.28, 0.0004, 44.10, 0.0001], 1933 [0.99, 0.0421, 1.99, 0.1541, 2.98, 0.0596, 3.98, 0.0309, 4.98, 0.0301, 1934 5.99, 0.0103, 7.00, 0.0240, 8.01, 0.0073, 9.01, 0.0222, 10.04, 0.0140, 1935 11.05, 0.0033, 12.08, 0.0045, 13.13, 0.0009, 14.13, 0.0015, 15.21, 1936 0.0026, 16.24, 0.0003, 17.30, 0.0004, 18.35, 0.0010, 19.39, 0.0003, 1937 20.50, 0.0015, 21.57, 0.0003, 22.68, 0.0011, 23.80, 0.0005, 24.90, 1938 0.0008, 26.02, 0.0002, 27.16, 0.0001, 28.30, 0.0006, 29.48, 0.0002, 1939 31.81, 0.0005, 33.00, 0.0003, 34.21, 0.0001, 37.89, 0.0001], 1940 [0.99, 0.0389, 2.00, 0.2095, 3.00, 0.0835, 3.99, 0.0289, 5.00, 0.0578, 1941 5.99, 0.0363, 7.01, 0.0387, 8.01, 0.0056, 9.04, 0.0173, 10.05, 0.0175, 1942 11.08, 0.0053, 12.10, 0.0056, 13.15, 0.0064, 14.19, 0.0036, 15.22, 1943 0.0019, 16.29, 0.0010, 17.36, 0.0017, 18.43, 0.0018, 19.51, 0.0004, 1944 20.60, 0.0011, 21.70, 0.0003, 22.82, 0.0003, 23.95, 0.0001, 25.05, 1945 0.0004, 26.17, 0.0001, 28.50, 0.0003, 29.68, 0.0001, 32.07, 0.0003, 1946 33.28, 0.0004, 34.52, 0.0001], 1947 [1.00, 0.1238, 1.99, 0.2270, 3.00, 0.0102, 3.99, 0.0181, 4.98, 0.0415, 1948 6.00, 0.0165, 7.01, 0.0314, 8.02, 0.0148, 9.04, 0.0203, 10.05, 0.0088, 1949 11.07, 0.0062, 12.11, 0.0070, 13.14, 0.0054, 14.19, 0.0028, 15.24, 1950 0.0044, 16.30, 0.0029, 17.38, 0.0009, 18.45, 0.0026, 19.56, 0.0003, 1951 20.65, 0.0025, 21.74, 0.0014, 22.87, 0.0013, 23.99, 0.0007, 25.15, 1952 0.0002, 27.46, 0.0004, 28.39, 0.0006, 28.65, 0.0004, 29.85, 0.0001, 1953 31.05, 0.0002, 32.27, 0.0003, 33.52, 0.0002, 34.76, 0.0003], 1954 [1.00, 0.1054, 2.00, 0.2598, 2.99, 0.0369, 3.98, 0.0523, 4.99, 0.0020, 1955 5.99, 0.0051, 7.00, 0.0268, 8.01, 0.0027, 9.04, 0.0029, 10.05, 0.0081, 1956 11.08, 0.0047, 12.12, 0.0051, 13.16, 0.0091, 14.19, 0.0015, 15.27, 1957 0.0030, 16.34, 0.0017, 17.42, 0.0006, 18.51, 0.0003, 19.61, 0.0007, 1958 20.72, 0.0003, 21.84, 0.0001, 22.99, 0.0010, 24.13, 0.0001, 28.44, 1959 0.0001, 30.09, 0.0001], 1960 [0.99, 0.0919, 2.00, 0.0418, 2.99, 0.0498, 3.99, 0.0135, 4.99, 0.0026, 1961 6.00, 0.0155, 7.01, 0.0340, 8.02, 0.0033, 9.04, 0.0218, 10.08, 0.0084, 1962 11.11, 0.0057, 12.15, 0.0051, 13.21, 0.0043, 14.25, 0.0015, 15.31, 1963 0.0023, 16.40, 0.0008, 17.48, 0.0004, 18.59, 0.0016, 19.71, 0.0010, 1964 20.84, 0.0018, 21.98, 0.0002, 23.11, 0.0013, 24.26, 0.0003, 26.67, 1965 0.0002, 29.12, 0.0002, 30.37, 0.0002, 31.62, 0.0003, 32.92, 0.0001], 1966 [0.99, 0.1174, 1.99, 0.1126, 2.99, 0.0370, 3.99, 0.0159, 5.01, 0.0472, 1967 6.01, 0.0091, 7.03, 0.0211, 8.05, 0.0015, 9.07, 0.0098, 10.11, 0.0038, 1968 11.15, 0.0042, 12.20, 0.0018, 13.24, 0.0041, 14.32, 0.0033, 15.41, 1969 0.0052, 16.49, 0.0001, 17.61, 0.0004, 18.71, 0.0004, 19.84, 0.0004, 1970 20.99, 0.0002, 22.14, 0.0006, 23.31, 0.0006, 24.50, 0.0004, 25.70, 1971 0.0002, 28.09, 0.0002, 28.66, 0.0002, 32.00, 0.0001], 1972 [1.00, 0.1085, 2.00, 0.1400, 2.99, 0.0173, 3.99, 0.0229, 5.00, 0.0272, 1973 6.02, 0.0077, 7.03, 0.0069, 8.04, 0.0017, 9.08, 0.0045, 10.10, 0.0030, 1974 11.15, 0.0040, 12.20, 0.0007, 13.25, 0.0019, 14.32, 0.0008, 15.42, 1975 0.0024, 16.50, 0.0002, 17.59, 0.0005, 18.71, 0.0003, 19.83, 0.0002, 1976 20.98, 0.0005, 23.29, 0.0008], 1977 [1.00, 0.0985, 2.00, 0.1440, 2.99, 0.0364, 3.99, 0.0425, 5.00, 0.0190, 1978 6.01, 0.0089, 7.03, 0.0278, 8.04, 0.0006, 9.07, 0.0083, 10.10, 0.0021, 1979 11.14, 0.0050, 12.18, 0.0005, 13.26, 0.0036, 14.33, 0.0005, 15.41, 1980 0.0026, 17.62, 0.0004, 18.75, 0.0004, 19.89, 0.0003, 21.04, 0.0012, 1981 22.21, 0.0002, 23.38, 0.0004, 27.04, 0.0001], 1982 [0.99, 0.1273, 2.00, 0.1311, 2.99, 0.0120, 4.00, 0.0099, 5.00, 0.0235, 1983 6.02, 0.0068, 7.03, 0.0162, 8.06, 0.0009, 9.08, 0.0083, 10.12, 0.0014, 1984 11.17, 0.0050, 12.24, 0.0010, 13.29, 0.0013, 14.39, 0.0022, 15.48, 1985 0.0011, 16.59, 0.0002, 17.70, 0.0003, 18.84, 0.0010, 20.00, 0.0003, 1986 21.17, 0.0003, 23.56, 0.0004, 28.79, 0.0003], 1987 [1.00, 0.1018, 2.00, 0.1486, 3.00, 0.0165, 4.00, 0.0186, 5.01, 0.0194, 1988 6.02, 0.0045, 7.04, 0.0083, 8.06, 0.0012, 9.10, 0.0066, 10.15, 0.0009, 1989 11.19, 0.0008, 12.26, 0.0011, 13.34, 0.0028, 14.45, 0.0006, 15.53, 1990 0.0009, 16.66, 0.0002, 17.79, 0.0006, 18.94, 0.0005, 20.11, 0.0003, 1991 21.29, 0.0005, 22.49, 0.0003, 23.73, 0.0005, 26.22, 0.0001, 27.52, 1992 0.0001, 28.88, 0.0002], 1993 [1.00, 0.1889, 1.99, 0.1822, 3.00, 0.0363, 4.00, 0.0047, 5.01, 0.0202, 1994 6.03, 0.0053, 7.05, 0.0114, 8.01, 0.0002, 9.13, 0.0048, 10.17, 0.0010, 1995 11.23, 0.0033, 12.30, 0.0010, 13.38, 0.0006, 14.50, 0.0002, 15.62, 1996 0.0010, 20.27, 0.0001, 21.47, 0.0001], 1997 [1.00, 0.0522, 1.99, 0.0763, 2.99, 0.0404, 4.00, 0.0139, 5.01, 0.0185, 1998 6.01, 0.0021, 7.06, 0.0045, 8.09, 0.0002, 9.11, 0.0003, 10.17, 0.0006, 1999 11.25, 0.0004, 12.32, 0.0005, 13.40, 0.0003, 14.53, 0.0003, 15.65, 2000 0.0007, 16.80, 0.0001, 17.95, 0.0002, 19.14, 0.0006, 20.34, 0.0002, 2001 21.56, 0.0003], 2002 [0.99, 0.1821, 1.99, 0.0773, 3.00, 0.0125, 4.01, 0.0065, 5.01, 0.0202, 2003 6.03, 0.0071, 7.05, 0.0090, 8.08, 0.0006, 9.13, 0.0008, 10.18, 0.0013, 2004 11.25, 0.0010, 12.33, 0.0012, 13.42, 0.0006, 14.54, 0.0005, 15.65, 2005 0.0004, 17.97, 0.0002, 19.15, 0.0001], 2006 [1.00, 0.1868, 2.00, 0.0951, 3.00, 0.0147, 4.01, 0.0134, 5.02, 0.0184, 2007 6.04, 0.0132, 7.06, 0.0011, 8.11, 0.0008, 9.15, 0.0010, 10.22, 0.0012, 2008 11.30, 0.0011, 12.40, 0.0003, 13.11, 0.0004, 13.49, 0.0002, 14.62, 2009 0.0003, 15.77, 0.0001], 2010 [1.00, 0.1933, 2.00, 0.0714, 3.00, 0.0373, 4.00, 0.0108, 5.02, 0.0094, 2011 6.02, 0.0010, 7.07, 0.0022, 8.11, 0.0002, 9.16, 0.0065, 10.23, 0.0015, 2012 11.31, 0.0023, 12.40, 0.0003, 13.53, 0.0014, 14.66, 0.0002, 15.81, 2013 0.0011, 18.20, 0.0002, 19.41, 0.0001], 2014 [0.99, 0.2113, 1.99, 0.0877, 3.00, 0.0492, 4.01, 0.0094, 5.02, 0.0144, 2015 6.04, 0.0103, 7.07, 0.0117, 8.12, 0.0006, 9.19, 0.0019, 10.25, 0.0007, 2016 11.35, 0.0017, 12.45, 0.0010, 13.58, 0.0003, 14.74, 0.0003, 15.91, 2017 0.0003, 19.57, 0.0002], 2018 [0.99, 0.2455, 1.99, 0.0161, 3.00, 0.0215, 4.01, 0.0036, 5.03, 0.0049, 2019 6.04, 0.0012, 7.09, 0.0036, 8.14, 0.0011, 9.21, 0.0009, 10.30, 0.0001, 2020 11.40, 0.0012, 12.50, 0.0001, 13.66, 0.0005, 14.84, 0.0001], 2021 [1.00, 0.1132, 2.00, 0.0252, 3.00, 0.0292, 4.01, 0.0136, 5.03, 0.0045, 2022 6.06, 0.0022, 7.11, 0.0101, 8.17, 0.0004, 9.23, 0.0010, 10.33, 0.0012, 2023 11.44, 0.0013, 12.58, 0.0011, 13.75, 0.0002, 14.93, 0.0005, 16.14, 0.0002], 2024 [1.00, 0.1655, 2.00, 0.0445, 3.00, 0.0120, 4.00, 0.0038, 5.02, 0.0015, 2025 6.07, 0.0038, 7.11, 0.0003, 8.19, 0.0002, 9.25, 0.0010, 10.36, 0.0011, 2026 11.48, 0.0005, 12.63, 0.0002, 13.79, 0.0003, 16.24, 0.0002], 2027 [0.99, 0.3637, 1.99, 0.0259, 3.01, 0.0038, 4.01, 0.0057, 5.03, 0.0040, 2028 6.07, 0.0067, 7.12, 0.0014, 8.19, 0.0004, 9.27, 0.0003, 10.38, 0.0002, 2029 12.67, 0.0001], 2030 [1.00, 0.1193, 2.00, 0.0230, 3.00, 0.0104, 4.01, 0.0084, 5.04, 0.0047, 2031 6.08, 0.0035, 7.13, 0.0041, 8.20, 0.0002, 9.29, 0.0005, 10.40, 0.0005, 2032 11.53, 0.0003, 12.70, 0.0002, 13.91, 0.0002], 2033 [1.00, 0.0752, 2.00, 0.0497, 3.00, 0.0074, 4.02, 0.0076, 5.05, 0.0053, 2034 6.09, 0.0043, 7.15, 0.0024, 8.22, 0.0001, 9.32, 0.0006, 10.45, 0.0002, 2035 11.58, 0.0001, 12.78, 0.0001, 15.22, 0.0001], 2036 [1.00, 0.2388, 2.00, 0.0629, 3.01, 0.0159, 4.04, 0.0063, 5.07, 0.0051, 2037 6.12, 0.0045, 7.19, 0.0026, 8.29, 0.0015, 9.43, 0.0001, 11.75, 0.0002], 2038 [1.00, 0.1919, 2.01, 0.0116, 3.01, 0.0031, 4.03, 0.0090, 5.07, 0.0061, 2039 6.13, 0.0036, 7.19, 0.0013, 8.30, 0.0016, 9.13, 0.0001, 10.59, 0.0002, 2040 11.78, 0.0002], 2041 [1.00, 0.1296, 2.00, 0.0135, 3.01, 0.0041, 4.04, 0.0045, 5.09, 0.0028, 2042 6.14, 0.0046, 7.23, 0.0007, 8.32, 0.0007, 9.50, 0.0001], 2043 [1.00, 0.0692, 2.00, 0.0209, 3.02, 0.0025, 4.05, 0.0030, 5.09, 0.0047, 2044 6.17, 0.0022, 7.25, 0.0015, 8.36, 0.0015, 9.53, 0.0010, 10.69, 0.0001, 2045 13.40, 0.0001], 2046 [1.00, 0.1715, 2.00, 0.0142, 3.01, 0.0024, 4.03, 0.0015, 5.07, 0.0017, 2047 6.13, 0.0018, 7.22, 0.0009, 8.33, 0.0014, 9.51, 0.0007, 10.69, 0.0002], 2048 [1.00, 0.1555, 2.01, 0.0148, 3.02, 0.0007, 4.06, 0.0006, 5.10, 0.0005, 2049 6.16, 0.0008, 7.26, 0.0009, 8.39, 0.0008, 9.58, 0.0002], 2050 [1.00, 0.1357, 2.00, 0.0116, 3.02, 0.0026, 4.04, 0.0009, 5.09, 0.0004, 2051 6.17, 0.0005, 7.27, 0.0002, 8.40, 0.0001], 2052 [1.00, 0.2185, 2.01, 0.0087, 3.03, 0.0018, 4.06, 0.0025, 5.11, 0.0020, 2053 6.20, 0.0012, 7.32, 0.0005, 8.46, 0.0001, 9.66, 0.0003], 2054 [1.00, 0.2735, 2.00, 0.0038, 3.02, 0.0008, 4.06, 0.0012, 5.12, 0.0008, 2055 6.22, 0.0011, 7.35, 0.0003, 8.50, 0.0002], 2056 [1.00, 0.1441, 1.99, 0.0062, 3.01, 0.0023, 4.05, 0.0011, 5.11, 0.0012, 2057 6.20, 0.0003, 7.33, 0.0004, 8.50, 0.0001], 2058 [1.00, 0.0726, 2.01, 0.0293, 3.03, 0.0022, 5.14, 0.0005, 6.26, 0.0011, 2059 7.41, 0.0002, 8.63, 0.0002], 2060 [1.00, 0.0516, 2.00, 0.0104, 3.02, 0.0029, 5.15, 0.0002, 6.27, 0.0001], 2061 [1.00, 0.0329, 2.00, 0.0033, 3.03, 0.0013, 4.10, 0.0005, 5.19, 2062 0.0004, 6.32, 0.0002], 2063 [1.00, 0.0179, 1.99, 0.0012, 3.04, 0.0005, 4.10, 0.0017, 5.20, 0.0005, 2064 6.35, 0.0001], 2065 [1.00, 0.0334, 2.01, 0.0033, 3.04, 0.0011, 4.13, 0.0003, 5.22, 0.0003], 2066 [0.99, 0.0161, 2.01, 0.0100, 3.04, 0.0020, 4.13, 0.0003], 2067 [1.00, 0.0475, 1.99, 0.0045, 3.03, 0.0035, 4.12, 0.0011], 2068 [1.00, 0.0593, 2.00, 0.0014, 4.17, 0.0002], 2069 [1.00, 0.0249, 2.01, 0.0016], 2070 [1.00, 0.0242, 2.00, 0.0038, 4.19, 0.0002], 2071 [1.00, 0.0170, 2.02, 0.0030], 2072 [1.00, 0.0381, 2.00, 0.0017, 3.09, 0.0002], 2073 [1.00, 0.0141, 2.03, 0.0005, 3.11, 0.0003, 4.26, 0.0001], 2074 [1.00, 0.0122, 2.03, 0.0024], 2075 [1.00, 0.0107, 2.07, 0.0007, 3.12, 0.0004], 2076 [1.00, 0.0250, 2.02, 0.0026, 3.15, 0.0002], 2077 [1.01, 0.0092], 2078 [1.01, 0.0102, 2.09, 0.0005], 2079 [1.00, 0.0080, 2.00, 0.0005, 3.19, 0.0001], 2080 [1.01, 0.0298, 2.01, 0.0005]] 2081 2082def lbj_piano(start, dur, freq, amp, *args) 2083 pfreq, degree, distance, reverb_amount = nil 2084 optkey(args, binding, 2085 [:pfreq, freq], 2086 [:degree, 45.0], 2087 [:distance, 1.0], 2088 [:reverb_amount, 0.0]) 2089 get_piano_partials = lambda do |frq| 2090 Piano_Spectra[(12 * (log(frq / 32.703) / log(2))).round] 2091 end 2092 make_piano_ampfun = lambda do |dr| 2093 release_amp = db2linear($clm_db_drop_per_second * dr) 2094 attack_time = $clm_piano_attack_duration * 100.0 / dr 2095 [0, 0, attack_time / 4, 1.0, attack_time, 1.0, 100, release_amp] 2096 end 2097 # This thing sounds pretty good down low, below middle c or so. 2098 # Unfortunately, there are some tens of partials down there and 2099 # we're using exponential envelopes. You're going to wait for a 2100 # long long time just to hear a single low note. The high notes 2101 # sound pretty rotten--they just don't sparkle; I have a feeling 2102 # that this is due to the low amplitude of the original data, and 2103 # the lack of mechanical noise. 2104 # 2105 # The only thing you can do to alter the sound of a piano note is to 2106 # set the pfreq parameter. Pfreq is used to look up the partials. 2107 # By default, it's set to the requested frequency. Setting it to a 2108 # neighboring freq is useful when you're repeating notes. Note that 2109 # there's no nyquist detection; a high freq with a low pfreq, will 2110 # give you fold over (hmmm...maybe I can get those high notes to 2111 # sparkle after all). 2112 partials = normalize_partials(get_piano_partials.call(pfreq)) 2113 newdur = dur + $clm_piano_attack_duration + $clm_piano_release_duration 2114 env1dur = newdur - $clm_piano_release_duration 2115 env1samples = (env1dur * @srate).floor 2116 siz = (partials.length / 2).floor 2117 oscils = Array.new(siz) 2118 alist = make_vct(siz) 2119 ampfun1 = make_piano_ampfun.call(env1dur) 2120 ampenv1 = make_env(:envelope, ampfun1, :scaler, amp, 2121 :duration, env1dur, :base, 10000.0) 2122 releaseamp = ampfun1.last 2123 ampenv2 = make_env(:envelope, [0, 1, 100, 0], :scaler, amp * releaseamp, 2124 :duration, env1dur, :base, 1.0) 2125 sktr = j = 0 2126 0.step(partials.length - 1, 2) do |i| 2127 alist[j] = partials[i + 1] 2128 oscils[j] = make_oscil(:frequency, partials[i] * freq) 2129 j += 1 2130 end 2131 run_instrument(start, newdur, 2132 :degree, degree, 2133 :distance, distance, 2134 :reverb_amount, reverb_amount) do 2135 sktr += 1 2136 let(0.0) do |sum| 2137 oscils.each_with_index do |osc, i| 2138 sum = sum + oscil(osc) * alist[i] 2139 end 2140 sum * env(((sktr > env1samples) ? ampenv2 : ampenv1)) 2141 end 2142 end 2143end 2144 2145def lbj_piano_test(start = 0.0, dur = 1.0) 2146 lbj_piano(start, dur, 440.0, 0.5) 2147 $now = start + dur + 0.24 + 0.2 2148end 2149 2150# RESFLT 2151def resflt(start, dur, driver, 2152 ranfreq, noiamp, noifun, cosamp, cosfreq1, cosfreq0, cosnum, 2153 ampcosfun, freqcosfun, 2154 frq1, r1, g1, frq2, r2, g2, frq3, r3, g3, *args) 2155 degree, distance, reverb_amount = nil 2156 optkey(args, binding, 2157 [:degree, 0.0], 2158 [:distance, 1.0], 2159 [:reverb_amount, 0.005]) 2160 # driver=0 -- use sum of cosines to drive the filter, 2161 # driver=1 -- use white noise 2162 # if noise used, ranfreq=frequency of random number generator, 2163 # noiamp=amplitude thereof, 2164 # noifun=amplitude envelope on white noise 2165 # if sum-of-cosines (i.e. a band-limited pulse train), 2166 # cosamp=amplitude of pulse train, 2167 # cosfreq1=top frequency (given freqcosfun) 2168 # (i.e. pulse frequency) 2169 # cosfreq0=bottom frequency, 2170 # cosnum=number of cosines in the pulse, 2171 # ampcosfun=amplitude envelope on pulse train 2172 # freqcosfun=frequency envelope on pulse train 2173 # There are then 3 resonators, centered at frq1, frq2, frq3, 2174 # with pole-radius r1, r2, and r3 respectively, and 2175 # with gains of g1, g2, and g3. 2176 f1 = make_two_pole(frq1, r1) 2177 f2 = make_two_pole(frq2, r2) 2178 f3 = make_two_pole(frq3, r3) 2179 with_noise = (driver == 1) 2180 frqf = if with_noise 2181 nil 2182 else 2183 make_env(:envelope, freqcosfun, :duration, dur, 2184 :scaler, hz2radians(cosfreq1 - cosfreq0)) 2185 end 2186 ampf = if with_noise 2187 make_env(:envelope, noifun, :scaler, noiamp, :duration, dur) 2188 else 2189 make_env(:envelope, ampcosfun, :scaler, cosamp, :duration, dur) 2190 end 2191 rn = if with_noise 2192 make_rand(:frequency, ranfreq) 2193 else 2194 nil 2195 end 2196 cn = if with_noise 2197 nil 2198 else 2199 make_sum_of_cosines(:frequency, cosfreq0, :cosines, cosnum) 2200 end 2201 if with_noise 2202 run_instrument(start, dur, 2203 :distance, distance, 2204 :degree, degree, 2205 :reverb_amount, reverb_amount) do 2206 input1 = env(ampf) * rand(rn) 2207 two_pole(f1, input1 * g1) + 2208 two_pole(f2, input1 * g2) + 2209 two_pole(f3, input1 * g3) 2210 end 2211 else 2212 run_instrument(start, dur, 2213 :distance, distance, 2214 :degree, degree, 2215 :reverb_amount, reverb_amount) do 2216 input1 = env(ampf) * sum_of_cosines(cn, env(frqf)) 2217 two_pole(f1, input1 * g1) + 2218 two_pole(f2, input1 * g2) + 2219 two_pole(f3, input1 * g3) 2220 end 2221 end 2222end 2223 2224def resflt_test(start = 0.0, dur = 1.0) 2225 $now = start 2226 resflt($now, dur, 0, 0, 0, nil, 2227 0.1, 200, 230, 10, [0, 0, 50, 1, 100, 0], [0, 0, 100, 1], 2228 500, 0.995, 0.1, 1000, 0.995, 0.1, 2000, 0.995, 0.1) 2229 $now += dur + 0.2 2230 resflt($now, dur, 1, 10000, 0.01, [0, 0, 50, 1, 100, 0], 2231 0, 0, 0, 0, nil, nil, 2232 500, 0.995, 0.1, 1000, 0.995, 0.1, 2000, 0.995, 0.1) 2233 $now += dur + 0.2 2234end 2235 2236# SCRATCH 2237def scratch(start, file, src_ratio, turntable) 2238 assert_type(File.exist?(file), file, 1, "an existing file") 2239 f = make_file2sample(file) 2240 turn_i = 1 2241 turns = turntable.length 2242 cur_sample = seconds2samples(turntable[0]) 2243 turn_sample = seconds2samples(turntable[turn_i]) 2244 rd = make_src(:srate, src_ratio) 2245 forwards = (src_ratio > 0.0) 2246 set_mus_increment(rd, -src_ratio) if forwards and turn_sample < cur_sample 2247 turning = 0 2248 last_val = last_val2 = 0.0 2249 run_instrument(start, ws_duration(file)) do 2250 break if turn_i >= turns 2251 val = src(rd, 0.0, lambda do |dir| 2252 inval = file2sample(f, cur_sample) 2253 cur_sample += dir 2254 inval 2255 end) 2256 if turning.zero? 2257 # we past turn point going forwards 2258 if forwards and cur_sample >= turn_sample 2259 turning = 1 2260 # we past turn point going backwards 2261 elsif (not forwards) and cur_sample <= turn_sample 2262 turning = -1 2263 end 2264 else 2265 # wait for an inflection... 2266 if (last_val2 <= last_val and last_val >= val) or 2267 (last_val2 >= last_val and last_val <= val) 2268 turn_i += 1 2269 if turn_i < turns 2270 turn_sample = seconds2samples(turntable[turn_i]) 2271 forwards = (not forwards) 2272 set_mus_increment(rd, -mus_increment(rd)) 2273 end 2274 turning = 0 2275 end 2276 end 2277 last_val2, last_val = last_val, val 2278 val 2279 end 2280 mus_close(f) 2281end 2282 2283def scratch_test(start = 0.0, dur = 1.0) 2284 scratch(start, "fyow.snd", [dur, 1.5].min, [0.0, 0.5, 0.25, 1.0]) 2285 $now = start + mus_sound_duration("fyow.snd") + 0.2 2286end 2287 2288# PINS 2289# 2290# spectral modeling (SMS) 2291def pins(start, dur, file, amp, *args) 2292 assert_type(File.exist?(file), file, 2, "an existing file") 2293 transposition, time_scaler, fftsize, highest_bin, max_peaks, attack = nil 2294 optkey(args, binding, 2295 [:transposition, 1.0], # this can be used to transpose the sound 2296 [:time_scaler, 1.0], # this can make things happen faster 2297 # (< 1.0)/slower (> 1.0) in the output 2298 [:fftsize, 256], # should be a power of 2 2299 # at 22050 srate, this is ok for 2300 # sounds above 300Hz or so, below that 2301 # you need 512 or 1024, at 44100, 2302 # probably best to double these sizes 2303 # -- it takes some searching 2304 # sometimes. 2305 [:highest_bin, 128], # how high in fft data should we search for pks 2306 [:max_peaks, 16], # how many spectral peaks to track at the max 2307 :attack) # whether to use original attack via time domain 2308 # splice do the sliding fft shuffle, 2309 # translate to polar coordinates, find 2310 # spectral peaks, match with current, 2311 # do some interesting transformation, 2312 # resynthesize using oscils All the 2313 # envelopes are created on the fly. 2314 # max-peaks is how many of these peaks 2315 # we are willing to track at any given 2316 # time. 2317 fil = make_file2sample(file) 2318 file_duration = ws_duration(file) 2319 fdr = make_vct(fftsize) 2320 fdi = make_vct(fftsize) 2321 window = make_fft_window(Blackman2_window, fftsize) 2322 fftamps = make_vct(fftsize) 2323 max_oscils = 2 * max_peaks 2324 current_peak_freqs = make_vct(max_oscils) 2325 last_peak_freqs = make_vct(max_oscils) 2326 current_peak_amps = make_vct(max_oscils) 2327 last_peak_amps = make_vct(max_oscils) 2328 peak_amps = make_vct(max_peaks) 2329 peak_freqs = make_vct(max_peaks) 2330 resynth_oscils = make_array(max_oscils) do 2331 make_oscil(:frequency, 0) 2332 end 2333 # run-time generated amplitude and frequency envelopes 2334 amps = make_vct(max_oscils) 2335 rates = make_vct(max_oscils) 2336 freqs = make_vct(max_oscils) 2337 sweeps = make_vct(max_oscils) 2338 lowest_magnitude = 0.001 2339 hop = (fftsize / 4).floor 2340 outhop = (time_scaler * hop).floor 2341 ifreq = 1.0 / outhop 2342 ihifreq = hz2radians(ifreq) 2343 # integrate Blackman-Harris window = .42323*window 2344 fftscale = 1.0 / (fftsize * 0.42323) 2345 # width and shift by fftsize 2346 fft_mag = @srate / fftsize 2347 furthest_away_accepted = 0.1 2348 filptr = 0 2349 cur_oscils = max_oscils 2350 ramped = (attack or 0) 2351 splice_attack = attack.kind_of?(Numeric) 2352 attack_size = (attack or 1) 2353 ramp_ind = 0 2354 ramped_attack = make_vct(attack_size) 2355 if (dur / time_scaler) > file_duration 2356 error("%s is %1.3f seconds long, \ 2357but we'll need %1.3f seconds of data for this note", 2358 file, file_duration, dur / time_scaler) 2359 end 2360 trigger = outhop 2361 vct_scale!(window, fftscale) 2362 run_instrument(start, dur) do 2363 if splice_attack 2364 ramp = 1.0 / attack_size 2365 # my experience in translating SMS, and rumor via Greg Sandell 2366 # leads me to believe that there is in fact no way to model some 2367 # attacks successfully in this manner, so this block simply 2368 # splices the original attack on to the rest of the note. 2369 # "attack" is the number of samples to include bodily. 2370 out_val = amp * file2sample(fil, filptr) 2371 filptr += 1 2372 if filptr > attack_size 2373 mult = 1.0 2374 attack_size.times do |j| 2375 ramped_attack[j] = mult * file2sample(fil, filptr + j) 2376 mult -= ramp 2377 end 2378 splice_attack = false 2379 end 2380 # if out_val 2381 out_val 2382 else 2383 if trigger >= outhop 2384 peaks = 0 2385 # get next block of data and apply window to it 2386 trigger = 0 2387 fftsize.times do |j| 2388 fdr[j] = window[j] * file2sample(fil, filptr) 2389 filptr += 1 2390 end 2391 vct_fill!(fdi, 0.0) 2392 filptr -= fftsize - hop 2393 # get the fft 2394 mus_fft(fdr, fdi, fftsize, 1) 2395 # change to polar coordinates (ignoring phases) 2396 highest_bin.times do |j| 2397 # no need to paw through the upper half 2398 # (so (<= highest-bin (floor fft-size 2))) 2399 x = fdr[j] 2400 y = fdi[j] 2401 fftamps[j] = 2.0 * sqrt(x * x + y * y) 2402 end 2403 max_oscils.times do |j| 2404 last_peak_freqs[j] = current_peak_freqs[j] 2405 last_peak_amps[j] = current_peak_amps[j] 2406 current_peak_amps[j] = 0.0 2407 end 2408 vct_fill!(peak_amps, 0.0) 2409 ra = fftamps[0] 2410 la = ca = 0.0 2411 # search for current peaks following Xavier Serra's recommendations in 2412 # "A System for Sound Analysis/Transformation/Synthesis 2413 # Based on a Deterministic Plus Stochastic Decomposition" 2414 highest_bin.times do |j| 2415 la, ca, ra = ca, ra, fftamps[j] 2416 if ca > lowest_magnitude and ca > ra and ca > la 2417 # found a local maximum above the current threshold 2418 # (its bin number is j-1) 2419 logla = log10(la) 2420 logca = log10(ca) 2421 logra = log10(ra) 2422 offset = (0.5 * (logla - logra)) / (logla + -2 * logca + logra) 2423 amp_1 = 10.0 ** (logca - (0.25 * (logla - logra) * offset)) 2424 freq = fft_mag * (j + offset - 1) 2425 if peaks == max_peaks 2426 # gotta either flush this peak, 2427 # or find current lowest and flush him 2428 minp = 0 2429 minpeak = peak_amps[0] 2430 1.upto(max_peaks - 1) do |k| 2431 if peak_amps[k] < minpeak 2432 minp = k 2433 minpeak = peak_amps[k] 2434 end 2435 end 2436 if amp_1 > minpeak 2437 peak_freqs[minp] = freq 2438 peak_amps[minp] = amp_1 2439 end 2440 else 2441 peak_freqs[peaks] = freq 2442 peak_amps[peaks] = amp_1 2443 peaks += 1 2444 end 2445 end 2446 end 2447 # now we have the current peaks -- match them to the previous 2448 # set and do something interesting with the result the end 2449 # results are reflected in the updated values in the rates and 2450 # sweeps arrays. search for fits between last and current, 2451 # set rates/sweeps for those found try to go by largest amp 2452 # first 2453 peaks.times do |j| 2454 maxp = 0 2455 maxpk = peak_amps[0] 2456 1.upto(max_peaks - 1) do |k| 2457 if peak_amps[k] > maxpk 2458 maxp = k 2459 maxpk = peak_amps[k] 2460 end 2461 end 2462 # now maxp points to next largest unmatched peak 2463 if maxpk > 0.0 2464 closestp = -1 2465 closestamp = 10.0 2466 current_freq = peak_freqs[maxp] 2467 icf = 1.0 / current_freq 2468 max_peaks.times do |k| 2469 if last_peak_amps[k] > 0.0 2470 closeness = icf * (last_peak_freqs[k] - current_freq).abs 2471 if closeness < closestamp 2472 closestamp = closeness 2473 closestp = k 2474 end 2475 end 2476 end 2477 if closestamp < furthest_away_accepted 2478 # peak_amp is transferred to appropriate current_amp and zeroed, 2479 current_peak_amps[closestp] = peak_amps[maxp] 2480 peak_amps[maxp] = 0.0 2481 current_peak_freqs[closestp] = current_freq 2482 end 2483 end 2484 end 2485 max_peaks.times do |j| 2486 if peak_amps[j] > 0.0 2487 # find a place for a new oscil and start it up 2488 new_place = -1 2489 max_oscils.times do |k| 2490 if last_peak_amps[k].zero? and current_peak_amps[k].zero? 2491 new_place = k 2492 break 2493 end 2494 end 2495 current_peak_amps[new_place] = peak_amps[j] 2496 peak_amps[j] = 0.0 2497 current_peak_freqs[new_place] = peak_freqs[j] 2498 last_peak_freqs[new_place] = peak_freqs[j] 2499 set_mus_frequency(resynth_oscils[new_place], 2500 transposition * peak_freqs[j]) 2501 end 2502 end 2503 cur_oscils = 0 2504 max_oscils.times do |j| 2505 rates[j] = ifreq * (current_peak_amps[j] - last_peak_amps[j]) 2506 if current_peak_amps[j].nonzero? or last_peak_amps[j].nonzero? 2507 cur_oscils = j 2508 end 2509 sweeps[j] = ihifreq * transposition * 2510 (current_peak_freqs[j] - last_peak_freqs[j]) 2511 end 2512 cur_oscils += 1 2513 end 2514 # run oscils, update envelopes 2515 trigger += 1 2516 if ramped.zero? 2517 sum = 0.0 2518 else 2519 sum = ramped_attack[ramp_ind] 2520 ramp_ind += 1 2521 ramped = 0 if ramp_ind == ramped 2522 end 2523 cur_oscils.times do |j| 2524 if amps[j].nonzero? or rates[j].nonzero? 2525 sum = sum + amps[j] * oscil(resynth_oscils[j], freqs[j]) 2526 amps[j] += rates[j] 2527 freqs[j] += sweeps[j] 2528 end 2529 end 2530 # else out_val 2531 amp * sum 2532 end 2533 end 2534 mus_close(fil) 2535end 2536 2537def pins_test(start = 0.0, dur = 1.0) 2538 pins(start, dur, "fyow.snd", 1, :time_scaler, 2) 2539 $now = start + dur + 0.2 2540end 2541 2542# ZC 2543def zc(start, dur, freq, amp, length1, length2, feedback) 2544 s = make_pulse_train(:frequency, freq) 2545 d0 = make_comb(:size, length1, 2546 :max_size, [length1, length2].max + 1, 2547 :scaler, feedback) 2548 zenv = make_env(:envelope, [0, 0, 1, 1], 2549 :scaler, length2 - length1, 2550 :duration, dur) 2551 run_instrument(start, dur) do 2552 comb(d0, amp * pulse_train(s), env(zenv)) 2553 end 2554end 2555 2556def zc_test(start = 0.0, dur = 1.0) 2557 $now = start 2558 zc($now, dur, 100, 0.4, 20, 100, 0.95) 2559 $now += dur + 0.2 2560 zc($now, dur, 100, 0.4, 100, 20, 0.95) 2561 $now += dur + 0.2 2562end 2563 2564# ZN 2565# 2566# notches are spaced at srate/len, feedforward sets depth thereof so 2567# sweep of len from 20 to 100 sweeps the notches down from 1000 Hz to 2568# ca 200 Hz so we hear our downward glissando beneath the pulses. 2569def zn(start, dur, freq, amp, length1, length2, feedforward) 2570 s = make_pulse_train(:frequency, freq) 2571 d0 = make_notch(:size, length1, 2572 :max_size, [length1, length2].max + 1, 2573 :scaler, feedforward) 2574 zenv = make_env(:envelope, [0, 0, 1, 1], 2575 :scaler, length2 - length1, 2576 :duration, dur) 2577 run_instrument(start, dur) do 2578 notch(d0, amp * pulse_train(s), env(zenv)) 2579 end 2580end 2581 2582def zn_test(start = 0.0, dur = 1.0) 2583 $now = start 2584 zn($now, dur, 100, 0.5, 20, 100, 0.95) 2585 $now += dur + 0.2 2586 zn($now, dur, 100, 0.5, 100, 20, 0.95) 2587 $now += dur + 0.2 2588end 2589 2590# ZA 2591def za(start, dur, freq, amp, length1, length2, feedback, feedforward) 2592 s = make_pulse_train(:frequency, freq) 2593 d0 = make_all_pass(:feedback, feedback, 2594 :feedforward, feedforward, 2595 :size, length1, 2596 :max_size, [length1, length2].max + 1) 2597 zenv = make_env(:envelope, [0, 0, 1, 1], 2598 :scaler, length2 - length1, 2599 :duration, dur) 2600 run_instrument(start, dur) do 2601 all_pass(d0, amp * pulse_train(s), env(zenv)) 2602 end 2603end 2604 2605def za_test(start = 0.0, dur = 1.0) 2606 $now = start 2607 za($now, dur, 100, 0.3, 20, 100, 0.95, 0.95) 2608 $now += dur + 0.2 2609 za($now, dur, 100, 0.3, 100, 20, 0.95, 0.95) 2610 $now += dur + 0.2 2611end 2612 2613# CLM-EXPSRC 2614def clm_expsrc(start, dur, in_file, exp_ratio, src_ratio, amp, 2615 rev = false, start_in_file = 0) 2616 assert_type(File.exist?(in_file), in_file, 0, "an existing file") 2617 stf = (start_in_file * srate(in_file)).floor 2618 fda = make_readin(in_file, :channel, 0, :start, stf) 2619 exa = make_granulate(lambda do |dir| 2620 readin(fda) 2621 end, :expansion, exp_ratio) 2622 srca = make_src(lambda do |dir| 2623 granulate(exa) 2624 end, :srate, src_ratio) 2625 two_chans = (channels(in_file) == 2) and (channels(@ws_output) == 2) 2626 revit = @reverb and rev 2627 beg = seconds2samples(start) 2628 fin = seconds2samples(dur) + beg 2629 # to satisfy with_sound-option :info and :notehook 2630 with_sound_info(get_func_name, start, dur) 2631 if two_chans 2632 fdb = make_readin(in_file, :channel, 1, :srate, stf) 2633 exb = make_granulate(lambda do |dir| 2634 readin(fdb) 2635 end, :expansion, exp_ratio) 2636 srcb = make_src(lambda do |dir| 2637 granulate(exb) 2638 end, :srate, src_ratio) 2639 if revit 2640 rev_amp = rev * 0.5 2641 (beg..fin).each do |i| 2642 vala = src(srca) * amp 2643 valb = src(srcb) * amp 2644 outa(i, vala, @ws_output) 2645 outb(i, valb, @ws_output) 2646 outa(i, (vala + valb) * rev_amp, @reverb) 2647 end 2648 else # !revit 2649 (beg..fin).each do |i| 2650 outa(i, src(srca) * amp, @ws_output) 2651 outb(i, src(srcb) * amp, @ws_output) 2652 end 2653 end # revit 2654 else # !two_chans 2655 if revit 2656 rev_amp = rev 2657 (beg..fin).each do |i| 2658 vala = src(srca) * amp 2659 outa(i, vala, @ws_output) 2660 outa(i, vala * rev_amp, @ws_reverb) 2661 end 2662 else # !revit 2663 (beg..fin).each do |i| 2664 outa(i, src(srca) * amp, @ws_output) 2665 end 2666 end # revit 2667 end # two_chans 2668end 2669 2670def clm_expsrc_test(start = 0.0, dur = 1.0) 2671 clm_expsrc(start, dur, "oboe.snd", 2.0, 1.0, 1.0, 0.05) 2672 $now = start + dur + 0.2 2673end 2674 2675# EXP-SND 2676# 2677# granulate with envelopes on the expansion amount, segment envelope 2678# shape, segment length, hop length, and input file resampling rate 2679def exp_snd(file, start, dur, amp, 2680 exp_amt = 1.0, ramp = 0.4, seglen = 0.15, 2681 sr = 1.0, hop = 0.05, ampenv = nil) 2682 assert_type(File.exist?(file), file, 0, "an existing file") 2683 f0 = make_ws_reader(file, :start, 0) 2684 expenv = make_env(:envelope, 2685 (exp_amt.kind_of?(Array) ? 2686 exp_amt : [0, exp_amt, 1, exp_amt]), 2687 :duration, dur) 2688 lenenv = make_env(:envelope, 2689 (seglen.kind_of?(Array) ? 2690 seglen : [0, seglen, 1, seglen]), 2691 :duration, dur) 2692 max_seg_len, initial_seg_len = if seglen 2693 if seglen.kind_of?(Array) 2694 [max_envelope(seglen), seglen[1]] 2695 else 2696 [seglen, seglen] 2697 end 2698 else 2699 [0.15, 0.15] 2700 end 2701 scaler_amp = ((max_seg_len > 0.15) ? ((0.6 * 0.15) / max_seg_len) : 0.6) 2702 srenv = make_env(:envelope, (sr.kind_of?(Array) ? sr : [0, sr, 1, sr]), 2703 :duration, dur) 2704 rampdata = (ramp.kind_of?(Array) ? ramp : [0, ramp, 1, ramp]) 2705 rampenv = make_env(:envelope, rampdata, :duration, dur) 2706 initial_ramp_time = if ramp 2707 if ramp.kind_of?(Array) 2708 ramp[1] 2709 else 2710 ramp 2711 end 2712 else 2713 0.4 2714 end 2715 hopenv = make_env(:envelope, (hop.kind_of?(Array) ? hop : [0, hop, 1, hop]), 2716 :duration, dur) 2717 max_out_hop, initial_out_hop = if hop 2718 if hop.kind_of?(Array) 2719 [max_envelope(hop), hop[1]] 2720 else 2721 [hop, hop] 2722 end 2723 else 2724 [0.05, 0.05] 2725 end 2726 min_exp_amt, initial_exp_amt = if exp_amt 2727 if exp_amt.kind_of?(Array) 2728 [min_envelope(exp_amt), exp_amt[1]] 2729 else 2730 [exp_amt, exp_amt] 2731 end 2732 else 2733 [1.0, 1.0] 2734 end 2735 max_in_hop = max_out_hop / min_exp_amt.to_f 2736 max_len = (@srate * ([max_out_hop, max_in_hop].max + max_seg_len)).ceil 2737 ampe = make_env(:envelope, (ampenv or [0, 0, 0.5, 1, 1, 0]), 2738 :scaler, amp, 2739 :duration, dur) 2740 ex_a = make_granulate(:input, lambda do |dir| ws_readin(f0) end, 2741 :expansion, initial_exp_amt, 2742 :max_size, max_len, 2743 :ramp, initial_ramp_time, 2744 :hop, initial_out_hop, 2745 :length, initial_seg_len, 2746 :scaler, scaler_amp) 2747 ex_samp = next_samp = 0.0 2748 vol = env(ampe) 2749 val_a0 = vol * granulate(ex_a) 2750 val_a1 = vol * granulate(ex_a) 2751 if min_envelope(rampdata) <= 0.0 or max_envelope(rampdata) >= 0.5 2752 error("ramp argument to expand must always be between 0.0 and 0.5: %1.3f", 2753 ramp) 2754 else 2755 run_instrument(start, dur) do 2756 expa = env(expenv) # current expansion amount 2757 segl = env(lenenv) # current segment length 2758 resa = env(srenv) # current resampling increment 2759 rmpl = env(rampenv) # current ramp length (0 to 0.5) 2760 hp = env(hopenv) # current hop size 2761 # now we set the granulate generator internal state to reflect all 2762 # these envelopes 2763 sl = (segl * @srate).floor 2764 rl = (rmpl * sl).floor 2765 vol = env(ampe) 2766 set_mus_length(ex_a, sl) 2767 set_mus_ramp(ex_a, rl) 2768 set_mus_frequency(ex_a, hp) 2769 set_mus_increment(ex_a, expa) 2770 next_samp += resa 2771 if next_samp > (ex_samp + 1) 2772 (next_samp - ex_samp).floor.times do 2773 val_a0, val_a1 = val_a1, vol * granulate(ex_a) 2774 ex_samp += 1 2775 end 2776 end 2777 if next_samp == ex_samp 2778 val_a0 2779 else 2780 val_a0 + (next_samp - ex_samp) * (val_a1 - val_a0) 2781 end 2782 end 2783 close_ws_reader(f0) 2784 end 2785end 2786 2787def exp_snd_test(start = 0.0, dur = 1.0) 2788 $now = start 2789 exp_snd("fyow.snd", $now, dur, 1, [0, 1, 1, 3], 0.4, 0.15, 2790 [0, 2, 1, 0.5], 0.05) 2791 $now += dur + 0.2 2792 exp_snd("oboe.snd", $now, dur, 1, [0, 1, 1, 3], 0.4, 0.15, 2793 [0, 2, 1, 0.5], 0.2) 2794 $now += dur + 0.2 2795end 2796 2797# EXPFIL 2798Grn = Struct.new("Grn", 2799 :rampval, :rampinc, 2800 :loc, :segctr, :whichseg, :ramplen, :steadylen, :trigger) 2801 2802def expfil(start, dur, hopsecs, rampsecs, steadysecs, file1, file2) 2803 assert_type(File.exist?(file1), file1, 5, "an existing file") 2804 assert_type(File.exist?(file2), file2, 6, "an existing file") 2805 fil1 = make_file2sample(file1) 2806 fil2 = make_file2sample(file2) 2807 hop = seconds2samples(hopsecs) 2808 ramplen = seconds2samples(rampsecs) 2809 steadylen = seconds2samples(steadysecs) 2810 grn1 = Grn.new(0.0, 1.0 / ramplen, 0, 0, 0, ramplen, steadylen, 0) 2811 grn2 = Grn.new(0.0, 1.0 / ramplen, 0, 0, 0, ramplen, steadylen, 0) 2812 beg = seconds2samples(start) 2813 out1 = beg 2814 out2 = hop + beg 2815 run_instrument(start, dur) do |i| 2816 val = 0.0 2817 if i == out1 2818 inval = ina(grn1.loc, fil1) 2819 grn1.loc += 1 2820 if grn1.whichseg.zero? # ramp-up 2821 inval *= grn1.rampval 2822 grn1.rampval += grn1.rampinc 2823 grn1.segctr += 1 2824 if grn1.segctr == grn1.ramplen 2825 grn1.segctr = 0 2826 grn1.whichseg += 1 2827 end 2828 else 2829 if grn1.whichseg == 1 # steady-state 2830 grn1.segctr += 1 2831 if grn1.segctr == grn1.steadylen 2832 grn1.segctr = 0 2833 grn1.whichseg += 1 2834 end 2835 else # ramp-down 2836 inval *= grn1.rampval 2837 grn1.segctr += 1 2838 grn1.rampval -= grn1.rampinc 2839 if grn1.segctr == grn1.ramplen 2840 grn1.segctr = 0 2841 grn1.trigger = 1 2842 grn1.whichseg = 0 2843 grn1.rampval = 0.0 2844 end 2845 end 2846 end 2847 val += inval 2848 out1 += 1 2849 if grn1.trigger == 1 2850 grn1.trigger = 0 2851 out1 += hop 2852 end 2853 end 2854 if i == out2 2855 inval = ina(grn2.loc, fil2) 2856 grn2.loc += 1 2857 if grn2.whichseg.zero? # ramp-up 2858 inval *= grn2.rampval 2859 grn2.rampval += grn2.rampinc 2860 grn2.segctr += 1 2861 if grn2.segctr == grn2.ramplen 2862 grn2.segctr = 0 2863 grn2.whichseg += 1 2864 end 2865 else 2866 if grn2.whichseg == 1 # steady-state 2867 grn2.segctr += 1 2868 if grn2.segctr == grn2.steadylen 2869 grn2.segctr = 0 2870 grn2.whichseg += 1 2871 end 2872 else # ramp-down 2873 inval *= grn2.rampval 2874 grn2.segctr += 1 2875 grn2.rampval -= grn2.rampinc 2876 if grn2.segctr == grn2.ramplen 2877 grn2.segctr = 0 2878 grn2.trigger = 1 2879 grn2.whichseg = 0 2880 grn2.rampval = 0.0 2881 end 2882 end 2883 end 2884 val += inval 2885 out2 += 1 2886 if grn2.trigger == 1 2887 grn2.trigger = 0 2888 out2 += hop 2889 end 2890 end 2891 val 2892 end 2893end 2894 2895def expfil_test(start = 0.0, dur = 1.0) 2896 expfil(start, dur, 0.2, 0.01, 0.1, "oboe.snd", "fyow.snd") 2897 $now = start + dur + 0.2 2898end 2899 2900# GRAPH-EQ 2901# 2902=begin 2903From: Marco Trevisani <marco@ccrma.Stanford.EDU> 2904 2905This should work like a Graphic Equalizer.... 2906Very easy to use. Just some note: 2907 2908"amp" & "amp-env" apply an enveloppe to the final result of the 2909filtering. 2910 2911"dur" as ""standard"" in my instruments, when dur = 0 it will take the length 2912of the sndfile input, otherwise the duration in seconds. 2913 2914"gain-freq-list" is a list of gains and frequencies to 2915filter --in this order gain and frequencies--. There is no limit to 2916the size of the list. Gain can be a number or an 2917envelope. Unfortunatelly in this version they cant alternate, one 2918should chose, all envelopes or all numbers i.e.: 2919case 1 -> '( .1 440.0 .3 1500.0 .2 330.0 ...etc) or 2920case 2 -> '((0 .1 1 .5) 440.0 (0 1 1 .01) 1500 (0 .3 1 .5) 330.0 ...etc) 2921'( .1 440.0 (0 1 1 .01) 1500 ..etc) <<< again, this is not allowed .. 2922 2923"offset-gain" This apply to all the gains if case 1. It adds or 2924subtracts an offset to all the gains in the list. This number can be positive 2925or negative. In case the result is a negative number --let's say offset = 2926-.4 and, like in case 1, the first gain is .1, the result would be 2927-.3 -- the instrument will pass a gain equal to 0. 2928 2929"filt-gain-scale" & "filt-gain-base" will apply to the elements of the 2930envelopes if we are in case 2, gains are envelopes. 2931 2932"stats" if #t --default-- prints the number of seconds processed, if 2933nil doesnt print anything, which will speed up a bit the process. 2934=end 2935# 2936def graph_eq(file, start, dur, *args) 2937 assert_type(File.exist?(file), file, 0, "an existing file") 2938 or_beg, amplitude, amp_env, amp_base, offset_gain = nil 2939 gain_freq_list, filt_gain_scale, filt_gain_base, a1 = nil 2940 optkey(args, binding, 2941 [:or_beg, 0], 2942 [:amplitude, 1], 2943 [:amp_env, [0, 1, 0.8, 1, 1, 0]], 2944 [:amp_base, 1], 2945 [:offset_gain, 0], 2946 [:gain_freq_list, [[0, 1, 1, 0], 440, [0, 0, 1, 1], 660]], 2947 [:filt_gain_scale, 1], 2948 [:filt_gain_base, 1], 2949 [:a1, 0.99]) 2950 durata = (dur.zero? ? ws_duration(file) : dur) 2951 len = seconds2samples(durata) 2952 or_start = (or_beg * ws_srate(file)).round 2953 rd_a = make_ws_reader(file, :start, or_start) 2954 half_list = gain_freq_list.length / 2 2955 ampenv = make_env(:envelope, amp_env, 2956 :scaler, amplitude, 2957 :duration, durata, 2958 :base, amp_base) 2959 gain_list = [] 2960 0.step(gain_freq_list.length - 1, 2) do |i| 2961 gain_list << gain_freq_list[i] 2962 end 2963 freq_list = [] 2964 1.step(gain_freq_list.length - 1, 2) do |i| 2965 freq_list << gain_freq_list[i] 2966 end 2967 if_list_in_gain = gain_list[0].kind_of?(Array) 2968 env_size = (if_list_in_gain ? Array.new(freq_list.length) : nil) 2969 frm_size = Array.new(freq_list.length) 2970 gains = Vct.new(len, 1.0) 2971 half_list.times do |i| 2972 gval = gain_list[i] 2973 fval = freq_list[i] 2974 if gval.kind_of?(Array) 2975 env_size[i] = make_env(:envelope, gval, 2976 :scaler, filt_gain_scale, 2977 :duration, durata, 2978 :base, filt_gain_base) 2979 frm_size[i] = make_formant(fval, a1) 2980 else 2981 gains[i] = (offset_gain + gval < 0) ? 0 : (offset_gain + gain) 2982 frm_size[i] = make_formant(fval, a1) 2983 end 2984 end 2985 run_instrument(start, durata) do 2986 outval = 0.0 2987 inval = ws_readin(rd_a) 2988 half_list.times do |j| 2989 if if_list_in_gain 2990 gains[j] = env(env_size[j]) * (1.0 - a1) 2991 end 2992 outval = outval + gains[j] * formant(frm_size[j], inval) 2993 end 2994 env(ampenv) * outval 2995 end 2996 close_ws_reader(rd_a) 2997end 2998 2999def graph_eq_test(start = 0.0, dur = 1.0) 3000 graph_eq("oboe.snd", start, dur, :amplitude, 50.0) 3001 $now = start + dur + 0.2 3002end 3003 3004# ANOI 3005# 3006# a kind of noise reduction -- on-going average spectrum is squelched 3007# to some extent obviously aimed at intermittent signal in background 3008# noise 3009# this is based on Perry Cook's Scrubber.m 3010def anoi(infile, start, dur, fftsize = 128, amp_scaler = 1.0, r = TWO_PI) 3011 assert_type(File.exist?(infile), infile, 0, "an existing file") 3012 freq_inc = (fftsize / 2).floor 3013 fdi = make_vct(fftsize) 3014 fdr = make_vct(fftsize) 3015 spectr = make_vct(freq_inc, 1.0) 3016 scales = make_vct(freq_inc, 1.0) 3017 diffs = make_vct(freq_inc) 3018 win = make_fft_window(Blackman2_window, fftsize) 3019 k = 0 3020 amp = 0.0 3021 incr = amp_scaler * 4.0 / @srate 3022 file = make_file2sample(infile) 3023 radius = 1.0 - r / fftsize.to_f 3024 bin = @srate / fftsize 3025 fs = make_array(freq_inc) do |i| 3026 make_formant(i * bin, radius) 3027 end 3028 samp = 0 3029 run_instrument(start, dur) do 3030 inval = file2sample(file, samp) 3031 samp += 1 3032 fdr[k] = inval 3033 k += 1 3034 amp += incr if amp < amp_scaler 3035 if k >= fftsize 3036 k = 0 3037 spectrum(fdr, fdi, win, 1) 3038 freq_inc.times do |j| 3039 spectr[j] = 0.9 * spectr[j] + 0.1 * fdr[j] 3040 if spectr[j] >= fdr[j] 3041 diffs[j] = scales[j] / -fftsize 3042 else 3043 diffs[j] = ((fdr[j] - spectr[j]) / fdr[j] - scales[j]) / fftsize 3044 end 3045 end 3046 end 3047 outval = 0.0 3048 1.upto(freq_inc - 1) do |j| 3049 cur_scale = scales[j] 3050 outval = outval + cur_scale * formant(fs[j], inval) 3051 scales[j] += diffs[j] 3052 end 3053 amp * outval 3054 end 3055end 3056 3057def anoi_test(start = 0.0, dur = 1.0) 3058 anoi("fyow.snd", start, dur, 128, 2.0) 3059 $now = start + dur + 0.2 3060end 3061 3062=begin 3063Date: Fri, 25 Sep 1998 09:56:41 +0300 3064From: Matti Koskinen <mjkoskin@sci.fi> 3065To: linux-audio-dev@ginette.musique.umontreal.ca 3066Subject: [linux-audio-dev] Announce: alpha version of denoising 3067[...] 3068 I wrote a simple denoiser called anoi after it's parent 3069 clm-instrument anoi.ins. 3070 3071 anoi tries to remove white noise like tape hiss from wav- 3072 files. Removing of noise succeeds ok, but depending of the 3073 original sound, some distortion can be audible. 3074 3075 If someone is interested, http://www.sci.fi/~mjkoskin 3076 contains tarred and gzipped file. 3077 3078 Now only monophonic wav-files can be denoised, but adding 3079 others isn't too difficult. 3080 3081-matti 3082mjkoskin@sci.fi 3083=end 3084 3085# FULLMIX 3086# 3087# ;; "matrix" can be a simple amplitude or a list of lists each inner 3088# ;; list represents one input channel's amps into one output channel 3089# ;; each element of the list can be a number, a list (turned into an 3090# ;; env) or an env 3091# ;; 3092# ;; "srate" can be a negative number (read in reverse), or an envelope. 3093def fullmix(in_file, 3094 start = 0.0, 3095 outdur = false, 3096 inbeg = 0.0, 3097 matrix = false, 3098 srate = false, 3099 reverb_amount = false) 3100 unless File.exist?(in_file) 3101 Snd.raise(:no_such_file, in_file, "no such file") 3102 end 3103 unless start 3104 start = 0.0 3105 end 3106 unless inbeg 3107 inbeg = 0.0 3108 end 3109 if number?(outdur) 3110 dur = outdur 3111 else 3112 sr = number?(srate) ? srate.abs : 1.0 3113 dur = (mus_sound_duration(in_file) - inbeg) / sr 3114 end 3115 in_chans = channels(in_file) 3116 reversed = ((number?(srate) and srate.negative?) or 3117 (array?(srate) and srate.cadr.negative?)) 3118 inloc = (Float(inbeg) * mus_sound_srate(in_file)).round 3119 ochans = [in_chans, @channels].max 3120 if @ws_reverb and number?(reverb_amount) and reverb_amount.positive? 3121 rev_mx = Vct.new(in_chans * in_chans, reverb_amount) 3122 else 3123 rev_mx = false 3124 end 3125 dir = (reversed ? -1 : 1) 3126 if (not srate) or (number?(srate) and srate == 1.0) 3127 file = make_file2frample(in_file) 3128 else 3129 file = make_array(in_chans) do |i| 3130 make_readin(in_file, i, inloc, :direction, dir) 3131 end 3132 end 3133 envs = false 3134 if array?(srate) 3135 srcenv = make_env(srate, :duration, dur, :scaler, Float(dir)) 3136 else 3137 srcenv = false 3138 end 3139 case matrix 3140 when Array 3141 mx = Vct.new(ochans * ochans, 0.0) 3142 matrix.each_with_index do |inlist, inp| 3143 break if inp >= in_chans 3144 inlist.each_with_index do |outn, outp| 3145 break if outp >= @channels 3146 case outn 3147 when Numeric 3148 # mx[inp][outp] = outn 3149 mx[inp * ochans + outp] = outn 3150 when Array, Mus 3151 unless envs 3152 envs = Array.new(in_chans * @channels, false) 3153 end 3154 if env?(outn) 3155 envs[inp * @channels + outp] = outn 3156 else 3157 envs[inp * @channels + outp] = make_env(outn, :duration, dur) 3158 end 3159 else 3160 Snd.warning("unknown element in matrix: %p", outn) 3161 end 3162 end 3163 end 3164 when Numeric 3165 # ; matrix is a number in this case (a global scaler) 3166 mx = Vct.new(ochans * ochans, matrix) 3167 else 3168 mx = Vct.new(ochans * ochans, 1.0) 3169 end 3170 # to satisfy with_sound-option :info and :notehook 3171 with_sound_info(get_func_name, start, dur) 3172 beg = seconds2samples(start) 3173 samps = seconds2samples(dur) 3174 if (not array?(file)) 3175 mxe = envs 3176 if envs 3177 mxe = Array.new(in_chans) do |i| 3178 Array.new(@channels) do |j| 3179 envs[i * @channels + j] 3180 end 3181 end 3182 end 3183 if sound?(@ws_output) 3184 output = file_name(@ws_output) 3185 if sound?(@ws_reverb) 3186 revout = file_name(@ws_reverb) 3187 end 3188 else 3189 output = @ws_output 3190 revout = @ws_reverb 3191 end 3192 mus_file_mix(output, file, beg, samps, inloc, mx, mxe) 3193 if rev_mx 3194 mus_file_mix(revout, file, beg, samps, inloc, rev_mx) 3195 end 3196 else 3197 if sound?(@ws_output) 3198 Snd.raise(:wrong_type_arg, "don't use :to_snd true") 3199 end 3200 sr = (number?(srate) ? srate.abs : 0.0) 3201 srcs = Array.new(in_chans) do |i| 3202 make_src(:input, file[i], :srate, sr) 3203 end 3204 mus_file_mix_with_envs(file, beg, samps, mx, rev_mx, envs, srcs, srcenv, 3205 @ws_output, @ws_reverb) 3206 end 3207end 3208 3209def fullmix_test(start = 0.0, dur = 1.0) 3210 $now = start 3211 fullmix("pistol.snd", $now, dur) 3212 $now += dur + 0.2 3213 fullmix("oboe.snd", $now, dur, 0, 3214 [[0.1, make_env([0, 0, 1, 1], :duration, dur, :scaler, 0.5)]]) 3215 $now += dur + 0.2 3216end 3217 3218# Original header: 3219 3220# ;;; grani: a granular synthesis instrument 3221# ;;; by Fernando Lopez-Lezcano 3222# ;;; http://ccrma.stanford.edu/~nando/clm/grani/ 3223# ;;; 3224# ;;; Original grani.ins instrument written for the 220a Course by 3225# ;;; Fernando Lopez-Lezcano & Juan Pampin, November 6 1996 3226# ;;; 3227# ;;; Mar 21 1997: working with hop and grain-dur envelopes 3228# ;;; Mar 22 1997: working with src envelope (grain wise) & src spread 3229# ;;; Jan 26 1998: started work on new version 3230# ;;; Nov 7 1998: input soundfile duration calculation wrong 3231# ;;; Nov 10 1998: bug in in-samples (thanks to Kristopher D. Giesing for this one) 3232# ;;; Dec 20 1998: added standard locsig code 3233# ;;; Feb 19 1999: added "nil" as default value of where to avoid warning (by bill) 3234# ;;; Jan 10 2000: added input-channel to select which channel of the input file 3235# ;;; to process. 3236# ;;; added grain-start-in-seconds to be able to specify input file 3237# ;;; locations in seconds for the grain-start envelope 3238# ;;; May 06 2002: fixed array passing of where-bins in clisp (reported by Charles 3239# ;;; Nichols and jennifer l doering 3240# ;;; Mar 27 2003: added option for sending grains to all channels (requested by 3241# ;;; Oded Ben-Tal) 3242 3243# ;;; calculate a random spread around a center of 0 3244def random_spread(spread) 3245 spread.nonzero? ? (random(spread) - spread / 2.0) : 0.0 3246end 3247 3248# ;;; create a constant envelope if argument is a number 3249def envelope_or_number(val) 3250 assert_type((number?(val) or array?(val) or vct?(val)), 3251 val, 0, "a number, an array or a vct") 3252 case val 3253 when Numeric 3254 [0, Float(val), 1, Float(val)] 3255 when Vct 3256 val.to_a 3257 when Array 3258 val 3259 end 3260end 3261 3262# ;;; create a vct from an envelope 3263def make_gr_env(env, length = 512) 3264 length_1 = (length - 1).to_f 3265 make_vct!(length) do |i| 3266 envelope_interp(i / length_1, env) 3267 end 3268end 3269 3270# ;;; Grain envelopes 3271def raised_cosine(*args) 3272 duty_cycle, length = nil 3273 optkey(args, binding, 3274 [:duty_cycle, 100], 3275 [:length, 128]) 3276 active = length * duty_cycle.to_f * 0.01 3277 incr = PI / (active - 1.0) 3278 start = (length - active) / 2.0 3279 fin = (length + active) / 2.0 3280 s = -1 3281 make_vct!(length) do |i| 3282 sine = if i >= start and i < fin 3283 s += 1 3284 sin(s * incr) 3285 else 3286 0.0 3287 end 3288 sine * sine 3289 end 3290end 3291 3292# ;;;============================================================================= 3293# ;;; Granular synthesis instrument 3294# ;;;============================================================================= 3295# 3296# ;;; input-channel: 3297# ;;; from which channel in the input file are samples read 3298# ;;; amp-envelope: 3299# ;;; amplitude envelope for the note 3300# ;;; grain-envelope: 3301# ;;; grain-envelope-end: 3302# ;;; envelopes for each individual grain. The envelope applied in the result 3303# ;;; of interpolating both envelopes. The interpolation is controlled by 3304# ;;; grain-envelope-trasition. If "grain-envelope-end" is nil interpolation 3305# ;;; is turned off and only grain-envelope is applied to the grains. 3306# ;;; grain-envelope-trasition: 3307# ;;; an enveloper that controls the interpolation between the two grain envelopes 3308# ;;; 0 -> selects "grain-envelope" 3309# ;;; 1 -> selects "grain-envelope-end" 3310# ;;; grain-envelope-array-size 3311# ;;; size of the array passed to make-table-lookup 3312# ;;; grain-duration: 3313# ;;; envelope that controls grain duration in seconds 3314# ;;; srate-linear: 3315# ;;; t -> sample rate envelope is linear 3316# ;;; nil -> sample rate envelope is exponential 3317# ;;; srate: 3318# ;;; envelope that controls sample rate conversion. The envelope is an 3319# ;;; exponential envelope, the base and error bound of the conversion 3320# ;;; are controlled by "srate-base" and "srate-error". 3321# ;;; srate-spread: 3322# ;;; random spread of sample rate conversion around "srate" 3323# ;;; srate-base: 3324# ;;; base for the exponential conversion 3325# ;;; for example: base = (expt 2 (/ 12)) creates a semitone envelope 3326# ;;; srate-error: 3327# ;;; error bound for the exponential conversion. 3328# ;;; grain-start: 3329# ;;; envelope that determines the starting point of the current grain in 3330# ;;; the input file. "y"->0 starts the grain at the beginning of the input 3331# ;;; file. "y"->1 starts the grain at the end of the input file. 3332# ;;; grain-start-spread: 3333# ;;; random spread around the value of "grain-start" 3334# ;;; grain-start-in-seconds: 3335# ;;; nil -> grain-start y envelope expressed in percent of the duration of the input file 3336# ;;; t -> grain-start y envelope expressed in seconds 3337# ;;; grain-density: 3338# ;;; envelope that controls the number of grains per second generated in the output file 3339 3340# ;;; grain-density-spread: 3341 3342Grani_to_locsig = 0 3343Grani_to_grain_duration = 1 3344Grani_to_grain_start = 2 3345Grani_to_grain_sample_rate = 3 3346Grani_to_grain_random = 4 3347Grani_to_grain_allchans = 5 3348 3349def grani(start, dur, amp, file, *args) 3350 assert_type(File.exist?(file), file, 3, "an existing file") 3351 input_channel = nil 3352 grains, amp_envelope, grain_envelope, grain_envelope_end = nil 3353 grain_envelope_transition, grain_envelope_array_size, grain_duration = nil 3354 grain_duration_spread, grain_duration_limit, srate, srate_spread = nil 3355 srate_linear, srate_base, srate_error, grain_start, grain_start_spread = nil 3356 grain_start_in_seconds, grain_density, grain_density_spread = nil 3357 reverb_amount, reverse, where_to, where_bins, grain_distance = nil 3358 grain_distance_spread, grain_degree, grain_degree_spread = nil 3359 optkey(args, binding, 3360 [:input_channel, 0], 3361 [:grains, 0], 3362 [:amp_envelope, [0, 0, 0.3, 1, 0.7, 1, 1, 0]], 3363 [:grain_envelope, [0, 0, 0.3, 1, 0.7, 1, 1, 0]], 3364 [:grain_envelope_end, false], 3365 [:grain_envelope_transition, [0, 0, 1, 1]], 3366 [:grain_envelope_array_size, 512], 3367 [:grain_duration, 0.1], 3368 [:grain_duration_spread, 0.0], 3369 [:grain_duration_limit, 0.002], 3370 [:srate, 0.0], 3371 [:srate_spread, 0.0], 3372 [:srate_linear, false], 3373 [:srate_base, 2.0 ** (1.0 / 12)], 3374 [:srate_error, 0.01], 3375 [:grain_start, [0, 0, 1, 1]], 3376 [:grain_start_spread, 0.0], 3377 [:grain_start_in_seconds, false], 3378 [:grain_density, 10.0], 3379 [:grain_density_spread, 0.0], 3380 [:reverb_amount, 0.01], 3381 [:reverse, false], 3382 [:where_to, 0], 3383 [:where_bins, []], 3384 [:grain_distance, 1.0], 3385 [:grain_distance_spread, 0.0], 3386 [:grain_degree, 45.0], 3387 [:grain_degree_spread, 0.0]) 3388 beg, fin = times2samples(start, dur) 3389 in_file_channels = ws_channels(file) 3390 in_file_sr = ws_srate(file) 3391 in_file_dur = ws_duration(file) 3392 rd = make_ws_reader(file, 3393 :channel, [input_channel, in_file_channels - 1].min, 3394 :vct?, true) 3395 in_file_reader = make_src(:input, lambda do |dir| ws_readin(rd) end, 3396 :srate, 1.0) 3397 set_mus_increment(in_file_reader, -1) if reverse 3398 last_in_sample = (in_file_dur * in_file_sr).round 3399 srate_ratio = in_file_sr / mus_srate() 3400 sr_env = make_env(:envelope, if srate_linear 3401 envelope_or_number(srate) 3402 else 3403 exp_envelope(envelope_or_number(srate), 3404 :base, srate_base, 3405 :error, srate_error) 3406 end, 3407 :scaler, srate_ratio, 3408 :duration, dur) 3409 sr_spread_env = make_env(:envelope, envelope_or_number(srate_spread), 3410 :duration, dur) 3411 amp_env = make_env(:envelope, amp_envelope, :scaler, amp, :duration, dur) 3412 gr_dur = make_env(:envelope, envelope_or_number(grain_duration), 3413 :duration, dur) 3414 gr_dur_spread = make_env(:envelope, envelope_or_number(grain_duration_spread), 3415 :duration, dur) 3416 gr_start_scaler = (grain_start_in_seconds ? 1.0 : in_file_dur) 3417 gr_start = make_env(:envelope, envelope_or_number(grain_start), 3418 :duration, dur) 3419 gr_start_spread = make_env(:envelope, envelope_or_number(grain_start_spread), 3420 :duration, dur) 3421 gr_dens_env = make_env(:envelope, envelope_or_number(grain_density), 3422 :duration, dur) 3423 gr_dens_spread_env = make_env(:envelope, 3424 envelope_or_number(grain_density_spread), 3425 :duration, dur) 3426 if vct?(grain_envelope) 3427 ge = grain_envelope 3428 else 3429 ge = make_gr_env(grain_envelope, grain_envelope_array_size) 3430 end 3431 gr_env = make_table_lookup(:frequency, 1.0, :initial_phase, 0, :wave, ge) 3432 if grain_envelope_end 3433 if vct?(grain_envelope_end) 3434 ge = grain_envelope_end 3435 else 3436 ge = make_gr_env(grain_envelope_end, grain_envelope_array_size) 3437 end 3438 else 3439 ge = make_vct(512) 3440 end 3441 gr_env_end = make_table_lookup(:frequency, 1.0, :initial_phase, 0, :wave, ge) 3442 gr_int_env = make_env(:envelope, 3443 envelope_or_number(grain_envelope_transition), 3444 :duration, dur) 3445 gr_dist = make_env(:envelope, envelope_or_number(grain_distance), 3446 :duration, dur) 3447 gr_dist_spread = make_env(:envelope, 3448 envelope_or_number(grain_distance_spread), 3449 :duration, dur) 3450 gr_degree = make_env(:envelope, envelope_or_number(grain_degree), 3451 :duration, dur) 3452 gr_degree_spread = make_env(:envelope, 3453 envelope_or_number(grain_degree_spread), 3454 :duration, dur) 3455 gr_start_sample = beg 3456 gr_samples = 0 3457 gr_offset = 1 3458 gr_dens = 0.0 3459 gr_dens_spread = 0.0 3460 grain_counter = 0 3461 samples = 0 3462 first_grain = true 3463 case grain_duration 3464 when Numeric 3465 dur += grain_duration 3466 when Array 3467 dur += grain_duration.last 3468 end 3469 run_instrument(start, dur, :degree, 45.0) do 3470 if gr_offset < gr_samples 3471 gr_offset += 1 3472 (if grain_envelope_end 3473 gr_where = env(gr_int_env) 3474 (1 - gr_where) * table_lookup(gr_env) + 3475 gr_where * table_lookup(gr_env_end) 3476 else 3477 table_lookup(gr_env) 3478 end) * env(amp_env) * src(in_file_reader) 3479 else 3480 if first_grain 3481 first_grain = false 3482 gr_start_sample = beg 3483 else 3484 gr_start_sample += seconds2samples(1.0 / (gr_dens + gr_dens_spread)) 3485 if (gr_start_sample > fin) or 3486 (grains.nonzero? and (grain_counter >= grains)) 3487 break 3488 end 3489 end 3490 gr_offset = 0 3491 gr_from_beg = gr_start_sample - beg 3492 set_mus_location(amp_env, gr_from_beg) 3493 set_mus_location(gr_dur, gr_from_beg) 3494 set_mus_location(gr_dur_spread, gr_from_beg) 3495 set_mus_location(sr_env, gr_from_beg) 3496 set_mus_location(sr_spread_env, gr_from_beg) 3497 set_mus_location(gr_start, gr_from_beg) 3498 set_mus_location(gr_start_spread, gr_from_beg) 3499 set_mus_location(gr_dens_env, gr_from_beg) 3500 set_mus_location(gr_dens_spread_env, gr_from_beg) 3501 in_start_value = env(gr_start) * gr_start_scaler + 3502 random_spread(env(gr_start_spread) * gr_start_scaler) 3503 in_start = (in_start_value * in_file_sr).round 3504 gr_duration = [grain_duration_limit, 3505 env(gr_dur) + random_spread(env(gr_dur_spread))].max 3506 gr_samples = seconds2samples(gr_duration) 3507 gr_srate = if srate_linear 3508 env(sr_env) + random_spread(env(sr_spread_env)) 3509 else 3510 env(sr_env) * srate_base ** random_spread(env(sr_spread_env)) 3511 end 3512 set_mus_increment(in_file_reader, gr_srate) 3513 in_samples = (gr_samples / (1.0 / srate_ratio)).round 3514 set_mus_phase(gr_env, 0.0) 3515 set_mus_phase(gr_env_end, 0.0) 3516 set_mus_frequency(gr_env, 1.0 / gr_duration) 3517 set_mus_frequency(gr_env_end, 1.0 / gr_duration) 3518 gr_dens = env(gr_dens_env) 3519 gr_dens_spread = random_spread(env(gr_dens_spread_env)) 3520 samples += gr_samples 3521 grain_counter += 1 3522 where = case where_to 3523 when Grani_to_grain_duration 3524 gr_duration 3525 when Grani_to_grain_start 3526 in_start_value 3527 when Grani_to_grain_sample_rate 3528 gr_srate 3529 when Grani_to_grain_random 3530 random(1.0) 3531 else 3532 Grani_to_locsig 3533 end 3534 if where.nonzero? and where_bins.length > 0 3535 (where_bins.length - 1).times do |chn| 3536 locsig_set!(@locsig, chn, 3537 (where.between?(where_bins[chn], where_bins[chn + 1]) ? 3538 1.0 : 3539 0.0)) 3540 end 3541 else 3542 if where_to == Grani_to_grain_allchans 3543 @channels.times do |chn| 3544 locsig_set!(@locsig, chn, 1.0) 3545 end 3546 else 3547 set_mus_location(gr_dist, gr_from_beg) 3548 set_mus_location(gr_dist_spread, gr_from_beg) 3549 set_mus_location(gr_degree, gr_from_beg) 3550 set_mus_location(gr_degree_spread, gr_from_beg) 3551 deg = env(gr_degree) + random_spread(env(gr_degree_spread)) 3552 dist = env(gr_dist) + random_spread(env(gr_dist_spread)) 3553 dist_scl = 1.0 / [dist, 1.0].max 3554 if sample2file?(@ws_reverb) 3555 locsig_reverb_set!(@locsig, 0, 3556 reverb_amount * (1.0 / sqrt([dist, 1.0].max))) 3557 end 3558 if @channels == 1 3559 locsig_set!(@locsig, 0, dist_scl) 3560 else 3561 if @channels == 2 3562 frac = [90.0, [0.0, deg].max].min / 90.0 3563 locsig_set!(@locsig, 0, dist_scl * (1.0 - frac)) 3564 locsig_set!(@locsig, 1, dist_scl * frac) 3565 else 3566 if @channels > 2 3567 locsig_set!(@locsig, 0, if deg.between?(0, 90) 3568 dist_scl * ((90.0 - deg) / 90.0) 3569 else 3570 if deg.between?(270, 360) 3571 dist_scl * ((deg - 270.0) / 90.0) 3572 else 3573 0.0 3574 end 3575 end) 3576 locsig_set!(@locsig, 1, if deg.between?(90, 180) 3577 dist_scl * (180.0 - deg) / 90.0 3578 else 3579 if deg.between?(0, 90) 3580 dist_scl * (deg / 90.0) 3581 else 3582 0.0 3583 end 3584 end) 3585 locsig_set!(@locsig, 2, if deg.between?(180, 270) 3586 dist_scl * (270.0 - deg) / 90.0 3587 else 3588 if deg.between?(90, 180) 3589 dist_scl * (deg - 90.0) / 90.0 3590 else 3591 0.0 3592 end 3593 end) 3594 if @channels > 3 3595 locsig_set!(@locsig, 3, if deg.between?(270, 360) 3596 dist_scl * (360.0 - deg) / 90.0 3597 else 3598 if deg.between?(180, 270) 3599 dist_scl * (deg - 180.0) / 90.0 3600 else 3601 0.0 3602 end 3603 end) 3604 end 3605 end 3606 end 3607 end 3608 end 3609 end 3610 in_start = if (in_start + in_samples) > last_in_sample 3611 last_in_sample - in_samples 3612 else 3613 [in_start, 0].max 3614 end 3615 set_ws_location(rd, in_start) 3616 0.0 3617 end 3618 end 3619 close_ws_reader(rd) 3620end 3621 3622def grani_test(start = 0.0, dur = 1.0) 3623 grani(start, dur, 5.0, "oboe.snd", :grain_envelope, raised_cosine()) 3624 $now = start + dur + 0.2 3625end 3626 3627# BES-FM 3628def bes_fm(start, dur, freq, amp, ratio, index) 3629 car_ph = mod_ph = 0.0 3630 car_incr = hz2radians(freq) 3631 mod_incr = ratio.to_f * car_incr 3632 ampenv = make_env(:envelope, [0, 0, 25, 1, 75, 1, 100, 0], 3633 :scaler, amp, 3634 :duration, dur) 3635 run_instrument(start, dur) do 3636 out_val = env(ampenv) * bes_j1(car_ph) 3637 car_ph = car_ph + car_incr + index.to_f * bes_j1(mod_ph) 3638 mod_ph += mod_incr 3639 out_val 3640 end 3641end 3642 3643def bes_fm_test(start = 0.0, dur = 1.0) 3644 bes_fm(start, dur, 440, 10, 1, 4) 3645 $now = start + dur + 0.2 3646end 3647 3648# SSB_FM 3649class Ssb_fm < Musgen 3650 def initialize(freq) 3651 super() 3652 @frequency = freq 3653 @osc1 = make_oscil(freq, 0) 3654 @osc2 = make_oscil(freq, HALF_PI) 3655 @osc3 = make_oscil(0, 0) 3656 @osc4 = make_oscil(0, HALF_PI) 3657 @hilbert = make_hilbert_transform(40) 3658 @delay = make_delay(40) 3659 end 3660 3661 def inspect 3662 format("%s.new(%s)", self.class, @frequency) 3663 end 3664 3665 def to_s 3666 format("#<%s freq: %s>", self.class, @frequency) 3667 end 3668 3669 def run_func(val1 = 0.0, val2 = 0.0) 3670 ssb_fm(val1) 3671 end 3672 3673 def ssb_fm(modsig) 3674 am0 = oscil(@osc1) 3675 am1 = oscil(@osc2) 3676 car0 = oscil(@osc3, hilbert_transform(@hilbert, modsig)) 3677 car1 = oscil(@osc4, delay(@delay, modsig)) 3678 am0 * car0 + am1 * car1 3679 end 3680end 3681 3682def make_ssb_fm(freq = 440.0) 3683 Ssb_fm.new(freq) 3684end 3685 3686def ssb_fm?(obj) 3687 obj.kind_of?(Ssb_fm) 3688end 3689 3690def ssb_fm(gen, modsig = 0.0) 3691 gen.ssb_fm(modsig) 3692end 3693 3694# FM2 3695class Fm2 < Musgen 3696 def initialize(f1, f2, f3, f4, p1, p2, p3, p4) 3697 super() 3698 @osc1 = make_oscil(f1, p1) 3699 @osc2 = make_oscil(f2, p2) 3700 @osc3 = make_oscil(f3, p3) 3701 @osc4 = make_oscil(f4, p4) 3702 end 3703 3704 def inspect 3705 format("%s.new(%s, %s, %s, %s, %s, %s, %s, %s)", 3706 self.class, @f1, @f2, @f3, @f4, @p1, @p2, @p3, @p4) 3707 end 3708 3709 def to_s 3710 format("#<%s %1.3f, %1.3f, %1.3f, %1.3f, %1.3f, %1.3f, %1.3f, %1.3f>", 3711 self.class, @f1, @f2, @f3, @f4, @p1, @p2, @p3, @p4) 3712 end 3713 3714 def run_func(val1 = 0.0, val2 = 0.0) 3715 fm2(val1) 3716 end 3717 3718 def fm2(index) 3719 (oscil(@osc1, index * oscil(@osc2)) + 3720 oscil(@osc3, index * oscil(@osc4))) * 0.25 3721 end 3722end 3723 3724# make_fm2(1000, 100, 1000, 100, 0, 0, HALF_PI, HALF_PI) 3725# make_fm2(1000, 100, 1000, 100, 0, 0, 0, HALF_PI) 3726def make_fm2(f1, f2, f3, f4, p1, p2, p3, p4) 3727 Fm2.new(f1, f2, f3, f4, p1, p2, p3, p4) 3728end 3729 3730def fm2?(obj) 3731 obj.kind_of?(Fm2) 3732end 3733 3734def fm2(gen, index = 0.0) 3735 gen.fm2(index) 3736end 3737 3738def clm_ins_test(start = 0.0, dur = 1.0) 3739 $now = start 3740 violin_test($now, dur) 3741 fm_violin_test($now, dur) 3742 pluck_test($now, dur) 3743 vox_test($now, dur) 3744 fofins_test($now, dur) 3745 fm_trumpet_test($now, dur) 3746 pqw_vox_test($now, dur) 3747 flute_test($now, dur) 3748 fm_bell_test($now, dur) 3749 fm_insect_test($now, dur) 3750 fm_drum_test($now, dur) 3751 gong_test($now, dur) 3752 attract_test($now, dur) 3753 pqw_test($now, dur) 3754 tubebell_test($now, dur) 3755 wurley_test($now, dur) 3756 rhodey_test($now, dur) 3757 hammondoid_test($now, dur) 3758 metal_test($now, dur) 3759 drone_canter_test($now, dur) 3760 reson_test($now, dur) 3761 cellon_test($now, dur) 3762 gran_synth_test($now, dur) 3763 touch_tone_test($now, dur) 3764 spectra_test($now, dur) 3765 two_tab_test($now, dur) 3766 lbj_piano_test($now, dur) 3767 resflt_test($now, dur) 3768 scratch_test($now, dur) 3769 pins_test($now, dur) 3770 zc_test($now, dur) 3771 zn_test($now, dur) 3772 za_test($now, dur) 3773 clm_expsrc_test($now, dur) 3774 exp_snd_test($now, dur) 3775 expfil_test($now, dur) 3776 graph_eq_test($now, dur) 3777 anoi_test($now, dur) 3778 fullmix_test($now, dur) 3779 grani_test($now, dur) 3780 bes_fm_test($now, dur) 3781end 3782 3783# clm-ins.rb ends here 3784