110 lines
3.4 KiB
C++
110 lines
3.4 KiB
C++
#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 fft.realfft
|
|
#define REALIFFT fft.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;
|
|
MayerFFT fft;
|
|
};
|
|
|
|
#endif // #ifndef Helmholtz_H
|