source: src/pitchyin.c @ 660c1d82

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 660c1d82 was 1aeac4c, checked in by Paul Brossier <piem@altern.org>, 19 years ago

speeding up yin

  • Property mode set to 100644
File size: 2.8 KB
Line 
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#include "aubio_priv.h"
29#include "sample.h"
30#include "mathutils.h"
31#include "pitchyin.h"
32
33/* outputs the difference function */
34void aubio_pitchyin_diff(fvec_t * input, fvec_t * yin){
35        uint_t c,j,tau;
36        smpl_t tmp;
37        for (c=0;c<input->channels;c++)
38        {
39                for (tau=0;tau<yin->length;tau++)
40                {
41                        yin->data[c][tau] = 0.;
42                }
43                for (tau=1;tau<yin->length;tau++)
44                {
45                        for (j=0;j<yin->length;j++)
46                        {
47                                tmp = input->data[c][j] - input->data[c][j+tau];
48                                yin->data[c][tau] += SQR(tmp);
49                        }
50                }
51        }
52}
53
54/* cumulative mean normalized difference function */
55void aubio_pitchyin_getcum(fvec_t * yin) {
56        uint_t c,tau;
57        smpl_t tmp;
58        for (c=0;c<yin->channels;c++)
59        {
60                tmp = 0.;
61                yin->data[c][0] = 1.;
62                //AUBIO_DBG("%f\t",yin->data[c][0]);
63                for (tau=1;tau<yin->length;tau++)
64                {
65                        tmp += yin->data[c][tau];
66                        yin->data[c][tau] *= tau/tmp;
67                        //AUBIO_DBG("%f\t",yin->data[c][tau]);
68                }
69                //AUBIO_DBG("\n");
70        }
71}
72
73uint_t aubio_pitchyin_getpitch(fvec_t * yin) {
74        uint_t c=0,tau=1;
75        do 
76        {
77                if(yin->data[c][tau] < 0.1) { 
78                        while (yin->data[c][tau+1] < yin->data[c][tau]) {
79                                tau++;
80                        }
81                        return tau;
82                }
83                tau++;
84        } while (tau<yin->length);
85        //AUBIO_DBG("No pitch found");
86        return 0;
87}
88
89
90/* all the above in one */
91uint_t aubio_pitchyin_getpitchfast(fvec_t * input, fvec_t * yin, smpl_t tol){
92        uint_t c=0,j,tau = 0;
93        smpl_t tmp = 0., tmp2 = 0.;
94        yin->data[c][0] = 1.;
95        for (tau=1;tau<yin->length;tau++)
96        {
97                yin->data[c][tau] = 0.;
98                for (j=0;j<yin->length;j++)
99                {
100                        tmp = input->data[c][j] - input->data[c][j+tau];
101                        yin->data[c][tau] += SQR(tmp);
102                }
103                tmp2 += yin->data[c][tau];
104                yin->data[c][tau] *= tau/tmp2;
105                if((yin->data[c][tau] < tol) && 
106                                (yin->data[c][tau-1] < yin->data[c][tau])) {
107                        return tau-1;
108                }
109        }
110        return 0;
111}
112
Note: See TracBrowser for help on using the repository browser.