shithub: aubio

Download patch

ref: f88a3262187e339c5d65f07175fdc875bb4376c5
parent: f8714ee0615e25a50d77668df664535665a46bf7
author: Paul Brossier <piem@altern.org>
date: Fri May 27 20:53:13 EDT 2005

added simplified mfft interface

--- a/src/fft.c
+++ b/src/fft.c
@@ -77,6 +77,7 @@
 
 void del_aubio_fft(aubio_fft_t * s) {
 	aubio_fft_free(s);
+        AUBIO_FREE(s);
 }
 
 void aubio_fft_do(const aubio_fft_t * s, 
@@ -110,3 +111,56 @@
 	for (i=0;i<size;i++) phas[i] = ARGC(spectrum[i]);
 }
 
+
+/* new interface aubio_mfft */
+struct _aubio_mfft_t {
+        aubio_fft_t * fft;      /* fftw interface */
+        fft_data_t ** spec;     /* complex spectral data */
+        uint_t winsize;
+        uint_t channels;
+};
+
+aubio_mfft_t * new_aubio_mfft(uint_t winsize, uint_t channels){
+        uint_t i;
+	aubio_mfft_t * fft = AUBIO_NEW(aubio_mfft_t);
+	fft->winsize       = winsize;
+	fft->channels      = channels;
+	fft->fft           = new_aubio_fft(winsize);
+	fft->spec          = AUBIO_ARRAY(fft_data_t*,channels);
+        for (i=0; i < channels; i++)
+                fft->spec[i] = AUBIO_ARRAY(fft_data_t,winsize);
+        return fft;
+}
+
+/* execute stft */
+void aubio_mfft_do (aubio_mfft_t * fft,fvec_t * in,cvec_t * fftgrain){
+        uint_t i=0;
+        /* execute stft */
+        for (i=0; i < fft->channels; i++) {
+                aubio_fft_do (fft->fft,in->data[i],fft->spec[i],fft->winsize);
+                /* put norm and phase into fftgrain */
+                aubio_fft_getnorm(fftgrain->norm[i], fft->spec[i], fft->winsize/2+1);
+                aubio_fft_getphas(fftgrain->phas[i], fft->spec[i], fft->winsize/2+1);
+        }
+}
+
+/* execute inverse fourier transform */
+void aubio_mfft_rdo(aubio_mfft_t * fft,cvec_t * fftgrain, fvec_t * out){
+        uint_t i=0,j;
+        for (i=0; i < fft->channels; i++) {
+                for (j=0; j<fft->winsize/2+1; j++) {
+                        fft->spec[i][j]  = CEXPC(I*unwrap2pi(fftgrain->phas[i][j]));
+                        fft->spec[i][j] *= fftgrain->norm[i][j];
+                }
+                aubio_fft_rdo(fft->fft,fft->spec[i],out->data[i],fft->winsize);
+        }
+}
+
+void del_aubio_mfft(aubio_mfft_t * fft) {
+        uint_t i;
+        for (i=0; i < fft->channels; i++)
+                AUBIO_FREE(fft->spec[i]);
+        AUBIO_FREE(fft->spec);
+	aubio_fft_free(fft->fft);
+        AUBIO_FREE(fft);        
+}
--- a/src/fft.h
+++ b/src/fft.h
@@ -55,6 +55,14 @@
 /** get phase from spectrum */
 void aubio_fft_getphas(smpl_t * phase, fft_data_t * spectrum, uint_t size);
 
+
+typedef struct _aubio_mfft_t aubio_mfft_t;
+aubio_mfft_t * new_aubio_mfft(uint_t winsize, uint_t channels);
+void aubio_mfft_do (aubio_mfft_t * fft,fvec_t * in,cvec_t * fftgrain);
+void aubio_mfft_rdo(aubio_mfft_t * fft,cvec_t * fftgrain, fvec_t * out);
+void del_aubio_mfft(aubio_mfft_t * fft);
+
+
 #ifdef __cplusplus
 }
 #endif
--- a/src/phasevoc.c
+++ b/src/phasevoc.c
@@ -32,13 +32,11 @@
 	/** number of channels */
 	uint_t channels;
 	/** spectral data */
-	aubio_fft_t * spectrum;
+	aubio_mfft_t * fft;
 	/**cur output grain 		[win_s] */
 	fvec_t * synth;		 
 	/**last input frame 		[win_s-hop_s] */
 	fvec_t * synthold; 
-	/**current spectrum 		[win_s] */
-	fft_data_t ** spec;
 	/**current input grain		[win_s] */
 	fvec_t * data;		 
 	/**last input frame 		[win_s-hop_s] */
@@ -48,10 +46,6 @@
 };
 
 
-/** memory allocation */
-static aubio_pvoc_t * aubio_pvoc_malloc (uint_t win_s, uint_t hop_s, uint_t channels);
-/** object deletion */
-static void aubio_pvoc_free (aubio_pvoc_t *pv);
 /** returns data and dataold slided by hop_s */
 static void aubio_pvoc_swapbuffers(
 		smpl_t * data,
@@ -74,25 +68,20 @@
 				datanew->data[i],pv->win_s,pv->hop_s);
 		/* windowing */
 		for (j=0; j<pv->win_s; j++) pv->data->data[i][j] *= pv->w[j];
