ref: 7a0495011fc900db311a726258eee5df41825703
parent: 603fca4c6194aa09cc4c252ba1c950d5247dc0ed
author: Paul Brossier <piem@altern.org>
date: Tue May 10 10:36:37 EDT 2005
added pitchfcomb and pitchschmitt
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,6 +17,8 @@
pitchdetection.h \
pitchmcomb.h \
pitchyin.h \
+ pitchschmitt.h \
+ pitchfcomb.h \
filter.h
lib_LTLIBRARIES = libaubio.la
@@ -50,6 +52,10 @@
pitchmcomb.h \
pitchyin.c \
pitchyin.h \
+ pitchschmitt.c \
+ pitchschmitt.h \
+ pitchfcomb.c \
+ pitchfcomb.h \
filter.c \
filter.h
--- a/src/aubio.h
+++ b/src/aubio.h
@@ -66,7 +66,6 @@
#include "onsetdetection.h"
#include "tss.h"
#include "resample.h"
-
#include "peakpick.h"
#include "biquad.h"
#include "filter.h"
@@ -73,6 +72,8 @@
#include "pitchdetection.h"
#include "pitchmcomb.h"
#include "pitchyin.h"
+#include "pitchschmitt.h"
+#include "pitchfcomb.h"
#ifdef __cplusplus
} /* extern "C" */
--- /dev/null
+++ b/src/pitchfcomb.c
@@ -1,0 +1,132 @@
+/*
+ Copyright (C) 2004, 2005 Mario Lang <mlang@delysid.org>
+
+ 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; k<MAX_PEAKS; k++) {
+ peaks[k].db = -200.;
+ peaks[k].freq = 0.;
+ }
+
+ aubio_pvoc_do (p->pvoc, 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<MAX_PEAKS && peaks[l].freq > 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);
+}
+
--- /dev/null
+++ b/src/pitchfcomb.h
@@ -1,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 */
+
+
--- a/src/pitchmcomb.c
+++ b/src/pitchmcomb.c
@@ -341,3 +341,16 @@
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;i<p->ncand;i++) {
+ AUBIO_FREE(p->candidates[i]);
+ }
+ AUBIO_FREE(p->candidates);
+ AUBIO_FREE(p);
+}
--- a/src/pitchmcomb.h
+++ b/src/pitchmcomb.h
@@ -35,6 +35,7 @@
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
}
--- /dev/null
+++ b/src/pitchschmitt.c
@@ -1,0 +1,115 @@
+/*
+ Copyright (C) 2004, 2005 Mario Lang <mlang@delysid.org>
+
+ 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; i<input->length; 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<nframes; i++) {
+ *schmittPointer++ = indata[i];
+ if (schmittPointer-schmittBuffer >= 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; schmittBuffer[j]<=t1 && j<blockSize; j++);
+ for (; !(schmittBuffer[j] >=t2 &&
+ schmittBuffer[j+1]< t2) && j<blockSize; 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) {
+ 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);
+}
+
--- /dev/null
+++ b/src/pitchschmitt.h
@@ -1,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 */
+
--- a/swig/aubio.i
+++ b/swig/aubio.i
@@ -162,11 +162,22 @@
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);