2 Copyright (C) 2004, 2005 Mario Lang <mlang@delysid.org>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "aubio_priv.h"
22 #include "pitchschmitt.h"
24 smpl_t aubio_schmittS16LE (aubio_pitchschmitt_t *p, uint_t nframes, signed short int *indata);
26 struct _aubio_pitchschmitt_t {
29 signed short int *schmittBuffer;
30 signed short int *schmittPointer;
33 aubio_pitchschmitt_t * new_aubio_pitchschmitt (uint_t size, uint_t samplerate)
35 aubio_pitchschmitt_t * p = AUBIO_NEW(aubio_pitchschmitt_t);
37 p->schmittBuffer = AUBIO_ARRAY(signed short int,p->blockSize);
38 p->schmittPointer = p->schmittBuffer;
43 smpl_t aubio_pitchschmitt_detect (aubio_pitchschmitt_t *p, fvec_t * input)
45 signed short int buf[input->length];
47 for (i=0; i<input->length; i++) {
48 buf[i] = input->data[0][i]*32768.;
50 return aubio_schmittS16LE(p, input->length, buf);
53 smpl_t aubio_schmittS16LE (aubio_pitchschmitt_t *p, uint_t nframes, signed short int *indata)
56 uint_t blockSize = p->blockSize;
57 signed short int *schmittBuffer = p->schmittBuffer;
58 signed short int *schmittPointer = p->schmittPointer;
60 smpl_t freq = 0., trigfact = 0.6;
62 for (i=0; i<nframes; i++) {
63 *schmittPointer++ = indata[i];
64 if (schmittPointer-schmittBuffer >= (sint_t)blockSize) {
65 sint_t endpoint, startpoint, t1, t2, A1, A2, tc, schmittTriggered;
67 schmittPointer = schmittBuffer;
69 for (j=0,A1=0,A2=0; j<blockSize; j++) {
70 if (schmittBuffer[j]>0 && A1<schmittBuffer[j]) A1 = schmittBuffer[j];
71 if (schmittBuffer[j]<0 && A2<-schmittBuffer[j]) A2 = -schmittBuffer[j];
73 t1 = (sint_t)( A1 * trigfact + 0.5);
74 t2 = - (sint_t)( A2 * trigfact + 0.5);
76 for (j=1; schmittBuffer[j]<=t1 && j<blockSize; j++);
77 for (; !(schmittBuffer[j] >=t2 &&
78 schmittBuffer[j+1]< t2) && j<blockSize; j++);
81 endpoint=startpoint+1;
82 for(j=startpoint,tc=0; j<blockSize; j++) {
83 if (!schmittTriggered) {
84 schmittTriggered = (schmittBuffer[j] >= t1);
85 } else if (schmittBuffer[j]>=t2 && schmittBuffer[j+1]<t2) {
91 if (endpoint > startpoint) {
92 freq = ((smpl_t)p->rate*(tc/(smpl_t)(endpoint-startpoint)));
97 p->schmittBuffer = schmittBuffer;
98 p->schmittPointer = schmittPointer;
102 void del_aubio_pitchschmitt (aubio_pitchschmitt_t *p)
104 AUBIO_FREE(p->schmittBuffer);