From 7a0495011fc900db311a726258eee5df41825703 Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Tue, 10 May 2005 14:36:37 +0000 Subject: [PATCH] added pitchfcomb and pitchschmitt --- src/Makefile.am | 6 +++ src/aubio.h | 3 +- src/pitchfcomb.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pitchfcomb.h | 40 ++++++++++++++++ src/pitchmcomb.c | 13 ++++++ src/pitchmcomb.h | 1 + src/pitchschmitt.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++ src/pitchschmitt.h | 39 ++++++++++++++++ swig/aubio.i | 11 +++++ 9 files changed, 359 insertions(+), 1 deletion(-) create mode 100644 src/pitchfcomb.c create mode 100644 src/pitchfcomb.h create mode 100644 src/pitchschmitt.c create mode 100644 src/pitchschmitt.h diff --git a/src/Makefile.am b/src/Makefile.am index 1ef0e115..f0516e30 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,6 +17,8 @@ pkginclude_HEADERS = aubio.h \ pitchdetection.h \ pitchmcomb.h \ pitchyin.h \ + pitchschmitt.h \ + pitchfcomb.h \ filter.h lib_LTLIBRARIES = libaubio.la @@ -50,6 +52,10 @@ libaubio_la_SOURCES = aubio.h \ pitchmcomb.h \ pitchyin.c \ pitchyin.h \ + pitchschmitt.c \ + pitchschmitt.h \ + pitchfcomb.c \ + pitchfcomb.h \ filter.c \ filter.h diff --git a/src/aubio.h b/src/aubio.h index d3279ebc..44ce440d 100644 --- a/src/aubio.h +++ b/src/aubio.h @@ -66,13 +66,14 @@ extern "C" { #include "onsetdetection.h" #include "tss.h" #include "resample.h" - #include "peakpick.h" #include "biquad.h" #include "filter.h" #include "pitchdetection.h" #include "pitchmcomb.h" #include "pitchyin.h" +#include "pitchschmitt.h" +#include "pitchfcomb.h" #ifdef __cplusplus } /* extern "C" */ diff --git a/src/pitchfcomb.c b/src/pitchfcomb.c new file mode 100644 index 00000000..1e200f81 --- /dev/null +++ b/src/pitchfcomb.c @@ -0,0 +1,132 @@ +/* + Copyright (C) 2004, 2005 Mario Lang + + This program 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 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/* + + This file was taken from the tuneit project, in the file + tuneit.c -- Detect fundamental frequency of a sound + see http://delysid.org/tuneit.html + + a fast harmonic comb filter algorithm for pitch tracking + +*/ + +#include "aubio_priv.h" +#include "sample.h" +#include "mathutils.h" +#include "phasevoc.h" +#include "pitchfcomb.h" + +#define MAX_PEAKS 8 + +typedef struct { + smpl_t freq; + smpl_t db; +} aubio_fpeak_t; + +struct _aubio_pitchfcomb_t { + uint_t fftSize; + uint_t rate; + cvec_t * fftOut; + fvec_t * fftLastPhase; + aubio_pvoc_t * pvoc; +}; + +aubio_pitchfcomb_t * new_aubio_pitchfcomb (uint_t size, uint_t samplerate) +{ + aubio_pitchfcomb_t * p = AUBIO_NEW(aubio_pitchfcomb_t); + uint_t overlap_rate = 4; + p->rate = samplerate; + p->fftSize = size; + p->fftOut = new_cvec(size,1); + p->fftLastPhase = new_fvec(size,1); + p->pvoc = new_aubio_pvoc(size, size/overlap_rate, 1); + return p; +} + +/* input must be stepsize long */ +smpl_t aubio_pitchfcomb_detect (aubio_pitchfcomb_t * p, fvec_t * input) +{ + uint_t k, l, maxharm = 0, stepSize = input->length; + smpl_t freqPerBin = p->rate/(smpl_t)p->fftSize, + phaseDifference = TWO_PI*(smpl_t)stepSize/(smpl_t)p->fftSize; + aubio_fpeak_t peaks[MAX_PEAKS]; + + for (k=0; kpvoc, input, p->fftOut); + + for (k=0; k<=p->fftSize; k++) { + //long qpd; + smpl_t + magnitude = 20.*LOG10(2.*p->fftOut->norm[0][k]/(smpl_t)p->fftSize), + phase = p->fftOut->phas[0][k], + tmp, freq; + + /* compute phase difference */ + tmp = phase - p->fftLastPhase->data[0][k]; + p->fftLastPhase->data[0][k] = phase; + + /* subtract expected phase difference */ + tmp -= (smpl_t)k*phaseDifference; + + /* map delta phase into +/- Pi interval */ + tmp = unwrap2pi(tmp); + + /* get deviation from bin frequency from the +/- Pi interval */ + tmp = p->fftSize/input->length*tmp/(TWO_PI); + + /* compute the k-th partials' true frequency */ + freq = (smpl_t)k*freqPerBin + tmp*freqPerBin; + + if (freq > 0.0 && magnitude > peaks[0].db && magnitude < 0) { + memmove(peaks+1, peaks, sizeof(aubio_fpeak_t)*(MAX_PEAKS-1)); + peaks[0].freq = freq; + peaks[0].db = magnitude; + } + } + + k = 0; + for (l=1; l 0.0; l++) { + sint_t harmonic; + for (harmonic=5; harmonic>1; harmonic--) { + if (peaks[0].freq / peaks[l].freq < harmonic+.02 && + peaks[0].freq / peaks[l].freq > harmonic-.02) { + if (harmonic > maxharm && + peaks[0].db < peaks[l].db/2) { + maxharm = harmonic; + k = l; + } + } + } + } + return peaks[k].freq; +} + +void del_aubio_pitchfcomb (aubio_pitchfcomb_t * p) +{ + del_cvec(p->fftOut); + del_fvec(p->fftLastPhase); + del_aubio_pvoc(p->pvoc); + AUBIO_FREE(p); +} + diff --git a/src/pitchfcomb.h b/src/pitchfcomb.h new file mode 100644 index 00000000..36e4cfab --- /dev/null +++ b/src/pitchfcomb.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 2003 Paul Brossier + + This program 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 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _PITCHFCOMB_H +#define _PITCHFCOMB_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _aubio_pitchfcomb_t aubio_pitchfcomb_t; + +smpl_t aubio_pitchfcomb_detect (aubio_pitchfcomb_t *p, fvec_t * input); +aubio_pitchfcomb_t * new_aubio_pitchfcomb (uint_t size, uint_t samplerate); +void del_aubio_pitchfcomb (aubio_pitchfcomb_t *p); + + +#ifdef __cplusplus +} +#endif + +#endif /* _PITCHFCOMB_H */ + + diff --git a/src/pitchmcomb.c b/src/pitchmcomb.c index 1c2fcf1a..7aa64a33 100644 --- a/src/pitchmcomb.c +++ b/src/pitchmcomb.c @@ -341,3 +341,16 @@ aubio_pitchmcomb_t * new_aubio_pitchmcomb(uint_t size, uint_t channels) { return p; } + +void del_aubio_pitchmcomb (aubio_pitchmcomb_t *p) { + uint_t i; + del_fvec(p->newmag); + del_fvec(p->newmag); + del_fvec(p->newmag); + AUBIO_FREE(p->peaks); + for (i=0;incand;i++) { + AUBIO_FREE(p->candidates[i]); + } + AUBIO_FREE(p->candidates); + AUBIO_FREE(p); +} diff --git a/src/pitchmcomb.h b/src/pitchmcomb.h index 49044e3d..00f2468b 100644 --- a/src/pitchmcomb.h +++ b/src/pitchmcomb.h @@ -35,6 +35,7 @@ typedef struct _aubio_pitchmcomb_t aubio_pitchmcomb_t; smpl_t aubio_pitchmcomb_detect(aubio_pitchmcomb_t * p, cvec_t * fftgrain); uint_t aubio_pitch_cands(aubio_pitchmcomb_t * p, cvec_t * fftgrain, smpl_t * cands); aubio_pitchmcomb_t * new_aubio_pitchmcomb(uint_t size, uint_t channels); +void del_aubio_pitchmcomb(aubio_pitchmcomb_t *p); #ifdef __cplusplus } diff --git a/src/pitchschmitt.c b/src/pitchschmitt.c new file mode 100644 index 00000000..087f21d0 --- /dev/null +++ b/src/pitchschmitt.c @@ -0,0 +1,115 @@ +/* + Copyright (C) 2004, 2005 Mario Lang + + This program 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 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/* + + This file was taken from the tuneit project, in the file + tuneit.c -- Detect fundamental frequency of a sound + see http://delysid.org/tuneit.html + + */ + +#include "aubio_priv.h" +#include "sample.h" +#include "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; +}; + +aubio_pitchschmitt_t * new_aubio_pitchschmitt (uint_t size, uint_t samplerate) +{ + aubio_pitchschmitt_t * p = AUBIO_NEW(aubio_pitchschmitt_t); + p->blockSize = size; + p->schmittBuffer = AUBIO_ARRAY(signed short int,p->blockSize); + p->schmittPointer = p->schmittBuffer; + p->rate = samplerate; + return p; +} + +smpl_t aubio_pitchschmitt_detect (aubio_pitchschmitt_t *p, fvec_t * input) +{ + signed short int buf[input->length]; + uint_t i; + for (i=0; ilength; i++) { + buf[i] = input->data[0][i]*32768.; + } + return aubio_schmittS16LE(p, input->length, 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 freq = 0., trigfact = 0.6; + + for (i=0; i= blockSize) { + sint_t endpoint, startpoint, t1, t2, A1, A2, tc, schmittTriggered; + + schmittPointer = schmittBuffer; + + for (j=0,A1=0,A2=0; j0 && A1=t2 && + schmittBuffer[j+1]< t2) && j= t1); + } else if (schmittBuffer[j]>=t2 && schmittBuffer[j+1] startpoint) { + freq = ((smpl_t)p->rate*(tc/(smpl_t)(endpoint-startpoint))); + } + } + } + + p->schmittBuffer = schmittBuffer; + p->schmittPointer = schmittPointer; + return freq; +} + +void del_aubio_pitchschmitt (aubio_pitchschmitt_t *p) +{ + AUBIO_FREE(p->schmittBuffer); + AUBIO_FREE(p); +} + diff --git a/src/pitchschmitt.h b/src/pitchschmitt.h new file mode 100644 index 00000000..c673be04 --- /dev/null +++ b/src/pitchschmitt.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2003 Paul Brossier + + This program 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 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _PITCHSCHMITT_H +#define _PITCHSCHMITT_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _aubio_pitchschmitt_t aubio_pitchschmitt_t; + +smpl_t aubio_pitchschmitt_detect (aubio_pitchschmitt_t *p, fvec_t * input); +aubio_pitchschmitt_t * new_aubio_pitchschmitt (uint_t size, uint_t samplerate); +void del_aubio_pitchschmitt (aubio_pitchschmitt_t *p); + + +#ifdef __cplusplus +} +#endif + +#endif /* _PITCHSCHMITT_H */ + diff --git a/swig/aubio.i b/swig/aubio.i index 79545dd1..1cdbdf58 100644 --- a/swig/aubio.i +++ b/swig/aubio.i @@ -162,12 +162,23 @@ void aubio_pvoc_rdo(aubio_pvoc_t *pv, cvec_t * fftgrain, fvec_t *out); aubio_pitchmcomb_t * new_aubio_pitchmcomb(uint_t size, uint_t channels); smpl_t aubio_pitchmcomb_detect(aubio_pitchmcomb_t * p, cvec_t * fftgrain); uint_t aubio_pitch_cands(aubio_pitchmcomb_t * p, cvec_t * fftgrain, smpl_t * cands); +void del_aubio_pitchmcomb (aubio_pitchmcomb_t *p); /* pitch yin */ void aubio_pitchyin_diff(fvec_t *input, fvec_t *yin); void aubio_pitchyin_getcum(fvec_t *yin); uint_t aubio_pitchyin_getpitch(fvec_t *yin); +/* pitch schmitt */ +aubio_pitchschmitt_t * new_aubio_pitchschmitt (uint_t size, uint_t samplerate); +smpl_t aubio_pitchschmitt_detect (aubio_pitchschmitt_t *p, fvec_t * input); +void del_aubio_pitchschmitt (aubio_pitchschmitt_t *p); + +/* pitch fcomb */ +aubio_pitchfcomb_t * new_aubio_pitchfcomb (uint_t size, uint_t samplerate); +smpl_t aubio_pitchfcomb_detect (aubio_pitchfcomb_t *p, fvec_t * input); +void del_aubio_pitchfcomb (aubio_pitchfcomb_t *p); + /* peakpicker */ aubio_pickpeak_t * new_aubio_peakpicker(smpl_t threshold); uint_t aubio_peakpick_pimrt(fvec_t * DF, aubio_pickpeak_t * p); -- 2.11.0