From: Paul Brossier Date: Sat, 24 Nov 2007 21:00:20 +0000 (+0100) Subject: src/: more moving and splitting X-Git-Tag: 0.4.0-beta1~965 X-Git-Url: https://git.aubio.org/?a=commitdiff_plain;h=32d69586108e1d0e451655e0a0da51bbea9169d4;p=aubio.git src/: more moving and splitting --- diff --git a/src/Makefile.am b/src/Makefile.am index f29dd3bd..7afd4d40 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,17 +1,19 @@ noinst_HEADERS = aubio_priv.h pkginclude_HEADERS = aubio.h \ types.h \ - phasevoc.h \ - mathutils.h \ - fft.h \ - sample.h \ fvec.h \ cvec.h \ - hist.h \ - scale.h \ - resample.h \ - tss.h \ - biquad.h \ + mathutils.h \ + utils/hist.h \ + utils/scale.h \ + temporal/resample.h \ + temporal/biquad.h \ + temporal/filter.h \ + spectral/filterbank.h \ + spectral/mfcc.c \ + spectral/phasevoc.h \ + spectral/fft.h \ + spectral/tss.h \ pitch/pitchdetection.h \ pitch/pitchmcomb.h \ pitch/pitchyin.h \ @@ -22,36 +24,39 @@ pkginclude_HEADERS = aubio.h \ onset/onsetdetection.h \ onset/peakpick.h \ tempo/tempo.h \ - tempo/beattracking.h \ - filter.h \ - filterbank.h \ - mfcc.h + tempo/beattracking.h nodist_pkginclude_HEADERS = config.h lib_LTLIBRARIES = libaubio.la libaubio_la_SOURCES = aubio.h \ types.h \ - phasevoc.c \ - phasevoc.h \ - mathutils.c \ - mathutils.h \ - fft.c \ - fft.h \ fvec.c \ fvec.h \ cvec.c \ cvec.h \ - hist.c \ - hist.h \ - scale.c \ - scale.h \ - resample.c \ - resample.h \ - tss.c \ - tss.h \ - biquad.c \ - biquad.h \ + mathutils.c \ + mathutils.h \ + utils/hist.c \ + utils/hist.h \ + utils/scale.c \ + utils/scale.h \ + temporal/resample.c \ + temporal/resample.h \ + temporal/biquad.c \ + temporal/biquad.h \ + temporal/filter.c \ + temporal/filter.h \ + spectral/filterbank.c \ + spectral/filterbank.h \ + spectral/mfcc.h \ + spectral/mfcc.c \ + spectral/phasevoc.c \ + spectral/phasevoc.h \ + spectral/fft.c \ + spectral/fft.h \ + spectral/tss.c \ + spectral/tss.h \ pitch/pitchdetection.c \ pitch/pitchdetection.h \ pitch/pitchmcomb.c \ @@ -73,13 +78,7 @@ libaubio_la_SOURCES = aubio.h \ tempo/tempo.c \ tempo/tempo.h \ tempo/beattracking.c \ - tempo/beattracking.h \ - filter.c \ - filter.h \ - filterbank.c \ - filterbank.h \ - mfcc.h \ - mfcc.c + tempo/beattracking.h AM_CFLAGS = @AUBIO_CFLAGS@ @FFTWLIB_CFLAGS@ @SAMPLERATE_CFLAGS@ libaubio_la_LIBADD = @FFTWLIB_LIBS@ @SAMPLERATE_LIBS@ @LTLIBOBJS@ diff --git a/src/aubio.h b/src/aubio.h index 73af8bbf..4515606b 100644 --- a/src/aubio.h +++ b/src/aubio.h @@ -59,15 +59,15 @@ extern "C" { /* in this order */ #include "types.h" #include "sample.h" -#include "fft.h" -#include "phasevoc.h" +#include "spectral/fft.h" +#include "spectral/phasevoc.h" #include "mathutils.h" -#include "scale.h" -#include "hist.h" -#include "tss.h" -#include "resample.h" -#include "biquad.h" -#include "filter.h" +#include "utils/scale.h" +#include "utils/hist.h" +#include "spectral/tss.h" +#include "temporal/resample.h" +#include "temporal/biquad.h" +#include "temporal/filter.h" #include "pitch/pitchdetection.h" #include "pitch/pitchmcomb.h" #include "pitch/pitchyin.h" @@ -79,8 +79,8 @@ extern "C" { #include "onset/peakpick.h" #include "tempo/beattracking.h" #include "tempo/tempo.h" -#include "filterbank.h" -#include "mfcc.h" +#include "spectral/filterbank.h" +#include "spectral/mfcc.h" #ifdef __cplusplus } /* extern "C" */ diff --git a/src/biquad.c b/src/biquad.c deleted file mode 100644 index 327abfa1..00000000 --- a/src/biquad.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "aubio_priv.h" -#include "sample.h" -#include "mathutils.h" -#include "biquad.h" - -/** \note this file needs to be in double or more less precision would lead to large - * errors in the output - */ - -struct _aubio_biquad_t { - lsmp_t a2; - lsmp_t a3; - lsmp_t b1; - lsmp_t b2; - lsmp_t b3; - lsmp_t o1; - lsmp_t o2; - lsmp_t i1; - lsmp_t i2; -}; - -void aubio_biquad_do(aubio_biquad_t * b, fvec_t * in) { - uint_t i,j; - lsmp_t i1 = b->i1; - lsmp_t i2 = b->i2; - lsmp_t o1 = b->o1; - lsmp_t o2 = b->o2; - lsmp_t a2 = b->a2; - lsmp_t a3 = b->a3; - lsmp_t b1 = b->b1; - lsmp_t b2 = b->b2; - lsmp_t b3 = b->b3; - - i=0; // works in mono only !!! - //for (i=0;ichannels;i++) { - for (j = 0; j < in->length; j++) { - lsmp_t i0 = in->data[i][j]; - lsmp_t o0 = b1 * i0 + b2 * i1 + b3 * i2 - - a2 * o1 - a3 * o2;// + 1e-37; - in->data[i][j] = o0; - i2 = i1; - i1 = i0; - o2 = o1; - o1 = o0; - } - b->i2 = i2; - b->i1 = i1; - b->o2 = o2; - b->o1 = o1; - //} -} - -void aubio_biquad_do_filtfilt(aubio_biquad_t * b, fvec_t * in, fvec_t * tmp) { - uint_t j,i=0; - uint_t length = in->length; - lsmp_t mir; - /* mirroring */ - mir = 2*in->data[i][0]; - b->i1 = mir - in->data[i][2]; - b->i2 = mir - in->data[i][1]; - /* apply filtering */ - aubio_biquad_do(b,in); - /* invert */ - for (j = 0; j < length; j++) - tmp->data[i][length-j-1] = in->data[i][j]; - /* mirror again */ - mir = 2*tmp->data[i][0]; - b->i1 = mir - tmp->data[i][2]; - b->i2 = mir - tmp->data[i][1]; - /* apply filtering */ - aubio_biquad_do(b,tmp); - /* invert back */ - for (j = 0; j < length; j++) - in->data[i][j] = tmp->data[i][length-j-1]; -} - -aubio_biquad_t * new_aubio_biquad( - lsmp_t b1, lsmp_t b2, lsmp_t b3, - lsmp_t a2, lsmp_t a3) { - aubio_biquad_t * b = AUBIO_NEW(aubio_biquad_t); - b->a2 = a2; - b->a3 = a3; - b->b1 = b1; - b->b2 = b2; - b->b3 = b3; - b->i1 = 0.; - b->i2 = 0.; - b->o1 = 0.; - b->o2 = 0.; - return b; -} - -void del_aubio_biquad(aubio_biquad_t * b) { - AUBIO_FREE(b); -} diff --git a/src/biquad.h b/src/biquad.h deleted file mode 100644 index 2ee3a810..00000000 --- a/src/biquad.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef BIQUAD_H -#define BIQUAD_H - -/** \file - - Second order Infinite Impulse Response filter - - This file implements a normalised biquad filter (second order IIR): - - \f$ y[n] = b_1 x[n] + b_2 x[n-1] + b_3 x[n-2] - a_2 y[n-1] - a_3 y[n-2] \f$ - - The filtfilt version runs the filter twice, forward and backward, to - compensate the phase shifting of the forward operation. - -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** biquad filter object */ -typedef struct _aubio_biquad_t aubio_biquad_t; - -/** filter input vector - - \param b biquad object as returned by new_aubio_biquad - \param in input vector to filter - -*/ -void aubio_biquad_do(aubio_biquad_t * b, fvec_t * in); -/** filter input vector forward and backward - - \param b biquad object as returned by new_aubio_biquad - \param in input vector to filter - \param tmp memory space to use for computation - -*/ -void aubio_biquad_do_filtfilt(aubio_biquad_t * b, fvec_t * in, fvec_t * tmp); -/** create new biquad filter - - \param b1 forward filter coefficient - \param b2 forward filter coefficient - \param b3 forward filter coefficient - \param a2 feedback filter coefficient - \param a3 feedback filter coefficient - -*/ -aubio_biquad_t * new_aubio_biquad(lsmp_t b1, lsmp_t b2, lsmp_t b3, lsmp_t a2, lsmp_t a3); - -/** delete biquad filter - - \param b biquad object to delete - -*/ -void del_aubio_biquad(aubio_biquad_t * b); - -#ifdef __cplusplus -} -#endif - -#endif /*BIQUAD_H*/ diff --git a/src/fft.c b/src/fft.c deleted file mode 100644 index 3521feba..00000000 --- a/src/fft.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "aubio_priv.h" -#include "fvec.h" -#include "cvec.h" -#include "mathutils.h" -#include "fft.h" - -#if FFTW3F_SUPPORT -#define fftw_malloc fftwf_malloc -#define fftw_free fftwf_free -#define fftw_execute fftwf_execute -#define fftw_plan_dft_r2c_1d fftwf_plan_dft_r2c_1d -#define fftw_plan_dft_c2r_1d fftwf_plan_dft_c2r_1d -#define fftw_plan_r2r_1d fftwf_plan_r2r_1d -#define fftw_plan fftwf_plan -#define fftw_destroy_plan fftwf_destroy_plan -#endif - -#if FFTW3F_SUPPORT -#define real_t smpl_t -#else -#define real_t lsmp_t -#endif - -struct _aubio_fft_t { - uint_t winsize; - uint_t channels; - uint_t fft_size; - real_t *in, *out; - fftw_plan pfw, pbw; - fft_data_t * specdata; /* complex spectral data */ - fvec_t * compspec; -}; - -aubio_fft_t * new_aubio_fft(uint_t winsize, uint_t channels) { - aubio_fft_t * s = AUBIO_NEW(aubio_fft_t); - 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); - /* create plans */ -#ifdef HAVE_COMPLEX_H - s->fft_size = winsize/2 + 1; - s->specdata = (fft_data_t*)fftw_malloc(sizeof(fft_data_t)*s->fft_size); - s->pfw = fftw_plan_dft_r2c_1d(winsize, s->in, s->specdata, FFTW_ESTIMATE); - s->pbw = fftw_plan_dft_c2r_1d(winsize, s->specdata, s->out, FFTW_ESTIMATE); -#else - s->fft_size = winsize; - s->specdata = (fft_data_t*)fftw_malloc(sizeof(fft_data_t)*s->fft_size); - s->pfw = fftw_plan_r2r_1d(winsize, s->in, s->specdata, FFTW_R2HC, FFTW_ESTIMATE); - s->pbw = fftw_plan_r2r_1d(winsize, s->specdata, s->out, FFTW_HC2R, FFTW_ESTIMATE); -#endif - return s; -} - -void del_aubio_fft(aubio_fft_t * s) { - /* destroy data */ - del_fvec(s->compspec); - fftw_destroy_plan(s->pfw); - fftw_destroy_plan(s->pbw); - fftw_free(s->specdata); - AUBIO_FREE(s->out); - AUBIO_FREE(s->in ); - AUBIO_FREE(s); -} - -void aubio_fft_do(aubio_fft_t * s, fvec_t * input, cvec_t * spectrum) { - aubio_fft_do_complex(s, input, s->compspec); - aubio_fft_get_spectrum(s->compspec, spectrum); -} - -void aubio_fft_rdo(aubio_fft_t * s, cvec_t * spectrum, fvec_t * output) { - aubio_fft_get_realimag(spectrum, s->compspec); - aubio_fft_rdo_complex(s, s->compspec, output); -} - -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); -#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]); -#else - for (j = 0; j < s->fft_size; j++) { - compspec->data[i][j] = s->specdata[j]; - } -#endif - } -} - -void aubio_fft_rdo_complex(aubio_fft_t * s, fvec_t * compspec, fvec_t * output) { - uint_t i, 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]; -#else - for (j=0; j < s->fft_size; j++) { - s->specdata[j] = compspec->data[i][j]; - } -#endif - fftw_execute(s->pbw); - for (j = 0; j < output->length; j++) { - output->data[i][j] = s->out[j]*renorm; - } - } -} - -void aubio_fft_get_spectrum(fvec_t * compspec, cvec_t * spectrum) { - aubio_fft_get_phas(compspec, spectrum); - aubio_fft_get_norm(compspec, spectrum); -} - -void aubio_fft_get_realimag(cvec_t * spectrum, fvec_t * compspec) { - aubio_fft_get_imag(spectrum, compspec); - aubio_fft_get_real(spectrum, compspec); -} - -void aubio_fft_get_phas(fvec_t * compspec, cvec_t * spectrum) { - uint_t i, j; - for (i = 0; i < spectrum->channels; i++) { - spectrum->phas[i][0] = 0.; - for (j=1; j < spectrum->length - 1; j++) { - spectrum->phas[i][j] = atan2f(compspec->data[i][compspec->length-j], - compspec->data[i][j]); - } - spectrum->phas[i][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] = 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] = compspec->data[i][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 / 2 + 1; j++) { - compspec->data[i][compspec->length - j] = - spectrum->norm[i][j]*SIN(spectrum->phas[i][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]); - } - } -} diff --git a/src/fft.h b/src/fft.h deleted file mode 100644 index 1737bd95..00000000 --- a/src/fft.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/** \file - - Fast Fourier Transform object - -*/ - -#ifndef FFT_H_ -#define FFT_H_ - -/* note that is not included here but only in aubio_priv.h, so that - * c++ projects can still use their own complex definition. */ -#include - -#ifdef HAVE_COMPLEX_H -#if FFTW3F_SUPPORT -#define FFTW_TYPE fftwf_complex -#else -#define FFTW_TYPE fftw_complex -#endif -#else -#if FFTW3F_SUPPORT -/** fft data type */ -#define FFTW_TYPE float -#else -/** fft data type */ -#define FFTW_TYPE double -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** fft data type */ -typedef FFTW_TYPE fft_data_t; - -/** FFT object - - This object computes forward and backward FFTs, using the complex type to - store the results. The phase vocoder or aubio_mfft_t objects should be - preferred to using directly aubio_fft_t. The FFT are computed using FFTW3 - (although support for another library could be added). - -*/ -typedef struct _aubio_fft_t aubio_fft_t; - -/** 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); -/** delete FFT object - - \param s fft object as returned by new_aubio_fft - -*/ -void del_aubio_fft(aubio_fft_t * s); - -/** compute forward FFT - - \param s fft object as returned by new_aubio_fft - \param input input signal - \param spectrum output spectrum - -*/ -void aubio_fft_do (aubio_fft_t *s, fvec_t * input, cvec_t * spectrum); -/** compute backward (inverse) FFT - - \param s fft object as returned by new_aubio_fft - \param spectrum input spectrum - \param output output signal - -*/ -void aubio_fft_rdo (aubio_fft_t *s, cvec_t * spectrum, fvec_t * output); - -/** compute forward FFT - - \param s fft object as returned by new_aubio_fft - \param input real input signal - \param compspec complex output fft real/imag - -*/ -void aubio_fft_do_complex (aubio_fft_t *s, fvec_t * input, fvec_t * compspec); -/** compute backward (inverse) FFT from real/imag - - \param s fft object as returned by new_aubio_fft - \param compspec real/imag input fft array - \param output real output array - -*/ -void aubio_fft_rdo_complex (aubio_fft_t *s, fvec_t * compspec, fvec_t * output); - -/** convert real/imag spectrum to norm/phas spectrum - - \param compspec real/imag input fft array - \param spectrum cvec norm/phas output array - -*/ -void aubio_fft_get_spectrum(fvec_t * compspec, cvec_t * spectrum); -/** convert real/imag spectrum to norm/phas spectrum - - \param compspec real/imag input fft array - \param spectrum cvec norm/phas output array - -*/ -void aubio_fft_get_realimag(cvec_t * spectrum, fvec_t * compspec); - -/** compute phas spectrum from real/imag parts - - \param compspec real/imag input fft array - \param spectrum cvec norm/phas output array - -*/ -void aubio_fft_get_phas(fvec_t * compspec, cvec_t * spectrum); -/** compute imaginary part from the norm/phas cvec - - \param spectrum norm/phas input array - \param compspec real/imag output fft array - -*/ -void aubio_fft_get_imag(cvec_t * spectrum, fvec_t * compspec); - -/** compute norm component from real/imag parts - - \param compspec real/imag input fft array - \param spectrum cvec norm/phas output array - -*/ -void aubio_fft_get_norm(fvec_t * compspec, cvec_t * spectrum); -/** compute real part from norm/phas components - - \param spectrum norm/phas input array - \param compspec real/imag output fft array - -*/ -void aubio_fft_get_real(cvec_t * spectrum, fvec_t * compspec); - -#ifdef __cplusplus -} -#endif - -#endif // FFT_H_ diff --git a/src/filter.c b/src/filter.c deleted file mode 100644 index 58c6191b..00000000 --- a/src/filter.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - - -/* Requires lsmp_t to be long or double. float will NOT give reliable - * results */ - -#include "aubio_priv.h" -#include "sample.h" -#include "mathutils.h" -#include "filter.h" - -struct _aubio_filter_t { - uint_t order; - lsmp_t * a; - lsmp_t * b; - lsmp_t * y; - lsmp_t * x; -}; - -/* bug: mono only */ -void aubio_filter_do(aubio_filter_t * f, fvec_t * in) { - uint_t i,j,l, order = f->order; - lsmp_t *x = f->x; - lsmp_t *y = f->y; - lsmp_t *a = f->a; - lsmp_t *b = f->b; - i=0;//for (i=0;ichannels;i++) { - for (j = 0; j < in->length; j++) { - /* new input */ - //AUBIO_DBG("befor %f\t", in->data[i][j]); - x[0] = in->data[i][j]; - y[0] = b[0] * x[0]; - for (l=1;ldata[i][j] = y[0]; - //AUBIO_DBG("after %f\n", in->data[i][j]); - /* store states for next sample */ - for (l=order-1; l>0; l--){ - x[l] = x[l-1]; - y[l] = y[l-1]; - } - } - /* store states for next buffer */ - f->x = x; - f->y = y; - //} -} - -void aubio_filter_do_outplace(aubio_filter_t * f, fvec_t * in, fvec_t * out) { - uint_t i,j,l, order = f->order; - lsmp_t *x = f->x; - lsmp_t *y = f->y; - lsmp_t *a = f->a; - lsmp_t *b = f->b; - - i=0; // works in mono only !!! - //for (i=0;ichannels;i++) { - for (j = 0; j < in->length; j++) { - /* new input */ - x[0] = in->data[i][j]; - y[0] = b[0] * x[0]; - for (l=1;ldata[i][j] = y[0]; - /* store for next sample */ - for (l=order-1; l>0; l--){ - x[l] = x[l-1]; - y[l] = y[l-1]; - } - } - /* store for next run */ - f->x = x; - f->y = y; - //} -} - -/* - * - * despite mirroring, end effects destroy both phse and amplitude. the longer - * the buffer, the less affected they are. - * - * replacing with zeros clicks. - * - * seems broken for order > 4 (see biquad_do_filtfilt for audible one) - */ -void aubio_filter_do_filtfilt(aubio_filter_t * f, fvec_t * in, fvec_t * tmp) { - uint_t j,i=0; - uint_t length = in->length; - //uint_t order = f->order; - //lsmp_t mir; - /* mirroring */ - //mir = 2*in->data[i][0]; - //for (j=1;jx[j] = 0.;//mir - in->data[i][order-j]; - /* apply filtering */ - aubio_filter_do(f,in); - /* invert */ - for (j = 0; j < length; j++) - tmp->data[i][length-j-1] = in->data[i][j]; - /* mirror inverted */ - //mir = 2*tmp->data[i][0]; - //for (j=1;jx[j] = 0.;//mir - tmp->data[i][order-j]; - /* apply filtering on inverted */ - aubio_filter_do(f,tmp); - /* invert back */ - for (j = 0; j < length; j++) - in->data[i][j] = tmp->data[i][length-j-1]; -} - - -aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate) { - aubio_filter_t * f = new_aubio_filter(samplerate, 7); - lsmp_t * a = f->a; - lsmp_t * b = f->b; - /* uint_t l; */ - /* for now, 44100, adsgn */ - a[0] = 1.00000000000000000000000000000000000000000000000000000; - a[1] = -4.01957618111583236952810693765059113502502441406250000; - a[2] = 6.18940644292069386267485242569819092750549316406250000; - a[3] = -4.45319890354411640487342083360999822616577148437500000; - a[4] = 1.42084294962187751565352300531230866909027099609375000; - a[5] = -0.14182547383030480458998567883099894970655441284179688; - a[6] = 0.00435117723349511334451911181986361043527722358703613; - b[0] = 0.25574112520425740235907596797915175557136535644531250; - b[1] = -0.51148225040851391653973223583307117223739624023437500; - b[2] = -0.25574112520426162120656954357400536537170410156250000; - b[3] = 1.02296450081703405032840237254276871681213378906250000; - b[4] = -0.25574112520426051098354491841746494174003601074218750; - b[5] = -0.51148225040851369449512731080176308751106262207031250; - b[6] = 0.25574112520425729133677350546349771320819854736328125; - /* DBG: filter coeffs at creation time */ - /* - for (l=0; lorder; l++){ - AUBIO_DBG("a[%d]=\t%1.16f\tb[%d]=\t%1.16f\n",l,a[l],l,b[l]); - } - */ - f->a = a; - f->b = b; - return f; -} - -aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate) { - aubio_filter_t * f = new_aubio_filter(samplerate, 5); - lsmp_t * a = f->a; - lsmp_t * b = f->b; - /* uint_t l; */ - /* for now, 44100, cdsgn */ - a[0] = 1.000000000000000000000000000000000000000000000000000000000000; - a[1] = -2.134674963687040794013682898366823792457580566406250000000000; - a[2] = 1.279333533236063358273781886964570730924606323242187500000000; - a[3] = -0.149559846089396208945743182994192466139793395996093750000000; - a[4] = 0.004908700174624848651394604104325480875559151172637939453125; - b[0] = 0.217008561949218803377448239189106971025466918945312500000000; - b[1] = -0.000000000000000222044604925031308084726333618164062500000000; - b[2] = -0.434017123898438272888711253472138196229934692382812500000000; - b[3] = 0.000000000000000402455846426619245903566479682922363281250000; - b[4] = 0.217008561949218969910901932962588034570217132568359375000000; - /* DBG: filter coeffs at creation time */ - /* - for (l=0; lorder; l++){ - AUBIO_DBG("a[%d]=\t%1.16f\tb[%d]=\t%1.16f\n",l,a[l],l,b[l]); - } - */ - f->a = a; - f->b = b; - return f; -} - -aubio_filter_t * new_aubio_filter(uint_t samplerate UNUSED, uint_t order) { - aubio_filter_t * f = AUBIO_NEW(aubio_filter_t); - lsmp_t * x = f->x; - lsmp_t * y = f->y; - lsmp_t * a = f->a; - lsmp_t * b = f->b; - uint_t l; - f->order = order; - a = AUBIO_ARRAY(lsmp_t,f->order); - b = AUBIO_ARRAY(lsmp_t,f->order); - x = AUBIO_ARRAY(lsmp_t,f->order); - y = AUBIO_ARRAY(lsmp_t,f->order); - /* initial states to zeros */ - for (l=0; lorder; l++){ - x[l] = 0.; - y[l] = 0.; - } - f->x = x; - f->y = y; - f->a = a; - f->b = b; - return f; -} - -void del_aubio_filter(aubio_filter_t * f) { - AUBIO_FREE(f->a); - AUBIO_FREE(f->b); - AUBIO_FREE(f->x); - AUBIO_FREE(f->y); - AUBIO_FREE(f); - return; -} diff --git a/src/filter.h b/src/filter.h deleted file mode 100644 index 1b0adab4..00000000 --- a/src/filter.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef FILTER_H -#define FILTER_H - -/** \file - - Infinite Impulse Response filter - - This file implements IIR filters of any order: - - \f$ y[n] = b_1 x[n] + ... + b_{order} x[n-order] - - a_2 y[n-1] - ... - a_{order} y[n-order]\f$ - - The filtfilt version runs the filter twice, forward and backward, to - compensate the phase shifting of the forward operation. - -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** IIR filter object */ -typedef struct _aubio_filter_t aubio_filter_t; - -/** filter input vector (in-place) - - \param b biquad object as returned by new_aubio_biquad - \param in input vector to filter - -*/ -void aubio_filter_do(aubio_filter_t * b, fvec_t * in); -/** filter input vector (out-of-place) - - \param b biquad object as returned by new_aubio_biquad - \param in input vector to filter - \param out output vector to store filtered input - -*/ -void aubio_filter_do_outplace(aubio_filter_t * b, fvec_t * in, fvec_t * out); -/** filter input vector forward and backward - - \param b biquad object as returned by new_aubio_biquad - \param in input vector to filter - \param tmp memory space to use for computation - -*/ -void aubio_filter_do_filtfilt(aubio_filter_t * b, fvec_t * in, fvec_t * tmp); -/** create new IIR filter - - \param samplerate signal sampling rate - \param order order of the filter (number of coefficients) - -*/ -aubio_filter_t * new_aubio_filter(uint_t samplerate, uint_t order); -/** create a new A-design filter - - \param samplerate sampling-rate of the signal to filter - -*/ -aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate); -/** create a new C-design filter - - \param samplerate sampling-rate of the signal to filter - -*/ -aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate); -/** delete a filter object - - \param f filter object to delete - -*/ -void del_aubio_filter(aubio_filter_t * f); - -#ifdef __cplusplus -} -#endif - -#endif /*FILTER_H*/ diff --git a/src/filterbank.c b/src/filterbank.c deleted file mode 100644 index c009e21e..00000000 --- a/src/filterbank.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - Copyright (C) 2007 Amaury Hazan - and Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - - -#include "aubio_priv.h" -#include "sample.h" -#include "filterbank.h" -#include "mathutils.h" - -#define VERY_SMALL_NUMBER 2e-42 - -/** \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; -}; - -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; - - /** allocating filter tables */ - fb->filters=AUBIO_ARRAY(fvec_t*,n_filters); - for (filter_cnt=0; filter_cntfilters[filter_cnt]=new_fvec(win_s, 1); - - return fb; -} - -/* -FB initialization based on Slaney's auditory toolbox -TODO: - *solve memory leak problems while - *solve quantization issues when constructing signal: - *bug for win_s=512 - *corrections for win_s=1024 -> why even filters with smaller amplitude - -*/ - -aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, uint_t samplerate, smpl_t freq_min, smpl_t freq_max){ - - aubio_filterbank_t * fb = new_aubio_filterbank(n_filters, win_s); - - - //slaney params - smpl_t lowestFrequency = 133.3333; - smpl_t linearSpacing = 66.66666666; - smpl_t logSpacing = 1.0711703; - - uint_t linearFilters = 13; - uint_t logFilters = 27; - uint_t allFilters = linearFilters + logFilters; - - //buffers for computing filter frequencies - fvec_t * freqs=new_fvec(allFilters+2 , 1); - - fvec_t * lower_freqs=new_fvec( allFilters, 1); - fvec_t * upper_freqs=new_fvec( allFilters, 1); - fvec_t * center_freqs=new_fvec( allFilters, 1); - - fvec_t * triangle_heights=new_fvec( allFilters, 1); - //lookup table of each bin frequency in hz - fvec_t * fft_freqs=new_fvec(win_s, 1); - - uint_t filter_cnt, bin_cnt; - - //first step: filling all the linear filter frequencies - for(filter_cnt=0; filter_cntdata[0][filter_cnt]=lowestFrequency+ filter_cnt*linearSpacing; - } - smpl_t lastlinearCF=freqs->data[0][filter_cnt-1]; - - //second step: filling all the log filter frequencies - for(filter_cnt=0; filter_cntdata[0][filter_cnt+linearFilters] = - lastlinearCF*(pow(logSpacing,filter_cnt+1)); - } - - //Option 1. copying interesting values to lower_freqs, center_freqs and upper freqs arrays - //TODO: would be nicer to have a reference to freqs->data, anyway we do not care in this init step - - for(filter_cnt=0; filter_cntdata[0][filter_cnt]=freqs->data[0][filter_cnt]; - center_freqs->data[0][filter_cnt]=freqs->data[0][filter_cnt+1]; - upper_freqs->data[0][filter_cnt]=freqs->data[0][filter_cnt+2]; - } - - //computing triangle heights so that each triangle has unit area - for(filter_cnt=0; filter_cntdata[0][filter_cnt] = 2./(upper_freqs->data[0][filter_cnt] - - lower_freqs->data[0][filter_cnt]); - } - - //AUBIO_DBG("filter tables frequencies\n"); - //for(filter_cnt=0; filter_cntdata[0][filter_cnt], - // center_freqs->data[0][filter_cnt], upper_freqs->data[0][filter_cnt], - // triangle_heights->data[0][filter_cnt]); - - //filling the fft_freqs lookup table, which assigns the frequency in hz to each bin - for(bin_cnt=0; bin_cntdata[0][bin_cnt]= aubio_bintofreq(bin_cnt, samplerate, win_s); - } - - //building each filter table - for(filter_cnt=0; filter_cntdata[0][filter_cnt]/(center_freqs->data[0][filter_cnt]-lower_freqs->data[0][filter_cnt]); - - //zeroing begining of filter - for(bin_cnt=0; bin_cntfilters[filter_cnt]->data[0][bin_cnt]=0.f; - if( fft_freqs->data[0][bin_cnt] <= lower_freqs->data[0][filter_cnt] && - fft_freqs->data[0][bin_cnt+1] > lower_freqs->data[0][filter_cnt]) { - break; - } - } - bin_cnt++; - - //positive slope - for(; bin_cntfilters[filter_cnt]->data[0][bin_cnt]=(fft_freqs->data[0][bin_cnt]-lower_freqs->data[0][filter_cnt])*riseInc; - //if(fft_freqs->data[0][bin_cnt]<= center_freqs->data[0][filter_cnt] && fft_freqs->data[0][bin_cnt+1]> center_freqs->data[0][filter_cnt]) - if(fft_freqs->data[0][bin_cnt+1]> center_freqs->data[0][filter_cnt]) - break; - } - //bin_cnt++; - - //negative slope - for(; bin_cntdata[0][filter_cnt]-(fft_freqs->data[0][bin_cnt]-center_freqs->data[0][filter_cnt])*riseInc; - if(val>=0) - fb->filters[filter_cnt]->data[0][bin_cnt]=val; - else fb->filters[filter_cnt]->data[0][bin_cnt]=0.f; - - //if(fft_freqs->data[0][bin_cnt]<= upper_freqs->data[0][bin_cnt] && fft_freqs->data[0][bin_cnt+1]> upper_freqs->data[0][filter_cnt]) - //TODO: CHECK whether bugfix correct - if(fft_freqs->data[0][bin_cnt+1]> upper_freqs->data[0][filter_cnt]) - break; - } - //bin_cnt++; - - //zeroing tail - for(; bin_cntfilters[filter_cnt]->data[0][bin_cnt]=0.f; - - } - - - del_fvec(freqs); - del_fvec(lower_freqs); - del_fvec(upper_freqs); - del_fvec(center_freqs); - - del_fvec(triangle_heights); - del_fvec(fft_freqs); - - return fb; - -} - -void del_aubio_filterbank(aubio_filterbank_t * fb){ - uint_t filter_cnt; - /** deleting filter tables first */ - for (filter_cnt=0; filter_cntn_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; -} - -fvec_t * aubio_filterbank_getchannel(aubio_filterbank_t * f, uint_t channel) { - if ( (channel < f->n_filters) ) { return f->filters[channel]; } - else { return NULL; } -} diff --git a/src/filterbank.h b/src/filterbank.h deleted file mode 100644 index 84c5ab6a..00000000 --- a/src/filterbank.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (C) 2007 Amaury Hazan - and Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/** \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 - -/** filterbank object */ -typedef struct aubio_filterbank_t_ aubio_filterbank_t; - -/** create filterbank object - - \param win_s size of analysis buffer (and length the FFT transform) - \param n_filters number of filters to create - -*/ - -aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s); - -/** filterbank initialization for mel filters - - - \param n_filters number of filters - \param win_s window size - \param samplerate - \param freq_min lowest filter frequency - \param freq_max highest filter frequency - -*/ -aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, uint_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); - -/** return the vector containing the filter coefficients of one channel - - */ -fvec_t * aubio_filterbank_getchannel(aubio_filterbank_t * f, uint_t channel); - -#ifdef __cplusplus -} -#endif - -#endif // FILTERBANK_H diff --git a/src/hist.c b/src/hist.c deleted file mode 100644 index e97287b4..00000000 --- a/src/hist.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "aubio_priv.h" -#include "sample.h" -#include "scale.h" -#include "mathutils.h" //vec_min vec_max -#include "hist.h" - -/******** - * Object Structure - */ - -struct _aubio_hist_t { - fvec_t * hist; - uint_t nelems; - uint_t channels; - fvec_t * cent; - aubio_scale_t *scaler; -}; - -/** - * Object creation/deletion calls - */ -aubio_hist_t * new_aubio_hist (smpl_t ilow, smpl_t ihig, uint_t nelems, uint_t channels){ - aubio_hist_t * s = AUBIO_NEW(aubio_hist_t); - smpl_t step = (ihig-ilow)/(smpl_t)(nelems); - smpl_t accum = step; - uint_t i; - s->channels = channels; - s->nelems = nelems; - s->hist = new_fvec(nelems, channels); - s->cent = new_fvec(nelems, 1); - - /* use scale to map ilow/ihig -> 0/nelems */ - s->scaler = new_aubio_scale(ilow,ihig,0,nelems); - /* calculate centers now once */ - s->cent->data[0][0] = ilow + 0.5 * step; - for (i=1; i < s->nelems; i++, accum+=step ) - s->cent->data[0][i] = s->cent->data[0][0] + accum; - - return s; -} - -void del_aubio_hist(aubio_hist_t *s) { - del_fvec(s->hist); - del_fvec(s->cent); - del_aubio_scale(s->scaler); - AUBIO_FREE(s); -} - -/*** - * do it - */ -void aubio_hist_do (aubio_hist_t *s, fvec_t *input) { - uint_t i,j; - sint_t tmp = 0; - aubio_scale_do(s->scaler, input); - /* reset data */ - for (i=0; i < s->channels; i++) - for (j=0; j < s->nelems; j++) - s->hist->data[i][j] = 0; - /* run accum */ - for (i=0; i < input->channels; i++) - for (j=0; j < input->length; j++) - { - tmp = (sint_t)FLOOR(input->data[i][j]); - if ((tmp >= 0) && (tmp < (sint_t)s->nelems)) - s->hist->data[i][tmp] += 1; - } -} - -void aubio_hist_do_notnull (aubio_hist_t *s, fvec_t *input) { - uint_t i,j; - sint_t tmp = 0; - aubio_scale_do(s->scaler, input); - /* reset data */ - for (i=0; i < s->channels; i++) - for (j=0; j < s->nelems; j++) - s->hist->data[i][j] = 0; - /* run accum */ - for (i=0; i < input->channels; i++) - for (j=0; j < input->length; j++) { - if (input->data[i][j] != 0) { - tmp = (sint_t)FLOOR(input->data[i][j]); - if ((tmp >= 0) && (tmp < (sint_t)s->nelems)) - s->hist->data[i][tmp] += 1; - } - } -} - - -void aubio_hist_dyn_notnull (aubio_hist_t *s, fvec_t *input) { - uint_t i,j; - sint_t tmp = 0; - smpl_t ilow = vec_min(input); - smpl_t ihig = vec_max(input); - smpl_t step = (ihig-ilow)/(smpl_t)(s->nelems); - - /* readapt */ - aubio_scale_set(s->scaler, ilow, ihig, 0, s->nelems); - - /* recalculate centers */ - s->cent->data[0][0] = ilow + 0.5f * step; - for (i=1; i < s->nelems; i++) - s->cent->data[0][i] = s->cent->data[0][0] + i * step; - - /* scale */ - aubio_scale_do(s->scaler, input); - - /* reset data */ - for (i=0; i < s->channels; i++) - for (j=0; j < s->nelems; j++) - s->hist->data[i][j] = 0; - /* run accum */ - for (i=0; i < input->channels; i++) - for (j=0; j < input->length; j++) { - if (input->data[i][j] != 0) { - tmp = (sint_t)FLOOR(input->data[i][j]); - if ((tmp >= 0) && (tmp < (sint_t)s->nelems)) - s->hist->data[i][tmp] += 1; - } - } -} - -void aubio_hist_weight (aubio_hist_t *s) { - uint_t i,j; - for (i=0; i < s->channels; i++) - for (j=0; j < s->nelems; j++) { - s->hist->data[i][j] *= s->cent->data[0][j]; - } -} - -smpl_t aubio_hist_mean (aubio_hist_t *s) { - uint_t i,j; - smpl_t tmp = 0.0f; - for (i=0; i < s->channels; i++) - for (j=0; j < s->nelems; j++) - tmp += s->hist->data[i][j]; - return tmp/(smpl_t)(s->nelems); -} - diff --git a/src/hist.h b/src/hist.h deleted file mode 100644 index 85cfbddb..00000000 --- a/src/hist.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/** @file - * - * Histogram function - * - * Big hacks to implement an histogram - */ - -#ifndef HIST_H -#define HIST_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** histogram object */ -typedef struct _aubio_hist_t aubio_hist_t; - -/** histogram creation - * \param flow minimum input - * \param fhig maximum input - * \param nelems number of histogram columns - * \param channels number of channels - */ -aubio_hist_t * new_aubio_hist(smpl_t flow, smpl_t fhig, uint_t nelems, uint_t channels); -/** histogram deletion */ -void del_aubio_hist(aubio_hist_t *s); -/** compute the histogram */ -void aubio_hist_do(aubio_hist_t *s, fvec_t * input); -/** compute the histogram ignoring null elements */ -void aubio_hist_do_notnull(aubio_hist_t *s, fvec_t * input); -/** compute the mean of the histogram */ -smpl_t aubio_hist_mean(aubio_hist_t *s); -/** weight the histogram */ -void aubio_hist_weight(aubio_hist_t *s); -/** compute dynamic histogram for non-null elements */ -void aubio_hist_dyn_notnull (aubio_hist_t *s, fvec_t *input); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/mfcc.c b/src/mfcc.c deleted file mode 100644 index 2420d803..00000000 --- a/src/mfcc.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - Copyright (C) 2006 Amaury Hazan - Ported to aubio from LibXtract - http://libxtract.sourceforge.net/ - - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "aubio_priv.h" -#include "sample.h" -#include "fft.h" -#include "filterbank.h" -#include "mfcc.h" -#include "math.h" - -/** Internal structure for mfcc object **/ - -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_fft_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); - - //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; - - - /** filterbank allocation */ - mfcc->fb = new_aubio_filterbank_mfcc(n_filters, mfcc->win_s, samplerate, lowfreq, highfreq); - - /** allocating space for fft object (used for dct) */ - mfcc->fft_dct=new_aubio_fft(n_filters, 1); - - /** allocating buffers */ - mfcc->in_dct=new_fvec(mfcc->win_s, 1); - - mfcc->fftgrain_dct=new_cvec(n_filters, 1); - - return mfcc; -}; - -void del_aubio_mfcc(aubio_mfcc_t *mf){ - /** deleting filterbank */ - del_aubio_filterbank(mf->fb); - /** deleting fft object */ - del_aubio_fft(mf->fft_dct); - /** deleting buffers */ - del_fvec(mf->in_dct); - del_cvec(mf->fftgrain_dct); - - /** deleting mfcc object */ - AUBIO_FREE(mf); -} - - -/** intermediate dct involved in aubio_mfcc_do - - \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) - -*/ -void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out); - -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; - - aubio_dct_do(mf, mf->in_dct, out); - - return; -} - -void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out){ - uint_t i; - //compute mag spectrum - aubio_fft_do (mf->fft_dct, in, mf->fftgrain_dct); - //extract real part of fft grain - for(i=0; in_coefs ;i++){ - //for(i=0; ilength;i++){ - out->data[0][i]= mf->fftgrain_dct->norm[0][i] - *COS(mf->fftgrain_dct->phas[0][i]); - } - return; -} - diff --git a/src/mfcc.h b/src/mfcc.h deleted file mode 100644 index 6acc6cd2..00000000 --- a/src/mfcc.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 2007 Amaury Hazan - and Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/* part of this mfcc implementation were inspired from LibXtract - http://libxtract.sourceforge.net/ -*/ - -#ifndef MFCC_H -#define MFCC_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "sample.h" -#include "filterbank.h" - -typedef struct aubio_mfcc_t_ aubio_mfcc_t; - -/** create mfcc object - - \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 - -*/ -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 - - \param mf mfcc object as returned by new_aubio_mfcc - -*/ -void del_aubio_mfcc(aubio_mfcc_t *mf); -/** mfcc object processing - - \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) - -*/ -void aubio_mfcc_do(aubio_mfcc_t * mf, cvec_t *in, fvec_t *out); - -#ifdef __cplusplus -} -#endif - -#endif // MFCC_H diff --git a/src/onset/onset.c b/src/onset/onset.c index e4bc5dde..084f8de7 100644 --- a/src/onset/onset.c +++ b/src/onset/onset.c @@ -20,10 +20,10 @@ #include "aubio_priv.h" #include "sample.h" #include "onset/onsetdetection.h" -#include "phasevoc.h" -#include "peakpick.h" +#include "spectral/phasevoc.h" +#include "onset/peakpick.h" #include "mathutils.h" -#include "onset.h" +#include "onset/onset.h" /** structure to store object state */ struct _aubio_onset_t { diff --git a/src/onset/onsetdetection.c b/src/onset/onsetdetection.c index 2e4b1bae..0dd52cf1 100644 --- a/src/onset/onsetdetection.c +++ b/src/onset/onsetdetection.c @@ -19,9 +19,9 @@ #include "aubio_priv.h" #include "sample.h" -#include "fft.h" +#include "spectral/fft.h" #include "mathutils.h" -#include "hist.h" +#include "utils/hist.h" #include "onset/onsetdetection.h" diff --git a/src/onset/peakpick.c b/src/onset/peakpick.c index 9f128e87..f9c93369 100644 --- a/src/onset/peakpick.c +++ b/src/onset/peakpick.c @@ -20,8 +20,8 @@ #include "aubio_priv.h" #include "sample.h" #include "mathutils.h" -#include "biquad.h" -#include "peakpick.h" +#include "temporal/biquad.h" +#include "onset/peakpick.h" /* peak picking parameters, default values in brackets * diff --git a/src/phasevoc.c b/src/phasevoc.c deleted file mode 100644 index b04b106f..00000000 --- a/src/phasevoc.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "aubio_priv.h" -#include "fvec.h" -#include "cvec.h" -#include "fft.h" -#include "mathutils.h" -#include "phasevoc.h" - -/** phasevocoder internal object */ -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] */ - fvec_t * data; /** current input grain [win_s] */ - fvec_t * dataold; /** last input frame [win_s-hop_s] */ - smpl_t * w; /** grain window [win_s] */ -}; - - -/** returns data and dataold slided by 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); - -/** do additive synthesis from 'old' and 'cur' */ -static void aubio_pvoc_addsynth(const smpl_t * synth, smpl_t * synthold, - 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,j; - for (i=0; ichannels; i++) { - /* slide */ - aubio_pvoc_swapbuffers(pv->data->data[i],pv->dataold->data[i], - datanew->data[i],pv->win_s,pv->hop_s); - /* windowing */ - for (j=0; jwin_s; j++) pv->data->data[i][j] *= pv->w[j]; - } - /* shift */ - vec_shift(pv->data); - /* calculate fft */ - aubio_fft_do (pv->fft,pv->data,fftgrain); -} - -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 */ - vec_shift(pv->synth); - for (i=0; ichannels; i++) { - aubio_pvoc_addsynth(pv->synth->data[i],pv->synthold->data[i], - synthnew->data[i],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 * pv = AUBIO_NEW(aubio_pvoc_t); - - if (win_s < 2*hop_s) { - 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"); - AUBIO_ERR("Resetting hop size to half the window size.\n"); - hop_s = win_s / 2; - } - - pv->fft = new_aubio_fft(win_s,channels); - - /* remember old */ - pv->data = new_fvec (win_s, channels); - pv->synth = new_fvec (win_s, channels); - - /* new input output */ - 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); - aubio_window(pv->w,win_s,aubio_win_hanningz); - - pv->channels = channels; - pv->hop_s = hop_s; - pv->win_s = win_s; - - return pv; -} - -void del_aubio_pvoc(aubio_pvoc_t *pv) { - del_fvec(pv->data); - del_fvec(pv->synth); - del_fvec(pv->dataold); - del_fvec(pv->synthold); - del_aubio_fft(pv->fft); - AUBIO_FREE(pv->w); - 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) -{ - uint_t i; - for (i=0;i /* from libsamplerate */ - -#include "aubio_priv.h" -#include "sample.h" -#include "resample.h" - -struct _aubio_resampler_t { - SRC_DATA *proc; - SRC_STATE *stat; - float ratio; - uint_t type; -}; - -aubio_resampler_t * new_aubio_resampler(float ratio, uint_t type) { - aubio_resampler_t * s = AUBIO_NEW(aubio_resampler_t); - int error = 0; - s->stat = src_new (type, 1, &error) ; /* only one channel */ - s->proc = AUBIO_NEW(SRC_DATA); - if (error) AUBIO_ERR("%s\n",src_strerror(error)); - s->ratio = ratio; - return s; -} - -void del_aubio_resampler(aubio_resampler_t *s) { - src_delete(s->stat); - AUBIO_FREE(s->proc); - AUBIO_FREE(s); -} - -uint_t aubio_resampler_process(aubio_resampler_t *s, - fvec_t * input, fvec_t * output) { - uint_t i ; - s->proc->input_frames = input->length; - s->proc->output_frames = output->length; - s->proc->src_ratio = s->ratio; - for (i = 0 ; i< input->channels; i++) - { - /* make SRC_PROC data point to input outputs */ - s->proc->data_in = input->data[i]; - s->proc->data_out= output->data[i]; - /* do resampling */ - src_process (s->stat, s->proc) ; - } - return AUBIO_OK; -} diff --git a/src/resample.h b/src/resample.h deleted file mode 100644 index d4449ca3..00000000 --- a/src/resample.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef _RESAMPLE_H -#define _RESAMPLE_H - -/** \file - - Resampling object - - This object resamples an input vector into an output vector using - libsamplerate. See http://www.mega-nerd.com/SRC/ - -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** resampler object */ -typedef struct _aubio_resampler_t aubio_resampler_t; -/** create resampler object - - \param ratio output_sample_rate / input_sample_rate - \param type libsamplerate resampling type - -*/ -aubio_resampler_t * new_aubio_resampler(float ratio, uint_t type); -/** delete resampler object */ -void del_aubio_resampler(aubio_resampler_t *s); -/** resample input in output - - \param s resampler object - \param input input buffer of size N - \param output output buffer of size N*ratio - -*/ -uint_t aubio_resampler_process(aubio_resampler_t *s, fvec_t * input, fvec_t * output); - -#ifdef __cplusplus -} -#endif - -#endif /* _RESAMPLE_H */ diff --git a/src/scale.c b/src/scale.c deleted file mode 100644 index dff32b03..00000000 --- a/src/scale.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "aubio_priv.h" -#include "sample.h" -#include "scale.h" - -struct _aubio_scale_t { - smpl_t ilow; - smpl_t ihig; - smpl_t olow; - smpl_t ohig; - - smpl_t scaler; - smpl_t irange; - - /* not implemented yet : type in/out data - bool inint; - bool outint; - */ -}; - -aubio_scale_t * new_aubio_scale (smpl_t ilow, smpl_t ihig, - smpl_t olow, smpl_t ohig) { - aubio_scale_t * s = AUBIO_NEW(aubio_scale_t); - aubio_scale_set (s, ilow, ihig, olow, ohig); - return s; -} - -void del_aubio_scale(aubio_scale_t *s) { - AUBIO_FREE(s); -} - -void aubio_scale_set (aubio_scale_t *s, smpl_t ilow, smpl_t ihig, - smpl_t olow, smpl_t ohig) { - smpl_t inputrange = ihig - ilow; - smpl_t outputrange= ohig - olow; - s->ilow = ilow; - s->ihig = ihig; - s->olow = olow; - s->ohig = ohig; - if (inputrange == 0) { - s->scaler = 0.0f; - } else { - s->scaler = outputrange/inputrange; - if (inputrange < 0) { - inputrange = inputrange * -1.0f; - } - } -} - -void aubio_scale_do (aubio_scale_t *s, fvec_t *input) -{ - uint_t i, j; - for (i=0; i < input->channels; i++){ - for (j=0; j < input->length; j++){ - input->data[i][j] -= s->ilow; - input->data[i][j] *= s->scaler; - input->data[i][j] += s->olow; - } - } -} - diff --git a/src/scale.h b/src/scale.h deleted file mode 100644 index 226bb74a..00000000 --- a/src/scale.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/** \file - - Vector scaling function - - This object, inspired from the scale object in FTS, the jMax engine, scales - the values of a vector according to an affine function defined as follow: - - \f$ y = (x - ilow)*(ohig-olow)/(ihig-ilow) + olow \f$ - -*/ -#ifndef SCALE_H -#define SCALE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** scale object */ -typedef struct _aubio_scale_t aubio_scale_t; - -/** create a scale object - - \param flow lower value of output function - \param fhig higher value of output function - \param ilow lower value of input function - \param ihig higher value of output function - -*/ -aubio_scale_t * new_aubio_scale(smpl_t flow, smpl_t fhig, - smpl_t ilow, smpl_t ihig); -/** delete a scale object - - \param s scale object as returned by new_aubio_scale - -*/ -void del_aubio_scale(aubio_scale_t *s); -/** scale input vector - - \param s scale object as returned by new_aubio_scale - \param input vector to scale - -*/ -void aubio_scale_do(aubio_scale_t *s, fvec_t * input); -/** modify scale parameters after object creation - - \param s scale object as returned by new_aubio_scale - \param olow lower value of output function - \param ohig higher value of output function - \param ilow lower value of input function - \param ihig higher value of output function - -*/ -void aubio_scale_set (aubio_scale_t *s, smpl_t ilow, smpl_t ihig, - smpl_t olow, smpl_t ohig); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/spectral/fft.c b/src/spectral/fft.c new file mode 100644 index 00000000..8bff6ac1 --- /dev/null +++ b/src/spectral/fft.c @@ -0,0 +1,194 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "cvec.h" +#include "mathutils.h" +#include "spectral/fft.h" + +#if FFTW3F_SUPPORT +#define fftw_malloc fftwf_malloc +#define fftw_free fftwf_free +#define fftw_execute fftwf_execute +#define fftw_plan_dft_r2c_1d fftwf_plan_dft_r2c_1d +#define fftw_plan_dft_c2r_1d fftwf_plan_dft_c2r_1d +#define fftw_plan_r2r_1d fftwf_plan_r2r_1d +#define fftw_plan fftwf_plan +#define fftw_destroy_plan fftwf_destroy_plan +#endif + +#if FFTW3F_SUPPORT +#define real_t smpl_t +#else +#define real_t lsmp_t +#endif + +struct _aubio_fft_t { + uint_t winsize; + uint_t channels; + uint_t fft_size; + real_t *in, *out; + fftw_plan pfw, pbw; + fft_data_t * specdata; /* complex spectral data */ + fvec_t * compspec; +}; + +aubio_fft_t * new_aubio_fft(uint_t winsize, uint_t channels) { + aubio_fft_t * s = AUBIO_NEW(aubio_fft_t); + 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); + /* create plans */ +#ifdef HAVE_COMPLEX_H + s->fft_size = winsize/2 + 1; + s->specdata = (fft_data_t*)fftw_malloc(sizeof(fft_data_t)*s->fft_size); + s->pfw = fftw_plan_dft_r2c_1d(winsize, s->in, s->specdata, FFTW_ESTIMATE); + s->pbw = fftw_plan_dft_c2r_1d(winsize, s->specdata, s->out, FFTW_ESTIMATE); +#else + s->fft_size = winsize; + s->specdata = (fft_data_t*)fftw_malloc(sizeof(fft_data_t)*s->fft_size); + s->pfw = fftw_plan_r2r_1d(winsize, s->in, s->specdata, FFTW_R2HC, FFTW_ESTIMATE); + s->pbw = fftw_plan_r2r_1d(winsize, s->specdata, s->out, FFTW_HC2R, FFTW_ESTIMATE); +#endif + return s; +} + +void del_aubio_fft(aubio_fft_t * s) { + /* destroy data */ + del_fvec(s->compspec); + fftw_destroy_plan(s->pfw); + fftw_destroy_plan(s->pbw); + fftw_free(s->specdata); + AUBIO_FREE(s->out); + AUBIO_FREE(s->in ); + AUBIO_FREE(s); +} + +void aubio_fft_do(aubio_fft_t * s, fvec_t * input, cvec_t * spectrum) { + aubio_fft_do_complex(s, input, s->compspec); + aubio_fft_get_spectrum(s->compspec, spectrum); +} + +void aubio_fft_rdo(aubio_fft_t * s, cvec_t * spectrum, fvec_t * output) { + aubio_fft_get_realimag(spectrum, s->compspec); + aubio_fft_rdo_complex(s, s->compspec, output); +} + +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); +#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]); +#else + for (j = 0; j < s->fft_size; j++) { + compspec->data[i][j] = s->specdata[j]; + } +#endif + } +} + +void aubio_fft_rdo_complex(aubio_fft_t * s, fvec_t * compspec, fvec_t * output) { + uint_t i, 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]; +#else + for (j=0; j < s->fft_size; j++) { + s->specdata[j] = compspec->data[i][j]; + } +#endif + fftw_execute(s->pbw); + for (j = 0; j < output->length; j++) { + output->data[i][j] = s->out[j]*renorm; + } + } +} + +void aubio_fft_get_spectrum(fvec_t * compspec, cvec_t * spectrum) { + aubio_fft_get_phas(compspec, spectrum); + aubio_fft_get_norm(compspec, spectrum); +} + +void aubio_fft_get_realimag(cvec_t * spectrum, fvec_t * compspec) { + aubio_fft_get_imag(spectrum, compspec); + aubio_fft_get_real(spectrum, compspec); +} + +void aubio_fft_get_phas(fvec_t * compspec, cvec_t * spectrum) { + uint_t i, j; + for (i = 0; i < spectrum->channels; i++) { + spectrum->phas[i][0] = 0.; + for (j=1; j < spectrum->length - 1; j++) { + spectrum->phas[i][j] = atan2f(compspec->data[i][compspec->length-j], + compspec->data[i][j]); + } + spectrum->phas[i][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] = 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] = compspec->data[i][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 / 2 + 1; j++) { + compspec->data[i][compspec->length - j] = + spectrum->norm[i][j]*SIN(spectrum->phas[i][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]); + } + } +} diff --git a/src/spectral/fft.h b/src/spectral/fft.h new file mode 100644 index 00000000..1737bd95 --- /dev/null +++ b/src/spectral/fft.h @@ -0,0 +1,163 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/** \file + + Fast Fourier Transform object + +*/ + +#ifndef FFT_H_ +#define FFT_H_ + +/* note that is not included here but only in aubio_priv.h, so that + * c++ projects can still use their own complex definition. */ +#include + +#ifdef HAVE_COMPLEX_H +#if FFTW3F_SUPPORT +#define FFTW_TYPE fftwf_complex +#else +#define FFTW_TYPE fftw_complex +#endif +#else +#if FFTW3F_SUPPORT +/** fft data type */ +#define FFTW_TYPE float +#else +/** fft data type */ +#define FFTW_TYPE double +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** fft data type */ +typedef FFTW_TYPE fft_data_t; + +/** FFT object + + This object computes forward and backward FFTs, using the complex type to + store the results. The phase vocoder or aubio_mfft_t objects should be + preferred to using directly aubio_fft_t. The FFT are computed using FFTW3 + (although support for another library could be added). + +*/ +typedef struct _aubio_fft_t aubio_fft_t; + +/** 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); +/** delete FFT object + + \param s fft object as returned by new_aubio_fft + +*/ +void del_aubio_fft(aubio_fft_t * s); + +/** compute forward FFT + + \param s fft object as returned by new_aubio_fft + \param input input signal + \param spectrum output spectrum + +*/ +void aubio_fft_do (aubio_fft_t *s, fvec_t * input, cvec_t * spectrum); +/** compute backward (inverse) FFT + + \param s fft object as returned by new_aubio_fft + \param spectrum input spectrum + \param output output signal + +*/ +void aubio_fft_rdo (aubio_fft_t *s, cvec_t * spectrum, fvec_t * output); + +/** compute forward FFT + + \param s fft object as returned by new_aubio_fft + \param input real input signal + \param compspec complex output fft real/imag + +*/ +void aubio_fft_do_complex (aubio_fft_t *s, fvec_t * input, fvec_t * compspec); +/** compute backward (inverse) FFT from real/imag + + \param s fft object as returned by new_aubio_fft + \param compspec real/imag input fft array + \param output real output array + +*/ +void aubio_fft_rdo_complex (aubio_fft_t *s, fvec_t * compspec, fvec_t * output); + +/** convert real/imag spectrum to norm/phas spectrum + + \param compspec real/imag input fft array + \param spectrum cvec norm/phas output array + +*/ +void aubio_fft_get_spectrum(fvec_t * compspec, cvec_t * spectrum); +/** convert real/imag spectrum to norm/phas spectrum + + \param compspec real/imag input fft array + \param spectrum cvec norm/phas output array + +*/ +void aubio_fft_get_realimag(cvec_t * spectrum, fvec_t * compspec); + +/** compute phas spectrum from real/imag parts + + \param compspec real/imag input fft array + \param spectrum cvec norm/phas output array + +*/ +void aubio_fft_get_phas(fvec_t * compspec, cvec_t * spectrum); +/** compute imaginary part from the norm/phas cvec + + \param spectrum norm/phas input array + \param compspec real/imag output fft array + +*/ +void aubio_fft_get_imag(cvec_t * spectrum, fvec_t * compspec); + +/** compute norm component from real/imag parts + + \param compspec real/imag input fft array + \param spectrum cvec norm/phas output array + +*/ +void aubio_fft_get_norm(fvec_t * compspec, cvec_t * spectrum); +/** compute real part from norm/phas components + + \param spectrum norm/phas input array + \param compspec real/imag output fft array + +*/ +void aubio_fft_get_real(cvec_t * spectrum, fvec_t * compspec); + +#ifdef __cplusplus +} +#endif + +#endif // FFT_H_ diff --git a/src/spectral/filterbank.c b/src/spectral/filterbank.c new file mode 100644 index 00000000..aa1336bf --- /dev/null +++ b/src/spectral/filterbank.c @@ -0,0 +1,218 @@ +/* + Copyright (C) 2007 Amaury Hazan + and Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#include "aubio_priv.h" +#include "sample.h" +#include "spectral/filterbank.h" +#include "mathutils.h" + +#define VERY_SMALL_NUMBER 2e-42 + +/** \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; +}; + +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; + + /** allocating filter tables */ + fb->filters=AUBIO_ARRAY(fvec_t*,n_filters); + for (filter_cnt=0; filter_cntfilters[filter_cnt]=new_fvec(win_s, 1); + + return fb; +} + +/* +FB initialization based on Slaney's auditory toolbox +TODO: + *solve memory leak problems while + *solve quantization issues when constructing signal: + *bug for win_s=512 + *corrections for win_s=1024 -> why even filters with smaller amplitude + +*/ + +aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, uint_t samplerate, smpl_t freq_min, smpl_t freq_max){ + + aubio_filterbank_t * fb = new_aubio_filterbank(n_filters, win_s); + + + //slaney params + smpl_t lowestFrequency = 133.3333; + smpl_t linearSpacing = 66.66666666; + smpl_t logSpacing = 1.0711703; + + uint_t linearFilters = 13; + uint_t logFilters = 27; + uint_t allFilters = linearFilters + logFilters; + + //buffers for computing filter frequencies + fvec_t * freqs=new_fvec(allFilters+2 , 1); + + fvec_t * lower_freqs=new_fvec( allFilters, 1); + fvec_t * upper_freqs=new_fvec( allFilters, 1); + fvec_t * center_freqs=new_fvec( allFilters, 1); + + fvec_t * triangle_heights=new_fvec( allFilters, 1); + //lookup table of each bin frequency in hz + fvec_t * fft_freqs=new_fvec(win_s, 1); + + uint_t filter_cnt, bin_cnt; + + //first step: filling all the linear filter frequencies + for(filter_cnt=0; filter_cntdata[0][filter_cnt]=lowestFrequency+ filter_cnt*linearSpacing; + } + smpl_t lastlinearCF=freqs->data[0][filter_cnt-1]; + + //second step: filling all the log filter frequencies + for(filter_cnt=0; filter_cntdata[0][filter_cnt+linearFilters] = + lastlinearCF*(pow(logSpacing,filter_cnt+1)); + } + + //Option 1. copying interesting values to lower_freqs, center_freqs and upper freqs arrays + //TODO: would be nicer to have a reference to freqs->data, anyway we do not care in this init step + + for(filter_cnt=0; filter_cntdata[0][filter_cnt]=freqs->data[0][filter_cnt]; + center_freqs->data[0][filter_cnt]=freqs->data[0][filter_cnt+1]; + upper_freqs->data[0][filter_cnt]=freqs->data[0][filter_cnt+2]; + } + + //computing triangle heights so that each triangle has unit area + for(filter_cnt=0; filter_cntdata[0][filter_cnt] = 2./(upper_freqs->data[0][filter_cnt] + - lower_freqs->data[0][filter_cnt]); + } + + //AUBIO_DBG("filter tables frequencies\n"); + //for(filter_cnt=0; filter_cntdata[0][filter_cnt], + // center_freqs->data[0][filter_cnt], upper_freqs->data[0][filter_cnt], + // triangle_heights->data[0][filter_cnt]); + + //filling the fft_freqs lookup table, which assigns the frequency in hz to each bin + for(bin_cnt=0; bin_cntdata[0][bin_cnt]= aubio_bintofreq(bin_cnt, samplerate, win_s); + } + + //building each filter table + for(filter_cnt=0; filter_cntdata[0][filter_cnt]/(center_freqs->data[0][filter_cnt]-lower_freqs->data[0][filter_cnt]); + + //zeroing begining of filter + for(bin_cnt=0; bin_cntfilters[filter_cnt]->data[0][bin_cnt]=0.f; + if( fft_freqs->data[0][bin_cnt] <= lower_freqs->data[0][filter_cnt] && + fft_freqs->data[0][bin_cnt+1] > lower_freqs->data[0][filter_cnt]) { + break; + } + } + bin_cnt++; + + //positive slope + for(; bin_cntfilters[filter_cnt]->data[0][bin_cnt]=(fft_freqs->data[0][bin_cnt]-lower_freqs->data[0][filter_cnt])*riseInc; + //if(fft_freqs->data[0][bin_cnt]<= center_freqs->data[0][filter_cnt] && fft_freqs->data[0][bin_cnt+1]> center_freqs->data[0][filter_cnt]) + if(fft_freqs->data[0][bin_cnt+1]> center_freqs->data[0][filter_cnt]) + break; + } + //bin_cnt++; + + //negative slope + for(; bin_cntdata[0][filter_cnt]-(fft_freqs->data[0][bin_cnt]-center_freqs->data[0][filter_cnt])*riseInc; + if(val>=0) + fb->filters[filter_cnt]->data[0][bin_cnt]=val; + else fb->filters[filter_cnt]->data[0][bin_cnt]=0.f; + + //if(fft_freqs->data[0][bin_cnt]<= upper_freqs->data[0][bin_cnt] && fft_freqs->data[0][bin_cnt+1]> upper_freqs->data[0][filter_cnt]) + //TODO: CHECK whether bugfix correct + if(fft_freqs->data[0][bin_cnt+1]> upper_freqs->data[0][filter_cnt]) + break; + } + //bin_cnt++; + + //zeroing tail + for(; bin_cntfilters[filter_cnt]->data[0][bin_cnt]=0.f; + + } + + + del_fvec(freqs); + del_fvec(lower_freqs); + del_fvec(upper_freqs); + del_fvec(center_freqs); + + del_fvec(triangle_heights); + del_fvec(fft_freqs); + + return fb; + +} + +void del_aubio_filterbank(aubio_filterbank_t * fb){ + uint_t filter_cnt; + /** deleting filter tables first */ + for (filter_cnt=0; filter_cntn_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; +} + +fvec_t * aubio_filterbank_getchannel(aubio_filterbank_t * f, uint_t channel) { + if ( (channel < f->n_filters) ) { return f->filters[channel]; } + else { return NULL; } +} diff --git a/src/spectral/filterbank.h b/src/spectral/filterbank.h new file mode 100644 index 00000000..84c5ab6a --- /dev/null +++ b/src/spectral/filterbank.h @@ -0,0 +1,80 @@ +/* + Copyright (C) 2007 Amaury Hazan + and Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/** \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 + +/** filterbank object */ +typedef struct aubio_filterbank_t_ aubio_filterbank_t; + +/** create filterbank object + + \param win_s size of analysis buffer (and length the FFT transform) + \param n_filters number of filters to create + +*/ + +aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s); + +/** filterbank initialization for mel filters + + + \param n_filters number of filters + \param win_s window size + \param samplerate + \param freq_min lowest filter frequency + \param freq_max highest filter frequency + +*/ +aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, uint_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); + +/** return the vector containing the filter coefficients of one channel + + */ +fvec_t * aubio_filterbank_getchannel(aubio_filterbank_t * f, uint_t channel); + +#ifdef __cplusplus +} +#endif + +#endif // FILTERBANK_H diff --git a/src/spectral/mfcc.c b/src/spectral/mfcc.c new file mode 100644 index 00000000..a7ac9d59 --- /dev/null +++ b/src/spectral/mfcc.c @@ -0,0 +1,123 @@ +/* + Copyright (C) 2006 Amaury Hazan + Ported to aubio from LibXtract + http://libxtract.sourceforge.net/ + + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "aubio_priv.h" +#include "sample.h" +#include "spectral/fft.h" +#include "spectral/filterbank.h" +#include "spectral/mfcc.h" + +/** Internal structure for mfcc object **/ + +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_fft_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); + + //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; + + + /** filterbank allocation */ + mfcc->fb = new_aubio_filterbank_mfcc(n_filters, mfcc->win_s, samplerate, lowfreq, highfreq); + + /** allocating space for fft object (used for dct) */ + mfcc->fft_dct=new_aubio_fft(n_filters, 1); + + /** allocating buffers */ + mfcc->in_dct=new_fvec(mfcc->win_s, 1); + + mfcc->fftgrain_dct=new_cvec(n_filters, 1); + + return mfcc; +}; + +void del_aubio_mfcc(aubio_mfcc_t *mf){ + /** deleting filterbank */ + del_aubio_filterbank(mf->fb); + /** deleting fft object */ + del_aubio_fft(mf->fft_dct); + /** deleting buffers */ + del_fvec(mf->in_dct); + del_cvec(mf->fftgrain_dct); + + /** deleting mfcc object */ + AUBIO_FREE(mf); +} + + +/** intermediate dct involved in aubio_mfcc_do + + \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) + +*/ +void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out); + +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; + + aubio_dct_do(mf, mf->in_dct, out); + + return; +} + +void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out){ + uint_t i; + //compute mag spectrum + aubio_fft_do (mf->fft_dct, in, mf->fftgrain_dct); + //extract real part of fft grain + for(i=0; in_coefs ;i++){ + //for(i=0; ilength;i++){ + out->data[0][i]= mf->fftgrain_dct->norm[0][i] + *COS(mf->fftgrain_dct->phas[0][i]); + } + return; +} + diff --git a/src/spectral/mfcc.h b/src/spectral/mfcc.h new file mode 100644 index 00000000..0c873c54 --- /dev/null +++ b/src/spectral/mfcc.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 2007 Amaury Hazan + and Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/* part of this mfcc implementation were inspired from LibXtract + http://libxtract.sourceforge.net/ +*/ + +#ifndef MFCC_H +#define MFCC_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct aubio_mfcc_t_ aubio_mfcc_t; + +/** create mfcc object + + \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 + +*/ +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 + + \param mf mfcc object as returned by new_aubio_mfcc + +*/ +void del_aubio_mfcc(aubio_mfcc_t *mf); +/** mfcc object processing + + \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) + +*/ +void aubio_mfcc_do(aubio_mfcc_t * mf, cvec_t *in, fvec_t *out); + +#ifdef __cplusplus +} +#endif + +#endif // MFCC_H diff --git a/src/spectral/phasevoc.c b/src/spectral/phasevoc.c new file mode 100644 index 00000000..d7ee1689 --- /dev/null +++ b/src/spectral/phasevoc.c @@ -0,0 +1,150 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "cvec.h" +#include "mathutils.h" +#include "spectral/fft.h" +#include "spectral/phasevoc.h" + +/** phasevocoder internal object */ +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] */ + fvec_t * data; /** current input grain [win_s] */ + fvec_t * dataold; /** last input frame [win_s-hop_s] */ + smpl_t * w; /** grain window [win_s] */ +}; + + +/** returns data and dataold slided by 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); + +/** do additive synthesis from 'old' and 'cur' */ +static void aubio_pvoc_addsynth(const smpl_t * synth, smpl_t * synthold, + 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,j; + for (i=0; ichannels; i++) { + /* slide */ + aubio_pvoc_swapbuffers(pv->data->data[i],pv->dataold->data[i], + datanew->data[i],pv->win_s,pv->hop_s); + /* windowing */ + for (j=0; jwin_s; j++) pv->data->data[i][j] *= pv->w[j]; + } + /* shift */ + vec_shift(pv->data); + /* calculate fft */ + aubio_fft_do (pv->fft,pv->data,fftgrain); +} + +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 */ + vec_shift(pv->synth); + for (i=0; ichannels; i++) { + aubio_pvoc_addsynth(pv->synth->data[i],pv->synthold->data[i], + synthnew->data[i],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 * pv = AUBIO_NEW(aubio_pvoc_t); + + if (win_s < 2*hop_s) { + 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"); + AUBIO_ERR("Resetting hop size to half the window size.\n"); + hop_s = win_s / 2; + } + + pv->fft = new_aubio_fft(win_s,channels); + + /* remember old */ + pv->data = new_fvec (win_s, channels); + pv->synth = new_fvec (win_s, channels); + + /* new input output */ + 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); + aubio_window(pv->w,win_s,aubio_win_hanningz); + + pv->channels = channels; + pv->hop_s = hop_s; + pv->win_s = win_s; + + return pv; +} + +void del_aubio_pvoc(aubio_pvoc_t *pv) { + del_fvec(pv->data); + del_fvec(pv->synth); + del_fvec(pv->dataold); + del_fvec(pv->synthold); + del_aubio_fft(pv->fft); + AUBIO_FREE(pv->w); + 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) +{ + uint_t i; + for (i=0;ilength; + uint_t channels = input->channels; + smpl_t alfa = o->alfa; + 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; + /* second phase derivative */ + for (i=0;iphas[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 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;jnorm[i][j] = input->norm[i][j] * test; + stead->phas[i][j] = input->phas[i][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] += alfa*test; + test = (stead->norm[i][j]>0.); + oft2[i][j] += alfa*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; + } + } +} + +void aubio_tss_set_thres(aubio_tss_t *o, smpl_t thrs){ + o->thrs = thrs; + o->parm = thrs*o->thrsfact; +} + +aubio_tss_t * new_aubio_tss(smpl_t thrs, smpl_t alfa, smpl_t beta, + uint_t size, uint_t overlap,uint_t channels) +{ + aubio_tss_t * o = AUBIO_NEW(aubio_tss_t); + uint_t rsize = size/2+1; + o->thrs = thrs; + o->thrsfact = TWO_PI*overlap/rsize; + o->alfa = alfa; + o->beta = beta; + o->parm = thrs*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); + return o; +} + +void del_aubio_tss(aubio_tss_t *s) +{ + free(s->theta1); + free(s->theta2); + free(s->oft1); + free(s->oft2); + free(s->dev); + free(s); +} + diff --git a/src/spectral/tss.h b/src/spectral/tss.h new file mode 100644 index 00000000..af85f398 --- /dev/null +++ b/src/spectral/tss.h @@ -0,0 +1,84 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/** \file + + Transient / Steady-state Separation (TSS) + + This file implement a Transient / Steady-state Separation (TSS) as described + in: + + Christopher Duxbury, Mike E. Davies, and Mark B. Sandler. Separation of + transient information in musical audio using multiresolution analysis + techniques. In Proceedings of the Digital Audio Effects Conference, DAFx-01, + pages 1­5, Limerick, Ireland, 2001. + +*/ + +#ifndef TSS_H +#define TSS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** TSS object */ +typedef struct _aubio_tss_t aubio_tss_t; + +/** create tss object + + \param thrs separation threshold + \param alfa alfa parameter + \param beta beta parameter + \param size buffer size + \param overlap step size + \param channels number of input channels + +*/ +aubio_tss_t * new_aubio_tss(smpl_t thrs, smpl_t alfa, smpl_t beta, + uint_t size, uint_t overlap,uint_t channels); +/** delete tss object + + \param s tss object as returned by new_aubio_tss + +*/ +void del_aubio_tss(aubio_tss_t *s); + +/** set transient / steady state separation threshold + + \param tss tss object as returned by new_aubio_tss + \param thrs new threshold value + +*/ +void aubio_tss_set_thres(aubio_tss_t *tss, smpl_t thrs); +/** split input into transient and steady states components + + \param s tss object as returned by new_aubio_tss + \param input input spectral frame + \param trans output transient components + \param stead output steady state components + +*/ +void aubio_tss_do(aubio_tss_t *s, cvec_t * input, cvec_t * trans, cvec_t * stead); + +#ifdef __cplusplus +} +#endif + +#endif /*TSS_H*/ diff --git a/src/tempo/beattracking.c b/src/tempo/beattracking.c index e67a6082..7066e1c5 100644 --- a/src/tempo/beattracking.c +++ b/src/tempo/beattracking.c @@ -20,7 +20,7 @@ #include "aubio_priv.h" #include "sample.h" #include "mathutils.h" -#include "beattracking.h" +#include "tempo/beattracking.h" uint_t fvec_gettimesig(smpl_t * acf, uint_t acflen, uint_t gp); void aubio_beattracking_checkstate(aubio_beattracking_t * bt); diff --git a/src/tempo/tempo.c b/src/tempo/tempo.c index 1794bae3..6408ba66 100644 --- a/src/tempo/tempo.c +++ b/src/tempo/tempo.c @@ -21,10 +21,10 @@ #include "sample.h" #include "onset/onsetdetection.h" #include "tempo/beattracking.h" -#include "phasevoc.h" +#include "spectral/phasevoc.h" #include "onset/peakpick.h" #include "mathutils.h" -#include "tempo.h" +#include "tempo/tempo.h" /* structure to store object state */ struct _aubio_tempo_t { diff --git a/src/temporal/biquad.c b/src/temporal/biquad.c new file mode 100644 index 00000000..1775125f --- /dev/null +++ b/src/temporal/biquad.c @@ -0,0 +1,114 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "aubio_priv.h" +#include "sample.h" +#include "mathutils.h" +#include "temporal/biquad.h" + +/** \note this file needs to be in double or more less precision would lead to large + * errors in the output + */ + +struct _aubio_biquad_t { + lsmp_t a2; + lsmp_t a3; + lsmp_t b1; + lsmp_t b2; + lsmp_t b3; + lsmp_t o1; + lsmp_t o2; + lsmp_t i1; + lsmp_t i2; +}; + +void aubio_biquad_do(aubio_biquad_t * b, fvec_t * in) { + uint_t i,j; + lsmp_t i1 = b->i1; + lsmp_t i2 = b->i2; + lsmp_t o1 = b->o1; + lsmp_t o2 = b->o2; + lsmp_t a2 = b->a2; + lsmp_t a3 = b->a3; + lsmp_t b1 = b->b1; + lsmp_t b2 = b->b2; + lsmp_t b3 = b->b3; + + i=0; // works in mono only !!! + //for (i=0;ichannels;i++) { + for (j = 0; j < in->length; j++) { + lsmp_t i0 = in->data[i][j]; + lsmp_t o0 = b1 * i0 + b2 * i1 + b3 * i2 + - a2 * o1 - a3 * o2;// + 1e-37; + in->data[i][j] = o0; + i2 = i1; + i1 = i0; + o2 = o1; + o1 = o0; + } + b->i2 = i2; + b->i1 = i1; + b->o2 = o2; + b->o1 = o1; + //} +} + +void aubio_biquad_do_filtfilt(aubio_biquad_t * b, fvec_t * in, fvec_t * tmp) { + uint_t j,i=0; + uint_t length = in->length; + lsmp_t mir; + /* mirroring */ + mir = 2*in->data[i][0]; + b->i1 = mir - in->data[i][2]; + b->i2 = mir - in->data[i][1]; + /* apply filtering */ + aubio_biquad_do(b,in); + /* invert */ + for (j = 0; j < length; j++) + tmp->data[i][length-j-1] = in->data[i][j]; + /* mirror again */ + mir = 2*tmp->data[i][0]; + b->i1 = mir - tmp->data[i][2]; + b->i2 = mir - tmp->data[i][1]; + /* apply filtering */ + aubio_biquad_do(b,tmp); + /* invert back */ + for (j = 0; j < length; j++) + in->data[i][j] = tmp->data[i][length-j-1]; +} + +aubio_biquad_t * new_aubio_biquad( + lsmp_t b1, lsmp_t b2, lsmp_t b3, + lsmp_t a2, lsmp_t a3) { + aubio_biquad_t * b = AUBIO_NEW(aubio_biquad_t); + b->a2 = a2; + b->a3 = a3; + b->b1 = b1; + b->b2 = b2; + b->b3 = b3; + b->i1 = 0.; + b->i2 = 0.; + b->o1 = 0.; + b->o2 = 0.; + return b; +} + +void del_aubio_biquad(aubio_biquad_t * b) { + AUBIO_FREE(b); +} diff --git a/src/temporal/biquad.h b/src/temporal/biquad.h new file mode 100644 index 00000000..2ee3a810 --- /dev/null +++ b/src/temporal/biquad.h @@ -0,0 +1,80 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef BIQUAD_H +#define BIQUAD_H + +/** \file + + Second order Infinite Impulse Response filter + + This file implements a normalised biquad filter (second order IIR): + + \f$ y[n] = b_1 x[n] + b_2 x[n-1] + b_3 x[n-2] - a_2 y[n-1] - a_3 y[n-2] \f$ + + The filtfilt version runs the filter twice, forward and backward, to + compensate the phase shifting of the forward operation. + +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** biquad filter object */ +typedef struct _aubio_biquad_t aubio_biquad_t; + +/** filter input vector + + \param b biquad object as returned by new_aubio_biquad + \param in input vector to filter + +*/ +void aubio_biquad_do(aubio_biquad_t * b, fvec_t * in); +/** filter input vector forward and backward + + \param b biquad object as returned by new_aubio_biquad + \param in input vector to filter + \param tmp memory space to use for computation + +*/ +void aubio_biquad_do_filtfilt(aubio_biquad_t * b, fvec_t * in, fvec_t * tmp); +/** create new biquad filter + + \param b1 forward filter coefficient + \param b2 forward filter coefficient + \param b3 forward filter coefficient + \param a2 feedback filter coefficient + \param a3 feedback filter coefficient + +*/ +aubio_biquad_t * new_aubio_biquad(lsmp_t b1, lsmp_t b2, lsmp_t b3, lsmp_t a2, lsmp_t a3); + +/** delete biquad filter + + \param b biquad object to delete + +*/ +void del_aubio_biquad(aubio_biquad_t * b); + +#ifdef __cplusplus +} +#endif + +#endif /*BIQUAD_H*/ diff --git a/src/temporal/filter.c b/src/temporal/filter.c new file mode 100644 index 00000000..f82cd1f0 --- /dev/null +++ b/src/temporal/filter.c @@ -0,0 +1,225 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/* Requires lsmp_t to be long or double. float will NOT give reliable + * results */ + +#include "aubio_priv.h" +#include "sample.h" +#include "mathutils.h" +#include "temporal/filter.h" + +struct _aubio_filter_t { + uint_t order; + lsmp_t * a; + lsmp_t * b; + lsmp_t * y; + lsmp_t * x; +}; + +/* bug: mono only */ +void aubio_filter_do(aubio_filter_t * f, fvec_t * in) { + uint_t i,j,l, order = f->order; + lsmp_t *x = f->x; + lsmp_t *y = f->y; + lsmp_t *a = f->a; + lsmp_t *b = f->b; + i=0;//for (i=0;ichannels;i++) { + for (j = 0; j < in->length; j++) { + /* new input */ + //AUBIO_DBG("befor %f\t", in->data[i][j]); + x[0] = in->data[i][j]; + y[0] = b[0] * x[0]; + for (l=1;ldata[i][j] = y[0]; + //AUBIO_DBG("after %f\n", in->data[i][j]); + /* store states for next sample */ + for (l=order-1; l>0; l--){ + x[l] = x[l-1]; + y[l] = y[l-1]; + } + } + /* store states for next buffer */ + f->x = x; + f->y = y; + //} +} + +void aubio_filter_do_outplace(aubio_filter_t * f, fvec_t * in, fvec_t * out) { + uint_t i,j,l, order = f->order; + lsmp_t *x = f->x; + lsmp_t *y = f->y; + lsmp_t *a = f->a; + lsmp_t *b = f->b; + + i=0; // works in mono only !!! + //for (i=0;ichannels;i++) { + for (j = 0; j < in->length; j++) { + /* new input */ + x[0] = in->data[i][j]; + y[0] = b[0] * x[0]; + for (l=1;ldata[i][j] = y[0]; + /* store for next sample */ + for (l=order-1; l>0; l--){ + x[l] = x[l-1]; + y[l] = y[l-1]; + } + } + /* store for next run */ + f->x = x; + f->y = y; + //} +} + +/* + * + * despite mirroring, end effects destroy both phse and amplitude. the longer + * the buffer, the less affected they are. + * + * replacing with zeros clicks. + * + * seems broken for order > 4 (see biquad_do_filtfilt for audible one) + */ +void aubio_filter_do_filtfilt(aubio_filter_t * f, fvec_t * in, fvec_t * tmp) { + uint_t j,i=0; + uint_t length = in->length; + //uint_t order = f->order; + //lsmp_t mir; + /* mirroring */ + //mir = 2*in->data[i][0]; + //for (j=1;jx[j] = 0.;//mir - in->data[i][order-j]; + /* apply filtering */ + aubio_filter_do(f,in); + /* invert */ + for (j = 0; j < length; j++) + tmp->data[i][length-j-1] = in->data[i][j]; + /* mirror inverted */ + //mir = 2*tmp->data[i][0]; + //for (j=1;jx[j] = 0.;//mir - tmp->data[i][order-j]; + /* apply filtering on inverted */ + aubio_filter_do(f,tmp); + /* invert back */ + for (j = 0; j < length; j++) + in->data[i][j] = tmp->data[i][length-j-1]; +} + + +aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate) { + aubio_filter_t * f = new_aubio_filter(samplerate, 7); + lsmp_t * a = f->a; + lsmp_t * b = f->b; + /* uint_t l; */ + /* for now, 44100, adsgn */ + a[0] = 1.00000000000000000000000000000000000000000000000000000; + a[1] = -4.01957618111583236952810693765059113502502441406250000; + a[2] = 6.18940644292069386267485242569819092750549316406250000; + a[3] = -4.45319890354411640487342083360999822616577148437500000; + a[4] = 1.42084294962187751565352300531230866909027099609375000; + a[5] = -0.14182547383030480458998567883099894970655441284179688; + a[6] = 0.00435117723349511334451911181986361043527722358703613; + b[0] = 0.25574112520425740235907596797915175557136535644531250; + b[1] = -0.51148225040851391653973223583307117223739624023437500; + b[2] = -0.25574112520426162120656954357400536537170410156250000; + b[3] = 1.02296450081703405032840237254276871681213378906250000; + b[4] = -0.25574112520426051098354491841746494174003601074218750; + b[5] = -0.51148225040851369449512731080176308751106262207031250; + b[6] = 0.25574112520425729133677350546349771320819854736328125; + /* DBG: filter coeffs at creation time */ + /* + for (l=0; lorder; l++){ + AUBIO_DBG("a[%d]=\t%1.16f\tb[%d]=\t%1.16f\n",l,a[l],l,b[l]); + } + */ + f->a = a; + f->b = b; + return f; +} + +aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate) { + aubio_filter_t * f = new_aubio_filter(samplerate, 5); + lsmp_t * a = f->a; + lsmp_t * b = f->b; + /* uint_t l; */ + /* for now, 44100, cdsgn */ + a[0] = 1.000000000000000000000000000000000000000000000000000000000000; + a[1] = -2.134674963687040794013682898366823792457580566406250000000000; + a[2] = 1.279333533236063358273781886964570730924606323242187500000000; + a[3] = -0.149559846089396208945743182994192466139793395996093750000000; + a[4] = 0.004908700174624848651394604104325480875559151172637939453125; + b[0] = 0.217008561949218803377448239189106971025466918945312500000000; + b[1] = -0.000000000000000222044604925031308084726333618164062500000000; + b[2] = -0.434017123898438272888711253472138196229934692382812500000000; + b[3] = 0.000000000000000402455846426619245903566479682922363281250000; + b[4] = 0.217008561949218969910901932962588034570217132568359375000000; + /* DBG: filter coeffs at creation time */ + /* + for (l=0; lorder; l++){ + AUBIO_DBG("a[%d]=\t%1.16f\tb[%d]=\t%1.16f\n",l,a[l],l,b[l]); + } + */ + f->a = a; + f->b = b; + return f; +} + +aubio_filter_t * new_aubio_filter(uint_t samplerate UNUSED, uint_t order) { + aubio_filter_t * f = AUBIO_NEW(aubio_filter_t); + lsmp_t * x = f->x; + lsmp_t * y = f->y; + lsmp_t * a = f->a; + lsmp_t * b = f->b; + uint_t l; + f->order = order; + a = AUBIO_ARRAY(lsmp_t,f->order); + b = AUBIO_ARRAY(lsmp_t,f->order); + x = AUBIO_ARRAY(lsmp_t,f->order); + y = AUBIO_ARRAY(lsmp_t,f->order); + /* initial states to zeros */ + for (l=0; lorder; l++){ + x[l] = 0.; + y[l] = 0.; + } + f->x = x; + f->y = y; + f->a = a; + f->b = b; + return f; +} + +void del_aubio_filter(aubio_filter_t * f) { + AUBIO_FREE(f->a); + AUBIO_FREE(f->b); + AUBIO_FREE(f->x); + AUBIO_FREE(f->y); + AUBIO_FREE(f); + return; +} diff --git a/src/temporal/filter.h b/src/temporal/filter.h new file mode 100644 index 00000000..1b0adab4 --- /dev/null +++ b/src/temporal/filter.h @@ -0,0 +1,97 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef FILTER_H +#define FILTER_H + +/** \file + + Infinite Impulse Response filter + + This file implements IIR filters of any order: + + \f$ y[n] = b_1 x[n] + ... + b_{order} x[n-order] - + a_2 y[n-1] - ... - a_{order} y[n-order]\f$ + + The filtfilt version runs the filter twice, forward and backward, to + compensate the phase shifting of the forward operation. + +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** IIR filter object */ +typedef struct _aubio_filter_t aubio_filter_t; + +/** filter input vector (in-place) + + \param b biquad object as returned by new_aubio_biquad + \param in input vector to filter + +*/ +void aubio_filter_do(aubio_filter_t * b, fvec_t * in); +/** filter input vector (out-of-place) + + \param b biquad object as returned by new_aubio_biquad + \param in input vector to filter + \param out output vector to store filtered input + +*/ +void aubio_filter_do_outplace(aubio_filter_t * b, fvec_t * in, fvec_t * out); +/** filter input vector forward and backward + + \param b biquad object as returned by new_aubio_biquad + \param in input vector to filter + \param tmp memory space to use for computation + +*/ +void aubio_filter_do_filtfilt(aubio_filter_t * b, fvec_t * in, fvec_t * tmp); +/** create new IIR filter + + \param samplerate signal sampling rate + \param order order of the filter (number of coefficients) + +*/ +aubio_filter_t * new_aubio_filter(uint_t samplerate, uint_t order); +/** create a new A-design filter + + \param samplerate sampling-rate of the signal to filter + +*/ +aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate); +/** create a new C-design filter + + \param samplerate sampling-rate of the signal to filter + +*/ +aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate); +/** delete a filter object + + \param f filter object to delete + +*/ +void del_aubio_filter(aubio_filter_t * f); + +#ifdef __cplusplus +} +#endif + +#endif /*FILTER_H*/ diff --git a/src/temporal/resample.c b/src/temporal/resample.c new file mode 100644 index 00000000..05d7a88d --- /dev/null +++ b/src/temporal/resample.c @@ -0,0 +1,65 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#include /* from libsamplerate */ + +#include "aubio_priv.h" +#include "sample.h" +#include "temporal/resample.h" + +struct _aubio_resampler_t { + SRC_DATA *proc; + SRC_STATE *stat; + float ratio; + uint_t type; +}; + +aubio_resampler_t * new_aubio_resampler(float ratio, uint_t type) { + aubio_resampler_t * s = AUBIO_NEW(aubio_resampler_t); + int error = 0; + s->stat = src_new (type, 1, &error) ; /* only one channel */ + s->proc = AUBIO_NEW(SRC_DATA); + if (error) AUBIO_ERR("%s\n",src_strerror(error)); + s->ratio = ratio; + return s; +} + +void del_aubio_resampler(aubio_resampler_t *s) { + src_delete(s->stat); + AUBIO_FREE(s->proc); + AUBIO_FREE(s); +} + +uint_t aubio_resampler_process(aubio_resampler_t *s, + fvec_t * input, fvec_t * output) { + uint_t i ; + s->proc->input_frames = input->length; + s->proc->output_frames = output->length; + s->proc->src_ratio = s->ratio; + for (i = 0 ; i< input->channels; i++) + { + /* make SRC_PROC data point to input outputs */ + s->proc->data_in = input->data[i]; + s->proc->data_out= output->data[i]; + /* do resampling */ + src_process (s->stat, s->proc) ; + } + return AUBIO_OK; +} diff --git a/src/temporal/resample.h b/src/temporal/resample.h new file mode 100644 index 00000000..d4449ca3 --- /dev/null +++ b/src/temporal/resample.h @@ -0,0 +1,60 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _RESAMPLE_H +#define _RESAMPLE_H + +/** \file + + Resampling object + + This object resamples an input vector into an output vector using + libsamplerate. See http://www.mega-nerd.com/SRC/ + +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** resampler object */ +typedef struct _aubio_resampler_t aubio_resampler_t; +/** create resampler object + + \param ratio output_sample_rate / input_sample_rate + \param type libsamplerate resampling type + +*/ +aubio_resampler_t * new_aubio_resampler(float ratio, uint_t type); +/** delete resampler object */ +void del_aubio_resampler(aubio_resampler_t *s); +/** resample input in output + + \param s resampler object + \param input input buffer of size N + \param output output buffer of size N*ratio + +*/ +uint_t aubio_resampler_process(aubio_resampler_t *s, fvec_t * input, fvec_t * output); + +#ifdef __cplusplus +} +#endif + +#endif /* _RESAMPLE_H */ diff --git a/src/tss.c b/src/tss.c deleted file mode 100644 index da5a585f..00000000 --- a/src/tss.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/* default values : alfa=4, beta=3, threshold=0.25 */ - -#include "aubio_priv.h" -#include "sample.h" -#include "mathutils.h" -#include "tss.h" - -struct _aubio_tss_t -{ - smpl_t thrs; - smpl_t alfa; - smpl_t beta; - smpl_t parm; - smpl_t thrsfact; - fvec_t *theta1; - fvec_t *theta2; - fvec_t *oft1; - fvec_t *oft2; - fvec_t *dev; -}; - -void aubio_tss_do(aubio_tss_t *o, cvec_t * input, - cvec_t * trans, cvec_t * stead) -{ - uint_t i,j; - uint_t test; - uint_t nbins = input->length; - uint_t channels = input->channels; - smpl_t alfa = o->alfa; - 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; - /* second phase derivative */ - for (i=0;iphas[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 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;jnorm[i][j] = input->norm[i][j] * test; - stead->phas[i][j] = input->phas[i][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] += alfa*test; - test = (stead->norm[i][j]>0.); - oft2[i][j] += alfa*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; - } - } -} - -void aubio_tss_set_thres(aubio_tss_t *o, smpl_t thrs){ - o->thrs = thrs; - o->parm = thrs*o->thrsfact; -} - -aubio_tss_t * new_aubio_tss(smpl_t thrs, smpl_t alfa, smpl_t beta, - uint_t size, uint_t overlap,uint_t channels) -{ - aubio_tss_t * o = AUBIO_NEW(aubio_tss_t); - uint_t rsize = size/2+1; - o->thrs = thrs; - o->thrsfact = TWO_PI*overlap/rsize; - o->alfa = alfa; - o->beta = beta; - o->parm = thrs*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); - return o; -} - -void del_aubio_tss(aubio_tss_t *s) -{ - free(s->theta1); - free(s->theta2); - free(s->oft1); - free(s->oft2); - free(s->dev); - free(s); -} - diff --git a/src/tss.h b/src/tss.h deleted file mode 100644 index af85f398..00000000 --- a/src/tss.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2003 Paul Brossier - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/** \file - - Transient / Steady-state Separation (TSS) - - This file implement a Transient / Steady-state Separation (TSS) as described - in: - - Christopher Duxbury, Mike E. Davies, and Mark B. Sandler. Separation of - transient information in musical audio using multiresolution analysis - techniques. In Proceedings of the Digital Audio Effects Conference, DAFx-01, - pages 1­5, Limerick, Ireland, 2001. - -*/ - -#ifndef TSS_H -#define TSS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** TSS object */ -typedef struct _aubio_tss_t aubio_tss_t; - -/** create tss object - - \param thrs separation threshold - \param alfa alfa parameter - \param beta beta parameter - \param size buffer size - \param overlap step size - \param channels number of input channels - -*/ -aubio_tss_t * new_aubio_tss(smpl_t thrs, smpl_t alfa, smpl_t beta, - uint_t size, uint_t overlap,uint_t channels); -/** delete tss object - - \param s tss object as returned by new_aubio_tss - -*/ -void del_aubio_tss(aubio_tss_t *s); - -/** set transient / steady state separation threshold - - \param tss tss object as returned by new_aubio_tss - \param thrs new threshold value - -*/ -void aubio_tss_set_thres(aubio_tss_t *tss, smpl_t thrs); -/** split input into transient and steady states components - - \param s tss object as returned by new_aubio_tss - \param input input spectral frame - \param trans output transient components - \param stead output steady state components - -*/ -void aubio_tss_do(aubio_tss_t *s, cvec_t * input, cvec_t * trans, cvec_t * stead); - -#ifdef __cplusplus -} -#endif - -#endif /*TSS_H*/ diff --git a/src/utils/hist.c b/src/utils/hist.c new file mode 100644 index 00000000..7337ec46 --- /dev/null +++ b/src/utils/hist.c @@ -0,0 +1,157 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "aubio_priv.h" +#include "sample.h" +#include "utils/scale.h" +#include "mathutils.h" //vec_min vec_max +#include "utils/hist.h" + +/******** + * Object Structure + */ + +struct _aubio_hist_t { + fvec_t * hist; + uint_t nelems; + uint_t channels; + fvec_t * cent; + aubio_scale_t *scaler; +}; + +/** + * Object creation/deletion calls + */ +aubio_hist_t * new_aubio_hist (smpl_t ilow, smpl_t ihig, uint_t nelems, uint_t channels){ + aubio_hist_t * s = AUBIO_NEW(aubio_hist_t); + smpl_t step = (ihig-ilow)/(smpl_t)(nelems); + smpl_t accum = step; + uint_t i; + s->channels = channels; + s->nelems = nelems; + s->hist = new_fvec(nelems, channels); + s->cent = new_fvec(nelems, 1); + + /* use scale to map ilow/ihig -> 0/nelems */ + s->scaler = new_aubio_scale(ilow,ihig,0,nelems); + /* calculate centers now once */ + s->cent->data[0][0] = ilow + 0.5 * step; + for (i=1; i < s->nelems; i++, accum+=step ) + s->cent->data[0][i] = s->cent->data[0][0] + accum; + + return s; +} + +void del_aubio_hist(aubio_hist_t *s) { + del_fvec(s->hist); + del_fvec(s->cent); + del_aubio_scale(s->scaler); + AUBIO_FREE(s); +} + +/*** + * do it + */ +void aubio_hist_do (aubio_hist_t *s, fvec_t *input) { + uint_t i,j; + sint_t tmp = 0; + aubio_scale_do(s->scaler, input); + /* reset data */ + for (i=0; i < s->channels; i++) + for (j=0; j < s->nelems; j++) + s->hist->data[i][j] = 0; + /* run accum */ + for (i=0; i < input->channels; i++) + for (j=0; j < input->length; j++) + { + tmp = (sint_t)FLOOR(input->data[i][j]); + if ((tmp >= 0) && (tmp < (sint_t)s->nelems)) + s->hist->data[i][tmp] += 1; + } +} + +void aubio_hist_do_notnull (aubio_hist_t *s, fvec_t *input) { + uint_t i,j; + sint_t tmp = 0; + aubio_scale_do(s->scaler, input); + /* reset data */ + for (i=0; i < s->channels; i++) + for (j=0; j < s->nelems; j++) + s->hist->data[i][j] = 0; + /* run accum */ + for (i=0; i < input->channels; i++) + for (j=0; j < input->length; j++) { + if (input->data[i][j] != 0) { + tmp = (sint_t)FLOOR(input->data[i][j]); + if ((tmp >= 0) && (tmp < (sint_t)s->nelems)) + s->hist->data[i][tmp] += 1; + } + } +} + + +void aubio_hist_dyn_notnull (aubio_hist_t *s, fvec_t *input) { + uint_t i,j; + sint_t tmp = 0; + smpl_t ilow = vec_min(input); + smpl_t ihig = vec_max(input); + smpl_t step = (ihig-ilow)/(smpl_t)(s->nelems); + + /* readapt */ + aubio_scale_set(s->scaler, ilow, ihig, 0, s->nelems); + + /* recalculate centers */ + s->cent->data[0][0] = ilow + 0.5f * step; + for (i=1; i < s->nelems; i++) + s->cent->data[0][i] = s->cent->data[0][0] + i * step; + + /* scale */ + aubio_scale_do(s->scaler, input); + + /* reset data */ + for (i=0; i < s->channels; i++) + for (j=0; j < s->nelems; j++) + s->hist->data[i][j] = 0; + /* run accum */ + for (i=0; i < input->channels; i++) + for (j=0; j < input->length; j++) { + if (input->data[i][j] != 0) { + tmp = (sint_t)FLOOR(input->data[i][j]); + if ((tmp >= 0) && (tmp < (sint_t)s->nelems)) + s->hist->data[i][tmp] += 1; + } + } +} + +void aubio_hist_weight (aubio_hist_t *s) { + uint_t i,j; + for (i=0; i < s->channels; i++) + for (j=0; j < s->nelems; j++) { + s->hist->data[i][j] *= s->cent->data[0][j]; + } +} + +smpl_t aubio_hist_mean (aubio_hist_t *s) { + uint_t i,j; + smpl_t tmp = 0.0f; + for (i=0; i < s->channels; i++) + for (j=0; j < s->nelems; j++) + tmp += s->hist->data[i][j]; + return tmp/(smpl_t)(s->nelems); +} + diff --git a/src/utils/hist.h b/src/utils/hist.h new file mode 100644 index 00000000..85cfbddb --- /dev/null +++ b/src/utils/hist.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/** @file + * + * Histogram function + * + * Big hacks to implement an histogram + */ + +#ifndef HIST_H +#define HIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** histogram object */ +typedef struct _aubio_hist_t aubio_hist_t; + +/** histogram creation + * \param flow minimum input + * \param fhig maximum input + * \param nelems number of histogram columns + * \param channels number of channels + */ +aubio_hist_t * new_aubio_hist(smpl_t flow, smpl_t fhig, uint_t nelems, uint_t channels); +/** histogram deletion */ +void del_aubio_hist(aubio_hist_t *s); +/** compute the histogram */ +void aubio_hist_do(aubio_hist_t *s, fvec_t * input); +/** compute the histogram ignoring null elements */ +void aubio_hist_do_notnull(aubio_hist_t *s, fvec_t * input); +/** compute the mean of the histogram */ +smpl_t aubio_hist_mean(aubio_hist_t *s); +/** weight the histogram */ +void aubio_hist_weight(aubio_hist_t *s); +/** compute dynamic histogram for non-null elements */ +void aubio_hist_dyn_notnull (aubio_hist_t *s, fvec_t *input); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utils/scale.c b/src/utils/scale.c new file mode 100644 index 00000000..d348326e --- /dev/null +++ b/src/utils/scale.c @@ -0,0 +1,79 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "aubio_priv.h" +#include "sample.h" +#include "utils/scale.h" + +struct _aubio_scale_t { + smpl_t ilow; + smpl_t ihig; + smpl_t olow; + smpl_t ohig; + + smpl_t scaler; + smpl_t irange; + + /* not implemented yet : type in/out data + bool inint; + bool outint; + */ +}; + +aubio_scale_t * new_aubio_scale (smpl_t ilow, smpl_t ihig, + smpl_t olow, smpl_t ohig) { + aubio_scale_t * s = AUBIO_NEW(aubio_scale_t); + aubio_scale_set (s, ilow, ihig, olow, ohig); + return s; +} + +void del_aubio_scale(aubio_scale_t *s) { + AUBIO_FREE(s); +} + +void aubio_scale_set (aubio_scale_t *s, smpl_t ilow, smpl_t ihig, + smpl_t olow, smpl_t ohig) { + smpl_t inputrange = ihig - ilow; + smpl_t outputrange= ohig - olow; + s->ilow = ilow; + s->ihig = ihig; + s->olow = olow; + s->ohig = ohig; + if (inputrange == 0) { + s->scaler = 0.0f; + } else { + s->scaler = outputrange/inputrange; + if (inputrange < 0) { + inputrange = inputrange * -1.0f; + } + } +} + +void aubio_scale_do (aubio_scale_t *s, fvec_t *input) +{ + uint_t i, j; + for (i=0; i < input->channels; i++){ + for (j=0; j < input->length; j++){ + input->data[i][j] -= s->ilow; + input->data[i][j] *= s->scaler; + input->data[i][j] += s->olow; + } + } +} + diff --git a/src/utils/scale.h b/src/utils/scale.h new file mode 100644 index 00000000..226bb74a --- /dev/null +++ b/src/utils/scale.h @@ -0,0 +1,78 @@ +/* + Copyright (C) 2003 Paul Brossier + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/** \file + + Vector scaling function + + This object, inspired from the scale object in FTS, the jMax engine, scales + the values of a vector according to an affine function defined as follow: + + \f$ y = (x - ilow)*(ohig-olow)/(ihig-ilow) + olow \f$ + +*/ +#ifndef SCALE_H +#define SCALE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** scale object */ +typedef struct _aubio_scale_t aubio_scale_t; + +/** create a scale object + + \param flow lower value of output function + \param fhig higher value of output function + \param ilow lower value of input function + \param ihig higher value of output function + +*/ +aubio_scale_t * new_aubio_scale(smpl_t flow, smpl_t fhig, + smpl_t ilow, smpl_t ihig); +/** delete a scale object + + \param s scale object as returned by new_aubio_scale + +*/ +void del_aubio_scale(aubio_scale_t *s); +/** scale input vector + + \param s scale object as returned by new_aubio_scale + \param input vector to scale + +*/ +void aubio_scale_do(aubio_scale_t *s, fvec_t * input); +/** modify scale parameters after object creation + + \param s scale object as returned by new_aubio_scale + \param olow lower value of output function + \param ohig higher value of output function + \param ilow lower value of input function + \param ihig higher value of output function + +*/ +void aubio_scale_set (aubio_scale_t *s, smpl_t ilow, smpl_t ihig, + smpl_t olow, smpl_t ohig); + +#ifdef __cplusplus +} +#endif + +#endif