Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 95d3f164d2d2601a18df0c474456c9fb921d821b)
+++ src/Makefile.am	(revision 1651b58b304306342c74fbf5e60e994f5b17f27b)
@@ -24,5 +24,4 @@
 	spectral/tss.h \
 	spectral/specdesc.h \
-	spectral/spectral_centroid.h \
 	pitch/pitch.h \
 	pitch/pitchmcomb.h \
@@ -58,5 +57,6 @@
 	spectral/fft.c \
 	spectral/tss.c \
-	spectral/spectral_centroid.c \
+	spectral/specdesc.c \
+	spectral/statistics.c \
 	pitch/pitch.c \
 	pitch/pitchmcomb.c \
@@ -66,5 +66,4 @@
 	pitch/pitchyinfft.c \
 	onset/onset.c \
-	onset/onsetdetection.c \
 	onset/peakpick.c \
 	tempo/tempo.c \
Index: src/aubio.h
===================================================================
--- src/aubio.h	(revision 95d3f164d2d2601a18df0c474456c9fb921d821b)
+++ src/aubio.h	(revision 1651b58b304306342c74fbf5e60e994f5b17f27b)
@@ -184,5 +184,4 @@
 #include "pitch/pitchschmitt.h"
 #include "pitch/pitchfcomb.h"
-#include "spectral/spectral_centroid.h"
 #include "onset/peakpick.h"
 #include "tempo/beattracking.h"
Index: src/spectral/specdesc.c
===================================================================
--- src/spectral/specdesc.c	(revision 95d3f164d2d2601a18df0c474456c9fb921d821b)
+++ src/spectral/specdesc.c	(revision 1651b58b304306342c74fbf5e60e994f5b17f27b)
@@ -27,101 +27,27 @@
 #include "utils/hist.h"
 
-/** Energy based onset detection function 
- 
-  This function calculates the local energy of the input spectral frame.
-  
-  \param o onset detection object as returned by new_aubio_specdesc()
-  \param fftgrain input spectral frame
-  \param onset output onset detection function
-
-*/
 void aubio_specdesc_energy(aubio_specdesc_t *o, cvec_t * fftgrain, fvec_t * onset);
-/** High Frequency Content onset detection function
- 
-  This method computes the High Frequency Content (HFC) of the input spectral
-  frame. The resulting function is efficient at detecting percussive onsets.
-
-  Paul Masri. Computer modeling of Sound for Transformation and Synthesis of
-  Musical Signal. PhD dissertation, University of Bristol, UK, 1996.
-  
-  \param o onset detection object as returned by new_aubio_specdesc()
-  \param fftgrain input spectral frame
-  \param onset output onset detection function
-
-*/
 void aubio_specdesc_hfc(aubio_specdesc_t *o, cvec_t * fftgrain, fvec_t * onset);
-/** Complex Domain Method onset detection function 
- 
-  Christopher Duxbury, Mike E. Davies, and Mark B. Sandler. Complex domain
-  onset detection for musical signals. In Proceedings of the Digital Audio
-  Effects Conference, DAFx-03, pages 90-93, London, UK, 2003.
-
-  \param o onset detection object as returned by new_aubio_specdesc()
-  \param fftgrain input spectral frame
-  \param onset output onset detection function
-
-*/
 void aubio_specdesc_complex(aubio_specdesc_t *o, cvec_t * fftgrain, fvec_t * onset);
-/** Phase Based Method onset detection function 
-
-  Juan-Pablo Bello, Mike P. Davies, and Mark B. Sandler. Phase-based note onset
-  detection for music signals. In Proceedings of the IEEE International
-  Conference on Acoustics Speech and Signal Processing, pages 441­444,
-  Hong-Kong, 2003.
-
-  \param o onset detection object as returned by new_aubio_specdesc()
-  \param fftgrain input spectral frame
-  \param onset output onset detection function
-
-*/
 void aubio_specdesc_phase(aubio_specdesc_t *o, cvec_t * fftgrain, fvec_t * onset);
-/** Spectral difference method onset detection function 
-
-  Jonhatan Foote and Shingo Uchihashi. The beat spectrum: a new approach to
-  rhythm analysis. In IEEE International Conference on Multimedia and Expo
-  (ICME 2001), pages 881­884, Tokyo, Japan, August 2001.
-
-  \param o onset detection object as returned by new_aubio_specdesc()
-  \param fftgrain input spectral frame
-  \param onset output onset detection function
-
-*/
 void aubio_specdesc_specdiff(aubio_specdesc_t *o, cvec_t * fftgrain, fvec_t * onset);
