#ifndef Helmholtz_H #define Helmholtz_H /*********************************************************************** Class Helmholtz implements a period-length detector using Philip McLeod's Specially Normalized AutoCorrelation function (SNAC). Function iosamples() takes a pointer to a buffer with n signal input samples and a pointer to a buffer where n output samples are stored, representing the SNAC function. Via function setframesize(), analysis frame size can be set to 128, 256, 512, 1024 or 2048 samples. Default is 1024. With setoverlap(), analysis frames can be set to overlap each other with factor 1, 2, 4 or 8. Default is 1. Function setbias() sets a bias which favours small lags over large lags in the period detection, thereby avoiding low-octave jumps. Default is 0.2 Function setminRMS() is used as a sensitivity setting. Default is RMS 0.003. With function getperiod(), the last detected period length is returned as number of samples with a possible fraction (floating point format). Function getfidelity() returns a value between 0. and 1. indicating to which extent the input signal is periodic. A fidelity of ~0.95 can be considered to indicate a periodic signal. Class Helmholtz needs mayer_realfft() and mayer_realifft() or similar fft functions. Note that Ron Mayer's functions for real fft have a peculiar organisation of imaginary coefficients (reversed order, sign flipped). Class Helmholtz uses t_float for float or double. Depending on the context where the class is used, you may need to define t_float. If used with PD or MaxMsp, it is already defined. *********************************************************************** Licensed under three-clause BSD license. Katja Vetter, Feb 2012. ***********************************************************************/ /* This section includes the Pure Data API header. If you build Helmholtz against another DSP framework, you need to define t_float, and you need to include Ron Mayer's fft or similar functionality. */ #include "mayer_fft.h" #define REALFFT mayer_realfft #define REALIFFT mayer_realifft /***********************************************************************/ #define DEFFRAMESIZE 1024 // default analysis framesize #define DEFOVERLAP 1 // default overlap #define DEFBIAS 0.2 // default bias #define DEFMINRMS 0.003 // default minimum RMS #define SEEK 0.85 // seek-length as ratio of framesize #define t_float float class Helmholtz { public: Helmholtz(int periodarg = DEFFRAMESIZE, int overlaparg = DEFOVERLAP, t_float biasarg = DEFBIAS); ~Helmholtz(); void iosamples(const t_float* in, t_float* out, int size); void setframesize(int frame); void setoverlap(int lap); void setbias(t_float bias); void setminRMS(t_float rms); t_float getperiod() const; t_float getfidelity() const; private: // procedures void analyzeframe(); void autocorrelation(); void normalize(); void pickpeak(); void periodandfidelity(); // functions t_float interpolate3max(t_float* buf, int peakindex); t_float interpolate3phase(t_float* buf, int peakindex); // buffers t_float inputbuf[2048]; t_float inputbuf2[2048]; t_float processbuf[4096]; // state variables int timeindex; int framesize; int overlap; int periodindex; t_float periodlength; t_float fidelity; t_float biasfactor; t_float minrms; }; #endif // #ifndef Helmholtz_H