scide: implement selectionLength for openDocument
[supercollider.git] / HelpSource / Classes / AmpComp.schelp
blob9ed9bc4ed210fea827ff63c2b97e14f56ba55c07
1 class:: AmpComp
2 summary:: Basic psychoacoustic amplitude compensation.
3 related:: Classes/AmpCompA
4 categories::  UGens>Analysis>Amplitude
7 Description::
9 Implements the (optimized) formula:
11 code::
12 compensationFactor = (root / freq) ** exp
16 Higher frequencies are normally perceived as louder, which AmpComp
17 compensates.
20 classmethods::
22 method::ar, kr, ir
24 argument::freq
26 Input frequency value. For freq == root, the output is 1.0.
29 argument::root
31 Root freq relative to which the curve is calculated
32 (usually lowest freq).
35 argument::exp
37 Exponent: how steep the curve decreases for increasing freq.
39 discussion::
40 Note that for frequencies very much smaller than root the amplitudes can become very high.
41 In this case limit the freq with code::freq.max(minval)::, or use AmpCompA.
43 Examples::
45 code::
46 // compare a sine without compensation
48 { SinOsc.ar(MouseX.kr(300, 15000, 1)) * 0.1 }.play;
50 // with one that uses amplitude compensation
53         var freq;
54         freq = MouseX.kr(300, 15000, 1);
55         SinOsc.ar(freq) * 0.1 * AmpComp.kr(freq, 300)
56 }.play;
60 // different sounds cause quite different loudness perception,
61 // and the desired musical behavior can vary, so the exponent can be tuned:
64         var freq;
65         freq = MouseX.kr(300, 15000, 1);
66         Pulse.ar(freq) * 0.1 * AmpComp.kr(freq, 300, 1.3)
67 }.play;
70 // the curves:
72 // exp = 0.3333
73 (200,210..10000).collect {|freq| (200/freq) ** 0.3333 }.plot;
75 // nearly linear for semitone steps:
77 (48..72).midicps.collect {|freq| (48.midicps/freq) ** 0.3333 }.plot;
78 { AmpComp.ar(Line.ar(48, 72, 1).midicps, 48.midicps) }.plot(1.0);
80 // exp = 1.2
81 (200,210..10000).collect {|freq| (200/freq) ** 1.2 }.plot;
82 (48..72).midicps.collect {|freq| (200/freq) ** 1.2 }.plot;
83 { AmpComp.ar(Line.ar(48, 72, 1).midicps, 48.midicps, 1.2) }.plot(1.0);
86 // amplitude compensation in frequency modulation
89         var freq;
90         freq = MouseX.kr(300, 15000, 1);
91         freq = freq * SinOsc.ar(MouseY.kr(3, 200, 1), 0, 0.5, 1);
92         SinOsc.ar(freq) * 0.1 * AmpComp.ar(freq, 300)
93 }.play;
96 // without amplitude compensation
99         var freq;
100         freq = MouseX.kr(300, 15000, 1);
101         freq = freq * SinOsc.ar(MouseY.kr(3, 200, 1), 0, 0.5, 1);
102         SinOsc.ar(freq) * 0.1
103 }.play;
106 // in granular synthesis:
108 SynthDef("pgrain",
109         { arg out = 0, sustain=0.01, amp=0.5, pan = 0;
110                 var freq = MouseX.kr(300, 7000, 1);
111                 var window = Env.sine(sustain, amp * AmpComp.ir(freq));
112                 Out.ar(out,
113                         Pan2.ar(
114                                 SinOsc.ar(freq),
115                                 pan
116                         ) * EnvGen.ar(window, doneAction:2)
117                 )
118         }
119 ).send(s);
122 // send grains
124 fork {
125         loop {
126                 s.sendBundle(0.1, [\s_new, \pgrain, -1,1,1]);
127                 0.02.wait;
128         };
133 // try different synth defs:
136 // without AmpComp:
139 SynthDef("pgrain",
140         { arg out = 0, sustain=0.01, amp=0.5, pan = 0;
141                 var freq = MouseX.kr(300, 7000, 1);
142                 var window = Env.sine(sustain, amp);
143                 Out.ar(out,
144                         Pan2.ar(
145                                 SinOsc.ar(freq),
146                                 pan
147                         ) * EnvGen.ar(window, doneAction:2)
148                 )
149         }
150 ).send(s);
153 // with AmpCompA
155 SynthDef("pgrain",
156         { arg out = 0, sustain=0.01, amp=0.5, pan = 0;
157                 var freq = MouseX.kr(300, 7000, 1);
158                 var window = Env.sine(sustain, amp * AmpCompA.ir(freq));
159                 Out.ar(out,
160                         Pan2.ar(
161                                 SinOsc.ar(freq),
162                                 pan
163                         ) * EnvGen.ar(window, doneAction:2)
164                 )
165         }
166 ).send(s);