ref: a7667ceb3c80615a37074899e5f62ec7251c4ba2
parent: 2b6144dd1fbe06dd150c77adbd2de8689610ac09
author: Paul Brossier <piem@piem.org>
date: Sat Dec 1 17:59:25 EST 2007
filter.c: add denormal, make multichannel using lvecs, update adsgn, cdsgn, pitchdetection
--- a/src/pitch/pitchdetection.c
+++ b/src/pitch/pitchdetection.c
@@ -21,7 +21,7 @@
#include "cvec.h"
#include "spectral/phasevoc.h"
#include "mathutils.h"
-#include "temporal/filter.h"
+#include "temporal/cdesign.h"
#include "pitch/pitchmcomb.h"
#include "pitch/pitchyin.h"
#include "pitch/pitchfcomb.h"
@@ -102,7 +102,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);
+ p->filter = new_aubio_cdsgn_filter(samplerate, channels);
p->callback = aubio_pitchdetection_mcomb;
break;
case aubio_pitch_fcomb:
--- a/src/temporal/adesign.c
+++ b/src/temporal/adesign.c
@@ -25,10 +25,10 @@
#include "temporal/filter_priv.h"
#include "temporal/adesign.h"
-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;
+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;
@@ -51,8 +51,8 @@
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;
+ f->a->data[0] = a;
+ f->b->data[0] = b;
return f;
}
--- a/src/temporal/adesign.h
+++ b/src/temporal/adesign.h
@@ -22,7 +22,7 @@
\param samplerate sampling-rate of the signal to filter
*/
-aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate);
+aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate, uint_t channels);
#define aubio_adsgn_filter_do aubio_filter_do
#define del_aubio_adsgn_filter del_aubio_filter
--- a/src/temporal/cdesign.c
+++ b/src/temporal/cdesign.c
@@ -25,10 +25,10 @@
#include "temporal/filter_priv.h"
#include "temporal/adesign.h"
-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;
+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;
@@ -47,8 +47,8 @@
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;
+ f->a->data[0] = a;
+ f->b->data[0] = b;
return f;
}
--- a/src/temporal/cdesign.h
+++ b/src/temporal/cdesign.h
@@ -24,7 +24,7 @@
\param samplerate sampling-rate of the signal to filter
*/
-aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate);
+aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate, uint_t channels);
#define aubio_cdsgn_filter_do aubio_filter_do
#define del_aubio_cdsgn_filter del_aubio_filter
--- a/src/temporal/filter.c
+++ b/src/temporal/filter.c
@@ -23,72 +23,49 @@
#include "aubio_priv.h"
#include "fvec.h"
+#include "lvec.h"
#include "mathutils.h"
#include "temporal/filter.h"
#include "temporal/filter_priv.h"
-/* 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;i<in->channels;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;l<order; l++) {
- y[0] += b[l] * x[l];
- y[0] -= a[l] * y[l];
- } /* + 1e-37; for denormal ? */
- /* new output */
- in->data[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;
- //}
+ aubio_filter_do_outplace(f, in, in);
}
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;
+ lsmp_t *x;
+ lsmp_t *y;
+ lsmp_t *a = f->a->data[0];
+ lsmp_t *b = f->b->data[0];
- i=0; // works in mono only !!!
- //for (i=0;i<in->channels;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;l<order; l++) {
- y[0] += b[l] * x[l];
- y[0] -= a[l] * y[l];
+ for (i = 0; i < in->channels; i++) {
+ x = f->x->data[i];
+ y = f->y->data[i];
+ for (j = 0; j < in->length; j++) {
+ /* new input */
+ if (ISDENORMAL(in->data[i][j])) {
+ x[0] = y[0] = 0.;
+ } else {
+ x[0] = in->data[i][j];
+ y[0] = b[0] * x[0];
+ for (l=1;l<order; l++) {
+ y[0] += b[l] * x[l];
+ y[0] -= a[l] * y[l];
+ }
+ }
+ /* new output */
+ out->data[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];
+ }
}
- // + 1e-37;
- /* new output */
- out->data[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->data[i] = x;
+ f->y->data[i] = y;
}
- /* store for next run */
- f->x = x;
- f->y = y;
- //}
}
/*
@@ -125,27 +102,14 @@
in->data[i][j] = tmp->data[i][length-j-1];
}
-aubio_filter_t * new_aubio_filter(uint_t samplerate UNUSED, uint_t order) {
+aubio_filter_t * new_aubio_filter(uint_t samplerate UNUSED, uint_t order, uint_t channels) {
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->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->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; l<f->order; l++){
- x[l] = 0.;
- y[l] = 0.;
- }
- f->x = x;
- f->y = y;
- f->a = a;
- f->b = b;
return f;
}
--- a/src/temporal/filter.h
+++ b/src/temporal/filter.h
@@ -68,9 +68,10 @@
\param samplerate signal sampling rate
\param order order of the filter (number of coefficients)
+ \param channels number of channels to allocate
*/
-aubio_filter_t * new_aubio_filter(uint_t samplerate, uint_t order);
+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
+++ b/src/temporal/filter_priv.h
@@ -17,12 +17,13 @@
*/
+#include "lvec.h"
struct _aubio_filter_t {
uint_t order;
- lsmp_t * a;
- lsmp_t * b;
- lsmp_t * y;
- lsmp_t * x;
+ lvec_t * a;
+ lvec_t * b;
+ lvec_t * y;
+ lvec_t * x;
};
--- a/swig/aubio.i
+++ b/swig/aubio.i
@@ -85,18 +85,17 @@
extern void aubio_fft_get_real(cvec_t * spectrum, fvec_t * compspec);
/* filter */
-extern aubio_filter_t * new_aubio_filter(uint_t samplerate, uint_t order);
-extern aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate);
+extern aubio_filter_t * new_aubio_filter(uint_t samplerate, uint_t order, uint_t channels);
extern void aubio_filter_do(aubio_filter_t * b, fvec_t * in);
extern void aubio_filter_do_outplace(aubio_filter_t * b, fvec_t * in, fvec_t * out);
extern void aubio_filter_do_filtfilt(aubio_filter_t * b, fvec_t * in, fvec_t * tmp);
extern void del_aubio_filter(aubio_filter_t * b);
-extern aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate);
+extern aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate, uint_t channels);
extern void aubio_adsgn_filter_do(aubio_filter_t * b, fvec_t * in);
extern void del_aubio_adsgn_filter(aubio_filter_t * b);
-extern aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate);
+extern aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate, uint_t channels);
extern void aubio_cdsgn_filter_do(aubio_filter_t * b, fvec_t * in);
extern void del_aubio_cdsgn_filter(aubio_filter_t * b);