comparison hs.cpp @ 5:5f3c32dc6e17

* Adjust comment syntax to permit Doxygen to generate HTML documentation; add Doxyfile
author Chris Cannam
date Wed, 06 Oct 2010 15:19:49 +0100
parents fc19d45615d1
children 9b1c0825cc77
comparison
equal deleted inserted replaced
4:92ee28024c05 5:5f3c32dc6e17
10 #include "xcomplex.h" 10 #include "xcomplex.h"
11 #ifdef I 11 #ifdef I
12 #undef I 12 #undef I
13 #endif 13 #endif
14 14
15 /** \file hs.h */
16
15 //--------------------------------------------------------------------------- 17 //---------------------------------------------------------------------------
16 //stiffcandid methods 18 //stiffcandid methods
17 19
18 /* 20 /**
19 method stiffcandid::stiffcandid: creates a harmonic atom with minimal info, i.e. fundamantal frequency 21 method stiffcandid::stiffcandid: creates a harmonic atom with minimal info, i.e. fundamantal frequency
20 between 0 and Nyqvist frequency, stiffness coefficient between 0 and STIFF_B_MAX. 22 between 0 and Nyqvist frequency, stiffness coefficient between 0 and STIFF_B_MAX.
21 23
22 In: Wid: DFT size (frame size, frequency resolution) 24 In: Wid: DFT size (frame size, frequency resolution)
23 */ 25 */
34 s=0; 36 s=0;
35 p=NULL; 37 p=NULL;
36 f=NULL; 38 f=NULL;
37 }//stiffcandid 39 }//stiffcandid
38 40
39 /* 41 /**
40 method stiffcandid::stiffcandid: creates a harmonic atom with a frequency range for the $ap-th partial, 42 method stiffcandid::stiffcandid: creates a harmonic atom with a frequency range for the $ap-th partial,
41 without actually taking this partial as "known". 43 without actually taking this partial as "known".
42 44
43 In; Wid: DFT size 45 In; Wid: DFT size
44 ap: partial index 46 ap: partial index
64 //apply constraints F+kG-g2<0 and -F-kG+g1<0 66 //apply constraints F+kG-g2<0 and -F-kG+g1<0
65 cutcvpoly(N, F, G, 1, k, -g2); 67 cutcvpoly(N, F, G, 1, k, -g2);
66 cutcvpoly(N, F, G, -1, -k, g1); 68 cutcvpoly(N, F, G, -1, -k, g1);
67 }//stiffcandid 69 }//stiffcandid
68 70
69 /* 71 /**
70 method stiffcandid::stiffcandid: creates a harmonic atom from one atom. 72 method stiffcandid::stiffcandid: creates a harmonic atom from one atom.
71 73
72 In; Wid: DFT size 74 In; Wid: DFT size
73 ap: partial index of the atom. 75 ap: partial index of the atom.
74 af, errf: centre and half-width of the frequency range of the atom, in bins. 76 af, errf: centre and half-width of the frequency range of the atom, in bins.
575 577
576 578
577 //--------------------------------------------------------------------------- 579 //---------------------------------------------------------------------------
578 //functions 580 //functions
579 581
580 /* 582 /**
581 function areaandcentroid: calculates the area and centroid of a convex polygon. 583 function areaandcentroid: calculates the area and centroid of a convex polygon.
582 584
583 In: x[N], y[N]: x- and y-coordinates of vertices of a polygon 585 In: x[N], y[N]: x- and y-coordinates of vertices of a polygon
584 Out: A: area 586 Out: A: area
585 (cx, cy): coordinate of the centroid 587 (cx, cy): coordinate of the centroid
605 A/=2; 607 A/=2;
606 cx=cx/6/A; 608 cx=cx/6/A;
607 cy=cy/6/A; 609 cy=cy/6/A;
608 }//areaandcentroid 610 }//areaandcentroid
609 611
610 /* 612 /**
611 function AtomsToPartials: sort a list of atoms as a number of partials. It is assumed that the atoms 613 function AtomsToPartials: sort a list of atoms as a number of partials. It is assumed that the atoms
612 are simply those from a harmonic sinusoid in arbitrary order with uniform timing and partial index 614 are simply those from a harmonic sinusoid in arbitrary order with uniform timing and partial index
613 clearly marked, so that it is easy to sort them into a list of partials. However, the sorting process 615 clearly marked, so that it is easy to sort them into a list of partials. However, the sorting process
614 does not check for harmonicity, missing or duplicate atoms, uniformity of timing, etc. 616 does not check for harmonicity, missing or duplicate atoms, uniformity of timing, etc.
615 617
651 else M=0, Fr=0; 653 else M=0, Fr=0;
652 } 654 }
653 else M=0, Fr=0; 655 else M=0, Fr=0;
654 }//AtomsToPartials 656 }//AtomsToPartials
655 657
656 /* 658 /**
657 function conta: a continuity measure between two set of amplitudes 659 function conta: a continuity measure between two set of amplitudes
658 660
659 In: a1[N], a2[N]: the amplitudes 661 In: a1[N], a2[N]: the amplitudes
660 662
661 Return the continuity measure, between 0 and 1 663 Return the continuity measure, between 0 and 1
672 e22+=la2*la2; 674 e22+=la2*la2;
673 } 675 }
674 return 2*e12/(e11+e22); 676 return 2*e12/(e11+e22);
675 }//conta 677 }//conta
676 678
677 /* 679 /**
678 function cutcvpoly: severs a polygon by a straight line 680 function cutcvpoly: severs a polygon by a straight line
679 681
680 In: x[N], y[N]: x- and y-coordinates of vertices of a polygon, starting from the leftmost (x[0]= 682 In: x[N], y[N]: x- and y-coordinates of vertices of a polygon, starting from the leftmost (x[0]=
681 min x[n]) point clockwise; in case of two leftmost points, x[0] is the upper one and x[N-1] is 683 min x[n]) point clockwise; in case of two leftmost points, x[0] is the upper one and x[N-1] is
682 the lower one. 684 the lower one.
821 //apply constraints F+kG-g2<0 and -F-kG+g1<0 823 //apply constraints F+kG-g2<0 and -F-kG+g1<0
822 cutcvpoly(R->N, R->X, R->Y, 1, k, -g2, protect); // update R 824 cutcvpoly(R->N, R->X, R->Y, 1, k, -g2, protect); // update R
823 cutcvpoly(R->N, R->X, R->Y, -1, -k, g1, protect); // 825 cutcvpoly(R->N, R->X, R->Y, -1, -k, g1, protect); //
824 }//CutR 826 }//CutR
825 827
826 /* 828 /**
827 function DeleteByHalf: reduces a list of stiffcandid objects by half, retaining those with higher s 829 function DeleteByHalf: reduces a list of stiffcandid objects by half, retaining those with higher s
828 and delete the others, freeing their memory. 830 and delete the others, freeing their memory.
829 831
830 In: cands[pcs]: the list of stiffcandid objects 832 In: cands[pcs]: the list of stiffcandid objects
831 Out: cands[return value]: the list of retained ones 833 Out: cands[return value]: the list of retained ones
845 else delete cands[j]; 847 else delete cands[j];
846 } 848 }
847 return k; 849 return k;
848 }//DeleteByHalf 850 }//DeleteByHalf
849 851
850 /* 852 /**
851 function DeleteByHalf: reduces a list of TTempAtom objects by half, retaining those with higher s and 853 function DeleteByHalf: reduces a list of TTempAtom objects by half, retaining those with higher s and
852 delete the others, freeing their memory. 854 delete the others, freeing their memory.
853 855
854 In: cands[pcs]: the list of TTempAtom objects 856 In: cands[pcs]: the list of TTempAtom objects
855 Out: cands[return value]: the list of retained ones 857 Out: cands[return value]: the list of retained ones
870 } 872 }
871 delete[] tmp; 873 delete[] tmp;
872 return k; 874 return k;
873 }//DeleteByHalf 875 }//DeleteByHalf
874 876
875 /* 877 /**
876 function ds0: atom score 0 - energy 878 function ds0: atom score 0 - energy
877 879
878 In: a: atom amplitude 880 In: a: atom amplitude
879 881
880 Returns a^2, or s[0]+a^2 is s is not NULL, as atom score. 882 Returns a^2, or s[0]+a^2 is s is not NULL, as atom score.
883 { 885 {
884 if (s) return *(double*)s+a*a; 886 if (s) return *(double*)s+a*a;
885 else return a*a; 887 else return a*a;
886 }//ds0 888 }//ds0
887 889
888 /* 890 /**
889 function ds2: atom score 1 - cross-correlation coefficient with another HA, e.g. from previous frame 891 function ds2: atom score 1 - cross-correlation coefficient with another HA, e.g. from previous frame
890 892
891 In: a: atom amplitude 893 In: a: atom amplitude
892 params: pointer to dsprams1 structure supplying other inputs. 894 params: pointer to dsprams1 structure supplying other inputs.
893 Out: cross-correlation coefficient as atom score. 895 Out: cross-correlation coefficient as atom score.
900 double hs=lparams->lastene+lparams->currentacce, hsaa=hs+a*a; 902 double hs=lparams->lastene+lparams->currentacce, hsaa=hs+a*a;
901 if (lparams->p<=lparams->lastP) return (lparams->s*hs+a*lparams->lastvfp[lparams->p-1])/hsaa; 903 if (lparams->p<=lparams->lastP) return (lparams->s*hs+a*lparams->lastvfp[lparams->p-1])/hsaa;
902 else return (lparams->s*hs+a*a)/hsaa; 904 else return (lparams->s*hs+a*a)/hsaa;
903 }//ds1 905 }//ds1
904 906
905 /* 907 /**
906 function ExBStiff: finds the minimal and maximal values of stiffness coefficient B given a F-G polygon 908 function ExBStiff: finds the minimal and maximal values of stiffness coefficient B given a F-G polygon
907 909
908 In: F[N], G[N]: vertices of a F-G polygon 910 In: F[N], G[N]: vertices of a F-G polygon
909 Out: Bmin, Bmax: minimal and maximal values of the stiffness coefficient 911 Out: Bmin, Bmax: minimal and maximal values of the stiffness coefficient
910 912
920 if (Bmin>vi) Bmin=vi; 922 if (Bmin>vi) Bmin=vi;
921 else if (Bmax<vi) Bmax=vi; 923 else if (Bmax<vi) Bmax=vi;
922 } 924 }
923 }//ExBStiff 925 }//ExBStiff
924 926
925 /* 927 /**
926 function ExFmStiff: finds the minimal and maximal frequecies of partial m given a F-G polygon 928 function ExFmStiff: finds the minimal and maximal frequecies of partial m given a F-G polygon
927 929
928 In: F[N], G[N]: vertices of a F-G polygon 930 In: F[N], G[N]: vertices of a F-G polygon
929 m: partial index, fundamental=1 931 m: partial index, fundamental=1
930 Out: Fmin, Fmax: minimal and maximal frequencies of partial m 932 Out: Fmin, Fmax: minimal and maximal frequencies of partial m
944 } 946 }
945 testnn(vmin); Fmin=m*sqrt(vmin); 947 testnn(vmin); Fmin=m*sqrt(vmin);
946 testnn(vmax); Fmax=m*sqrt(vmax); 948 testnn(vmax); Fmax=m*sqrt(vmax);
947 }//ExFmStiff 949 }//ExFmStiff
948 950
949 /* 951 /**
950 function ExtendR: extends a F-G polygon on the f axis (to allow a larger pitch range) 952 function ExtendR: extends a F-G polygon on the f axis (to allow a larger pitch range)
951 953
952 In: R: the F-G polygon 954 In: R: the F-G polygon
953 delp1: amount of extension to the low end, in semitones 955 delp1: amount of extension to the low end, in semitones
954 delpe: amount of extension to the high end, in semitones 956 delpe: amount of extension to the high end, in semitones
1092 memcpy(&G[1], &G[n], sizeof(double)*(N-n)); 1094 memcpy(&G[1], &G[n], sizeof(double)*(N-n));
1093 } 1095 }
1094 } 1096 }
1095 }//ExtendR 1097 }//ExtendR
1096 1098
1097 /* 1099 /**
1098 function FGFrom2: solves the following equation system given m[2], f[2], norm[2]. This is interpreted 1100 function FGFrom2: solves the following equation system given m[2], f[2], norm[2]. This is interpreted
1099 as searching from (F0, G0) down direction (dF, dG) until the first equation is satisfied, where 1101 as searching from (F0, G0) down direction (dF, dG) until the first equation is satisfied, where
1100 k[*]=m[*]^2-1. 1102 k[*]=m[*]^2-1.
1101 1103
1102 m[0](F+k[0]G)^0.5-f[0] m[1](F+k[1]G)^0.5-f[1] 1104 m[0](F+k[0]G)^0.5-f[0] m[1](F+k[1]G)^0.5-f[1]
1177 return roots; 1179 return roots;
1178 } 1180 }
1179 } 1181 }
1180 }//FGFrom2 1182 }//FGFrom2
1181 1183
1182 /* 1184 /**
1183 function FGFrom2: solves the following equation system given m[2], f[2], k[2]. This is interpreted as 1185 function FGFrom2: solves the following equation system given m[2], f[2], k[2]. This is interpreted as
1184 searching from (F0, G0) down direction (dF, dG) until the first equation is satisfied. Functionally 1186 searching from (F0, G0) down direction (dF, dG) until the first equation is satisfied. Functionally
1185 this is the same as the version using norm[2], with m[] anf f[] normalized by norm[] beforehand so 1187 this is the same as the version using norm[2], with m[] anf f[] normalized by norm[] beforehand so
1186 that norm[] is no longer needed. However, k[2] cannot be computed from normalized m[2] so that it must 1188 that norm[] is no longer needed. However, k[2] cannot be computed from normalized m[2] so that it must
1187 be specified explicitly. 1189 be specified explicitly.
1268 return roots; 1270 return roots;
1269 } 1271 }
1270 } 1272 }
1271 }//FGFrom2 1273 }//FGFrom2
1272 1274
1273 /* 1275 /**
1274 function FGFrom3: solves the following equation system given m[3], f[3], norm[3]. 1276 function FGFrom3: solves the following equation system given m[3], f[3], norm[3].
1275 1277
1276 m[0](F+k[0]G)^0.5-f[0] m[1](F+k[1]G)^0.5-f[1] m[2](F+k[2]G)^0.5-f[2] 1278 m[0](F+k[0]G)^0.5-f[0] m[1](F+k[1]G)^0.5-f[1] m[2](F+k[2]G)^0.5-f[2]
1277 ------------------------ = ------------------------ = ------------------------ > 0 1279 ------------------------ = ------------------------ = ------------------------ > 0
1278 norm[0] norm[1] norm[2] 1280 norm[0] norm[1] norm[2]
1356 return roots; 1358 return roots;
1357 } 1359 }
1358 } 1360 }
1359 }//FGFrom3 1361 }//FGFrom3
1360 1362
1361 /* 1363 /**
1362 function FGFrom3: solves the following equation system given m[3], f[3], k[3]. Functionally this is 1364 function FGFrom3: solves the following equation system given m[3], f[3], k[3]. Functionally this is
1363 the same as the version using norm[3], with m[] anf f[] normalized by norm[] beforehand so that norm[] 1365 the same as the version using norm[3], with m[] anf f[] normalized by norm[] beforehand so that norm[]
1364 is no longer needed. However, k[3] cannot be computed from normalized m[3] so that it must be 1366 is no longer needed. However, k[3] cannot be computed from normalized m[3] so that it must be
1365 specified explicitly. 1367 specified explicitly.
1366 1368
1464 return roots; 1466 return roots;
1465 } 1467 }
1466 } 1468 }
1467 }//FGFrom3 1469 }//FGFrom3
1468 1470
1469 /* 1471 /**
1470 function FindNote: harmonic sinusoid tracking from a starting point in time-frequency plane forward 1472 function FindNote: harmonic sinusoid tracking from a starting point in time-frequency plane forward
1471 and backward. 1473 and backward.
1472 1474
1473 In: _t, _f: start time and frequency 1475 In: _t, _f: start time and frequency
1474 frst, fren: tracking range, in frames 1476 frst, fren: tracking range, in frames
1519 // ReEst1(M, frst, fren, partials, WV->Data16[channel], wid, offst); 1521 // ReEst1(M, frst, fren, partials, WV->Data16[channel], wid, offst);
1520 1522
1521 return 0; 1523 return 0;
1522 }//Findnote*/ 1524 }//Findnote*/
1523 1525
1524 /* 1526 /**
1525 function FindNoteConst: constant-pitch harmonic sinusoid tracking 1527 function FindNoteConst: constant-pitch harmonic sinusoid tracking
1526 1528
1527 In: _t, _f: start time and frequency 1529 In: _t, _f: start time and frequency
1528 frst, fren: tracking range, in frames 1530 frst, fren: tracking range, in frames
1529 Spec: spectrogram 1531 Spec: spectrogram
1656 delete R; delete[] x; delete[] as; DeAlloc2(xx); 1658 delete R; delete[] x; delete[] as; DeAlloc2(xx);
1657 delete[] starts; 1659 delete[] starts;
1658 return 1; 1660 return 1;
1659 }//FindNoteConst 1661 }//FindNoteConst
1660 1662
1661 /* 1663 /**
1662 function FindNoteF: forward harmonic sinusoid tracking starting from a given harmonic atom until an 1664 function FindNoteF: forward harmonic sinusoid tracking starting from a given harmonic atom until an
1663 endpoint is detected or a search boundary is reached. 1665 endpoint is detected or a search boundary is reached.
1664 1666
1665 In: starts: harmonic atom score of the start HA 1667 In: starts: harmonic atom score of the start HA
1666 startvfp[startp]: amplitudes of partials of start HA 1668 startvfp[startp]: amplitudes of partials of start HA
1703 } 1705 }
1704 delete RR; delete[] lastvfp; delete[] x; delete[] fpp; 1706 delete RR; delete[] lastvfp; delete[] x; delete[] fpp;
1705 return k; 1707 return k;
1706 }//FindNoteF 1708 }//FindNoteF
1707 1709
1708 /* 1710 /**
1709 function FindNoteFB: forward-backward harmonic sinusid tracking. 1711 function FindNoteFB: forward-backward harmonic sinusid tracking.
1710 1712
1711 In: frst, fren: index of start and end frames 1713 In: frst, fren: index of start and end frames
1712 Rst, Ren: F-G polygons of start and end harmonic atoms 1714 Rst, Ren: F-G polygons of start and end harmonic atoms
1713 vfpst[M], vfpen[M]: amplitude vectors of start and end harmonic atoms 1715 vfpst[M], vfpen[M]: amplitude vectors of start and end harmonic atoms
1856 DeAlloc2(pitches); DeAlloc2(prev); 1858 DeAlloc2(pitches); DeAlloc2(prev);
1857 delete[] pitchres; delete[] pc; 1859 delete[] pitchres; delete[] pc;
1858 return result; //*/ 1860 return result; //*/
1859 }//FindNoteFB 1861 }//FindNoteFB
1860 1862
1861 /* 1863 /**
1862 function GetResultsSingleFr: used by NoteMatchStiff3 to obtain final note match results after harmonic 1864 function GetResultsSingleFr: used by NoteMatchStiff3 to obtain final note match results after harmonic
1863 grouping of peaks with rough frequency estimates, including a screening of found peaks based on shape 1865 grouping of peaks with rough frequency estimates, including a screening of found peaks based on shape
1864 and consistency with other peak frequencies, reestimating sinusoid parameters using LSE, estimating 1866 and consistency with other peak frequencies, reestimating sinusoid parameters using LSE, estimating
1865 atoms without peaks by inferring their frequencies, and translating internal peak type to atom type. 1867 atoms without peaks by inferring their frequencies, and translating internal peak type to atom type.
1866 1868
1972 delete[] f1; delete[] values; delete[] indices; 1974 delete[] f1; delete[] values; delete[] indices;
1973 } 1975 }
1974 return result; 1976 return result;
1975 }//GetResultsSingleFr 1977 }//GetResultsSingleFr
1976 1978
1977 /* 1979 /**
1978 function GetResultsMultiFr: the constant-pitch multi-frame version of GetResultsSingleFr. 1980 function GetResultsMultiFr: the constant-pitch multi-frame version of GetResultsSingleFr.
1979 1981
1980 In: x[Fr][N]: spectrogram 1982 In: x[Fr][N]: spectrogram
1981 ps[P], fs[P]; partial indices and frequencies, may miss partials 1983 ps[P], fs[P]; partial indices and frequencies, may miss partials
1982 psb[P]: peak type flags, related to atom::ptype. 1984 psb[P]: peak type flags, related to atom::ptype.
2091 } 2093 }
2092 delete[] pclass; 2094 delete[] pclass;
2093 return result; 2095 return result;
2094 }//GetResultsMultiFr 2096 }//GetResultsMultiFr
2095 2097
2096 /* 2098 /**
2097 function InitailizeR: initializes a F-G polygon with a fundamental frequency range and stiffness coefficient bound 2099 function InitailizeR: initializes a F-G polygon with a fundamental frequency range and stiffness coefficient bound
2098 2100
2099 In: af, ef: centre and half width of the fundamental frequency range 2101 In: af, ef: centre and half width of the fundamental frequency range
2100 maxB: maximal value of stiffness coefficient (the minimal is set to 0) 2102 maxB: maximal value of stiffness coefficient (the minimal is set to 0)
2101 Out: R: the initialized F-G polygon. 2103 Out: R: the initialized F-G polygon.
2111 g1=g1*g1, g2=g2*g2; 2113 g1=g1*g1, g2=g2*g2;
2112 X[0]=X[3]=g1, X[1]=X[2]=g2; 2114 X[0]=X[3]=g1, X[1]=X[2]=g2;
2113 Y[0]=X[0]*maxB, Y[1]=X[1]*maxB, Y[2]=Y[3]=0; 2115 Y[0]=X[0]*maxB, Y[1]=X[1]*maxB, Y[2]=Y[3]=0;
2114 }//InitializeR 2116 }//InitializeR
2115 2117
2116 /* 2118 /**
2117 function InitialzeR: initializes a F-G polygon with a frequency range for a given partial and 2119 function InitialzeR: initializes a F-G polygon with a frequency range for a given partial and
2118 stiffness coefficient bound 2120 stiffness coefficient bound
2119 2121
2120 In: apind: partial index 2122 In: apind: partial index
2121 af, ef: centre and half width of the frequency range of the apind-th partial 2123 af, ef: centre and half width of the frequency range of the apind-th partial
2135 double kb1=1+k*maxB; 2137 double kb1=1+k*maxB;
2136 X[0]=g1/kb1, X[1]=g2/kb1, X[2]=g2, X[3]=g1; 2138 X[0]=g1/kb1, X[1]=g2/kb1, X[2]=g2, X[3]=g1;
2137 Y[0]=X[0]*maxB, Y[1]=X[1]*maxB, Y[2]=Y[3]=0; 2139 Y[0]=X[0]*maxB, Y[1]=X[1]*maxB, Y[2]=Y[3]=0;
2138 }//InitializeR 2140 }//InitializeR
2139 2141
2140 /* 2142 /**
2141 function maximalminimum: finds the point within a polygon that maximizes its minimal distance to the 2143 function maximalminimum: finds the point within a polygon that maximizes its minimal distance to the
2142 sides. 2144 sides.
2143 2145
2144 In: sx[N], sy[N]: x- and y-coordinates of vertices of a polygon 2146 In: sx[N], sy[N]: x- and y-coordinates of vertices of a polygon
2145 Out: (x, y): point within the polygon with maximal minimal distance to the sides 2147 Out: (x, y): point within the polygon with maximal minimal distance to the sides
2244 2246
2245 delete[] A; 2247 delete[] A;
2246 return dm; 2248 return dm;
2247 }//maximalminimum 2249 }//maximalminimum
2248 2250
2249 /* 2251 /**
2250 function minimaxstiff: finds the point in polygon (N; F, G) that minimizes the maximal value of the 2252 function minimaxstiff: finds the point in polygon (N; F, G) that minimizes the maximal value of the
2251 function 2253 function
2252 2254
2253 | m[l]sqrt(F+(m[l]^2-1)*G)-f[l] | 2255 | m[l]sqrt(F+(m[l]^2-1)*G)-f[l] |
2254 e_l = | ----------------------------- | regarding l=0, ..., L-1 2256 e_l = | ----------------------------- | regarding l=0, ..., L-1
3368 delete[] vmnl; 3370 delete[] vmnl;
3369 3371
3370 return vmax; 3372 return vmax;
3371 }//minimaxstiff*/ 3373 }//minimaxstiff*/
3372 3374
3373 /* 3375 /**
3374 function NMResultToAtoms: converts the note-match result hosted in a NMResults structure, i.e. 3376 function NMResultToAtoms: converts the note-match result hosted in a NMResults structure, i.e.
3375 parameters of a harmonic atom, to a list of atoms. The process retrieves atom parameters from low 3377 parameters of a harmonic atom, to a list of atoms. The process retrieves atom parameters from low
3376 partials until a required number of atoms have been retrieved or a non-positive frequency is 3378 partials until a required number of atoms have been retrieved or a non-positive frequency is
3377 encountered (non-positive frequencies are returned by note-match to indicate high partials for which 3379 encountered (non-positive frequencies are returned by note-match to indicate high partials for which
3378 no informative estimates can be obtained). 3380 no informative estimates can be obtained).
3396 HP[i].p=pfpp[i]; HP[i].type=ptype[i]; HP[i].pin=i+1; 3398 HP[i].p=pfpp[i]; HP[i].type=ptype[i]; HP[i].pin=i+1;
3397 } 3399 }
3398 return M; 3400 return M;
3399 }//NMResultToAtoms 3401 }//NMResultToAtoms
3400 3402
3401 /* 3403 /**
3402 function NMResultToPartials: reads atoms of a harmonic atom in a NMResult structure into HS partials. 3404 function NMResultToPartials: reads atoms of a harmonic atom in a NMResult structure into HS partials.
3403 3405
3404 In: results: the NMResults structure hosting the harmonic atom 3406 In: results: the NMResults structure hosting the harmonic atom
3405 M: number of atoms to request from &results 3407 M: number of atoms to request from &results
3406 fr: frame index of this harmonic atom 3408 fr: frame index of this harmonic atom
3422 part->p=pfpp[i]; part->type=ptype[i]; part->pin=i+1; 3424 part->p=pfpp[i]; part->type=ptype[i]; part->pin=i+1;
3423 } 3425 }
3424 return M; 3426 return M;
3425 }//NMResultToPartials 3427 }//NMResultToPartials
3426 3428
3427 /* 3429 /**
3428 function NoteMatchStiff3: finds harmonic atom from spectrum if Fr=1, or constant-pitch harmonic 3430 function NoteMatchStiff3: finds harmonic atom from spectrum if Fr=1, or constant-pitch harmonic
3429 sinusoid from spectrogram if Fr>1. 3431 sinusoid from spectrogram if Fr>1.
3430 3432
3431 In: x[Fr][N/2+1]: spectrogram 3433 In: x[Fr][N/2+1]: spectrogram
3432 fps[pc], vps[pc]: primitive (rough) peak frequencies and amplitudes 3434 fps[pc], vps[pc]: primitive (rough) peak frequencies and amplitudes
3693 delete[] psb; 3695 delete[] psb;
3694 3696
3695 return result; 3697 return result;
3696 }//NoteMatchStiff3 3698 }//NoteMatchStiff3
3697 3699
3698 /* 3700 /**
3699 function NoteMatchStiff3: finds harmonic atom from spectrum if Fr=1, or constant-pitch harmonic 3701 function NoteMatchStiff3: finds harmonic atom from spectrum if Fr=1, or constant-pitch harmonic
3700 sinusoid from spectrogram if Fr>1. This version uses residue-sinusoid ratio ("rsr") that measures how 3702 sinusoid from spectrogram if Fr>1. This version uses residue-sinusoid ratio ("rsr") that measures how
3701 "good" a spectral peak is in terms of its shape. peaks with large rsr[] is likely to be contaminated 3703 "good" a spectral peak is in terms of its shape. peaks with large rsr[] is likely to be contaminated
3702 and their frequency estimates are regarded unreliable. 3704 and their frequency estimates are regarded unreliable.
3703 3705
4010 delete[] psb; 4012 delete[] psb;
4011 4013
4012 return result; 4014 return result;
4013 }//NoteMatchStiff3 4015 }//NoteMatchStiff3
4014 4016
4015 /* 4017 /**
4016 function NoteMatchStiff3: wrapper function of the above that does peak picking and HA grouping (or 4018 function NoteMatchStiff3: wrapper function of the above that does peak picking and HA grouping (or
4017 constant-pitch HS finding) in a single call. 4019 constant-pitch HS finding) in a single call.
4018 4020
4019 In: x[Fr][N/2+1]: spectrogram 4021 In: x[Fr][N/2+1]: spectrogram
4020 N, offst: atom scale and hop size 4022 N, offst: atom scale and hop size
4045 double result=NoteMatchStiff3(R, f0, B, pc, fps, vps, rsr, Fr, x, N, offst, settings, results, lastp, lastvfp, computes, forceinputlocalfr?startfr:-1); 4047 double result=NoteMatchStiff3(R, f0, B, pc, fps, vps, rsr, Fr, x, N, offst, settings, results, lastp, lastvfp, computes, forceinputlocalfr?startfr:-1);
4046 free8(fps); 4048 free8(fps);
4047 return result; 4049 return result;
4048 }//NoteMatchStiff3 4050 }//NoteMatchStiff3
4049 4051
4050 /* 4052 /**
4051 function NoteMatchStiff3: finds harmonic atom from spectrum given the pitch as a (partial index, 4053 function NoteMatchStiff3: finds harmonic atom from spectrum given the pitch as a (partial index,
4052 frequency) pair. This is used internally by NoteMatch3FB(). 4054 frequency) pair. This is used internally by NoteMatch3FB().
4053 4055
4054 In: x[N/2+1]: spectrum 4056 In: x[N/2+1]: spectrum
4055 fps[pc], vps[pc]: primitive (rough) peak frequencies and amplitudes 4057 fps[pc], vps[pc]: primitive (rough) peak frequencies and amplitudes
4183 double result=0; 4185 double result=0;
4184 if (f0>0) for (int i=0; i<numsam; i++) result+=vfp[i]*vfp[i]; 4186 if (f0>0) for (int i=0; i<numsam; i++) result+=vfp[i]*vfp[i];
4185 return result; 4187 return result;
4186 }//NoteMatchStiff3*/ 4188 }//NoteMatchStiff3*/
4187 4189
4188 /* 4190 /**
4189 function NoteMatchStiff3FB: does one dynamic programming step in forward-background pitch tracking of 4191 function NoteMatchStiff3FB: does one dynamic programming step in forward-background pitch tracking of
4190 harmonic sinusoids. This is used internally by FindNoteFB(). 4192 harmonic sinusoids. This is used internally by FindNoteFB().
4191 4193
4192 In: R[pitchcount]: initial F-G polygons associated with pitch candidates at last frame 4194 In: R[pitchcount]: initial F-G polygons associated with pitch candidates at last frame
4193 vfp[pitchcount][maxp]: amplitude vectors associated with pitch candidates at last frame 4195 vfp[pitchcount][maxp]: amplitude vectors associated with pitch candidates at last frame
4292 DeAlloc2(vfp); vfp=newvfp; 4294 DeAlloc2(vfp); vfp=newvfp;
4293 delete[] sc; sc=newsc; 4295 delete[] sc; sc=newsc;
4294 pitchcount=newpc; 4296 pitchcount=newpc;
4295 }//NoteMatchStiff3FB 4297 }//NoteMatchStiff3FB
4296 4298
4297 /* 4299 /**
4298 function PeakShapeC: residue-sinusoid-ratio for a given (hypothesis) sinusoid frequency 4300 function PeakShapeC: residue-sinusoid-ratio for a given (hypothesis) sinusoid frequency
4299 4301
4300 In: x[Fr][N/2+1]: spectrogram 4302 In: x[Fr][N/2+1]: spectrogram
4301 M, c[], iH2: cosine-family window specifiers 4303 M, c[], iH2: cosine-family window specifiers
4302 f: reference frequency, in bins 4304 f: reference frequency, in bins
4334 delete[] w; 4336 delete[] w;
4335 if (xx.x==0) return 1; 4337 if (xx.x==0) return 1;
4336 return 1-xw2/(xx.x*ww.x); 4338 return 1-xw2/(xx.x*ww.x);
4337 }//PeakShapeC 4339 }//PeakShapeC
4338 4340
4339 /* 4341 /**
4340 function QuickPeaks: finds rough peaks in the spectrum (peak picking) 4342 function QuickPeaks: finds rough peaks in the spectrum (peak picking)
4341 4343
4342 In: x[N/2+1]: spectrum 4344 In: x[N/2+1]: spectrum
4343 M, c[], iH2: cosine-family window function specifiers 4345 M, c[], iH2: cosine-family window function specifiers
4344 mina: minimal amplitude to spot a spectral peak 4346 mina: minimal amplitude to spot a spectral peak
4388 } 4390 }
4389 delete[] w; 4391 delete[] w;
4390 return p; 4392 return p;
4391 }//QuickPeaks 4393 }//QuickPeaks
4392 4394
4393 /* 4395 /**
4394 function QuickPeaks: finds rough peaks in the spectrogram (peak picking) for constant-frequency 4396 function QuickPeaks: finds rough peaks in the spectrogram (peak picking) for constant-frequency
4395 sinusoids 4397 sinusoids
4396 4398
4397 In: x[Fr][N/2+1]: spectrogram 4399 In: x[Fr][N/2+1]: spectrogram
4398 fr0, r0: centre and half width of interval (in frames) to use for peak picking 4400 fr0, r0: centre and half width of interval (in frames) to use for peak picking
4514 delete[] frc; 4516 delete[] frc;
4515 DeAlloc2(frs); 4517 DeAlloc2(frs);
4516 return pc; 4518 return pc;
4517 }//QuickPeaks 4519 }//QuickPeaks
4518 4520
4519 /* 4521 /**
4520 function ReEstHS1: reestimates a harmonic sinusoid by one multiplicative reestimation using phasor 4522 function ReEstHS1: reestimates a harmonic sinusoid by one multiplicative reestimation using phasor
4521 multiplier 4523 multiplier
4522 4524
4523 In: partials[M][Fr]: HS partials 4525 In: partials[M][Fr]: HS partials
4524 [frst, fren): frame (measurement point) range on which to do reestimation 4526 [frst, fren): frame (measurement point) range on which to do reestimation
4540 for (int fr=0; fr<Fr; fr++) partials[m][fr].f=fs[fr], partials[m][fr].a=as[fr], partials[m][fr].p=phs[fr]; 4542 for (int fr=0; fr<Fr; fr++) partials[m][fr].f=fs[fr], partials[m][fr].a=as[fr], partials[m][fr].p=phs[fr];
4541 } 4543 }
4542 delete[] fs; 4544 delete[] fs;
4543 }//ReEstHS1 4545 }//ReEstHS1
4544 4546
4545 /* 4547 /**
4546 function ReEstHS1: wrapper function. 4548 function ReEstHS1: wrapper function.
4547 4549
4548 In: HS: a harmonic sinusoid 4550 In: HS: a harmonic sinusoid
4549 Data16: its waveform data 4551 Data16: its waveform data
4550 Out: HS: updated harmonic sinusoid 4552 Out: HS: updated harmonic sinusoid
4554 void ReEstHS1(THS* HS, __int16* Data16) 4556 void ReEstHS1(THS* HS, __int16* Data16)
4555 { 4557 {
4556 ReEstHS1(HS->M, HS->Fr, 0, HS->Fr, HS->Partials, Data16); 4558 ReEstHS1(HS->M, HS->Fr, 0, HS->Fr, HS->Partials, Data16);
4557 }//ReEstHS1 4559 }//ReEstHS1
4558 4560
4559 /* 4561 /**
4560 function SortCandid: inserts a candid object into a listed of candid objects sorted first by f, then 4562 function SortCandid: inserts a candid object into a listed of candid objects sorted first by f, then
4561 (for identical f's) by df. 4563 (for identical f's) by df.
4562 4564
4563 In: cand: the candid object to insert to the list 4565 In: cand: the candid object to insert to the list
4564 cands[newN]: the sorted list of candid objects 4566 cands[newN]: the sorted list of candid objects
4575 memmove(&cands[lnN+1], &cands[lnN], sizeof(candid)*(newN-lnN)); 4577 memmove(&cands[lnN+1], &cands[lnN], sizeof(candid)*(newN-lnN));
4576 cands[lnN]=cand; 4578 cands[lnN]=cand;
4577 return lnN; 4579 return lnN;
4578 }//SortCandid 4580 }//SortCandid
4579 4581
4580 /* 4582 /**
4581 function SynthesisHS: synthesizes a harmonic sinusoid without aligning the phases 4583 function SynthesisHS: synthesizes a harmonic sinusoid without aligning the phases
4582 4584
4583 In: partials[M][Fr]: HS partials 4585 In: partials[M][Fr]: HS partials
4584 terminatetag: external termination flag. Function SynthesisHS() polls *terminatetag and exits with 4586 terminatetag: external termination flag. Function SynthesisHS() polls *terminatetag and exits with
4585 0 when it is set. 4587 0 when it is set.
4631 } 4633 }
4632 free8(as); 4634 free8(as);
4633 return xrec; 4635 return xrec;
4634 }//SynthesisHS 4636 }//SynthesisHS
4635 4637
4636 /* 4638 /**
4637 function SynthesisHS: synthesizes a perfectly harmonic sinusoid without aligning the phases. 4639 function SynthesisHS: synthesizes a perfectly harmonic sinusoid without aligning the phases.
4638 Frequencies of partials above the fundamental are not used in this synthesis process. 4640 Frequencies of partials above the fundamental are not used in this synthesis process.
4639 4641
4640 In: partials[M][Fr]: HS partials 4642 In: partials[M][Fr]: HS partials
4641 terminatetag: external termination flag. This function polls *terminatetag and exits with 0 when 4643 terminatetag: external termination flag. This function polls *terminatetag and exits with 0 when
4697 } 4699 }
4698 free8(as); free8(ph); free8(a0[0]); delete[] a0; 4700 free8(as); free8(ph); free8(a0[0]); delete[] a0;
4699 return xrec; 4701 return xrec;
4700 }//SynthesisHS2 4702 }//SynthesisHS2
4701 4703
4702 /* 4704 /**
4703 function SynthesisHSp: synthesizes a harmonic sinusoid with phase alignment 4705 function SynthesisHSp: synthesizes a harmonic sinusoid with phase alignment
4704 4706
4705 In: partials[pm][pfr]: HS partials 4707 In: partials[pm][pfr]: HS partials
4706 startamp[pm][st_count]: onset amplifiers, optional 4708 startamp[pm][st_count]: onset amplifiers, optional
4707 st_start, st_offst: start of and interval between onset amplifying points, optional 4709 st_start, st_offst: start of and interval between onset amplifying points, optional
4780 4782
4781 delete[] a1; 4783 delete[] a1;
4782 return xrec; 4784 return xrec;
4783 }//SynthesisHSp 4785 }//SynthesisHSp
4784 4786
4785 /* 4787 /**
4786 function SynthesisHSp: wrapper function. 4788 function SynthesisHSp: wrapper function.
4787 4789
4788 In: HS: a harmonic sinusoid. 4790 In: HS: a harmonic sinusoid.
4789 Out: [dst, den): time interval synthesized 4791 Out: [dst, den): time interval synthesized
4790 xrec[den-dst]: resynthesized harmonic sinusoid 4792 xrec[den-dst]: resynthesized harmonic sinusoid