2 Copyright (C) 2003 Paul Brossier
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.
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.
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.
19 /* This algorithm was developped by A. de Cheveigne and H. Kawahara and
22 * de Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
23 * estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
25 * see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
28 #include "aubio_priv.h"
30 #include "mathutils.h"
33 /* outputs the difference function */
34 void aubio_pitchyin_diff(fvec_t * input, fvec_t * yin){
37 for (c=0;c<input->channels;c++)
39 for (tau=0;tau<yin->length;tau++)
41 yin->data[c][tau] = 0.;
43 for (tau=1;tau<yin->length;tau++)
45 for (j=0;j<yin->length;j++)
47 tmp = input->data[c][j] - input->data[c][j+tau];
48 yin->data[c][tau] += SQR(tmp);
54 /* cumulative mean normalized difference function */
55 void aubio_pitchyin_getcum(fvec_t * yin) {
58 for (c=0;c<yin->channels;c++)
62 //AUBIO_DBG("%f\t",yin->data[c][0]);
63 for (tau=1;tau<yin->length;tau++)
65 tmp += yin->data[c][tau];
66 yin->data[c][tau] *= tau/tmp;
67 //AUBIO_DBG("%f\t",yin->data[c][tau]);
73 uint_t aubio_pitchyin_getpitch(fvec_t * yin) {
77 if(yin->data[c][tau] < 0.1) {
78 while (yin->data[c][tau+1] < yin->data[c][tau]) {
84 } while (tau<yin->length);
85 //AUBIO_DBG("No pitch found");
90 /* all the above in one */
91 smpl_t aubio_pitchyin_getpitchfast(fvec_t * input, fvec_t * yin, smpl_t tol){
94 smpl_t tmp = 0., tmp2 = 0.;
96 for (tau=1;tau<yin->length;tau++)
98 yin->data[c][tau] = 0.;
99 for (j=0;j<yin->length;j++)
101 tmp = input->data[c][j] - input->data[c][j+tau];
102 yin->data[c][tau] += SQR(tmp);
104 tmp2 += yin->data[c][tau];
105 yin->data[c][tau] *= tau/tmp2;
107 if(tau > 4 && (yin->data[c][period] < tol) &&
108 (yin->data[c][period] < yin->data[c][period+1])) {
109 return vec_quadint_min(yin,period,1)-1;