File: HarmonicsVoice.html

package info (click to toggle)
supercollider 1%3A3.4.5-1wheezy1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 26,972 kB
  • sloc: cpp: 116,645; lisp: 64,914; ansic: 10,725; python: 3,548; perl: 766; ruby: 487; sh: 152; makefile: 117; xml: 13
file content (140 lines) | stat: -rw-r--r-- 12,037 bytes parent folder | download | duplicates (3)
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title></title>
<meta name="Generator" content="Cocoa HTML Writer">
<meta name="CocoaVersion" content="949.54">
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 22.0px Arial}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Arial; min-height: 15.0px}
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Arial}
p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #ad1d13}
p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #0019ba}
span.s1 {text-decoration: underline}
span.s2 {color: #0019ba}
span.s3 {color: #000000}
span.s4 {color: #ad1d13}
span.s5 {color: #2b6f11}
span.s6 {color: #606060}
span.Apple-tab-span {white-space:pre}
</style>
</head>
<body>
<p class="p1">Adding harmonics to a voice input</p>
<p class="p2"><br></p>
<p class="p3">One easy way to add harmonics is to use the <span class="s1">[PitchShift]</span> UGen. See its helpfile for more details.</p>
<p class="p2"><br></p>
<p class="p3">An alternative approach is to use the <span class="s1">[Pitch]</span> UGen to track the pitch contour, and use that in synthesis. This allows you to generate sounds matching the pitch of the input but with any kind of texture.</p>
<p class="p2"><br></p>
<p class="p4">// (Dan Stowell) (public domain 2006)</p>
<p class="p4">// USE HEADPHONES to prevent feedback.</p>
<p class="p5">(</p>
<p class="p5">x = {</p>
<p class="p5"><span class="s2"><span class="Apple-tab-span">	</span>var</span> son, freq, hasFreq, amp, out, harm;</p>
<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span>son = </span><span class="s2">AudioIn</span><span class="s3">.ar(1); </span>// get first channel of sound input</p>
<p class="p5"><span class="Apple-tab-span">	</span># freq, hasFreq = <span class="s2">Pitch</span>.kr(son); <span class="s4">// Pitch of input signal</span></p>
<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span>amp = </span><span class="s2">Amplitude</span><span class="s3">.ar(son); </span>// Amplitude of input signal</p>
<p class="p6"><span class="Apple-tab-span">	</span></p>
<p class="p5"><span class="Apple-tab-span">	</span>harm = <span class="s2">SinOsc</span>.ar(freq * 2, 0, amp * hasFreq);</p>
<p class="p6"><span class="Apple-tab-span">	</span></p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="s2">Pan2</span>.ar(harm + son)</p>
<p class="p5">}.play;</p>
<p class="p5">)</p>
<p class="p6"><br></p>
<p class="p4"><span class="s3">x.free; </span>// Use this to stop the synth</p>
<p class="p2"><br></p>
<p class="p3">The above example adds only one harmonic. You can extend this to create multiple harmonics quite easily, for example by using an array of pitch ratios rather than a single ratio (and therefore creating an array of sine oscillators); or you could change the texture by using a more unusual oscillator (e.g. <span class="s1">[Saw]</span> or <span class="s1">[Gendy1]</span> or <span class="s1">[HenonN]</span>).</p>
<p class="p2"><br></p>
<p class="p3">If you want a large number of controllable overtones then a bank of separate sine oscillators will become quite computationally intensive, so a good alternative is to use the general wavetable oscillator <span class="s1">[Osc]</span> instead of SinOsc. The wavetable (a buffer) can be filled with a wave representing the harmonic profile you're interested in, and only one oscillator is needed to read it back.</p>
<p class="p2"><br></p>
<p class="p3">Let's implement this, and add a GUI for controlling the contents of the wavetable:</p>
<p class="p2"><br></p>
<p class="p4">// (Dan Stowell, kernel) (gpl 2006)</p>
<p class="p4">//first make and send the Synthdef so it's on the server</p>
<p class="p6"><br></p>
<p class="p5">(</p>
<p class="p7">SynthDef<span class="s3">(</span><span class="s5">\oscPlayer</span><span class="s3">, {</span>|bufnum,balance=0.5,smooth=0.1|</p>
<p class="p5"><span class="s2"><span class="Apple-tab-span">	</span>var</span> input,freq,hasFreq,amp,mix,wet;<span class="Apple-tab-span">	</span></p>
<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span>input = </span><span class="s2">AudioIn</span><span class="s3">.ar(1); </span>// get first channel of sound input</p>
<p class="p5"><span class="Apple-tab-span">	</span>#freq,hasFreq = <span class="s2">Pitch</span>.kr(input); <span class="s4">// pitch of input signal</span></p>
<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span>amp = </span><span class="s2">Amplitude</span><span class="s3">.ar(input); </span>// amplitude of input signal</p>
<p class="p5"><span class="Apple-tab-span">	</span>wet = <span class="s2">Osc</span>.ar(bufnum,<span class="s2">Lag</span>.kr(freq,smooth), 0, amp);</p>
<p class="p5"><span class="Apple-tab-span">	</span>mix = (input * (1-balance)) + (wet * balance);<span class="Apple-converted-space"> <span class="Apple-tab-span">	</span></span></p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="s2">Out</span>.ar(0, <span class="s2">Pan2</span>.ar(mix));</p>
<p class="p5">}).add;</p>
<p class="p5">)</p>
<p class="p6"><br></p>
<p class="p4">// select a GUI server:</p>
<p class="p4"><span class="s2">GUI</span><span class="s3">.cocoa;<span class="Apple-tab-span">	</span></span>// use Mac OS X native GUI</p>
<p class="p4"><span class="s2">GUI</span><span class="s3">.swing;<span class="Apple-tab-span">	</span></span>// use Java GUI</p>
<p class="p6"><br></p>
<p class="p6"><br></p>
<p class="p4">// Now to instantiate the synth and build the GUI.</p>
<p class="p4">// USE HEADPHONES to prevent feedback.</p>
<p class="p5">(</p>
<p class="p5"><span class="s2">var</span> win,buf,m,harmonics,maxHarmonics=60,theSynth;</p>
<p class="p6"><br></p>
<p class="p5">win = <span class="s2">Window</span>(<span class="s6">"input harmonica"</span>,<span class="s2">Rect</span>(200,200,420,160)).front;</p>
<p class="p6"><br></p>
<p class="p5">harmonics = <span class="s2">Array</span>.fill(maxHarmonics,0);</p>
<p class="p4"><span class="s3">harmonics.put(0,1);<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// init array so first partial is alive</p>
<p class="p5">buf = <span class="s2">Buffer</span>.alloc(s, 4096, 1);<span class="Apple-tab-span">	</span><span class="s4">// create buffer</span></p>
<p class="p5">buf.sine1(harmonics);<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s4">// fill buffer</span></p>
<p class="p6"><br></p>
<p class="p5">theSynth = <span class="s2">Synth</span>(<span class="s5">\oscPlayer</span>, [<span class="s5">\bufnum</span>, buf.bufnum], s);</p>
<p class="p6"><br></p>
<p class="p5">m = <span class="s2">MultiSliderView</span>(win, <span class="s2">Rect</span>(5, 5, 350, 100))</p>
<p class="p5"><span class="Apple-tab-span">	</span>.value_(harmonics)</p>
<p class="p5"><span class="Apple-tab-span">	</span>.isFilled_(<span class="s2">true</span>)</p>
<p class="p5"><span class="Apple-tab-span">	</span>.valueThumbSize_(3.0)</p>
<p class="p5"><span class="Apple-tab-span">	</span>.indexThumbSize_(3.0)</p>
<p class="p5"><span class="Apple-tab-span">	</span>.gap_(2)</p>
<p class="p5"><span class="Apple-tab-span">	</span>.elasticMode_(1)</p>
<p class="p5"><span class="Apple-tab-span">	</span>.action_({<span class="s2">|v|</span> buf.sine1(v.value)}); <span class="s4">// fill buffer again</span></p>
<p class="p6"><span class="Apple-tab-span">	</span></p>
<p class="p5"><span class="s2">Button</span>(win,<span class="s2">Rect</span>(5,110,70,20))</p>
<p class="p5"><span class="Apple-tab-span">	</span>.states_([[<span class="s6">"CLEAR"</span>,<span class="s2">Color</span>.green,<span class="s2">Color</span>.black]])</p>
<p class="p5"><span class="Apple-tab-span">	</span>.action_({<span class="s2">var</span> temp;</p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>temp = <span class="s2">Array</span>.fill(maxHarmonics,0);</p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>buf.sine1(temp);</p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>m.value_(temp);</p>
<p class="p5"><span class="Apple-tab-span">	</span>});</p>
<p class="p6"><span class="Apple-tab-span">	</span></p>
<p class="p5"><span class="s2">Button</span>(win,<span class="s2">Rect</span>(80,110,65,20))</p>
<p class="p5"><span class="Apple-tab-span">	</span>.states_([[<span class="s6">"RAND"</span>,<span class="s2">Color</span>.green,<span class="s2">Color</span>.black]])</p>
<p class="p5"><span class="Apple-tab-span">	</span>.action_({<span class="s2">|v|</span> <span class="s2">var</span> temp;</p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>temp = m.value.scramble;</p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>buf.sine1(temp);</p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>m.value_(temp);</p>
<p class="p5"><span class="Apple-tab-span">	</span>});</p>
<p class="p6"><span class="Apple-tab-span">	</span></p>
<p class="p5"><span class="s2">Button</span>(win,<span class="s2">Rect</span>(150,110,20,20))</p>
<p class="p5"><span class="Apple-tab-span">	</span>.states_([[<span class="s6">"&lt;&lt;"</span>,<span class="s2">Color</span>.green,<span class="s2">Color</span>.black]])</p>
<p class="p5"><span class="Apple-tab-span">	</span>.action_({<span class="s2">|v|</span> <span class="s2">var</span> temp;</p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>temp = m.value.rotate(-1);</p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>buf.sine1(temp);</p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>m.value_(temp);</p>
<p class="p5"><span class="Apple-tab-span">	</span>});</p>
<p class="p6"><span class="Apple-tab-span">	</span></p>
<p class="p5"><span class="s2">Button</span>(win,<span class="s2">Rect</span>(175,110,20,20))</p>
<p class="p5"><span class="Apple-tab-span">	</span>.states_([[<span class="s6">"&gt;&gt;"</span>,<span class="s2">Color</span>.green,<span class="s2">Color</span>.black]])</p>
<p class="p5"><span class="Apple-tab-span">	</span>.action_({<span class="s2">|v|</span> <span class="s2">var</span> temp;</p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>temp = m.value.rotate(1);</p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>buf.sine1(temp);</p>
<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>m.value_(temp);</p>
<p class="p5"><span class="Apple-tab-span">	</span>});</p>
<p class="p6"><span class="Apple-tab-span">	</span></p>
<p class="p5"><span class="s2">Slider</span>(win, <span class="s2">Rect</span>(365,5,20,100))</p>
<p class="p5"><span class="Apple-tab-span">	</span>.value_(0.1)</p>
<p class="p5"><span class="Apple-tab-span">	</span>.action_({<span class="s2">|v|</span> theSynth.set(<span class="s5">\smooth</span>,[0,1,<span class="s5">\lin</span>,0.001].asSpec.unmap(v.value))});</p>
<p class="p6"><span class="Apple-tab-span">	</span></p>
<p class="p5"><span class="s2">Slider</span>(win, <span class="s2">Rect</span>(390,5,20,100))</p>
<p class="p5"><span class="Apple-tab-span">	</span>.value_(0.5)</p>
<p class="p5"><span class="Apple-tab-span">	</span>.action_({<span class="s2">|v|</span> theSynth.set(<span class="s5">\balance</span>,v.value)});</p>
<p class="p5">)</p>
</body>
</html>