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