Extending sigmund~ to also output the spectral centroid

    Feb 06 2012 | 2:08 am
    Hi there, in the interests of speed I want sigmund~ to output the spectral centroid. Looking at the sigmund~ code, I'm having a bit of difficultly working out where to inject the code, because almost none of it is commented. So basically I'm looking for an array of the results of the FFT, so I can take the weighted average of the bins. I think it might be here but I'm not sure. Can someone who knows the object more confirm this? Cheers.
    mayer_realfft(npts2, bigbuf);
        for (i = 0; i < npts; i++)
            rawreal[i] = bigbuf[i];
        for (i = 1; i < npts-1; i++)
            rawimag[i] = bigbuf[npts2-i];
        rawreal[-1] = rawreal[1];
        rawreal[-2] = rawreal[2];
        rawreal[-3] = rawreal[3];
        rawreal[-4] = rawreal[4];
        rawimag[0] = rawimag[npts-1] = 0;
        rawimag[-1] = -rawimag[1];
        rawimag[-2] = -rawimag[2];
        rawimag[-3] = -rawimag[3];
        rawimag[-4] = -rawimag[4];
    #if 1
        for (i = 0, fp1 = rawreal, fp2 = rawimag; i < npts-1; i++, fp1++, fp2++)
            float x1 = fp1[1] - fp1[-1], x2 = fp2[1] - fp2[-1];
            powbuf[i] = x1*x1+x2*x2;
        powbuf[npts-1] = 0;

    • Feb 06 2012 | 4:24 am
      Why not just use descriptorsrt~ ? It does pitch/centroid and oodles more.
    • Feb 07 2012 | 9:49 pm
      Cheers for the heads up, but it's mac only at the moment unfortunately (that pack looks great too). Also, I'm doing this for performance reasons, since all I need is the pitch and centroid so slipping it into sigmund seems the best option.
    • Feb 08 2012 | 1:26 am
      the zsa descriptors package has zsa.centroid~, which might be easier to use than recompiling external code
    • Feb 08 2012 | 1:45 am
      I keep forgetting it's mac only. I think I've read he has a beta windows set out there, so that might be worth looking into as it's a pretty solid (set of) object(s).
    • Feb 08 2012 | 2:13 am
      I have a working windows build here. It's on my todo list to release very soon but in the meantime feel free to contact me offlist (see my website for email).
      The zsa stuff is another possible route.
      As for the sigmund code you are looking at the power calculation there. You could calculate the centroid directly from the powerbuf. FWIW - The fft in sigmund~ is taken without window function, as miller applies a von hann window in the frequency domain with a 3 bin convolution (convolution in the freq domain is multiplication in the time domain). If you want windowing) you'll ahve to do it in the frequency domain otherwise it'll mess the rest of sigmund's calculations up. For a von han window I'm sure it'll change the result by much and possibly not at all, but my brain can't cope with the maths that would confirm that right now....
      It's pretty gnarly code - so good luck!
    • Feb 08 2012 | 8:15 am
      Sorry - that should be I'm *not* sure it will change the result by much....
    • Feb 08 2012 | 9:28 pm
      Thanks. I'm gonna check out the zsa stuff for sure. Ta for the help Alex, so calculating the centroid from the powbuff won't be effected by the windowing (or lack of it)? And just to confirm, do I calculate the centroid by sum the freqs*pow / sum of the pow?
    • Feb 09 2012 | 12:35 am
      Sorry, my bad, the calculation will definitely be affected by windowing - the question is by how much? I suspect that the effect is not significant, but if it is you just need to have it windowed you can do a von hann window with just adds/subtracts in the freq domain but it is bit complex to explain in full and needs to operate on the raw complex data. Technically you need a multiply also for the scaling to be correct, but the centroid should be unaffected by scaling by a constant factor as far as I can deduce right now...
      Looking again at the code above I am unclear on whether the power buffer is being calculated for the windowed data or not. The subtracts before the squaring and addition *might* be doing this, but I'd need to look over the sigmund code in a lot more detail to be sure, and figure out the data format of the mayer fft also, which I forget....
    • Apr 15 2012 | 10:26 am
      Look at my object library there is a centroid~ object, it works on Windows and OsX with fftw. This a beta version but it works.
      Pierre Guillot
    • Apr 18 2012 | 3:38 pm
      Zsa.descriptors also works on windows. If you just want to calculate a centroid, have a look to the gen~.pfft_centroid.maxpat example which comes with Max 6. In my experience the window doesn't affect significantly (it does a bit, but nothing really worth worrying about IMHO).