ref: a4364b83d213f0c725b47bacbea5bfa39f798f91
parent: d9c45df5930c9964f82363e4ea88a4a9c4cda732
author: Paul Brossier <piem@piem.org>
date: Tue Sep 29 03:43:12 EDT 2009
src/temporal: revamp filter object, clarify API for A- and C-weighting filters, add coefficients for 8000 16000 22050 44100 96000 192000, improve documentation, remove unneeded filter_priv.h, add A and C weighting tests.
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,5 @@
noinst_HEADERS = \
- aubio_priv.h \
- temporal/filter_priv.h
+ aubio_priv.h
nobase_pkginclude_HEADERS = \
aubio.h \
--- a/src/pitch/pitchdetection.c
+++ b/src/pitch/pitchdetection.c
@@ -19,6 +19,7 @@
#include "aubio_priv.h"
#include "fvec.h"
#include "cvec.h"
+#include "lvec.h"
#include "spectral/phasevoc.h"
#include "mathutils.h"
#include "temporal/filter.h"
@@ -103,7 +104,7 @@
p->pv = new_aubio_pvoc(bufsize, hopsize, channels);
p->fftgrain = new_cvec(bufsize, channels);
p->mcomb = new_aubio_pitchmcomb(bufsize,hopsize,channels,samplerate);
- p->filter = new_aubio_cdsgn_filter(samplerate, channels);
+ p->filter = new_aubio_filter_cdsgn (samplerate, channels);
p->callback = aubio_pitchdetection_mcomb;
break;
case aubio_pitch_fcomb:
--- a/src/temporal/adesign.c
+++ b/src/temporal/adesign.c
@@ -1,58 +1,160 @@
/*
- Copyright (C) 2003-2007 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.
+ Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
- 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.
+ This file is part of aubio.
- 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.
+ aubio is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
-*/
+ aubio is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with aubio. If not, see <http://www.gnu.org/licenses/>.
+*/
+
#include "aubio_priv.h"
#include "types.h"
#include "fvec.h"
+#include "lvec.h"
#include "temporal/filter.h"
-#include "temporal/filter_priv.h"
#include "temporal/adesign.h"
-aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate, uint_t channels) {
- aubio_filter_t * f = new_aubio_filter(samplerate, 7, channels);
- lsmp_t * a = f->a->data[0];
- lsmp_t * b = f->b->data[0];
- /* 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; l<f->order; l++){
- AUBIO_DBG("a[%d]=\t%1.16f\tb[%d]=\t%1.16f\n",l,a[l],l,b[l]);
+void aubio_filter_set_adsgn (aubio_filter_t * f) {
+
+ uint_t samplerate = aubio_filter_get_samplerate (f);
+ lvec_t *bs = aubio_filter_get_feedforward (f);
+ lvec_t *as = aubio_filter_get_feedback (f);
+ lsmp_t *b = bs->data[0], *a = as->data[0];
+ uint_t order = aubio_filter_get_order (f);
+
+ if ( order != 7 ) {
+ AUBIO_ERROR ( "order of A-weighting filter must be 7, not %d\n", order );
+ return;
}
- */
- f->a->data[0] = a;
- f->b->data[0] = b;
+
+ /* select coefficients according to sampling frequency */
+ switch ( samplerate ) {
+
+ case 8000:
+ b[0] = 6.306209468238731519207362907764036208391189575195312500e-01;
+ b[1] = -1.261241893647746525886077506584115326404571533203125000e+00;
+ b[2] = -6.306209468238730408984338282607495784759521484375000000e-01;
+ b[3] = 2.522483787295493051772155013168230652809143066406250000e+00;
+ b[4] = -6.306209468238730408984338282607495784759521484375000000e-01;
+ b[5] = -1.261241893647746525886077506584115326404571533203125000e+00;
+ b[6] = 6.306209468238731519207362907764036208391189575195312500e-01;
+ a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
+ a[1] = -2.128467193009123015201566886389628052711486816406250000e+00;
+ a[2] = 2.948668980101234460278192273108288645744323730468750000e-01;
+ a[3] = 1.824183830735050637628091863007284700870513916015625000e+00;
+ a[4] = -8.056628943119792385374466903158463537693023681640625000e-01;
+ a[5] = -3.947497982842933517133587884018197655677795410156250000e-01;
+ a[6] = 2.098548546080332977137317129745497368276119232177734375e-01;
+ break;
+
+ case 16000:
+ b[0] = 5.314898298235570806014038680586963891983032226562500000e-01;
+ b[1] = -1.062979659647114161202807736117392778396606445312500000e+00;
+ b[2] = -5.314898298235570806014038680586963891983032226562500000e-01;
+ b[3] = 2.125959319294228322405615472234785556793212890625000000e+00;
+ b[4] = -5.314898298235570806014038680586963891983032226562500000e-01;
+ b[5] = -1.062979659647114161202807736117392778396606445312500000e+00;
+ b[6] = 5.314898298235570806014038680586963891983032226562500000e-01;
+ a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
+ a[1] = -2.867832572992162987191022693878039717674255371093750000e+00;
+ a[2] = 2.221144410202312347024644623161293566226959228515625000e+00;
+ a[3] = 4.552683347886614662058946123579517006874084472656250000e-01;
+ a[4] = -9.833868636162828025248927588108927011489868164062500000e-01;
+ a[5] = 5.592994142413361402521587706360151059925556182861328125e-02;
+ a[6] = 1.188781038285612462468421313133148942142724990844726562e-01;
+ break;
+
+ case 22050:
+ b[0] = 4.492998504299193784916610638902056962251663208007812500e-01;
+ b[1] = -8.985997008598388680056245902960654348134994506835937500e-01;
+ b[2] = -4.492998504299192674693586013745516538619995117187500000e-01;
+ b[3] = 1.797199401719677958055854105623438954353332519531250000e+00;
+ b[4] = -4.492998504299192674693586013745516538619995117187500000e-01;
+ b[5] = -8.985997008598388680056245902960654348134994506835937500e-01;
+ b[6] = 4.492998504299193784916610638902056962251663208007812500e-01;
+ a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
+ a[1] = -3.229078805225074955131958631682209670543670654296875000e+00;
+ a[2] = 3.354494881236033787530459449044428765773773193359375000e+00;
+ a[3] = -7.317843680657351024265722116979304701089859008789062500e-01;
+ a[4] = -6.271627581807257545420952737913466989994049072265625000e-01;
+ a[5] = 1.772142005020879151899748649157118052244186401367187500e-01;
+ a[6] = 5.631716697383508385410522123493137769401073455810546875e-02;
+ break;
+
+ case 44100:
+ b[0] = 2.55741125204257513381378430494805797934532165527343750e-01;
+ b[1] = -5.114822504085150267627568609896115958690643310546875000e-01;
+ b[2] = -2.557411252042575133813784304948057979345321655273437500e-01;
+ b[3] = 1.022964500817030053525513721979223191738128662109375000e+00;
+ b[4] = -2.557411252042575133813784304948057979345321655273437500e-01;
+ b[5] = -5.114822504085150267627568609896115958690643310546875000e-01;
+ b[6] = 2.557411252042575133813784304948057979345321655273437500e-01;
+ a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
+ a[1] = -4.019576181115832369528106937650591135025024414062500000e+00;
+ a[2] = 6.189406442920693862674852425698190927505493164062500000e+00;
+ a[3] = -4.453198903544116404873420833609998226165771484375000000e+00;
+ a[4] = 1.420842949621876627475103305187076330184936523437500000e+00;
+ a[5] = -1.418254738303044160119270600262098014354705810546875000e-01;
+ a[6] = 4.351177233495117681327801761881346465088427066802978516e-03;
+
+ case 96000:
+ b[0] = 9.951898975972744976203898659150581806898117065429687500e-02;
+ b[1] = -1.990379795194548995240779731830116361379623413085937500e-01;
+ b[2] = -9.951898975972744976203898659150581806898117065429687500e-02;
+ b[3] = 3.980759590389097990481559463660232722759246826171875000e-01;
+ b[4] = -9.951898975972744976203898659150581806898117065429687500e-02;
+ b[5] = -1.990379795194548995240779731830116361379623413085937500e-01;
+ b[6] = 9.951898975972744976203898659150581806898117065429687500e-02;
+ a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
+ a[1] = -4.802203044225376693532325589330866932868957519531250000e+00;
+ a[2] = 9.401807218627226347962277941405773162841796875000000000e+00;
+ a[3] = -9.566143943569164420637207513209432363510131835937500000e+00;
+ a[4] = 5.309775930392619081032989925006404519081115722656250000e+00;
+ a[5] = -1.517333360452622237346531619550660252571105957031250000e+00;
+ a[6] = 1.740971994228911745583587844521389342844486236572265625e-01;
+ break;
+
+ case 192000:
+ b[0] = 3.433213424548713782469278044118254911154508590698242188e-02;
+ b[1] = -6.866426849097426177159775306790834292769432067871093750e-02;
+ b[2] = -3.433213424548714476358668434841092675924301147460937500e-02;
+ b[3] = 1.373285369819485235431955061358166858553886413574218750e-01;
+ b[4] = -3.433213424548714476358668434841092675924301147460937500e-02;
+ b[5] = -6.866426849097426177159775306790834292769432067871093750e-02;
+ b[6] = 3.433213424548713782469278044118254911154508590698242188e-02;
+ a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
+ a[1] = -5.305923689674640009172890131594613194465637207031250000e+00;
+ a[2] = 1.165952437466175695135461864992976188659667968750000000e+01;
+ a[3] = -1.357560092700591525272102444432675838470458984375000000e+01;
+ a[4] = 8.828906932824192921316353022120893001556396484375000000e+00;
+ a[5] = -3.039490120988216581565666274400427937507629394531250000e+00;
+ a[6] = 4.325834301870381537469256727490574121475219726562500000e-01;
+ break;
+
+ default:
+ AUBIO_ERROR ( "sampling rate of A-weighting filter is %d, should be one of\
+ 8000, 16000, 22050, 44100, 96000, 192000.\n", samplerate );
+ break;
+
+ }
+
+}
+
+aubio_filter_t * new_aubio_filter_adsgn (uint_t samplerate, uint_t channels) {
+ aubio_filter_t * f = new_aubio_filter (samplerate, 7, channels);
+ aubio_filter_set_adsgn (f);
return f;
}
--- a/src/temporal/adesign.h
+++ b/src/temporal/adesign.h
@@ -1,20 +1,21 @@
/*
- Copyright (C) 2003-2007 Paul Brossier
+ Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This file is part of aubio.
- 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.
+ aubio is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- 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.
+ aubio is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with aubio. If not, see <http://www.gnu.org/licenses/>.
+
*/
#ifndef _ADESIGN_H
@@ -22,9 +23,30 @@
/** \file
- Create a new A-design filter
+ Create an A-weighting filter
+
+ This file creates an A-weighting digital filter, which reduces low and high
+ frequencies and enhance the middle ones to reflect the ability of the human
+ hearing.
+
+ The implementation is based on the following standard:
- This file creates an IIR filter object with A-design coefficients.
+ - IEC/CD 1672: Electroacoustics-Sound Level Meters, IEC, Geneva, Nov. 1996,
+ for A- and C-weighting filters.
+
+ See also:
+
+ - <a href="http://en.wikipedia.org/wiki/A-weighting">A-Weighting on
+ Wikipedia</a>
+ - <a href="http://en.wikipedia.org/wiki/Weighting_filter">Weighting filter on
+ Wikipedia</a>
+ - <a href="http://www.mathworks.com/matlabcentral/fileexchange/69">Christophe
+ Couvreur's 'octave' toolbox</a>
+
+ The coefficients in this file have been computed using Christophe Couvreur's
+ scripts in octave 3.0 (debian package 1:3.0.5-6+b2 with octave-signal
+ 1.0.9-1+b1 on i386), with <pre> [b, a] = adsign(1/Fs) </pre> for various
+ sampling frequencies.
*/
@@ -34,16 +56,21 @@
/** create new A-design filter
- \param samplerate sampling-rate of the signal to filter
+ \param samplerate sampling frequency of the signal to filter. Should be one of
+ 8000, 16000, 22050, 44100, 96000, 192000.
\param channels number of channels to allocate
+ \return a new filter object
+
*/
-aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate, uint_t channels);
+aubio_filter_t * new_aubio_filter_adsgn (uint_t samplerate, uint_t channels);
-/** filter input vector (in-place) */
-#define aubio_adsgn_filter_do aubio_filter_do
-/** delete a-design filter object */
-#define del_aubio_adsgn_filter del_aubio_filter
+/** set feedback and feedforward coefficients of a A-weighting filter
+
+ \param f filter object to get coefficients from
+
+*/
+void aubio_filter_set_adsgn (aubio_filter_t *f);
#ifdef __cplusplus
}
--- a/src/temporal/cdesign.c
+++ b/src/temporal/cdesign.c
@@ -1,54 +1,136 @@
/*
- Copyright (C) 2003-2007 Paul Brossier
+ Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This file is part of aubio.
- 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.
+ aubio is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- 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.
+ aubio is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with aubio. If not, see <http://www.gnu.org/licenses/>.
+
*/
-
#include "aubio_priv.h"
#include "types.h"
#include "fvec.h"
+#include "lvec.h"
#include "temporal/filter.h"
-#include "temporal/filter_priv.h"
-#include "temporal/adesign.h"
+#include "temporal/cdesign.h"
-aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate, uint_t channels) {
- aubio_filter_t * f = new_aubio_filter(samplerate, 5, channels);
- lsmp_t * a = f->a->data[0];
- lsmp_t * b = f->b->data[0];
- /* 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; l<f->order; l++){
- AUBIO_DBG("a[%d]=\t%1.16f\tb[%d]=\t%1.16f\n",l,a[l],l,b[l]);
+void aubio_filter_set_cdsgn (aubio_filter_t * f) {
+
+ uint_t samplerate = aubio_filter_get_samplerate (f);
+ lvec_t * bs = aubio_filter_get_feedforward (f);
+ lvec_t * as = aubio_filter_get_feedback (f);
+ lsmp_t *b = bs->data[0], *a = as->data[0];
+ uint_t order = aubio_filter_get_order (f);
+
+ if ( order != 5 ) {
+ AUBIO_ERROR ( "order of C-weighting filter must be 5, not %d\n", order );
+ return;
}
- */
- f->a->data[0] = a;
- f->b->data[0] = b;
+
+ /* select coefficients according to sampling frequency */
+ switch ( samplerate ) {
+
+ case 8000:
+ b[0] = 6.782173932405135552414776611840352416038513183593750000e-01;
+ b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
+ b[2] = -1.356434786481027110482955322368070483207702636718750000e+00;
+ b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
+ b[4] = 6.782173932405135552414776611840352416038513183593750000e-01;
+ a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
+ a[1] = -6.589092811505605773447769024642184376716613769531250000e-01;
+ a[2] = -1.179445664897062595599663836765103042125701904296875000e+00;
+ a[3] = 4.243329729632123736848825501510873436927795410156250000e-01;
+ a[4] = 4.147270002091348328754349950031610205769538879394531250e-01;
+ break;
+
+ case 16000:
+ b[0] = 4.971057193673903418229542694461997598409652709960937500e-01;
+ b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
+ b[2] = -9.942114387347806836459085388923995196819305419921875000e-01;
+ b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
+ b[4] = 4.971057193673903418229542694461997598409652709960937500e-01;
+ a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
+ a[1] = -1.162322939286873690889478893950581550598144531250000000e+00;
+ a[2] = -4.771961355734982701548574368644040077924728393554687500e-01;
+ a[3] = 4.736145114694704227886745684372726827859878540039062500e-01;
+ a[4] = 1.660337524309875301131711466950946487486362457275390625e-01;
+ break;
+
+ case 22050:
+ b[0] = 4.033381299002754549754001800465630367398262023925781250e-01;
+ b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
+ b[2] = -8.066762598005509099508003600931260734796524047851562500e-01;
+ b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
+ b[4] = 4.033381299002754549754001800465630367398262023925781250e-01;
+ a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
+ a[1] = -1.449545371157945350404361306573264300823211669921875000e+00;
+ a[2] = -1.030104190885922088583015465701464563608169555664062500e-02;
+ a[3] = 3.881857047554073680828423675848171114921569824218750000e-01;
+ a[4] = 7.171589940116777917022972133054281584918498992919921875e-02;
+ break;
+
+ case 44100:
+ b[0] = 2.170085619492190254220531642204150557518005371093750000e-01;
+ b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
+ b[2] = -4.340171238984380508441063284408301115036010742187500000e-01;
+ b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
+ b[4] = 2.170085619492190254220531642204150557518005371093750000e-01;
+ a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
+ a[1] = -2.134674963687040794013682898366823792457580566406250000e+00;
+ a[2] = 1.279333533236062692139967111870646476745605468750000000e+00;
+ a[3] = -1.495598460893957093453821016737492755055427551269531250e-01;
+ a[4] = 4.908700174624683852664386307651511742733418941497802734e-03;
+ break;
+
+ case 96000:
+ b[0] = 8.182864044979756834585771230194950476288795471191406250e-02;
+ b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
+ b[2] = -1.636572808995951366917154246038990095257759094238281250e-01;
+ b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
+ b[4] = 8.182864044979756834585771230194950476288795471191406250e-02;
+ a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
+ a[1] = -2.856378516857566829401093855267390608787536621093750000e+00;
+ a[2] = 2.897640237559524045707348705036565661430358886718750000e+00;
+ a[3] = -1.225265958339703198376469117647502571344375610351562500e+00;
+ a[4] = 1.840048283551226071530493300087982788681983947753906250e-01;
+ break;
+
+ case 192000:
+ b[0] = 2.784755468532278815940728122768632601946592330932617188e-02;
+ b[1] = 0.000000000000000000000000000000000000000000000000000000e+00;
+ b[2] = -5.569510937064557631881456245537265203893184661865234375e-02;
+ b[3] = 0.000000000000000000000000000000000000000000000000000000e+00;
+ b[4] = 2.784755468532278815940728122768632601946592330932617188e-02;
+ a[0] = 1.000000000000000000000000000000000000000000000000000000e+00;
+ a[1] = -3.333298856144166322224009491037577390670776367187500000e+00;
+ a[2] = 4.111467536240339448738723149290308356285095214843750000e+00;
+ a[3] = -2.222889041651291641699117462849244475364685058593750000e+00;
+ a[4] = 4.447204118126878991112960193277103826403617858886718750e-01;
+ break;
+
+ default:
+ AUBIO_ERROR ( "sampling rate of C-weighting filter is %d, should be one of\
+ 8000, 16000, 22050, 44100, 96000, 192000.\n", samplerate );
+ break;
+
+ }
+
+}
+
+aubio_filter_t * new_aubio_filter_cdsgn (uint_t samplerate, uint_t channels) {
+ aubio_filter_t * f = new_aubio_filter(samplerate, 5, channels);
+ aubio_filter_set_cdsgn (f);
return f;
}
--- a/src/temporal/cdesign.h
+++ b/src/temporal/cdesign.h
@@ -1,20 +1,21 @@
/*
- Copyright (C) 2003-2007 Paul Brossier
+ Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This file is part of aubio.
- 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.
+ aubio is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- 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.
+ aubio is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with aubio. If not, see <http://www.gnu.org/licenses/>.
+
*/
#ifndef _CDESIGN_H
@@ -22,9 +23,30 @@
/** \file
- Create a new C-design filter
+ Create a C-weighting filter
+
+ This file creates a C-weighting digital filter, which reduces low and high
+ frequencies and enhance the middle ones to reflect the ability of the human
+ hearing.
+
+ The implementation is based on the following standard:
- This file creates an IIR filter object with A-design coefficients.
+ - IEC/CD 1672: Electroacoustics-Sound Level Meters, IEC, Geneva, Nov. 1996,
+ for A- and C-weighting filters.
+
+ See also:
+
+ - <a href="http://en.wikipedia.org/wiki/A-weighting">A-Weighting on
+ Wikipedia</a>
+ - <a href="http://en.wikipedia.org/wiki/Weighting_filter">Weighting filter on
+ Wikipedia</a>
+ - <a href="http://www.mathworks.com/matlabcentral/fileexchange/69">Christophe
+ Couvreur's 'octave' toolbox</a>
+
+ The coefficients in this file have been computed using Christophe Couvreur's
+ scripts in octave 3.0 (debian package 1:3.0.5-6+b2 with octave-signal
+ 1.0.9-1+b1 on i386), with <pre> [b, a] = cdsign(1/Fs) </pre> for various
+ sampling frequencies.
*/
@@ -34,16 +56,21 @@
/** create new C-design filter
- \param samplerate sampling-rate of the signal to filter
+ \param samplerate sampling frequency of the signal to filter. Should be one of
+ 8000, 16000, 22050, 44100, 96000, 192000.
\param channels number of channels to allocate
+ \return a new filter object
+
*/
-aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate, uint_t channels);
+aubio_filter_t * new_aubio_filter_cdsgn (uint_t samplerate, uint_t channels);
-/** filter input vector (in-place) */
-#define aubio_cdsgn_filter_do aubio_filter_do
-/** delete c-design filter object */
-#define del_aubio_cdsgn_filter del_aubio_filter
+/** set feedback and feedforward coefficients of a C-weighting filter
+
+ \param f filter object to get coefficients from
+
+*/
+void aubio_filter_set_cdsgn (aubio_filter_t *f);
#ifdef __cplusplus
}
--- a/src/temporal/filter.c
+++ b/src/temporal/filter.c
@@ -26,8 +26,16 @@
#include "lvec.h"
#include "mathutils.h"
#include "temporal/filter.h"
-#include "temporal/filter_priv.h"
+struct _aubio_filter_t {
+ uint_t order;
+ uint_t samplerate;
+ lvec_t * a;
+ lvec_t * b;
+ lvec_t * y;
+ lvec_t * x;
+};
+
void aubio_filter_do(aubio_filter_t * f, fvec_t * in) {
aubio_filter_do_outplace(f, in, in);
}
@@ -102,22 +110,41 @@
in->data[i][j] = tmp->data[i][length-j-1];
}
-aubio_filter_t * new_aubio_filter(uint_t samplerate UNUSED, uint_t order, uint_t channels) {
+lvec_t * aubio_filter_get_feedback ( aubio_filter_t *f ) {
+ return f->a;
+}
+
+lvec_t * aubio_filter_get_feedforward ( aubio_filter_t *f ) {
+ return f->b;
+}
+
+uint_t aubio_filter_get_order ( aubio_filter_t *f ) {
+ return f->order;
+}
+
+uint_t aubio_filter_get_samplerate ( aubio_filter_t *f ) {
+ return f->samplerate;
+}
+
+aubio_filter_t * new_aubio_filter(uint_t samplerate,
+ uint_t order, uint_t channels) {
aubio_filter_t * f = AUBIO_NEW(aubio_filter_t);
f->x = new_lvec(order, channels);
f->y = new_lvec(order, channels);
f->a = new_lvec(order, 1);
f->b = new_lvec(order, 1);
- f->a->data[0][1] = 1.;
+ f->samplerate = samplerate;
f->order = order;
+ /* set default to identity */
+ f->a->data[0][1] = 1.;
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);
+ del_lvec(f->a);
+ del_lvec(f->b);
+ del_lvec(f->x);
+ del_lvec(f->y);
AUBIO_FREE(f);
return;
}
--- a/src/temporal/filter.h
+++ b/src/temporal/filter.h
@@ -22,16 +22,39 @@
/** \file
- Infinite Impulse Response filter
+ Digital filter
- This file implements IIR filters of any order:
+ This object stores a digital filter of order \f$n\f$ for \f$c\f$ channels.
+ It contains the following data:
+ - \f$ n*1 b_i \f$ feedforward coefficients
+ - \f$ n*1 a_i \f$ feedback coefficients
+ - \f$ n*c x_i \f$ input signal
+ - \f$ n*c y_i \f$ output signal
+
+ For convenience, the samplerate of the input signal is also stored in the object.
+
+ Feedforward and feedback parameters can be modified using
+ aubio_filter_get_feedback() and aubio_filter_get_feedforward().
+
+ The function aubio_filter_do_outplace() computes the following output signal
+ \f$ y[n] \f$ from the input signal \f$ x[n] \f$:
- \f$ y[n] = b_1 x[n] + ... + b_{order} x[n-order] -
- a_2 y[n-1] - ... - a_{order} y[n-order]\f$
+ \f{eqnarray*}{
+ y[n] = b_0 x[n] & + & b_1 x[n-1] + b_2 x[n-2] + ... + b_P x[n-P] \\
+ & - & a_1 y[n-1] - a_2 y[n-2] - ... - a_P y[n-P] \\
+ \f}
- The filtfilt version runs the filter twice, forward and backward, to
- compensate the phase shifting of the forward operation.
+ The function aubio_filter_do() executes the same computation but modifies
+ directly the input signal (in-place).
+ The function aubio_filter_do_filtfilt() version runs the filter twice, first
+ forward then backward, to compensate with the phase shifting of the forward
+ operation.
+
+ Some convenience functions are provided:
+ - new_aubio_filter_adsgn() and aubio_filter_set_adsgn(),
+ - new_aubio_filter_cdsgn() and aubio_filter_set_cdsgn().
+
*/
#ifdef __cplusplus
@@ -38,40 +61,87 @@
extern "C" {
#endif
-/** IIR filter object */
+/** Digital filter
+
+*/
typedef struct _aubio_filter_t aubio_filter_t;
/** filter input vector (in-place)
- \param b biquad object as returned by new_aubio_biquad
+ \param f filter object as returned by new_aubio_filter()
\param in input vector to filter
*/
-void aubio_filter_do(aubio_filter_t * b, fvec_t * in);
+void aubio_filter_do(aubio_filter_t * f, fvec_t * in);
+
/** filter input vector (out-of-place)
- \param b biquad object as returned by new_aubio_biquad
+ \param f filter object as returned by new_aubio_filter()
\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);
+void aubio_filter_do_outplace(aubio_filter_t * f, 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 f ::aubio_filter_t object as returned by new_aubio_filter()
+ \param in ::fvec_t 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
+void aubio_filter_do_filtfilt(aubio_filter_t * f, fvec_t * in, fvec_t * tmp);
+/** returns a pointer to feedback coefficients \f$ a_i \f$
+
+ \param f filter object to get parameters from
+
+ \return a pointer to the \f$ a_0 ... a_i ... a_P \f$ coefficients
+
+*/
+lvec_t * aubio_filter_get_feedback ( aubio_filter_t *f );
+
+/** returns a pointer to feedforward coefficients \f$ b_i \f$
+
+ \param f filter object to get coefficients from
+
+ \return a pointer to the \f$ b_0 ... b_i ... b_P \f$ coefficients
+
+*/
+lvec_t * aubio_filter_get_feedforward ( aubio_filter_t *f );
+
+/** get order of the filter
+
+ \param f filter to get order from
+
+ \return the order of the filter
+
+*/
+uint_t aubio_filter_get_order ( aubio_filter_t *f );
+
+/** get sampling rate of the filter
+
+ \param f filter to get sampling rate from
+
+ \return the sampling rate of the filter, in Hz
+
+*/
+uint_t aubio_filter_get_samplerate ( aubio_filter_t *f );
+
+/** create new filter object
+
+ This function creates a new ::aubio_filter_t object, given an order
+ and a specific number of channels.
+
\param samplerate signal sampling rate
\param order order of the filter (number of coefficients)
\param channels number of channels to allocate
+ \return the newly created filter object
+
*/
aubio_filter_t * new_aubio_filter(uint_t samplerate, uint_t order, uint_t channels);
+
/** delete a filter object
\param f filter object to delete
--- a/src/temporal/filter_priv.h
+++ /dev/null
@@ -1,29 +1,0 @@
-/*
- Copyright (C) 2003-2008 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 "lvec.h"
-struct _aubio_filter_t {
- uint_t order;
- lvec_t * a;
- lvec_t * b;
- lvec_t * y;
- lvec_t * x;
-};
-
-
--- /dev/null
+++ b/tests/src/temporal/test-aweighting.c
@@ -1,0 +1,37 @@
+#include <aubio.h>
+
+int main(){
+
+ aubio_filter_t * f;
+
+ uint_t rates[] = { 8000, 16000, 22050, 44100, 96000, 192000};
+ uint_t nrates = 6;
+ uint_t samplerate, i = 0;
+ uint_t channels = 2;
+
+ for ( samplerate = rates[i]; i < nrates ; i++ ) {
+ f = new_aubio_filter_adsgn (samplerate, channels);
+ del_aubio_filter (f);
+
+ f = new_aubio_filter (samplerate, 7, channels*2);
+ aubio_filter_set_adsgn (f);
+ del_aubio_filter (f);
+ }
+
+ // samplerate unknown
+ f = new_aubio_filter_adsgn (12089, channels);
+ del_aubio_filter (f);
+
+ // order to small
+ f = new_aubio_filter (samplerate, 2, channels*2);
+ aubio_filter_set_adsgn (f);
+ del_aubio_filter (f);
+
+ // order to big
+ f = new_aubio_filter (samplerate, 12, channels*2);
+ aubio_filter_set_adsgn (f);
+ del_aubio_filter (f);
+
+ return 0;
+}
+
--- /dev/null
+++ b/tests/src/temporal/test-cweighting.c
@@ -1,0 +1,37 @@
+#include <aubio.h>
+
+int main(){
+
+ aubio_filter_t * f;
+
+ uint_t rates[] = { 8000, 16000, 22050, 44100, 96000, 192000};
+ uint_t nrates = 6;
+ uint_t samplerate, i = 0;
+ uint_t channels = 2;
+
+ for ( samplerate = rates[i]; i < nrates ; i++ ) {
+ f = new_aubio_filter_cdsgn (samplerate, channels);
+ del_aubio_filter (f);
+
+ f = new_aubio_filter (samplerate, 5, channels*2);
+ aubio_filter_set_cdsgn (f);
+ del_aubio_filter (f);
+ }
+
+ // samplerate unknown
+ f = new_aubio_filter_cdsgn (12089, channels);
+ del_aubio_filter (f);
+
+ // order to small
+ f = new_aubio_filter (samplerate, 2, channels*2);
+ aubio_filter_set_cdsgn (f);
+ del_aubio_filter (f);
+
+ // order to big
+ f = new_aubio_filter (samplerate, 12, channels*2);
+ aubio_filter_set_cdsgn (f);
+ del_aubio_filter (f);
+
+ return 0;
+}
+
--- a/tests/src/test-filter.c
+++ b/tests/src/test-filter.c
@@ -8,7 +8,7 @@
fvec_t * out = new_fvec (win_s, channels); /* input buffer */
/* allocate fft and other memory space */
- aubio_filter_t * o = new_aubio_cdsgn_filter(44100, channels);
+ aubio_filter_t * o = new_aubio_filter_cdsgn (44100, channels);
aubio_filter_do(o,in);
aubio_filter_do_outplace(o,in,out);