SuperCollider CLASSES (extension)


k-means classification in real time
Inherits from: UGen : AbstractFunction : Object


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 ( ). McFee calls it "online Hartigan k-means".

Class Methods

*kr (bufnum, inputdata, k: 5, gate: 1, reset: 0, learn: 1)



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).


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


k is the number of centroids.


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


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


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.


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

*getCentroid (bufnum, classif, ndims)

A convenience method (just a wrapper round BufRd really) that lets you access the centroid location, given a cluster index.



the same buffer as is passed to .kr


the classification index, i.e. the output from .kr


the number of dimensions ("d" in the above description)


the "d"-dimensional current location of the centroid corresponding to index "classif".

Inherited class methods

Instance Methods

Inherited instance methods


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

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

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

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

    features = []; // just one 1D feature here
    classif =, features, k, chaintrig);

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

    resynth =, 0, 0.1);
    [sig, resynth]

This example clusters onsets:

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 =, b.bufnum);

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

    features = []; // just one 1D feature here
    classif =, features, k, trig);

    resynth =, k, 100, 1000)) * 0.9 *, trig);
    sig + resynth