Mercurial > hg > x
comparison hsedit.cpp @ 1:6422640a802f
first upload
author | Wen X <xue.wen@elec.qmul.ac.uk> |
---|---|
date | Tue, 05 Oct 2010 10:45:57 +0100 |
parents | |
children | 5f3c32dc6e17 |
comparison
equal
deleted
inserted
replaced
0:9b9f21935f24 | 1:6422640a802f |
---|---|
1 //--------------------------------------------------------------------------- | |
2 | |
3 #include "hsedit.h" | |
4 #include "splines.h" | |
5 | |
6 //--------------------------------------------------------------------------- | |
7 | |
8 /* | |
9 function DeFM: frequency de-modulation | |
10 | |
11 In: peakfr[npfr]: segmentation into FM cycles, peakfr[0]=0, peakfr[npfr-1]=Fr-1 | |
12 a1[Fr], f1[Fr]: sequence of amplitudes and frequencies | |
13 arec[Fr]: amplitude-based weights for frequency averaging | |
14 Out: a2[Fr], f2[Fr]: amplitude and frequency sequance after demodulation | |
15 | |
16 No return value. | |
17 */ | |
18 void DeFM(double* a2, double* f2, double* a1, double* f1, double* arec, int npfr, int* peakfr) | |
19 { | |
20 double *frs=new double[npfr*12], *a=&frs[npfr], *f=&frs[npfr*2], | |
21 *aa=&frs[npfr*3], *ab=&frs[npfr*4], *ac=&frs[npfr*5], *ad=&frs[npfr*6], | |
22 *fa=&frs[npfr*7], *fb=&frs[npfr*8], *fc=&frs[npfr*9], *fd=&frs[npfr*10]; | |
23 a[0]=a1[0], f[0]=f1[0], frs[0]=peakfr[0]; | |
24 for (int i=1; i<npfr-1; i++) | |
25 { | |
26 a[i]=f[i]=frs[i]=0; double lrec=0; | |
27 for (int fr=peakfr[i-1]; fr<peakfr[i+1]; fr++) | |
28 a[i]+=a1[fr]*a1[fr], f[i]+=f1[fr]*arec[fr], frs[i]+=fr*arec[fr], lrec+=arec[fr]; | |
29 a[i]=sqrt(a[i]/(peakfr[i+1]-peakfr[i-1])), f[i]/=lrec, frs[i]/=lrec; | |
30 } | |
31 a[npfr-1]=a1[peakfr[npfr-1]], f[npfr-1]=f1[peakfr[npfr-1]], frs[npfr-1]=peakfr[npfr-1]; | |
32 CubicSpline(npfr-1, aa, ab, ac, ad, frs, a, 1, 1, a2); | |
33 CubicSpline(npfr-1, fa, fb, fc, fd, frs, f, 1, 1, f2); | |
34 delete[] frs; | |
35 }//DeFM | |
36 | |
37 /* | |
38 function DFMSeg: segments HS frames into FM cycles | |
39 | |
40 In: partials[M][Fr]: HS partials | |
41 Out: peakfr[npfr]: segmentation, peakfr[0]=0, peakfr[npfr-1]=Fr-1. | |
42 arec[Fr]: total amplitudes of frames | |
43 | |
44 No return value. | |
45 */ | |
46 void DFMSeg(double* arec, int& npfr, int* peakfr, int M, int Fr, atom** partials) | |
47 { | |
48 double *frec=new double[Fr]; | |
49 memset(arec, 0, sizeof(double)*Fr); memset(frec, 0, sizeof(double)*Fr); | |
50 for (int m=0; m<M; m++) for (int fr=0; fr<Fr; fr++) {double la=partials[m][fr].a; la=la*la; arec[fr]+=la; frec[fr]+=partials[m][fr].f/(m+1)*la;} | |
51 for (int fr=0; fr<Fr; fr++) frec[fr]=frec[fr]/arec[fr]; | |
52 peakfr[0]=0; npfr=1; | |
53 for (int fr=1; fr<Fr-1; fr++) | |
54 { | |
55 if ((frec[fr]<frec[fr-1] && frec[fr]<frec[fr+1]) || (frec[fr]>frec[fr-1] && frec[fr]>frec[fr+1])) | |
56 { | |
57 peakfr[npfr]=fr; | |
58 if (peakfr[npfr]-peakfr[npfr-1]>2) npfr++; | |
59 } | |
60 } | |
61 peakfr[npfr++]=Fr-1; | |
62 delete[] frec; | |
63 }//DFMSeg | |
64 | |
65 /* | |
66 function HSAM: harmonic sinusoid amplitude modulation | |
67 | |
68 In: SrcHS: source harmonic sinusoid | |
69 dep: modulation depth | |
70 fre: modulator frequency | |
71 ph: modulator phase | |
72 Out: HS: destination harmonic sinusoid | |
73 | |
74 No reutrn value. | |
75 */ | |
76 void HSAM(THS* HS, THS* SrcHS, double dep, double fre, double ph) | |
77 { | |
78 double omg=M_PI*2*fre; | |
79 for (int m=0; m<HS->M; m++) | |
80 for (int fr=0; fr<HS->Fr; fr++) | |
81 HS->Partials[m][fr].a=SrcHS->Partials[m][fr].a*(1+dep*cos(omg*SrcHS->Partials[m][fr].t+ph)); | |
82 }//HSAM | |
83 | |
84 /* | |
85 function HSFM: harmonic sinusoid frequency modulation | |
86 | |
87 In: SrcHS: source harmonic sinusoid | |
88 a: modulation extent, in semitones | |
89 fre: modulator frequency | |
90 ph: modulator phase | |
91 Out: HS: destination harmonic sinusoid | |
92 | |
93 No reutrn value. | |
94 */ | |
95 void HSFM(THS* HS, THS* SrcHS, double a, double freq, double ph) | |
96 { | |
97 double omg=M_PI*2*freq, pa=pow(2, a/12.0)-1; | |
98 for (int m=0; m<HS->M; m++) | |
99 for (int fr=0; fr<HS->Fr; fr++) | |
100 HS->Partials[m][fr].f=SrcHS->Partials[m][fr].f*(1+pa*cos(omg*SrcHS->Partials[m][fr].t+ph)); | |
101 }//HSFM | |
102 | |
103 /* | |
104 function HSFM_SF: harmonic sinusoid frequency modulation with source-filter model | |
105 | |
106 In: SrcHS: source harmonic sinusoid | |
107 a: modulation extent, in semitones | |
108 fre: modulator frequency | |
109 ph: modulator phase | |
110 SF: source-filter model | |
111 Out: HS: destination harmonic sinusoid | |
112 | |
113 No reutrn value. | |
114 */ | |
115 void HSFM_SF(THS* HS, THS* SrcHS, double a, double freq, double ph, TSF* SF) | |
116 { | |
117 double omg=M_PI*2*freq, pa=pow(2, a/12.0)-1; | |
118 for (int m=0; m<HS->M; m++) for (int fr=0; fr<HS->Fr; fr++) | |
119 { | |
120 double f0=SrcHS->Partials[m][fr].f; | |
121 double f1=f0*(1+pa*cos(omg*SrcHS->Partials[m][fr].t+ph)); | |
122 HS->Partials[m][fr].f=f1; | |
123 HS->Partials[m][fr].a=SrcHS->Partials[m][fr].a*exp(SF->LogAF(f1)-SF->LogAF(f0)); | |
124 } | |
125 }//HSFM_SF | |
126 | |
127 /* | |
128 function: HSPitchShift: harmonic sinusoid pitch shifting | |
129 | |
130 In: SrcHS: source harmonic sinusoid | |
131 ps12: amount of pitch shift, in semitones | |
132 Out: HS: destination harmonic sinusoid | |
133 | |
134 No return value. | |
135 */ | |
136 void HSPitchShift(THS* HS, THS* SrcHS, double ps12) | |
137 { | |
138 double pa=pow(2, ps12/12.0); | |
139 for (int m=0; m<HS->M; m++) for (int fr=0; fr<HS->Fr; fr++) HS->Partials[m][fr].f=SrcHS->Partials[m][fr].f*pa; | |
140 }//HSPitchShift | |
141 | |
142 /* | |
143 function ReFM: frequency re-modulation | |
144 | |
145 In: partials[M][Fr]: HS partials | |
146 amount: relative modulation depth after remodulation | |
147 rate: relateive modulation rate after remodulation | |
148 SF: a source-filter model, optional | |
149 Out: partials2[M][Fr]: remodulated HS partials. Must be allocated before calling. | |
150 | |
151 No return value. | |
152 */ | |
153 void ReFM(int M, int Fr, atom** partials, atom** partials2, double amount, double rate, TSF* SF) | |
154 { | |
155 double *arec=new double[Fr]; int *peakfr=new int[Fr], npfr; | |
156 DFMSeg(arec, npfr, peakfr, M, Fr, partials); | |
157 | |
158 double *a1=new double[Fr*8]; | |
159 double *f1=&a1[Fr], *a2=&a1[Fr*3], *f2=&a1[Fr*4], *da=&a1[Fr*5], *df=&a1[Fr*6]; | |
160 | |
161 for (int m=0; m<M; m++) | |
162 { | |
163 atom *part=partials[m], *part2=partials2[m]; bool fzero=false; | |
164 for (int fr=0; fr<Fr; fr++) | |
165 { | |
166 if (part[fr].f<=0){fzero=true; break;} | |
167 a1[fr]=part[fr].a*2; | |
168 f1[fr]=part[fr].f; | |
169 } | |
170 if (fzero){part2[0].f=0; break;} | |
171 DeFM(a2, f2, a1, f1, arec, npfr, peakfr); | |
172 for (int i=0; i<Fr; i++) da[i]=a1[i]-a2[i], df[i]=f1[i]-f2[i]; | |
173 for (int fr=0; fr<Fr; fr++) | |
174 { | |
175 double frd=fr/rate; int dfrd=floor(frd); frd-=dfrd; | |
176 double lda=0, ldf=0; | |
177 if (dfrd<Fr-1) lda=da[dfrd]*(1-frd)+da[dfrd+1]*frd, ldf=df[dfrd]*(1-frd)+df[dfrd+1]*frd; | |
178 else if (dfrd==Fr-1) lda=da[dfrd]*(1-frd), ldf=df[dfrd]*(1-frd); | |
179 part2[fr].f=f2[fr]=f2[fr]+ldf*amount; | |
180 if (SF) part2[fr].a=part[fr].a*exp(SF->LogAF(part2[fr].f)-SF->LogAF(part[fr].f)); | |
181 else part2[fr].a=(a2[fr]+lda*amount)*0.5; | |
182 } | |
183 } | |
184 delete[] a1; | |
185 delete[] arec; delete[] peakfr; | |
186 }//ReFM | |
187 | |
188 | |
189 | |
190 |