-/** Kullback-Liebler onset detection function 
-  
-  Stephen Hainsworth and Malcom Macleod. Onset detection in music audio
-  signals. In Proceedings of the International Computer Music Conference
-  (ICMC), Singapore, 2003.
-  
-  \param o onset detection object as returned by new_aubio_specdesc()
-  \param fftgrain input spectral frame
-  \param onset output onset detection function
-
-*/
 void aubio_specdesc_kl(aubio_specdesc_t *o, cvec_t * fftgrain, fvec_t * onset);
-/** Modified Kullback-Liebler onset detection function 
-
-  Paul Brossier, ``Automatic annotation of musical audio for interactive
-  systems'', Chapter 2, Temporal segmentation, PhD thesis, Centre for Digital
-  music, Queen Mary University of London, London, UK, 2006.
-
-  \param o onset detection object as returned by new_aubio_specdesc()
-  \param fftgrain input spectral frame
-  \param onset output onset detection function
-
-*/
 void aubio_specdesc_mkl(aubio_specdesc_t *o, cvec_t * fftgrain, fvec_t * onset);
-/** Spectral Flux 
-
-  Simon Dixon, Onset Detection Revisited, in ``Proceedings of the 9th
-  International Conference on Digital Audio Effects'' (DAFx-06), Montreal,
-  Canada, 2006. 
-
-  \param o onset detection object as returned by new_aubio_specdesc()
-  \param fftgrain input spectral frame
-  \param onset output onset detection function
-
-*/
 void aubio_specdesc_specflux(aubio_specdesc_t *o, cvec_t * fftgrain, fvec_t * onset);
+
+extern void aubio_specdesc_centroid (aubio_specdesc_t * o, cvec_t * spec,
+    fvec_t * desc);
+extern void aubio_specdesc_spread (aubio_specdesc_t * o, cvec_t * spec,
+    fvec_t * desc);
+extern void aubio_specdesc_skewness (aubio_specdesc_t * o, cvec_t * spec,
+    fvec_t * desc);
+extern void aubio_specdesc_kurtosis (aubio_specdesc_t * o, cvec_t * spec,
+    fvec_t * desc);
+extern void aubio_specdesc_slope (aubio_specdesc_t * o, cvec_t * spec,
+    fvec_t * desc);
+extern void aubio_specdesc_decrease (aubio_specdesc_t * o, cvec_t * spec,
+    fvec_t * desc);
+extern void aubio_specdesc_rolloff (aubio_specdesc_t * o, cvec_t * spec,
+    fvec_t * desc);
 
 /** onsetdetection types */
@@ -135,4 +61,11 @@
         aubio_onset_mkl,            /**< modified Kullback Liebler */
         aubio_onset_specflux,       /**< spectral flux */
+        aubio_specmethod_centroid,  /**< spectral centroid */
+        aubio_specmethod_spread,    /**< spectral spread */
+        aubio_specmethod_skewness,  /**< spectral skewness */
+        aubio_specmethod_kurtosis,  /**< spectral kurtosis */
+        aubio_specmethod_slope,     /**< spectral kurtosis */
+        aubio_specmethod_decrease,  /**< spectral decrease */
+        aubio_specmethod_rolloff,   /**< spectral rolloff */
         aubio_onset_default = aubio_onset_hfc, /**< default mode, set to hfc */
 } aubio_specdesc_type;
@@ -342,8 +275,22 @@
   else if (strcmp (onset_mode, "specflux") == 0)
       onset_type = aubio_onset_specflux;
+  else if (strcmp (onset_mode, "centroid") == 0)
+      onset_type = aubio_specmethod_centroid;
+  else if (strcmp (onset_mode, "spread") == 0)
+      onset_type = aubio_specmethod_spread;
+  else if (strcmp (onset_mode, "skewness") == 0)
+      onset_type = aubio_specmethod_skewness;
+  else if (strcmp (onset_mode, "kurtosis") == 0)
+      onset_type = aubio_specmethod_kurtosis;
+  else if (strcmp (onset_mode, "slope") == 0)
+      onset_type = aubio_specmethod_slope;
+  else if (strcmp (onset_mode, "decrease") == 0)
+      onset_type = aubio_specmethod_decrease;
+  else if (strcmp (onset_mode, "rolloff") == 0)
+      onset_type = aubio_specmethod_rolloff;
   else if (strcmp (onset_mode, "default") == 0)
       onset_type = aubio_onset_default;
   else {
-      AUBIO_ERR("unknown onset type.\n");
+      AUBIO_ERR("unknown spectral descriptor type %s.\n", onset_mode);
       onset_type = aubio_onset_default;
   }
@@ -412,4 +359,26 @@
       o->funcpointer = aubio_specdesc_specflux;
       break;
