File: KMeansRT.schelp

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 (114 lines) | stat: -rw-r--r-- 3,608 bytes parent folder | download | duplicates (4)
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
CLASS:: KMeansRT
summary:: k-means classification in real time
categories:: UGens>Analysis
related:: Classes/KMeans, Classes/NearestN

DESCRIPTION::

Performs online k-means classification, classifying each datapoint that comes in and updating the k-means centroids.

The method is described in Algorithm B.1 of Brian McFee's 2012 thesis (http://cseweb.ucsd.edu/~bmcfee/papers/bmcfee_dissertation.pdf ). McFee calls it "online Hartigan k-means".


CLASSMETHODS::

METHOD:: kr
argument:: bufnum
a Buffer with "k" frames and "d + 1" channels (where d is the number of dimensions of input data. Each frame of the Buffer will hold data for a centroid (the centroid location, plus the final channel holds the effective number of points associated with the centroid).

argument:: inputdata
An array representing the input point. Num channels must match the dimensionality of the points in the dataset.

argument:: k
k is the number of centroids.

argument:: gate
The unit is active while gate > 0. While <=0, no search is performed and output is held steady

argument:: reset
If reset is greater than 0, the "flexibility" of the centroids is reset back to initial values (as if no data had been received).

argument:: learn
Controls whether the unit is learning from its input. If you set this to zero it will not learn, but will still output decisions. This is useful for applying a previously-learned clusterer without modifying it.
This argument cannot be modulated: each time you use KMeansRT it is either learning from scratch, or using a fixed pre-learnt buffer.

returns:: the cluster index with which the input datapoint has been associated.


METHOD:: getCentroid
A convenience method (just a wrapper round BufRd really) that lets you access the centroid location, given a cluster index.
argument:: bufnum
the same buffer as is passed to .kr
argument:: classif
the classification index, i.e. the output from .kr
argument:: ndims
the number of dimensions ("d" in the above description)
returns:: the "d"-dimensional current location of the centroid corresponding to index "classif".

EXAMPLES::

This example clusters every frame of a sound sample, using the spectral centroid of each frame, and sonifies the result:

code::
s.boot;
k = 5;
~ndims = 1;
b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");
~kbuf = Buffer.alloc(s, k, ~ndims+1)

(
x = {
	var sig, chain, chaintrig, features, kbuf, classif, centroid, resynth;

	// sig = AudioIn.ar;
	sig = PlayBuf.ar(1, b, loop: 1);
	chain = FFT(LocalBuf(512), sig);
	chaintrig = chain > -0.001;

	features = [SpecCentroid.kr(chain)]; // just one 1D feature here
	classif = KMeansRT.kr(~kbuf, features, k, chaintrig);
	classif.poll(chaintrig);

	// Now we read the centroid position back out of the buffer and sonify
	centroid = KMeansRT.getCentroid(~kbuf, classif, ~ndims).at(0);

	resynth = SinOsc.ar(centroid, 0, 0.1);
	[sig, resynth]
}.play
)

x.free
::

This example clusters onsets:

code::
s.boot;
k = 5;
~ndims = 1;
// Specify a stereo music recording you have locally.
b = Buffer.cueSoundFile(s, "~/back_to_black.wav".standardizePath, 0, 2);
~kbuf = Buffer.alloc(s, k, ~ndims+1)

(
x = {
	var sig, chain, trig, features, kbuf, classif, centroid, resynth;

	sig = DiskIn.ar(2, b.bufnum);

	chain = FFT(LocalBuf(1024), sig.mean);
	trig = Onsets.kr(chain);

	features = [SpecCentroid.kr(chain)]; // just one 1D feature here
	classif = KMeansRT.kr(~kbuf, features, k, trig);
	classif.poll(trig);

	resynth = Pulse.ar(classif.linexp(0, k, 100, 1000)) * 0.9 * EnvGen.ar(Env.perc, trig);
	sig + resynth
}.play
)

x.free;
b.close; b.free;
::