hs.h
Go to the documentation of this file.
1 /*
2  Harmonic sinusoidal modelling and tools
3 
4  C++ code package for harmonic sinusoidal modelling and relevant signal processing.
5  Centre for Digital Music, Queen Mary, University of London.
6  This file copyright 2011 Wen Xue.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2 of the
11  License, or (at your option) any later version.
12 */
13 #ifndef hsH
14 #define hsH
15 
22 //---------------------------------------------------------------------------
23 #include <string.h>
24 #include "arrayalloc.h"
25 #include "align8.h"
26 #include "fft.h"
27 #include "quickspec.h"
28 
29 #ifndef __BORLANDC__
30 #include "tstream.h"
31 #else
32 #include <Classes.hpp>
33 #endif
34 
35 #define ATOM_LOCALANCHOR 1
36 #define HS_CONSTF 1
37 #define MAX_CAND 64
38 #define STIFF_B_MAX 0.01
39 
40 enum atomtype //type flags of an HS atom
41 {
42  atAnchor, //"anchor" is an atom whose validity is taken for granted, e.g. user input
43  atPeak, //an atom whose frequency is an actual spectral peak
44  atInfered, //an atom which has no spectral peak and whose frequency is inferred from other atoms
45  atMuted, //an atom which is being muted
46  atBuried //an atom which is buried in background noise
47 };
48 
49 struct atom //an atom of a harmonic sinusoid
50 {
51  double t; //time
52  double s; //scale
53  double f; //digital frequency
54  double a; //amplitude
55  double p; //phase angle
56  int pin; //partial index
57  atomtype type; //atom type
58  int tags; //additional info on atom type
59  float r1;
60 };
61 
62 struct candid //candidate atom
63 {
64  int p; //partial index
65  double f; //frequency
66  double df; //delta freqdel folk
67  double s; //score in partial-sum
68  int prev; //index of last partial f-df
69  int type; //0: f0, 1: local maximum, 2: not a maxixum
70  double ms;
71 };
72 
73 struct dsparams1 //argument structure for calling ds1()
74 {
75  double s; //score
76  double lastene; //energy of last frame
77  double currentacce; //energy of this frame, currently accumulated
78  int p; //partial index
79  int lastP; //number of efficient partials in last frame
80  double* lastvfp; //amplitude estimates of partials at last frame
81 };
82 
83 struct NMResults //note match output structure
84 {
85  double* fp; //frequencies, in bins
86  double* vfp; //amplitudes
87  double* pfp; //phase angles
88  atomtype* ptype; //atom types
89 };
90 
91 struct NMSettings //note match algorithm settings
92 {
93  double c[4]; //cosine-family window specifiers
94  int M; //ditto
95  double iH2; //ditto
96  double hB; //spectral truncation half width
97  int maxp; //maximal number of partials
98  double maxB; //stiffness coefficient upper bound
99  double epf; //frequency estimation error tolerance for LSE estimation
100  double epf0; //input frequency error bound for harmonic grouping
101  double delm; //frequency error bound for harmonic grouping
102  double delp; //pitch jump upper bound
103  double minf0; //minimal fundamental frequency
104  double maxf0; //maximal fundamental frequency
105  int pin0; //input partial index
106  bool forcepin0; //force the peak nearest to input frequency as an atom
107  bool pin0asanchor; //mark atom found near the input frequency as anchor
108  int pcount; //number of "pinned" (anchor) partials
109  int* pin; //partial indices of pinned partials
110  double* pinf; //frequencies of pinned partials
111  int* pinfr; //frame indices of pinned partials, used in multi-frame constant-pitch note match
112 };
113 
114 
124 {
125 public:
126  int P; //number of partial estimates located
127  int* p; //partial indices of located partials, sizeof(int)*P
128  double* f; //frequencies of located partials, sizeof(double)*P
129  double s; //score in partial-sum
130  //{N; F, G}: the feasible polygonal area of (F, G) given the P partials, where F=F0*F0, G=F0*B
131  int N;
132  double* F; //sizeof(double)*N
133  double* G; //sizeof(double)*N
134 
135  stiffcandid(int Wid); //create empty with minimal info
136  stiffcandid(int Wid, int ap, double af, double errf); //create empty with pitch range
137  stiffcandid(int Wid, int ap, double af, double errf, double ds); //create with 1 atom
138  stiffcandid(stiffcandid* prev, int ap, double af, double errf, double ds); //create by updating with new atom
139  ~stiffcandid();
140 };
141 
142 
147 class THS
148 {
149 public:
150  int Channel; //channel id: THS describes a harmonic sinusoid in single channel
151  int M; //number of partials
152  int Fr; //number of frames
153  atom** Partials; //atoms, [M][Fr]
154 
155  int* BufM[128]; //a buffer for algorithmic use
156 
157  int isconstf; //constant frequencies flag
158 
159  double** startamp;//onset amplifiers, optional
160  int st_start; //position of the first onset amplifying point
161  int st_offst; //interval of onset amplifying points
162  int st_count; //number of onset amplifying points
163 
164  //constructors and destructor
165  THS();
166  THS(int aM, int aFr);
167  THS(THS* HS);
168  THS(THS* HS, double start, double end);
169  ~THS();
170 
171  int StartPos(); //start position
172  int EndPos(); //end position
173  int EndPosEx(); //extended end position
174  int StdOffst(); //hop size
175 
176  void ClearBufM(); //free buffers registered in BufM[]
177  void Resize(int aM, int aFr, bool copydata=false, bool forcealloc=false); //change size (M or Fr)
178 
179  //I/O routines
180  int WriteHdrToStream(TStream* Stream);
181  int ReadHdrFromStream(TStream* Stream);
182  int WriteAtomToStream(TStream* Stream, atom* atm);
183  int ReadAtomFromStream(TStream* Stream, atom* atm);
184  int WriteToStream(TStream* Stream);
185  int ReadFromStream(TStream* Stream);
186 };
187 
188 
199 class TPolygon
200 {
201 public:
202  int N; //number of vertices (equals number of edges)
203  double* X; //x-coordinates of vertices
204  double* Y; //y-coordinates of vertices
205  TPolygon(int cap);
206  TPolygon(int cap, TPolygon* R);
207  ~TPolygon();
208 };
209 
210 
221 {
222 public:
223  int pind; //partial index
224  double f; //frequency
225  double a; //amplitude
226  double s; //scale
227  double rsr; //residue-sinusoid ratio
228  TTempAtom* Prev; //previous atom
229  TPolygon *R; //F-G polygon for harmonic group
230  union {double acce; int tag[2];};
231 
232  TTempAtom(double af, double ef, double maxB); //create empty with frequency range
233  TTempAtom(int apin, double af, double ef, double maxB); //create empty with frequency range
234  TTempAtom(TPolygon* AR, double delf1, double delf2, double minf); //create empty with extended R
235  TTempAtom(int apind, double af, double ef, double aa, double as, double maxB); //create with one partial
236  TTempAtom(TTempAtom* APrev, bool DupR); //create duplicate
237  TTempAtom(TTempAtom* APrev, int apind, double af, double ef, double aa, double as, bool updateR=true); //duplicate and add one partial
238  ~TTempAtom();
239 };
240 
241 //--internal function--------------------------------------------------------
242 double ds0(double, void*); //a score function, internal use only
243 
244 //--general polygon routines-------------------------------------------------
245 void areaandcentroid(double& A, double& cx, double& cy, int N, double* x, double* y); //compute area and centroid
246 void cutcvpoly(int& N, double* x, double* y, double A, double B, double C, bool protect=false); //sever polygon by line
247 double maximalminimum(double& x, double& y, int N, double* sx, double* sy); //maximum inscribed circle
248 
249 //--F-G polygon routines-----------------------------------------------------
250 void CutR(TPolygon* R, int apind, double af, double ef, bool protect=false);
251 void ExBStiff(double& Bmin, double& Bmax, int N, double* F, double* G);
252 void ExFmStiff(double& Fmin, double& Fmax, int m, int N, double* F, double* G);
253 void ExtendR(TPolygon* R, double delf1, double delf2, double minf);
254 void InitializeR(TPolygon* R, double af, double ef, double maxB);
255 void InitializeR(TPolygon* R, int apind, double af, double ef, double maxB);
256 
257 //--internal structure conversion routines-----------------------------------
258 void AtomsToPartials(int k, atom* part, int& M, int& Fr, atom**& partials, int offst);
259 int NMResultToAtoms(int M, atom* HP, int t, int wid, NMResults results);
260 int NMResultToPartials(int M, int fr, atom** Partials, int t, int wid, NMResults results);
261 
262 //--batch sinusoid estimation routines---------------------------------------
263 double PeakShapeC(double f, int Fr, int N, cdouble** x, int B, int M, double* c, double iH2);
264 double PeakShapeC(double f, int Fr, int N, cfloat** x, int B, int M, double* c, double iH2);
265 int QuickPeaks(double* f, double* a, int N, cdouble* x, int M, double* c, double iH2, double mina, int binst=-1, int binen=-1, int B=5, double* rsr=0);
266 int QuickPeaks(double* f, double* a, int Fr, int N, cdouble** x, int fr0, int r0, int M, double* c, double iH2, double mina, int binst=-1, int binen=-1, int B=5, double* rsr=0);
267 
268 //--harmonic atom detection (harmonic grouping) routines---------------------
269 double NoteMatchStiff3(TPolygon* R, double &f0, double& B, int pc, double* fps, double* vps, int Fr, cdouble** x, int N, int offst, NMSettings* settings, NMResults* results, int lastp, double* lastvfp, double (*computes)(double a, void* params)=ds0, int forceinputlocalfr=-1); //basic grouping without rsr
270 double NoteMatchStiff3(TPolygon* R, double &f0, double& B, int pc, double* fps, double* vps, double* rsr, int Fr, cdouble** x, int N, int offst, NMSettings* settings, NMResults* results, int lastp, double* lastvfp, double (*computes)(double a, void* params)=ds0, int forceinputlocalfr=-1); //basic grouping with rsr
271 double NoteMatchStiff3(TPolygon* R, double &f0, double& B, int Fr, cdouble** x, int N, int offst, NMSettings* settings, NMResults* results, int lastp, double* lastvfp, double (*deltas)(double a, void* params)=ds0, bool forceinputlocalfr=false, int startfr=-1, int validfrrange=0); //basic grouping with rsr - wrapper
272 double NoteMatchStiff3(TPolygon* R, int peak0, int pin0, cdouble* x, int pc, double* fps, double* vps, int N, NMSettings* settings, double* vfp, int** pitchind, int newpc); //grouping with given pitch, single-frame
273 
274 //--harmonic sinusoid tracking routines--------------------------------------
275 int FindNote(int _t, double _f, int& M, int& Fr, atom**& partials, int frst, int fren, int wid, int offst, TQuickSpectrogram* Spec, NMSettings settings); //harmonic sinusoid tracking (forward and backward tracking)
276 int FindNoteConst(int _t, double _f, int& M, int& Fr, atom**& partials, int frst, int fren, int wid, int offst, TQuickSpectrogram* Spec, NMSettings settings, double brake); //constant-pitch harmonic sinusoid tracking
277 int FindNoteF(atom* part, double& starts, TPolygon* R, int startp, double* startvfp, int frst, int fren, int wid, int offst, TQuickSpectrogram* Spec, NMSettings settings, double brake); //forward harmonic sinusoid tracking
278 int FindNoteFB(int frst, TPolygon* Rst, double* vfpst, int fren, TPolygon* Ren, double* vfpen, int M, atom** partials, int wid, int offst, TQuickSpectrogram* Spec, NMSettings settings); //forward-backward harmonic sinusoid tracking
279 void NoteMatchStiff3FB(int& pitchcount, TPolygon**& R, double**& vfp, double*& sc, int* newpitches, int* prev, int pc, double* fps, double* vps, cdouble* x, int wid, int maxpitch, NMSettings* settings); //single DP step of FindNoteFB()
280 
281 //--harmonic sinusoid synthesis routines-------------------------------------
282 double* SynthesisHS(int pm, int pfr, atom** partials, int& dst, int& den, bool* terminatetag=0);
283 double* SynthesisHS(THS* HS, int& dst, int& den, bool* terminatetag=0);
284 double* SynthesisHS2(int M, int Fr, atom** partials, int& dst, int& den, bool* terminatetag=0);
285 double* SynthesisHSp(int pm, int pfr, atom** partials, int& dst, int& den, double** startamp=0, int st_start=0, int st_offst=0, int st_count=0);
286 double* SynthesisHSp(THS* HS, int& dst, int& den);
287 
288 //--other functions----------------------------------------------------------
289 void ReEstHS1(THS* HS, __int16* Data16); //reestimation of HS
290 
291 #endif
double * SynthesisHSp(int pm, int pfr, atom **partials, int &dst, int &den, double **startamp=0, int st_start=0, int st_offst=0, int st_count=0)
Definition: hs.cpp:4733
void AtomsToPartials(int k, atom *part, int &M, int &Fr, atom **&partials, int offst)
Definition: hs.cpp:636
Definition: hs.h:49
double maximalminimum(double &x, double &y, int N, double *sx, double *sy)
Definition: hs.cpp:2164
int NMResultToPartials(int M, int fr, atom **Partials, int t, int wid, NMResults results)
Definition: hs.cpp:3427
Definition: hs.h:73
Definition: quickspec.h:110
Definition: hs.h:91
double NoteMatchStiff3(TPolygon *R, double &f0, double &B, int pc, double *fps, double *vps, int Fr, cdouble **x, int N, int offst, NMSettings *settings, NMResults *results, int lastp, double *lastvfp, double(*computes)(double a, void *params)=ds0, int forceinputlocalfr=-1)
Definition: hs.cpp:3459
double ds0(double, void *)
Definition: hs.cpp:896
double * SynthesisHS2(int M, int Fr, atom **partials, int &dst, int &den, bool *terminatetag=0)
Definition: hs.cpp:4669
void ExBStiff(double &Bmin, double &Bmax, int N, double *F, double *G)
Definition: hs.cpp:927
Definition: tstream.h:26
void ExtendR(TPolygon *R, double delf1, double delf2, double minf)
Definition: hs.cpp:974
Definition: hs.h:123
void InitializeR(TPolygon *R, double af, double ef, double maxB)
Definition: hs.cpp:2119
void cutcvpoly(int &N, double *x, double *y, double A, double B, double C, bool protect=false)
Definition: hs.cpp:704
int QuickPeaks(double *f, double *a, int N, cdouble *x, int M, double *c, double iH2, double mina, int binst=-1, int binen=-1, int B=5, double *rsr=0)
Definition: hs.cpp:4366
int FindNoteF(atom *part, double &starts, TPolygon *R, int startp, double *startvfp, int frst, int fren, int wid, int offst, TQuickSpectrogram *Spec, NMSettings settings, double brake)
Definition: hs.cpp:1692
int FindNoteFB(int frst, TPolygon *Rst, double *vfpst, int fren, TPolygon *Ren, double *vfpen, int M, atom **partials, int wid, int offst, TQuickSpectrogram *Spec, NMSettings settings)
Definition: hs.cpp:1736
int FindNoteConst(int _t, double _f, int &M, int &Fr, atom **&partials, int frst, int fren, int wid, int offst, TQuickSpectrogram *Spec, NMSettings settings, double brake)
Definition: hs.cpp:1551
Definition: hs.h:147
void ExFmStiff(double &Fmin, double &Fmax, int m, int N, double *F, double *G)
Definition: hs.cpp:948
Definition: xcomplex.h:26
int NMResultToAtoms(int M, atom *HP, int t, int wid, NMResults results)
Definition: hs.cpp:3402
double PeakShapeC(double f, int Fr, int N, cdouble **x, int B, int M, double *c, double iH2)
Definition: hs.cpp:4321
void NoteMatchStiff3FB(int &pitchcount, TPolygon **&R, double **&vfp, double *&sc, int *newpitches, int *prev, int pc, double *fps, double *vps, cdouble *x, int wid, int maxpitch, NMSettings *settings)
Definition: hs.cpp:4222
void ReEstHS1(THS *HS, __int16 *Data16)
Definition: hs.cpp:4568
int FindNote(int _t, double _f, int &M, int &Fr, atom **&partials, int frst, int fren, int wid, int offst, TQuickSpectrogram *Spec, NMSettings settings)
Definition: hs.cpp:1497
Definition: hs.h:83
void areaandcentroid(double &A, double &cx, double &cy, int N, double *x, double *y)
Definition: hs.cpp:603
Definition: hs.h:62
Definition: hs.h:199
Definition: hs.h:220
double * SynthesisHS(int pm, int pfr, atom **partials, int &dst, int &den, bool *terminatetag=0)
Definition: hs.cpp:4606