History

add yinfft method, make it default for pd plugin add yinfft method, make it default for pd plugin

Paul Brossier committed 20 years ago

Commit 650e39b1 parent 4994ebb10 files · +258 −12Browse files

Unified · Split

10 files
  1. plugins/puredata/aubiopitch~.c +2 −1
  2. python/aubio/task/pitch.py +10 −4
  3. python/aubio/task/utils.py +2 −0
  4. python/aubiopitch +1 −2
  5. src/Makefile.am +3 −0
  6. src/pitchdetection.c +25 −1
  7. src/pitchdetection.h +3 −1
  8. src/pitchyinfft.c +163 −0
  9. src/pitchyinfft.h +45 −0
  10. swig/aubio.i +4 −3
plugins/puredata/aubiopitch~.c+2−1
@@ -12,7 +12,7 @@ · 11 unmodified lines
1212
1313 char aubiopitch_version[] = "aubiopitch~ version 0.1";
1414
15−aubio_pitchdetection_type type_pitch = aubio_pitch_mcomb;
15+aubio_pitchdetection_type type_pitch = aubio_pitch_yinfft;
1616 aubio_pitchdetection_mode mode_pitch = aubio_pitchm_freq;
1717
1818 static t_class *aubiopitch_tilde_class;
@@ -80,6 +80,7 @@ static void *aubiopitch_tilde_new (void) · 61 unmodified lines
8080 //FIXME: get the real samplerate
8181 x->o = new_aubio_pitchdetection(x->bufsize*4,
8282 x->hopsize, 1, 44100., type_pitch, mode_pitch);
83+ aubio_pitchdetection_set_yinthresh(x->o, 0.7);
8384 x->vec = (fvec_t *)new_fvec(x->hopsize,1);
8485
8586 //floatinlet_new (&x->x_obj, &x->threshold);
python/aubio/task/pitch.py+10−4
@@ -7,13 +7,19 @@ class taskpitch(task): · 6 unmodified lines
77 def __init__(self,input,params=None):
88 task.__init__(self,input,params=params)
99 self.shortlist = [0. for i in range(self.params.pitchsmooth)]
10+ if self.params.pitchmode == 'yinfft':
11+ yinthresh = self.params.yinfftthresh
12+ elif self.params.pitchmode == 'yin':
13+ yinthresh = self.params.yinthresh
14+ else:
15+ yinthresh = 0.
1016 self.pitchdet = pitchdetection(mode=get_pitch_mode(self.params.pitchmode),
1117 bufsize=self.params.bufsize,
1218 hopsize=self.params.hopsize,
1319 channels=self.channels,
1420 samplerate=self.srate,
1521 omode=self.params.omode,
16− yinthresh=self.params.yinthresh)
22+ yinthresh=yinthresh)
1723
1824 def __call__(self):
1925 from aubio.median import short_find
@@ -67,7 +73,7 @@ class taskpitch(task): · 47 unmodified lines
6773 time,pitch =[],[]
6874 while(tasksil.readsize==tasksil.params.hopsize):
6975 tasksil()
70− time.append(tasksil.params.step*tasksil.frameread)
76+ time.append(tasksil.params.step*(tasksil.frameread))
7177 if not tasksil.issilence:
7278 pitch.append(self.truth)
7379 else:
@@ -155,7 +161,7 @@ class taskpitch(task): · 81 unmodified lines
155161 title=self.params.pitchmode))
156162
157163
158− def plotplot(self,wplot,oplots,outplot=None,multiplot = 1, midi = 1):
164+ def plotplot(self,wplot,oplots,outplot=None,multiplot = 0, midi = 1):
159165 from aubio.gnuplot import gnuplot_init, audio_to_array, make_audio_plot
160166 import re
161167 import Gnuplot
@@ -197,7 +203,7 @@ class taskpitch(task): · 35 unmodified lines
197203 g('set yrange [100:%f]' % self.params.pitchmax)
198204 else:
199205 g.ylabel('pitch (midi)')
200− g('set yrange [%f:%f]' % (40, aubio_freqtomidi(self.params.pitchmax)))
206+ g('set yrange [%f:%f]' % (aubio_freqtomidi(self.params.pitchmin), aubio_freqtomidi(self.params.pitchmax)))
201207 g('set key right top')
202208 g('set noclip one')
203209 g('set format x ""')
python/aubio/task/utils.py+2−0
@@ -33,6 +33,8 @@ def get_pitch_mode(nvalue): · 32 unmodified lines
3333 return aubio_pitch_fcomb
3434 elif nvalue == 'schmitt':
3535 return aubio_pitch_schmitt
36+ elif nvalue == 'yinfft':
37+ return aubio_pitch_yinfft
3638 else:
3739 import sys
3840 print "error: unknown pitch detection function selected"
python/aubiopitch+1−2
@@ -89,7 +89,7 @@ params.samplerate = float(sndfile(filename).samplerate()) · 88 unmodified lines
8989 params.hopsize = int(options.hopsize)
9090 params.bufsize = int(options.bufsize)
9191 params.step = params.samplerate/float(params.hopsize)
92−params.threshold = float(options.threshold)
92+params.yinthresh = float(options.threshold)
9393 params.silence = float(options.silence)
9494 params.verbose = options.verbose
9595 #mintol = float(options.mintol)*step
@@ -100,7 +100,6 @@ else: delay = 2./params.step · 4 unmodified lines
100100 if options.note:
101101 exit("not implemented yet")
102102
103−
104103 wplot,oplots = [],[]
105104 modes = options.mode.split(',')
106105 for i in range(len(modes)):
src/Makefile.am+3−0
@@ -17,6 +17,7 @@ pkginclude_HEADERS = aubio.h \ · 16 unmodified lines
1717 pitchyin.h \
1818 pitchschmitt.h \
1919 pitchfcomb.h \
20+ pitchyinfft.h \
2021 beattracking.h \
2122 filter.h
2223 nodist_pkginclude_HEADERS = config.h
@@ -56,6 +57,8 @@ libaubio_la_SOURCES = aubio.h \ · 33 unmodified lines
5657 pitchschmitt.h \
5758 pitchfcomb.c \
5859 pitchfcomb.h \
60+ pitchyinfft.c \
61+ pitchyinfft.h \
5962 beattracking.c \
6063 beattracking.h \
6164 filter.c \
src/pitchdetection.c+25−1
@@ -25,6 +25,7 @@ · 24 unmodified lines
2525 #include "pitchyin.h"
2626 #include "pitchfcomb.h"
2727 #include "pitchschmitt.h"
28+#include "pitchyinfft.h"
2829 #include "pitchdetection.h"
2930
3031 typedef smpl_t (*aubio_pitchdetection_func_t)(aubio_pitchdetection_t *p,
@@ -43,6 +44,7 @@ struct _aubio_pitchdetection_t { · 12 unmodified lines
4344 aubio_pitchmcomb_t * mcomb;
4445 aubio_pitchfcomb_t * fcomb;
4546 aubio_pitchschmitt_t * schmitt;
47+ aubio_pitchyinfft_t * yinfft;
4648 aubio_filter_t * filter;
4749 /* for yin */
4850 fvec_t * buf;
@@ -91,7 +93,7 @@ aubio_pitchdetection_t * new_aubio_pitchdetection(uint_t bufsize, · 42 unmodified lines
9193 case aubio_pitch_mcomb:
9294 p->pv = new_aubio_pvoc(bufsize, hopsize, channels);
9395 p->fftgrain = new_cvec(bufsize, channels);
94− p->mcomb = new_aubio_pitchmcomb(bufsize,channels,samplerate);
96+ p->mcomb = new_aubio_pitchmcomb(bufsize,hopsize,channels,samplerate);
9597 p->filter = new_aubio_cdsgn_filter(samplerate);
9698 p->callback = aubio_pitchdetection_mcomb;
9799 break;
@@ -105,6 +107,12 @@ aubio_pitchdetection_t * new_aubio_pitchdetection(uint_t bufsize, · 7 unmodified lines
105107 p->schmitt = new_aubio_pitchschmitt(bufsize,samplerate);
106108 p->callback = aubio_pitchdetection_schmitt;
107109 break;
110+ case aubio_pitch_yinfft:
111+ p->buf = new_fvec(bufsize,channels);
112+ p->yinfft = new_aubio_pitchyinfft(bufsize);
113+ p->callback = aubio_pitchdetection_yinfft;
114+ p->yinthres = 0.2;
115+ break;
108116 default:
109117 break;
110118 }
@@ -147,6 +155,10 @@ void del_aubio_pitchdetection(aubio_pitchdetection_t * p) { · 36 unmodified lines
147155 del_fvec(p->buf);
148156 del_aubio_pitchfcomb(p->fcomb);
149157 break;
158+ case aubio_pitch_yinfft:
159+ del_fvec(p->buf);
160+ del_aubio_pitchyinfft(p->yinfft);
161+ break;
150162 default:
151163 break;
152164 }
@@ -205,6 +217,18 @@ smpl_t aubio_pitchdetection_yin(aubio_pitchdetection_t *p, fvec_t *ibuf) { · 52 unmodified lines
205217 }
206218
207219
220+smpl_t aubio_pitchdetection_yinfft(aubio_pitchdetection_t *p, fvec_t *ibuf){
221+ smpl_t pitch = 0.;
222+ aubio_pitchdetection_slideblock(p,ibuf);
223+ pitch = aubio_pitchyinfft_detect(p->yinfft,p->buf,p->yinthres);
224+ if (pitch>0) {
225+ pitch = p->srate/(pitch+0.);
226+ } else {
227+ pitch = 0.;
228+ }
229+ return pitch;
230+}
231+
208232 smpl_t aubio_pitchdetection_fcomb(aubio_pitchdetection_t *p, fvec_t *ibuf){
209233 aubio_pitchdetection_slideblock(p,ibuf);
210234 return aubio_pitchfcomb_detect(p->fcomb,p->buf);
src/pitchdetection.h+3−1
@@ -27,7 +27,8 @@ typedef enum { · 26 unmodified lines
2727 aubio_pitch_yin,
2828 aubio_pitch_mcomb,
2929 aubio_pitch_schmitt,
30− aubio_pitch_fcomb
30+ aubio_pitch_fcomb,
31+ aubio_pitch_yinfft
3132 } aubio_pitchdetection_type;
3233
3334 typedef enum {
@@ -44,6 +45,7 @@ smpl_t aubio_pitchdetection_mcomb(aubio_pitchdetection_t *p, fvec_t * ibuf); · 10 unmodified lines
4445 smpl_t aubio_pitchdetection_yin(aubio_pitchdetection_t *p, fvec_t *ibuf);
4546 smpl_t aubio_pitchdetection_schmitt(aubio_pitchdetection_t *p, fvec_t *ibuf);
4647 smpl_t aubio_pitchdetection_fcomb(aubio_pitchdetection_t *p, fvec_t *ibuf);
48+smpl_t aubio_pitchdetection_yinfft(aubio_pitchdetection_t *p, fvec_t *ibuf);
4749
4850 void aubio_pitchdetection_set_yinthresh(aubio_pitchdetection_t *p, smpl_t thres);
4951 void del_aubio_pitchdetection(aubio_pitchdetection_t * p);
src/pitchyinfft.c+163−0
@@ -0,0 +1,163 @@
1+/*
2+ Copyright (C) 2003 Paul Brossier
3+
4+ This program is free software; you can redistribute it and/or modify
5+ it under the terms of the GNU General Public License as published by
6+ the Free Software Foundation; either version 2 of the License, or
7+ (at your option) any later version.
8+
9+ This program is distributed in the hope that it will be useful,
10+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ GNU General Public License for more details.
13+
14+ You should have received a copy of the GNU General Public License
15+ along with this program; if not, write to the Free Software
16+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17+*/
18+
19+/* This algorithm was developped by A. de Cheveigne and H. Kawahara and
20+ * published in:
21+ *
22+ * de Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
23+ * estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
24+ *
25+ * see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
26+ *
27+ * This implementation is using an FFT to compute the square difference
28+ * function, which allows spectral weighting
29+ *
30+ */
31+
32+#include "aubio_priv.h"
33+#include "sample.h"
34+#include "mathutils.h"
35+#include "fft.h"
36+#include "pitchyinfft.h"
37+
38+struct _aubio_pitchyinfft_t {
39+ uint_t bufsize;
40+ uint_t rate;
41+ fvec_t * win;
42+ fvec_t * winput;
43+ cvec_t * res;
44+ fvec_t * sqrmag;
45+ fvec_t * weight;
46+ cvec_t * fftout;
47+ aubio_mfft_t * fft;
48+ fvec_t * yinfft;
49+};
50+
51+static const smpl_t freqs[] = {0., 20., 25., 31.5, 40., 50., 63., 80., 100.,
52+ 125., 160., 200., 250., 315., 400., 500., 630., 800., 1000., 1250.,
53+ 1600., 2000., 2500., 3150., 4000., 5000., 6300., 8000., 9000., 10000.,
54+ 12500., 15000., 20000., 25100};
55+
56+static const smpl_t weight[] = {-75.8, -70.1, -60.8, -52.1, -44.2, -37.5,
57+ -31.3, -25.6, -20.9, -16.5, -12.6, -9.6, -7.0, -4.7, -3.0, -1.8, -0.8,
58+ -0.2, -0.0, 0.5, 1.6, 3.2, 5.4, 7.8, 8.1, 5.3, -2.4, -11.1, -12.8,
59+ -12.2, -7.4, -17.8, -17.8, -17.8};
60+
61+aubio_pitchyinfft_t * new_aubio_pitchyinfft (uint_t bufsize)
62+{
63+ aubio_pitchyinfft_t * p = AUBIO_NEW(aubio_pitchyinfft_t);
64+ p->bufsize = bufsize;
65+ p->winput = new_fvec(bufsize,1);
66+ p->fft = new_aubio_mfft(bufsize, 1);
67+ p->fftout = new_cvec(bufsize,1);
68+ p->sqrmag = new_fvec(bufsize,1);
69+ p->res = new_cvec(bufsize,1);
70+ p->yinfft = new_fvec(bufsize/2+1,1);
71+ p->win = new_fvec(bufsize,1);
72+ aubio_window(p->win->data[0], bufsize, aubio_win_hanningz);
73+ p->weight = new_fvec(bufsize/2+1,1);
74+ {
75+ uint_t i = 0, j = 1;
76+ smpl_t freq = 0, a0 = 0, a1 = 0, f0 = 0, f1 = 0;
77+ for (i=0; i<p->weight->length; i++) {
78+ freq = (smpl_t)i/(smpl_t)bufsize*(smpl_t)44100.;
79+ while (freq > freqs[j]) {
80+ j +=1;
81+ }
82+ a0 = weight[j-1];
83+ f0 = freqs[j-1];
84+ a1 = weight[j];
85+ f1 = freqs[j];
86+ if (f0 == f1) { // just in case
87+ p->weight->data[0][i] = a0;
88+ } else if (f0 == 0) { // y = ax+b
89+ p->weight->data[0][i] = (a1-a0)/f1*freq + a0;
90+ } else {
91+ p->weight->data[0][i] = (a1-a0)/(f1-f0)*freq +
92+ (a0 - (a1 - a0)/(f1/f0 - 1.));
93+ }
94+ while (freq > freqs[j]) {
95+ j +=1;
96+ }
97+ //AUBIO_DBG("%f\n",p->weight->data[0][i]);
98+ p->weight->data[0][i] = DB2LIN(p->weight->data[0][i]);
99+ //p->weight->data[0][i] = SQRT(DB2LIN(p->weight->data[0][i]));
100+ }
101+ }
102+ return p;
103+}
104+
105+smpl_t aubio_pitchyinfft_detect(aubio_pitchyinfft_t * p, fvec_t * input, smpl_t tol) {
106+ uint_t tau, l = 0;
107+ uint_t halfperiod;
108+ smpl_t tmp = 0, sum = 0;
109+ cvec_t * res = (cvec_t *)p->res;
110+ fvec_t * yin = (fvec_t *)p->yinfft;
111+ for (l=0; l < input->length; l++){
112+ p->winput->data[0][l] = p->win->data[0][l] * input->data[0][l];
113+ }
114+ aubio_mfft_do(p->fft,p->winput,p->fftout);
115+ for (l=0; l < p->fftout->length; l++){
116+ p->sqrmag->data[0][l] = SQR(p->fftout->norm[0][l]);
117+ p->sqrmag->data[0][(p->fftout->length-1)*2-l] =
118+ SQR(p->fftout->norm[0][l]);
119+ p->sqrmag->data[0][l] *= p->weight->data[0][l];
120+ p->sqrmag->data[0][(p->fftout->length-1)*2-l] *=
121+ p->weight->data[0][l];
122+ }
123+ for (l=0; l < p->sqrmag->length/2+1; l++) {
124+ sum += p->sqrmag->data[0][l];
125+ }
126+ sum *= 2.;
127+ aubio_mfft_do(p->fft,p->sqrmag,res);
128+ yin->data[0][0] = 1.;
129+ for (tau=1; tau < yin->length; tau++) {
130+ yin->data[0][tau] = sum -
131+ res->norm[0][tau+1]*COS(res->phas[0][tau+1]);
132+ tmp += yin->data[0][tau];
133+ yin->data[0][tau] *= tau/tmp;
134+ }
135+ tau = vec_min_elem(yin);
136+ if (yin->data[0][tau] < tol) {
137+ /* no interpolation */
138+ //return tau+2;
139+ /* 3 point quadratic interpolation */
140+ //return vec_quadint_min(yin,tau,1);
141+ /* additional check nlikely octave doubling in higher frequencies */
142+ if (tau>35) {
143+ return vec_quadint_min(yin,tau,1)+1;
144+ } else {
145+ /* should compare the minimum value of each interpolated peaks */
146+ halfperiod = FLOOR(tau/2+.5);
147+ if (yin->data[0][halfperiod] < tol)
148+ return vec_quadint_min(yin,halfperiod,1)+1;
149+ else
150+ return vec_quadint_min(yin,tau,1)+1;
151+ }
152+ } else
153+ return 0;
154+}
155+
156+void del_aubio_pitchyinfft(aubio_pitchyinfft_t *p){
157+ del_fvec(p->win);
158+ del_aubio_mfft(p->fft);
159+ del_fvec(p->yinfft);
160+ del_fvec(p->sqrmag);
161+ del_cvec(p->res);
162+ del_cvec(p->fftout);
163+}
src/pitchyinfft.h+45−0
@@ -0,0 +1,45 @@
1+/*
2+ Copyright (C) 2003 Paul Brossier
3+
4+ This program is free software; you can redistribute it and/or modify
5+ it under the terms of the GNU General Public License as published by
6+ the Free Software Foundation; either version 2 of the License, or
7+ (at your option) any later version.
8+
9+ This program is distributed in the hope that it will be useful,
10+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ GNU General Public License for more details.
13+
14+ You should have received a copy of the GNU General Public License
15+ along with this program; if not, write to the Free Software
16+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17+*/
18+
19+/* This algorithm was developped by A. de Cheveigne and H. Kawahara and
20+ * published in:
21+ *
22+ * de Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
23+ * estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
24+ *
25+ * see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
26+ */
27+
28+#ifndef PITCHYINFFT_H
29+#define PITCHYINFFT_H
30+
31+#ifdef __cplusplus
32+extern "C" {
33+#endif
34+
35+typedef struct _aubio_pitchyinfft_t aubio_pitchyinfft_t;
36+
37+smpl_t aubio_pitchyinfft_detect (aubio_pitchyinfft_t *p, fvec_t * input, smpl_t tol);
38+aubio_pitchyinfft_t * new_aubio_pitchyinfft (uint_t bufsize);
39+void del_aubio_pitchyinfft (aubio_pitchyinfft_t *p);
40+
41+#ifdef __cplusplus
42+}
43+#endif
44+
45+#endif /*PITCHYINFFT_H*/
swig/aubio.i+4−3
@@ -190,7 +190,8 @@ typedef enum { · 189 unmodified lines
190190 aubio_pitch_yin,
191191 aubio_pitch_mcomb,
192192 aubio_pitch_schmitt,
193− aubio_pitch_fcomb
193+ aubio_pitch_fcomb,
194+ aubio_pitch_yinfft
194195 } aubio_pitchdetection_type;
195196
196197 typedef enum {
@@ -217,7 +218,7 @@ aubio_pitchdetection_t * new_aubio_pitchdetection(uint_t bufsize, · 20 unmodified lines
217218
218219
219220 /* pitch mcomb */
220−aubio_pitchmcomb_t * new_aubio_pitchmcomb(uint_t size, uint_t channels, uint_t samplerate);
221+aubio_pitchmcomb_t * new_aubio_pitchmcomb(uint_t bufsize, uint_t hopsize, uint_t channels, uint_t samplerate);
221222 smpl_t aubio_pitchmcomb_detect(aubio_pitchmcomb_t * p, cvec_t * fftgrain);
222223 uint_t aubio_pitch_cands(aubio_pitchmcomb_t * p, cvec_t * fftgrain, smpl_t * cands);
223224 void del_aubio_pitchmcomb (aubio_pitchmcomb_t *p);
@@ -226,7 +227,7 @@ void del_aubio_pitchmcomb (aubio_pitchmcomb_t *p); · 2 unmodified lines
226227 void aubio_pitchyin_diff(fvec_t *input, fvec_t *yin);
227228 void aubio_pitchyin_getcum(fvec_t *yin);
228229 uint_t aubio_pitchyin_getpitch(fvec_t *yin);
229−uint_t aubio_pitchyin_getpitchfast(fvec_t * input, fvec_t *yin, smpl_t tol);
230+smpl_t aubio_pitchyin_getpitchfast(fvec_t * input, fvec_t *yin, smpl_t tol);
230231
231232 /* pitch schmitt */
232233 aubio_pitchschmitt_t * new_aubio_pitchschmitt (uint_t size, uint_t samplerate);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t