File: Qitch.html

package info (click to toggle)
supercollider-sc3-plugins 3.7.1~repack-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 14,332 kB
  • ctags: 11,704
  • sloc: cpp: 140,180; lisp: 14,746; ansic: 2,133; xml: 86; makefile: 82; haskell: 21; sh: 8
file content (147 lines) | stat: -rw-r--r-- 12,268 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
141
142
143
144
145
146
147
<!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="1038.32">
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #376c2a}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica; min-height: 22.0px}
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica}
p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #606060}
p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
p.p9 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #cd1713}
p.p10 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 9.0px Monaco; color: #737373}
p.p11 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 9.0px Monaco; color: #cd1713}
p.p12 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #000000; min-height: 12.0px}
p.p13 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #ad140d}
p.p14 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 9.0px Monaco; color: #ad140d}
p.p15 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 9.0px Monaco}
span.s1 {font: 12.0px Helvetica; color: #000000}
span.s2 {color: #001bb9}
span.s3 {color: #000000}
span.s4 {color: #102ac3}
span.s5 {color: #606060}
span.s6 {color: #2c7014}
span.s7 {color: #ad140d}
span.Apple-tab-span {white-space:pre}
</style>
</head>
<body>
<p class="p1">//Copyright (C) 2006<span class="Apple-converted-space">  </span>Nick Collins distributed under the terms of the GNU General Public License</p>
<p class="p2"><br></p>
<p class="p3"><b>Qitch<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>constant Q transform pitch follower</b></p>
<p class="p4"><br></p>
<p class="p5"><b>#freq, hasFreq = Qitch.kr(in, databufnum,ampThreshold, algoflag, ampbufnum, minfreq, maxfreq)</b></p>
<p class="p4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
<p class="p5">This alternative pitch follower works in the frequency domain rather than Pitch's time domain correlation. Tradeoffs are made between latency and frequency resolution. It is meant to provide a relatively stable resultant tracked pitch based on a harmonic template. <span class="Apple-converted-space"> </span></p>
<p class="p4"><br></p>
<p class="p5">You must load one of the auxilliary data files into a Buffer and pass the bufnum to the routine. These files take the form:</p>
<p class="p4"><br></p>
<p class="p6"><span class="s1"><span class="Apple-converted-space"> </span></span>QspeckernN1024SR44100.wav</p>
<p class="p6"><span class="s1"><span class="Apple-converted-space"> </span></span>QspeckernN2048SR44100.wav</p>
<p class="p6"><span class="s1"><span class="Apple-converted-space"> </span></span>QspeckernN4096SR44100.wav</p>
<p class="p6"><span class="s1"><span class="Apple-converted-space"> </span></span>QspeckernN8192SR44100.wav</p>
<p class="p6"><span class="s1"><span class="Apple-converted-space"> </span></span>QspeckernN2048SR48000.wav</p>
<p class="p6"><span class="s1"><span class="Apple-converted-space"> </span></span>QspeckernN4096SR48000.wav</p>
<p class="p4"><br></p>
<p class="p5">Only use the one for your output sampling rate. Bigger N means more stability and resolution but longer delay and higher average CPU cost. N= 2048 is a good tradeoff if you don't want to track over 1000Hz fundamentals. The 48000 SR files are untested and provided without any promises.<span class="Apple-converted-space"> </span></p>
<p class="p4"><br></p>
<p class="p5"><b>in</b>- the audio rate input signal</p>
<p class="p5"><b>databufnum</b>- you must provide the initialisation data required by Qitch. This in the form of a .wav file that must be loaded to a buffer (see examples below).<span class="Apple-converted-space">  </span>The data files should have come with this UGen.<span class="Apple-converted-space"> </span></p>
<p class="p5"><b>ampThreshold</b>- Qitch outputs a 0 in hasFreq if the input amplitude is below this threshold. Same as original Pitch.<span class="Apple-converted-space"> </span></p>
<p class="p5"><b>algoflag</b>- 0 means use just the constant Q template pattern matcher. 1 flags the refinement based on the phase estimate.</p>
<p class="p5"><b>ampbufnum</b>- you may provide an 11 component buffer with template amplitudes- see example below.<span class="Apple-converted-space"> </span></p>
<p class="p5"><b>minfreq</b>- minimum output frequency in Hz</p>
<p class="p5"><b>maxfreq</b>- maximum output frequency in Hz</p>
<p class="p4"><br></p>
<p class="p5">In technical terms, this UGen calculates an FFT, applying Brown and Puckette's efficient constant Q transform on a quartertone scale, base note F3= 174.6Hz. Cross correlation search leads to the best match for a harmonic spectrum grid with falling amplitude components. A further fine tuning takes place based on instantaneous frequency estimation (rate of change of phase) for the winning FFT bin.<span class="Apple-converted-space"> </span></p>
<p class="p4"><br></p>
<p class="p5">The algorithms are based on the following papers:</p>
<p class="p4"><span class="Apple-converted-space"> </span></p>
<p class="p5">Judith C. Brown and Miller S. Puckette, 1992, An efficient algorithm for the calculation of a constant Q transform. Journal of the Acoustical Society of America. 92(5); 2698-701.</p>
<p class="p4"><span class="Apple-converted-space">   </span></p>
<p class="p5">Judith C. Brown, 1992, Musical Fundamental Frequency Tracking Using a Pattern Recognition Method. Journal of the Acoustical Society of America. 92(3); 1394-402.</p>
<p class="p4"><span class="Apple-converted-space">   </span></p>
<p class="p5">Judith C. Brown and Miller S. Puckette, 1993, A High-Resolution Fundamental Frequency Determination Based on Phase Changes of the Fourier Transform. Journal of the Acoustical Society of America. 94(2); 662-7.</p>
<p class="p4"><span class="Apple-converted-space">         </span></p>
<p class="p4"><br></p>
<p class="p5"><b>Examples: (use headphones!)</b></p>
<p class="p4"><br></p>
<p class="p7">s = <span class="s2">Server</span>.local;</p>
<p class="p8"><br></p>
<p class="p9">//assumes data file is in SC home application directory; else provide full path</p>
<p class="p10"><span class="s3">b = </span><span class="s4">Buffer</span><span class="s3">.read(s, </span>"QspeckernN4096SR44100.wav"<span class="s3">);<span class="Apple-converted-space"> </span></span></p>
<p class="p11">//this line is absolutely essential! You must load the data required by the UGen!<span class="Apple-converted-space"> </span></p>
<p class="p12"><br></p>
<p class="p9"><span class="s3">b.numFrames </span>//it's not that much data</p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p7">(</p>
<p class="p7">a= <span class="s2">SynthDef</span>(<span class="s5">"testqitch"</span>,{<span class="s2">arg</span> infreq=440;</p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="s2">var</span> in, freq, hasFreq, out;</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span>in=<span class="s2">SinOsc</span>.ar(infreq);</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span># freq, hasFreq = <span class="s2">Qitch</span>.kr(in, b.bufnum,0.01,1);</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="s2">Out</span>.ar(0,[<span class="s2">SinOsc</span>.ar(freq,0.1),in]);</p>
<p class="p7">}).play(s);</p>
<p class="p7">)</p>
<p class="p8"><br></p>
<p class="p7">a.set(<span class="s6">\infreq</span>,237);</p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p13"><span class="s3">c=</span><span class="s2">Buffer</span><span class="s3">.read(s,</span><span class="s5">"/Volumes/data/audio/nikkisitar/warmup.wav"</span><span class="s3">); </span>//sitar test file, try anything you have on your disk</p>
<p class="p8"><br></p>
<p class="p7">c.numFrames</p>
<p class="p8"><br></p>
<p class="p13"><span class="s3">( </span>//sample tracking</p>
<p class="p6"><span class="s2">SynthDef</span><span class="s3">(</span>"pitchFollow1"<span class="s3">,{</span></p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="s2">var</span> in, amp, freq, hasFreq, out;</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span>in = <span class="s2">PlayBuf</span>.ar(1,c.bufnum, loop:1);</p>
<p class="p7"><span class="Apple-tab-span">	</span>amp = <span class="s2">Amplitude</span>.kr(in, 0.05, 0.05);</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span># freq, hasFreq = <span class="s2">Qitch</span>.kr(in, b.bufnum, 0.1,1, -1,261, 800 );</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span>out = <span class="s2">Mix</span>.new(<span class="s2">VarSaw</span>.ar(freq * [0.5,1,2], 0, <span class="s2">LFNoise1</span>.kr(0.3,0.1,0.1), amp));</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="s2">Out</span>.ar(0,[out,in])</p>
<p class="p7">}).play(s);</p>
<p class="p7">)</p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p14"><span class="s3">b = </span><span class="s2">Buffer</span><span class="s3">.read(s, </span><span class="s5">"QspeckernN2048SR44100.wav"</span><span class="s3">); </span>//quicker response with this data set</p>
<p class="p8"><br></p>
<p class="p13"><span class="s3">d = </span><span class="s2">Buffer</span><span class="s3">.alloc(s,11); </span>//make an amp template</p>
<p class="p15">d.setn(0, [1,0.98,0.92,0.88,0.84,0.8,0.76,0.72,1.68,1.64,1.6]); <span class="s7">//must have 11 components</span></p>
<p class="p8"><br></p>
<p class="p13">//analogous to example in the Pitch helpfile<span class="Apple-converted-space"> </span></p>
<p class="p7">(</p>
<p class="p6"><span class="s2">SynthDef</span><span class="s3">(</span>"pitchFollow1"<span class="s3">,{</span></p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="s2">var</span> in, amp, freq, hasFreq, out;</p>
<p class="p7"><span class="Apple-tab-span">	</span>in = <span class="s2">Mix</span>.new(<span class="s2">AudioIn</span>.ar([1,2]));</p>
<p class="p7"><span class="Apple-tab-span">	</span>amp = <span class="s2">Amplitude</span>.kr(in, 0.05, 0.05);</p>
<p class="p7"><span class="Apple-tab-span">	</span># freq, hasFreq = <span class="s2">Qitch</span>.kr(in, b.bufnum, 0.02, 1, d.bufnum, 160, 880);</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p13"><span class="s3"><span class="Apple-tab-span">	</span></span>//freq = Lag.kr(freq.cpsmidi.round(1).midicps, 0.05);</p>
<p class="p7"><span class="Apple-tab-span">	</span>out = <span class="s2">Mix</span>.new(<span class="s2">VarSaw</span>.ar(freq * [0.5,1,2], 0, <span class="s2">LFNoise1</span>.kr(0.3,0.1,0.1), amp));</p>
<p class="p7"><span class="Apple-tab-span">	</span>6.do({</p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>out = <span class="s2">AllpassN</span>.ar(out, 0.040, [0.040.rand,0.040.rand], 2)</p>
<p class="p7"><span class="Apple-tab-span">	</span>});</p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="s2">Out</span>.ar(0,out)</p>
<p class="p7">}).play(s);</p>
<p class="p7">)</p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p4"><br></p>
<p class="p4"><br></p>
</body>
</html>