From: Paul Brossier Date: Mon, 8 Apr 2013 16:50:55 +0000 (-0500) Subject: src/pitch/: add first draft for specacf X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=95dc7f22aae8730b570fce5e226b6240a1b9e3e5;p=aubio.git src/pitch/: add first draft for specacf --- diff --git a/src/pitch/pitch.c b/src/pitch/pitch.c index 35c12a06..e29d7a91 100644 --- a/src/pitch/pitch.c +++ b/src/pitch/pitch.c @@ -32,6 +32,7 @@ #include "pitch/pitchfcomb.h" #include "pitch/pitchschmitt.h" #include "pitch/pitchyinfft.h" +#include "pitch/pitchspecacf.h" #include "pitch/pitch.h" /** pitch detection algorithms */ @@ -42,6 +43,7 @@ typedef enum aubio_pitcht_schmitt, /**< `schmitt`, Schmitt trigger */ aubio_pitcht_fcomb, /**< `fcomb`, Fast comb filter */ aubio_pitcht_yinfft, /**< `yinfft`, Spectral YIN */ + aubio_pitcht_specacf, /**< `specacf`, Spectral autocorrelation */ aubio_pitcht_default = aubio_pitcht_yinfft, /**< `default` */ } aubio_pitch_type; @@ -88,6 +90,7 @@ static void aubio_pitch_do_yin (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * obuf) static void aubio_pitch_do_schmitt (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * obuf); static void aubio_pitch_do_fcomb (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * obuf); static void aubio_pitch_do_yinfft (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * obuf); +static void aubio_pitch_do_specacf (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * obuf); /* conversion functions for frequency conversions */ smpl_t freqconvbin (smpl_t f, uint_t samplerate, uint_t bufsize); @@ -114,6 +117,8 @@ new_aubio_pitch (char_t * pitch_mode, pitch_type = aubio_pitcht_schmitt; else if (strcmp (pitch_mode, "fcomb") == 0) pitch_type = aubio_pitcht_fcomb; + else if (strcmp (pitch_mode, "specacf") == 0) + pitch_type = aubio_pitcht_specacf; else if (strcmp (pitch_mode, "default") == 0) pitch_type = aubio_pitcht_default; else { @@ -158,6 +163,13 @@ new_aubio_pitch (char_t * pitch_mode, p->conf_cb = (aubio_pitch_get_conf_t)aubio_pitchyinfft_get_confidence; aubio_pitchyinfft_set_tolerance (p->p_object, 0.85); break; + case aubio_pitcht_specacf: + p->buf = new_fvec (bufsize); + p->p_object = new_aubio_pitchspecacf (bufsize); + p->detect_cb = aubio_pitch_do_specacf; + p->conf_cb = (aubio_pitch_get_conf_t)aubio_pitchspecacf_get_tolerance; + aubio_pitchspecacf_set_tolerance (p->p_object, 0.85); + break; default: break; } @@ -190,6 +202,10 @@ del_aubio_pitch (aubio_pitch_t * p) del_fvec (p->buf); del_aubio_pitchyinfft (p->p_object); break; + case aubio_pitcht_specacf: + del_fvec (p->buf); + del_aubio_pitchspecacf (p->p_object); + break; default: break; } @@ -314,6 +330,21 @@ aubio_pitch_do_yinfft (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * obuf) obuf->data[0] = pitch; } +void +aubio_pitch_do_specacf (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * out) +{ + aubio_pitch_slideblock (p, ibuf); + aubio_pitchspecacf_do (p->p_object, p->buf, out); + //out->data[0] = aubio_bintofreq (out->data[0], p->samplerate, p->bufsize); + smpl_t pitch = 0., period = out->data[0]; + if (period > 0) { + pitch = p->samplerate / period; + } else { + pitch = 0.; + } + out->data[0] = pitch; +} + void aubio_pitch_do_fcomb (aubio_pitch_t * p, fvec_t * ibuf, fvec_t * out) { diff --git a/src/pitch/pitchspecacf.c b/src/pitch/pitchspecacf.c new file mode 100644 index 00000000..269f4b2b --- /dev/null +++ b/src/pitch/pitchspecacf.c @@ -0,0 +1,108 @@ +/* + Copyright (C) 2013 Paul Brossier + + This file is part of aubio. + + aubio is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + aubio is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "cvec.h" +#include "mathutils.h" +#include "spectral/fft.h" +#include "pitch/pitchspecacf.h" + +/** pitch specacf structure */ +struct _aubio_pitchspecacf_t +{ + fvec_t *win; /**< temporal weighting window */ + fvec_t *winput; /**< windowed spectrum */ + aubio_fft_t *fft; /**< fft object to compute*/ + fvec_t *fftout; /**< Fourier transform output */ + fvec_t *sqrmag; /**< square magnitudes */ + fvec_t *acf; /**< auto correlation function */ + smpl_t tol; /**< tolerance */ + smpl_t confidence; /**< confidence */ +}; + +aubio_pitchspecacf_t * +new_aubio_pitchspecacf (uint_t bufsize) +{ + aubio_pitchspecacf_t *p = AUBIO_NEW (aubio_pitchspecacf_t); + p->win = new_aubio_window ("hanningz", bufsize); + p->winput = new_fvec (bufsize); + p->fft = new_aubio_fft (bufsize); + p->fftout = new_fvec (bufsize); + p->sqrmag = new_fvec (bufsize); + p->acf = new_fvec (bufsize / 2 + 1); + p->tol = 1.; + return p; +} + +void +aubio_pitchspecacf_do (aubio_pitchspecacf_t * p, fvec_t * input, fvec_t * output) +{ + uint_t l; + fvec_t *fftout = p->fftout; + // window the input + for (l = 0; l < input->length; l++) { + p->winput->data[l] = p->win->data[l] * input->data[l]; + } + // get the real / imag parts of its fft + aubio_fft_do_complex (p->fft, p->winput, fftout); + for (l = 0; l < input->length / 2 + 1; l++) { + p->sqrmag->data[l] = SQR(fftout->data[l]); + } + // get the real / imag parts of the fft of the squared magnitude + aubio_fft_do_complex (p->fft, p->sqrmag, fftout); + // copy real part to acf + for (l = 0; l < fftout->length / 2 + 1; l++) { + p->acf->data[l] = fftout->data[l]; + } + // get the minimum + uint_t tau = fvec_min_elem (p->acf); + // get the interpolated minimum + output->data[0] = fvec_quadratic_peak_pos (p->acf, tau) * 2.; +} + +void +del_aubio_pitchspecacf (aubio_pitchspecacf_t * p) +{ + del_fvec (p->win); + del_fvec (p->winput); + del_aubio_fft (p->fft); + del_fvec (p->sqrmag); + del_fvec (p->fftout); + AUBIO_FREE (p); +} + +smpl_t +aubio_pitchspecacf_get_confidence (aubio_pitchspecacf_t * o) { + return 0; +} + +uint_t +aubio_pitchspecacf_set_tolerance (aubio_pitchspecacf_t * p, smpl_t tol) +{ + p->tol = tol; + return 0; +} + +smpl_t +aubio_pitchspecacf_get_tolerance (aubio_pitchspecacf_t * p) +{ + return p->tol; +} diff --git a/src/pitch/pitchspecacf.h b/src/pitch/pitchspecacf.h new file mode 100644 index 00000000..06b5b623 --- /dev/null +++ b/src/pitch/pitchspecacf.h @@ -0,0 +1,103 @@ +/* + Copyright (C) 2013 Paul Brossier + + This file is part of aubio. + + aubio is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + aubio is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with aubio. If not, see . + +*/ + +/** \file + + Pitch detection using spectral auto correlation + + This algorithm implements pitch detection by computing the autocorrelation + function as the cosine transform of the square spectral magnitudes. + + Anssi Klapuri. Qualitative and quantitative aspects in the design of + periodicity esti- mation algorithms. In Proceedings of the European Signal + Processing Conference (EUSIPCO), 2000. + + Paul Brossier, [Automatic annotation of musical audio for interactive + systems](http://aubio.org/phd/), Chapter 3, Pitch Analysis, Autocorrelation, + pp. 75-77, PhD thesis, Centre for Digital music, Queen Mary University of + London, London, UK, 2006. + + \example pitch/test-pitchspecacf.c + +*/ + +#ifndef AUBIO_PITCHSPECACF_H +#define AUBIO_PITCHSPECACF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** pitch detection object */ +typedef struct _aubio_pitchspecacf_t aubio_pitchspecacf_t; + +/** execute pitch detection on an input buffer + + \param o pitch detection object as returned by new_aubio_pitchspecacf + \param samples_in input signal vector (length as specified at creation time) + \param cands_out pitch period candidates, in samples + +*/ +void aubio_pitchspecacf_do (aubio_pitchspecacf_t * o, fvec_t * samples_in, fvec_t * cands_out); +/** creation of the pitch detection object + + \param buf_size size of the input buffer to analyse + +*/ +aubio_pitchspecacf_t *new_aubio_pitchspecacf (uint_t buf_size); +/** deletion of the pitch detection object + + \param o pitch detection object as returned by new_aubio_pitchspecacf() + +*/ +void del_aubio_pitchspecacf (aubio_pitchspecacf_t * o); + +/** get tolerance parameter for `specacf` pitch detection object + + \param o pitch detection object + + \return tolerance parameter for minima selection [default 1.] + +*/ +smpl_t aubio_pitchspecacf_get_tolerance (aubio_pitchspecacf_t * o); + +/** set tolerance parameter for `specacf` pitch detection object + + \param o pitch detection object + \param tol tolerance parameter for minima selection [default 1.] + + \return `1` on error, `0` on success + +*/ +uint_t aubio_pitchspecacf_set_tolerance (aubio_pitchspecacf_t * o, smpl_t tol); + +/** get currenct confidence for `specacf` pitch detection object + + \param o pitch detection object + \return confidence parameter + +*/ +smpl_t aubio_pitchspecacf_get_confidence (aubio_pitchspecacf_t * o); + +#ifdef __cplusplus +} +#endif + +#endif /*AUBIO_PITCHSPECACF_H*/