-		/* fftshift */
-		vec_shift(pv->data);
-		/* calculate fft */
-		aubio_fft_do(pv->spectrum,pv->data->data[i],pv->spec[i],pv->win_s);
-		/* put norm and phase to fftgrain */
-		aubio_fft_getnorm(fftgrain->norm[i], pv->spec[i], pv->win_s/2+1);
-		aubio_fft_getphas(fftgrain->phas[i], pv->spec[i], pv->win_s/2+1);
-	}
+        }
+        /* shift */
+        vec_shift(pv->data);
+	/* calculate fft */
+        aubio_mfft_do (pv->fft,pv->data,fftgrain);
 }
 
 void aubio_pvoc_rdo(aubio_pvoc_t *pv,cvec_t * fftgrain, fvec_t * synthnew) {
 	uint_t i,j;
+	/* calculate rfft */
+        aubio_mfft_rdo(pv->fft,fftgrain,pv->synth);
+        /* unshift */
+        vec_shift(pv->synth);
 	for (i=0; i<pv->channels; i++) {
-		for (j=0; j<pv->win_s/2+1; j++) {
-			pv->spec[i][j]  = CEXPC(I*unwrap2pi(fftgrain->phas[i][j]));
-			pv->spec[i][j] *= fftgrain->norm[i][j];
-		}
-		aubio_fft_rdo(pv->spectrum,pv->spec[i],pv->synth->data[i],pv->win_s);
-		vec_shift(pv->synth);
 		for (j=0; j<pv->win_s; j++) pv->synth->data[i][j] *= pv->w[j];
 		aubio_pvoc_addsynth(pv->synth->data[i],pv->synthold->data[i],
 				synthnew->data[i],pv->win_s,pv->hop_s);
@@ -99,32 +88,22 @@
 	}
 }
 
-void del_aubio_pvoc(aubio_pvoc_t *pv) {
-	aubio_pvoc_free(pv);
-}
-
 aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s, uint_t channels) {
-	aubio_pvoc_t * pv = aubio_pvoc_malloc(win_s, hop_s, channels);
-	window(pv->w,pv->win_s,hanningz);
-	return pv;
-}
-
-static aubio_pvoc_t * aubio_pvoc_malloc (uint_t win_s, uint_t hop_s, uint_t channels) {
-	uint_t i;
-
 	aubio_pvoc_t * pv = AUBIO_NEW(aubio_pvoc_t);
 
 	if (win_s < 2*hop_s) {
-		AUBIO_ERR("Window size is smaller than twice the hop size!\n");
-		return 0;
+		AUBIO_ERR("Hop size bigger than half the window size!\n");
+		AUBIO_ERR("Resetting hop size to half the window size.\n");
+                hop_s = win_s / 2;
 	}
 
 	if (hop_s < 1) {
 		AUBIO_ERR("Hop size is smaller than 1!\n");
-		return 0;
+		AUBIO_ERR("Resetting hop size to half the window size.\n");
+                hop_s = win_s / 2;
 	}
 	
-	pv->spectrum = new_aubio_fft(win_s);
+	pv->fft      = new_aubio_mfft(win_s,channels);
 
 	/* remember old */
 	pv->data     = new_fvec (win_s, channels);
@@ -134,11 +113,8 @@
 	pv->dataold  = new_fvec  (win_s-hop_s, channels);
 	pv->synthold = new_fvec (win_s-hop_s, channels);
 	pv->w        = AUBIO_ARRAY(smpl_t,win_s);
+	window(pv->w,win_s,hanningz);
 
-	pv->spec     = AUBIO_ARRAY(fft_data_t*,channels);
-	for (i=0; i<channels; i++) 
-		pv->spec[i] = AUBIO_ARRAY(fft_data_t,win_s);
-
 	pv->channels = channels;
 	pv->hop_s    = hop_s;
 	pv->win_s    = win_s;
@@ -146,23 +122,17 @@
 	return pv;
 }
 
-static void aubio_pvoc_free (aubio_pvoc_t *pv) {
-	uint_t i;
-	del_aubio_fft(pv->spectrum);
+void del_aubio_pvoc(aubio_pvoc_t *pv) {
 	del_fvec(pv->data);
 	del_fvec(pv->synth);
 	del_fvec(pv->dataold);
 	del_fvec(pv->synthold);
 	AUBIO_FREE(pv->w);
-	for (i=0; i< pv->channels; i++) {
-	        AUBIO_FREE(pv->spec[i]);
-	}
-	AUBIO_FREE(pv->spec);
 	AUBIO_FREE(pv);
 }
 
-static void aubio_pvoc_swapbuffers(smpl_t * data, smpl_t * dataold, const smpl_t * datanew, 
-		uint_t win_s, uint_t hop_s)
+static void aubio_pvoc_swapbuffers(smpl_t * data, smpl_t * dataold, 
+                const smpl_t * datanew, uint_t win_s, uint_t hop_s)
 {
 	uint_t i;
 	for (i=0;i<win_s-hop_s;i++)
@@ -173,8 +143,8 @@
 		dataold[i] = data[i+hop_s];
 }
 
-static void aubio_pvoc_addsynth(const smpl_t * synth, smpl_t * synthold, smpl_t * synthnew, 
-		uint_t win_s, uint_t hop_s)
+static void aubio_pvoc_addsynth(const smpl_t * synth, smpl_t * synthold, 
+                smpl_t * synthnew, uint_t win_s, uint_t hop_s)
 {
 	uint_t i;
 	smpl_t scale = 2*hop_s/(win_s+.0);