Mercurial > hg > x
diff hs.h @ 1:6422640a802f
first upload
author | Wen X <xue.wen@elec.qmul.ac.uk> |
---|---|
date | Tue, 05 Oct 2010 10:45:57 +0100 |
parents | |
children | fc19d45615d1 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hs.h Tue Oct 05 10:45:57 2010 +0100 @@ -0,0 +1,273 @@ +#ifndef hsH +#define hsH + +/* + hs.cpp - harmonic sinusoid model + + Further reading: Wen X. and M. Sandler, "Sinusoid modeling in a harmonic context," in Proc. DAFx'07, Bordeaux, 2007. +*/ + +//--------------------------------------------------------------------------- +#include <mem.h> +#include "arrayalloc.h" +#include "align8.h" +#include "fft.h" +#include "QuickSpec.h" +#include "TStream.h" + +#define ATOM_LOCALANCHOR 1 +#define HS_CONSTF 1 +#define MAX_CAND 64 +#define STIFF_B_MAX 0.01 + +enum atomtype //type flags of an HS atom +{ + atAnchor, //"anchor" is an atom whose validity is taken for granted, e.g. user input + atPeak, //an atom whose frequency is an actual spectral peak + atInfered, //an atom which has no spectral peak and whose frequency is inferred from other atoms + atMuted, //an atom which is being muted + atBuried //an atom which is buried in background noise +}; + +struct atom //an atom of a harmonic sinusoid +{ + double t; //time + double s; //scale + double f; //digital frequency + double a; //amplitude + double p; //phase angle + int pin; //partial index + atomtype type; //atom type + int tags; //additional info on atom type + float r1; +}; + +struct candid //candidate atom +{ + int p; //partial index + double f; //frequency + double df; //delta freqdel folk + double s; //score in partial-sum + int prev; //index of last partial f-df + int type; //0: f0, 1: local maximum, 2: not a maxixum + double ms; +}; + +struct dsparams1 //argument structure for calling ds1() +{ + double s; //score + double lastene; //energy of last frame + double currentacce; //energy of this frame, currently accumulated + int p; //partial index + int lastP; //number of efficient partials in last frame + double* lastvfp; //amplitude estimates of partials at last frame +}; + +struct NMResults //note match output structure +{ + double* fp; //frequencies, in bins + double* vfp; //amplitudes + double* pfp; //phase angles + atomtype* ptype; //atom types +}; + +struct NMSettings //note match algorithm settings +{ + double c[4]; //cosine-family window specifiers + int M; //ditto + double iH2; //ditto + double hB; //spectral truncation half width + int maxp; //maximal number of partials + double maxB; //stiffness coefficient upper bound + double epf; //frequency estimation error tolerance for LSE estimation + double epf0; //input frequency error bound for harmonic grouping + double delm; //frequency error bound for harmonic grouping + double delp; //pitch jump upper bound + double minf0; //minimal fundamental frequency + double maxf0; //maximal fundamental frequency + int pin0; //input partial index + bool forcepin0; //force the peak nearest to input frequency as an atom + bool pin0asanchor; //mark atom found near the input frequency as anchor + int pcount; //number of "pinned" (anchor) partials + int* pin; //partial indices of pinned partials + double* pinf; //frequencies of pinned partials + int* pinfr; //frame indices of pinned partials, used in multi-frame constant-pitch note match +}; + + +/* + stiffcandid is the harmonic atom class used internally by harmonic grouping and tracking routines. Literally + it means "candidate harmonic atoms on a stiff string model". The stiff string is the main harmonic model used + by me for describing frequency relations between partials of a harmonic sound. + + stiffcandid is superceded by TTempAtom class. +*/ + +class stiffcandid +{ +public: + int P; //number of partial estimates located + int* p; //partial indices of located partials, sizeof(int)*P + double* f; //frequencies of located partials, sizeof(double)*P + double s; //score in partial-sum + //{N; F, G}: the feasible polygonal area of (F, G) given the P partials, where F=F0*F0, G=F0*B + int N; + double* F; //sizeof(double)*N + double* G; //sizeof(double)*N + + stiffcandid(int Wid); //create empty with minimal info + stiffcandid(int Wid, int ap, double af, double errf); //create empty with pitch range + stiffcandid(int Wid, int ap, double af, double errf, double ds); //create with 1 atom + stiffcandid(stiffcandid* prev, int ap, double af, double errf, double ds); //create by updating with new atom + ~stiffcandid(); +}; + + +/* + THS is the data structure hosting a harmonic sinusoid representation. Its key members include the number + of partials, number of frames, and all its atoms (sinusoid parameters of all partials at measurement points). +*/ + +class THS +{ +public: + int Channel; //channel id: THS describes a harmonic sinusoid in single channel + int M; //number of partials + int Fr; //number of frames + atom** Partials; //atoms, [M][Fr] + + int* BufM[128]; //a buffer for algorithmic use + + int isconstf; //constant frequencies flag + + double** startamp;//onset amplifiers, optional + int st_start; //position of the first onset amplifying point + int st_offst; //interval of onset amplifying points + int st_count; //number of onset amplifying points + + //constructors and destructor + THS(); + THS(int aM, int aFr); + THS(THS* HS); + THS(THS* HS, double start, double end); + ~THS(); + + int StartPos(); //start position + int EndPos(); //end position + int EndPosEx(); //extended end position + int StdOffst(); //hop size + + void ClearBufM(); //free buffers registered in BufM[] + void Resize(int aM, int aFr, bool copydata=false, bool forcealloc=false); //change size (M or Fr) + + //I/O routines + int WriteHdrToStream(TStream* Stream); + int ReadHdrFromStream(TStream* Stream); + int WriteAtomToStream(TStream* Stream, atom* atm); + int ReadAtomFromStream(TStream* Stream, atom* atm); + int WriteToStream(TStream* Stream); + int ReadFromStream(TStream* Stream); +}; + + +/* + TPolygon is a polygon class. This class itself does not enforce convexness. However, when used for solving + the stiff string model, all polygons are convex, as they are the results of current a first convex polygon + by straight lines. + + For the convenience of computation, the sequence of vertices are arranged so that they come in clockwise + order starting from the leftmost (smallest x coordinate) vertex; in case two vertices are both leftmost + the upper (larger y coordinate) one is placed at the start and the lower one is placed at the end. +*/ + +class TPolygon +{ +public: + int N; //number of vertices (equals number of edges) + double* X; //x-coordinates of vertices + double* Y; //y-coordinates of vertices + TPolygon(int cap); + TPolygon(int cap, TPolygon* R); + ~TPolygon(); +}; + + +/* + TTempAtom is an atom class within the stiff-stirng harmonic atom context used internally by harmonic + grouping and tracking routines. Literally it means "a temporary atom", and truly it hosts most info + one expects of a potential atom. TTempAtom replaces stiffcandid class in harmonic sinusoid group and + tracking algorithms, due to the advanges that it carries atom information (frequency, amplitude, etc.) + as well as harmonic atom information (link to other atom, the F-G polygon), and is therefore both an + individual atom and a harmonic atom containing all atoms tracked down through the linked list Prev. +*/ + +class TTempAtom +{ +public: + int pind; //partial index + double f; //frequency + double a; //amplitude + double s; //scale + double rsr; //residue-sinusoid ratio + TTempAtom* Prev; //previous atom + TPolygon *R; //F-G polygon for harmonic group + union {double acce; int tag[2];}; + + TTempAtom(double af, double ef, double maxB); //create empty with frequency range + TTempAtom(int apin, double af, double ef, double maxB); //create empty with frequency range + TTempAtom(TPolygon* AR, double delf1, double delf2, double minf); //create empty with extended R + TTempAtom(int apind, double af, double ef, double aa, double as, double maxB); //create with one partial + TTempAtom(TTempAtom* APrev, bool DupR); //create duplicate + TTempAtom(TTempAtom* APrev, int apind, double af, double ef, double aa, double as, bool updateR=true); //duplicate and add one partial + ~TTempAtom(); +}; + +//--internal function-------------------------------------------------------- +double ds0(double, void*); //a score function, internal use only + +//--general polygon routines------------------------------------------------- +void areaandcentroid(double& A, double& cx, double& cy, int N, double* x, double* y); //compute area and centroid +void cutcvpoly(int& N, double* x, double* y, double A, double B, double C, bool protect=false); //sever polygon by line +double maximalminimum(double& x, double& y, int N, double* sx, double* sy); //maximum inscribed circle + +//--F-G polygon routines----------------------------------------------------- +void CutR(TPolygon* R, int apind, double af, double ef, bool protect=false); +void ExBStiff(double& Bmin, double& Bmax, int N, double* F, double* G); +void ExFmStiff(double& Fmin, double& Fmax, int m, int N, double* F, double* G); +void ExtendR(TPolygon* R, double delf1, double delf2, double minf); +void InitializeR(TPolygon* R, double af, double ef, double maxB); +void InitializeR(TPolygon* R, int apind, double af, double ef, double maxB); + +//--internal structure conversion routines----------------------------------- +int NMResultToAtoms(int M, atom* HP, int t, int wid, NMResults results); +int NMResultToPartials(int M, int fr, atom** Partials, int t, int wid, NMResults results); + +//--batch sinusoid estimation routines--------------------------------------- +double PeakShapeC(double f, int Fr, int N, cdouble** x, int B, int M, double* c, double iH2); +double PeakShapeC(double f, int Fr, int N, cfloat** x, int B, int M, double* c, double iH2); +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); +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); + +//--harmonic atom detection (harmonic grouping) routines--------------------- +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 +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 +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 +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 + +//--harmonic sinusoid tracking routines-------------------------------------- +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) +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 +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 +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 +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() + +//--harmonic sinusoid synthesis routines------------------------------------- +double* SynthesisHS(int pm, int pfr, atom** partials, int& dst, int& den, bool* terminatetag=0); +double* SynthesisHS2(int M, int Fr, atom** partials, int& dst, int& den, bool* terminatetag=0); +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); +double* SynthesisHSp(THS* HS, int& dst, int& den); + +//--other functions---------------------------------------------------------- +void ReEstHS1(THS* HS, __int16* Data16); //reestimation of HS + +#endif