shithub: aubio

Download patch

ref: d95ff38e87972196954e1050130a87fbff85b385
parent: 0b9a02a653bc4e9d33b82eb5369ce6a94a637eed
author: Paul Brossier <piem@piem.org>
date: Thu Dec 3 20:38:30 EST 2009

src/spectral: switch to mono

--- a/src/spectral/fft.c
+++ b/src/spectral/fft.c
@@ -74,7 +74,6 @@
 
 struct _aubio_fft_t {
   uint_t winsize;
-  uint_t channels;
   uint_t fft_size;
   real_t *in, *out;
   fftw_plan pfw, pbw;
@@ -82,15 +81,14 @@
   fvec_t * compspec;
 };
 
-aubio_fft_t * new_aubio_fft(uint_t winsize, uint_t channels) {
+aubio_fft_t * new_aubio_fft(uint_t winsize) {
   aubio_fft_t * s = AUBIO_NEW(aubio_fft_t);
   uint_t i;
   s->winsize  = winsize;
-  s->channels = channels;
   /* allocate memory */
   s->in       = AUBIO_ARRAY(real_t,winsize);
   s->out      = AUBIO_ARRAY(real_t,winsize);
-  s->compspec = new_fvec(winsize,channels);
+  s->compspec = new_fvec(winsize);
   /* create plans */
 #ifdef HAVE_COMPLEX_H
   s->fft_size = winsize/2 + 1;
@@ -135,47 +133,43 @@
 }
 
 void aubio_fft_do_complex(aubio_fft_t * s, fvec_t * input, fvec_t * compspec) {
-  uint_t i, j;
-  for (i = 0; i < s->channels; i++) {
-    for (j=0; j < s->winsize; j++) {
-      s->in[j] = input->data[i][j];
-    }
-    fftw_execute(s->pfw);
+  uint_t j;
+  for (j=0; j < s->winsize; j++) {
+    s->in[j] = input->data[j];
+  }
+  fftw_execute(s->pfw);
 #ifdef HAVE_COMPLEX_H
-    compspec->data[i][0] = REAL(s->specdata[0]);
-    for (j = 1; j < s->fft_size -1 ; j++) {
-      compspec->data[i][j] = REAL(s->specdata[j]);
-      compspec->data[i][compspec->length - j] = IMAG(s->specdata[j]);
-    }
-    compspec->data[i][s->fft_size-1] = REAL(s->specdata[s->fft_size-1]);
+  compspec->data[0] = REAL(s->specdata[0]);
+  for (j = 1; j < s->fft_size -1 ; j++) {
+    compspec->data[j] = REAL(s->specdata[j]);
+    compspec->data[compspec->length - j] = IMAG(s->specdata[j]);
+  }
+  compspec->data[s->fft_size-1] = REAL(s->specdata[s->fft_size-1]);
 #else
-    for (j = 0; j < s->fft_size; j++) {
-      compspec->data[i][j] = s->specdata[j];
-    }
-#endif
+  for (j = 0; j < s->fft_size; j++) {
+    compspec->data[j] = s->specdata[j];
   }
+#endif
 }
 
 void aubio_fft_rdo_complex(aubio_fft_t * s, fvec_t * compspec, fvec_t * output) {
-  uint_t i, j;
+  uint_t j;
   const smpl_t renorm = 1./(smpl_t)s->winsize;
-  for (i = 0; i < compspec->channels; i++) {
 #ifdef HAVE_COMPLEX_H
-    s->specdata[0] = compspec->data[i][0];
-    for (j=1; j < s->fft_size - 1; j++) {
-      s->specdata[j] = compspec->data[i][j] + 
-        I * compspec->data[i][compspec->length - j];
-    }
-    s->specdata[s->fft_size - 1] = compspec->data[i][s->fft_size - 1];
+  s->specdata[0] = compspec->data[0];
+  for (j=1; j < s->fft_size - 1; j++) {
+    s->specdata[j] = compspec->data[j] + 
+      I * compspec->data[compspec->length - j];
+  }
+  s->specdata[s->fft_size - 1] = compspec->data[s->fft_size - 1];
 #else
-    for (j=0; j < s->fft_size; j++) {
-      s->specdata[j] = compspec->data[i][j];
-    }
+  for (j=0; j < s->fft_size; j++) {
+    s->specdata[j] = compspec->data[j];
+  }
 #endif
-    fftw_execute(s->pbw);
-    for (j = 0; j < output->length; j++) {
-      output->data[i][j] = s->out[j]*renorm;
-    }
+  fftw_execute(s->pbw);
+  for (j = 0; j < output->length; j++) {
+    output->data[j] = s->out[j]*renorm;
   }
 }
 
@@ -190,54 +184,46 @@
 }
 
 void aubio_fft_get_phas(fvec_t * compspec, cvec_t * spectrum) {
-  uint_t i, j;
-  for (i = 0; i < spectrum->channels; i++) {
-    if (compspec->data[i][0] < 0) {
-      spectrum->phas[i][0] = PI;
-    } else {
-      spectrum->phas[i][0] = 0.;
-    }
-    for (j=1; j < spectrum->length - 1; j++) {
-      spectrum->phas[i][j] = ATAN2(compspec->data[i][compspec->length-j],
-          compspec->data[i][j]);
-    }
-    if (compspec->data[i][compspec->length/2] < 0) {
-      spectrum->phas[i][spectrum->length - 1] = PI;
-    } else {
-      spectrum->phas[i][spectrum->length - 1] = 0.;
-    }
+  uint_t j;
+  if (compspec->data[0] < 0) {
+    spectrum->phas[0] = PI;
+  } else {
+    spectrum->phas[0] = 0.;
   }
+  for (j=1; j < spectrum->length - 1; j++) {
+    spectrum->phas[j] = ATAN2(compspec->data[compspec->length-j],
+        compspec->data[j]);
+  }
+  if (compspec->data[compspec->length/2] < 0) {
+    spectrum->phas[spectrum->length - 1] = PI;
+  } else {
+    spectrum->phas[spectrum->length - 1] = 0.;
+  }
 }
 
 void aubio_fft_get_norm(fvec_t * compspec, cvec_t * spectrum) {
-  uint_t i, j = 0;
-  for (i = 0; i < spectrum->channels; i++) {
-    spectrum->norm[i][0] = ABS(compspec->data[i][0]);
-    for (j=1; j < spectrum->length - 1; j++) {
-      spectrum->norm[i][j] = SQRT(SQR(compspec->data[i][j]) 
-          + SQR(compspec->data[i][compspec->length - j]) );
-    }
-    spectrum->norm[i][spectrum->length-1] = 
-      ABS(compspec->data[i][compspec->length/2]);
+  uint_t j = 0;
+  spectrum->norm[0] = ABS(compspec->data[0]);
+  for (j=1; j < spectrum->length - 1; j++) {
+    spectrum->norm[j] = SQRT(SQR(compspec->data[j]) 
+        + SQR(compspec->data[compspec->length - j]) );
   }
+  spectrum->norm[spectrum->length-1] = 
+    ABS(compspec->data[compspec->length/2]);
 }
 
 void aubio_fft_get_imag(cvec_t * spectrum, fvec_t * compspec) {
-  uint_t i, j;
-  for (i = 0; i < compspec->channels; i++) {
-    for (j = 1; j < ( compspec->length + 1 ) / 2 /*- 1 + 1*/; j++) {
-      compspec->data[i][compspec->length - j] =
-        spectrum->norm[i][j]*SIN(spectrum->phas[i][j]);
-    }
+  uint_t j;
+  for (j = 1; j < ( compspec->length + 1 ) / 2 /*- 1 + 1*/; j++) {
+    compspec->data[compspec->length - j] =
+      spectrum->norm[j]*SIN(spectrum->phas[j]);
   }
 }
 
 void aubio_fft_get_real(cvec_t * spectrum, fvec_t * compspec) {
-  uint_t i, j;
-  for (i = 0; i < compspec->channels; i++) {
-    for (j = 0; j < compspec->length / 2 + 1; j++) {
-      compspec->data[i][j] = 
-        spectrum->norm[i][j]*COS(spectrum->phas[i][j]);
-    }
+  uint_t j;
+  for (j = 0; j < compspec->length / 2 + 1; j++) {
+    compspec->data[j] = 
+      spectrum->norm[j]*COS(spectrum->phas[j]);
   }
 }
--- a/src/spectral/fft.h
+++ b/src/spectral/fft.h
@@ -44,10 +44,9 @@
 /** create new FFT computation object
 
   \param size length of the FFT
-  \param channels number of channels
 
 */
-aubio_fft_t * new_aubio_fft(uint_t size, uint_t channels);
+aubio_fft_t * new_aubio_fft (uint_t size);
 /** delete FFT object 
 
   \param s fft object as returned by new_aubio_fft
--- a/src/spectral/filterbank.c
+++ b/src/spectral/filterbank.c
@@ -21,6 +21,7 @@
 
 #include "aubio_priv.h"
 #include "fvec.h"
+#include "fmat.h"
 #include "cvec.h"
 #include "spectral/filterbank.h"
 #include "mathutils.h"
@@ -30,7 +31,7 @@
 {
   uint_t win_s;
   uint_t n_filters;
-  fvec_t *filters;
+  fmat_t *filters;
 };
 
 aubio_filterbank_t *
@@ -41,8 +42,8 @@
   fb->win_s = win_s;
   fb->n_filters = n_filters;
 
-  /* allocate filter tables, an fvec of length win_s and of filter_cnt channel */
-  fb->filters = new_fvec (win_s / 2 + 1, n_filters);
+  /* allocate filter tables, a matrix of length win_s and of height n_filters */
+  fb->filters = new_fmat (win_s / 2 + 1, n_filters);
 
   return fb;
 }
@@ -50,7 +51,7 @@
 void
 del_aubio_filterbank (aubio_filterbank_t * fb)
 {
-  del_fvec (fb->filters);
+  del_fmat (fb->filters);
   AUBIO_FREE (fb);
 }
 
@@ -57,10 +58,9 @@
 void
 aubio_filterbank_do (aubio_filterbank_t * f, cvec_t * in, fvec_t * out)
 {
-  uint_t i, j, fn;
+  uint_t j, fn;
 
   /* apply filter to all input channel, provided out has enough channels */
-  uint_t max_channels = MIN (in->channels, out->channels);
   uint_t max_filters = MIN (f->n_filters, out->length);
   uint_t max_length = MIN (in->length, f->filters->length);
 
@@ -67,16 +67,12 @@
   /* reset all values in output vector */
   fvec_zeros (out);
 
-  /* apply filters on all channels */
-  for (i = 0; i < max_channels; i++) {
+  /* for each filter */
+  for (fn = 0; fn < max_filters; fn++) {
 
-    /* for each filter */
-    for (fn = 0; fn < max_filters; fn++) {
-
-      /* for each sample */
-      for (j = 0; j < max_length; j++) {
-        out->data[i][fn] += in->norm[i][j] * f->filters->data[fn][j];
-      }
+    /* for each sample */
+    for (j = 0; j < max_length; j++) {
+      out->data[fn] += in->norm[j] * f->filters->data[fn][j];
     }
   }
 
@@ -83,7 +79,7 @@
   return;
 }
 
-fvec_t *
+fmat_t *
 aubio_filterbank_get_coeffs (aubio_filterbank_t * f)
 {
   return f->filters;
@@ -90,8 +86,8 @@
 }
 
 uint_t
-aubio_filterbank_set_coeffs (aubio_filterbank_t * f, fvec_t * filters)
+aubio_filterbank_set_coeffs (aubio_filterbank_t * f, fmat_t * filter_coeffs)
 {
-  fvec_copy(filters, f->filters);
+  fmat_copy(filter_coeffs, f->filters);
   return 0;
 }
--- a/src/spectral/filterbank.h
+++ b/src/spectral/filterbank.h
@@ -62,12 +62,12 @@
 */
 void aubio_filterbank_do (aubio_filterbank_t * fb, cvec_t * in, fvec_t * out);
 
-/** return a pointer to the fvec object containing all filter coefficients 
+/** return a pointer to the matrix object containing all filter coefficients 
 
   \param f filterbank object to get coefficients from
 
  */
-fvec_t *aubio_filterbank_get_coeffs (aubio_filterbank_t * f);
+fmat_t *aubio_filterbank_get_coeffs (aubio_filterbank_t * f);
 
 /** copy filter coefficients to the filterbank
 
@@ -75,7 +75,7 @@
   \param filters filter bank coefficients to copy from
 
  */
-uint_t aubio_filterbank_set_coeffs (aubio_filterbank_t * f, fvec_t * filters);
+uint_t aubio_filterbank_set_coeffs (aubio_filterbank_t * f, fmat_t * filters);
 
 #ifdef __cplusplus
 }
--- a/src/spectral/filterbank_mel.c
+++ b/src/spectral/filterbank_mel.c
@@ -20,6 +20,7 @@
 */
 
 #include "aubio_priv.h"
+#include "fmat.h"
 #include "fvec.h"
 #include "cvec.h"
 #include "spectral/filterbank.h"
@@ -30,8 +31,8 @@
     fvec_t * freqs, smpl_t samplerate)
 {
 
-  fvec_t *filters = aubio_filterbank_get_coeffs (fb);
-  uint_t n_filters = filters->channels, win_s = filters->length;
+  fmat_t *filters = aubio_filterbank_get_coeffs (fb);
+  uint_t n_filters = filters->height, win_s = filters->length;
 
   uint_t fn;                    /* filter counter */
   uint_t bin;                   /* bin counter */
@@ -48,52 +49,52 @@
         n_filters, freqs->length - 2);
   }
 
-  if (freqs->data[0][freqs->length - 1] > samplerate / 2) {
+  if (freqs->data[freqs->length - 1] > samplerate / 2) {
     AUBIO_WRN ("Nyquist frequency is %fHz, but highest frequency band ends at \
-%fHz\n", samplerate / 2, freqs->data[0][freqs->length - 1]);
+%fHz\n", samplerate / 2, freqs->data[freqs->length - 1]);
   }
 
   /* convenience reference to lower/center/upper frequency for each triangle */
-  fvec_t *lower_freqs = new_fvec (n_filters, 1);
-  fvec_t *upper_freqs = new_fvec (n_filters, 1);
-  fvec_t *center_freqs = new_fvec (n_filters, 1);
+  fvec_t *lower_freqs = new_fvec (n_filters);
+  fvec_t *upper_freqs = new_fvec (n_filters);
+  fvec_t *center_freqs = new_fvec (n_filters);
 
   /* height of each triangle */
-  fvec_t *triangle_heights = new_fvec (n_filters, 1);
+  fvec_t *triangle_heights = new_fvec (n_filters);
 
   /* lookup table of each bin frequency in hz */
-  fvec_t *fft_freqs = new_fvec (win_s, 1);
+  fvec_t *fft_freqs = new_fvec (win_s);
 
   /* fill up the lower/center/upper */
   for (fn = 0; fn < n_filters; fn++) {
-    lower_freqs->data[0][fn] = freqs->data[0][fn];
-    center_freqs->data[0][fn] = freqs->data[0][fn + 1];
-    upper_freqs->data[0][fn] = freqs->data[0][fn + 2];
+    lower_freqs->data[fn] = freqs->data[fn];
+    center_freqs->data[fn] = freqs->data[fn + 1];
+    upper_freqs->data[fn] = freqs->data[fn + 2];
   }
 
   /* compute triangle heights so that each triangle has unit area */
   for (fn = 0; fn < n_filters; fn++) {
-    triangle_heights->data[0][fn] =
-        2. / (upper_freqs->data[0][fn] - lower_freqs->data[0][fn]);
+    triangle_heights->data[fn] =
+        2. / (upper_freqs->data[fn] - lower_freqs->data[fn]);
   }
 
   /* fill fft_freqs lookup table, which assigns the frequency in hz to each bin */
   for (bin = 0; bin < win_s; bin++) {
-    fft_freqs->data[0][bin] =
+    fft_freqs->data[bin] =
         aubio_bintofreq (bin, samplerate, (win_s - 1) * 2);
   }
 
   /* zeroing of all filters */
-  fvec_zeros (filters);
+  fmat_zeros (filters);
 
-  if (fft_freqs->data[0][1] >= lower_freqs->data[0][0]) {
+  if (fft_freqs->data[1] >= lower_freqs->data[0]) {
     /* - 1 to make sure we don't miss the smallest power of two */
     uint_t min_win_s =
-        (uint_t) FLOOR (samplerate / lower_freqs->data[0][0]) - 1;
+        (uint_t) FLOOR (samplerate / lower_freqs->data[0]) - 1;
     AUBIO_WRN ("Lowest frequency bin (%.2fHz) is higher than lowest frequency \
 band (%.2f-%.2fHz). Consider increasing the window size from %d to %d.\n",
-        fft_freqs->data[0][1], lower_freqs->data[0][0],
-        upper_freqs->data[0][0], (win_s - 1) * 2,
+        fft_freqs->data[1], lower_freqs->data[0],
+        upper_freqs->data[0], (win_s - 1) * 2,
         aubio_next_power_of_two (min_win_s));
   }
 
@@ -102,8 +103,8 @@
 
     /* skip first elements */
     for (bin = 0; bin < win_s - 1; bin++) {
-      if (fft_freqs->data[0][bin] <= lower_freqs->data[0][fn] &&
-          fft_freqs->data[0][bin + 1] > lower_freqs->data[0][fn]) {
+      if (fft_freqs->data[bin] <= lower_freqs->data[fn] &&
+          fft_freqs->data[bin + 1] > lower_freqs->data[fn]) {
         bin++;
         break;
       }
@@ -111,15 +112,15 @@
 
     /* compute positive slope step size */
     smpl_t riseInc =
-        triangle_heights->data[0][fn] /
-        (center_freqs->data[0][fn] - lower_freqs->data[0][fn]);
+        triangle_heights->data[fn] /
+        (center_freqs->data[fn] - lower_freqs->data[fn]);
 
     /* compute coefficients in positive slope */
     for (; bin < win_s - 1; bin++) {
       filters->data[fn][bin] =
-          (fft_freqs->data[0][bin] - lower_freqs->data[0][fn]) * riseInc;
+          (fft_freqs->data[bin] - lower_freqs->data[fn]) * riseInc;
 
-      if (fft_freqs->data[0][bin + 1] >= center_freqs->data[0][fn]) {
+      if (fft_freqs->data[bin + 1] >= center_freqs->data[fn]) {
         bin++;
         break;
       }
@@ -127,19 +128,19 @@
 
     /* compute negative slope step size */
     smpl_t downInc =
-        triangle_heights->data[0][fn] /
-        (upper_freqs->data[0][fn] - center_freqs->data[0][fn]);
+        triangle_heights->data[fn] /
+        (upper_freqs->data[fn] - center_freqs->data[fn]);
 
     /* compute coefficents in negative slope */
     for (; bin < win_s - 1; bin++) {
       filters->data[fn][bin] +=
-          (upper_freqs->data[0][fn] - fft_freqs->data[0][bin]) * downInc;
+          (upper_freqs->data[fn] - fft_freqs->data[bin]) * downInc;
 
       if (filters->data[fn][bin] < 0.) {
         filters->data[fn][bin] = 0.;
       }
 
-      if (fft_freqs->data[0][bin + 1] >= upper_freqs->data[0][fn])
+      if (fft_freqs->data[bin + 1] >= upper_freqs->data[fn])
         break;
     }
     /* nothing else to do */
@@ -175,17 +176,17 @@
   uint_t fn;                    /* filter counter */
 
   /* buffers to compute filter frequencies */
-  fvec_t *freqs = new_fvec (n_filters + 2, 1);
+  fvec_t *freqs = new_fvec (n_filters + 2);
 
   /* first step: fill all the linear filter frequencies */
   for (fn = 0; fn < linearFilters; fn++) {
-    freqs->data[0][fn] = lowestFrequency + fn * linearSpacing;
+    freqs->data[fn] = lowestFrequency + fn * linearSpacing;
   }
-  smpl_t lastlinearCF = freqs->data[0][fn - 1];
+  smpl_t lastlinearCF = freqs->data[fn - 1];
 
   /* second step: fill all the log filter frequencies */
   for (fn = 0; fn < logFilters + 2; fn++) {
-    freqs->data[0][fn + linearFilters] =
+    freqs->data[fn + linearFilters] =
         lastlinearCF * (POW (logSpacing, fn + 1));
   }
 
--- a/src/spectral/mfcc.c
+++ b/src/spectral/mfcc.c
@@ -21,6 +21,7 @@
 
 #include "aubio_priv.h"
 #include "fvec.h"
+#include "fmat.h"
 #include "cvec.h"
 #include "mathutils.h"
 #include "vecutils.h"
@@ -39,7 +40,7 @@
   uint_t n_coefs;           /** number of coefficients (<= n_filters/2 +1) */
   aubio_filterbank_t *fb;   /** filter bank */
   fvec_t *in_dct;           /** input buffer for dct * [fb->n_filters] */
-  fvec_t *dct_coeffs;       /** DCT transform n_filters * n_coeffs */
+  fmat_t *dct_coeffs;       /** DCT transform n_filters * n_coeffs */
 };
 
 
@@ -63,9 +64,9 @@
   aubio_filterbank_set_mel_coeffs_slaney (mfcc->fb, samplerate);
 
   /* allocating buffers */
-  mfcc->in_dct = new_fvec (n_filters, 1);
+  mfcc->in_dct = new_fvec (n_filters);
 
-  mfcc->dct_coeffs = new_fvec (n_coefs, n_filters);
+  mfcc->dct_coeffs = new_fmat (n_coefs, n_filters);
 
   /* compute DCT transform dct_coeffs[i][j] as
      cos ( j * (i+.5) * PI / n_filters ) */
@@ -99,7 +100,7 @@
 void
 aubio_mfcc_do (aubio_mfcc_t * mf, cvec_t * in, fvec_t * out)
 {
-  uint_t i, j, k;
+  uint_t j, k;
 
   /* compute filterbank */
   aubio_filterbank_do (mf->fb, in, mf->in_dct);
@@ -114,12 +115,10 @@
   fvec_zeros(out);
 
   /* compute discrete cosine transform */
-  for (i = 0; i < out->channels; i++) {
-    for (j = 0; j < mf->n_filters; j++) {
-      for (k = 0; k < mf->n_coefs; k++) {
-        out->data[i][k] += mf->in_dct->data[i][j]
-            * mf->dct_coeffs->data[j][k];
-      }
+  for (j = 0; j < mf->n_filters; j++) {
+    for (k = 0; k < mf->n_coefs; k++) {
+      out->data[k] += mf->in_dct->data[j]
+          * mf->dct_coeffs->data[j][k];
     }
   }
 
--- a/src/spectral/phasevoc.c
+++ b/src/spectral/phasevoc.c
@@ -29,7 +29,6 @@
 struct _aubio_pvoc_t {
   uint_t win_s;       /** grain length */
   uint_t hop_s;       /** overlap step */
-  uint_t channels;    /** number of channels */
   aubio_fft_t * fft;  /** fft object */
   fvec_t * synth;     /** cur output grain [win_s] */
   fvec_t * synthold;  /** last input frame [win_s-hop_s] */
@@ -48,12 +47,9 @@
     smpl_t * synthnew, uint_t win_s, uint_t hop_s);
 
 void aubio_pvoc_do(aubio_pvoc_t *pv, fvec_t * datanew, cvec_t *fftgrain) {
-  uint_t i;
-  for (i=0; i<pv->channels; i++) {
-    /* slide  */
-    aubio_pvoc_swapbuffers(pv->data->data[i],pv->dataold->data[i],
-        datanew->data[i],pv->win_s,pv->hop_s);
-  }
+  /* slide  */
+  aubio_pvoc_swapbuffers(pv->data->data,pv->dataold->data,
+      datanew->data,pv->win_s,pv->hop_s);
   /* windowing */
   fvec_weight(pv->data, pv->w);
   /* shift */
@@ -63,18 +59,15 @@
 }
 
 void aubio_pvoc_rdo(aubio_pvoc_t *pv,cvec_t * fftgrain, fvec_t * synthnew) {
-  uint_t i;
   /* calculate rfft */
   aubio_fft_rdo(pv->fft,fftgrain,pv->synth);
   /* unshift */
   fvec_shift(pv->synth);
-  for (i=0; i<pv->channels; i++) {
-    aubio_pvoc_addsynth(pv->synth->data[i],pv->synthold->data[i],
-        synthnew->data[i],pv->win_s,pv->hop_s);
-  }
+  aubio_pvoc_addsynth(pv->synth->data,pv->synthold->data,
+      synthnew->data,pv->win_s,pv->hop_s);
 }
 
-aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s, uint_t channels) {
+aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s) {
   aubio_pvoc_t * pv = AUBIO_NEW(aubio_pvoc_t);
 
   /* if (win_s < 2*hop_s) {
@@ -87,18 +80,17 @@
     hop_s = win_s / 2;
   }
 
-  pv->fft      = new_aubio_fft(win_s,channels);
+  pv->fft      = new_aubio_fft (win_s);
 
   /* remember old */
-  pv->data     = new_fvec (win_s, channels);
-  pv->synth    = new_fvec (win_s, channels);
+  pv->data     = new_fvec (win_s);
+  pv->synth    = new_fvec (win_s);
 
   /* new input output */
-  pv->dataold  = new_fvec  (win_s-hop_s, channels);
-  pv->synthold = new_fvec (win_s-hop_s, channels);
+  pv->dataold  = new_fvec  (win_s-hop_s);
+  pv->synthold = new_fvec (win_s-hop_s);
   pv->w        = new_aubio_window ("hanningz", win_s);
 
-  pv->channels = channels;
   pv->hop_s    = hop_s;
   pv->win_s    = win_s;
 
--- a/src/spectral/phasevoc.h
+++ b/src/spectral/phasevoc.h
@@ -25,7 +25,7 @@
   This object implements a phase vocoder. The spectral frames are computed
   using a HanningZ window and a swapped version of the signal to simplify the
   phase relationships across frames. The window sizes and overlap are specified
-  at creation time. Multiple channels are fully supported.
+  at creation time.
 
 */
 
@@ -43,10 +43,9 @@
 
   \param win_s size of analysis buffer (and length the FFT transform)
   \param hop_s step size between two consecutive analysis
-  \param channels number of channels
 
 */
-aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s, uint_t channels);
+aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s);
 /** delete phase vocoder object
 
   \param pv phase vocoder object as returned by new_aubio_pvoc
@@ -56,7 +55,7 @@
 
 /** compute spectral frame
   
-  This function accepts an input vector of size [channels]x[hop_s]. The
+  This function accepts an input vector of size [hop_s]. The
   analysis buffer is rotated and filled with the new data. After windowing of
   this signal window, the Fourier transform is computed and returned in
   fftgrain as two vectors, magnitude and phase.
@@ -70,7 +69,7 @@
 /** compute signal from spectral frame
 
   This function takes an input spectral frame fftgrain of size
-  [channels]x[buf_s] and computes its inverse Fourier transform. Overlap-add
+  [buf_s] and computes its inverse Fourier transform. Overlap-add
   synthesis is then computed using the previously synthetised frames, and the
   output stored in out.
   
@@ -93,12 +92,6 @@
 
 */
 uint_t aubio_pvoc_get_hop(aubio_pvoc_t* pv);
-/** get channel number
- 
-  \param pv phase vocoder to get the number of channels from
-
-*/
-uint_t aubio_pvoc_get_channels(aubio_pvoc_t* pv);
 
 #ifdef __cplusplus
 }
--- a/src/spectral/specdesc.c
+++ b/src/spectral/specdesc.c
@@ -88,12 +88,10 @@
 /* Energy based onset detection function */
 void aubio_specdesc_energy  (aubio_specdesc_t *o UNUSED,
     cvec_t * fftgrain, fvec_t * onset) {
-  uint_t i,j;
-  for (i=0;i<fftgrain->channels;i++) {
-    onset->data[i][0] = 0.;
-    for (j=0;j<fftgrain->length;j++) {
-      onset->data[i][0] += SQR(fftgrain->norm[i][j]);
-    }
+  uint_t j;
+  onset->data[0] = 0.;
+  for (j=0;j<fftgrain->length;j++) {
+    onset->data[0] += SQR(fftgrain->norm[j]);
   }
 }
 
@@ -100,12 +98,10 @@
 /* High Frequency Content onset detection function */
 void aubio_specdesc_hfc(aubio_specdesc_t *o UNUSED,
     cvec_t * fftgrain, fvec_t * onset){
-  uint_t i,j;
-  for (i=0;i<fftgrain->channels;i++) {
-    onset->data[i][0] = 0.;
-    for (j=0;j<fftgrain->length;j++) {
-      onset->data[i][0] += (j+1)*fftgrain->norm[i][j];
-    }
+  uint_t j;
+  onset->data[0] = 0.;
+  for (j=0;j<fftgrain->length;j++) {
+    onset->data[0] += (j+1)*fftgrain->norm[j];
   }
 }
 
@@ -112,25 +108,23 @@
 
 /* Complex Domain Method onset detection function */
 void aubio_specdesc_complex (aubio_specdesc_t *o, cvec_t * fftgrain, fvec_t * onset) {
-  uint_t i, j;
+  uint_t j;
   uint_t nbins = fftgrain->length;
-  for (i=0;i<fftgrain->channels; i++)  {
-    onset->data[i][0] = 0.;
-    for (j=0;j<nbins; j++)  {
-      // compute the predicted phase
-      o->dev1->data[i][j] = 2. * o->theta1->data[i][j] - o->theta2->data[i][j];
-      // compute the euclidean distance in the complex domain
-      // sqrt ( r_1^2 + r_2^2 - 2 * r_1 * r_2 * \cos ( \phi_1 - \phi_2 ) )
-      onset->data[i][0] +=
-        SQRT (ABS (SQR (o->oldmag->data[i][j]) + SQR (fftgrain->norm[i][j])
-              - 2. * o->oldmag->data[i][j] * fftgrain->norm[i][j]
-              * COS (o->dev1->data[i][j] - fftgrain->phas[i][j])));
-      /* swap old phase data (need to remember 2 frames behind)*/
-      o->theta2->data[i][j] = o->theta1->data[i][j];
-      o->theta1->data[i][j] = fftgrain->phas[i][j];
-      /* swap old magnitude data (1 frame is enough) */
-      o->oldmag->data[i][j] = fftgrain->norm[i][j];
-    }
+  onset->data[0] = 0.;
+  for (j=0;j<nbins; j++)  {
+    // compute the predicted phase
+    o->dev1->data[j] = 2. * o->theta1->data[j] - o->theta2->data[j];
+    // compute the euclidean distance in the complex domain
+    // sqrt ( r_1^2 + r_2^2 - 2 * r_1 * r_2 * \cos ( \phi_1 - \phi_2 ) )
+    onset->data[0] +=
+      SQRT (ABS (SQR (o->oldmag->data[j]) + SQR (fftgrain->norm[j])
+            - 2. * o->oldmag->data[j] * fftgrain->norm[j]
+            * COS (o->dev1->data[j] - fftgrain->phas[j])));
+    /* swap old phase data (need to remember 2 frames behind)*/
+    o->theta2->data[j] = o->theta1->data[j];
+    o->theta1->data[j] = fftgrain->phas[j];
+    /* swap old magnitude data (1 frame is enough) */
+    o->oldmag->data[j] = fftgrain->norm[j];
   }
 }
 
@@ -138,51 +132,48 @@
 /* Phase Based Method onset detection function */
 void aubio_specdesc_phase(aubio_specdesc_t *o, 
     cvec_t * fftgrain, fvec_t * onset){
-  uint_t i, j;
+  uint_t j;
   uint_t nbins = fftgrain->length;
-  for (i=0;i<fftgrain->channels; i++)  {
-    onset->data[i][0] = 0.0;
-    o->dev1->data[i][0]=0.;
-    for ( j=0;j<nbins; j++ )  {
-      o->dev1->data[i][j] = 
-        aubio_unwrap2pi(
-            fftgrain->phas[i][j]
-            -2.0*o->theta1->data[i][j]
-            +o->theta2->data[i][j]);
-      if ( o->threshold < fftgrain->norm[i][j] )
-        o->dev1->data[i][j] = ABS(o->dev1->data[i][j]);
-      else 
-        o->dev1->data[i][j] = 0.0;
-      /* keep a track of the past frames */
-      o->theta2->data[i][j] = o->theta1->data[i][j];
-      o->theta1->data[i][j] = fftgrain->phas[i][j];
-    }
-    /* apply o->histogram */
-    aubio_hist_dyn_notnull(o->histog,o->dev1);
-    /* weight it */
-    aubio_hist_weight(o->histog);
-    /* its mean is the result */
-    onset->data[i][0] = aubio_hist_mean(o->histog);  
-    //onset->data[i][0] = fvec_mean(o->dev1);
+  onset->data[0] = 0.0;
+  o->dev1->data[0]=0.;
+  for ( j=0;j<nbins; j++ )  {
+    o->dev1->data[j] = 
+      aubio_unwrap2pi(
+          fftgrain->phas[j]
+          -2.0*o->theta1->data[j]
+          +o->theta2->data[j]);
+    if ( o->threshold < fftgrain->norm[j] )
+      o->dev1->data[j] = ABS(o->dev1->data[j]);
+    else 
+      o->dev1->data[j] = 0.0;
+    /* keep a track of the past frames */
+    o->theta2->data[j] = o->theta1->data[j];
+    o->theta1->data[j] = fftgrain->phas[j];
   }
+  /* apply o->histogram */
+  aubio_hist_dyn_notnull(o->histog,o->dev1);
+  /* weight it */
+  aubio_hist_weight(o->histog);
+  /* its mean is the result */
+  onset->data[0] = aubio_hist_mean(o->histog);  
+  //onset->data[0] = fvec_mean(o->dev1);
 }
 
 /* Spectral difference method onset detection function */
 void aubio_specdesc_specdiff(aubio_specdesc_t *o,
     cvec_t * fftgrain, fvec_t * onset){
-  uint_t i, j;
+  uint_t j;
   uint_t nbins = fftgrain->length;
-  for (i=0;i<fftgrain->channels; i++)  {
-    onset->data[i][0] = 0.0;
+    onset->data[0] = 0.0;
     for (j=0;j<nbins; j++)  {
-      o->dev1->data[i][j] = SQRT(
-          ABS(SQR( fftgrain->norm[i][j])
-            - SQR(o->oldmag->data[i][j])));
-      if (o->threshold < fftgrain->norm[i][j] )
-        o->dev1->data[i][j] = ABS(o->dev1->data[i][j]);
+      o->dev1->data[j] = SQRT(
+          ABS(SQR( fftgrain->norm[j])
+            - SQR(o->oldmag->data[j])));
+      if (o->threshold < fftgrain->norm[j] )
+        o->dev1->data[j] = ABS(o->dev1->data[j]);
       else 
-        o->dev1->data[i][j] = 0.0;
-      o->oldmag->data[i][j] = fftgrain->norm[i][j];
+        o->dev1->data[j] = 0.0;
+      o->oldmag->data[j] = fftgrain->norm[j];
     }
 
     /* apply o->histogram (act somewhat as a low pass on the
@@ -191,9 +182,7 @@
     /* weight it */
     aubio_hist_weight(o->histog);
     /* its mean is the result */
-    onset->data[i][0] = aubio_hist_mean(o->histog);  
-
-  }
+    onset->data[0] = aubio_hist_mean(o->histog);  
 }
 
 /* Kullback Liebler onset detection function
@@ -200,16 +189,14 @@
  * note we use ln(1+Xn/(Xn-1+0.0001)) to avoid 
  * negative (1.+) and infinite values (+1.e-10) */
 void aubio_specdesc_kl(aubio_specdesc_t *o, cvec_t * fftgrain, fvec_t * onset){
-  uint_t i,j;
-  for (i=0;i<fftgrain->channels;i++) {
-    onset->data[i][0] = 0.;
+  uint_t j;
+    onset->data[0] = 0.;
     for (j=0;j<fftgrain->length;j++) {
-      onset->data[i][0] += fftgrain->norm[i][j]
-        *LOG(1.+fftgrain->norm[i][j]/(o->oldmag->data[i][j]+1.e-10));
-      o->oldmag->data[i][j] = fftgrain->norm[i][j];
+      onset->data[0] += fftgrain->norm[j]
+        *LOG(1.+fftgrain->norm[j]/(o->oldmag->data[j]+1.e-10));
+      o->oldmag->data[j] = fftgrain->norm[j];
     }
-    if (isnan(onset->data[i][0])) onset->data[i][0] = 0.;
-  }
+    if (isnan(onset->data[0])) onset->data[0] = 0.;
 }
 
 /* Modified Kullback Liebler onset detection function
@@ -216,27 +203,23 @@
  * note we use ln(1+Xn/(Xn-1+0.0001)) to avoid 
  * negative (1.+) and infinite values (+1.e-10) */
 void aubio_specdesc_mkl(aubio_specdesc_t *o, cvec_t * fftgrain, fvec_t * onset){
-  uint_t i,j;
-  for (i=0;i<fftgrain->channels;i++) {
-    onset->data[i][0] = 0.;
+  uint_t j;
+    onset->data[0] = 0.;
     for (j=0;j<fftgrain->length;j++) {
-      onset->data[i][0] += LOG(1.+fftgrain->norm[i][j]/(o->oldmag->data[i][j]+1.e-10));
-      o->oldmag->data[i][j] = fftgrain->norm[i][j];
+      onset->data[0] += LOG(1.+fftgrain->norm[j]/(o->oldmag->data[j]+1.e-10));
+      o->oldmag->data[j] = fftgrain->norm[j];
     }
-    if (isnan(onset->data[i][0])) onset->data[i][0] = 0.;
-  }
+    if (isnan(onset->data[0])) onset->data[0] = 0.;
 }
 
 /* Spectral flux */
 void aubio_specdesc_specflux(aubio_specdesc_t *o, cvec_t * fftgrain, fvec_t * onset){ 
-  uint_t i, j;
-  for (i=0;i<fftgrain->channels;i++) {
-    onset->data[i][0] = 0.;
-    for (j=0;j<fftgrain->length;j++) {
-      if (fftgrain->norm[i][j] > o->oldmag->data[i][j])
-        onset->data[i][0] += fftgrain->norm[i][j] - o->oldmag->data[i][j];
-      o->oldmag->data[i][j] = fftgrain->norm[i][j];
-    }
+  uint_t j;
+  onset->data[0] = 0.;
+  for (j=0;j<fftgrain->length;j++) {
+    if (fftgrain->norm[j] > o->oldmag->data[j])
+      onset->data[0] += fftgrain->norm[j] - o->oldmag->data[j];
+    o->oldmag->data[j] = fftgrain->norm[j];
   }
 }
 
@@ -251,8 +234,7 @@
  * depending on the choosen type, allocate memory as needed
  */
 aubio_specdesc_t * 
-new_aubio_specdesc (char_t * onset_mode, 
-    uint_t size, uint_t channels){
+new_aubio_specdesc (char_t * onset_mode, uint_t size){
   aubio_specdesc_t * o = AUBIO_NEW(aubio_specdesc_t);
   uint_t rsize = size/2+1;
   aubio_specdesc_type onset_type;
@@ -302,28 +284,28 @@
       break;
       /* the other approaches will need some more memory spaces */
     case aubio_onset_complex:
-      o->oldmag = new_fvec(rsize,channels);
-      o->dev1   = new_fvec(rsize,channels);
-      o->theta1 = new_fvec(rsize,channels);
-      o->theta2 = new_fvec(rsize,channels);
+      o->oldmag = new_fvec(rsize);
+      o->dev1   = new_fvec(rsize);
+      o->theta1 = new_fvec(rsize);
+      o->theta2 = new_fvec(rsize);
       break;
     case aubio_onset_phase:
-      o->dev1   = new_fvec(rsize,channels);
-      o->theta1 = new_fvec(rsize,channels);
-      o->theta2 = new_fvec(rsize,channels);
-      o->histog = new_aubio_hist(0.0, PI, 10, channels);
+      o->dev1   = new_fvec(rsize);
+      o->theta1 = new_fvec(rsize);
+      o->theta2 = new_fvec(rsize);
+      o->histog = new_aubio_hist(0.0, PI, 10);
       o->threshold = 0.1;
       break;
     case aubio_onset_specdiff:
-      o->oldmag = new_fvec(rsize,channels);
-      o->dev1   = new_fvec(rsize,channels);
-      o->histog = new_aubio_hist(0.0, PI, 10, channels);
+      o->oldmag = new_fvec(rsize);
+      o->dev1   = new_fvec(rsize);
+      o->histog = new_aubio_hist(0.0, PI, 10);
       o->threshold = 0.1;
       break;
     case aubio_onset_kl:
     case aubio_onset_mkl:
     case aubio_onset_specflux:
-      o->oldmag = new_fvec(rsize,channels);
+      o->oldmag = new_fvec(rsize);
       break;
     default:
       break;
--- a/src/spectral/specdesc.h
+++ b/src/spectral/specdesc.h
@@ -24,7 +24,7 @@
  
   All of the following spectral description functions take as arguments the FFT
   of a windowed signal (as created with aubio_pvoc). They output one smpl_t per
-  buffer and per channel (stored in a vector of size [channels]x[1]).
+  buffer (stored in a vector of size [1]).
  
   A list of the spectral description methods currently available follows.
 
@@ -167,11 +167,9 @@
 
   \param method spectral description method
   \param buf_size length of the input spectrum frame
-  \param channels number of input channels
 
 */
-aubio_specdesc_t *new_aubio_specdesc (char_t * method, uint_t buf_size,
-    uint_t channels);
+aubio_specdesc_t *new_aubio_specdesc (char_t * method, uint_t buf_size);
 
 /** deletion of a spectral descriptor 
 
--- a/src/spectral/statistics.c
+++ b/src/spectral/statistics.c
@@ -23,32 +23,33 @@
 #include "spectral/specdesc.h"
 
 smpl_t
-cvec_sum_channel (cvec_t * s, uint_t i)
+cvec_sum (cvec_t * s)
 {
   uint_t j;
   smpl_t tmp = 0.0;
-  for (j = 0; j < s->length; j++)
-      tmp += s->norm[i][j];
+  for (j = 0; j < s->length; j++) {
+    tmp += s->norm[j];
+  }
   return tmp;
 }
 
 smpl_t
-cvec_mean_channel (cvec_t * s, uint_t i)
+cvec_mean (cvec_t * s)
 {
-  return cvec_sum_channel(s, i) / (smpl_t) (s->length);
+  return cvec_sum (s) / (smpl_t) (s->length);
 }
 
 smpl_t
-cvec_centroid_channel (cvec_t * spec, uint_t i)
+cvec_centroid (cvec_t * spec)
 {
   smpl_t sum = 0., sc = 0.;
   uint_t j;
-  sum = cvec_sum_channel (spec, i); 
+  sum = cvec_sum (spec); 
   if (sum == 0.) {
     return 0.;
   } else {
     for (j = 0; j < spec->length; j++) {
-      sc += (smpl_t) j *spec->norm[i][j];
+      sc += (smpl_t) j *spec->norm[j];
     }
     return sc / sum;
   }
@@ -55,17 +56,17 @@
 }
 
 smpl_t
-cvec_moment_channel (cvec_t * spec, uint_t i, uint_t order)
+cvec_moment (cvec_t * spec, uint_t order)
 {
   smpl_t sum = 0., centroid = 0., sc = 0.;
   uint_t j;
-  sum = cvec_sum_channel (spec, i); 
+  sum = cvec_sum (spec); 
   if (sum == 0.) {
     return 0.;
   } else {
-    centroid = cvec_centroid_channel (spec, i);
+    centroid = cvec_centroid (spec);
     for (j = 0; j < spec->length; j++) {
-      sc += (smpl_t) POW(j - centroid, order) * spec->norm[i][j];
+      sc += (smpl_t) POW(j - centroid, order) * spec->norm[j];
     }
     return sc / sum;
   }
@@ -75,10 +76,7 @@
 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); 
-  }
+  desc->data[0] = cvec_centroid (spec); 
 }
 
 void
@@ -85,10 +83,7 @@
 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);
-  }
+  desc->data[0] = cvec_moment (spec, 2);
 }
 
 void
@@ -95,15 +90,13 @@
 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);
-    }
+  smpl_t spread;
+  spread = cvec_moment (spec, 2);
+  if (spread == 0) {
+    desc->data[0] = 0.;
+  } else {
+    desc->data[0] = cvec_moment (spec, 3);
+    desc->data[0] /= POW ( SQRT (spread), 3);
   }
 }
 
@@ -111,15 +104,13 @@
 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);
-    }
+  smpl_t spread;
+  spread = cvec_moment (spec, 2);
+  if (spread == 0) {
+    desc->data[0] = 0.;
+  } else {
+    desc->data[0] = cvec_moment (spec, 4);
+    desc->data[0] /= SQR (spread);
   }
 }
 
@@ -127,7 +118,7 @@
 aubio_specdesc_slope (aubio_specdesc_t * o UNUSED, cvec_t * spec,
     fvec_t * desc)
 {
-  uint_t i, j;
+  uint_t j;
   smpl_t norm = 0, sum = 0.; 
   // compute N * sum(j**2) - sum(j)**2
   for (j = 0; j < spec->length; j++) {
@@ -136,20 +127,18 @@
   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;
+  sum = cvec_sum (spec); 
+  desc->data[0] = 0.;
+  if (sum == 0.) {
+    return; 
+  } else {
+    for (j = 0; j < spec->length; j++) {
+      desc->data[0] += j * spec->norm[j]; 
     }
+    desc->data[0] *= spec->length;
+    desc->data[0] -= sum * spec->length * (spec->length - 1) / 2.;
+    desc->data[0] /= norm;
+    desc->data[0] /= sum;
   }
 }
 
@@ -157,19 +146,17 @@
 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;
+  uint_t j; smpl_t sum;
+  sum = cvec_sum (spec); 
+  desc->data[0] = 0;
+  if (sum == 0.) {
+    return;
+  } else {
+    sum -= spec->norm[0];
+    for (j = 1; j < spec->length; j++) {
+      desc->data[0] += (spec->norm[j] - spec->norm[0]) / j;
     }
+    desc->data[0] /= sum;
   }
 }
 
@@ -177,22 +164,20 @@
 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]);
+  uint_t j; smpl_t cumsum, rollsum;
+  cumsum = 0.; rollsum = 0.;
+  for (j = 0; j < spec->length; j++) {
+    cumsum += SQR (spec->norm[j]);
+  }
+  if (cumsum == 0) {
+    desc->data[0] = 0.;
+  } else {
+    cumsum *= 0.95;
+    j = 0;
+    while (rollsum < cumsum) { 
+      rollsum += SQR (spec->norm[j]);
+      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;
-    }
+    desc->data[0] = j;
   }
 }
--- a/src/spectral/tss.c
+++ b/src/spectral/tss.c
@@ -43,54 +43,51 @@
 void aubio_tss_do(aubio_tss_t *o, cvec_t * input, 
     cvec_t * trans, cvec_t * stead)
 {
-  uint_t i,j;
+  uint_t j;
   uint_t test;
   uint_t nbins     = input->length;
-  uint_t channels  = input->channels;
   smpl_t alpha     = o->alpha;
   smpl_t beta      = o->beta;
   smpl_t parm      = o->parm;
-  smpl_t ** dev    = (smpl_t **)o->dev->data;
-  smpl_t ** oft1   = (smpl_t **)o->oft1->data;
-  smpl_t ** oft2   = (smpl_t **)o->oft2->data;
-  smpl_t ** theta1 = (smpl_t **)o->theta1->data;
-  smpl_t ** theta2 = (smpl_t **)o->theta2->data;
+  smpl_t * dev    = (smpl_t *)o->dev->data;
+  smpl_t * oft1   = (smpl_t *)o->oft1->data;
+  smpl_t * oft2   = (smpl_t *)o->oft2->data;
+  smpl_t * theta1 = (smpl_t *)o->theta1->data;
+  smpl_t * theta2 = (smpl_t *)o->theta2->data;
   /* second phase derivative */
-  for (i=0;i<channels; i++){
-    for (j=0;j<nbins; j++){
-      dev[i][j] = aubio_unwrap2pi(input->phas[i][j]
-          -2.0*theta1[i][j]+theta2[i][j]);
-      theta2[i][j] = theta1[i][j];
-      theta1[i][j] = input->phas[i][j];
-    }
+  for (j=0;j<nbins; j++){
+    dev[j] = aubio_unwrap2pi(input->phas[j]
+        -2.0*theta1[j]+theta2[j]);
+    theta2[j] = theta1[j];
+    theta1[j] = input->phas[j];
+  }
 
-    for (j=0;j<nbins; j++){
-      /* transient analysis */
-      test = (ABS(dev[i][j]) > parm*oft1[i][j]);
-      trans->norm[i][j] = input->norm[i][j] * test;
-      trans->phas[i][j] = input->phas[i][j] * test;
-    }
+  for (j=0;j<nbins; j++){
+    /* transient analysis */
+    test = (ABS(dev[j]) > parm*oft1[j]);
+    trans->norm[j] = input->norm[j] * test;
+    trans->phas[j] = input->phas[j] * test;
+  }
 
-    for (j=0;j<nbins; j++){
-      /* steady state analysis */
-      test = (ABS(dev[i][j]) < parm*oft2[i][j]);
-      stead->norm[i][j] = input->norm[i][j] * test;
-      stead->phas[i][j] = input->phas[i][j] * test;
+  for (j=0;j<nbins; j++){
+    /* steady state analysis */
+    test = (ABS(dev[j]) < parm*oft2[j]);
+    stead->norm[j] = input->norm[j] * test;
+    stead->phas[j] = input->phas[j] * test;
 
-      /*increase sstate probability for sines */
-      test = (trans->norm[i][j]==0.);
-      oft1[i][j]  = test;
-      test = (stead->norm[i][j]==0.);
-      oft2[i][j]  = test;
-      test = (trans->norm[i][j]>0.);
-      oft1[i][j] += alpha*test;
-      test = (stead->norm[i][j]>0.);
-      oft2[i][j] += alpha*test;
-      test = (oft1[i][j]>1. && trans->norm[i][j]>0.);
-      oft1[i][j] += beta*test;
-      test = (oft2[i][j]>1. && stead->norm[i][j]>0.);
-      oft2[i][j] += beta*test;
-    }
+    /*increase sstate probability for sines */
+    test = (trans->norm[j]==0.);
+    oft1[j]  = test;
+    test = (stead->norm[j]==0.);
+    oft2[j]  = test;
+    test = (trans->norm[j]>0.);
+    oft1[j] += alpha*test;
+    test = (stead->norm[j]>0.);
+    oft2[j] += alpha*test;
+    test = (oft1[j]>1. && trans->norm[j]>0.);
+    oft1[j] += beta*test;
+    test = (oft2[j]>1. && stead->norm[j]>0.);
+    oft2[j] += beta*test;
   }
 }
 
@@ -100,7 +97,7 @@
   return AUBIO_OK;
 }
 
-aubio_tss_t * new_aubio_tss(uint_t buf_size, uint_t hop_size, uint_t channels)
+aubio_tss_t * new_aubio_tss(uint_t buf_size, uint_t hop_size)
 {
   aubio_tss_t * o = AUBIO_NEW(aubio_tss_t);
   uint_t rsize = buf_size/2+1;
@@ -109,11 +106,11 @@
   o->alpha = 3.;
   o->beta = 4.;
   o->parm = o->threshold*o->thrsfact;
-  o->theta1 = new_fvec(rsize,channels);
-  o->theta2 = new_fvec(rsize,channels);
-  o->oft1 = new_fvec(rsize,channels);
-  o->oft2 = new_fvec(rsize,channels);
-  o->dev = new_fvec(rsize,channels);
+  o->theta1 = new_fvec(rsize);
+  o->theta2 = new_fvec(rsize);
+  o->oft1 = new_fvec(rsize);
+  o->oft2 = new_fvec(rsize);
+  o->dev = new_fvec(rsize);
   return o;
 }
 
--- a/src/spectral/tss.h
+++ b/src/spectral/tss.h
@@ -48,10 +48,9 @@
 
   \param buf_size buffer size
   \param hop_size step size
-  \param channels number of input channels
 
 */
-aubio_tss_t *new_aubio_tss (uint_t buf_size, uint_t hop_size, uint_t channels);
+aubio_tss_t *new_aubio_tss (uint_t buf_size, uint_t hop_size);
 
 /** delete tss object