+    // for for the additional descriptors. these don't need additional memory
+    case aubio_specmethod_centroid:
+      o->funcpointer = aubio_specdesc_centroid;
+      break;
+    case aubio_specmethod_spread:
+      o->funcpointer = aubio_specdesc_spread;
+      break;
+    case aubio_specmethod_skewness:
+      o->funcpointer = aubio_specdesc_skewness;
+      break;
+    case aubio_specmethod_kurtosis:
+      o->funcpointer = aubio_specdesc_kurtosis;
+      break;
+    case aubio_specmethod_slope:
+      o->funcpointer = aubio_specdesc_slope;
+      break;
+    case aubio_specmethod_decrease:
+      o->funcpointer = aubio_specdesc_decrease;
+      break;
+    case aubio_specmethod_rolloff:
+      o->funcpointer = aubio_specdesc_rolloff;
+      break;
     default:
       break;
Index: c/spectral/spectral_centroid.c
===================================================================
--- src/spectral/spectral_centroid.c	(revision 95d3f164d2d2601a18df0c474456c9fb921d821b)
+++ 	(revision )
@@ -1,38 +1,0 @@
-/*
-  Copyright (C) 2007-2009 Paul Brossier <piem@aubio.org>
-
-  This file is part of aubio.
-
-  aubio is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  aubio is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with aubio.  If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "aubio_priv.h"
-#include "cvec.h"
-#include "spectral/spectral_centroid.h"
-
-smpl_t aubio_spectral_centroid(cvec_t * spectrum, smpl_t samplerate) {
-  uint_t i=0, j;
-  smpl_t sum = 0., sc = 0.;
-  for ( j = 0; j < spectrum->length; j++ ) {
-    sum += spectrum->norm[i][j];
-  }
-  if (sum == 0.) return 0.;
-  for ( j = 0; j < spectrum->length; j++ ) {
-    sc += (smpl_t)j * spectrum->norm[i][j];
-  }
-  return sc / sum * samplerate / (smpl_t)(spectrum->length);
-}
-
-
Index: c/spectral/spectral_centroid.h
===================================================================
--- src/spectral/spectral_centroid.h	(revision 95d3f164d2d2601a18df0c474456c9fb921d821b)
+++ 	(revision )
@@ -1,41 +1,0 @@
-/*
-  Copyright (C) 2007-2009 Paul Brossier <piem@aubio.org>
-
-  This file is part of aubio.
-
-  aubio is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  aubio is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with aubio.  If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-/** @file
- * compute spectrum centroid of a cvec object
- */
-
-#ifndef _SPECTRAL_CENTROID_H
-#define _SPECTRAL_CENTROID_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * spectrum centroid computed on a cvec
- */
-smpl_t aubio_spectral_centroid(cvec_t * input, smpl_t samplerate);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SPECTRAL_CENTROID_H */
Index: src/spectral/statistics.c
===================================================================
--- src/spectral/statistics.c	(revision 1651b58b304306342c74fbf5e60e994f5b17f27b)
+++ src/spectral/statistics.c	(revision 1651b58b304306342c74fbf5e60e994f5b17f27b)
@@ -0,0 +1,198 @@
+/*
+  Copyright (C) 2007-2009 Paul Brossier <piem@aubio.org>
+
+  This file is part of aubio.
+
+  aubio is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  aubio is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with aubio.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "aubio_priv.h"
+#include "cvec.h"
+#include "spectral/specdesc.h"
+
+smpl_t
+cvec_sum_channel (cvec_t * s, uint_t i)
+{
+  uint_t j;
+  smpl_t tmp = 0.0;
+  for (j = 0; j < s->length; j++)
+      tmp += s->norm[i][j];
+  return tmp;
+}
+
+smpl_t
+cvec_mean_channel (cvec_t * s, uint_t i)
+{
+  return cvec_sum_channel(s, i) / (smpl_t) (s->length);
+}
+
+smpl_t
+cvec_centroid_channel (cvec_t * spec, uint_t i)
+{
+  smpl_t sum = 0., sc = 0.;
+  uint_t j;
+  sum = cvec_sum_channel (spec, i); 
+  if (sum == 0.) {
+    return 0.;
+  } else {
+    for (j = 0; j < spec->length; j++) {
+      sc += (smpl_t) j *spec->norm[i][j];
+    }
+    return sc / sum;
+  }
+}
+
+smpl_t
+cvec_moment_channel (cvec_t * spec, uint_t i, uint_t order)
+{
+  smpl_t sum = 0., centroid = 0., sc = 0.;
+  uint_t j;
+  sum = cvec_sum_channel (spec, i); 
+  if (sum == 0.) {
+    return 0.;
+  } else {
+    centroid = cvec_centroid_channel (spec, i);
+    for (j = 0; j < spec->length; j++) {
+      sc += (smpl_t) POW(j - centroid, order) * spec->norm[i][j];
+    }
+    return sc / sum;
+  }
+}
+
+void
+aubio_specdesc_centroid (aubio_specdesc_t * o UNUSED, cvec_t * spec,
+    fvec_t * desc)
+{
+  uint_t i;
+  for (i = 0; i < spec->channels; i++) {
+    desc->data[i][0] = cvec_centroid_channel (spec, i); 
+  }
+}
+
+void
+aubio_specdesc_spread (aubio_specdesc_t * o UNUSED, cvec_t * spec,
+    fvec_t * desc)
+{
+  uint_t i;
+  for (i = 0; i < spec->channels; i++) {
+    desc->data[i][0] = cvec_moment_channel (spec, i, 2);
+  }
+}
+
+void
+aubio_specdesc_skewness (aubio_specdesc_t * o UNUSED, cvec_t * spec,
+    fvec_t * desc)
+{
+  uint_t i; smpl_t spread;
+  for (i = 0; i < spec->channels; i++) {
+    spread = cvec_moment_channel (spec, i, 2);
+    if (spread == 0) {
+      desc->data[i][0] = 0.;
+    } else {
+      desc->data[i][0] = cvec_moment_channel (spec, i, 3);
+      desc->data[i][0] /= POW ( SQRT (spread), 3);
+    }
+  }
+}
+
+void
+aubio_specdesc_kurtosis (aubio_specdesc_t * o UNUSED, cvec_t * spec,
+    fvec_t * desc)
+{
+  uint_t i; smpl_t spread;
+  for (i = 0; i < spec->channels; i++) {
+    spread = cvec_moment_channel (spec, i, 2);
+    if (spread == 0) {
+      desc->data[i][0] = 0.;
+    } else {
+      desc->data[i][0] = cvec_moment_channel (spec, i, 4);
+      desc->data[i][0] /= SQR (spread);
+    }
+  }
+}
+
+void
+aubio_specdesc_slope (aubio_specdesc_t * o UNUSED, cvec_t * spec,
+    fvec_t * desc)
+{
+  uint_t i, j;
+  smpl_t norm = 0, sum = 0.; 
+  // compute N * sum(j**2) - sum(j)**2
+  for (j = 0; j < spec->length; j++) {
+    norm += j*j;
+  }
+  norm *= spec->length;
+  // sum_0^N(j) = length * (length + 1) / 2
+  norm -= SQR( (spec->length) * (spec->length - 1.) / 2. );
+  for (i = 0; i < spec->channels; i++) {
+    sum = cvec_sum_channel (spec, i); 
+    desc->data[i][0] = 0.;
+    if (sum == 0.) {
+      break; 
+    } else {
+      for (j = 0; j < spec->length; j++) {
+        desc->data[i][0] += j * spec->norm[i][j]; 
+      }
+      desc->data[i][0] *= spec->length;
+      desc->data[i][0] -= sum * spec->length * (spec->length - 1) / 2.;
+      desc->data[i][0] /= norm;
+      desc->data[i][0] /= sum;
+    }
+  }
+}
+
+void
+aubio_specdesc_decrease (aubio_specdesc_t *o UNUSED, cvec_t * spec,
+    fvec_t * desc)
+{
+  uint_t i, j; smpl_t sum;
+  for (i = 0; i < spec->channels; i++) {
+    sum = cvec_sum_channel (spec, i); 
+    desc->data[i][0] = 0;
+    if (sum == 0.) {
+      break;
+    } else {
+      sum -= spec->norm[i][0];
+      for (j = 1; j < spec->length; j++) {
+        desc->data[i][0] += (spec->norm[i][j] - spec->norm[i][0]) / j;
+      }
+      desc->data[i][0] /= sum;
+    }
+  }
+}
+
+void
+aubio_specdesc_rolloff (aubio_specdesc_t *o UNUSED, cvec_t * spec,
+    fvec_t *desc)
+{
+  uint_t i, j; smpl_t cumsum, rollsum;
+  for (i = 0; i < spec->channels; i++) {
+    cumsum = 0.; rollsum = 0.;
+    for (j = 0; j < spec->length; j++) {
+      cumsum += SQR (spec->norm[i][j]);
+    }
+    if (cumsum == 0) {
+      desc->data[i][0] = 0.;
+    } else {
+      cumsum *= 0.95;
+      j = 0;
+      while (rollsum < cumsum) { 
+        rollsum += SQR (spec->norm[i][j]);
+        j++;
+      }
+      desc->data[i][0] = j;
+    }
+  }
+}
