shithub: aubio

Download patch

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);