#include "mathutils.h"
#include "pitch/pitchyin.h"
+struct _aubio_pitchyin_t {
+ fvec_t * yin;
+ smpl_t tol;
+};
+
+/** compute difference function
+
+ \param input input signal
+ \param yinbuf output buffer to store difference function (half shorter than input)
+
+*/
+void aubio_pitchyin_diff(fvec_t * input, fvec_t * yinbuf);
+
+/** in place computation of the YIN cumulative normalised function
+
+ \param yinbuf input signal (a square difference function), also used to store function
+
+*/
+void aubio_pitchyin_getcum(fvec_t * yinbuf);
+
+/** detect pitch in a YIN function
+
+ \param yinbuf input buffer as computed by aubio_pitchyin_getcum
+
+*/
+uint_t aubio_pitchyin_getpitch(fvec_t *yinbuf);
+
+aubio_pitchyin_t * new_aubio_pitchyin (uint_t bufsize) {
+ aubio_pitchyin_t * o = AUBIO_NEW(aubio_pitchyin_t);
+ o->yin = new_fvec (bufsize/2, 1);
+ o->tol = 0.15;
+ return o;
+}
+
+void del_aubio_pitchyin (aubio_pitchyin_t *o) {
+ del_fvec(o->yin);
+ AUBIO_FREE(o);
+}
+
/* outputs the difference function */
void aubio_pitchyin_diff(fvec_t * input, fvec_t * yin){
uint_t c,j,tau;
/* all the above in one */
-smpl_t aubio_pitchyin_getpitchfast(fvec_t * input, fvec_t * yin, smpl_t tol){
- uint_t c=0,j,tau = 0;
+void aubio_pitchyin_do(aubio_pitchyin_t *o, fvec_t * input, fvec_t * out){
+ smpl_t tol = o->tol;
+ fvec_t * yin = o->yin;
+ uint_t c , j,tau = 0;
sint_t period;
smpl_t tmp = 0., tmp2 = 0.;
- yin->data[c][0] = 1.;
- for (tau=1;tau<yin->length;tau++)
- {
- yin->data[c][tau] = 0.;
- for (j=0;j<yin->length;j++)
+ for (c = 0; c < input->channels; c++) {
+ yin->data[c][0] = 1.;
+ for (tau=1;tau<yin->length;tau++)
{
- tmp = input->data[c][j] - input->data[c][j+tau];
- yin->data[c][tau] += SQR(tmp);
- }
- tmp2 += yin->data[c][tau];
- yin->data[c][tau] *= tau/tmp2;
- period = tau-3;
- if(tau > 4 && (yin->data[c][period] < tol) &&
- (yin->data[c][period] < yin->data[c][period+1])) {
- return fvec_quadint(yin,period,1);
+ yin->data[c][tau] = 0.;
+ for (j=0;j<yin->length;j++)
+ {
+ tmp = input->data[c][j] - input->data[c][j+tau];
+ yin->data[c][tau] += SQR(tmp);
+ }
+ tmp2 += yin->data[c][tau];
+ yin->data[c][tau] *= tau/tmp2;
+ period = tau-3;
+ if(tau > 4 && (yin->data[c][period] < tol) &&
+ (yin->data[c][period] < yin->data[c][period+1])) {
+ out->data[c][0] = fvec_quadint(yin,period,1);
+ goto beach;
+ }
}
+ out->data[c][0] = fvec_quadint(yin,fvec_min_elem(yin),1);
+beach:
+ continue;
}
- return fvec_quadint(yin,fvec_min_elem(yin),1);
//return 0;
}
+uint_t aubio_pitchyin_set_tolerance (aubio_pitchyin_t *o, smpl_t tol) {
+ o->tol = tol;
+ return 0;
+}
+
+smpl_t aubio_pitchyin_get_tolerance (aubio_pitchyin_t *o) {
+ return o->tol;
+}
extern "C" {
#endif
-/** compute difference function
-
- \param input input signal
- \param yinbuf output buffer to store difference function (half shorter than input)
+/** pitch detection object */
+typedef struct _aubio_pitchyin_t aubio_pitchyin_t;
+/** creation of the pitch detection object
+
+ \param bufsize size of the input buffer to analyse
+
*/
-void aubio_pitchyin_diff(fvec_t * input, fvec_t * yinbuf);
+aubio_pitchyin_t * new_aubio_pitchyin (uint_t bufsize);
-/** in place computation of the YIN cumulative normalised function
-
- \param yinbuf input signal (a square difference function), also used to store function
+/** deletion of the pitch detection object
+
+ \param p pitch detection object as returned by new_aubio_pitchyin()
+
+*/
+void del_aubio_pitchyin (aubio_pitchyin_t * o);
+/** execute pitch detection on an input buffer
+
+ \param p pitch detection object as returned by new_aubio_pitchyin()
+ \param input input signal window (length as specified at creation time)
+ \param tol tolerance parameter for minima selection [default 0.85]
+
*/
-void aubio_pitchyin_getcum(fvec_t * yinbuf);
+void aubio_pitchyin_do (aubio_pitchyin_t * o, fvec_t *in, fvec_t *out);
-/** detect pitch in a YIN function
+
+/** set tolerance parameter for YIN algorithm
- \param yinbuf input buffer as computed by aubio_pitchyin_getcum
+ \param o YIN pitch detection object
+ \param tol tolerance parameter for minima selection [default 0.15]
*/
-uint_t aubio_pitchyin_getpitch(fvec_t *yinbuf);
+uint_t aubio_pitchyin_set_tolerance (aubio_pitchyin_t *o, smpl_t tol);
-/** fast implementation of the YIN algorithm
+/** get tolerance parameter for YIN algorithm
- \param input input signal
- \param yinbuf input buffer used to compute the YIN function
- \param tol tolerance parameter for minima selection [default 0.15]
+ \param o YIN pitch detection object
+ \return tolerance parameter for minima selection [default 0.15]
*/
-smpl_t aubio_pitchyin_getpitchfast(fvec_t * input, fvec_t *yinbuf, smpl_t tol);
+smpl_t aubio_pitchyin_get_tolerance (aubio_pitchyin_t *o);
#ifdef __cplusplus
}
uint_t channels = 1; /* number of channel */
fvec_t * in = new_fvec (win_s, channels); /* input buffer */
fvec_t * out = new_fvec (win_s/2, channels); /* input buffer */
+ aubio_pitchyin_t *p = new_aubio_pitchyin (win_s);
uint_t i = 0;
while (i < 10) {
- aubio_pitchyin_diff (in,out);
- aubio_pitchyin_getcum (out);
- aubio_pitchyin_getpitch (out);
- aubio_pitchyin_getpitchfast (in,out,0.2);
+ aubio_pitchyin_do (p, in,out);
i++;
};