xue@11
|
1 /*
|
xue@11
|
2 Harmonic sinusoidal modelling and tools
|
xue@11
|
3
|
xue@11
|
4 C++ code package for harmonic sinusoidal modelling and relevant signal processing.
|
xue@11
|
5 Centre for Digital Music, Queen Mary, University of London.
|
xue@11
|
6 This file copyright 2011 Wen Xue.
|
xue@11
|
7
|
xue@11
|
8 This program is free software; you can redistribute it and/or
|
xue@11
|
9 modify it under the terms of the GNU General Public License as
|
xue@11
|
10 published by the Free Software Foundation; either version 2 of the
|
xue@11
|
11 License, or (at your option) any later version.
|
xue@11
|
12 */
|
xue@1
|
13 #ifndef proceduresH
|
xue@1
|
14 #define proceduresH
|
xue@1
|
15
|
Chris@5
|
16 /**
|
Chris@5
|
17 \file procedures.h - this file collects miscellaneous structures and functions. Not all of these are
|
xue@1
|
18 referenced somewhere else.
|
xue@1
|
19 */
|
xue@1
|
20
|
xue@1
|
21
|
xue@1
|
22 //---------------------------------------------------------------------------
|
xue@1
|
23 #include <memory.h>
|
xue@1
|
24 #include <stdlib.h>
|
xue@1
|
25 #include <values.h>
|
xue@1
|
26 #include "fft.h"
|
xue@1
|
27 #include "windowfunctions.h"
|
xue@1
|
28
|
Chris@5
|
29 /**
|
xue@1
|
30 macro testnn: non-negative test. This macro throws out an exception if the value of x is negative.
|
xue@1
|
31 */
|
xue@1
|
32 #ifndef testnn
|
xue@1
|
33 #define testnn(x) {try{if (x<0) throw("testnn");}catch(...){x=0;}}
|
xue@1
|
34 #endif
|
xue@1
|
35
|
xue@1
|
36 /*
|
xue@1
|
37 macro AllocateGMM and ReleaseGMM: allocates and frees buffers that hosts descriptors of a Gaussian-
|
xue@1
|
38 mixture model.
|
xue@1
|
39 */
|
xue@1
|
40 #define AllocateGMM(_MIXS, _DIM, _P, _M, _DEV) \
|
xue@1
|
41 double* _P=new double[_MIXS]; double** _M=new double*[_MIXS]; double ** _DEV=new double*[_MIXS]; \
|
xue@1
|
42 _M[0]=new double[(_MIXS)*(_DIM)]; _DEV[0]=new double[(_MIXS)*(_DIM)]; \
|
xue@1
|
43 for (int _MIX=1; _MIX<_MIXS; _MIX++) _M[_MIX]=&_M[0][_MIX*(_DIM)], _DEV[_MIX]=&_DEV[0][_MIX*(_DIM)];
|
xue@1
|
44 #define ReleaseGMM(_P, _M, _DEV) \
|
xue@1
|
45 delete[] _P; if (_M) {delete[] _M[0]; delete[] _M;} if (_DEV) {delete[] _DEV[0]; delete[] _DEV;}
|
xue@1
|
46
|
xue@1
|
47
|
xue@1
|
48 //---------------------------------------------------------------------------
|
Chris@5
|
49 /**
|
xue@1
|
50 Tick count tool (stop watch) is made up of a TickClock struct and three macros that uses this
|
xue@1
|
51 structure as augument.
|
xue@1
|
52
|
xue@1
|
53 Use of TickClock: declare the instance directly. Use StartClock() and StopClock() to start and stop
|
xue@1
|
54 tick counting. Each time the clock is stopped the interval between last start and stop operations is
|
xue@1
|
55 added to run-time t. Clear the recorded run-time with ResetClock().
|
xue@1
|
56 */
|
xue@1
|
57 struct TickClock //tick counter struct
|
xue@1
|
58 {
|
xue@1
|
59 double t; //accumulated run time
|
xue@1
|
60 __int64 Ticks; //tick count recorded at start trigger
|
xue@1
|
61 __int64 Ticks2; //tick count recorded at stop trigger
|
xue@1
|
62 };
|
xue@1
|
63 #define ResetClock(AClock) {AClock.t=0;}
|
xue@1
|
64 #define StartClock(AClock) {AClock.Ticks=GetTickCount();}
|
xue@1
|
65 #define StopClock(AClock) {AClock.Ticks2=GetTickCount(); AClock.t+=0.001*(AClock.Ticks2-AClock.Ticks);}
|
xue@1
|
66
|
xue@1
|
67 //---------------------------------------------------------------------------
|
xue@1
|
68
|
xue@1
|
69 struct fftparams //buffers used by FFT routines
|
xue@1
|
70 {
|
xue@1
|
71 double* Amp; //amplitude output buffer
|
xue@1
|
72 double* Arg; //phase angle output buffer
|
xue@1
|
73 cdouble* w; //twiddle factor buffer
|
xue@1
|
74 cdouble* x; //data buffer
|
xue@1
|
75 };
|
xue@1
|
76
|
xue@1
|
77 struct TGMM //Gaussian mixture model
|
xue@1
|
78 {
|
xue@1
|
79 public:
|
xue@1
|
80 bool mcs;
|
xue@1
|
81 int mixs; //number of mixtures
|
xue@1
|
82 int dim; //data dimension
|
xue@1
|
83 double* p; //mixture weights
|
xue@1
|
84 double** m; //mixture component centres
|
xue@1
|
85 double** dev; //diagonal mixture component correlation
|
xue@1
|
86 double acct;
|
xue@1
|
87 TGMM();
|
xue@1
|
88 ~TGMM();
|
xue@1
|
89 };
|
xue@1
|
90
|
xue@1
|
91 struct TTFSpan //a rectanguar area in the T-F plane
|
xue@1
|
92 {
|
xue@1
|
93 int T1; //start time
|
xue@1
|
94 int T2; //finish time
|
xue@1
|
95 double F1; //lowest frequency
|
xue@1
|
96 double F2; //highest frequency
|
xue@1
|
97 };
|
xue@1
|
98
|
xue@1
|
99 struct TSpecPeak //spectral peak
|
xue@1
|
100 {
|
xue@1
|
101 int t; //time in samples
|
xue@1
|
102 int tres; //time resolution
|
xue@1
|
103 double f; //digital frequency
|
xue@1
|
104 double fres; //frequency resolution
|
xue@1
|
105 double df; //derivative of f
|
xue@1
|
106 double am; //amplitude
|
xue@1
|
107 double ph; //phase angle
|
xue@1
|
108 };
|
xue@1
|
109
|
Chris@5
|
110 /**
|
xue@1
|
111 TSpecTrack is a class that maintains a list of TSpecPeak objects that form a spectral track. It models
|
xue@1
|
112 a sinusid track in sinusoid modeling.
|
xue@1
|
113 */
|
xue@1
|
114 class TSpecTrack
|
xue@1
|
115 {
|
xue@1
|
116 private:
|
xue@1
|
117 int Capacity; //number of peaks the current storage space is allocated to host
|
xue@1
|
118 public:
|
xue@1
|
119 int t1; //time of first peak
|
xue@1
|
120 int t2; //time of last peak
|
xue@1
|
121 double fmin; //minimum peak frequency
|
xue@1
|
122 double fmax; //maximum peak frequency
|
xue@1
|
123
|
xue@1
|
124 int Count; //number of peaks in the track
|
xue@1
|
125 TSpecPeak* Peaks; //peaks in the track, ordered by time
|
xue@1
|
126
|
xue@1
|
127 TSpecTrack(int ACapacity=50);
|
xue@1
|
128 ~TSpecTrack();
|
xue@1
|
129
|
xue@1
|
130 void InsertPeak(TSpecPeak& APeak, int index);
|
xue@1
|
131 int LocatePeak(TSpecPeak& APeak);
|
xue@1
|
132 int Add(TSpecPeak& APeak);
|
xue@1
|
133 };
|
xue@1
|
134
|
Chris@5
|
135 /**
|
xue@1
|
136 TTFSpans is a class that maintains a list of TFSpans. This is used to mark selected areas in the time-
|
xue@1
|
137 frequency plane for further processing.
|
xue@1
|
138 */
|
xue@1
|
139 class TTFSpans
|
xue@1
|
140 {
|
xue@1
|
141 public:
|
xue@1
|
142 int Count; //number of spans
|
xue@1
|
143 int Capacity; //number of spans the current storage space is allocated to host
|
xue@1
|
144 TTFSpan* Items; //the hosted spans
|
xue@1
|
145
|
xue@1
|
146 TTFSpans();
|
xue@1
|
147 ~TTFSpans();
|
xue@1
|
148 void Add(TTFSpan& ATFSpan);
|
xue@1
|
149 void Clear();
|
xue@1
|
150 int Delete(int Index);
|
xue@1
|
151 };
|
xue@1
|
152
|
xue@1
|
153 double ACPower(double* data, int Count, void*);
|
xue@1
|
154 void Add(double* dest, double* source, int Count);
|
xue@1
|
155 void Add(double* out, double* addend, double* adder, int count);
|
xue@1
|
156 void ApplyWindow(double* OutBuffer, double* Buffer, double* Weights, int Size);
|
xue@1
|
157 double Avg(double*, int, void*);
|
xue@1
|
158 void AvgFilter(double* dataout, double* data, int Count, int HWid);
|
xue@1
|
159 int BitInv(int value, int order);
|
xue@1
|
160 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
|
161 void Conv(double* out, int N1, double* in1, int N2, double* in2);
|
xue@1
|
162 void DCT( double* output, double* input, int N);
|
xue@1
|
163 void IDCT( double* output, double* input, int N);
|
xue@1
|
164 double DCAmplitude(double*, int, void*);
|
xue@1
|
165 double DCPower(double*, int, void*);
|
xue@1
|
166 double ddIPHann(double, void*);
|
xue@1
|
167 void DeDC(double* data, int Count, int HWid);
|
xue@1
|
168 void DeDC_static(double* data, int Count);
|
xue@1
|
169 void DoubleToInt(void* out, int BytesPerSample, double* in, int Count);
|
xue@1
|
170 void DoubleToIntAdd(void* out, int BytesPerSample, double* in, int Count);
|
xue@1
|
171 double DPower(double* data, int Count, void*);
|
xue@1
|
172 double Energy(double* data, int Count);
|
xue@1
|
173 double ExpOnsetFilter(double* dataout, double* data, int Count, double Tr, double Ta);
|
xue@1
|
174 double ExpOnsetFilter_balanced(double* dataout, double* data, int Count, double Tr, double Ta, int bal=5);
|
xue@1
|
175 double ExtractLinearComponent(double* dataout, double* data, int Count);
|
xue@1
|
176 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
|
177 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
|
178 void FFTConv(double* dest, double* source1, int size1, double* source2, int size2, double* pre_buffer=NULL);
|
xue@1
|
179 void FFTFilter(double* dataout, double* data, int Count, int Wid, int On, int Off);
|
xue@1
|
180 void FFTFilterOLA(double* dataout, double* data, int Count, int Wid, int On, int Off, double* pre_buffer=NULL);
|
xue@1
|
181 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
|
182 void FFTFilterOLA(double* dataout, double* data, int Count, double* amp, double* ph, int Wid, double* pre_buffer=NULL);
|
xue@1
|
183 double FFTMask(double* dataout, double* data, int Count, int Wid, double DigiOn, double DigiOff, double maskcoef=1);
|
xue@1
|
184 int FindInc(double value, double* data, int Count);
|
xue@1
|
185 double Gaussian(int Dim, double* Vector, double* Mean, double* Dev, bool StartFrom1);
|
xue@1
|
186 void HalfDCT(double* data, int Count, double* CC, int order);
|
xue@1
|
187 double Hamming(double f, double T);
|
xue@1
|
188 double Hann(double x, double N);
|
xue@1
|
189 double HannSq(double x, double N);
|
xue@1
|
190 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
|
191 double I0(double x);
|
xue@1
|
192 int InsertDec(double value, double* data, int Count);
|
xue@1
|
193 int InsertDec(int value, int* data, int Count);
|
xue@1
|
194 int InsertDec(double value, int index, double* data, int* indices, int Count);
|
xue@1
|
195 int InsertInc(void* value, void** data, int Count, int (*Compare)(void*, void*));
|
xue@1
|
196 int InsertInc(double value, double* data, int Count, bool doinsert=true);
|
xue@1
|
197 int InsertInc(double value, int index, double* data, int* indices, int Count);
|
xue@1
|
198 int InsertInc(double value, double index, double* data, double* indices, int Count);
|
xue@1
|
199 int InsertInc(double value, int* data, int Count, bool doinsert=true);
|
xue@1
|
200 int InsertIncApp(double value, double* data, int Count);
|
xue@1
|
201 double InstantFreq(int k, int hwid, cdouble* x, int mode=1);
|
xue@1
|
202 void InstantFreq(double* freqspec, int hwid, cdouble* x, int mode=1);
|
xue@1
|
203 void IntToDouble(double* out, void* in, int BytesPerSample, int Count);
|
xue@1
|
204 double IPHannC(double f, cdouble* x, int N, int K1, int K2);
|
xue@1
|
205 double IPHannC(double f, void* params);
|
xue@1
|
206 double IPHannCP(double f, void* params);
|
xue@1
|
207 void lse(double* x, double* y, int Count, double& a, double& b);
|
xue@1
|
208 void memdoubleadd(double* dest, double* source, int count);
|
xue@1
|
209 void MFCC(int FrameWidth, int NumBands, int Ceps_Order, double* Data, double* Bands, double* C, double* Amps, cdouble* W, cdouble* X);
|
xue@1
|
210 double* MFCCPrepareBands(int NumberOfBands, int SamplesPerSec, int NumberOfBins);
|
xue@1
|
211 void Multi(double* data, int count, double mul);
|
xue@1
|
212 void Multi(double* out, double* in, int count, double mul);
|
xue@1
|
213 void MultiAdd(double* out, double* in, double* adder, int count, double mul);
|
xue@1
|
214 int NearestPeak(double* data, int count, int anindex);
|
xue@1
|
215 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
|
216 double NL(double* data, int Count, int Wid);
|
xue@1
|
217 double Normalize(double* data, int Count, double Maxi=1);
|
xue@1
|
218 double Normalize2(double* data, int Count, double Norm=1);
|
xue@1
|
219 double nextdouble(double x, double dir);
|
xue@1
|
220 double PhaseSpan(double* data, int Count, void*);
|
xue@1
|
221 void PolyFit(int P, double* a, int N, double* x, double* y);
|
xue@1
|
222 void Pow(double* data, int Count, double ex);
|
xue@1
|
223 //int prevcand(candid** cands, int p, int n, int ap);
|
xue@1
|
224 int Rectify(double* data, int Count, double th=0);
|
xue@1
|
225 double Res(double in, double mod);
|
xue@1
|
226 double Romberg(int n, double(*f)(double, void*), double a, double b, void* params=0);
|
xue@1
|
227 double Romberg(double(*f)(double, void*), double a, double b, void* params=0, int maxiter=50, double ep=1e-6);
|
xue@1
|
228 double sinca(double x);
|
xue@1
|
229 double sincd_unn(double x, int N);
|
xue@1
|
230 double SmoothPhase(double* Arg, int Count, int mpi=2);
|
xue@1
|
231 //int SortCandid(candid cand, candid* cands, int newN);
|
xue@1
|
232 double StiffB(double f0, double fm, int m);
|
xue@1
|
233 double StiffFm(double f0, int m, double B);
|
xue@1
|
234 double StiffF0(double fm, int m, double B);
|
xue@1
|
235 double StiffM(double f0, double fm, double B);
|
xue@1
|
236 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
|
237 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
|
238 void TFMask(double* data, double* dataout, int Count, int Wid, TTFSpans* Spans, double masklevel, WindowType wt, double windp, int Sps, int TOffst);
|
xue@1
|
239 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
|
240
|
xue@1
|
241 #endif
|