1# noise.rb -- CLM -> Snd/Ruby translation of noise.ins 2 3# Translator/Author: Michael Scholz <mi-scholz@users.sourceforge.net> 4# Created: Wed Mar 19 05:16:56 CET 2003 5# Changed: Thu Oct 15 00:17:48 CEST 2009 6 7# Comments beginning with ;; are taken from noise.ins! 8 9# attack_point(dur, attack, decay, total_x = 100.0) 10# fm_noise(...) 11 12# ;;; The "noise" instrument (useful for Oceanic Music): 13 14require "ws" 15require "env" 16include Env 17 18def attack_point(dur, attack, decay, total_x = 100.0) 19 x = if 0.0 == attack 20 if 0.0 == decay 21 dur / 4.0 22 else 23 (dur - decay) / 4.0 24 end 25 else 26 attack.to_f 27 end 28 total_x * (x / dur) 29end 30 31def fm_noise(start, dur, freq0, 32 amp, ampfun, ampat, ampdc, 33 freq1, glissfun, freqat, freqdc, 34 rfreq0, rfreq1, rfreqfun, rfreqat, rfreqdc, 35 dev0, dev1, devfun, devat, devdc, 36 *args) 37 degree, distance, reverb = nil 38 optkey(args, binding, 39 [:degree, kernel_rand(90.0)], 40 [:distance, 1.0], 41 [:reverb, 0.005]) 42 43 # ;; ampat = amp envelope attack time, and so on -- this instrument 44 # ;; assumes your envelopes go from 0 to 100 on the x-axis, and that 45 # ;; the "attack" portion ends at 25, the "decay" portion starts at 46 # ;; 75. "rfreq" is the frequency of the random number generator -- 47 # ;; if below about 25 hz you get automatic composition, above that 48 # ;; you start to get noise. well, you get a different kind of 49 # ;; noise. "dev" is the bandwidth of the noise -- very narrow 50 # ;; gives a whistle, very broad more of a whoosh. this is 51 # ;; basically "simple fm", but the modulating signal is white 52 # ;; noise. 53 54 car = make_oscil(:frequency, freq0) 55 mod = make_rand(:frequency, rfreq0, :amplitude, 1.0) 56 dev_0 = hz2radians(dev0) 57 58 # ;; next fix-up troubles in attack and decay times (there are lots 59 # ;; of ways to handle this -- the basic problem is that these 60 # ;; durned instruments end up having way too many parameters. rick 61 # ;; taube's common music replacement for pla should help, but just 62 # ;; for old time's sake, we'll do it the way the ancients did it. 63 # ;; (we could also package up this stuff in our own function, 64 # ;; somewhat like the allvln function in vln.clm, leaving the 65 # ;; instrument code to apply envelopes and other data to some 66 # ;; patch). 67 68 amp_attack = attack_point(dur, ampat, ampdc) 69 amp_decay = 100.0 - attack_point(dur, ampdc, ampat) 70 freq_attack = attack_point(dur, freqat, freqdc) 71 freq_decay = 100.0 - attack_point(dur, freqdc, freqat) 72 dev_attack = attack_point(dur, devat, devdc) 73 dev_decay = 100.0 - attack_point(dur, devdc, devat) 74 rfreq_attack = attack_point(dur, rfreqat, rfreqdc) 75 rfreq_decay = 100.0 - attack_point(dur, rfreqdc, rfreqat) 76 77 # ;; now make the actual envelopes -- these all assume we are 78 # ;; thinking in terms of the "value when the envelope is 1" 79 # ;; (i.e. dev1 and friends), and the "value when the envelope is 0" 80 # ;; (i.e. dev0 and friends) -- over the years this seemed to make 81 # ;; beginners happier than various other ways of describing the 82 # ;; y-axis behaviour of the envelope. all this boiler-plate for 83 # ;; envelopes might seem overly elaborate when our basic instrument 84 # ;; is really simple, but in most cases, and this one in 85 # ;; particular, nearly all the musical interest comes from the 86 # ;; envelopes, not the somewhat dull spectrum generated by the 87 # ;; basic patch. 88 89 dev_f = make_env(stretch_envelope(devfun, 25, dev_attack, 75, dev_decay), 90 hz2radians(dev1 - dev0), dur) 91 amp_f = make_env(stretch_envelope(ampfun, 25, amp_attack, 75, amp_decay), amp, dur) 92 freq_f = make_env(stretch_envelope(glissfun, 25, freq_attack, 75, freq_decay), 93 hz2radians(freq1 - freq0), dur) 94 rfreq_f = make_env(stretch_envelope(rfreqfun, 25, rfreq_attack, 75, rfreq_decay), 95 hz2radians(rfreq1 - rfreq0), dur) 96 97 run_instrument(start, dur, :degree, degree, :distance, distance, :reverb_amount, reverb) do 98 env(amp_f) * oscil(car, env(freq_f) + (dev_0 + env(dev_f)) * rand(mod, env(rfreq_f))) 99 end 100end 101 102=begin 103with_sound(:statistics, true, :play, 1) do 104 fm_noise(0, 1.8, 500, 105 0.25, [0, 0, 25, 1, 75, 1, 100, 0], 0.1, 0.1, 106 1000, [0, 0, 100, 1], 0.1, 0.1, 107 10, 1000, [0, 0, 100, 1], 0, 0, 108 100, 500, [0, 0, 100, 1], 0, 0) 109 fm_noise(2, 1.8, 200, 110 0.25, [0, 0, 25, 1, 75, 1, 100, 0], 0.1, 0.1, 111 1000, [0, 0, 100, 1], 0.1, 0.1, 112 10, 1000, [0, 0, 100, 1], 0, 0, 113 100, 500, [0, 0, 100, 1], 0, 0) 114end 115=end 116 117# noise.rb ends here 118