xue@11: /* xue@11: Harmonic sinusoidal modelling and tools xue@11: xue@11: C++ code package for harmonic sinusoidal modelling and relevant signal processing. xue@11: Centre for Digital Music, Queen Mary, University of London. xue@11: This file copyright 2011 Wen Xue. xue@11: xue@11: This program is free software; you can redistribute it and/or xue@11: modify it under the terms of the GNU General Public License as xue@11: published by the Free Software Foundation; either version 2 of the xue@11: License, or (at your option) any later version. xue@11: */ xue@1: #ifndef proceduresH xue@1: #define proceduresH xue@1: Chris@5: /** Chris@5: \file procedures.h - this file collects miscellaneous structures and functions. Not all of these are xue@1: referenced somewhere else. xue@1: */ xue@1: xue@1: xue@1: //--------------------------------------------------------------------------- xue@1: #include xue@1: #include xue@1: #include xue@1: #include "fft.h" xue@1: #include "windowfunctions.h" xue@1: Chris@5: /** xue@1: macro testnn: non-negative test. This macro throws out an exception if the value of x is negative. xue@1: */ xue@1: #ifndef testnn xue@1: #define testnn(x) {try{if (x<0) throw("testnn");}catch(...){x=0;}} xue@1: #endif xue@1: xue@1: /* xue@1: macro AllocateGMM and ReleaseGMM: allocates and frees buffers that hosts descriptors of a Gaussian- xue@1: mixture model. xue@1: */ xue@1: #define AllocateGMM(_MIXS, _DIM, _P, _M, _DEV) \ xue@1: double* _P=new double[_MIXS]; double** _M=new double*[_MIXS]; double ** _DEV=new double*[_MIXS]; \ xue@1: _M[0]=new double[(_MIXS)*(_DIM)]; _DEV[0]=new double[(_MIXS)*(_DIM)]; \ xue@1: for (int _MIX=1; _MIX<_MIXS; _MIX++) _M[_MIX]=&_M[0][_MIX*(_DIM)], _DEV[_MIX]=&_DEV[0][_MIX*(_DIM)]; xue@1: #define ReleaseGMM(_P, _M, _DEV) \ xue@1: delete[] _P; if (_M) {delete[] _M[0]; delete[] _M;} if (_DEV) {delete[] _DEV[0]; delete[] _DEV;} xue@1: xue@1: xue@1: //--------------------------------------------------------------------------- Chris@5: /** xue@1: Tick count tool (stop watch) is made up of a TickClock struct and three macros that uses this xue@1: structure as augument. xue@1: xue@1: Use of TickClock: declare the instance directly. Use StartClock() and StopClock() to start and stop xue@1: tick counting. Each time the clock is stopped the interval between last start and stop operations is xue@1: added to run-time t. Clear the recorded run-time with ResetClock(). xue@1: */ xue@1: struct TickClock //tick counter struct xue@1: { xue@1: double t; //accumulated run time xue@1: __int64 Ticks; //tick count recorded at start trigger xue@1: __int64 Ticks2; //tick count recorded at stop trigger xue@1: }; xue@1: #define ResetClock(AClock) {AClock.t=0;} xue@1: #define StartClock(AClock) {AClock.Ticks=GetTickCount();} xue@1: #define StopClock(AClock) {AClock.Ticks2=GetTickCount(); AClock.t+=0.001*(AClock.Ticks2-AClock.Ticks);} xue@1: xue@1: //--------------------------------------------------------------------------- xue@1: xue@1: struct fftparams //buffers used by FFT routines xue@1: { xue@1: double* Amp; //amplitude output buffer xue@1: double* Arg; //phase angle output buffer xue@1: cdouble* w; //twiddle factor buffer xue@1: cdouble* x; //data buffer xue@1: }; xue@1: xue@1: struct TGMM //Gaussian mixture model xue@1: { xue@1: public: xue@1: bool mcs; xue@1: int mixs; //number of mixtures xue@1: int dim; //data dimension xue@1: double* p; //mixture weights xue@1: double** m; //mixture component centres xue@1: double** dev; //diagonal mixture component correlation xue@1: double acct; xue@1: TGMM(); xue@1: ~TGMM(); xue@1: }; xue@1: xue@1: struct TTFSpan //a rectanguar area in the T-F plane xue@1: { xue@1: int T1; //start time xue@1: int T2; //finish time xue@1: double F1; //lowest frequency xue@1: double F2; //highest frequency xue@1: }; xue@1: xue@1: struct TSpecPeak //spectral peak xue@1: { xue@1: int t; //time in samples xue@1: int tres; //time resolution xue@1: double f; //digital frequency xue@1: double fres; //frequency resolution xue@1: double df; //derivative of f xue@1: double am; //amplitude xue@1: double ph; //phase angle xue@1: }; xue@1: Chris@5: /** xue@1: TSpecTrack is a class that maintains a list of TSpecPeak objects that form a spectral track. It models xue@1: a sinusid track in sinusoid modeling. xue@1: */ xue@1: class TSpecTrack xue@1: { xue@1: private: xue@1: int Capacity; //number of peaks the current storage space is allocated to host xue@1: public: xue@1: int t1; //time of first peak xue@1: int t2; //time of last peak xue@1: double fmin; //minimum peak frequency xue@1: double fmax; //maximum peak frequency xue@1: xue@1: int Count; //number of peaks in the track xue@1: TSpecPeak* Peaks; //peaks in the track, ordered by time xue@1: xue@1: TSpecTrack(int ACapacity=50); xue@1: ~TSpecTrack(); xue@1: xue@1: void InsertPeak(TSpecPeak& APeak, int index); xue@1: int LocatePeak(TSpecPeak& APeak); xue@1: int Add(TSpecPeak& APeak); xue@1: }; xue@1: Chris@5: /** xue@1: TTFSpans is a class that maintains a list of TFSpans. This is used to mark selected areas in the time- xue@1: frequency plane for further processing. xue@1: */ xue@1: class TTFSpans xue@1: { xue@1: public: xue@1: int Count; //number of spans xue@1: int Capacity; //number of spans the current storage space is allocated to host xue@1: TTFSpan* Items; //the hosted spans xue@1: xue@1: TTFSpans(); xue@1: ~TTFSpans(); xue@1: void Add(TTFSpan& ATFSpan); xue@1: void Clear(); xue@1: int Delete(int Index); xue@1: }; xue@1: xue@1: double ACPower(double* data, int Count, void*); xue@1: void Add(double* dest, double* source, int Count); xue@1: void Add(double* out, double* addend, double* adder, int count); xue@1: void ApplyWindow(double* OutBuffer, double* Buffer, double* Weights, int Size); xue@1: double Avg(double*, int, void*); xue@1: void AvgFilter(double* dataout, double* data, int Count, int HWid); xue@1: int BitInv(int value, int order); xue@1: void CalculateSpectrogram(double* data, int Count, int start, int end, int Wid, int Offst, double* Window=0, double** Spec=0, double** Ph=0, double amp=1, bool half=true); xue@1: void Conv(double* out, int N1, double* in1, int N2, double* in2); xue@1: void DCT( double* output, double* input, int N); xue@1: void IDCT( double* output, double* input, int N); xue@1: double DCAmplitude(double*, int, void*); xue@1: double DCPower(double*, int, void*); xue@1: double ddIPHann(double, void*); xue@1: void DeDC(double* data, int Count, int HWid); xue@1: void DeDC_static(double* data, int Count); xue@1: void DoubleToInt(void* out, int BytesPerSample, double* in, int Count); xue@1: void DoubleToIntAdd(void* out, int BytesPerSample, double* in, int Count); xue@1: double DPower(double* data, int Count, void*); xue@1: double Energy(double* data, int Count); xue@1: double ExpOnsetFilter(double* dataout, double* data, int Count, double Tr, double Ta); xue@1: double ExpOnsetFilter_balanced(double* dataout, double* data, int Count, double Tr, double Ta, int bal=5); xue@1: double ExtractLinearComponent(double* dataout, double* data, int Count); xue@1: void FFTConv(double* dest, double* source1, int size1, double* source2, int size2, int zero=0, double* pre_buffer=NULL, double* post_buffer=NULL); xue@1: void FFTConv(unsigned char* dest, unsigned char* source1, int bps, int size1, double* source2, int size2, int zero=0, unsigned char* pre_buffer=NULL, unsigned char* post_buffer=NULL); xue@1: void FFTConv(double* dest, double* source1, int size1, double* source2, int size2, double* pre_buffer=NULL); xue@1: void FFTFilter(double* dataout, double* data, int Count, int Wid, int On, int Off); xue@1: void FFTFilterOLA(double* dataout, double* data, int Count, int Wid, int On, int Off, double* pre_buffer=NULL); xue@1: void FFTFilterOLA(unsigned char* dataout, unsigned char* data, int BytesPerSample, int Count, int Wid, int On, int Off, unsigned char* pre_buffer=NULL); xue@1: void FFTFilterOLA(double* dataout, double* data, int Count, double* amp, double* ph, int Wid, double* pre_buffer=NULL); xue@1: double FFTMask(double* dataout, double* data, int Count, int Wid, double DigiOn, double DigiOff, double maskcoef=1); xue@1: int FindInc(double value, double* data, int Count); xue@1: double Gaussian(int Dim, double* Vector, double* Mean, double* Dev, bool StartFrom1); xue@1: void HalfDCT(double* data, int Count, double* CC, int order); xue@1: double Hamming(double f, double T); xue@1: double Hann(double x, double N); xue@1: double HannSq(double x, double N); xue@1: int HxPeak2(double*& hps, double*& vhps, double (*F)(double, void*), double (*dF)(double, void*), double(*ddF)(double, void*), void* params, double st, double en, double epf=1e-6); xue@1: double I0(double x); xue@1: int InsertDec(double value, double* data, int Count); xue@1: int InsertDec(int value, int* data, int Count); xue@1: int InsertDec(double value, int index, double* data, int* indices, int Count); xue@1: int InsertInc(void* value, void** data, int Count, int (*Compare)(void*, void*)); xue@1: int InsertInc(double value, double* data, int Count, bool doinsert=true); xue@1: int InsertInc(double value, int index, double* data, int* indices, int Count); xue@1: int InsertInc(double value, double index, double* data, double* indices, int Count); xue@1: int InsertInc(double value, int* data, int Count, bool doinsert=true); xue@1: int InsertIncApp(double value, double* data, int Count); xue@1: double InstantFreq(int k, int hwid, cdouble* x, int mode=1); xue@1: void InstantFreq(double* freqspec, int hwid, cdouble* x, int mode=1); xue@1: void IntToDouble(double* out, void* in, int BytesPerSample, int Count); xue@1: double IPHannC(double f, cdouble* x, int N, int K1, int K2); xue@1: double IPHannC(double f, void* params); xue@1: double IPHannCP(double f, void* params); xue@1: void lse(double* x, double* y, int Count, double& a, double& b); xue@1: void memdoubleadd(double* dest, double* source, int count); xue@1: void MFCC(int FrameWidth, int NumBands, int Ceps_Order, double* Data, double* Bands, double* C, double* Amps, cdouble* W, cdouble* X); xue@1: double* MFCCPrepareBands(int NumberOfBands, int SamplesPerSec, int NumberOfBins); xue@1: void Multi(double* data, int count, double mul); xue@1: void Multi(double* out, double* in, int count, double mul); xue@1: void MultiAdd(double* out, double* in, double* adder, int count, double mul); xue@1: int NearestPeak(double* data, int count, int anindex); xue@1: double NegativeExp(double* x, double* y, int Count, double& lmd, int sample=1, double step=0.05, double eps=1e-6, int maxiter=50); xue@1: double NL(double* data, int Count, int Wid); xue@1: double Normalize(double* data, int Count, double Maxi=1); xue@1: double Normalize2(double* data, int Count, double Norm=1); xue@1: double nextdouble(double x, double dir); xue@1: double PhaseSpan(double* data, int Count, void*); xue@1: void PolyFit(int P, double* a, int N, double* x, double* y); xue@1: void Pow(double* data, int Count, double ex); xue@1: //int prevcand(candid** cands, int p, int n, int ap); xue@1: int Rectify(double* data, int Count, double th=0); xue@1: double Res(double in, double mod); xue@1: double Romberg(int n, double(*f)(double, void*), double a, double b, void* params=0); xue@1: double Romberg(double(*f)(double, void*), double a, double b, void* params=0, int maxiter=50, double ep=1e-6); xue@1: double sinca(double x); xue@1: double sincd_unn(double x, int N); xue@1: double SmoothPhase(double* Arg, int Count, int mpi=2); xue@1: //int SortCandid(candid cand, candid* cands, int newN); xue@1: double StiffB(double f0, double fm, int m); xue@1: double StiffFm(double f0, int m, double B); xue@1: double StiffF0(double fm, int m, double B); xue@1: double StiffM(double f0, double fm, double B); xue@1: void TFFilter(double* data, double* dataout, int Count, int Wid, TTFSpans* Spans, bool Pass, WindowType wt, double windp, int Sps, int TOffst=0); xue@1: void TFFilter(void* data, void* dataout, int BytesPerSample, int Count, int Wid, TTFSpans* Spans, bool Pass, WindowType wt, double windp, int Sps, int TOffst); xue@1: void TFMask(double* data, double* dataout, int Count, int Wid, TTFSpans* Spans, double masklevel, WindowType wt, double windp, int Sps, int TOffst); xue@1: void TFMask(void* data, void* dataout, int BytesPerSec, int Count, int Wid, TTFSpans* Spans, double masklevel, WindowType wt, double windp, int Sps, int TOffst); xue@1: xue@1: #endif