Add in tree aubio
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
0d952f80af
commit
2ae7009b0e
48 changed files with 8937 additions and 1 deletions
530
deps/aubio/src/pitch/pitch.c
vendored
Normal file
530
deps/aubio/src/pitch/pitch.c
vendored
Normal file
|
@ -0,0 +1,530 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "cvec.h"
|
||||
#include "lvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "musicutils.h"
|
||||
#include "spectral/phasevoc.h"
|
||||
#include "temporal/filter.h"
|
||||
#include "temporal/c_weighting.h"
|
||||
#include "pitch/pitchmcomb.h"
|
||||
#include "pitch/pitchyin.h"
|
||||
#include "pitch/pitchfcomb.h"
|
||||
#include "pitch/pitchschmitt.h"
|
||||
#include "pitch/pitchyinfft.h"
|
||||
#include "pitch/pitchyinfast.h"
|
||||
#include "pitch/pitchspecacf.h"
|
||||
#include "pitch/pitch.h"
|
||||
|
||||
#define DEFAULT_PITCH_SILENCE -50.
|
||||
|
||||
/** pitch detection algorithms */
|
||||
typedef enum
|
||||
{
|
||||
aubio_pitcht_yin, /**< `yin`, YIN algorithm */
|
||||
aubio_pitcht_mcomb, /**< `mcomb`, Multi-comb filter */
|
||||
aubio_pitcht_schmitt, /**< `schmitt`, Schmitt trigger */
|
||||
aubio_pitcht_fcomb, /**< `fcomb`, Fast comb filter */
|
||||
aubio_pitcht_yinfft, /**< `yinfft`, Spectral YIN */
|
||||
aubio_pitcht_yinfast, /**< `yinfast`, YIN fast */
|
||||
aubio_pitcht_specacf, /**< `specacf`, Spectral autocorrelation */
|
||||
aubio_pitcht_default
|
||||
= aubio_pitcht_yinfft, /**< `default` */
|
||||
} aubio_pitch_type;
|
||||
|
||||
/** pitch detection output modes */
|
||||
typedef enum
|
||||
{
|
||||
aubio_pitchm_freq, /**< Frequency (Hz) */
|
||||
aubio_pitchm_midi, /**< MIDI note (0.,127) */
|
||||
aubio_pitchm_cent, /**< Cent */
|
||||
aubio_pitchm_bin, /**< Frequency bin (0,bufsize) */
|
||||
aubio_pitchm_default = aubio_pitchm_freq, /**< the one used when "default" is asked */
|
||||
} aubio_pitch_mode;
|
||||
|
||||
/** callback to get pitch candidate, defined below */
|
||||
typedef void (*aubio_pitch_detect_t) (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
|
||||
/** callback to convert pitch from one unit to another, defined below */
|
||||
typedef smpl_t(*aubio_pitch_convert_t) (smpl_t value, uint_t samplerate, uint_t bufsize);
|
||||
|
||||
/** callback to fetch the confidence of the algorithm */
|
||||
typedef smpl_t (*aubio_pitch_get_conf_t) (void * p);
|
||||
|
||||
/** generic pitch detection structure */
|
||||
struct _aubio_pitch_t
|
||||
{
|
||||
aubio_pitch_type type; /**< pitch detection mode */
|
||||
aubio_pitch_mode mode; /**< pitch detection output mode */
|
||||
uint_t samplerate; /**< samplerate */
|
||||
uint_t bufsize; /**< buffer size */
|
||||
void *p_object; /**< pointer to pitch object */
|
||||
aubio_filter_t *filter; /**< filter */
|
||||
fvec_t *filtered; /**< filtered input */
|
||||
aubio_pvoc_t *pv; /**< phase vocoder for mcomb */
|
||||
cvec_t *fftgrain; /**< spectral frame for mcomb */
|
||||
fvec_t *buf; /**< temporary buffer for yin */
|
||||
aubio_pitch_detect_t detect_cb; /**< callback to get the pitch candidates */
|
||||
aubio_pitch_convert_t conv_cb; /**< callback to convert it to the desired unit */
|
||||
aubio_pitch_get_conf_t conf_cb; /**< pointer to the current confidence callback */
|
||||
smpl_t silence; /**< silence threshold */
|
||||
};
|
||||
|
||||
/* callback functions for pitch detection */
|
||||
static void aubio_pitch_do_mcomb (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
static void aubio_pitch_do_yin (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
static void aubio_pitch_do_schmitt (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
static void aubio_pitch_do_fcomb (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
static void aubio_pitch_do_yinfft (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
static void aubio_pitch_do_yinfast (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
static void aubio_pitch_do_specacf (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf);
|
||||
|
||||
/* internal functions for frequency conversion */
|
||||
static smpl_t freqconvbin (smpl_t f, uint_t samplerate, uint_t bufsize);
|
||||
static smpl_t freqconvmidi (smpl_t f, uint_t samplerate, uint_t bufsize);
|
||||
static smpl_t freqconvpass (smpl_t f, uint_t samplerate, uint_t bufsize);
|
||||
|
||||
/* adapter to stack ibuf new samples at the end of buf, and trim `buf` to `bufsize` */
|
||||
void aubio_pitch_slideblock (aubio_pitch_t * p, const fvec_t * ibuf);
|
||||
|
||||
|
||||
aubio_pitch_t *
|
||||
new_aubio_pitch (const char_t * pitch_mode,
|
||||
uint_t bufsize, uint_t hopsize, uint_t samplerate)
|
||||
{
|
||||
aubio_pitch_t *p = AUBIO_NEW (aubio_pitch_t);
|
||||
aubio_pitch_type pitch_type;
|
||||
if (pitch_mode == NULL) {
|
||||
AUBIO_ERR ("pitch: can not use ‘NULL‘ for pitch detection method\n");
|
||||
goto beach;
|
||||
}
|
||||
if (strcmp (pitch_mode, "mcomb") == 0)
|
||||
pitch_type = aubio_pitcht_mcomb;
|
||||
else if (strcmp (pitch_mode, "yinfast") == 0)
|
||||
pitch_type = aubio_pitcht_yinfast;
|
||||
else if (strcmp (pitch_mode, "yinfft") == 0)
|
||||
pitch_type = aubio_pitcht_yinfft;
|
||||
else if (strcmp (pitch_mode, "yin") == 0)
|
||||
pitch_type = aubio_pitcht_yin;
|
||||
else if (strcmp (pitch_mode, "schmitt") == 0)
|
||||
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 {
|
||||
AUBIO_ERR ("pitch: unknown pitch detection method ‘%s’\n", pitch_mode);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
// check parameters are valid
|
||||
if ((sint_t)hopsize < 1) {
|
||||
AUBIO_ERR("pitch: got hopsize %d, but can not be < 1\n", hopsize);
|
||||
goto beach;
|
||||
} else if ((sint_t)bufsize < 1) {
|
||||
AUBIO_ERR("pitch: got buffer_size %d, but can not be < 1\n", bufsize);
|
||||
goto beach;
|
||||
} else if (bufsize < hopsize) {
|
||||
AUBIO_ERR("pitch: hop size (%d) is larger than win size (%d)\n", hopsize, bufsize);
|
||||
goto beach;
|
||||
} else if ((sint_t)samplerate < 1) {
|
||||
AUBIO_ERR("pitch: samplerate (%d) can not be < 1\n", samplerate);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
p->samplerate = samplerate;
|
||||
p->type = pitch_type;
|
||||
aubio_pitch_set_unit (p, "default");
|
||||
p->bufsize = bufsize;
|
||||
p->silence = DEFAULT_PITCH_SILENCE;
|
||||
p->conf_cb = NULL;
|
||||
switch (p->type) {
|
||||
case aubio_pitcht_yin:
|
||||
p->buf = new_fvec (bufsize);
|
||||
p->p_object = new_aubio_pitchyin (bufsize);
|
||||
if (!p->p_object) goto beach;
|
||||
p->detect_cb = aubio_pitch_do_yin;
|
||||
p->conf_cb = (aubio_pitch_get_conf_t)aubio_pitchyin_get_confidence;
|
||||
aubio_pitchyin_set_tolerance (p->p_object, 0.15);
|
||||
break;
|
||||
case aubio_pitcht_mcomb:
|
||||
p->filtered = new_fvec (hopsize);
|
||||
p->pv = new_aubio_pvoc (bufsize, hopsize);
|
||||
if (!p->pv) goto beach;
|
||||
p->fftgrain = new_cvec (bufsize);
|
||||
p->p_object = new_aubio_pitchmcomb (bufsize, hopsize);
|
||||
p->filter = new_aubio_filter_c_weighting (samplerate);
|
||||
p->detect_cb = aubio_pitch_do_mcomb;
|
||||
break;
|
||||
case aubio_pitcht_fcomb:
|
||||
p->buf = new_fvec (bufsize);
|
||||
p->p_object = new_aubio_pitchfcomb (bufsize, hopsize);
|
||||
if (!p->p_object) goto beach;
|
||||
p->detect_cb = aubio_pitch_do_fcomb;
|
||||
break;
|
||||
case aubio_pitcht_schmitt:
|
||||
p->buf = new_fvec (bufsize);
|
||||
p->p_object = new_aubio_pitchschmitt (bufsize);
|
||||
p->detect_cb = aubio_pitch_do_schmitt;
|
||||
break;
|
||||
case aubio_pitcht_yinfft:
|
||||
p->buf = new_fvec (bufsize);
|
||||
p->p_object = new_aubio_pitchyinfft (samplerate, bufsize);
|
||||
if (!p->p_object) goto beach;
|
||||
p->detect_cb = aubio_pitch_do_yinfft;
|
||||
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_yinfast:
|
||||
p->buf = new_fvec (bufsize);
|
||||
p->p_object = new_aubio_pitchyinfast (bufsize);
|
||||
if (!p->p_object) goto beach;
|
||||
p->detect_cb = aubio_pitch_do_yinfast;
|
||||
p->conf_cb = (aubio_pitch_get_conf_t)aubio_pitchyinfast_get_confidence;
|
||||
aubio_pitchyinfast_set_tolerance (p->p_object, 0.15);
|
||||
break;
|
||||
case aubio_pitcht_specacf:
|
||||
p->buf = new_fvec (bufsize);
|
||||
p->p_object = new_aubio_pitchspecacf (bufsize);
|
||||
if (!p->p_object) goto beach;
|
||||
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;
|
||||
}
|
||||
return p;
|
||||
|
||||
beach:
|
||||
if (p->filtered) del_fvec(p->filtered);
|
||||
if (p->buf) del_fvec(p->buf);
|
||||
AUBIO_FREE(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitch (aubio_pitch_t * p)
|
||||
{
|
||||
switch (p->type) {
|
||||
case aubio_pitcht_yin:
|
||||
del_fvec (p->buf);
|
||||
del_aubio_pitchyin (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_mcomb:
|
||||
del_fvec (p->filtered);
|
||||
del_aubio_pvoc (p->pv);
|
||||
del_cvec (p->fftgrain);
|
||||
del_aubio_filter (p->filter);
|
||||
del_aubio_pitchmcomb (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_schmitt:
|
||||
del_fvec (p->buf);
|
||||
del_aubio_pitchschmitt (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_fcomb:
|
||||
del_fvec (p->buf);
|
||||
del_aubio_pitchfcomb (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_yinfft:
|
||||
del_fvec (p->buf);
|
||||
del_aubio_pitchyinfft (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_yinfast:
|
||||
del_fvec (p->buf);
|
||||
del_aubio_pitchyinfast (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_specacf:
|
||||
del_fvec (p->buf);
|
||||
del_aubio_pitchspecacf (p->p_object);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
AUBIO_FREE (p);
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitch_slideblock (aubio_pitch_t * p, const fvec_t * ibuf)
|
||||
{
|
||||
uint_t overlap_size = p->buf->length - ibuf->length;
|
||||
#if 1 //!HAVE_MEMCPY_HACKS
|
||||
uint_t j;
|
||||
for (j = 0; j < overlap_size; j++) {
|
||||
p->buf->data[j] = p->buf->data[j + ibuf->length];
|
||||
}
|
||||
for (j = 0; j < ibuf->length; j++) {
|
||||
p->buf->data[j + overlap_size] = ibuf->data[j];
|
||||
}
|
||||
#else
|
||||
smpl_t *data = p->buf->data;
|
||||
smpl_t *newdata = ibuf->data;
|
||||
memmove(data, data + ibuf->length, overlap_size);
|
||||
memcpy(data + overlap_size, newdata, ibuf->length);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitch_set_unit (aubio_pitch_t * p, const char_t * pitch_unit)
|
||||
{
|
||||
uint_t err = AUBIO_OK;
|
||||
aubio_pitch_mode pitch_mode;
|
||||
if (strcmp (pitch_unit, "freq") == 0)
|
||||
pitch_mode = aubio_pitchm_freq;
|
||||
else if (strcmp (pitch_unit, "hertz") == 0)
|
||||
pitch_mode = aubio_pitchm_freq;
|
||||
else if (strcmp (pitch_unit, "Hertz") == 0)
|
||||
pitch_mode = aubio_pitchm_freq;
|
||||
else if (strcmp (pitch_unit, "Hz") == 0)
|
||||
pitch_mode = aubio_pitchm_freq;
|
||||
else if (strcmp (pitch_unit, "f0") == 0)
|
||||
pitch_mode = aubio_pitchm_freq;
|
||||
else if (strcmp (pitch_unit, "midi") == 0)
|
||||
pitch_mode = aubio_pitchm_midi;
|
||||
else if (strcmp (pitch_unit, "cent") == 0)
|
||||
pitch_mode = aubio_pitchm_cent;
|
||||
else if (strcmp (pitch_unit, "bin") == 0)
|
||||
pitch_mode = aubio_pitchm_bin;
|
||||
else if (strcmp (pitch_unit, "default") == 0)
|
||||
pitch_mode = aubio_pitchm_default;
|
||||
else {
|
||||
AUBIO_WRN("pitch: unknown pitch detection unit ‘%s’, using default\n",
|
||||
pitch_unit);
|
||||
pitch_mode = aubio_pitchm_default;
|
||||
err = AUBIO_FAIL;
|
||||
}
|
||||
p->mode = pitch_mode;
|
||||
switch (p->mode) {
|
||||
case aubio_pitchm_freq:
|
||||
p->conv_cb = freqconvpass;
|
||||
break;
|
||||
case aubio_pitchm_midi:
|
||||
p->conv_cb = freqconvmidi;
|
||||
break;
|
||||
case aubio_pitchm_cent:
|
||||
/* bug: not implemented */
|
||||
p->conv_cb = freqconvmidi;
|
||||
break;
|
||||
case aubio_pitchm_bin:
|
||||
p->conv_cb = freqconvbin;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitch_set_tolerance (aubio_pitch_t * p, smpl_t tol)
|
||||
{
|
||||
switch (p->type) {
|
||||
case aubio_pitcht_yin:
|
||||
aubio_pitchyin_set_tolerance (p->p_object, tol);
|
||||
break;
|
||||
case aubio_pitcht_yinfft:
|
||||
aubio_pitchyinfft_set_tolerance (p->p_object, tol);
|
||||
break;
|
||||
case aubio_pitcht_yinfast:
|
||||
aubio_pitchyinfast_set_tolerance (p->p_object, tol);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return AUBIO_OK;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitch_get_tolerance (aubio_pitch_t * p)
|
||||
{
|
||||
smpl_t tolerance = 1.;
|
||||
switch (p->type) {
|
||||
case aubio_pitcht_yin:
|
||||
tolerance = aubio_pitchyin_get_tolerance (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_yinfft:
|
||||
tolerance = aubio_pitchyinfft_get_tolerance (p->p_object);
|
||||
break;
|
||||
case aubio_pitcht_yinfast:
|
||||
tolerance = aubio_pitchyinfast_get_tolerance (p->p_object);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return tolerance;
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitch_set_silence (aubio_pitch_t * p, smpl_t silence)
|
||||
{
|
||||
if (silence <= 0 && silence >= -200) {
|
||||
p->silence = silence;
|
||||
return AUBIO_OK;
|
||||
} else {
|
||||
AUBIO_WRN("pitch: could not set silence to %.2f\n", silence);
|
||||
return AUBIO_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitch_get_silence (aubio_pitch_t * p)
|
||||
{
|
||||
return p->silence;
|
||||
}
|
||||
|
||||
|
||||
/* do method, calling the detection callback, then the conversion callback */
|
||||
void
|
||||
aubio_pitch_do (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf)
|
||||
{
|
||||
p->detect_cb (p, ibuf, obuf);
|
||||
if (aubio_silence_detection(ibuf, p->silence) == 1) {
|
||||
obuf->data[0] = 0.;
|
||||
}
|
||||
obuf->data[0] = p->conv_cb (obuf->data[0], p->samplerate, p->bufsize);
|
||||
}
|
||||
|
||||
/* do method for each algorithm */
|
||||
void
|
||||
aubio_pitch_do_mcomb (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf)
|
||||
{
|
||||
aubio_filter_do_outplace (p->filter, ibuf, p->filtered);
|
||||
aubio_pvoc_do (p->pv, ibuf, p->fftgrain);
|
||||
aubio_pitchmcomb_do (p->p_object, p->fftgrain, obuf);
|
||||
obuf->data[0] = aubio_bintofreq (obuf->data[0], p->samplerate, p->bufsize);
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitch_do_yin (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf)
|
||||
{
|
||||
smpl_t pitch = 0.;
|
||||
aubio_pitch_slideblock (p, ibuf);
|
||||
aubio_pitchyin_do (p->p_object, p->buf, obuf);
|
||||
pitch = obuf->data[0];
|
||||
if (pitch > 0) {
|
||||
pitch = p->samplerate / (pitch + 0.);
|
||||
} else {
|
||||
pitch = 0.;
|
||||
}
|
||||
obuf->data[0] = pitch;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
aubio_pitch_do_yinfft (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf)
|
||||
{
|
||||
smpl_t pitch = 0.;
|
||||
aubio_pitch_slideblock (p, ibuf);
|
||||
aubio_pitchyinfft_do (p->p_object, p->buf, obuf);
|
||||
pitch = obuf->data[0];
|
||||
if (pitch > 0) {
|
||||
pitch = p->samplerate / (pitch + 0.);
|
||||
} else {
|
||||
pitch = 0.;
|
||||
}
|
||||
obuf->data[0] = pitch;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitch_do_yinfast (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf)
|
||||
{
|
||||
smpl_t pitch = 0.;
|
||||
aubio_pitch_slideblock (p, ibuf);
|
||||
aubio_pitchyinfast_do (p->p_object, p->buf, obuf);
|
||||
pitch = obuf->data[0];
|
||||
if (pitch > 0) {
|
||||
pitch = p->samplerate / (pitch + 0.);
|
||||
} else {
|
||||
pitch = 0.;
|
||||
}
|
||||
obuf->data[0] = pitch;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitch_do_specacf (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * out)
|
||||
{
|
||||
smpl_t pitch = 0., period;
|
||||
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);
|
||||
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, const fvec_t * ibuf, fvec_t * out)
|
||||
{
|
||||
aubio_pitch_slideblock (p, ibuf);
|
||||
aubio_pitchfcomb_do (p->p_object, p->buf, out);
|
||||
out->data[0] = aubio_bintofreq (out->data[0], p->samplerate, p->bufsize);
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitch_do_schmitt (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * out)
|
||||
{
|
||||
smpl_t period, pitch = 0.;
|
||||
aubio_pitch_slideblock (p, ibuf);
|
||||
aubio_pitchschmitt_do (p->p_object, p->buf, out);
|
||||
period = out->data[0];
|
||||
if (period > 0) {
|
||||
pitch = p->samplerate / period;
|
||||
} else {
|
||||
pitch = 0.;
|
||||
}
|
||||
out->data[0] = pitch;
|
||||
}
|
||||
|
||||
/* conversion callbacks */
|
||||
smpl_t
|
||||
freqconvbin(smpl_t f, uint_t samplerate, uint_t bufsize)
|
||||
{
|
||||
return aubio_freqtobin(f, samplerate, bufsize);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
freqconvmidi (smpl_t f, uint_t samplerate UNUSED, uint_t bufsize UNUSED)
|
||||
{
|
||||
return aubio_freqtomidi (f);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
freqconvpass (smpl_t f, uint_t samplerate UNUSED, uint_t bufsize UNUSED)
|
||||
{
|
||||
return f;
|
||||
}
|
||||
|
||||
/* confidence callbacks */
|
||||
smpl_t
|
||||
aubio_pitch_get_confidence (aubio_pitch_t * p)
|
||||
{
|
||||
if (p->conf_cb) {
|
||||
return p->conf_cb(p->p_object);
|
||||
}
|
||||
return 0.;
|
||||
}
|
197
deps/aubio/src/pitch/pitch.h
vendored
Normal file
197
deps/aubio/src/pitch/pitch.h
vendored
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCH_H
|
||||
#define AUBIO_PITCH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection object
|
||||
|
||||
This file creates the objects required for the computation of the selected
|
||||
pitch detection algorithm and output the results, in midi note or Hz.
|
||||
|
||||
\section pitch Pitch detection methods
|
||||
|
||||
A list of the pitch detection methods currently available follows.
|
||||
|
||||
\b \p default : use the default method
|
||||
|
||||
Currently, the default method is set to \p yinfft .
|
||||
|
||||
\b \p schmitt : Schmitt trigger
|
||||
|
||||
This pitch extraction method implements a Schmitt trigger to estimate the
|
||||
period of a signal.
|
||||
|
||||
This file was derived from the tuneit project, written by Mario Lang to
|
||||
detect the fundamental frequency of a sound.
|
||||
|
||||
See http://delysid.org/tuneit.html
|
||||
|
||||
\b \p fcomb : a fast harmonic comb filter
|
||||
|
||||
This pitch extraction method implements a fast harmonic comb filter to
|
||||
determine the fundamental frequency of a harmonic sound.
|
||||
|
||||
This file was derived from the tuneit project, written by Mario Lang to
|
||||
detect the fundamental frequency of a sound.
|
||||
|
||||
See http://delysid.org/tuneit.html
|
||||
|
||||
\b \p mcomb : multiple-comb filter
|
||||
|
||||
This fundamental frequency estimation algorithm implements spectral
|
||||
flattening, multi-comb filtering and peak histogramming.
|
||||
|
||||
This method was designed by Juan P. Bello and described in:
|
||||
|
||||
Juan-Pablo Bello. ``Towards the Automated Analysis of Simple Polyphonic
|
||||
Music''. PhD thesis, Centre for Digital Music, Queen Mary University of
|
||||
London, London, UK, 2003.
|
||||
|
||||
\b \p yin : YIN algorithm
|
||||
|
||||
This algorithm was developed by A. de Cheveigne and H. Kawahara and
|
||||
published in:
|
||||
|
||||
De Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
|
||||
estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
|
||||
|
||||
see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
|
||||
|
||||
\b \p yinfast : Yinfast algorithm
|
||||
|
||||
This algorithm is equivalent to the YIN algorithm, but computed in the
|
||||
spectral domain for efficiency. See also `python/demos/demo_yin_compare.py`.
|
||||
|
||||
\b \p yinfft : Yinfft algorithm
|
||||
|
||||
This algorithm was derived from the YIN algorithm. In this implementation, a
|
||||
Fourier transform is used to compute a tapered square difference function,
|
||||
which allows spectral weighting. Because the difference function is tapered,
|
||||
the selection of the period is simplified.
|
||||
|
||||
Paul Brossier, [Automatic annotation of musical audio for interactive
|
||||
systems](http://aubio.org/phd/), Chapter 3, Pitch Analysis, PhD thesis,
|
||||
Centre for Digital music, Queen Mary University of London, London, UK, 2006.
|
||||
|
||||
\example pitch/test-pitch.c
|
||||
\example examples/aubiopitch.c
|
||||
|
||||
*/
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitch_t aubio_pitch_t;
|
||||
|
||||
/** execute pitch detection on an input signal frame
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
\param in input signal of size [hop_size]
|
||||
\param out output pitch candidates of size [1]
|
||||
|
||||
*/
|
||||
void aubio_pitch_do (aubio_pitch_t * o, const fvec_t * in, fvec_t * out);
|
||||
|
||||
/** change yin or yinfft tolerance threshold
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
\param tol tolerance default is 0.15 for yin and 0.85 for yinfft
|
||||
|
||||
*/
|
||||
uint_t aubio_pitch_set_tolerance (aubio_pitch_t * o, smpl_t tol);
|
||||
|
||||
/** get yin or yinfft tolerance threshold
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
\return tolerance (default is 0.15 for yin and 0.85 for yinfft)
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitch_get_tolerance (aubio_pitch_t * o);
|
||||
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
|
||||
*/
|
||||
void del_aubio_pitch (aubio_pitch_t * o);
|
||||
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param method set pitch detection algorithm
|
||||
\param buf_size size of the input buffer to analyse
|
||||
\param hop_size step size between two consecutive analysis instant
|
||||
\param samplerate sampling rate of the signal
|
||||
|
||||
\return newly created ::aubio_pitch_t
|
||||
|
||||
*/
|
||||
aubio_pitch_t *new_aubio_pitch (const char_t * method,
|
||||
uint_t buf_size, uint_t hop_size, uint_t samplerate);
|
||||
|
||||
/** set the output unit of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
\param mode set pitch units for output
|
||||
|
||||
mode can be one of "Hz", "midi", "cent", or "bin". Defaults to "Hz".
|
||||
|
||||
\return 0 if successfull, non-zero otherwise
|
||||
|
||||
*/
|
||||
uint_t aubio_pitch_set_unit (aubio_pitch_t * o, const char_t * mode);
|
||||
|
||||
/** set the silence threshold of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
\param silence level threshold under which pitch should be ignored, in dB
|
||||
|
||||
\return 0 if successfull, non-zero otherwise
|
||||
|
||||
*/
|
||||
uint_t aubio_pitch_set_silence (aubio_pitch_t * o, smpl_t silence);
|
||||
|
||||
/** set the silence threshold of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by ::new_aubio_pitch()
|
||||
|
||||
\return level threshold under which pitch should be ignored, in dB
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitch_get_silence (aubio_pitch_t * o);
|
||||
|
||||
/** get the current confidence
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitch()
|
||||
|
||||
\return the current confidence of the pitch algorithm
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitch_get_confidence (aubio_pitch_t * o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCH_H */
|
144
deps/aubio/src/pitch/pitchfcomb.c
vendored
Normal file
144
deps/aubio/src/pitch/pitchfcomb.c
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
Copyright (C) 2004, 2005 Mario Lang <mlang@delysid.org>
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "cvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "musicutils.h"
|
||||
#include "spectral/fft.h"
|
||||
#include "pitch/pitchfcomb.h"
|
||||
|
||||
#define MAX_PEAKS 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
smpl_t bin;
|
||||
smpl_t db;
|
||||
} aubio_fpeak_t;
|
||||
|
||||
struct _aubio_pitchfcomb_t
|
||||
{
|
||||
uint_t fftSize;
|
||||
uint_t stepSize;
|
||||
uint_t rate;
|
||||
fvec_t *winput;
|
||||
fvec_t *win;
|
||||
cvec_t *fftOut;
|
||||
fvec_t *fftLastPhase;
|
||||
aubio_fft_t *fft;
|
||||
};
|
||||
|
||||
aubio_pitchfcomb_t *
|
||||
new_aubio_pitchfcomb (uint_t bufsize, uint_t hopsize)
|
||||
{
|
||||
aubio_pitchfcomb_t *p = AUBIO_NEW (aubio_pitchfcomb_t);
|
||||
p->fftSize = bufsize;
|
||||
p->stepSize = hopsize;
|
||||
p->fft = new_aubio_fft (bufsize);
|
||||
if (!p->fft) goto beach;
|
||||
p->winput = new_fvec (bufsize);
|
||||
p->fftOut = new_cvec (bufsize);
|
||||
p->fftLastPhase = new_fvec (bufsize);
|
||||
p->win = new_aubio_window ("hanning", bufsize);
|
||||
return p;
|
||||
|
||||
beach:
|
||||
AUBIO_FREE(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* input must be stepsize long */
|
||||
void
|
||||
aubio_pitchfcomb_do (aubio_pitchfcomb_t * p, const fvec_t * input, fvec_t * output)
|
||||
{
|
||||
uint_t k, l, maxharm = 0;
|
||||
smpl_t phaseDifference = TWO_PI * (smpl_t) p->stepSize / (smpl_t) p->fftSize;
|
||||
aubio_fpeak_t peaks[MAX_PEAKS];
|
||||
|
||||
for (k = 0; k < MAX_PEAKS; k++) {
|
||||
peaks[k].db = -200.;
|
||||
peaks[k].bin = 0.;
|
||||
}
|
||||
|
||||
for (k = 0; k < input->length; k++) {
|
||||
p->winput->data[k] = p->win->data[k] * input->data[k];
|
||||
}
|
||||
aubio_fft_do (p->fft, p->winput, p->fftOut);
|
||||
|
||||
for (k = 0; k <= p->fftSize / 2; k++) {
|
||||
smpl_t
|
||||
magnitude =
|
||||
20. * LOG10 (2. * p->fftOut->norm[k] / (smpl_t) p->fftSize),
|
||||
phase = p->fftOut->phas[k], tmp, bin;
|
||||
|
||||
/* compute phase difference */
|
||||
tmp = phase - p->fftLastPhase->data[k];
|
||||
p->fftLastPhase->data[k] = phase;
|
||||
|
||||
/* subtract expected phase difference */
|
||||
tmp -= (smpl_t) k *phaseDifference;
|
||||
|
||||
/* map delta phase into +/- Pi interval */
|
||||
tmp = aubio_unwrap2pi (tmp);
|
||||
|
||||
/* get deviation from bin frequency from the +/- Pi interval */
|
||||
tmp = p->fftSize / (smpl_t) p->stepSize * tmp / (TWO_PI);
|
||||
|
||||
/* compute the k-th partials' true bin */
|
||||
bin = (smpl_t) k + tmp;
|
||||
|
||||
if (bin > 0.0 && magnitude > peaks[0].db) { // && magnitude < 0) {
|
||||
memmove (peaks + 1, peaks, sizeof (aubio_fpeak_t) * (MAX_PEAKS - 1));
|
||||
peaks[0].bin = bin;
|
||||
peaks[0].db = magnitude;
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
for (l = 1; l < MAX_PEAKS && peaks[l].bin > 0.0; l++) {
|
||||
sint_t harmonic;
|
||||
for (harmonic = 5; harmonic > 1; harmonic--) {
|
||||
if (peaks[0].bin / peaks[l].bin < harmonic + .02 &&
|
||||
peaks[0].bin / peaks[l].bin > harmonic - .02) {
|
||||
if (harmonic > (sint_t) maxharm && peaks[0].db < peaks[l].db / 2) {
|
||||
maxharm = harmonic;
|
||||
k = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
output->data[0] = peaks[k].bin;
|
||||
/* quick hack to clean output a bit */
|
||||
if (peaks[k].bin > 5000.)
|
||||
output->data[0] = 0.;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitchfcomb (aubio_pitchfcomb_t * p)
|
||||
{
|
||||
del_cvec (p->fftOut);
|
||||
del_fvec (p->fftLastPhase);
|
||||
del_fvec (p->win);
|
||||
del_fvec (p->winput);
|
||||
del_aubio_fft (p->fft);
|
||||
AUBIO_FREE (p);
|
||||
}
|
76
deps/aubio/src/pitch/pitchfcomb.h
vendored
Normal file
76
deps/aubio/src/pitch/pitchfcomb.h
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using a fast harmonic comb filter
|
||||
|
||||
This pitch extraction method implements a fast harmonic comb filter to
|
||||
determine the fundamental frequency of a harmonic sound.
|
||||
|
||||
This file was derived from the tuneit project, written by Mario Lang to
|
||||
detect the fundamental frequency of a sound.
|
||||
|
||||
See http://delysid.org/tuneit.html
|
||||
|
||||
\example pitch/test-pitchfcomb.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHFCOMB_H
|
||||
#define AUBIO_PITCHFCOMB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchfcomb_t aubio_pitchfcomb_t;
|
||||
|
||||
/** execute pitch detection on an input buffer
|
||||
|
||||
\param p pitch detection object as returned by new_aubio_pitchfcomb
|
||||
\param input input signal window (length as specified at creation time)
|
||||
\param output pitch candidates in bins
|
||||
|
||||
*/
|
||||
void aubio_pitchfcomb_do (aubio_pitchfcomb_t * p, const fvec_t * input,
|
||||
fvec_t * output);
|
||||
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param buf_size size of the input buffer to analyse
|
||||
\param hop_size step size between two consecutive analysis instant
|
||||
|
||||
*/
|
||||
aubio_pitchfcomb_t *new_aubio_pitchfcomb (uint_t buf_size, uint_t hop_size);
|
||||
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param p pitch detection object as returned by new_aubio_pitchfcomb
|
||||
|
||||
*/
|
||||
void del_aubio_pitchfcomb (aubio_pitchfcomb_t * p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHFCOMB_H */
|
435
deps/aubio/src/pitch/pitchmcomb.c
vendored
Normal file
435
deps/aubio/src/pitch/pitchmcomb.c
vendored
Normal file
|
@ -0,0 +1,435 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "cvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "pitch/pitchmcomb.h"
|
||||
|
||||
#define CAND_SWAP(a,b) { register aubio_spectralcandidate_t *t=(a);(a)=(b);(b)=t; }
|
||||
|
||||
typedef struct _aubio_spectralpeak_t aubio_spectralpeak_t;
|
||||
typedef struct _aubio_spectralcandidate_t aubio_spectralcandidate_t;
|
||||
uint_t aubio_pitchmcomb_get_root_peak (aubio_spectralpeak_t * peaks,
|
||||
uint_t length);
|
||||
uint_t aubio_pitchmcomb_quadpick (aubio_spectralpeak_t * spectral_peaks,
|
||||
const fvec_t * X);
|
||||
void aubio_pitchmcomb_spectral_pp (aubio_pitchmcomb_t * p, const fvec_t * oldmag);
|
||||
void aubio_pitchmcomb_combdet (aubio_pitchmcomb_t * p, const fvec_t * newmag);
|
||||
/* not used but useful : sort by amplitudes (or anything else)
|
||||
* sort_pitchpeak(peaks, length);
|
||||
*/
|
||||
#if 0
|
||||
/** spectral_peak comparison function (must return signed int) */
|
||||
static sint_t aubio_pitchmcomb_sort_peak_comp (const void *x, const void *y);
|
||||
/** sort spectral_peak against their mag */
|
||||
void aubio_pitchmcomb_sort_peak (aubio_spectralpeak_t * peaks, uint_t nbins);
|
||||
/** select the best candidates */
|
||||
uint_t aubio_pitch_cands (aubio_pitchmcomb_t * p, const cvec_t * fftgrain,
|
||||
smpl_t * cands);
|
||||
#endif
|
||||
|
||||
/** sort spectral_candidate against their comb ene */
|
||||
void aubio_pitchmcomb_sort_cand_ene (aubio_spectralcandidate_t ** candidates,
|
||||
uint_t nbins);
|
||||
#if 0
|
||||
/** sort spectral_candidate against their frequency */
|
||||
void aubio_pitchmcomb_sort_cand_freq (aubio_spectralcandidate_t ** candidates,
|
||||
uint_t nbins);
|
||||
#endif
|
||||
|
||||
struct _aubio_pitchmcomb_t
|
||||
{
|
||||
smpl_t threshold; /**< offset threshold [0.033 or 0.01] */
|
||||
smpl_t alpha; /**< normalisation exponent [9] */
|
||||
smpl_t cutoff; /**< low-pass filter cutoff [0.34, 1] */
|
||||
smpl_t tol; /**< tolerance [0.05] */
|
||||
// smpl_t tau; /**< frequency precision [44100/4096] */
|
||||
uint_t win_post; /**< median filter window length */
|
||||
uint_t win_pre; /**< median filter window */
|
||||
uint_t ncand; /**< maximum number of candidates (combs) */
|
||||
uint_t npartials; /**< maximum number of partials per combs */
|
||||
uint_t count; /**< picked picks */
|
||||
uint_t goodcandidate; /**< best candidate */
|
||||
uint_t spec_partition; /**< spectrum partition to consider */
|
||||
aubio_spectralpeak_t *peaks; /**< up to length win/spec_partition */
|
||||
aubio_spectralcandidate_t **candidates; /** up to five candidates */
|
||||
/* some scratch pads */
|
||||
/** \bug (unnecessary copied from fftgrain?) */
|
||||
fvec_t *newmag; /**< vec to store mag */
|
||||
fvec_t *scratch; /**< vec to store modified mag */
|
||||
fvec_t *scratch2; /**< vec to compute moving median */
|
||||
fvec_t *theta; /**< vec to store phase */
|
||||
smpl_t phasediff;
|
||||
smpl_t phasefreq;
|
||||
/** threshfn: name or handle of fn for computing adaptive threshold [median] */
|
||||
/** aubio_thresholdfn_t thresholdfn; */
|
||||
/** picker: name or handle of fn for picking event times [quadpick] */
|
||||
/** aubio_pickerfn_t pickerfn; */
|
||||
};
|
||||
|
||||
/** spectral peak object */
|
||||
struct _aubio_spectralpeak_t
|
||||
{
|
||||
uint_t bin; /**< bin [0-(length-1)] */
|
||||
smpl_t ebin; /**< estimated bin */
|
||||
smpl_t mag; /**< peak magnitude */
|
||||
};
|
||||
|
||||
/** spectral candidates array object */
|
||||
struct _aubio_spectralcandidate_t
|
||||
{
|
||||
smpl_t ebin; /**< interpolated bin */
|
||||
smpl_t *ecomb; /**< comb */
|
||||
smpl_t ene; /**< candidate energy */
|
||||
smpl_t len; /**< length */
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
aubio_pitchmcomb_do (aubio_pitchmcomb_t * p, const cvec_t * fftgrain, fvec_t * output)
|
||||
{
|
||||
uint_t j;
|
||||
smpl_t instfreq;
|
||||
fvec_t *newmag = (fvec_t *) p->newmag;
|
||||
//smpl_t hfc; //fe=instfreq(theta1,theta,ops); //theta1=theta;
|
||||
/* copy incoming grain to newmag */
|
||||
for (j = 0; j < newmag->length; j++)
|
||||
newmag->data[j] = fftgrain->norm[j];
|
||||
/* detect only if local energy > 10. */
|
||||
//if (aubio_level_lin (newmag) * newmag->length > 10.) {
|
||||
//hfc = fvec_local_hfc(newmag); //not used
|
||||
aubio_pitchmcomb_spectral_pp (p, newmag);
|
||||
aubio_pitchmcomb_combdet (p, newmag);
|
||||
//aubio_pitchmcomb_sort_cand_freq(p->candidates,p->ncand);
|
||||
//return p->candidates[p->goodcandidate]->ebin;
|
||||
j = (uint_t) FLOOR (p->candidates[p->goodcandidate]->ebin + .5);
|
||||
instfreq = aubio_unwrap2pi (fftgrain->phas[j]
|
||||
- p->theta->data[j] - j * p->phasediff);
|
||||
instfreq *= p->phasefreq;
|
||||
/* store phase for next run */
|
||||
for (j = 0; j < p->theta->length; j++) {
|
||||
p->theta->data[j] = fftgrain->phas[j];
|
||||
}
|
||||
//return p->candidates[p->goodcandidate]->ebin;
|
||||
output->data[0] =
|
||||
FLOOR (p->candidates[p->goodcandidate]->ebin + .5) + instfreq;
|
||||
/*} else {
|
||||
return -1.;
|
||||
} */
|
||||
}
|
||||
|
||||
#if 0
|
||||
uint_t
|
||||
aubio_pitch_cands (aubio_pitchmcomb_t * p, const cvec_t * fftgrain, smpl_t * cands)
|
||||
{
|
||||
uint_t j;
|
||||
uint_t k;
|
||||
fvec_t *newmag = (fvec_t *) p->newmag;
|
||||
aubio_spectralcandidate_t **scands =
|
||||
(aubio_spectralcandidate_t **) (p->candidates);
|
||||
//smpl_t hfc; //fe=instfreq(theta1,theta,ops); //theta1=theta;
|
||||
/* copy incoming grain to newmag */
|
||||
for (j = 0; j < newmag->length; j++)
|
||||
newmag->data[j] = fftgrain->norm[j];
|
||||
/* detect only if local energy > 10. */
|
||||
if (aubio_level_lin (newmag) * newmag->length > 10.) {
|
||||
/* hfc = fvec_local_hfc(newmag); do not use */
|
||||
aubio_pitchmcomb_spectral_pp (p, newmag);
|
||||
aubio_pitchmcomb_combdet (p, newmag);
|
||||
aubio_pitchmcomb_sort_cand_freq (scands, p->ncand);
|
||||
/* store ncand comb energies in cands[1:ncand] */
|
||||
for (k = 0; k < p->ncand; k++)
|
||||
cands[k] = p->candidates[k]->ene;
|
||||
/* store ncand[end] freq in cands[end] */
|
||||
cands[p->ncand] = p->candidates[p->ncand - 1]->ebin;
|
||||
return 1;
|
||||
} else {
|
||||
for (k = 0; k < p->ncand; k++)
|
||||
cands[k] = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
aubio_pitchmcomb_spectral_pp (aubio_pitchmcomb_t * p, const fvec_t * newmag)
|
||||
{
|
||||
fvec_t *mag = (fvec_t *) p->scratch;
|
||||
fvec_t *tmp = (fvec_t *) p->scratch2;
|
||||
uint_t j;
|
||||
uint_t length = mag->length;
|
||||
/* copy newmag to mag (scracth) */
|
||||
for (j = 0; j < length; j++) {
|
||||
mag->data[j] = newmag->data[j];
|
||||
}
|
||||
fvec_min_removal (mag); /* min removal */
|
||||
fvec_alpha_normalise (mag, p->alpha); /* alpha normalisation */
|
||||
/* skipped *//* low pass filtering */
|
||||
/** \bug fvec_moving_thres may write out of bounds */
|
||||
fvec_adapt_thres (mag, tmp, p->win_post, p->win_pre); /* adaptative threshold */
|
||||
fvec_add (mag, -p->threshold); /* fixed threshold */
|
||||
{
|
||||
aubio_spectralpeak_t *peaks = (aubio_spectralpeak_t *) p->peaks;
|
||||
uint_t count;
|
||||
/* return bin and ebin */
|
||||
count = aubio_pitchmcomb_quadpick (peaks, mag);
|
||||
for (j = 0; j < count; j++)
|
||||
peaks[j].mag = newmag->data[peaks[j].bin];
|
||||
/* reset non peaks */
|
||||
for (j = count; j < length; j++)
|
||||
peaks[j].mag = 0.;
|
||||
p->peaks = peaks;
|
||||
p->count = count;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitchmcomb_combdet (aubio_pitchmcomb_t * p, const fvec_t * newmag)
|
||||
{
|
||||
aubio_spectralpeak_t *peaks = (aubio_spectralpeak_t *) p->peaks;
|
||||
aubio_spectralcandidate_t **candidate =
|
||||
(aubio_spectralcandidate_t **) p->candidates;
|
||||
|
||||
/* parms */
|
||||
uint_t N = p->npartials; /* maximum number of partials to be considered 10 */
|
||||
uint_t M = p->ncand; /* maximum number of combs to be considered 5 */
|
||||
uint_t length = newmag->length;
|
||||
uint_t count = p->count;
|
||||
uint_t k;
|
||||
uint_t l;
|
||||
uint_t d;
|
||||
uint_t curlen = 0;
|
||||
|
||||
smpl_t delta2;
|
||||
smpl_t xx;
|
||||
uint_t position = 0;
|
||||
|
||||
uint_t root_peak = 0;
|
||||
uint_t tmpl = 0;
|
||||
smpl_t tmpene = 0.;
|
||||
|
||||
/* get the biggest peak in the spectrum */
|
||||
root_peak = aubio_pitchmcomb_get_root_peak (peaks, count);
|
||||
/* not enough partials in highest notes, could be forced */
|
||||
//if (peaks[root_peak].ebin >= aubio_miditofreq(85.)/p->tau) N=2;
|
||||
//if (peaks[root_peak].ebin >= aubio_miditofreq(90.)/p->tau) N=1;
|
||||
/* now calculate the energy of each of the 5 combs */
|
||||
for (l = 0; l < M; l++) {
|
||||
smpl_t scaler = (1. / (l + 1.));
|
||||
candidate[l]->ene = 0.; /* reset ene and len sums */
|
||||
candidate[l]->len = 0.;
|
||||
candidate[l]->ebin = scaler * peaks[root_peak].ebin;
|
||||
/* if less than N peaks available, curlen < N */
|
||||
if (candidate[l]->ebin != 0.)
|
||||
curlen = (uint_t) FLOOR (length / (candidate[l]->ebin));
|
||||
curlen = (N < curlen) ? N : curlen;
|
||||
/* fill candidate[l]->ecomb[k] with (k+1)*candidate[l]->ebin */
|
||||
for (k = 0; k < curlen; k++)
|
||||
candidate[l]->ecomb[k] = (candidate[l]->ebin) * (k + 1.);
|
||||
for (k = curlen; k < length; k++)
|
||||
candidate[l]->ecomb[k] = 0.;
|
||||
/* for each in candidate[l]->ecomb[k] */
|
||||
for (k = 0; k < curlen; k++) {
|
||||
xx = 100000.;
|
||||
/** get the candidate->ecomb the closer to peaks.ebin
|
||||
* (to cope with the inharmonicity)*/
|
||||
for (d = 0; d < count; d++) {
|
||||
delta2 = ABS (candidate[l]->ecomb[k] - peaks[d].ebin);
|
||||
if (delta2 <= xx) {
|
||||
position = d;
|
||||
xx = delta2;
|
||||
}
|
||||
}
|
||||
/* for a Q factor of 17, maintaining "constant Q filtering",
|
||||
* and sum energy and length over non null combs */
|
||||
if (17. * xx < candidate[l]->ecomb[k]) {
|
||||
candidate[l]->ecomb[k] = peaks[position].ebin;
|
||||
candidate[l]->ene += /* ecomb rounded to nearest int */
|
||||
POW (newmag->data[(uint_t) FLOOR (candidate[l]->ecomb[k] + .5)],
|
||||
0.25);
|
||||
candidate[l]->len += 1. / curlen;
|
||||
} else
|
||||
candidate[l]->ecomb[k] = 0.;
|
||||
}
|
||||
/* punishment */
|
||||
/*if (candidate[l]->len<0.6)
|
||||
candidate[l]->ene=0.; */
|
||||
/* remember best candidate energy (in polyphonic, could check for
|
||||
* tmpene*1.1 < candidate->ene to reduce jumps towards low frequencies) */
|
||||
if (tmpene < candidate[l]->ene) {
|
||||
tmpl = l;
|
||||
tmpene = candidate[l]->ene;
|
||||
}
|
||||
}
|
||||
//p->candidates=candidate;
|
||||
//p->peaks=peaks;
|
||||
p->goodcandidate = tmpl;
|
||||
}
|
||||
|
||||
/** T=quadpick(X): return indices of elements of X which are peaks and positive
|
||||
* exact peak positions are retrieved by quadratic interpolation
|
||||
*
|
||||
* \bug peak-picking too picky, sometimes counts too many peaks ?
|
||||
*/
|
||||
uint_t
|
||||
aubio_pitchmcomb_quadpick (aubio_spectralpeak_t * spectral_peaks, const fvec_t * X)
|
||||
{
|
||||
uint_t j, ispeak, count = 0;
|
||||
for (j = 1; j < X->length - 1; j++) {
|
||||
ispeak = fvec_peakpick (X, j);
|
||||
if (ispeak) {
|
||||
count += ispeak;
|
||||
spectral_peaks[count - 1].bin = j;
|
||||
spectral_peaks[count - 1].ebin = fvec_quadratic_peak_pos (X, j);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* get predominant partial */
|
||||
uint_t
|
||||
aubio_pitchmcomb_get_root_peak (aubio_spectralpeak_t * peaks, uint_t length)
|
||||
{
|
||||
uint_t i, pos = 0;
|
||||
smpl_t tmp = 0.;
|
||||
for (i = 0; i < length; i++)
|
||||
if (tmp <= peaks[i].mag) {
|
||||
pos = i;
|
||||
tmp = peaks[i].mag;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
aubio_pitchmcomb_sort_peak (aubio_spectralpeak_t * peaks, uint_t nbins)
|
||||
{
|
||||
qsort (peaks, nbins, sizeof (aubio_spectralpeak_t),
|
||||
aubio_pitchmcomb_sort_peak_comp);
|
||||
}
|
||||
|
||||
static sint_t
|
||||
aubio_pitchmcomb_sort_peak_comp (const void *x, const void *y)
|
||||
{
|
||||
return (((aubio_spectralpeak_t *) y)->mag -
|
||||
((aubio_spectralpeak_t *) x)->mag);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
aubio_pitchmcomb_sort_cand_ene (aubio_spectralcandidate_t ** candidates,
|
||||
uint_t nbins)
|
||||
{
|
||||
uint_t cur = 0;
|
||||
uint_t run = 0;
|
||||
for (cur = 0; cur < nbins; cur++) {
|
||||
for (run = cur + 1; run < nbins; run++) {
|
||||
if (candidates[run]->ene > candidates[cur]->ene)
|
||||
CAND_SWAP (candidates[run], candidates[cur]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitchmcomb_sort_cand_freq (aubio_spectralcandidate_t ** candidates,
|
||||
uint_t nbins)
|
||||
{
|
||||
uint_t cur = 0;
|
||||
uint_t run = 0;
|
||||
for (cur = 0; cur < nbins; cur++) {
|
||||
for (run = cur + 1; run < nbins; run++) {
|
||||
if (candidates[run]->ebin < candidates[cur]->ebin)
|
||||
CAND_SWAP (candidates[run], candidates[cur]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
aubio_pitchmcomb_t *
|
||||
new_aubio_pitchmcomb (uint_t bufsize, uint_t hopsize)
|
||||
{
|
||||
aubio_pitchmcomb_t *p = AUBIO_NEW (aubio_pitchmcomb_t);
|
||||
/* bug: should check if size / 8 > post+pre+1 */
|
||||
uint_t i, j;
|
||||
uint_t spec_size;
|
||||
p->spec_partition = 2;
|
||||
p->ncand = 5;
|
||||
p->npartials = 5;
|
||||
p->cutoff = 1.;
|
||||
p->threshold = 0.01;
|
||||
p->win_post = 8;
|
||||
p->win_pre = 7;
|
||||
// p->tau = samplerate/bufsize;
|
||||
p->alpha = 9.;
|
||||
p->goodcandidate = 0;
|
||||
p->phasefreq = bufsize / hopsize / TWO_PI;
|
||||
p->phasediff = TWO_PI * hopsize / bufsize;
|
||||
spec_size = bufsize / p->spec_partition + 1;
|
||||
//p->pickerfn = quadpick;
|
||||
//p->biquad = new_biquad(0.1600,0.3200,0.1600, -0.5949, 0.2348);
|
||||
/* allocate temp memory */
|
||||
p->newmag = new_fvec (spec_size);
|
||||
/* array for median */
|
||||
p->scratch = new_fvec (spec_size);
|
||||
/* array for phase */
|
||||
p->theta = new_fvec (spec_size);
|
||||
/* array for adaptative threshold */
|
||||
p->scratch2 = new_fvec (p->win_post + p->win_pre + 1);
|
||||
/* array of spectral peaks */
|
||||
p->peaks = AUBIO_ARRAY (aubio_spectralpeak_t, spec_size);
|
||||
for (i = 0; i < spec_size; i++) {
|
||||
p->peaks[i].bin = 0.;
|
||||
p->peaks[i].ebin = 0.;
|
||||
p->peaks[i].mag = 0.;
|
||||
}
|
||||
/* array of pointers to spectral candidates */
|
||||
p->candidates = AUBIO_ARRAY (aubio_spectralcandidate_t *, p->ncand);
|
||||
for (i = 0; i < p->ncand; i++) {
|
||||
p->candidates[i] = AUBIO_NEW (aubio_spectralcandidate_t);
|
||||
p->candidates[i]->ecomb = AUBIO_ARRAY (smpl_t, spec_size);
|
||||
for (j = 0; j < spec_size; j++) {
|
||||
p->candidates[i]->ecomb[j] = 0.;
|
||||
}
|
||||
p->candidates[i]->ene = 0.;
|
||||
p->candidates[i]->ebin = 0.;
|
||||
p->candidates[i]->len = 0.;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
del_aubio_pitchmcomb (aubio_pitchmcomb_t * p)
|
||||
{
|
||||
uint_t i;
|
||||
del_fvec (p->newmag);
|
||||
del_fvec (p->scratch);
|
||||
del_fvec (p->theta);
|
||||
del_fvec (p->scratch2);
|
||||
AUBIO_FREE (p->peaks);
|
||||
for (i = 0; i < p->ncand; i++) {
|
||||
AUBIO_FREE (p->candidates[i]->ecomb);
|
||||
AUBIO_FREE (p->candidates[i]);
|
||||
}
|
||||
AUBIO_FREE (p->candidates);
|
||||
AUBIO_FREE (p);
|
||||
}
|
77
deps/aubio/src/pitch/pitchmcomb.h
vendored
Normal file
77
deps/aubio/src/pitch/pitchmcomb.h
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using multiple-comb filter
|
||||
|
||||
This fundamental frequency estimation algorithm implements spectral
|
||||
flattening, multi-comb filtering and peak histogramming.
|
||||
|
||||
This method was designed by Juan P. Bello and described in:
|
||||
|
||||
Juan-Pablo Bello. ``Towards the Automated Analysis of Simple Polyphonic
|
||||
Music''. PhD thesis, Centre for Digital Music, Queen Mary University of
|
||||
London, London, UK, 2003.
|
||||
|
||||
\example pitch/test-pitchmcomb.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHMCOMB_H
|
||||
#define AUBIO_PITCHMCOMB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchmcomb_t aubio_pitchmcomb_t;
|
||||
|
||||
/** execute pitch detection on an input spectral frame
|
||||
|
||||
\param p pitch detection object as returned by new_aubio_pitchmcomb
|
||||
\param in_fftgrain input signal spectrum as computed by aubio_pvoc_do
|
||||
\param out_cands pitch candidate frequenciess, in bins
|
||||
|
||||
*/
|
||||
void aubio_pitchmcomb_do (aubio_pitchmcomb_t * p, const cvec_t * in_fftgrain,
|
||||
fvec_t * out_cands);
|
||||
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param buf_size size of the input buffer to analyse
|
||||
\param hop_size step size between two consecutive analysis instant
|
||||
|
||||
*/
|
||||
aubio_pitchmcomb_t *new_aubio_pitchmcomb (uint_t buf_size, uint_t hop_size);
|
||||
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param p pitch detection object as returned by new_aubio_pitchfcomb
|
||||
|
||||
*/
|
||||
void del_aubio_pitchmcomb (aubio_pitchmcomb_t * p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHMCOMB_H */
|
119
deps/aubio/src/pitch/pitchschmitt.c
vendored
Normal file
119
deps/aubio/src/pitch/pitchschmitt.c
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
Copyright (C) 2004, 2005 Mario Lang <mlang@delysid.org>
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "pitch/pitchschmitt.h"
|
||||
|
||||
smpl_t aubio_schmittS16LE (aubio_pitchschmitt_t * p, uint_t nframes,
|
||||
signed short int *indata);
|
||||
|
||||
struct _aubio_pitchschmitt_t
|
||||
{
|
||||
uint_t blockSize;
|
||||
uint_t rate;
|
||||
signed short int *schmittBuffer;
|
||||
signed short int *schmittPointer;
|
||||
signed short int *buf;
|
||||
};
|
||||
|
||||
aubio_pitchschmitt_t *
|
||||
new_aubio_pitchschmitt (uint_t size)
|
||||
{
|
||||
aubio_pitchschmitt_t *p = AUBIO_NEW (aubio_pitchschmitt_t);
|
||||
p->blockSize = size;
|
||||
p->schmittBuffer = AUBIO_ARRAY (signed short int, p->blockSize);
|
||||
p->buf = AUBIO_ARRAY (signed short int, p->blockSize);
|
||||
p->schmittPointer = p->schmittBuffer;
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitchschmitt_do (aubio_pitchschmitt_t * p, const fvec_t * input,
|
||||
fvec_t * output)
|
||||
{
|
||||
uint_t j;
|
||||
for (j = 0; j < input->length; j++) {
|
||||
p->buf[j] = input->data[j] * 32768.;
|
||||
}
|
||||
output->data[0] = aubio_schmittS16LE (p, input->length, p->buf);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_schmittS16LE (aubio_pitchschmitt_t * p, uint_t nframes,
|
||||
signed short int *indata)
|
||||
{
|
||||
uint_t i, j;
|
||||
uint_t blockSize = p->blockSize;
|
||||
signed short int *schmittBuffer = p->schmittBuffer;
|
||||
signed short int *schmittPointer = p->schmittPointer;
|
||||
|
||||
smpl_t period = 0., trigfact = 0.6;
|
||||
|
||||
for (i = 0; i < nframes; i++) {
|
||||
*schmittPointer++ = indata[i];
|
||||
if (schmittPointer - schmittBuffer >= (sint_t) blockSize) {
|
||||
sint_t endpoint, startpoint, t1, t2, A1, A2, tc, schmittTriggered;
|
||||
|
||||
schmittPointer = schmittBuffer;
|
||||
|
||||
for (j = 0, A1 = 0, A2 = 0; j < blockSize; j++) {
|
||||
if (schmittBuffer[j] > 0 && A1 < schmittBuffer[j])
|
||||
A1 = schmittBuffer[j];
|
||||
if (schmittBuffer[j] < 0 && A2 < -schmittBuffer[j])
|
||||
A2 = -schmittBuffer[j];
|
||||
}
|
||||
t1 = (sint_t) (A1 * trigfact + 0.5);
|
||||
t2 = -(sint_t) (A2 * trigfact + 0.5);
|
||||
startpoint = 0;
|
||||
for (j = 1; j < blockSize && schmittBuffer[j] <= t1; j++);
|
||||
for ( ; j < blockSize - 1 && !(schmittBuffer[j] >= t2 &&
|
||||
schmittBuffer[j + 1] < t2); j++);
|
||||
startpoint = j;
|
||||
schmittTriggered = 0;
|
||||
endpoint = startpoint + 1;
|
||||
for (j = startpoint, tc = 0; j < blockSize; j++) {
|
||||
if (!schmittTriggered) {
|
||||
schmittTriggered = (schmittBuffer[j] >= t1);
|
||||
} else if (schmittBuffer[j] >= t2 && schmittBuffer[j + 1] < t2) {
|
||||
endpoint = j;
|
||||
tc++;
|
||||
schmittTriggered = 0;
|
||||
}
|
||||
}
|
||||
if ((endpoint > startpoint) && (tc > 0)) {
|
||||
period = (smpl_t) (endpoint - startpoint) / tc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p->schmittBuffer = schmittBuffer;
|
||||
p->schmittPointer = schmittPointer;
|
||||
return period;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitchschmitt (aubio_pitchschmitt_t * p)
|
||||
{
|
||||
AUBIO_FREE (p->schmittBuffer);
|
||||
AUBIO_FREE (p->buf);
|
||||
AUBIO_FREE (p);
|
||||
}
|
75
deps/aubio/src/pitch/pitchschmitt.h
vendored
Normal file
75
deps/aubio/src/pitch/pitchschmitt.h
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using a Schmitt trigger
|
||||
|
||||
This pitch extraction method implements a Schmitt trigger to estimate the
|
||||
period of a signal.
|
||||
|
||||
This file was derived from the tuneit project, written by Mario Lang to
|
||||
detect the fundamental frequency of a sound.
|
||||
|
||||
See http://delysid.org/tuneit.html
|
||||
|
||||
\example pitch/test-pitchschmitt.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHSCHMITT_H
|
||||
#define AUBIO_PITCHSCHMITT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchschmitt_t aubio_pitchschmitt_t;
|
||||
|
||||
/** execute pitch detection on an input buffer
|
||||
|
||||
\param p pitch detection object as returned by new_aubio_pitchschmitt
|
||||
\param samples_in input signal vector (length as specified at creation time)
|
||||
\param cands_out pitch period estimates, in samples
|
||||
|
||||
*/
|
||||
void aubio_pitchschmitt_do (aubio_pitchschmitt_t * p, const 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_pitchschmitt_t *new_aubio_pitchschmitt (uint_t buf_size);
|
||||
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param p pitch detection object as returned by new_aubio_pitchschmitt
|
||||
|
||||
*/
|
||||
void del_aubio_pitchschmitt (aubio_pitchschmitt_t * p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHSCHMITT_H */
|
116
deps/aubio/src/pitch/pitchspecacf.c
vendored
Normal file
116
deps/aubio/src/pitch/pitchspecacf.c
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
Copyright (C) 2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#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->fft = new_aubio_fft (bufsize);
|
||||
if (!p->fft) goto beach;
|
||||
p->win = new_aubio_window ("hanningz", bufsize);
|
||||
p->winput = new_fvec (bufsize);
|
||||
p->fftout = new_fvec (bufsize);
|
||||
p->sqrmag = new_fvec (bufsize);
|
||||
p->acf = new_fvec (bufsize / 2 + 1);
|
||||
p->tol = 1.;
|
||||
p->confidence = 0.;
|
||||
return p;
|
||||
|
||||
beach:
|
||||
AUBIO_FREE(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitchspecacf_do (aubio_pitchspecacf_t * p, const fvec_t * input, fvec_t * output)
|
||||
{
|
||||
uint_t l, tau;
|
||||
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
|
||||
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);
|
||||
del_fvec (p->acf);
|
||||
AUBIO_FREE (p);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchspecacf_get_confidence (const aubio_pitchspecacf_t * o) {
|
||||
// no confidence for now
|
||||
return o->confidence;
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitchspecacf_set_tolerance (aubio_pitchspecacf_t * p, smpl_t tol)
|
||||
{
|
||||
p->tol = tol;
|
||||
return 0;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchspecacf_get_tolerance (const aubio_pitchspecacf_t * p)
|
||||
{
|
||||
return p->tol;
|
||||
}
|
103
deps/aubio/src/pitch/pitchspecacf.h
vendored
Normal file
103
deps/aubio/src/pitch/pitchspecacf.h
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
Copyright (C) 2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \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, const 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 (const 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 (const aubio_pitchspecacf_t * o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHSPECACF_H */
|
189
deps/aubio/src/pitch/pitchyin.c
vendored
Normal file
189
deps/aubio/src/pitch/pitchyin.c
vendored
Normal file
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/* This algorithm was developed by A. de Cheveigné and H. Kawahara and
|
||||
* published in:
|
||||
*
|
||||
* de Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
|
||||
* estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
|
||||
*
|
||||
* see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "pitch/pitchyin.h"
|
||||
|
||||
struct _aubio_pitchyin_t
|
||||
{
|
||||
fvec_t *yin;
|
||||
smpl_t tol;
|
||||
uint_t peak_pos;
|
||||
};
|
||||
|
||||
#if 0
|
||||
/** 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 (const fvec_t * yinbuf);
|
||||
#endif
|
||||
|
||||
aubio_pitchyin_t *
|
||||
new_aubio_pitchyin (uint_t bufsize)
|
||||
{
|
||||
aubio_pitchyin_t *o = AUBIO_NEW (aubio_pitchyin_t);
|
||||
o->yin = new_fvec (bufsize / 2);
|
||||
o->tol = 0.15;
|
||||
o->peak_pos = 0;
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitchyin (aubio_pitchyin_t * o)
|
||||
{
|
||||
del_fvec (o->yin);
|
||||
AUBIO_FREE (o);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* outputs the difference function */
|
||||
void
|
||||
aubio_pitchyin_diff (fvec_t * input, fvec_t * yin)
|
||||
{
|
||||
uint_t j, tau;
|
||||
smpl_t tmp;
|
||||
for (tau = 0; tau < yin->length; tau++) {
|
||||
yin->data[tau] = 0.;
|
||||
}
|
||||
for (tau = 1; tau < yin->length; tau++) {
|
||||
for (j = 0; j < yin->length; j++) {
|
||||
tmp = input->data[j] - input->data[j + tau];
|
||||
yin->data[tau] += SQR (tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* cumulative mean normalized difference function */
|
||||
void
|
||||
aubio_pitchyin_getcum (fvec_t * yin)
|
||||
{
|
||||
uint_t tau;
|
||||
smpl_t tmp = 0.;
|
||||
yin->data[0] = 1.;
|
||||
//AUBIO_DBG("%f\t",yin->data[0]);
|
||||
for (tau = 1; tau < yin->length; tau++) {
|
||||
tmp += yin->data[tau];
|
||||
yin->data[tau] *= tau / tmp;
|
||||
//AUBIO_DBG("%f\t",yin->data[tau]);
|
||||
}
|
||||
//AUBIO_DBG("\n");
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitchyin_getpitch (const fvec_t * yin)
|
||||
{
|
||||
uint_t tau = 1;
|
||||
do {
|
||||
if (yin->data[tau] < 0.1) {
|
||||
while (yin->data[tau + 1] < yin->data[tau]) {
|
||||
tau++;
|
||||
}
|
||||
return tau;
|
||||
}
|
||||
tau++;
|
||||
} while (tau < yin->length);
|
||||
//AUBIO_DBG("No pitch found");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* all the above in one */
|
||||
void
|
||||
aubio_pitchyin_do (aubio_pitchyin_t * o, const fvec_t * input, fvec_t * out)
|
||||
{
|
||||
const smpl_t tol = o->tol;
|
||||
fvec_t* yin = o->yin;
|
||||
const smpl_t *input_data = input->data;
|
||||
const uint_t length = yin->length;
|
||||
smpl_t *yin_data = yin->data;
|
||||
uint_t j, tau;
|
||||
sint_t period;
|
||||
smpl_t tmp, tmp2 = 0.;
|
||||
|
||||
yin_data[0] = 1.;
|
||||
for (tau = 1; tau < length; tau++) {
|
||||
yin_data[tau] = 0.;
|
||||
for (j = 0; j < length; j++) {
|
||||
tmp = input_data[j] - input_data[j + tau];
|
||||
yin_data[tau] += SQR (tmp);
|
||||
}
|
||||
tmp2 += yin_data[tau];
|
||||
if (tmp2 != 0) {
|
||||
yin->data[tau] *= tau / tmp2;
|
||||
} else {
|
||||
yin->data[tau] = 1.;
|
||||
}
|
||||
period = tau - 3;
|
||||
if (tau > 4 && (yin_data[period] < tol) &&
|
||||
(yin_data[period] < yin_data[period + 1])) {
|
||||
o->peak_pos = (uint_t)period;
|
||||
out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos);
|
||||
return;
|
||||
}
|
||||
}
|
||||
o->peak_pos = (uint_t)fvec_min_elem (yin);
|
||||
out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchyin_get_confidence (aubio_pitchyin_t * o) {
|
||||
return 1. - o->yin->data[o->peak_pos];
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
100
deps/aubio/src/pitch/pitchyin.h
vendored
Normal file
100
deps/aubio/src/pitch/pitchyin.h
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using the YIN algorithm
|
||||
|
||||
This algorithm was developed by A. de Cheveigne and H. Kawahara and
|
||||
published in:
|
||||
|
||||
De Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
|
||||
estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
|
||||
|
||||
see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
|
||||
http://recherche.ircam.fr/equipes/pcm/cheveign/ps/2002_JASA_YIN_proof.pdf
|
||||
|
||||
\example pitch/test-pitchyin.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHYIN_H
|
||||
#define AUBIO_PITCHYIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchyin_t aubio_pitchyin_t;
|
||||
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param buf_size size of the input buffer to analyse
|
||||
|
||||
*/
|
||||
aubio_pitchyin_t *new_aubio_pitchyin (uint_t buf_size);
|
||||
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchyin()
|
||||
|
||||
*/
|
||||
void del_aubio_pitchyin (aubio_pitchyin_t * o);
|
||||
|
||||
/** execute pitch detection an input buffer
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchyin()
|
||||
\param samples_in input signal vector (length as specified at creation time)
|
||||
\param cands_out pitch period candidates, in samples
|
||||
|
||||
*/
|
||||
void aubio_pitchyin_do (aubio_pitchyin_t * o, const fvec_t * samples_in, fvec_t * cands_out);
|
||||
|
||||
|
||||
/** set tolerance parameter for YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\param tol tolerance parameter for minima selection [default 0.15]
|
||||
|
||||
*/
|
||||
uint_t aubio_pitchyin_set_tolerance (aubio_pitchyin_t * o, smpl_t tol);
|
||||
|
||||
/** get tolerance parameter for YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\return tolerance parameter for minima selection [default 0.15]
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchyin_get_tolerance (aubio_pitchyin_t * o);
|
||||
|
||||
/** get current confidence of YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\return confidence parameter
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchyin_get_confidence (aubio_pitchyin_t * o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHYIN_H */
|
201
deps/aubio/src/pitch/pitchyinfast.c
vendored
Normal file
201
deps/aubio/src/pitch/pitchyinfast.c
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
Copyright (C) 2003-2017 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/* This algorithm was developed by A. de Cheveigné and H. Kawahara and
|
||||
* published in:
|
||||
*
|
||||
* de Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
|
||||
* estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
|
||||
*
|
||||
* see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "cvec.h"
|
||||
#include "spectral/fft.h"
|
||||
#include "pitch/pitchyinfast.h"
|
||||
|
||||
struct _aubio_pitchyinfast_t
|
||||
{
|
||||
fvec_t *yin;
|
||||
smpl_t tol;
|
||||
uint_t peak_pos;
|
||||
fvec_t *tmpdata;
|
||||
fvec_t *sqdiff;
|
||||
fvec_t *kernel;
|
||||
fvec_t *samples_fft;
|
||||
fvec_t *kernel_fft;
|
||||
aubio_fft_t *fft;
|
||||
};
|
||||
|
||||
aubio_pitchyinfast_t *
|
||||
new_aubio_pitchyinfast (uint_t bufsize)
|
||||
{
|
||||
aubio_pitchyinfast_t *o = AUBIO_NEW (aubio_pitchyinfast_t);
|
||||
o->yin = new_fvec (bufsize / 2);
|
||||
o->tmpdata = new_fvec (bufsize);
|
||||
o->sqdiff = new_fvec (bufsize / 2);
|
||||
o->kernel = new_fvec (bufsize);
|
||||
o->samples_fft = new_fvec (bufsize);
|
||||
o->kernel_fft = new_fvec (bufsize);
|
||||
o->fft = new_aubio_fft (bufsize);
|
||||
if (!o->yin || !o->tmpdata || !o->tmpdata || !o->sqdiff
|
||||
|| !o->kernel || !o->samples_fft || !o->kernel || !o->fft)
|
||||
{
|
||||
del_aubio_pitchyinfast(o);
|
||||
return NULL;
|
||||
}
|
||||
o->tol = 0.15;
|
||||
o->peak_pos = 0;
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitchyinfast (aubio_pitchyinfast_t * o)
|
||||
{
|
||||
if (o->yin)
|
||||
del_fvec (o->yin);
|
||||
if (o->tmpdata)
|
||||
del_fvec (o->tmpdata);
|
||||
if (o->sqdiff)
|
||||
del_fvec (o->sqdiff);
|
||||
if (o->kernel)
|
||||
del_fvec (o->kernel);
|
||||
if (o->samples_fft)
|
||||
del_fvec (o->samples_fft);
|
||||
if (o->kernel_fft)
|
||||
del_fvec (o->kernel_fft);
|
||||
if (o->fft)
|
||||
del_aubio_fft (o->fft);
|
||||
AUBIO_FREE (o);
|
||||
}
|
||||
|
||||
/* all the above in one */
|
||||
void
|
||||
aubio_pitchyinfast_do (aubio_pitchyinfast_t * o, const fvec_t * input, fvec_t * out)
|
||||
{
|
||||
const smpl_t tol = o->tol;
|
||||
fvec_t* yin = o->yin;
|
||||
const uint_t length = yin->length;
|
||||
uint_t B = o->tmpdata->length;
|
||||
uint_t W = o->yin->length; // B / 2
|
||||
fvec_t tmp_slice, kernel_ptr;
|
||||
uint_t tau;
|
||||
sint_t period;
|
||||
smpl_t tmp2 = 0.;
|
||||
|
||||
// compute r_t(0) + r_t+tau(0)
|
||||
{
|
||||
fvec_t *squares = o->tmpdata;
|
||||
fvec_weighted_copy(input, input, squares);
|
||||
#if 0
|
||||
for (tau = 0; tau < W; tau++) {
|
||||
tmp_slice.data = squares->data + tau;
|
||||
tmp_slice.length = W;
|
||||
o->sqdiff->data[tau] = fvec_sum(&tmp_slice);
|
||||
}
|
||||
#else
|
||||
tmp_slice.data = squares->data;
|
||||
tmp_slice.length = W;
|
||||
o->sqdiff->data[0] = fvec_sum(&tmp_slice);
|
||||
for (tau = 1; tau < W; tau++) {
|
||||
o->sqdiff->data[tau] = o->sqdiff->data[tau-1];
|
||||
o->sqdiff->data[tau] -= squares->data[tau-1];
|
||||
o->sqdiff->data[tau] += squares->data[W+tau-1];
|
||||
}
|
||||
#endif
|
||||
fvec_add(o->sqdiff, o->sqdiff->data[0]);
|
||||
}
|
||||
// compute r_t(tau) = -2.*ifft(fft(samples)*fft(samples[W-1::-1]))
|
||||
{
|
||||
fvec_t *compmul = o->tmpdata;
|
||||
fvec_t *rt_of_tau = o->samples_fft;
|
||||
aubio_fft_do_complex(o->fft, input, o->samples_fft);
|
||||
// build kernel, take a copy of first half of samples
|
||||
tmp_slice.data = input->data;
|
||||
tmp_slice.length = W;
|
||||
kernel_ptr.data = o->kernel->data + 1;
|
||||
kernel_ptr.length = W;
|
||||
fvec_copy(&tmp_slice, &kernel_ptr);
|
||||
// reverse them
|
||||
fvec_rev(&kernel_ptr);
|
||||
// compute fft(kernel)
|
||||
aubio_fft_do_complex(o->fft, o->kernel, o->kernel_fft);
|
||||
// compute complex product
|
||||
compmul->data[0] = o->kernel_fft->data[0] * o->samples_fft->data[0];
|
||||
for (tau = 1; tau < W; tau++) {
|
||||
compmul->data[tau] = o->kernel_fft->data[tau] * o->samples_fft->data[tau];
|
||||
compmul->data[tau] -= o->kernel_fft->data[B-tau] * o->samples_fft->data[B-tau];
|
||||
}
|
||||
compmul->data[W] = o->kernel_fft->data[W] * o->samples_fft->data[W];
|
||||
for (tau = 1; tau < W; tau++) {
|
||||
compmul->data[B-tau] = o->kernel_fft->data[B-tau] * o->samples_fft->data[tau];
|
||||
compmul->data[B-tau] += o->kernel_fft->data[tau] * o->samples_fft->data[B-tau];
|
||||
}
|
||||
// compute inverse fft
|
||||
aubio_fft_rdo_complex(o->fft, compmul, rt_of_tau);
|
||||
// compute square difference r_t(tau) = sqdiff - 2 * r_t_tau[W-1:-1]
|
||||
for (tau = 0; tau < W; tau++) {
|
||||
yin->data[tau] = o->sqdiff->data[tau] - 2. * rt_of_tau->data[tau+W];
|
||||
}
|
||||
}
|
||||
|
||||
// now build yin and look for first minimum
|
||||
fvec_zeros(out);
|
||||
yin->data[0] = 1.;
|
||||
for (tau = 1; tau < length; tau++) {
|
||||
tmp2 += yin->data[tau];
|
||||
if (tmp2 != 0) {
|
||||
yin->data[tau] *= tau / tmp2;
|
||||
} else {
|
||||
yin->data[tau] = 1.;
|
||||
}
|
||||
period = tau - 3;
|
||||
if (tau > 4 && (yin->data[period] < tol) &&
|
||||
(yin->data[period] < yin->data[period + 1])) {
|
||||
o->peak_pos = (uint_t)period;
|
||||
out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// use global minimum
|
||||
o->peak_pos = (uint_t)fvec_min_elem (yin);
|
||||
out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchyinfast_get_confidence (aubio_pitchyinfast_t * o) {
|
||||
return 1. - o->yin->data[o->peak_pos];
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitchyinfast_set_tolerance (aubio_pitchyinfast_t * o, smpl_t tol)
|
||||
{
|
||||
o->tol = tol;
|
||||
return 0;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchyinfast_get_tolerance (aubio_pitchyinfast_t * o)
|
||||
{
|
||||
return o->tol;
|
||||
}
|
102
deps/aubio/src/pitch/pitchyinfast.h
vendored
Normal file
102
deps/aubio/src/pitch/pitchyinfast.h
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
Copyright (C) 2003-2017 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using YIN algorithm (fast implementation)
|
||||
|
||||
This algorithm was developed by A. de Cheveigne and H. Kawahara and
|
||||
published in:
|
||||
|
||||
De Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency
|
||||
estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
|
||||
|
||||
This implementation compute the autocorrelation function using time domain
|
||||
convolution computed in the spectral domain.
|
||||
|
||||
see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
|
||||
http://recherche.ircam.fr/equipes/pcm/cheveign/ps/2002_JASA_YIN_proof.pdf
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHYINFAST_H
|
||||
#define AUBIO_PITCHYINFAST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchyinfast_t aubio_pitchyinfast_t;
|
||||
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param buf_size size of the input buffer to analyse
|
||||
|
||||
*/
|
||||
aubio_pitchyinfast_t *new_aubio_pitchyinfast (uint_t buf_size);
|
||||
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchyin()
|
||||
|
||||
*/
|
||||
void del_aubio_pitchyinfast (aubio_pitchyinfast_t * o);
|
||||
|
||||
/** execute pitch detection an input buffer
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchyin()
|
||||
\param samples_in input signal vector (length as specified at creation time)
|
||||
\param cands_out pitch period candidates, in samples
|
||||
|
||||
*/
|
||||
void aubio_pitchyinfast_do (aubio_pitchyinfast_t * o, const fvec_t * samples_in, fvec_t * cands_out);
|
||||
|
||||
|
||||
/** set tolerance parameter for YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\param tol tolerance parameter for minima selection [default 0.15]
|
||||
|
||||
*/
|
||||
uint_t aubio_pitchyinfast_set_tolerance (aubio_pitchyinfast_t * o, smpl_t tol);
|
||||
|
||||
/** get tolerance parameter for YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\return tolerance parameter for minima selection [default 0.15]
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchyinfast_get_tolerance (aubio_pitchyinfast_t * o);
|
||||
|
||||
/** get current confidence of YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\return confidence parameter
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchyinfast_get_confidence (aubio_pitchyinfast_t * o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHYINFAST_H */
|
||||
|
208
deps/aubio/src/pitch/pitchyinfft.c
vendored
Normal file
208
deps/aubio/src/pitch/pitchyinfft.c
vendored
Normal file
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "aubio_priv.h"
|
||||
#include "fvec.h"
|
||||
#include "cvec.h"
|
||||
#include "mathutils.h"
|
||||
#include "spectral/fft.h"
|
||||
#include "pitch/pitchyinfft.h"
|
||||
|
||||
/** pitch yinfft structure */
|
||||
struct _aubio_pitchyinfft_t
|
||||
{
|
||||
fvec_t *win; /**< temporal weighting window */
|
||||
fvec_t *winput; /**< windowed spectrum */
|
||||
fvec_t *sqrmag; /**< square difference function */
|
||||
fvec_t *weight; /**< spectral weighting window (psychoacoustic model) */
|
||||
fvec_t *fftout; /**< Fourier transform output */
|
||||
aubio_fft_t *fft; /**< fft object to compute square difference function */
|
||||
fvec_t *yinfft; /**< Yin function */
|
||||
smpl_t tol; /**< Yin tolerance */
|
||||
uint_t peak_pos; /**< currently selected peak pos*/
|
||||
uint_t short_period; /** shortest period under which to check for octave error */
|
||||
};
|
||||
|
||||
static const smpl_t freqs[] = {
|
||||
0., 20., 25., 31.5, 40., 50., 63., 80., 100., 125.,
|
||||
160., 200., 250., 315., 400., 500., 630., 800., 1000., 1250.,
|
||||
1600., 2000., 2500., 3150., 4000., 5000., 6300., 8000., 9000., 10000.,
|
||||
12500., 15000., 20000., 25100., -1.
|
||||
};
|
||||
|
||||
static const smpl_t weight[] = {
|
||||
-75.8, -70.1, -60.8, -52.1, -44.2, -37.5, -31.3, -25.6, -20.9, -16.5,
|
||||
-12.6, -9.60, -7.00, -4.70, -3.00, -1.80, -0.80, -0.20, -0.00, 0.50,
|
||||
1.60, 3.20, 5.40, 7.80, 8.10, 5.30, -2.40, -11.1, -12.8, -12.2,
|
||||
-7.40, -17.8, -17.8, -17.8
|
||||
};
|
||||
|
||||
aubio_pitchyinfft_t *
|
||||
new_aubio_pitchyinfft (uint_t samplerate, uint_t bufsize)
|
||||
{
|
||||
uint_t i = 0, j = 1;
|
||||
smpl_t freq = 0, a0 = 0, a1 = 0, f0 = 0, f1 = 0;
|
||||
aubio_pitchyinfft_t *p = AUBIO_NEW (aubio_pitchyinfft_t);
|
||||
p->winput = new_fvec (bufsize);
|
||||
p->fft = new_aubio_fft (bufsize);
|
||||
if (!p->fft) goto beach;
|
||||
p->fftout = new_fvec (bufsize);
|
||||
p->sqrmag = new_fvec (bufsize);
|
||||
p->yinfft = new_fvec (bufsize / 2 + 1);
|
||||
p->tol = 0.85;
|
||||
p->peak_pos = 0;
|
||||
p->win = new_aubio_window ("hanningz", bufsize);
|
||||
p->weight = new_fvec (bufsize / 2 + 1);
|
||||
for (i = 0; i < p->weight->length; i++) {
|
||||
freq = (smpl_t) i / (smpl_t) bufsize *(smpl_t) samplerate;
|
||||
while (freq > freqs[j] && freqs[j] > 0) {
|
||||
//AUBIO_DBG("freq %3.5f > %3.5f \tsamplerate %d (Hz) \t"
|
||||
// "(weight length %d, bufsize %d) %d %d\n", freq, freqs[j],
|
||||
// samplerate, p->weight->length, bufsize, i, j);
|
||||
j += 1;
|
||||
}
|
||||
a0 = weight[j - 1];
|
||||
f0 = freqs[j - 1];
|
||||
a1 = weight[j];
|
||||
f1 = freqs[j];
|
||||
if (f0 == f1) { // just in case
|
||||
p->weight->data[i] = a0;
|
||||
} else if (f0 == 0) { // y = ax+b
|
||||
p->weight->data[i] = (a1 - a0) / f1 * freq + a0;
|
||||
} else {
|
||||
p->weight->data[i] = (a1 - a0) / (f1 - f0) * freq +
|
||||
(a0 - (a1 - a0) / (f1 / f0 - 1.));
|
||||
}
|
||||
while (freq > freqs[j]) {
|
||||
j += 1;
|
||||
}
|
||||
//AUBIO_DBG("%f\n",p->weight->data[i]);
|
||||
p->weight->data[i] = DB2LIN (p->weight->data[i]);
|
||||
//p->weight->data[i] = SQRT(DB2LIN(p->weight->data[i]));
|
||||
}
|
||||
// check for octave errors above 1300 Hz
|
||||
p->short_period = (uint_t)ROUND(samplerate / 1300.);
|
||||
return p;
|
||||
|
||||
beach:
|
||||
if (p->winput) del_fvec(p->winput);
|
||||
AUBIO_FREE(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, const fvec_t * input, fvec_t * output)
|
||||
{
|
||||
uint_t tau, l;
|
||||
uint_t length = p->fftout->length;
|
||||
uint_t halfperiod;
|
||||
fvec_t *fftout = p->fftout;
|
||||
fvec_t *yin = p->yinfft;
|
||||
smpl_t tmp = 0., sum = 0.;
|
||||
// window the input
|
||||
fvec_weighted_copy(input, p->win, p->winput);
|
||||
// get the real / imag parts of its fft
|
||||
aubio_fft_do_complex (p->fft, p->winput, fftout);
|
||||
// get the squared magnitude spectrum, applying some weight
|
||||
p->sqrmag->data[0] = SQR(fftout->data[0]);
|
||||
p->sqrmag->data[0] *= p->weight->data[0];
|
||||
for (l = 1; l < length / 2; l++) {
|
||||
p->sqrmag->data[l] = SQR(fftout->data[l]) + SQR(fftout->data[length - l]);
|
||||
p->sqrmag->data[l] *= p->weight->data[l];
|
||||
p->sqrmag->data[length - l] = p->sqrmag->data[l];
|
||||
}
|
||||
p->sqrmag->data[length / 2] = SQR(fftout->data[length / 2]);
|
||||
p->sqrmag->data[length / 2] *= p->weight->data[length / 2];
|
||||
// get sum of weighted squared mags
|
||||
for (l = 0; l < length / 2 + 1; l++) {
|
||||
sum += p->sqrmag->data[l];
|
||||
}
|
||||
sum *= 2.;
|
||||
// get the real / imag parts of the fft of the squared magnitude
|
||||
aubio_fft_do_complex (p->fft, p->sqrmag, fftout);
|
||||
yin->data[0] = 1.;
|
||||
for (tau = 1; tau < yin->length; tau++) {
|
||||
// compute the square differences
|
||||
yin->data[tau] = sum - fftout->data[tau];
|
||||
// and the cumulative mean normalized difference function
|
||||
tmp += yin->data[tau];
|
||||
if (tmp != 0) {
|
||||
yin->data[tau] *= tau / tmp;
|
||||
} else {
|
||||
yin->data[tau] = 1.;
|
||||
}
|
||||
}
|
||||
// find best candidates
|
||||
tau = fvec_min_elem (yin);
|
||||
if (yin->data[tau] < p->tol) {
|
||||
// no interpolation, directly return the period as an integer
|
||||
//output->data[0] = tau;
|
||||
//return;
|
||||
|
||||
// 3 point quadratic interpolation
|
||||
//return fvec_quadratic_peak_pos (yin,tau,1);
|
||||
/* additional check for (unlikely) octave doubling in higher frequencies */
|
||||
if (tau > p->short_period) {
|
||||
output->data[0] = fvec_quadratic_peak_pos (yin, tau);
|
||||
} else {
|
||||
/* should compare the minimum value of each interpolated peaks */
|
||||
halfperiod = FLOOR (tau / 2 + .5);
|
||||
if (yin->data[halfperiod] < p->tol)
|
||||
p->peak_pos = halfperiod;
|
||||
else
|
||||
p->peak_pos = tau;
|
||||
output->data[0] = fvec_quadratic_peak_pos (yin, p->peak_pos);
|
||||
}
|
||||
} else {
|
||||
p->peak_pos = 0;
|
||||
output->data[0] = 0.;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
del_aubio_pitchyinfft (aubio_pitchyinfft_t * p)
|
||||
{
|
||||
del_fvec (p->win);
|
||||
del_aubio_fft (p->fft);
|
||||
del_fvec (p->yinfft);
|
||||
del_fvec (p->sqrmag);
|
||||
del_fvec (p->fftout);
|
||||
del_fvec (p->winput);
|
||||
del_fvec (p->weight);
|
||||
AUBIO_FREE (p);
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchyinfft_get_confidence (aubio_pitchyinfft_t * o) {
|
||||
return 1. - o->yinfft->data[o->peak_pos];
|
||||
}
|
||||
|
||||
uint_t
|
||||
aubio_pitchyinfft_set_tolerance (aubio_pitchyinfft_t * p, smpl_t tol)
|
||||
{
|
||||
p->tol = tol;
|
||||
return 0;
|
||||
}
|
||||
|
||||
smpl_t
|
||||
aubio_pitchyinfft_get_tolerance (aubio_pitchyinfft_t * p)
|
||||
{
|
||||
return p->tol;
|
||||
}
|
99
deps/aubio/src/pitch/pitchyinfft.h
vendored
Normal file
99
deps/aubio/src/pitch/pitchyinfft.h
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
||||
Pitch detection using a spectral implementation of the YIN algorithm
|
||||
|
||||
This algorithm was derived from the YIN algorithm. In this implementation, a
|
||||
Fourier transform is used to compute a tapered square difference function,
|
||||
which allows spectral weighting. Because the difference function is tapered,
|
||||
the selection of the period is simplified.
|
||||
|
||||
Paul Brossier, [Automatic annotation of musical audio for interactive
|
||||
systems](http://aubio.org/phd/), Chapter 3, Pitch Analysis, PhD thesis,
|
||||
Centre for Digital music, Queen Mary University of London, London, UK, 2006.
|
||||
|
||||
\example pitch/test-pitchyinfft.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUBIO_PITCHYINFFT_H
|
||||
#define AUBIO_PITCHYINFFT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** pitch detection object */
|
||||
typedef struct _aubio_pitchyinfft_t aubio_pitchyinfft_t;
|
||||
|
||||
/** execute pitch detection on an input buffer
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchyinfft
|
||||
\param samples_in input signal vector (length as specified at creation time)
|
||||
\param cands_out pitch period candidates, in samples
|
||||
|
||||
*/
|
||||
void aubio_pitchyinfft_do (aubio_pitchyinfft_t * o, const fvec_t * samples_in, fvec_t * cands_out);
|
||||
/** creation of the pitch detection object
|
||||
|
||||
\param samplerate samplerate of the input signal
|
||||
\param buf_size size of the input buffer to analyse
|
||||
|
||||
*/
|
||||
aubio_pitchyinfft_t *new_aubio_pitchyinfft (uint_t samplerate, uint_t buf_size);
|
||||
/** deletion of the pitch detection object
|
||||
|
||||
\param o pitch detection object as returned by new_aubio_pitchyinfft()
|
||||
|
||||
*/
|
||||
void del_aubio_pitchyinfft (aubio_pitchyinfft_t * o);
|
||||
|
||||
/** get tolerance parameter for YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
|
||||
\return tolerance parameter for minima selection [default 0.15]
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchyinfft_get_tolerance (aubio_pitchyinfft_t * o);
|
||||
|
||||
/** set tolerance parameter for YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\param tol tolerance parameter for minima selection [default 0.15]
|
||||
|
||||
*/
|
||||
uint_t aubio_pitchyinfft_set_tolerance (aubio_pitchyinfft_t * o, smpl_t tol);
|
||||
|
||||
/** get current confidence of YIN algorithm
|
||||
|
||||
\param o YIN pitch detection object
|
||||
\return confidence parameter
|
||||
|
||||
*/
|
||||
smpl_t aubio_pitchyinfft_get_confidence (aubio_pitchyinfft_t * o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AUBIO_PITCHYINFFT_H */
|
Loading…
Add table
Add a link
Reference in a new issue