ref: 22d33e22c85d5ff1699897f0ef5b6c251a6a5a13
parent: 2ba3440468478fdaaf5b4fbc11e7103d54f7500e
author: Paul Brossier <piem@piem.org>
date: Thu Oct 8 16:49:10 EDT 2009
src/pitch/pitchyinfft.{c,h}: add get/set for tolerance, clean and update prototypes, make multichannel
--- a/src/pitch/pitchyinfft.c
+++ b/src/pitch/pitchyinfft.c
@@ -33,6 +33,7 @@
cvec_t * fftout; /**< Fourier transform output */
aubio_fft_t * fft; /**< fft object to compute square difference function */
fvec_t * yinfft; /**< Yin function */
+ smpl_t tol; /**< Yin tolerance */
};
static const smpl_t freqs[] = {0., 20., 25., 31.5, 40., 50., 63., 80., 100.,
@@ -54,6 +55,7 @@
p->sqrmag = new_fvec(bufsize,1);
p->res = new_cvec(bufsize,1);
p->yinfft = new_fvec(bufsize/2+1,1);
+ p->tol = 0.85;
p->win = new_aubio_window(bufsize, aubio_win_hanningz);
p->weight = new_fvec(bufsize/2+1,1);
{
@@ -87,14 +89,16 @@
return p;
}
-smpl_t aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, fvec_t * input, smpl_t tol) {
- uint_t tau, l = 0;
+void aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, fvec_t * input, fvec_t * output) {
+ uint_t i, tau, l;
uint_t halfperiod;
- smpl_t tmp = 0, sum = 0;
+ smpl_t tmp, sum;
cvec_t * res = (cvec_t *)p->res;
fvec_t * yin = (fvec_t *)p->yinfft;
+ for (i=0; i < input->channels; i++){
+ l = 0; tmp = 0.; sum = 0.;
for (l=0; l < input->length; l++){
- p->winput->data[0][l] = p->win->data[0][l] * input->data[0][l];
+ p->winput->data[0][l] = p->win->data[0][l] * input->data[i][l];
}
aubio_fft_do(p->fft,p->winput,p->fftout);
for (l=0; l < p->fftout->length; l++){
@@ -120,7 +124,7 @@
yin->data[0][tau] *= tau/tmp;
}
tau = fvec_min_elem(yin);
- if (yin->data[0][tau] < tol) {
+ if (yin->data[0][tau] < p->tol) {
/* no interpolation */
//return tau;
/* 3 point quadratic interpolation */
@@ -127,17 +131,19 @@
//return fvec_quadint_min(yin,tau,1);
/* additional check for (unlikely) octave doubling in higher frequencies */
if (tau>35) {
- return fvec_quadint(yin,tau,1);
+ output->data[i][0] = fvec_quadint(yin,tau,1);
} else {
/* should compare the minimum value of each interpolated peaks */
halfperiod = FLOOR(tau/2+.5);
- if (yin->data[0][halfperiod] < tol)
- return fvec_quadint(yin,halfperiod,1);
+ if (yin->data[0][halfperiod] < p->tol)
+ output->data[i][0] = fvec_quadint(yin,halfperiod,1);
else
- return fvec_quadint(yin,tau,1);
+ output->data[i][0] = fvec_quadint(yin,tau,1);
}
- } else
- return 0.;
+ } else {
+ output->data[i][0] = 0.;
+ }
+ }
}
void del_aubio_pitchyinfft(aubio_pitchyinfft_t *p){
@@ -150,4 +156,13 @@
del_fvec(p->winput);
del_fvec(p->weight);
AUBIO_FREE(p);
+}
+
+uint_t aubio_pitchyinfft_set_tolerance (aubio_pitchyinfft_t * p, smpl_t tol) {
+ p->tol = tol;
+ return 0;
+}
+
+smpl_t aubio_pitchyinfft_get_tolerance (aubio_pitchyinfft_t * p) {
+ return p->tol;
}
--- a/src/pitch/pitchyinfft.h
+++ b/src/pitch/pitchyinfft.h
@@ -45,10 +45,10 @@
\param p pitch detection object as returned by new_aubio_pitchyinfft
\param input input signal window (length as specified at creation time)
- \param tol tolerance parameter for minima selection [default 0.85]
+ \param output pitch period candidates, in samples
*/
-smpl_t aubio_pitchyinfft_do (aubio_pitchyinfft_t *p, fvec_t * input, smpl_t tol);
+void aubio_pitchyinfft_do (aubio_pitchyinfft_t *p, fvec_t * input, fvec_t * output);
/** creation of the pitch detection object
\param bufsize size of the input buffer to analyse
@@ -61,6 +61,23 @@
*/
void del_aubio_pitchyinfft (aubio_pitchyinfft_t *p);
+
+/** get tolerance parameter for YIN algorithm
+
+ \param o YIN pitch detection object
+
+ \return tolerance parameter for minima selection [default 0.15]
+
+*/
+smpl_t aubio_pitchyinfft_get_tolerance (aubio_pitchyinfft_t * p);
+
+/** set tolerance parameter for YIN algorithm
+
+ \param o YIN pitch detection object
+ \param tol tolerance parameter for minima selection [default 0.15]
+
+*/
+uint_t aubio_pitchyinfft_set_tolerance (aubio_pitchyinfft_t * p, smpl_t tol);
#ifdef __cplusplus
}
--- a/tests/src/test-pitchyinfft.c
+++ b/tests/src/test-pitchyinfft.c
@@ -5,11 +5,13 @@
uint_t win_s = 1024; /* window size */
uint_t channels = 1; /* number of channel */
fvec_t * in = new_fvec (win_s, channels); /* input buffer */
+ fvec_t * out = new_fvec (1, channels); /* output pitch periods */
aubio_pitchyinfft_t * o = new_aubio_pitchyinfft(win_s);
+ aubio_pitchyinfft_set_tolerance (o, 0.2);
uint_t i = 0;
while (i < 10) {
- aubio_pitchyinfft_do (o,in,0.2);
+ aubio_pitchyinfft_do (o,in,out);
i++;
};