ref: 7a46bf6cec4e3b9ce9f40ff1db3a98933e016c56
parent: 7c6c806dda27c76b03afac7bfeecdaa88371a0ed
parent: 45134c5d80f69a506f3619ce88fbafc1b2a54434
author: Amaury Hazan <mahmoudax@gmail.org>
date: Mon Sep 10 15:29:32 EDT 2007
merged from piem, corrected mffcs coefs/filter number added some scripts to visualize filterbank and mfccs
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -10,7 +10,8 @@
bin_PROGRAMS = \
aubioonset \
aubiotrack \
- aubionotes
+ aubionotes \
+ aubiomfcc
noinst_PROGRAMS = \
aubioquiet
@@ -22,8 +23,10 @@
aubionotes_SOURCES = aubionotes.c utils.c
aubiotrack_SOURCES = aubiotrack.c utils.c
aubioquiet_SOURCES = aubioquiet.c utils.c
+aubiomfcc_SOURCES = aubiomfcc.c utils.c
aubioonset_LDADD = @JACK_LIBS@
aubionotes_LDADD = @JACK_LIBS@
aubiotrack_LDADD = @JACK_LIBS@
aubioquiet_LDADD = @JACK_LIBS@
+aubiomfcc_LDADD = @JACK_LIBS@
--- a/examples/aubiomfcc.c
+++ b/examples/aubiomfcc.c
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2007 Amaury Hazan
+ Copyright (C) 2007 Amaury Hazan <ahazan@iua.upf.edu>
+ and Paul Brossier <piem@piem.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,6 +19,13 @@
#include "utils.h"
+/* mfcc objects */
+fvec_t * mfcc_out;
+aubio_mfcc_t * mfcc;
+
+uint_t n_filters = 20;
+uint_t n_coefs = 11;
+
unsigned int pos = 0; /*frames%dspblocksize*/
uint_t usepitch = 0;
@@ -42,21 +50,8 @@
//compute mag spectrum
aubio_pvoc_do (pv,ibuf, fftgrain);
- uint_t n_coefs= n_filters/2 +1;
- uint_t coef_cnt;
-
-
- for (coef_cnt=0; coef_cnt<n_coefs ; coef_cnt++)
- mfcc_outbuf[coef_cnt]=0.f;
-
//compute mfccs
- aubio_mffc_do(fftgrain->norm, nframes, mf, mfcc_outbuf, fft_dct, fftgrain_dct);
-
- for (coef_cnt=0; coef_cnt<n_coefs ; coef_cnt++)
- outmsg("%f ",mfcc_outbuf[coef_cnt]);
- outmsg("\n");
-
-
+ aubio_mfcc_do(mfcc, fftgrain, mfcc_out);
/* end of block loop */
pos = -1; /* so it will be zero next j loop */
@@ -72,41 +67,46 @@
write extracted mfccs
*/
+ uint_t coef_cnt;
if (output_filename == NULL) {
- if(frames >= 4) {
- outmsg("%f\n",(frames-4)*overlap_size/(float)samplerate);
- } else if (frames < 4) {
- outmsg("%f\n",0.);
+// if(frames >= 4) {
+// outmsg("%f\t",(frames-4)*overlap_size/(float)samplerate);
+// }
+// else if (frames < 4) {
+// outmsg("%f\t",0.);
+// }
+ //outmsg("%f ",mfcc_out->data[0][0]);
+
+ /*for (coef_cnt = 0; coef_cnt < n_coefs; coef_cnt++) {
+ outmsg("%f ",mfcc_out->data[0][coef_cnt]);
}
+ outmsg("\n");/*/
}
}
int main(int argc, char **argv) {
+ // params
+ //uint_t n_filters = 40;
+ //uint_t n_coefs = 15;
+
examples_common_init(argc,argv);
+ smpl_t lowfreq = 133.333f;
+ smpl_t highfreq = 44100.f;
+ mfcc_out = new_fvec(n_coefs,channels);
- //allocate and initialize mel filter bank
-
-
- //allocating global mf (in utils.c)
- uint_t banksize = (uint) ( sizeof(aubio_mel_filter));
- mf = (aubio_mel_filter *)getbytes(banksize);
-
- mf->n_filters = 20;
- mf->filters = (smpl_t **)getbytes(mf->n_filters * sizeof(smpl_t *));
- for(n = 0; n < mf->n_filters; n++)
- mf->filters[n] = (smpl_t *)getbytes((buffer_size/2+1) * sizeof(smpl_t));
-
//populating the filter
- aubio_mfcc_init(buffer_size, nyquist, XTRACT_EQUAL_GAIN, lowfreq, highfreq, mf->n_filters, mf->filters);
+ mfcc = new_aubio_mfcc(buffer_size, samplerate, n_filters, n_coefs , lowfreq, highfreq, channels);
//process
examples_common_process(aubio_process,process_print);
+
+ //destroying mfcc
+ del_aubio_mfcc(mfcc);
+ del_fvec(mfcc_out);
+
examples_common_del();
debug("End of program.\n");
fflush(stderr);
-
- //destroying filterbank
- free(mf);
return 0;
}
--- /dev/null
+++ b/examples/plotfb.py
@@ -1,0 +1,21 @@
+#!/usr/bin/env python
+
+import pylab
+import numpy
+import sys
+
+filename=sys.argv[1]
+
+mat = pylab.load(filename)
+nmat= numpy.array(mat)
+print numpy.shape(nmat)
+
+pylab.hold(True)
+
+n_filters=numpy.shape(nmat)[0]
+for i in range(n_filters):
+ pylab.plot(nmat[i,:])
+
+
+pylab.hold(False)
+pylab.show()
\ No newline at end of file
--- /dev/null
+++ b/examples/plotmat.py
@@ -1,0 +1,18 @@
+#!/usr/bin/env python
+
+import pylab
+import numpy
+import sys
+
+filename=sys.argv[1]
+
+mat=pylab.load(filename)
+nmat=numpy.array(mat).T
+print numpy.shape(nmat)
+
+
+pylab.matshow(nmat, cmap=pylab.cm.gray, aspect='auto')
+#pylab.imshow(nmat, cmap=pylab.cm.gray, aspect='auto', interpolation=False)
+#pylab.contour(nmat, cmap=pylab.cm.gray, aspect='auto')
+
+pylab.show()
\ No newline at end of file
--- a/examples/tests/test-beattracking.c
+++ b/examples/tests/test-beattracking.c
@@ -12,8 +12,15 @@
uint_t i = 0;
+ smpl_t curtempo;
+
while (i < 10) {
aubio_beattracking_do(tempo,in,out);
+ curtempo = aubio_beattracking_get_bpm(tempo);
+ if (curtempo != 0.) {
+ fprintf(stdout,"%f\n",curtempo);
+ return 1;
+ }
i++;
};
--- a/examples/tests/test-tempo.c
+++ b/examples/tests/test-tempo.c
@@ -9,8 +9,14 @@
aubio_tempo_t * o = new_aubio_tempo(aubio_onset_complex, win_s, win_s/4, channels);
uint_t i = 0;
+ smpl_t curtempo;
+
while (i < 1000) {
aubio_tempo(o,in,out);
+ curtempo = aubio_tempo_get_bpm(o);
+ if (curtempo != 0.) {
+ fprintf(stdout,"%f\n",curtempo);
+ }
i++;
};
--- a/examples/utils.c
+++ b/examples/utils.c
@@ -60,21 +60,6 @@
int isonset = 0;
aubio_pickpeak_t * parms;
-/* mfcc objects */
-//parameters
-uint_t n_filters=20;
-uint_t nyquist= samplerate / 2.;
-smpl_t lowfreq=80.f;
-smpl_t highfreq=18000.f;
-// filterbank object
-aubio_mel_filter * mf;
-
-// DCT mfft and result storage
-aubio_mfft * fft_dct;
-cvec_t * fftgrain_dct;
-smpl_t mfcc_outbuf[11];
-
-
/* pitch objects */
smpl_t pitch = 0.;
aubio_pitchdetection_t * pitchdet;
@@ -314,9 +299,7 @@
obuf = new_fvec(overlap_size, channels);
fftgrain = new_cvec(buffer_size, channels);
- //init for mfcc process
- fftgrain_dct= new_cvec(n_filters, channels);
-
+
if (usepitch) {
pitchdet = new_aubio_pitchdetection(buffer_size*4,
overlap_size, channels, samplerate, type_pitch, mode_pitch);
@@ -330,10 +313,6 @@
/* phase vocoder */
pv = new_aubio_pvoc(buffer_size, overlap_size, channels);
- // dct phase vocoder
- //TODO: check size
- fft_dct = new_aubio_mfft(n_filters, channels);
-
/* onsets */
parms = new_aubio_peakpicker(threshold);
o = new_aubio_onsetdetection(type_onset,buffer_size,channels);
@@ -367,10 +346,6 @@
del_cvec(fftgrain);
del_fvec(onset);
del_fvec(woodblock);
-
- //mffc related
- del_aubio_mfft(fft_dct);
- del_cvec(fftgrain_dct);
aubio_cleanup();
}
--- a/examples/utils.h
+++ b/examples/utils.h
@@ -97,19 +97,6 @@
extern int isonset;
extern aubio_pickpeak_t * parms;
-/* mfcc objects */
-// params
-extern uint_t n_filters;
-extern uint_t nyquist;
-extern smpl_t lowfreq;
-extern smpl_t highfreq;
-// filterbank object
-extern aubio_mel_filter * mf;
-// DCT pvoc and result storage
-extern aubio_mfft_t * fft_dct;
-extern cvec_t * fftgrain_dct;
-extern smpl_t mfcc_outbuf[20];
-
/* pitch objects */
extern smpl_t pitch;
extern aubio_pitchdetection_t * pitchdet;
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,6 +22,7 @@
onset.h \
tempo.h \
filter.h \
+ filterbank.h \
mfcc.h
nodist_pkginclude_HEADERS = config.h
@@ -71,6 +72,8 @@
tempo.h \
filter.c \
filter.h \
+ filterbank.c \
+ filterbank.h \
mfcc.h \
mfcc.c
--- a/src/aubio.h
+++ b/src/aubio.h
@@ -79,6 +79,7 @@
#include "beattracking.h"
#include "onset.h"
#include "tempo.h"
+#include "filterbank.h"
#include "mfcc.h"
#ifdef __cplusplus
--- a/src/beattracking.c
+++ b/src/beattracking.c
@@ -452,3 +452,11 @@
bt->rp2 = rp2;
}
+
+smpl_t aubio_beattracking_get_bpm(aubio_beattracking_t * bt) {
+ if (bt->timesig != 0 && bt->counter == 0 && bt->flagstep == 0) {
+ return 5168. / (smpl_t)bt->gp;
+ } else {
+ return 0.;
+ }
+}
--- a/src/beattracking.h
+++ b/src/beattracking.h
@@ -59,6 +59,15 @@
*/
void aubio_beattracking_do(aubio_beattracking_t * bt, fvec_t * dfframes, fvec_t * out);
+/** get current tempo in bpm
+
+ \param bt beat tracking object
+
+ Returns the currently observed tempo, in beats per minutes, or 0 if no
+ consistent value is found.
+
+*/
+smpl_t aubio_beattracking_get_bpm(aubio_beattracking_t * bt);
/** delete beat tracking object
\param p beat tracking object
--- a/src/filterbank.c
+++ b/src/filterbank.c
@@ -1,8 +1,6 @@
/*
- Copyright (C) 2007 Amaury Hazan
- Ported to aubio from LibXtract
- http://libxtract.sourceforge.net/
-
+ Copyright (C) 2007 Amaury Hazan <ahazan@iua.upf.edu>
+ and Paul Brossier <piem@piem.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,114 +18,184 @@
*/
+/* part of this mfcc implementation were inspired from LibXtract
+ http://libxtract.sourceforge.net/
+*/
+
#include "aubio_priv.h"
+#include "sample.h"
#include "filterbank.h"
+#include "stdio.h"
-// Struct Declaration
+#define USE_EQUAL_GAIN 1
+#define VERY_SMALL_NUMBER 2e-42
-/** \brief A structure to store a set of n_filters Mel filters */
-typedef struct aubio_mel_filter_ {
- int n_filters;
- smpl_t **filters;
+/** \brief A structure to store a set of n_filters filters of lenghts win_s */
+struct aubio_filterbank_t_ {
+ uint_t win_s;
+ uint_t n_filters;
+ fvec_t **filters;
};
-// Initialization
+aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s){
+ /** allocating space for filterbank object */
+ aubio_filterbank_t * fb = AUBIO_NEW(aubio_filterbank_t);
+ uint_t filter_cnt;
+ fb->win_s=win_s;
+ fb->n_filters=n_filters;
-int aubio_mfcc_init(int N, smpl_t nyquist, int style, smpl_t freq_min, smpl_t freq_max, int freq_bands, smpl_t **fft_tables){
+ /** allocating filter tables */
+ fb->filters=AUBIO_ARRAY(fvec_t*,n_filters);
+ for (filter_cnt=0; filter_cnt<n_filters; filter_cnt++)
+ /* considering one-channel filters */
+ fb->filters[filter_cnt]=new_fvec(win_s, 1);
- int n, i, k, *fft_peak, M, next_peak;
- smpl_t norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val,
- freq_bw_mel, *mel_peak, *height_norm, *lin_peak;
+ return fb;
+}
- mel_peak = height_norm = lin_peak = NULL;
- fft_peak = NULL;
- norm = 1;
+aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, smpl_t samplerate, smpl_t freq_min, smpl_t freq_max){
+
+ uint_t writelog=1;
- mel_freq_max = 1127 * log(1 + freq_max / 700);
- mel_freq_min = 1127 * log(1 + freq_min / 700);
- freq_bw_mel = (mel_freq_max - mel_freq_min) / freq_bands;
+ FILE * mlog;
+ if(writelog==1) mlog=fopen("filterbank.txt","w");
+
- mel_peak = (smpl_t *)malloc((freq_bands + 2) * sizeof(smpl_t));
- /* +2 for zeros at start and end */
- lin_peak = (smpl_t *)malloc((freq_bands + 2) * sizeof(smpl_t));
- fft_peak = (int *)malloc((freq_bands + 2) * sizeof(int));
- height_norm = (smpl_t *)malloc(freq_bands * sizeof(smpl_t));
+ smpl_t nyquist = samplerate/2.;
+ uint_t style = 1;
+ aubio_filterbank_t * fb = new_aubio_filterbank(n_filters, win_s);
- if(mel_peak == NULL || height_norm == NULL ||
- lin_peak == NULL || fft_peak == NULL)
- return XTRACT_MALLOC_FAILED;
-
- M = N >> 1;
+ uint_t n, i, k, *fft_peak, M, next_peak;
+ smpl_t norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val,
+ freq_bw_mel, *mel_peak, *height_norm, *lin_peak;
- mel_peak[0] = mel_freq_min;
- lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1);
- fft_peak[0] = lin_peak[0] / nyquist * M;
+ mel_peak = height_norm = lin_peak = NULL;
+ fft_peak = NULL;
+ norm = 1;
+ mel_freq_max = 1127 * log(1 + freq_max / 700);
+ mel_freq_min = 1127 * log(1 + freq_min / 700);
+ freq_bw_mel = (mel_freq_max - mel_freq_min) / fb->n_filters;
- for (n = 1; n <= freq_bands; n++){
+ mel_peak = (smpl_t *)malloc((fb->n_filters + 2) * sizeof(smpl_t));
+ /* +2 for zeros at start and end */
+ lin_peak = (smpl_t *)malloc((fb->n_filters + 2) * sizeof(smpl_t));
+ fft_peak = (uint_t *)malloc((fb->n_filters + 2) * sizeof(uint_t));
+ height_norm = (smpl_t *)malloc(fb->n_filters * sizeof(smpl_t));
+
+ if(mel_peak == NULL || height_norm == NULL ||
+ lin_peak == NULL || fft_peak == NULL)
+ return NULL;
+
+ M = fb->win_s >> 1;
+
+ mel_peak[0] = mel_freq_min;
+ lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1);
+ fft_peak[0] = lin_peak[0] / nyquist * M;
+
+ for (n = 1; n <= fb->n_filters; n++){
/*roll out peak locations - mel, linear and linear on fft window scale */
- mel_peak[n] = mel_peak[n - 1] + freq_bw_mel;
- lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1);
- fft_peak[n] = lin_peak[n] / nyquist * M;
+ mel_peak[n] = mel_peak[n - 1] + freq_bw_mel;
+ lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1);
+ fft_peak[n] = lin_peak[n] / nyquist * M;
+ }
+
+ for (n = 0; n < fb->n_filters; n++){
+ /*roll out normalised gain of each peak*/
+ if (style == USE_EQUAL_GAIN){
+ height = 1;
+ norm_fact = norm;
}
+ else{
+ height = 2 / (lin_peak[n + 2] - lin_peak[n]);
+ norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0]));
+ }
+ height_norm[n] = height * norm_fact;
+ }
- for (n = 0; n < freq_bands; n++){
- /*roll out normalised gain of each peak*/
- if (style == XTRACT_EQUAL_GAIN){
- height = 1;
- norm_fact = norm;
- }
- else{
- height = 2 / (lin_peak[n + 2] - lin_peak[n]);
- norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0]));
- }
- height_norm[n] = height * norm_fact;
+ i = 0;
+
+ for(n = 0; n < fb->n_filters; n++){
+
+ /*calculate the rise increment*/
+ if(n > 0)
+ inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]);
+ else
+ inc = height_norm[n] / fft_peak[n];
+ val = 0;
+
+ /*zero the start of the array*/
+ for(k = 0; k < i; k++)
+ fb->filters[n]->data[0][k]=0.f;
+
+ /*fill in the rise */
+ for(; i <= fft_peak[n]; i++){
+ fb->filters[n]->data[0][k]=val;
+ val += inc;
}
- i = 0;
-
- for(n = 0; n < freq_bands; n++){
-
- /*calculate the rise increment*/
- if(n > 0)
- inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]);
- else
- inc = height_norm[n] / fft_peak[n];
- val = 0;
-
- /*zero the start of the array*/
- for(k = 0; k < i; k++)
- fft_tables[n][k] = 0.f;
-
- /*fill in the rise */
- for(; i <= fft_peak[n]; i++){
- fft_tables[n][i] = val;
- val += inc;
- }
-
- /*calculate the fall increment */
- inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);
-
- val = 0;
- next_peak = fft_peak[n + 1];
-
- /*reverse fill the 'fall' */
- for(i = next_peak; i > fft_peak[n]; i--){
- fft_tables[n][i] = val;
- val += inc;
- }
+ /*calculate the fall increment */
+ inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);
- /*zero the rest of the array*/
- for(k = next_peak + 1; k < N; k++)
- fft_tables[n][k] = 0.f;
+ val = 0;
+ next_peak = fft_peak[n + 1];
+
+ /*reverse fill the 'fall' */
+ for(i = next_peak; i > fft_peak[n]; i--){
+ fb->filters[n]->data[0][k]=val;
+ val += inc;
}
- free(mel_peak);
- free(lin_peak);
- free(height_norm);
- free(fft_peak);
+ /*zero the rest of the array*/
+ for(k = next_peak + 1; k < fb->win_s; k++)
+ fb->filters[n]->data[0][k]=0.f;
- return XTRACT_SUCCESS;
+ if(writelog){
+ //dumping filter values
+ smpl_t area_tmp=0.f;
+ for(k = 0; k < fb->win_s; k++){
+ fprintf(mlog,"%f ",fb->filters[n]->data[0][k]);
+ }
+ fprintf(mlog,"\n");
+ }
+ }
+
+ free(mel_peak);
+ free(lin_peak);
+ free(height_norm);
+ free(fft_peak);
+
+ if(mlog) fclose(mlog);
+
+ return fb;
+
+}
+
+
+void del_aubio_filterbank(aubio_filterbank_t * fb){
+ uint_t filter_cnt;
+ /** deleting filter tables first */
+ for (filter_cnt=0; filter_cnt<fb->n_filters; filter_cnt++)
+ del_fvec(fb->filters[filter_cnt]);
+ AUBIO_FREE(fb->filters);
+ AUBIO_FREE(fb);
+}
+
+void aubio_filterbank_do(aubio_filterbank_t * f, cvec_t * in, fvec_t *out) {
+ uint_t n, filter_cnt;
+ for(filter_cnt = 0; (filter_cnt < f->n_filters)
+ && (filter_cnt < out->length); filter_cnt++){
+ out->data[0][filter_cnt] = 0.f;
+ for(n = 0; n < in->length; n++){
+ out->data[0][filter_cnt] += in->norm[0][n]
+ * f->filters[filter_cnt]->data[0][n];
+ }
+ out->data[0][filter_cnt] =
+ LOG(out->data[0][filter_cnt] < VERY_SMALL_NUMBER ?
+ VERY_SMALL_NUMBER : out->data[0][filter_cnt]);
+ }
+
+ return;
}
--- a/src/filterbank.h
+++ b/src/filterbank.h
@@ -1,8 +1,6 @@
/*
- Copyright (C) 2007 Amaury Hazan
- Ported to aubio from LibXtract
- http://libxtract.sourceforge.net/
-
+ Copyright (C) 2007 Amaury Hazan <ahazan@iua.upf.edu>
+ and Paul Brossier <piem@piem.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,27 +17,57 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef AUBIOFILTERBANK_H
-#define AUBIOFILTERBANK_H
+/** \file
+ Filterbank object
+
+ General-purpose spectral filterbank object. Comes with mel-filter initialization function.
+
+*/
+
+#ifndef FILTERBANK_H
+#define FILTERBANK_H
+
#ifdef __cplusplus
extern "C" {
#endif
+typedef struct aubio_filterbank_t_ aubio_filterbank_t;
+/** create filterbank object
-typedef struct aubio_mel_filter_ aubio_mel_filter;
+ \param win_s size of analysis buffer (and length the FFT transform)
+ \param n_filters number of filters to create
-// Initialization
+*/
-/** \brief A function to initialise a mel filter bank
- *
- * It is up to the caller to pass in a pointer to memory allocated for freq_bands arrays of length N. This function populates these arrays with magnitude coefficients representing the mel filterbank on a linear scale
- */
-int aubio_mfcc_init(int N, smpl_t nyquist, int style, smpl_t freq_min, smpl_t freq_max, int freq_bands, smpl_t ** fft_tables);
+aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s);
+/** filterbank initialization for mel filters
+
+ \param nyquist nyquist frequency, i.e. half of the sampling rate
+ \param style libxtract style
+ \param freqmin lowest filter frequency
+ \param freqmax highest filter frequency
+
+*/
+aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, smpl_t samplerate, smpl_t freq_min, smpl_t freq_max);
+
+
+/** destroy filterbank object
+
+ \param fb filterbank, as returned by new_aubio_filterbank method
+
+*/
+void del_aubio_filterbank(aubio_filterbank_t * fb);
+
+/** compute filterbank
+
+*/
+void aubio_filterbank_do(aubio_filterbank_t * fb, cvec_t * in, fvec_t *out);
+
#ifdef __cplusplus
}
#endif
-#endif
+#endif // FILTERBANK_H
--- a/src/mfcc.c
+++ b/src/mfcc.c
@@ -23,64 +23,91 @@
#include "aubio_priv.h"
#include "sample.h"
#include "fft.h"
+#include "filterbank.h"
#include "mfcc.h"
#include "math.h"
-/*
-new_aubio_mfcc
-aubio_mfcc_do
-del_aubio_mfcc
-*/
+/** Internal structure for mfcc object **/
-// Computation
-// Added last two arguments to be able to pass from example
+struct aubio_mfcc_t_{
+ uint_t win_s; /** grain length */
+ uint_t samplerate; /** sample rate (needed?) */
+ uint_t channels; /** number of channels */
+ uint_t n_filters; /** number of *filters */
+ uint_t n_coefs; /** number of coefficients (<= n_filters/2 +1) */
+ smpl_t lowfreq; /** lowest frequency for filters */
+ smpl_t highfreq; /** highest frequency for filters */
+ aubio_filterbank_t * fb; /** filter bank */
+ fvec_t * in_dct; /** input buffer for dct * [fb->n_filters] */
+ aubio_mfft_t * fft_dct; /** fft object for dct */
+ cvec_t * fftgrain_dct; /** output buffer for dct */
+};
+aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate, uint_t n_filters, uint_t n_coefs, smpl_t lowfreq, smpl_t highfreq, uint_t channels){
+ /** allocating space for mfcc object */
+ aubio_mfcc_t * mfcc = AUBIO_NEW(aubio_mfcc_t);
-int aubio_mfcc_do(const float *data, const int N, const void *argv, float *result, aubio_mfft_t * fft_dct, cvec_t * fftgrain_dct){
+ //we need (n_coefs-1)*2 filters to obtain n_coefs coefficients after dct
+ //uint_t n_filters = (n_coefs-1)*2;
+
+ mfcc->win_s=win_s;
+ mfcc->samplerate=samplerate;
+ mfcc->channels=channels;
+ mfcc->n_filters=n_filters;
+ mfcc->n_coefs=n_coefs;
+ mfcc->lowfreq=lowfreq;
+ mfcc->highfreq=highfreq;
- aubio_mel_filter *f;
- int n, filter;
+ /** filterbank allocation */
+ mfcc->fb = new_aubio_filterbank_mfcc(n_filters, mfcc->win_s, samplerate, lowfreq, highfreq);
- f = (aubio_mel_filter *)argv;
-
- for(filter = 0; filter < f->n_filters; filter++){
- result[filter] = 0.f;
- for(n = 0; n < N; n++){
- result[filter] += data[n] * f->filters[filter][n];
- }
- result[filter] = LOG(result[filter] < XTRACT_LOG_LIMIT ? XTRACT_LOG_LIMIT : result[filter]);
- }
+ /** allocating space for fft object (used for dct) */
+ mfcc->fft_dct=new_aubio_mfft(n_filters, 1);
- //TODO: check that zero padding
- for(n = filter + 1; n < N; n++) result[n] = 0;
-
- aubio_dct_do(result, f->n_filters, NULL, result, fft_dct, fftgrain_dct);
-
- return XTRACT_SUCCESS;
-}
+ /** allocating buffers */
+ mfcc->in_dct=new_fvec(mfcc->win_s, 1);
+
+ mfcc->fftgrain_dct=new_cvec(n_filters, 1);
-// Added last two arguments to be able to pass from example
+ return mfcc;
+};
-int aubio_dct_do(const float *data, const int N, const void *argv, float *result, aubio_mfft_t * fft_dct, cvec_t * fftgrain_dct){
+void del_aubio_mfcc(aubio_mfcc_t *mf){
+ /** deleting filterbank */
+ del_aubio_filterbank(mf->fb);
+ /** deleting mfft object */
+ del_aubio_mfft(mf->fft_dct);
+ /** deleting buffers */
+ del_fvec(mf->in_dct);
+ del_cvec(mf->fftgrain_dct);
+
+ /** deleting mfcc object */
+ AUBIO_FREE(mf);
+}
+
+void aubio_mfcc_do(aubio_mfcc_t * mf, cvec_t *in, fvec_t *out){
+ // compute filterbank
+ aubio_filterbank_do(mf->fb, in, mf->in_dct);
+ //TODO: check that zero padding
+ // the following line seems useless since the in_dct buffer has the correct size
+ //for(n = filter + 1; n < N; n++) result[n] = 0;
-
- //call aubio p_voc in dct setting
+ aubio_dct_do(mf, mf->in_dct, out);
- //TODO: fvec as input? Remove data length, N?
+ return;
+}
- fvec_t * momo = new_fvec(20, 1);
- momo->data = data;
-
+void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out){
+ uint_t i;
//compute mag spectrum
- aubio_mfft_do (fft_dct, data, fftgrain_dct);
-
- int i;
+ aubio_mfft_do (mf->fft_dct, in, mf->fftgrain_dct);
//extract real part of fft grain
- for(i=0; i<N ;i++){
- result[i]= fftgrain_dct->norm[0][i]*COS(fftgrain_dct->phas[0][i]);
+ for(i=0; i<mf->n_coefs ;i++){
+ //for(i=0; i<out->length;i++){
+ out->data[0][i]= mf->fftgrain_dct->norm[0][i]
+ *COS(mf->fftgrain_dct->phas[0][i]);
}
-
-
- return XTRACT_SUCCESS;
+ return;
}
+
--- a/src/mfcc.h
+++ b/src/mfcc.h
@@ -1,8 +1,6 @@
/*
- Copyright (C) 2006 Amaury Hazan
- Ported to aubio from LibXtract
- http://libxtract.sourceforge.net/
-
+ Copyright (C) 2007 Amaury Hazan <ahazan@iua.upf.edu>
+ and Paul Brossier <piem@piem.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,6 +18,10 @@
*/
+/* part of this mfcc implementation were inspired from LibXtract
+ http://libxtract.sourceforge.net/
+*/
+
#ifndef MFCC_H
#define MFCC_H
@@ -27,153 +29,48 @@
extern "C" {
#endif
+#include "sample.h"
#include "filterbank.h"
-//libXtract constants and enums
-// TODO: remove them
+typedef struct aubio_mfcc_t_ aubio_mfcc_t;
-#define XTRACT_SQ(a) ((a) * (a))
-#define XTRACT_MIN(a, b) ((a) < (b) ? (a) : (b))
-#define XTRACT_MAX(a, b) ((a) > (b) ? (a) : (b))
-#define XTRACT_NEEDS_FFTW printf("LibXtract must be compiled with fftw support to use this function.\n")
-#define XTRACT_VERY_SMALL_NUMBER 2e-42
-#define XTRACT_LOG_LIMIT XTRACT_VERY_SMALL_NUMBER
-#define XTRACT_LOG_LIMIT_DB -96.0
-#define XTRACT_DB_SCALE_OFFSET 96.0
-#define XTRACT_VERY_BIG_NUMBER 2e42
-#define XTRACT_SR_UPPER_LIMIT 192000.0
-#define XTRACT_SR_LOWER_LIMIT 22050.0
-#define XTRACT_SR_DEFAULT 44100.0
-#define XTRACT_FUNDAMENTAL_DEFAULT 440.0
-#define XTRACT_CHECK_nyquist if(!nyquist) nyquist = XTRACT_SR_DEFAULT / 2
-#define XTRACT_CHECK_q if(!q) q = XTRACT_SR_DEFAULT / N
-#define XTRACT_IS_ODD(x) (x % 2 != 0 ? 1 : 0)
-#define XTRACT_SR_LIMIT SR_UPPER_LIMIT
-#define XTRACT_FFT_BANDS_MIN 16
-#define XTRACT_FFT_BANDS_MAX 65536
-#define XTRACT_FFT_BANDS_DEF 1024
-#define XTRACT_SPEC_BW_MIN 0.168 /* Minimum spectral bandwidth \
- (= SR_LOWER_LIMIT / FFT_BANDS_MAX*/
-#define XTRACT_SPEC_BW_MAX 12000.0 /* SR_UPPER_LIMIT / FFT_BANDS_MIN */
-#define XTRACT_SPEC_BW_DEF 43.066 /* SR_DEFAULT / FFT_BANDS_DEF */
+/** create mfcc object
-/** \brief Enumeration of feature initialisation functions */
-enum xtract_feature_init_ {
- XTRACT_INIT_MFCC = 100,
- XTRACT_INIT_BARK
-};
+ \param win_s size of analysis buffer (and length the FFT transform)
+ \param samplerate
+ \param n_coefs: number of desired coefs
+ \param lowfreq: lowest frequency to use in filterbank
+ \param highfreq highest frequency to use in filterbank
+ \param channels number of channels
-/** \brief Enumeration of feature types */
-enum xtract_feature_types_ {
- XTRACT_SCALAR,
- XTRACT_VECTOR,
- XTRACT_DELTA
-};
+*/
+aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate, uint_t n_filters, uint_t n_coefs, smpl_t lowfreq, smpl_t highfreq, uint_t channels);
+/** delete mfcc object
-/** \brief Enumeration of mfcc types */
-enum xtract_mfcc_types_ {
- XTRACT_EQUAL_GAIN,
- XTRACT_EQUAL_AREA
-};
+ \param mf mfcc object as returned by new_aubio_mfcc
-/** \brief Enumeration of return codes */
-enum xtract_return_codes_ {
- XTRACT_SUCCESS,
- XTRACT_MALLOC_FAILED,
- XTRACT_BAD_ARGV,
- XTRACT_BAD_VECTOR_SIZE,
- XTRACT_NO_RESULT,
- XTRACT_FEATURE_NOT_IMPLEMENTED
-};
+*/
+void del_aubio_mfcc(aubio_mfcc_t *mf);
+/** mfcc object processing
-/** \brief Enumeration of spectrum types */
-enum xtract_spectrum_ {
- XTRACT_MAGNITUDE_SPECTRUM,
- XTRACT_LOG_MAGNITUDE_SPECTRUM,
- XTRACT_POWER_SPECTRUM,
- XTRACT_LOG_POWER_SPECTRUM
-};
+ \param mf mfcc object as returned by new_aubio_mfcc
+ \param in input spectrum (win_s long)
+ \param out output mel coefficients buffer (n_filters/2 +1 long)
-/** \brief Enumeration of data types*/
-typedef enum type_ {
- XTRACT_FLOAT,
- XTRACT_FLOATARRAY,
- XTRACT_INT,
- XTRACT_MEL_FILTER
-} xtract_type_t;
+*/
+void aubio_mfcc_do(aubio_mfcc_t * mf, cvec_t *in, fvec_t *out);
-/** \brief Enumeration of units*/
-typedef enum unit_ {
- /* NONE, ANY */
- XTRACT_HERTZ = 2,
- XTRACT_ANY_AMPLITUDE_HERTZ,
- XTRACT_DBFS,
- XTRACT_DBFS_HERTZ,
- XTRACT_PERCENT,
- XTRACT_SONE
-} xtract_unit_t;
+/** intermediate dct involved in aubio_mfcc_do
-/** \brief Boolean */
-typedef enum {
- XTRACT_FALSE,
- XTRACT_TRUE
-} xtract_bool_t;
+ \param mf mfcc object as returned by new_aubio_mfcc
+ \param in input spectrum (n_filters long)
+ \param out output mel coefficients buffer (n_filters/2 +1 long)
-/** \brief Enumeration of vector format types*/
-typedef enum xtract_vector_ {
- /* N/2 magnitude/log-magnitude/power/log-power coeffs and N/2 frequencies */
- XTRACT_SPECTRAL,
- /* N spectral amplitudes */
- XTRACT_SPECTRAL_MAGNITUDES,
- /* N/2 magnitude/log-magnitude/power/log-power peak coeffs and N/2
- * frequencies */
- XTRACT_SPECTRAL_PEAKS,
- /* N spectral peak amplitudes */
- XTRACT_SPECTRAL_PEAKS_MAGNITUDES,
- /* N spectral peak frequencies */
- XTRACT_SPECTRAL_PEAKS_FREQUENCIES,
- /* N/2 magnitude/log-magnitude/power/log-power harmonic peak coeffs and N/2
- * frequencies */
- XTRACT_SPECTRAL_HARMONICS,
- /* N spectral harmonic amplitudes */
- XTRACT_SPECTRAL_HARMONICS_MAGNITUDES,
- /* N spectral harmonic frequencies */
- XTRACT_SPECTRAL_HARMONICS_FREQUENCIES,
- XTRACT_ARBITRARY_SERIES,
- XTRACT_AUDIO_SAMPLES,
- XTRACT_MEL_COEFFS,
- XTRACT_BARK_COEFFS,
- XTRACT_NO_DATA
-} xtract_vector_t;
+*/
+void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out);
-
-
-
-// Computation
-
-/** \brief Extract Mel Frequency Cepstral Coefficients based on a method described by Rabiner
- *
- * \param *data: a pointer to the first element in an array of spectral magnitudes, e.g. the first half of the array pointed to by *resul from xtract_spectrum()
- * \param N: the number of array elements to be considered
- * \param *argv: a pointer to a data structure of type xtract_mel_filter, containing n_filters coefficient tables to make up a mel-spaced filterbank
- * \param *result: a pointer to an array containing the resultant MFCC
- *
- * The data structure pointed to by *argv must be obtained by first calling xtract_init_mfcc
- */
-
-
-int aubio_mfcc_do(const float *data, const int N, const void *argv, float *result, aubio_mfft_t *fft_dct, cvec_t *fftgrain_dct);
-
-/** \brief Extract the Discrete Cosine transform of a time domain signal
- * \param *data: a pointer to the first element in an array of floats representing an audio vector
- * \param N: the number of array elements to be considered
- * \param *argv: a pointer to NULL
- * \param *result: a pointer to an array containing resultant dct coefficients
- */
-int aubio_dct_do(const float *data, const int N, const void *argv, float *result, aubio_mfft_t *fft_dct, cvec_t *fftgrain_dct);
-
#ifdef __cplusplus
}
#endif
-#endif
+#endif // MFCC_H
--- a/src/tempo.c
+++ b/src/tempo.c
@@ -123,6 +123,10 @@
return o;
}
+smpl_t aubio_tempo_get_bpm(aubio_tempo_t *o) {
+ return aubio_beattracking_get_bpm(o->bt);
+}
+
void del_aubio_tempo (aubio_tempo_t *o)
{
del_aubio_onsetdetection(o->od);
--- a/src/tempo.h
+++ b/src/tempo.h
@@ -49,6 +49,15 @@
/** set tempo detection peak picking threshold */
void aubio_tempo_set_threshold(aubio_tempo_t * o, smpl_t threshold);
+/** get current tempo
+
+ \param bt beat tracking object
+
+ Returns the currently observed tempo, or 0 if no consistent value is found
+
+*/
+smpl_t aubio_tempo_get_bpm(aubio_tempo_t * bt);
+
/** delete tempo detection object */
void del_aubio_tempo(aubio_tempo_t * o);