ref: 650e39b95abdb31b0efd5bcffd3d6e09f01ea658
parent: 4994ebb0b9c40c198883ef0bfc300d29669b72fe
author: Paul Brossier <piem@altern.org>
date: Tue Mar 21 17:59:17 EST 2006
add yinfft method, make it default for pd plugin add yinfft method, make it default for pd plugin
--- a/plugins/puredata/aubiopitch~.c
+++ b/plugins/puredata/aubiopitch~.c
@@ -12,7 +12,7 @@
char aubiopitch_version[] = "aubiopitch~ version 0.1";
-aubio_pitchdetection_type type_pitch = aubio_pitch_mcomb;
+aubio_pitchdetection_type type_pitch = aubio_pitch_yinfft;
aubio_pitchdetection_mode mode_pitch = aubio_pitchm_freq;
static t_class *aubiopitch_tilde_class;
@@ -80,6 +80,7 @@
//FIXME: get the real samplerate
x->o = new_aubio_pitchdetection(x->bufsize*4,
x->hopsize, 1, 44100., type_pitch, mode_pitch);
+ aubio_pitchdetection_set_yinthresh(x->o, 0.7);
x->vec = (fvec_t *)new_fvec(x->hopsize,1);
//floatinlet_new (&x->x_obj, &x->threshold);
--- a/python/aubio/task/pitch.py
+++ b/python/aubio/task/pitch.py
@@ -7,6 +7,12 @@
def __init__(self,input,params=None):
task.__init__(self,input,params=params)
self.shortlist = [0. for i in range(self.params.pitchsmooth)]
+ if self.params.pitchmode == 'yinfft':
+ yinthresh = self.params.yinfftthresh
+ elif self.params.pitchmode == 'yin':
+ yinthresh = self.params.yinthresh
+ else:
+ yinthresh = 0.
self.pitchdet = pitchdetection(mode=get_pitch_mode(self.params.pitchmode),
bufsize=self.params.bufsize,
hopsize=self.params.hopsize,
@@ -13,7 +19,7 @@
channels=self.channels,
samplerate=self.srate,
omode=self.params.omode,
- yinthresh=self.params.yinthresh)
+ yinthresh=yinthresh)
def __call__(self):
from aubio.median import short_find
@@ -67,7 +73,7 @@
time,pitch =[],[]
while(tasksil.readsize==tasksil.params.hopsize):
tasksil()
- time.append(tasksil.params.step*tasksil.frameread)
+ time.append(tasksil.params.step*(tasksil.frameread))
if not tasksil.issilence:
pitch.append(self.truth)
else:
@@ -155,7 +161,7 @@
title=self.params.pitchmode))
- def plotplot(self,wplot,oplots,outplot=None,multiplot = 1, midi = 1):
+ def plotplot(self,wplot,oplots,outplot=None,multiplot = 0, midi = 1):
from aubio.gnuplot import gnuplot_init, audio_to_array, make_audio_plot
import re
import Gnuplot
@@ -197,7 +203,7 @@
g('set yrange [100:%f]' % self.params.pitchmax)
else:
g.ylabel('pitch (midi)')
- g('set yrange [%f:%f]' % (40, aubio_freqtomidi(self.params.pitchmax)))
+ g('set yrange [%f:%f]' % (aubio_freqtomidi(self.params.pitchmin), aubio_freqtomidi(self.params.pitchmax)))
g('set key right top')
g('set noclip one')
g('set format x ""')
--- a/python/aubio/task/utils.py
+++ b/python/aubio/task/utils.py
@@ -33,6 +33,8 @@
return aubio_pitch_fcomb
elif nvalue == 'schmitt':
return aubio_pitch_schmitt
+ elif nvalue == 'yinfft':
+ return aubio_pitch_yinfft
else:
import sys
print "error: unknown pitch detection function selected"
--- a/python/aubiopitch
+++ b/python/aubiopitch
@@ -89,7 +89,7 @@
params.hopsize = int(options.hopsize)
params.bufsize = int(options.bufsize)
params.step = params.samplerate/float(params.hopsize)
-params.threshold = float(options.threshold)
+params.yinthresh = float(options.threshold)
params.silence = float(options.silence)
params.verbose = options.verbose
#mintol = float(options.mintol)*step
@@ -99,7 +99,6 @@
if options.note:
exit("not implemented yet")
-
wplot,oplots = [],[]
modes = options.mode.split(',')
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,6 +17,7 @@
pitchyin.h \
pitchschmitt.h \
pitchfcomb.h \
+ pitchyinfft.h \
beattracking.h \
filter.h
nodist_pkginclude_HEADERS = config.h
@@ -56,6 +57,8 @@
pitchschmitt.h \
pitchfcomb.c \
pitchfcomb.h \
+ pitchyinfft.c \
+ pitchyinfft.h \
beattracking.c \
beattracking.h \
filter.c \
--- a/src/pitchdetection.c
+++ b/src/pitchdetection.c
@@ -25,6 +25,7 @@
#include "pitchyin.h"
#include "pitchfcomb.h"
#include "pitchschmitt.h"
+#include "pitchyinfft.h"
#include "pitchdetection.h"
typedef smpl_t (*aubio_pitchdetection_func_t)(aubio_pitchdetection_t *p,
@@ -43,6 +44,7 @@
aubio_pitchmcomb_t * mcomb;
aubio_pitchfcomb_t * fcomb;
aubio_pitchschmitt_t * schmitt;
+ aubio_pitchyinfft_t * yinfft;
aubio_filter_t * filter;
/* for yin */
fvec_t * buf;
@@ -91,7 +93,7 @@
case aubio_pitch_mcomb:
p->pv = new_aubio_pvoc(bufsize, hopsize, channels);
p->fftgrain = new_cvec(bufsize, channels);
- p->mcomb = new_aubio_pitchmcomb(bufsize,channels,samplerate);
+ p->mcomb = new_aubio_pitchmcomb(bufsize,hopsize,channels,samplerate);
p->filter = new_aubio_cdsgn_filter(samplerate);
p->callback = aubio_pitchdetection_mcomb;
break;
@@ -105,6 +107,12 @@
p->schmitt = new_aubio_pitchschmitt(bufsize,samplerate);
p->callback = aubio_pitchdetection_schmitt;
break;
+ case aubio_pitch_yinfft:
+ p->buf = new_fvec(bufsize,channels);
+ p->yinfft = new_aubio_pitchyinfft(bufsize);
+ p->callback = aubio_pitchdetection_yinfft;
+ p->yinthres = 0.2;
+ break;
default:
break;
}
@@ -147,6 +155,10 @@
del_fvec(p->buf);
del_aubio_pitchfcomb(p->fcomb);
break;
+ case aubio_pitch_yinfft:
+ del_fvec(p->buf);
+ del_aubio_pitchyinfft(p->yinfft);
+ break;
default:
break;
}
@@ -204,6 +216,18 @@
return pitch;
}
+
+smpl_t aubio_pitchdetection_yinfft(aubio_pitchdetection_t *p, fvec_t *ibuf){
+ smpl_t pitch = 0.;
+ aubio_pitchdetection_slideblock(p,ibuf);
+ pitch = aubio_pitchyinfft_detect(p->yinfft,p->buf,p->yinthres);
+ if (pitch>0) {
+ pitch = p->srate/(pitch+0.);
+ } else {
+ pitch = 0.;
+ }
+ return pitch;
+}
smpl_t aubio_pitchdetection_fcomb(aubio_pitchdetection_t *p, fvec_t *ibuf){
aubio_pitchdetection_slideblock(p,ibuf);
--- a/src/pitchdetection.h
+++ b/src/pitchdetection.h
@@ -27,7 +27,8 @@
aubio_pitch_yin,
aubio_pitch_mcomb,
aubio_pitch_schmitt,
- aubio_pitch_fcomb
+ aubio_pitch_fcomb,
+ aubio_pitch_yinfft
} aubio_pitchdetection_type;
typedef enum {
@@ -44,6 +45,7 @@
smpl_t aubio_pitchdetection_yin(aubio_pitchdetection_t *p, fvec_t *ibuf);
smpl_t aubio_pitchdetection_schmitt(aubio_pitchdetection_t *p, fvec_t *ibuf);
smpl_t aubio_pitchdetection_fcomb(aubio_pitchdetection_t *p, fvec_t *ibuf);
+smpl_t aubio_pitchdetection_yinfft(aubio_pitchdetection_t *p, fvec_t *ibuf);
void aubio_pitchdetection_set_yinthresh(aubio_pitchdetection_t *p, smpl_t thres);
void del_aubio_pitchdetection(aubio_pitchdetection_t * p);
--- /dev/null
+++ b/src/pitchyinfft.c
@@ -1,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.
+*/
+
+/* This algorithm was developped by A. de Cheveigne and H. Kawahara and
+ * published in:
+ *
+ * de Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
+ * estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
+ *
+ * see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
+ *
+ * This implementation is using an FFT to compute the square difference
+ * function, which allows spectral weighting
+ *
+ */
+
+#include "aubio_priv.h"
+#include "sample.h"
+#include "mathutils.h"
+#include "fft.h"
+#include "pitchyinfft.h"
+
+struct _aubio_pitchyinfft_t {
+ uint_t bufsize;
+ uint_t rate;
+ fvec_t * win;
+ fvec_t * winput;
+ cvec_t * res;
+ fvec_t * sqrmag;
+ fvec_t * weight;
+ cvec_t * fftout;
+ aubio_mfft_t * fft;
+ fvec_t * yinfft;
+};
+
+static const smpl_t freqs[] = {0., 20., 25., 31.5, 40., 50., 63., 80., 100.,
+ 125., 160., 200., 250., 315., 400., 500., 630., 800., 1000., 1250.,
+ 1600., 2000., 2500., 3150., 4000., 5000., 6300., 8000., 9000., 10000.,
+ 12500., 15000., 20000., 25100};
+
+static const smpl_t weight[] = {-75.8, -70.1, -60.8, -52.1, -44.2, -37.5,
+ -31.3, -25.6, -20.9, -16.5, -12.6, -9.6, -7.0, -4.7, -3.0, -1.8, -0.8,
+ -0.2, -0.0, 0.5, 1.6, 3.2, 5.4, 7.8, 8.1, 5.3, -2.4, -11.1, -12.8,
+ -12.2, -7.4, -17.8, -17.8, -17.8};
+
+aubio_pitchyinfft_t * new_aubio_pitchyinfft (uint_t bufsize)
+{
+ aubio_pitchyinfft_t * p = AUBIO_NEW(aubio_pitchyinfft_t);
+ p->bufsize = bufsize;
+ p->winput = new_fvec(bufsize,1);
+ p->fft = new_aubio_mfft(bufsize, 1);
+ p->fftout = new_cvec(bufsize,1);
+ p->sqrmag = new_fvec(bufsize,1);
+ p->res = new_cvec(bufsize,1);
+ p->yinfft = new_fvec(bufsize/2+1,1);
+ p->win = new_fvec(bufsize,1);
+ aubio_window(p->win->data[0], bufsize, aubio_win_hanningz);
+ p->weight = new_fvec(bufsize/2+1,1);
+ {
+ uint_t i = 0, j = 1;
+ smpl_t freq = 0, a0 = 0, a1 = 0, f0 = 0, f1 = 0;
+ for (i=0; i<p->weight->length; i++) {
+ freq = (smpl_t)i/(smpl_t)bufsize*(smpl_t)44100.;
+ while (freq > freqs[j]) {
+ j +=1;
+ }
+ a0 = weight[j-1];
+ f0 = freqs[j-1];
+ a1 = weight[j];
+ f1 = freqs[j];
+ if (f0 == f1) { // just in case
+ p->weight->data[0][i] = a0;
+ } else if (f0 == 0) { // y = ax+b
+ p->weight->data[0][i] = (a1-a0)/f1*freq + a0;
+ } else {
+ p->weight->data[0][i] = (a1-a0)/(f1-f0)*freq +
+ (a0 - (a1 - a0)/(f1/f0 - 1.));
+ }
+ while (freq > freqs[j]) {
+ j +=1;
+ }
+ //AUBIO_DBG("%f\n",p->weight->data[0][i]);
+ p->weight->data[0][i] = DB2LIN(p->weight->data[0][i]);
+ //p->weight->data[0][i] = SQRT(DB2LIN(p->weight->data[0][i]));
+ }
+ }
+ return p;
+}
+
+smpl_t aubio_pitchyinfft_detect(aubio_pitchyinfft_t * p, fvec_t * input, smpl_t tol) {
+ uint_t tau, l = 0;
+ uint_t halfperiod;
+ smpl_t tmp = 0, sum = 0;
+ cvec_t * res = (cvec_t *)p->res;
+ fvec_t * yin = (fvec_t *)p->yinfft;
+ for (l=0; l < input->length; l++){
+ p->winput->data[0][l] = p->win->data[0][l] * input->data[0][l];
+ }
+ aubio_mfft_do(p->fft,p->winput,p->fftout);
+ for (l=0; l < p->fftout->length; l++){
+ p->sqrmag->data[0][l] = SQR(p->fftout->norm[0][l]);
+ p->sqrmag->data[0][(p->fftout->length-1)*2-l] =
+ SQR(p->fftout->norm[0][l]);
+ p->sqrmag->data[0][l] *= p->weight->data[0][l];
+ p->sqrmag->data[0][(p->fftout->length-1)*2-l] *=
+ p->weight->data[0][l];
+ }
+ for (l=0; l < p->sqrmag->length/2+1; l++) {
+ sum += p->sqrmag->data[0][l];
+ }
+ sum *= 2.;
+ aubio_mfft_do(p->fft,p->sqrmag,res);
+ yin->data[0][0] = 1.;
+ for (tau=1; tau < yin->length; tau++) {
+ yin->data[0][tau] = sum -
+ res->norm[0][tau+1]*COS(res->phas[0][tau+1]);
+ tmp += yin->data[0][tau];
+ yin->data[0][tau] *= tau/tmp;
+ }
+ tau = vec_min_elem(yin);
+ if (yin->data[0][tau] < tol) {
+ /* no interpolation */
+ //return tau+2;
+ /* 3 point quadratic interpolation */
+ //return vec_quadint_min(yin,tau,1);
+ /* additional check nlikely octave doubling in higher frequencies */
+ if (tau>35) {
+ return vec_quadint_min(yin,tau,1)+1;
+ } else {
+ /* should compare the minimum value of each interpolated peaks */
+ halfperiod = FLOOR(tau/2+.5);
+ if (yin->data[0][halfperiod] < tol)
+ return vec_quadint_min(yin,halfperiod,1)+1;
+ else
+ return vec_quadint_min(yin,tau,1)+1;
+ }
+ } else
+ return 0;
+}
+
+void del_aubio_pitchyinfft(aubio_pitchyinfft_t *p){
+ del_fvec(p->win);
+ del_aubio_mfft(p->fft);
+ del_fvec(p->yinfft);
+ del_fvec(p->sqrmag);
+ del_cvec(p->res);
+ del_cvec(p->fftout);
+}
--- /dev/null
+++ b/src/pitchyinfft.h
@@ -1,0 +1,45 @@
+/*
+ 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.
+*/
+
+/* This algorithm was developped by A. de Cheveigne and H. Kawahara and
+ * published in:
+ *
+ * de Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
+ * estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
+ *
+ * see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
+ */
+
+#ifndef PITCHYINFFT_H
+#define PITCHYINFFT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _aubio_pitchyinfft_t aubio_pitchyinfft_t;
+
+smpl_t aubio_pitchyinfft_detect (aubio_pitchyinfft_t *p, fvec_t * input, smpl_t tol);
+aubio_pitchyinfft_t * new_aubio_pitchyinfft (uint_t bufsize);
+void del_aubio_pitchyinfft (aubio_pitchyinfft_t *p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*PITCHYINFFT_H*/
--- a/swig/aubio.i
+++ b/swig/aubio.i
@@ -190,7 +190,8 @@
aubio_pitch_yin,
aubio_pitch_mcomb,
aubio_pitch_schmitt,
- aubio_pitch_fcomb
+ aubio_pitch_fcomb,
+ aubio_pitch_yinfft
} aubio_pitchdetection_type;
typedef enum {
@@ -217,7 +218,7 @@
/* pitch mcomb */
-aubio_pitchmcomb_t * new_aubio_pitchmcomb(uint_t size, uint_t channels, uint_t samplerate);
+aubio_pitchmcomb_t * new_aubio_pitchmcomb(uint_t bufsize, uint_t hopsize, uint_t channels, uint_t samplerate);
smpl_t aubio_pitchmcomb_detect(aubio_pitchmcomb_t * p, cvec_t * fftgrain);
uint_t aubio_pitch_cands(aubio_pitchmcomb_t * p, cvec_t * fftgrain, smpl_t * cands);
void del_aubio_pitchmcomb (aubio_pitchmcomb_t *p);
@@ -226,7 +227,7 @@
void aubio_pitchyin_diff(fvec_t *input, fvec_t *yin);
void aubio_pitchyin_getcum(fvec_t *yin);
uint_t aubio_pitchyin_getpitch(fvec_t *yin);
-uint_t aubio_pitchyin_getpitchfast(fvec_t * input, fvec_t *yin, smpl_t tol);
+smpl_t aubio_pitchyin_getpitchfast(fvec_t * input, fvec_t *yin, smpl_t tol);
/* pitch schmitt */
aubio_pitchschmitt_t * new_aubio_pitchschmitt (uint_t size, uint_t samplerate);