source: src/pitch/pitchyin.c @ 2fde783

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 2fde783 was 2ba3440, checked in by Paul Brossier <piem@piem.org>, 15 years ago

src/pitch/pitchyin.{c,h}: add proper aubio_pitchyin_t object, clean and update prototypes, make multichannel

  • Property mode set to 100644
File size: 4.2 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 "fvec.h"
30#include "mathutils.h"
31#include "pitch/pitchyin.h"
32
33struct _aubio_pitchyin_t {
34  fvec_t * yin;
35  smpl_t tol;
36};
37
38/** compute difference function
39 
40  \param input input signal
41  \param yinbuf output buffer to store difference function (half shorter than input)
42
43*/
44void aubio_pitchyin_diff(fvec_t * input, fvec_t * yinbuf);
45
46/** in place computation of the YIN cumulative normalised function
47 
48  \param yinbuf input signal (a square difference function), also used to store function
49
50*/
51void aubio_pitchyin_getcum(fvec_t * yinbuf);
52
53/** detect pitch in a YIN function
54 
55  \param yinbuf input buffer as computed by aubio_pitchyin_getcum
56
57*/
58uint_t aubio_pitchyin_getpitch(fvec_t *yinbuf);
59
60aubio_pitchyin_t * new_aubio_pitchyin (uint_t bufsize) {
61  aubio_pitchyin_t * o = AUBIO_NEW(aubio_pitchyin_t);
62  o->yin = new_fvec (bufsize/2, 1);
63  o->tol = 0.15;
64  return o;
65}
66
67void del_aubio_pitchyin (aubio_pitchyin_t *o) {
68  del_fvec(o->yin);
69  AUBIO_FREE(o);
70}
71
72/* outputs the difference function */
73void aubio_pitchyin_diff(fvec_t * input, fvec_t * yin){
74  uint_t c,j,tau;
75  smpl_t tmp;
76  for (c=0;c<input->channels;c++)
77  {
78    for (tau=0;tau<yin->length;tau++)
79    {
80      yin->data[c][tau] = 0.;
81    }
82    for (tau=1;tau<yin->length;tau++)
83    {
84      for (j=0;j<yin->length;j++)
85      {
86        tmp = input->data[c][j] - input->data[c][j+tau];
87        yin->data[c][tau] += SQR(tmp);
88      }
89    }
90  }
91}
92
93/* cumulative mean normalized difference function */
94void aubio_pitchyin_getcum(fvec_t * yin) {
95  uint_t c,tau;
96  smpl_t tmp;
97  for (c=0;c<yin->channels;c++)
98  {
99    tmp = 0.;
100    yin->data[c][0] = 1.;
101    //AUBIO_DBG("%f\t",yin->data[c][0]);
102    for (tau=1;tau<yin->length;tau++)
103    {
104      tmp += yin->data[c][tau];
105      yin->data[c][tau] *= tau/tmp;
106      //AUBIO_DBG("%f\t",yin->data[c][tau]);
107    }
108    //AUBIO_DBG("\n");
109  }
110}
111
112uint_t aubio_pitchyin_getpitch(fvec_t * yin) {
113  uint_t c=0,tau=1;
114  do 
115  {
116    if(yin->data[c][tau] < 0.1) { 
117      while (yin->data[c][tau+1] < yin->data[c][tau]) {
118        tau++;
119      }
120      return tau;
121    }
122    tau++;
123  } while (tau<yin->length);
124  //AUBIO_DBG("No pitch found");
125  return 0;
126}
127
128
129/* all the above in one */
130void aubio_pitchyin_do(aubio_pitchyin_t *o, fvec_t * input, fvec_t * out){
131  smpl_t tol = o->tol;
132  fvec_t * yin = o->yin;
133  uint_t c , j,tau = 0;
134  sint_t period;
135  smpl_t tmp = 0., tmp2 = 0.;
136  for (c = 0; c < input->channels; c++) {
137    yin->data[c][0] = 1.;
138    for (tau=1;tau<yin->length;tau++)
139    {
140      yin->data[c][tau] = 0.;
141      for (j=0;j<yin->length;j++)
142      {
143        tmp = input->data[c][j] - input->data[c][j+tau];
144        yin->data[c][tau] += SQR(tmp);
145      }
146      tmp2 += yin->data[c][tau];
147      yin->data[c][tau] *= tau/tmp2;
148      period = tau-3;
149      if(tau > 4 && (yin->data[c][period] < tol) && 
150          (yin->data[c][period] < yin->data[c][period+1])) {
151        out->data[c][0] = fvec_quadint(yin,period,1);
152        goto beach;
153      }
154    }
155    out->data[c][0] = fvec_quadint(yin,fvec_min_elem(yin),1);
156beach:
157    continue;
158  }
159  //return 0;
160}
161
162uint_t aubio_pitchyin_set_tolerance (aubio_pitchyin_t *o, smpl_t tol) {
163  o->tol = tol;
164  return 0;
165}
166
167smpl_t aubio_pitchyin_get_tolerance (aubio_pitchyin_t *o) {
168  return o->tol;
169}
Note: See TracBrowser for help on using the repository browser.